* 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)
[not found] <878qtycdmi.fsf@k-7.ch>
@ 2024-12-15 15:28 ` Ihor Radchenko
2024-12-16 7:49 ` May we have a variant of display-buffer-reuse-window that considers indirect buffers? Juri Linkov
0 siblings, 1 reply; 9+ messages in thread
From: Ihor Radchenko @ 2024-12-15 15:28 UTC (permalink / raw)
To: Sébastien Gendre; +Cc: Org Mode List, emacs-devel
Hi,
We got a use case when we want to display an Org buffer in other window,
but want to reuse an indirect buffer if it is already present.
May it be possible?
It feels like a natural thing to be available for `display-buffer', but
I cannot find anything.
Sébastien Gendre <seb@k-7.ch> writes:
> When I want to edit a task and press "TAB", the point is moved to
> a window that show all the task. Not into the window opened by the
> indirect follow mode. Is it possible to modify this ?
--
Ihor Radchenko // yantar92,
Org mode maintainer,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: May we have a variant of display-buffer-reuse-window that considers indirect buffers?
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 ` Juri Linkov
2024-12-16 9:23 ` martin rudalics
2024-12-16 18:07 ` Ihor Radchenko
0 siblings, 2 replies; 9+ messages in thread
From: Juri Linkov @ 2024-12-16 7:49 UTC (permalink / raw)
To: Ihor Radchenko
Cc: Sébastien Gendre, Org Mode List, emacs-devel,
martin rudalics
>> When I want to edit a task and press "TAB", the point is moved to
>> a window that show all the task. Not into the window opened by the
>> indirect follow mode. Is it possible to modify this ?
>
> We got a use case when we want to display an Org buffer in other window,
> but want to reuse an indirect buffer if it is already present.
>
> May it be possible?
> It feels like a natural thing to be available for `display-buffer', but
> I cannot find anything.
It's possible to select the necessary window by using 'pop-to-buffer'
while displaying the non-selected window with a simple 'display-window'.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: May we have a variant of display-buffer-reuse-window that considers indirect buffers?
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
1 sibling, 0 replies; 9+ messages in thread
From: martin rudalics @ 2024-12-16 9:23 UTC (permalink / raw)
To: Juri Linkov, Ihor Radchenko
Cc: Sébastien Gendre, Org Mode List, emacs-devel
> It's possible to select the necessary window by using 'pop-to-buffer'
> while displaying the non-selected window with a simple 'display-window'.
'display-buffer'
I suppose.
martin
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: May we have a variant of display-buffer-reuse-window that considers indirect buffers?
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
1 sibling, 1 reply; 9+ messages in thread
From: Ihor Radchenko @ 2024-12-16 18:07 UTC (permalink / raw)
To: Juri Linkov
Cc: Sébastien Gendre, Org Mode List, emacs-devel,
martin rudalics
Juri Linkov <juri@linkov.net> writes:
>> We got a use case when we want to display an Org buffer in other window,
>> but want to reuse an indirect buffer if it is already present.
>>
>> May it be possible?
>> It feels like a natural thing to be available for `display-buffer', but
>> I cannot find anything.
>
> It's possible to select the necessary window by using 'pop-to-buffer'
> while displaying the non-selected window with a simple 'display-window'.
May you please provide more information? AFAIK, `pop-to-buffer' will
search for exact buffer without considering its indirect buffers and
base buffer.
--
Ihor Radchenko // yantar92,
Org mode maintainer,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: May we have a variant of display-buffer-reuse-window that considers indirect buffers?
2024-12-16 18:07 ` Ihor Radchenko
@ 2024-12-17 9:01 ` martin rudalics
2024-12-17 18:11 ` Ihor Radchenko
0 siblings, 1 reply; 9+ messages in thread
From: martin rudalics @ 2024-12-17 9:01 UTC (permalink / raw)
To: Ihor Radchenko, Juri Linkov
Cc: Sébastien Gendre, Org Mode List, emacs-devel
> May you please provide more information? AFAIK, `pop-to-buffer' will
> search for exact buffer without considering its indirect buffers and
> base buffer.
Could you please tell us what you would like 'display-buffer' to do
without referring to org-mode. IIUC you want it to automatically detect
that if a base buffer has been displayed in a window earlier and BUFFER
is an indirect buffer sharing that base buffer, then it should try to
use that window for the indirect buffer. Is that assumption correct?
martin
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: May we have a variant of display-buffer-reuse-window that considers indirect buffers?
2024-12-17 9:01 ` martin rudalics
@ 2024-12-17 18:11 ` Ihor Radchenko
2024-12-18 9:08 ` martin rudalics
0 siblings, 1 reply; 9+ messages in thread
From: Ihor Radchenko @ 2024-12-17 18:11 UTC (permalink / raw)
To: martin rudalics
Cc: Juri Linkov, Sébastien Gendre, Org Mode List, emacs-devel
martin rudalics <rudalics@gmx.at> writes:
> Could you please tell us what you would like 'display-buffer' to do
> without referring to org-mode. IIUC you want it to automatically detect
> that if a base buffer has been displayed in a window earlier and BUFFER
> is an indirect buffer sharing that base buffer, then it should try to
> use that window for the indirect buffer. Is that assumption correct?
Yup.
To be 100% clear, let me try to restate exactly what I have in mind.
I want to call something like
(pop-to-buffer BUFFER
'((display-buffer-reuse-window display-buffer-pop-up-window)
(reuse-indirect . t)))
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
3. Otherwise, pop up a new window displaying BUFFER
(2) is the feature I am failing to find.
--
Ihor Radchenko // yantar92,
Org mode maintainer,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: May we have a variant of display-buffer-reuse-window that considers indirect buffers?
2024-12-17 18:11 ` Ihor Radchenko
@ 2024-12-18 9:08 ` martin rudalics
2024-12-18 18:18 ` Ihor Radchenko
0 siblings, 1 reply; 9+ messages in thread
From: martin rudalics @ 2024-12-18 9:08 UTC (permalink / raw)
To: Ihor Radchenko
Cc: Juri Linkov, Sébastien Gendre, Org Mode List, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 629 bytes --]
> To be 100% clear, let me try to restate exactly what I have in mind.
>
> I want to call something like
>
> (pop-to-buffer BUFFER
> '((display-buffer-reuse-window display-buffer-pop-up-window)
> (reuse-indirect . t)))
>
> 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.
martin
[-- Attachment #2: display-indirect-buffer.diff --]
[-- Type: text/x-patch, Size: 4165 bytes --]
diff --git a/lisp/window.el b/lisp/window.el
index e9d57652ec6..31c2ae50792 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,11 +2673,17 @@ 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 include in the list returned all windows that
+are indirectly related to BUFFER-OR-NAME, that is, all 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))
windows)
(dolist (window (window-list-1 (selected-window) minibuf all-frames))
- (when (eq (window-buffer window) buffer)
+ (when (or (eq (window-buffer window) buffer)
+ (and indirect (window-indirect-buffer-p window buffer)))
(setq windows (cons window windows))))
(nreverse windows)))
@@ -8239,20 +8274,24 @@ display-buffer-reuse-window
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))
+ (window (if (and (or (eq buffer (window-buffer))
+ (and reuse-indirect
+ (window-indirect-buffer-p nil 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)))
+ (let* ((windows
+ (delq (selected-window)
+ (get-buffer-window-list
+ buffer 'nomini frames reuse-indirect)))
(first (car windows))
(this-frame (selected-frame)))
(cond
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: May we have a variant of display-buffer-reuse-window that considers indirect buffers?
2024-12-18 9:08 ` martin rudalics
@ 2024-12-18 18:18 ` Ihor Radchenko
2024-12-18 19:13 ` martin rudalics
0 siblings, 1 reply; 9+ messages in thread
From: Ihor Radchenko @ 2024-12-18 18:18 UTC (permalink / raw)
To: martin rudalics
Cc: Juri Linkov, Sébastien Gendre, Org Mode List, emacs-devel
martin rudalics <rudalics@gmx.at> writes:
> > (pop-to-buffer BUFFER
> > '((display-buffer-reuse-window display-buffer-pop-up-window)
> > (reuse-indirect . t)))
> >
> > 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.
--
Ihor Radchenko // yantar92,
Org mode maintainer,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: May we have a variant of display-buffer-reuse-window that considers indirect buffers?
2024-12-18 18:18 ` Ihor Radchenko
@ 2024-12-18 19:13 ` martin rudalics
0 siblings, 0 replies; 9+ messages in thread
From: martin rudalics @ 2024-12-18 19:13 UTC (permalink / raw)
To: Ihor Radchenko
Cc: Juri Linkov, Sébastien Gendre, Org Mode List, emacs-devel
[-- 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)))))))
^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2024-12-18 19:13 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <878qtycdmi.fsf@k-7.ch>
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
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.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).