> 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
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

Reply via email to