2

I'm trying to add functionality to my spacemacs config. I want to show allAlchemist buffers in another frame. For example Alchemist Test Report or Alchemist Mix. So when I use M-RET t b, spacemacs should open a new frame if it does not already exist.

I have this in my config right now:

(add-to-list 'display-buffer-alist
             `(,(rx bos "*alchemist*" eos)
                (display-buffer-reuse-window
                   display-buffer-pop-up-frame)
               (reusable-frames     . visible)
                 ))

It works, but only partially. If I have more than one buffer opened in the current frame, the new frame is opened with the Alchemist buffer, but with other buffers too (Neotree for example).

The other problem is that some Alchemist frames, like those with mix or iex, are not using the Alchemist frame already opened, and they are opening a new frame.

In resume, and to simplify, I want to have one frame at the same time, with only one buffer and one window with Alchemist stuff.

Is it possible? How?

1
  • Here is a link to a complex example of how to target a new or specific existing frame with a certain buffer, either file-visiting or non-file-visiting, entitled "How to intercept a file before it opens and decide which frame": stackoverflow.com/questions/18346785/… Rather than targeting the largest window in the existing frame, you could delete those existing windows and have only one window for your new buffer if you so choose; e.g., once the frame has been selected programmatically, just call delete-other-windows.
    – lawlist
    Feb 17, 2018 at 23:21

1 Answer 1

4

Here is a simple way to make Emacs show certain buffers in their own frame, by default. (And that frame will be reused when you refer to its buffer.)

Customize option special-display-buffer-names or option special-display-regexps to reflect the names of the buffers you want to display in their own frames.

For example, if all Alchemist buffers start with Alchemist, and no other buffers do, then this is all you need:

(add-to-list 'special-display-regexps "\\`Alchemist ")

or even:

(setq special-display-regexps  '("\\`Alchemist "))

Option special-display-regexps is just a list of regexps that are matched against buffer names. Option special-display-buffer-names is just a list of buffer names. C-h f special-display-buffer-names says this:

*special-display-buffer-names is a variable defined in window.el. Its value is shown below.

This variable is obsolete since 24.3; use display-buffer-alist instead. This variable can be risky when used as a file-local variable.

Documentation:

List of names of buffers that should be displayed specially.

Displaying a buffer with display-buffer or pop-to-buffer, if its name is in this list, displays the buffer in a way specified by special-display-function. special-display-popup-frame (the default for special-display-function) usually displays the buffer in a separate frame made with the parameters specified by special-display-frame-alist. If special-display-function has been set to some other function, that function is called with the buffer as first, and nil as second argument.

Alternatively, an element of this list can be specified as (BUFFER-NAME FRAME-PARAMETERS), where BUFFER-NAME is a buffer name and FRAME-PARAMETERS an alist of (PARAMETER . VALUE) pairs. special-display-popup-frame will interpret such pairs as frame parameters when it creates a special frame, overriding the corresponding values from special-display-frame-alist.

As a special case, if FRAME-PARAMETERS contains (same-window . t) special-display-popup-frame displays that buffer in the selected window. If FRAME-PARAMETERS contains (same-frame . t), it displays that buffer in a window on the selected frame.

If special-display-function specifies some other function than special-display-popup-frame, that function is called with the buffer named BUFFER-NAME as first, and FRAME-PARAMETERS as second argument.

Finally, an element of this list can be also specified as (BUFFER-NAME FUNCTION OTHER-ARGS). In that case, special-display-popup-frame will call FUNCTION with the buffer named BUFFER-NAME as first argument, and OTHER-ARGS as the second.

Any alternative function specified here is responsible for setting up the quit-restore parameter of the window used.

If this variable appears "not to work", because you added a name to it but the corresponding buffer is displayed in the selected window, look at the values of same-window-buffer-names and same-window-regexps. Those variables take precedence over this one.

See also special-display-regexps.

You can customize this variable.


Alternatively, you can use option display-buffer-alist.

Emacs claims that the special-display-* variables are obsolete, but they work just fine. They should never have been deprecated, IMO. That was done when the display-buffer-alist monster was created. The idea was perhaps that the special-display-* options made it too easy to do such a simple thing. ;-)

It is good that display-buffer-alist was created. It is not good (IMHO) for Emacs to consider special-display-* to be deprecated.

1
  • Hear hear on your op-ed below the box.
    – Roadowl
    Jul 23, 2019 at 20:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.