Subject: bug#32790: 27.0.50; point jumps unexpectedly after delete-window

From: Juri Linkov <[email-masked]>
Date: Sun, 25 Nov 2018 23:01:34 +0200

> -     ((eq buffer (window-buffer)))
> +     ((and (eq buffer (window-buffer))
> +           (not switch-to-buffer-pop-to)))
>
> This would show the buffer twice even when it already appears in the
> same window, right?  Are you sure that this is TRT?  Unconditionally?

This change is intentional.  If the user requests to display the same
buffer in another window, we have to follow user's request - it's
a normal wish to display the same buffer in two different windows.

> BTW your patch does not apply here well due to some whitespace
> mismatches.

Sorry, I created the previous patch ignoring whitespace changes, so it
would be easier for you to see differences.  But now it should apply
properly with this new patch that takes into account all your comments:

diff --git a/lisp/window.el b/lisp/window.el
index 43a742b2d8..60daa9f070 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7779,6 +7779,13 @@ switch-to-buffer-in-dedicated-window
   :group 'windows
   :version "25.1")
 
+(defcustom switch-to-buffer-pop nil
+  "If non-nil, have `switch-to-buffer' run `pop-to-buffer-same-window'.
+This allows customization of actions for `display-buffer'."
+  :type 'boolean
+  :group 'windows
+  :version "27.1")
+
 (defun switch-to-buffer (buffer-or-name &optional norecord force-same-window)
   "Display buffer BUFFER-OR-NAME in the selected window.
 
@@ -7820,29 +7827,32 @@ switch-to-buffer
 Return the buffer switched to."
   (interactive
    (let ((force-same-window
-          (cond
-           ((window-minibuffer-p) nil)
-           ((not (eq (window-dedicated-p) t)) 'force-same-window)
-           ((pcase switch-to-buffer-in-dedicated-window
-              (`nil (user-error
-                     "Cannot switch buffers in a dedicated window"))
-              (`prompt
-               (if (y-or-n-p
-                    (format "Window is dedicated to %s; undedicate it"
-                            (window-buffer)))
-                   (progn
-                     (set-window-dedicated-p nil nil)
-                     'force-same-window)
-                 (user-error
-                  "Cannot switch buffers in a dedicated window")))
-              (`pop nil)
-              (_ (set-window-dedicated-p nil nil) 'force-same-window))))))
+          (unless switch-to-buffer-pop
+            (cond
+             ((window-minibuffer-p) nil)
+             ((not (eq (window-dedicated-p) t)) 'force-same-window)
+             ((pcase switch-to-buffer-in-dedicated-window
+                (`nil (user-error
+                       "Cannot switch buffers in a dedicated window"))
+                (`prompt
+                 (if (y-or-n-p
+                      (format "Window is dedicated to %s; undedicate it"
+                              (window-buffer)))
+                     (progn
+                       (set-window-dedicated-p nil nil)
+                       'force-same-window)
+                   (user-error
+                    "Cannot switch buffers in a dedicated window")))
+                (`pop nil)
+                (_ (set-window-dedicated-p nil nil) 'force-same-window)))))))
      (list (read-buffer-to-switch "Switch to buffer: ") nil force-same-window)))
-  (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
+  (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name))
+        (set-window-start-and-point (not switch-to-buffer-pop)))
     (cond
      ;; Don't call set-window-buffer if it's not needed since it
      ;; might signal an error (e.g. if the window is dedicated).
-     ((eq buffer (window-buffer)))
+     ((and (eq buffer (window-buffer))
+           (not switch-to-buffer-pop)))
      ((window-minibuffer-p)
       (if force-same-window
           (user-error "Cannot switch buffers in minibuffer window")
@@ -7852,18 +7862,25 @@ switch-to-buffer
           (user-error "Cannot switch buffers in a dedicated window")
         (pop-to-buffer buffer norecord)))
      (t
-      (let* ((entry (assq buffer (window-prev-buffers)))
-	     (displayed (and (eq switch-to-buffer-preserve-window-point
-				 'already-displayed)
-			     (get-buffer-window buffer 0))))
-	(set-window-buffer nil buffer)
-	(when (and entry
-		   (or (eq switch-to-buffer-preserve-window-point t)
-		       displayed))
-	  ;; Try to restore start and point of buffer in the selected
-	  ;; window (Bug#4041).
-	  (set-window-start (selected-window) (nth 1 entry) t)
-	  (set-window-point nil (nth 2 entry))))))
+      (when switch-to-buffer-pop
+        (let ((selected-window (selected-window)))
+          (pop-to-buffer-same-window buffer norecord)
+          (when (eq (selected-window) selected-window)
+            (setq set-window-start-and-point t))))
+
+      (when set-window-start-and-point
+        (let* ((entry (assq buffer (window-prev-buffers)))
+	       (displayed (and (eq switch-to-buffer-preserve-window-point
+				   'already-displayed)
+			       (get-buffer-window buffer 0))))
+	  (set-window-buffer nil buffer)
+	  (when (and entry
+		     (or (eq switch-to-buffer-preserve-window-point t)
+		         displayed))
+	    ;; Try to restore start and point of buffer in the selected
+	    ;; window (Bug#4041).
+	    (set-window-start (selected-window) (nth 1 entry) t)
+	    (set-window-point nil (nth 2 entry)))))))
 
     (unless norecord
       (select-window (selected-window)))