From 26fbad2bcf7cabf98678dda0095334fab7722480 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 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' which is passed reusable-frames if it is provided. If 'get-lru-window' returns nil then 'display-buffer-pop-p-window' is used to split the current window. If an existing window is selected then it runs code adapted from 'display-buffer-use-some-window'. --- lisp/window.el | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/lisp/window.el b/lisp/window.el index 0cd30822ff6..c507f4c6c1f 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -8507,10 +8507,38 @@ 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 the +least recent window in all matching frames. By default it only +searches the current frame." + (let* ((reusable-frames (cdr (assq 'reusable-frames alist))) + (frame (or (window--frame-usable-p (selected-frame)) + (window--frame-usable-p (last-nonminibuffer-frame)))) + (window (or (get-lru-window (or reusable-frames frame) nil t)))) + (let ((window + (if window + (let* ((quit-restore (and (window-live-p window) + (window-parameter window 'quit-restore))) + (quad (nth 1 quit-restore))) + (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))) + (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))))) + (display-buffer-pop-up-window buffer alist)))) + (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