3

I like to work with two windows split horizontally or vertically. However, when I try to use C-x 4 f (ido-find-file-other-window) when I already have two windows, it will split one of my windows so I have a total of three windows. How can I change this behavior so that no more than two windows should ever be open?

1
  • 1
    In my experiments with Emacs 27.1.90, called with emacs -Q I saw the following behavior: If the frame is only horizontally split into two windows then ido-find-file-other-window reuses the already existing currently unselected window. If the frame is vertically split into two windows it splits the currently selected window horizontally and displays the buffer in the newly created window. If this is the same for you, it may be worth mentioning.
    – Tobias
    May 20, 2021 at 4:33

1 Answer 1

2

Actually, the option pop-up-window controlls the generation of new windows.
The pitfall is, that there are commands that locally bind that variable to t.
The command switch-to-buffer-other-window is such a command that is especially relevant for your problem, since ido-find-file-other-window uses it.

The strategy for displaying buffers is controlled by a chain of action lists for the command display-buffer.
Normally, all action lists but display-buffer-fallback-action are set to (nil) which means "no action in this list".

The last action list display-buffer-fallback-action cannot be modified by the user and it has the following value:

((display-buffer--maybe-same-window display-buffer-reuse-window
display-buffer--maybe-pop-up-frame-or-window
display-buffer-in-previous-window display-buffer-use-some-window
display-buffer-pop-up-frame))

The option pop-up-window is used in display-buffer--maybe-pop-up-window (called from display-buffer--maybe-pop-up-frame-or-window) to block the call of display-buffer-pop-up-window.
Since we do not have full control over pop-up-window in a non-hacky way we need to override display-buffer-fallback-action with a similar action list like display-buffer-fallback-action that does only split the window if it is the only one of the frame. We use display-buffer-base-action for that purpose which is processed before display-buffer-fallback-action:

(defun display-buffer-2-windows (buffer alist)
  "If only one window is available split it and display BUFFER there.
ALIST is the option channel for display actions (see `display-buffer')."
  (when (eq (length (window-list nil 'no-minibuf)) 1)
    (display-buffer--maybe-pop-up-window buffer alist)))

(setq display-buffer-base-action
      '((display-buffer--maybe-same-window
     display-buffer-reuse-window
     display-buffer--maybe-pop-up-frame
     display-buffer-2-windows
     display-buffer-in-previous-window
     display-buffer-use-some-window
     display-buffer-pop-up-frame)))

Your Answer

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

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