From: martin rudalics <rudalics@gmx.at>
To: Ihor Radchenko <yantar92@posteo.net>
Cc: "Juri Linkov" <juri@linkov.net>, "Sébastien Gendre" <seb@k-7.ch>,
"Org Mode List" <emacs-orgmode@gnu.org>,
emacs-devel@gnu.org
Subject: Re: May we have a variant of display-buffer-reuse-window that considers indirect buffers?
Date: Wed, 18 Dec 2024 20:13:14 +0100 [thread overview]
Message-ID: <4a276720-259e-458a-a0ea-53cdd24e8ee6@gmx.at> (raw)
In-Reply-To: <87o7187t44.fsf@localhost>
[-- Attachment #1: Type: text/plain, Size: 931 bytes --]
attached.
>> > 1. If there is a window displaying BUFFER, switch to that window
>> > 2. If there is a window that is an indirect buffer of BUFFER or that
>> > shares the same base buffer with BUFFER, switch to that window
>>
>> I included the facility that if there is a window whose buffer is the
>> base buffer of BUFFER use that window. See the attached diff which I
>> did not test very thoroughly.
>
> Thanks!
> It seems to work, although somewhat different than I described.
>
> With your diff, in case (2), if BUFFER is what is passed to
> `pop-to-buffer' and BUFFER2 is indirectly related buffer displayed in a
> visible window, then BUFFER2 is replaced with BUFFER. I expected that
> BUFFER2's window will be selected; nothing more.
Hmmm... This is not really what 'display-buffer' is supposed to do. I
have to disguise the fact that we wanted to display BUFFER. I attach a
new patch.
martin
[-- Attachment #2: display-indirect-buffer.diff --]
[-- Type: text/x-patch, Size: 6261 bytes --]
diff --git a/lisp/window.el b/lisp/window.el
index e9d57652ec6..dd030547350 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -2615,7 +2615,36 @@ get-largest-window
(setq best-window window))))
best-window))
-(defun get-buffer-window-list (&optional buffer-or-name minibuf all-frames)
+(defun window-indirect-buffer-p (&optional window buffer-or-name)
+ "Return non-nil if specified WINDOW is indirectly related to BUFFER-OR-NAME.
+WINDOW must be a live window and defaults to the selected window.
+BUFFER-OR-NAME may be a buffer or the name of an existing buffer and
+defaults to the current buffer.
+
+WINODW is indirectly related to BUFFER-OR-NAME if one of the following
+conditions hold:
+
+- BUFFER-OR-NAME specifies an indirect buffer and WINDOW's buffer is its
+ base buffer.
+
+- WINDOW's buffer is an indirect buffer whose base buffer is the buffer
+ specified by BUFFER-OR-NAME.
+
+- Both, WINDOW's buffer and the buffer specified by BUFFER-OR-NAME, are
+ indirect buffer's sharing the same base buffer.
+
+Return nil if none of the above holds."
+ (let* ((window (window-normalize-window window t))
+ (window-buffer (window-buffer window))
+ (window-base-buffer (buffer-base-buffer window-buffer))
+ (buffer (window-normalize-buffer buffer-or-name))
+ (buffer-base-buffer (buffer-base-buffer buffer)))
+ (or (eq buffer-base-buffer window-buffer)
+ (eq window-base-buffer buffer)
+ (and buffer-base-buffer
+ (eq buffer-base-buffer window-base-buffer)))))
+
+(defun get-buffer-window-list (&optional buffer-or-name minibuf all-frames indirect)
"Return list of all windows displaying BUFFER-OR-NAME, or nil if none.
BUFFER-OR-NAME may be a buffer or the name of an existing buffer
and defaults to the current buffer. If the selected window displays
@@ -2644,12 +2673,23 @@ get-buffer-window-list
- A frame means consider all windows on that frame only.
Anything else means consider all windows on the selected frame
-and no others."
+and no others.
+
+INDIRECT non-nil means to append to the list of windows showing
+BUFFER-OR-NAME a list of all windows that are indirectly related to
+BUFFER-OR-NAME, that is, windows for which `window-indirect-buffer-p'
+with the window and the buffer specified by BUFFER-OR-NAME as arguments
+returns non-nil."
(let ((buffer (window-normalize-buffer buffer-or-name))
+ (window-list (window-list-1 (selected-window) minibuf all-frames))
windows)
- (dolist (window (window-list-1 (selected-window) minibuf all-frames))
+ (dolist (window window-list)
(when (eq (window-buffer window) buffer)
(setq windows (cons window windows))))
+ (when indirect
+ (dolist (window window-list)
+ (when (window-indirect-buffer-p window buffer)
+ (setq windows (cons window windows)))))
(nreverse windows)))
(defun minibuffer-window-active-p (window)
@@ -8235,35 +8275,53 @@ display-buffer-reuse-window
event that a window on another frame is chosen, avoid raising
that frame.
+If ALIST has a non-nil `reuse-indirect' entry and no window showing
+BUFFER has been found, try to find a window that is indirectly related
+to BUFFER and return that window. This would be a window for which
+`window-indirect-buffer-p' with the window and BUFFER as arguments
+returns non-nil.
+
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* ((alist-entry (assq 'reusable-frames alist))
- (frames (cond (alist-entry (cdr alist-entry))
+ (let* ((reusable-frames (assq 'reusable-frames alist))
+ (reuse-indirect (assq 'reuse-indirect alist))
+ (frames (cond (reusable-frames (cdr reusable-frames))
((window--pop-up-frames alist)
0)
(display-buffer-reuse-frames 0)
(t (last-nonminibuffer-frame))))
- (window (if (and (eq buffer (window-buffer))
- (not (cdr (assq 'inhibit-same-window alist))))
- (selected-window)
- ;; Preferably use a window on the selected frame,
- ;; if such a window exists (Bug#36680).
- (let* ((windows (delq (selected-window)
- (get-buffer-window-list
- buffer 'nomini frames)))
- (first (car windows))
- (this-frame (selected-frame)))
- (cond
- ((eq (window-frame first) this-frame)
- first)
- ((catch 'found
- (dolist (next (cdr windows))
- (when (eq (window-frame next) this-frame)
- (throw 'found next)))))
- (t first))))))
+ (inhibit-same (cdr (assq 'inhibit-same-window alist)))
+ (window
+ ;; Avoid calling 'get-buffer-window-list' if the selected
+ ;; window already shows BUFFER and can be used.
+ (if (and (eq buffer (window-buffer)) (not inhibit-same))
+ (selected-window)
+ ;; Preferably use a window on the selected frame,
+ ;; if such a window exists (Bug#36680).
+ (let* ((windows-raw
+ (get-buffer-window-list
+ buffer 'nomini frames reuse-indirect))
+ (windows (if inhibit-same
+ (delq (selected-window) windows-raw)
+ windows-raw))
+ (first (car windows))
+ (this-frame (selected-frame)))
+ (cond
+ ((eq (window-frame first) this-frame)
+ first)
+ ((catch 'found
+ (dolist (next (cdr windows))
+ (when (eq (window-frame next) this-frame)
+ (throw 'found next)))))
+ (t first))))))
(when (window-live-p window)
+ (when (and reuse-indirect
+ (not (eq (window-buffer window) buffer)))
+ ;; Pretend we were asking for a window showing the buffer of
+ ;; that window.
+ (setq buffer (window-buffer window)))
(prog1 (window--display-buffer buffer window 'reuse alist)
(unless (cdr (assq 'inhibit-switch-frame alist))
(window--maybe-raise-frame (window-frame window)))))))
prev parent reply other threads:[~2024-12-18 19:14 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-05 8:02 Indirect follow mode in agenda: Display, edition and how to hide drawers Sébastien Gendre
2024-11-05 9:22 ` Kristoffer Balintona
2024-11-05 21:15 ` Karthik Chikmagalur
2024-11-08 15:05 ` Sébastien Gendre
2024-11-08 14:59 ` Sébastien Gendre
2024-11-10 23:34 ` Sébastien Gendre
2024-11-11 0:09 ` Sébastien Gendre
2024-11-11 17:59 ` Ihor Radchenko
2024-11-12 0:30 ` Sébastien Gendre
2024-11-12 19:17 ` Ihor Radchenko
2024-11-18 23:22 ` Sébastien Gendre
2024-12-15 15:09 ` Ihor Radchenko
2024-12-15 15:28 ` May we have a variant of display-buffer-reuse-window that considers indirect buffers? (was: Indirect follow mode in agenda: Display, edition and how to hide drawers) Ihor Radchenko
2024-12-16 7:49 ` May we have a variant of display-buffer-reuse-window that considers indirect buffers? Juri Linkov
2024-12-16 9:23 ` martin rudalics
2024-12-16 18:07 ` Ihor Radchenko
2024-12-17 9:01 ` martin rudalics
2024-12-17 18:11 ` Ihor Radchenko
2024-12-18 9:08 ` martin rudalics
2024-12-18 18:18 ` Ihor Radchenko
2024-12-18 19:13 ` martin rudalics [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.orgmode.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4a276720-259e-458a-a0ea-53cdd24e8ee6@gmx.at \
--to=rudalics@gmx.at \
--cc=emacs-devel@gnu.org \
--cc=emacs-orgmode@gnu.org \
--cc=juri@linkov.net \
--cc=seb@k-7.ch \
--cc=yantar92@posteo.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).