]> git.eshelyaron.com Git - emacs.git/commitdiff
Add new alist entry 'some-window' for 'display-buffer-use-some-window'
authorJuri Linkov <juri@linkov.net>
Fri, 7 Jun 2024 16:45:06 +0000 (19:45 +0300)
committerEshel Yaron <me@eshelyaron.com>
Sat, 8 Jun 2024 12:59:11 +0000 (14:59 +0200)
* doc/lispref/windows.texi (Buffer Display Action Functions):
Add details of using the alist entry 'some-window' in
'display-buffer-use-some-window'.
(Buffer Display Action Alists): Add 'some-window'.

* lisp/window.el (display-buffer-use-some-window):
Handle the alist entry 'some-window' (bug#70949).
Extend docstring with its description.

(cherry picked from commit 979365eef2f09e2c9d21cbf5ff0d350b210d4127)

doc/lispref/windows.texi
etc/NEWS
lisp/window.el

index 61e72eae6806ab4041290a9721da3de0e1fc6a85..ef61e2780c17f2af71485338c279df71d3e56d0e 100644 (file)
@@ -2805,6 +2805,21 @@ If no less recently used window is found, this function will try to use
 some other window, preferably a large window on some visible frame.  It
 can fail if all windows are dedicated to other buffers (@pxref{Dedicated
 Windows}).
+
+The above describes the behavior when @code{some-window} @var{alist}
+entry is @code{lru} or @code{nil} which is the default.  But when,
+for example, @code{display-buffer-base-action} is customized to
+@w{@code{(nil . ((some-window . mru)))}}, then the value @code{mru}
+means that this function will prefer the most recently used window
+that is useful to display several buffers from the consecutive calls
+of @code{display-buffer} in the same window.  Consider a configuration
+of three or more windows where a user wants to consult, in
+a non-selected window, one after the other, the results of a query
+spread among several buffers.  With the @code{lru} strategy, Emacs might
+continuously choose another window because the least recently used
+window changes with every call of @code{display-buffer-use-some-window}.
+With the @code{mru} strategy, the window chosen would always remain the
+same, resulting in a predictable user experience.
 @end defun
 
 @defun display-buffer-use-least-recent-window buffer alist
@@ -3358,6 +3373,16 @@ since there is no guarantee that an arbitrary caller of
 will display the buffer.  @code{display-buffer-no-window} is the only
 action function that cares about this entry.
 
+@vindex some-window@r{, a buffer display action alist entry}
+@item some-window
+If the value is @code{nil} or @code{lru}, @code{display-buffer-use-some-window}
+prefers the least recently used window while avoiding selecting windows
+that are not full-width and windows on another frame.  If the value is
+@code{mru}, it prefers the most recently used window not considering the
+selected window and windows on any frame but the selected one.  If the
+value is a function, it is called with two arguments: a buffer and an
+alist, and should return the window where to display the buffer.
+
 @vindex body-function@r{, a buffer display action alist entry}
 @item body-function
 The value must be a function taking one argument (a displayed window).
index e91270701d3a67f9bbbb433f6733db7a805c45cb..e464168908f7895ff318c1252d67eb2250f64695 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -297,6 +297,14 @@ right-aligned to is controlled by the new user option
 
 ** Windows
 
++++
+*** New action alist entry 'some-window' for 'display-buffer'.
+It defines which window 'display-buffer-use-some-window' should prefer.
+For example, when 'display-buffer-base-action' is customized to
+'(nil . ((some-window . mru)))' then a buffer will be displayed
+in the same most recently used window from the consecutive calls
+display-buffer' (on a configuration with more than two windows).
+
 +++
 *** New action alist entry 'category' for 'display-buffer'.
 If the caller of 'display-buffer' passes '(category . symbol)'
index 6a97cdec118fb82d8c2fb220551c1232e31f63a2..54568a9389a389a12d89121792a36523f4c391f9 100644 (file)
@@ -7855,6 +7855,18 @@ Action alist entries are:
     parameters to give the chosen window.
  `allow-no-window' -- A non-nil value means that `display-buffer'
     may not display the buffer and return nil immediately.
+ `some-window' -- This entry defines which window
+    `display-buffer-use-some-window' should choose.  The possible choices
+    are `lru' or nil (the default) to select the least recently used window,
+    and `mru' to select the most recently used window.  It can also be
+    a function that takes two arguments: a buffer and an alist, and should
+    return the window where to display the buffer.  If the value is `lru',
+    it avoids selecting windows that are not full-width and windows on
+    another frame.  If the value is `mru', it does not consider the
+    selected window and windows on any frame but the selected one.
+    It's useful to customize `display-buffer-base-action' to
+    `(nil . ((some-window . mru))) when you want to display buffers in the
+    same non-selected window in a configuration with more than two windows.
  `body-function' -- A function called with one argument - the
     displayed window.  It is called after the buffer is
     displayed, and before `window-height', `window-width'
@@ -8748,20 +8760,33 @@ If ALIST has a non-nil `inhibit-switch-frame' entry, then in the
 event that a window on another frame is chosen, avoid raising
 that frame.
 
+If ALIST contains a non-nil `some-window' entry, then prefer the least
+recently used window if the entry's value is `lru' or nil, or the most
+recently used window if it's `mru'.  If the value is a function, it is
+called with two arguments: a buffer and an alist, and should return
+the window where to display the buffer.
+
 This is an action function for buffer display, see Info
 node `(elisp) Buffer Display Action Functions'.  It should be
 called only by `display-buffer' or a function directly or
 indirectly called by the latter."
   (let* ((not-this-window (cdr (assq 'inhibit-same-window alist)))
+        (some-window-method (cdr (assq 'some-window alist)))
         (frame (or (window--frame-usable-p (selected-frame))
                    (window--frame-usable-p (last-nonminibuffer-frame))))
         (window
          ;; Reuse an existing window.
-         (or (display-buffer--lru-window
-               ;; If ALIST specifies 'lru-frames' or 'window-min-width'
-               ;; let them prevail.
-               (append alist `((lru-frames . ,frame)
-                               (window-min-width . full-width))))
+         (or (cond
+              ((memq some-window-method '(nil lru))
+               (display-buffer--lru-window
+                ;; If ALIST specifies 'lru-frames' or 'window-min-width'
+                ;; let them prevail.
+                (append alist `((lru-frames . ,frame)
+                                (window-min-width . full-width)))))
+              ((eq some-window-method 'mru)
+               (get-mru-window nil nil t))
+              ((functionp some-window-method)
+               (funcall some-window-method buffer alist)))
              (let ((window (get-buffer-window buffer 'visible)))
                (unless (and not-this-window
                             (eq window (selected-window)))