display-buffer
is the basic routine that decides how to display a buffer. It uses a variable display-buffer-alist
to help it decide. You can modify that variable to use a different action
than the default in order to do what you want. C-h f display-buffer
gives you a list of action functions, e.g. here is the description of one of them: ‘display-buffer-use-least-recent-window’ -- Try to avoid re-using windows that have recently been switched to.
This looks promising, so we define a function that uses that as follows:
(defun my/switch-to-buffer-other-window (buf)
(let ((display-buffer-alist '((".*" display-buffer-use-least-recent-window))))
(switch-to-buffer-other-window buf)))
You can then use this function to switch to the buffer in the least-recently-used window:
(my/switch-to-buffer-other-window (get-buffer "*scratch*"))
For (much more) information about display-buffer
, consult Displaying buffers in the Emacs Lisp Reference manual.
Keeping the functions separate allows you to use one or the other as the need arises. OTOH, if you want to permanently change the behavior, you could advise the original switch-to-buffer-other-window
function to do the new thing:
(defun use-least-recent-window (orig-fun &rest args)
(let ((display-buffer-alist '((".*" display-buffer-use-least-recent-window))))
(apply orig-fun args)))
(advice-add 'switch-to-buffer-other-window :around #'use-least-recent-window)
If at any point you want to get rid of the advice, then evaluate the following:
(advice-remove 'switch-to-buffer-other-window #'use-least-recent-window)
Manipulating the heuristics used for window choice by display-buffer
like this can be finicky. I believe there are higher-level libraries to do things like this conveniently, but I haven't used any of them and I cannot even remember names ATM, so I hope others will provide answers that use them. I am under the impression that they trade off flexibility for convenience, but you shouldn't put much stock in that.
EDIT: Here's one such library: emacs-purpose - but as I mentioned, I've never used it and I don't know much about it.