Subject: bug#20206: 25.0.50; [PATCH] keep diff-mode's window visible when we visit sources from diff-mode

From: martin rudalics <[email-masked]>
Date: Mon, 30 Mar 2015 10:37:33 +0200

> I'm not sure what you mean: '((inhibit-same-window . t)) is not a valid
 > as an action argument to display-buffer,

Sorry, I meant '(nil (inhibit-same-window . t)).

 > and emacs barfs if I try to use
 > it as such. I'm not at all married to using display-buffer-pop-up-window
 > here. If you have a better idea for solving 19901 (or if you think
 > there's nothing to fix), then I'm fine with it.

I'm afraid we are miscommunicating or I am misssing something.  You
propose the following change:

-  (pop-to-buffer (current-buffer))
+  (pop-to-buffer (current-buffer) '(display-buffer-use-some-window (inhibit-same-window . t)))

I think this precludes the following scenario: Consider a frame that
contains two windows.  The user has set `split-height-threshold' and/or
`split-width-threshold' to very small values which easily allow further
splitting.  In this case, a `pop-to-buffer' call for a buffer that
doesn't appear on the frame yet will usually try to split one of the two
windows and show the buffer in a third one.  Agreed?

Now with your proposed change `pop-to-buffer' will always use the "other
window" for displaying the current buffer, thus overriding the user's
customizations of `split-height-threshold' and `split-width-threshold'.
The reason is that `display-buffer-pop-up-window' will not be called
because `display-buffer-use-some-window' is always called first.  Do you
agree?  And can we agree that such behavior would be wrong?

Also, a user who wants to show the buffer in a separate frame via say

(setq pop-up-frames t)

will be disappointed as well.  With a two windows frame he'll never get
a new frame.  Agreed?

Maybe

(pop-to-buffer (current-buffer) t)

is already what we want here because we know that the current buffer is
not shown in the selected window.  Otherwise we could try a patch like
the one I attached.  Then we could do ...

(pop-to-buffer (current-buffer) '(nil (previous-window)))

... if I got it right this time.  WDYT?

 > Another wrinkle is that the behavior reported in 19901 as a bug is only
 > observable with particular geometries of the emacs X11 window. On my
 > machine, 19901 is reproducible if emacs takes up my whole screen
 > (1440x1050), but not if it takes only half (720x1050). Presumably emacs
 > thinks that splitting into a 3rd window will create new windows that are
 > too narrow. That is all to say that maybe 19901 is not a bug.

I have no problems with Bug#19901.  Let's care only about Bug#20206
here.

martin
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -6371,6 +6371,10 @@ Recognized alist entries include:
                       window that already displays the buffer.
                       See `display-buffer-reuse-window'.
 
+ `previous-window' -- A window `display-buffer-in-previous-window'
+                      should use or nil to not try finding such a
+                      window.
+
  `pop-up-frame-parameters' -- Value specifies an alist of frame
                               parameters to give a new frame, if
                               one is created.
@@ -6678,43 +6682,47 @@ selected frame if `display-buffer-reuse-frames' and
 `pop-up-frames' are both nil; search all frames on the current
 terminal if either of those variables is non-nil.
 
-If ALIST has a `previous-window' entry, the window specified by
-that entry will override any other window found by the methods
-above, even if that window never showed BUFFER before."
-  (let* ((alist-entry (assq 'reusable-frames alist))
-	 (inhibit-same-window
-	  (cdr (assq 'inhibit-same-window alist)))
-	 (frames (cond
-		  (alist-entry (cdr alist-entry))
-		  ((if (eq pop-up-frames 'graphic-only)
-		       (display-graphic-p)
-		     pop-up-frames)
-		   0)
-		  (display-buffer-reuse-frames 0)
-		  (t (last-nonminibuffer-frame))))
-	 best-window second-best-window window)
-    ;; Scan windows whether they have shown the buffer recently.
-    (catch 'best
-      (dolist (window (window-list-1 (frame-first-window) 'nomini frames))
-	(when (and (assq buffer (window-prev-buffers window))
-		   (not (window-dedicated-p window)))
-	  (if (eq window (selected-window))
-	      (unless inhibit-same-window
-		(setq second-best-window window))
-	    (setq best-window window)
-	    (throw 'best t)))))
-    ;; When ALIST has a `previous-window' entry, that entry may override
-    ;; anything we found so far.
-    (when (and (setq window (cdr (assq 'previous-window alist)))
-	       (window-live-p window)
-	       (not (window-dedicated-p window)))
-      (if (eq window (selected-window))
-	  (unless inhibit-same-window
-	    (setq second-best-window window))
-	(setq best-window window)))
-    ;; Return best or second best window found.
-    (when (setq window (or best-window second-best-window))
-      (window--display-buffer buffer window 'reuse alist))))
+If ALIST has a `previous-window' entry, the window specified in
+the cdr of that entry will override any other window found by the
+methods above, even if that window never showed BUFFER before.
+If the cdr of that entry is nil, do not try to find a window that
+previously showed BUFFER."
+  (unless (let ((previous-window (assq 'previous-window alist)))
+	    (and previous-window (not (cdr previous-window))))
+    (let* ((alist-entry (assq 'reusable-frames alist))
+	   (inhibit-same-window
+	    (cdr (assq 'inhibit-same-window alist)))
+	   (frames (cond
+		    (alist-entry (cdr alist-entry))
+		    ((if (eq pop-up-frames 'graphic-only)
+			 (display-graphic-p)
+		       pop-up-frames)
+		     0)
+		    (display-buffer-reuse-frames 0)
+		    (t (last-nonminibuffer-frame))))
+	   best-window second-best-window window)
+      ;; Scan windows whether they have shown the buffer recently.
+      (catch 'best
+	(dolist (window (window-list-1 (frame-first-window) 'nomini frames))
+	  (when (and (assq buffer (window-prev-buffers window))
+		     (not (window-dedicated-p window)))
+	    (if (eq window (selected-window))
+		(unless inhibit-same-window
+		  (setq second-best-window window))
+	      (setq best-window window)
+	      (throw 'best t)))))
+      ;; When ALIST has a `previous-window' entry, that entry may override
+      ;; anything we found so far.
+      (when (and (setq window (cdr (assq 'previous-window alist)))
+		 (window-live-p window)
+		 (not (window-dedicated-p window)))
+	(if (eq window (selected-window))
+	    (unless inhibit-same-window
+	      (setq second-best-window window))
+	  (setq best-window window)))
+      ;; Return best or second best window found.
+      (when (setq window (or best-window second-best-window))
+	(window--display-buffer buffer window 'reuse alist)))))
 
 (defun display-buffer-use-some-window (buffer alist)
   "Display BUFFER in an existing window.