From 274493ccb0e15aeec88b08fcf79180616deacf6f Mon Sep 17 00:00:00 2001 From: Tom Gillespie Date: Thu, 26 Jan 2023 23:47:22 -0500 Subject: [PATCH] Fix display-buffer-use-least-recent-window to split, return window. * lisp/window.el (display-buffer-use-least-recent-window): Return window instead of nil, and actually split in single window case. 'display-buffer-use-least-recent-window' now returns window if one is selected which prevents the rather nasty behavior of selecting a window in the current frame and then also selecting a window in another random frame as well (quite maddening). The docs for 'display-buffer-use-least-recent-window' state that it will pick the least recently used window or and if there is only a single window it will split the window. Prior to this commit that behavior was impossible to achieve because 'display-buffer-use-least-recent-window' reused the internals of 'display-buffer-use-some-window' which would attempt to find a valid window in other frames and never split the current window. 'display-buffer-use-least-recent-window' no longer calls 'display-buffer-use-some-window' and instead directly calls 'get-lru-window' followed by 'display-buffer-pop-p-window' when reusable-frames is not provided or nil, or 'get-buffer-window' when reusable-frames is non-nil. Once the window is selected it runs code that has been duplicated from 'display-buffer-use-some-window'. --- lisp/window.el | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/lisp/window.el b/lisp/window.el index 0cd30822ff6..6dd4fed1dd3 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -8507,10 +8507,41 @@ display-buffer-use-least-recent-window This `display-buffer' action function is like `display-buffer-use-some-window', but will cycle through windows when displaying buffers repeatedly, and if there's only a single -window, it will split the window." - (when-let ((window (display-buffer-use-some-window - buffer (cons (cons 'inhibit-same-window t) alist)))) - (window-bump-use-time window))) +window, it will split the window. + +If `reusable-frames' is provided in the alist then +`display-buffer-use-least-recent-window' will attempt to find a +window in other frames accordingly. By default it only searches +the current frame." + (let* ((not-this-window t) + (reusable-frames (assq 'reusable-frames alist)) + (frame (or (window--frame-usable-p (selected-frame)) + (window--frame-usable-p (last-nonminibuffer-frame)))) + (window (or (get-lru-window frame nil not-this-window) + (if (not reusable-frames) + (display-buffer-pop-up-window buffer alist) + (window (get-buffer-window buffer reusable-frames))))) + (quit-restore (and (window-live-p window) + (window-parameter window 'quit-restore))) + (quad (nth 1 quit-restore))) + (unless (eq window (selected-window)) + (when (window-live-p window) + ;; If the window was used by `display-buffer' before, try to + ;; resize it to its old height but don't signal an error. + (when (and (listp quad) + (integerp (nth 3 quad)) + (> (nth 3 quad) (window-total-height window))) + (condition-case nil + (window-resize window (- (nth 3 quad) (window-total-height window))) + (error nil))) + (prog1 + (window--display-buffer buffer window 'reuse alist) + (window--even-window-sizes window) + (unless (cdr (assq 'inhibit-switch-frame alist)) + (window--maybe-raise-frame (window-frame window)))))) + (when window + (window-bump-use-time window) + window))) (defun display-buffer-use-some-window (buffer alist) "Display BUFFER in an existing window. -- 2.39.1