From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.bugs Subject: bug#70949: display-buffer-choose-some-window Date: Mon, 20 May 2024 19:54:54 +0300 Organization: LINKOV.NET Message-ID: <86jzjoo23l.fsf@mail.linkov.net> References: <86jzjwqqmd.fsf@mail.linkov.net> <8d1947c7-a4d1-4920-8638-f8ae17acfe65@gmx.at> <86r0e32fnj.fsf@mail.linkov.net> <867cft0xt2.fsf@mail.linkov.net> <86ed9xvz3o.fsf@mail.linkov.net> <73251208-1e4c-4231-ae58-faf82363f241@gmx.at> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="36421"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/30.0.50 (x86_64-pc-linux-gnu) Cc: 70949@debbugs.gnu.org To: martin rudalics Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Mon May 20 19:03:13 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1s96Po-0009EF-K2 for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 20 May 2024 19:03:12 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1s96Pe-00071J-QV; Mon, 20 May 2024 13:03:02 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1s96Pa-0006z5-Sh for bug-gnu-emacs@gnu.org; Mon, 20 May 2024 13:02:59 -0400 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1s96Pa-0003oL-6g for bug-gnu-emacs@gnu.org; Mon, 20 May 2024 13:02:58 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1s96Pe-0004X2-E5 for bug-gnu-emacs@gnu.org; Mon, 20 May 2024 13:03:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Juri Linkov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 20 May 2024 17:03:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 70949 X-GNU-PR-Package: emacs Original-Received: via spool by 70949-submit@debbugs.gnu.org id=B70949.171622454917412 (code B ref 70949); Mon, 20 May 2024 17:03:02 +0000 Original-Received: (at 70949) by debbugs.gnu.org; 20 May 2024 17:02:29 +0000 Original-Received: from localhost ([127.0.0.1]:43695 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1s96P6-0004Wm-MJ for submit@debbugs.gnu.org; Mon, 20 May 2024 13:02:29 -0400 Original-Received: from relay8-d.mail.gandi.net ([217.70.183.201]:58079) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1s96P1-0004We-KI for 70949@debbugs.gnu.org; Mon, 20 May 2024 13:02:27 -0400 Original-Received: by mail.gandi.net (Postfix) with ESMTPSA id 2604D1BF203; Mon, 20 May 2024 17:02:10 +0000 (UTC) In-Reply-To: <73251208-1e4c-4231-ae58-faf82363f241@gmx.at> (martin rudalics's message of "Mon, 20 May 2024 10:01:13 +0200") X-GND-Sasl: juri@linkov.net X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:285484 Archived-At: --=-=-= Content-Type: text/plain >> + `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 . When a function, it > > I'd say "It can also be a function that takes two arguments ..." > >> + takes two arguments: a buffer and an alist, and should return the window >> + where to display the buffer. When the value is `lru', it avoids >> + selecting windows that are not full-width and windows on another frame. >> + When the value is `mru', it avoids selecting an already selected window >> + and windows on another frame. > > I'd say "..., it does not consider the selected window and windows on > any frame but the selected one." > > But the more important thing is to tell users how this can help to fix > problems like the one that triggered this thread. A short description > in the doc-string and a more elaborated one with an example in the Elisp > manual in the description of 'display-buffer-use-some-window' and in the > "Action Alists for Buffer Display" section. Thanks for suggestions, here is a complete patch: --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=some-window.patch diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi index 61e72eae680..efffb0d3f3f 100644 --- a/doc/lispref/windows.texi +++ b/doc/lispref/windows.texi @@ -2805,6 +2805,14 @@ Buffer Display Action Functions 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 in the same window +in a layout with more than two windows. @end defun @defun display-buffer-use-least-recent-window buffer alist @@ -3358,6 +3366,16 @@ Buffer Display Action Alists 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). diff --git a/etc/NEWS b/etc/NEWS index 4e52d4dccb2..cc2405ca09a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -306,6 +306,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 any buffer will be displayed +in the same most recently used window on a layout with more +than two windows. + +++ *** New action alist entry 'category' for 'display-buffer'. If the caller of 'display-buffer' passes '(category . symbol)' diff --git a/lisp/window.el b/lisp/window.el index e709e978cc9..1549fba6f2e 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -7845,6 +7850,18 @@ display-buffer 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 layout 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' @@ -8734,20 +8751,33 @@ display-buffer-use-some-window 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))) --=-=-=--