modeller
modeller

Reputation: 3850

How to control which window to be used for new contents in Emacs?

Often I have multiples windows carefully arranged within a frame.

However, certain command, say M-x man RET will grab one of the visible windows to display its own content. Sometimes this is annoying because the window that was taken away is one that I need to keep it visible.

e.g. I have 3 windows on screen, one useful source-code window and two useless windows. I want to keep the soure-code window visible while checking the man page. But very often Emacs just take away the code-window for the newly opened man page.

One way I can think of is to display the (chronological) open order of each window, so that I can focus point on n-th window and be confident that Emacs will grab (n+1)-th window for new content.

Is there a way to display such order, e.g. in the mode-line of each window?

Or is there another way for better control for displaying new window?

Upvotes: 3

Views: 579

Answers (2)

phils
phils

Reputation: 73345

I'll throw this example usage of display-buffer-alist into the mix, given that it was mentioned in the comments, and is indeed a general mechanism for controlling how and where buffers are displayed (even though, as Drew indicates, it is far from trivial).

Start with the help for the variable itself:
C-hv display-buffer-alist RET

From there you'll get to the help for display-buffer, and no doubt acquire some idea of the complexities involved :)

In any case, the following is an example of using a custom function to decide how to display buffers named *Buffer List*.

You can easily see that if you can write a function which can figure out how to display a buffer where you want it to, then you can use display-buffer-alist to make it happen.

(defun my-display-buffer-pop-up-same-width-window (buffer alist)
  "A `display-buffer' ACTION forcing a vertical window split.
    See `split-window-sensibly' and `display-buffer-pop-up-window'."
  (let ((split-width-threshold nil)
        (split-height-threshold 0))
    (display-buffer-pop-up-window buffer alist)))

(add-to-list 'display-buffer-alist
             '("\\*Buffer List\\*" my-display-buffer-pop-up-same-width-window))

A key quote regarding the ACTION functions is:

Each such FUNCTION should accept two arguments: the buffer to display and an alist. Based on those arguments, it should display the buffer and return the window.

Upvotes: 2

itsjeyd
itsjeyd

Reputation: 5290

A little late to the party but as discussed in the comments, using dedicated windows is a good way to control where new content is displayed (+1 to @lawlist for bringing it up and to @phils for mentioning toggling!).

I'm pretty sure you'd be able to implement a command that toggles dedicatedness yourself at this point, but since I have the code for this handy I'll share it anyway:

(defun toggle-window-dedicated ()
  "Control whether or not Emacs is allowed to display another
buffer in current window."
  (interactive)
  (message
   (if (let (window (get-buffer-window (current-buffer)))
         ; set-window-dedicated-p returns FLAG that was passed as
         ; second argument, thus can be used as COND for if:
         (set-window-dedicated-p window (not (window-dedicated-p window))))
       "%s: Can't touch this!"
     "%s is up for grabs.")
   (current-buffer)))

(global-set-key (kbd "C-c d") 'toggle-window-dedicated)

Now, in a multi-window setup you can simply press C-c d in each window you would like to "protect".

Upvotes: 3

Related Questions