]> git.eshelyaron.com Git - emacs.git/commitdiff
Split default-buffer-default into separate display action components.
authorChong Yidong <cyd@stupidchicken.com>
Fri, 2 Sep 2011 02:23:43 +0000 (22:23 -0400)
committerChong Yidong <cyd@stupidchicken.com>
Fri, 2 Sep 2011 02:23:43 +0000 (22:23 -0400)
* lisp/window.el (display-buffer-alist): Doc fix.
(display-buffer): Add docstring.  Don't treat display-buffer-default specially.
(display-buffer-reuse-selected-window)
(display-buffer-same-window, display-buffer-maybe-same-window)
(display-buffer-reuse-window, display-buffer-pop-up-frame)
(display-buffer-pop-up-window)
(display-buffer-reuse-or-pop-window)
(display-buffer-use-some-window): New functions.
(display-buffer-default-action): Use them.
(display-buffer-default): Deleted.
(pop-to-buffer-1): Fix choice of actions.

lisp/ChangeLog
lisp/window.el

index a7d2083f4b1327a31598c1ceb1622c994116f902..7ea1dffe1c275d097bec10a6643e25662a9a3b09 100644 (file)
@@ -1,3 +1,18 @@
+2011-09-02  Chong Yidong  <cyd@stupidchicken.com>
+
+       * window.el (display-buffer-alist): Doc fix.
+       (display-buffer): Add docstring.  Don't treat
+       display-buffer-default specially.
+       (display-buffer-reuse-selected-window)
+       (display-buffer-same-window, display-buffer-maybe-same-window)
+       (display-buffer-reuse-window, display-buffer-pop-up-frame)
+       (display-buffer-pop-up-window)
+       (display-buffer-reuse-or-pop-window)
+       (display-buffer-use-some-window): New functions.
+       (display-buffer-default-action): Use them.
+       (display-buffer-default): Deleted.
+       (pop-to-buffer-1): Fix choice of actions.
+
 2011-09-02  Stefan Monnier  <monnier@iro.umontreal.ca>
 
        * minibuffer.el (completion--insert-strings): Don't get confused by
index 277b1fd5c092cec0a622831001efaa6af8c40a23..b33c46acf93821a25555a8dea3d5a99bae11a424 100644 (file)
@@ -4478,155 +4478,6 @@ Return WINDOW."
 The actual non-nil value of this variable will be copied to the
 `window-dedicated-p' flag.")
 
-(defun display-buffer-default (buffer-or-name &optional not-this-window frame)
-  "Make buffer BUFFER-OR-NAME appear in some window but don't select it.
-BUFFER-OR-NAME must be a buffer or the name of an existing
-buffer.  Return the window chosen to display BUFFER-OR-NAME or
-nil if no such window is found.
-
-Optional argument NOT-THIS-WINDOW non-nil means display the
-buffer in a window other than the selected one, even if it is
-already displayed in the selected window.
-
-Optional argument FRAME specifies which frames to investigate
-when the specified buffer is already displayed.  If the buffer is
-already displayed in some window on one of these frames simply
-return that window.  Possible values of FRAME are:
-
-`visible' - consider windows on all visible frames on the current
-terminal.
-
-0 - consider windows on all visible or iconified frames on the
-current terminal.
-
-t - consider windows on all frames.
-
-A specific frame - consider windows on that frame only.
-
-nil - consider windows on the selected frame \(actually the
-last non-minibuffer frame\) only.  If, however, either
-`display-buffer-reuse-frames' or `pop-up-frames' is non-nil
-\(non-nil and not graphic-only on a text-only terminal),
-consider all visible or iconified frames on the current terminal."
-  (interactive "BDisplay buffer:\nP")
-  (let* ((can-use-selected-window
-         ;; The selected window is usable unless either NOT-THIS-WINDOW
-         ;; is non-nil, it is dedicated to its buffer, or it is the
-         ;; `minibuffer-window'.
-         (not (or not-this-window
-                  (window-dedicated-p (selected-window))
-                  (window-minibuffer-p))))
-        (buffer (if (bufferp buffer-or-name)
-                    buffer-or-name
-                  (get-buffer buffer-or-name)))
-        (name-of-buffer (buffer-name buffer))
-        ;; On text-only terminals do not pop up a new frame when
-        ;; `pop-up-frames' equals graphic-only.
-        (use-pop-up-frames (if (eq pop-up-frames 'graphic-only)
-                               (display-graphic-p)
-                             pop-up-frames))
-        ;; `frame-to-use' is the frame where to show `buffer' - either
-        ;; the selected frame or the last nonminibuffer frame.
-        (frame-to-use
-         (or (window--frame-usable-p (selected-frame))
-             (window--frame-usable-p (last-nonminibuffer-frame))))
-        ;; `window-to-use' is the window we use for showing `buffer'.
-        window-to-use popped-up-frame)
-    (cond
-     ((not (buffer-live-p buffer))
-      (error "No such buffer %s" buffer))
-     (display-buffer-function
-      ;; Let `display-buffer-function' do the job.
-      (funcall display-buffer-function buffer not-this-window))
-     ((and (not not-this-window)
-          (eq (window-buffer (selected-window)) buffer))
-      ;; The selected window already displays BUFFER and
-      ;; `not-this-window' is nil, so use it.
-      (display-buffer-record-window 'reuse-window (selected-window) buffer)
-      (window--display-buffer-1 (selected-window)))
-     ((and can-use-selected-window (same-window-p name-of-buffer))
-      ;; If the buffer's name tells us to use the selected window do so.
-      (display-buffer-record-window 'reuse-window (selected-window) buffer)
-      (window--display-buffer-2 buffer (selected-window)))
-     ((let ((frames (or frame
-                       (and (or use-pop-up-frames
-                                display-buffer-reuse-frames
-                                (not (last-nonminibuffer-frame)))
-                            0)
-                       (last-nonminibuffer-frame))))
-       (setq window-to-use
-             (catch 'found
-               ;; Search frames for a window displaying BUFFER.  Return
-               ;; the selected window only if we are allowed to do so.
-               (dolist (window (get-buffer-window-list buffer 'nomini frames))
-                 (when (or can-use-selected-window
-                           (not (eq (selected-window) window)))
-                   (throw 'found window))))))
-      ;; The buffer is already displayed in some window; use that.
-      (display-buffer-record-window 'reuse-window window-to-use buffer)
-      (window--display-buffer-1 window-to-use))
-     ((and special-display-function
-          ;; `special-display-p' returns either t or a list of frame
-          ;; parameters to pass to `special-display-function'.
-          (let ((pars (special-display-p name-of-buffer)))
-            (when pars
-              (funcall special-display-function
-                       buffer (if (listp pars) pars))))))
-     ((or use-pop-up-frames (not frame-to-use))
-      ;; We want or need a new frame.
-      (setq window-to-use
-           (frame-selected-window (funcall pop-up-frame-function)))
-      (display-buffer-record-window 'pop-up-frame window-to-use buffer)
-      (window--display-buffer-2 buffer window-to-use))
-     ((and pop-up-windows
-          ;; Make a new window.
-          (or (not (frame-parameter frame-to-use 'unsplittable))
-              ;; If the selected frame cannot be split look at
-              ;; `last-nonminibuffer-frame'.
-              (and (eq frame-to-use (selected-frame))
-                   (setq frame-to-use (last-nonminibuffer-frame))
-                   (window--frame-usable-p frame-to-use)
-                   (not (frame-parameter frame-to-use 'unsplittable))))
-          ;; Attempt to split largest or least recently used window.
-          (setq window-to-use
-                (or (window--try-to-split-window
-                     (get-largest-window frame-to-use t))
-                    (window--try-to-split-window
-                     (get-lru-window frame-to-use t))))
-          (display-buffer-record-window 'pop-up-window window-to-use buffer)
-          (window--display-buffer-2 buffer window-to-use)))
-     ((let ((window-to-undedicate
-            ;; When NOT-THIS-WINDOW is non-nil, temporarily dedicate
-            ;; the selected window to its buffer, to avoid that some of
-            ;; the `get-' routines below choose it.  (Bug#1415)
-            (and not-this-window (not (window-dedicated-p))
-                 (set-window-dedicated-p (selected-window) t)
-                 (selected-window))))
-       (unwind-protect
-           (setq window-to-use
-                 ;; Reuse an existing window.
-                 (or (get-lru-window frame-to-use)
-                     (let ((window (get-buffer-window buffer 'visible)))
-                       (unless (and not-this-window
-                                    (eq window (selected-window)))
-                         window))
-                     (get-largest-window 'visible)
-                     (let ((window (get-buffer-window buffer 0)))
-                       (unless (and not-this-window
-                                    (eq window (selected-window)))
-                         window))
-                     (get-largest-window 0)
-                     (prog1
-                         (frame-selected-window (funcall pop-up-frame-function))
-                       (setq popped-up-frame t))))
-         (when (window-live-p window-to-undedicate)
-           ;; Restore dedicated status of selected window.
-           (set-window-dedicated-p window-to-undedicate nil))))
-      (display-buffer-record-window
-       (if popped-up-frame 'pop-up-frame 'reuse-window) window-to-use buffer)
-      (window--even-window-heights window-to-use)
-      (window--display-buffer-2 buffer window-to-use)))))
-
 (defun window-normalize-buffer-to-display (buffer-or-name)
   "Normalize BUFFER-OR-NAME argument for buffer display functions.
 If BUFFER-OR-NAME is nil, return the curent buffer.  Else, if a
@@ -4641,24 +4492,52 @@ BUFFER-OR-NAME and return that buffer."
     (current-buffer)))
 
 (defvar display-buffer-alist nil
-  "Specifications of user preferences for `display-buffer'.
-This is a list of elements of the form (CONDITION . ACTION) where
-CONDITION is either a regexp matching buffer names, or a function
-that takes a buffer and returns a boolean.  ACTION is a list of
-the form (FUNCTION . ALIST) where FUNCTION can be either a
-function or a list of functions.  Those functions will be called
-with 2 arguments: the buffer to display and an ALIST built from
-the various alists specified in the various ACTIONs.  It should
-either return the window used, or nil to fallback to the next
-function.")
-
-(defvar display-buffer-default-action (list #'display-buffer-default)
-  "Default action to perform to display a buffer.
-This is an ACTION just like in `display-buffer-alist'.")
-
-(defvar display-buffer-overriding-action '(nil)
+  "Alist of conditional actions for `display-buffer'.
+This is a list of elements (CONDITION . ACTION), where:
+
+ CONDITION is either a regexp matching buffer names, or a function
+  that takes a buffer and returns a boolean.
+
+ ACTION is a cons cell (FUNCTION . ALIST), where FUNCTION is
+  either a function or a list of functions.  Each such function
+  should accept 2 arguments: a buffer to display and an alist of
+  the same form as ALIST.  It should return the window used, or
+  nil if it fails to display the window.  See `display-buffer'
+  for more details.
+
+Usable action functions include:
+ `display-buffer-reuse-selected-window'
+ `display-buffer-same-window'
+ `display-buffer-maybe-same-window'
+ `display-buffer-reuse-window'
+ `display-buffer-pop-up-frame'
+ `display-buffer-pop-up-window'
+ `display-buffer-reuse-or-pop-window'
+ `display-buffer-use-some-window'
+
+The above functions recognize the following alist entries:
+ - `inhibit-same-window', if non-nil, prevents the same window
+   from being used for display.
+ - `reuse-frame' specifies the frames that can be searched for a
+   window displaying the buffer.  Its values have the same
+   meaning as the ALL-FRAMES arg to `get-buffer-window-list'.")
+
+(defvar display-buffer-default-action
+  '((display-buffer-reuse-selected-window
+     display-buffer-maybe-same-window
+     display-buffer-reuse-or-pop-window
+     display-buffer-use-some-window
+     ;; If all else fails, pop up a new frame regardless of
+     ;; restrictions.
+     display-buffer-pop-up-frame))
+  "List of default actions for `display-buffer'.
+It should be a cons cell of the form (FUNCTION . ALIST), which
+has the same meaning as in `display-buffer-alist'.")
+
+(defvar display-buffer-overriding-action nil
   "Overriding action to perform to display a buffer.
-This is an ACTION just like in `display-buffer-alist'.")
+If non-nil, it should be a cons cell (FUNCTION . ALIST), which
+has the same meaning as in `display-buffer-alist'.")
 
 (defun display-buffer-assq-regexp (buffer-name alist)
   "Retrieve ALIST entry corresponding to BUFFER-NAME."
@@ -4673,46 +4552,72 @@ This is an ACTION just like in `display-buffer-alist'.")
          (throw 'match (cdr entry)))))))
 
 (defun display-buffer (&optional buffer-or-name action frame)
-  "Display BUFFER in some window."
+  "Display BUFFER-OR-NAME in some window.
+BUFFER-OR-NAME must be a buffer or the name of an existing
+buffer.  Return the window chosen for displaying BUFFER-OR-NAME,
+or nil if no such window is found.
+
+Optional argument ACTION should have the form (FUNCTION . ALIST).
+FUNCTION is either a function or a list of functions.  Each such
+function is called with 2 arguments: the buffer to display and an
+alist.  It should either display the buffer and return the
+window, or return nil if it is unable to display the buffer.
+
+`display-buffer' constructs a list of action functions and an
+action alist from `display-buffer-overriding-action',
+`user-action', ACTION, and `display-buffer-default-action' (in
+order).  It calls each action function in turn, passing the
+consolidated action alist as the second argument, until one of
+the functions returns non-nil.
+
+ACTION can also have a non-nil and non-list value.  This means to
+display the buffer in a window other than the selected one, even
+if it is already displayed in the selected window.  If called
+interactively with a prefix argument, ACTION is t.
+
+Optional argument FRAME specifies where to look for a window that
+already displays the buffer.  If nil, check only the selected
+frame (actually the last non-minibuffer frame), except if
+`display-buffer-reuse-frames' or `pop-up-frames' is non-nil
+\(non-nil and not graphic-only on a text-only terminal), in which
+case check all visible or iconified frames.  Otherwise, FRAME can
+be a specific frame, `visible' (all visible frames), 0 (all
+frames on the current terminal), or t (all frames)."
   (interactive "BDisplay buffer:\nP")
-  (let* ((buffer (window-normalize-buffer-to-display buffer-or-name))
-        (buffer-name (buffer-name buffer))
-        (user-action
-         (display-buffer-assq-regexp buffer-name display-buffer-alist))
-        (functions
-         (append
-          (list (car display-buffer-overriding-action))
-          (list (car user-action))
-          (and (listp action) (list (car action)))
-          (list (car display-buffer-default-action))))
-        (specifiers (append (cdr display-buffer-overriding-action)
-                            (cdr user-action)
-                            (and (listp action) (cdr action))
-                            (cdr display-buffer-default-action)))
-        function window)
-    (while (and functions (not window))
-      (setq function (car functions))
-      (cond
-       ((listp function)
-       (while (and function (not window))
-         (cond
-          ((eq (car function) 'display-buffer-default)
-           (setq window
-                 (display-buffer-default
-                  buffer (memq action '(t other-window)) frame)))
-          ((functionp (car function))
-           (setq window (funcall (car function) buffer specifiers))))
-         (setq function (cdr function))))
-       ((eq function 'display-buffer-default)
-       (setq window
-             (display-buffer-default
-              buffer (memq action '(t other-window)) frame)))
-       ((functionp function)
-       (setq window
-             (funcall function buffer specifiers))))
-      (setq functions (cdr functions)))
-
-    window))
+  (let ((buffer (window-normalize-buffer-to-display buffer-or-name))
+       ;; Handle the old form of the first argument.
+       (inhibit-same-window (and action (not (listp action)))))
+    (unless (listp action) (setq action nil))
+    (if display-buffer-function
+       ;; If `display-buffer-function' is defined, let it do the job.
+       (funcall display-buffer-function buffer inhibit-same-window)
+      ;; Otherwise, use the defined actions.
+      (let* ((user-action
+             (display-buffer-assq-regexp (buffer-name buffer)
+                                         display-buffer-alist))
+            ;; Extra actions from the arguments to this function:
+            (extra-action
+             (cons nil (append (if inhibit-same-window
+                                   '((inhibit-same-window . t)))
+                               (if frame
+                                   `((reuse-frame . ,frame))))))
+            ;; Construct action function list and action alist.
+            (actions (list display-buffer-overriding-action
+                           user-action action extra-action
+                           display-buffer-default-action))
+            (functions (apply 'append
+                              (mapcar (lambda (x)
+                                        (setq x (car x))
+                                        (if (listp x) x (list x)))
+                                      actions)))
+            (alist (apply 'append (mapcar 'cdr actions)))
+            window)
+       (unless (buffer-live-p buffer)
+         (error "Invalid buffer"))
+       (while (and functions (not window))
+         (setq window (funcall (car functions) buffer alist)
+               functions (cdr functions)))
+       window))))
 
 (defun display-buffer-other-frame (buffer)
   "Display buffer BUFFER in another frame.
@@ -4737,24 +4642,182 @@ its documentation for additional customization information."
     ;;(make-frame-visible (window-frame old-window))
     ))
 
-;;; Functions for use via `display-buffer-alist'.
+;;; `display-buffer' action functions:
 
-(defun display-buffer-same-window (buffer alist)
-  "Display BUFFER in the selected window, and return the window.
-If BUFFER cannot be displayed in the selected window (usually
-because it is dedicated to another buffer), return nil."
-  (let ((norecord (cadr (assq 'norecord alist))))
-    (cond
-     ((eq buffer (window-buffer))
-      (selected-window))
-     ((not (or (window-minibuffer-p) (window-dedicated-p)))
-      (set-window-buffer nil buffer)
-      (selected-window)))))
+(defun display-buffer-reuse-selected-window (buffer alist)
+  "Try to display BUFFER in the selected window if it is already there.
+If this succeeds, return the selected window.
 
-(defun display-buffer-other-window (buffer alist)
-  "Display BUFFER in another window, and return BUFFER.
-If BUFFER cannot be displayed in another window, just return nil."
-  (display-buffer-default buffer t))
+This fails if BUFFER is not displayed in the selected window, or
+if ALIST has a non-nil `inhibit-same-window' entry.  In that
+case, return nil."
+  (when (and (not (cdr (assq 'inhibit-same-window alist)))
+            (eq buffer (window-buffer)))
+    (display-buffer-record-window 'reuse-window (selected-window) buffer)
+    (window--display-buffer-1 (selected-window))))
+
+(defun display-buffer-same-window (buffer alist)
+  "Try to display BUFFER in the selected window.
+If this succeeds, return the selected window.
+
+This fails if the selected window is a minibuffer window or is
+dedicated to another buffer, or if ALIST has a non-nil
+`inhibit-same-window' entry.  In that case, return nil."
+  (unless (or (cdr (assq 'inhibit-same-window alist))
+             (window-minibuffer-p)
+             (window-dedicated-p))
+    (display-buffer-record-window 'reuse-window (selected-window) buffer)
+    (window--display-buffer-2 buffer (selected-window))))
+
+(defun display-buffer-maybe-same-window (buffer alist)
+  "Try to display BUFFER in the selected window.
+This acts like `display-buffer-same-window', except that it also
+fails if `same-window-p' returns nil for this buffer."
+  (and (same-window-p (buffer-name buffer))
+       (display-buffer-same-window buffer alist)))
+
+(defun display-buffer-reuse-window (buffer alist)
+  "Return a window that is already displaying BUFFER.
+If no usable window is found, return nil.
+
+If ALIST has a non-nil `inhibit-same-window' entry, the same
+window cannot be reused.
+
+If ALIST contains a `reuse-frame' entry, that determines the
+frames to check for a window displaying the buffer.  If the entry
+is omitted or the value is nil, check only this frame.  The value
+can also be a specific frame, `visible' (all visible frames),
+0 (all frames on the current terminal), or t (all frames)."
+  (let* ((can-use-selected-window
+         (not (cdr (assq 'inhibit-same-window alist))))
+        (frames (or (cdr (assq 'reuse-frame alist))
+                    (last-nonminibuffer-frame)))
+        (window (catch 'found
+                  (dolist (window (get-buffer-window-list
+                                   buffer 'nomini frames))
+                    (when (or can-use-selected-window
+                              (not (eq (selected-window) window)))
+                      (throw 'found window))))))
+    (when window
+      (display-buffer-record-window 'reuse-window window buffer)
+      (window--display-buffer-1 window))))
+
+(defun display-buffer-pop-up-frame (buffer alist)
+  "Display BUFFER in a new frame.
+This works by calling `pop-up-frame-function'.  If sucessful,
+return the window on the new frame; otherwise return nil."
+  (let ((fun pop-up-frame-function)
+       frame window)
+    (when (and fun
+              (setq frame (funcall fun))
+              (setq window (frame-selected-window frame)))
+      (display-buffer-record-window 'pop-up-frame window buffer)
+      (window--display-buffer-2 buffer window))))
+
+(defun display-buffer-pop-up-window (buffer alist)
+  "Display BUFFER by popping up a new window.
+The new window is created on the selected frame, or in
+`last-nonminibuffer-frame' if no windows can be created there.
+If sucessful, return the new window; otherwise return nil."
+  (let ((frame (or (window--frame-usable-p (selected-frame))
+                  (window--frame-usable-p (last-nonminibuffer-frame))))
+       window)
+    (when (and (or (not (frame-parameter frame 'unsplittable))
+                  ;; If the selected frame cannot be split, look at
+                  ;; `last-nonminibuffer-frame'.
+                  (and (eq frame (selected-frame))
+                       (setq frame (last-nonminibuffer-frame))
+                       (window--frame-usable-p frame)
+                       (not (frame-parameter frame 'unsplittable))))
+              ;; Attempt to split largest or least recently used window.
+              (setq window (or (window--try-to-split-window
+                                (get-largest-window frame t))
+                               (window--try-to-split-window
+                                (get-lru-window frame t)))))
+      (display-buffer-record-window 'pop-up-window window buffer)
+      (window--display-buffer-2 buffer window))))
+
+;; This display action function groups together some lower-level ones:
+(defun display-buffer-reuse-or-pop-window (buffer alist)
+  "Display BUFFER in some window other than the selected one.
+This attempts to call the following functions (in order):
+ - `display-buffer-reuse-window', ensuring that it checks all
+   frames on this terminal if `display-buffer-reuse-frames' or
+   `pop-up-frames' is non-nil.
+ - `special-display-function', if it is available.
+ - `display-buffer-pop-up-frame', if specified by `pop-up-frames'.
+ - `display-buffer-pop-up-window', if specified by `pop-up-windows'.
+
+If BUFFER is sucessfully display, return its window; otherwise
+return nil."
+  (let ((use-pop-up-frames (if (eq pop-up-frames 'graphic-only)
+                              (display-graphic-p)
+                            pop-up-frames)))
+    (or (display-buffer-reuse-window
+        buffer
+        ;; If `display-buffer-reuse-frames' or `pop-up-frames' is
+        ;; non-nil, check all frames on this terminal.
+        (if (and (null (cdr (assq 'reuse-frame alist)))
+                 (or use-pop-up-frames display-buffer-reuse-frames))
+            (cons '(reuse-frame . 0) alist)
+          alist))
+       ;; Try with `special-display-function':
+       (and special-display-function
+            ;; `special-display-p' returns either t or a list of frame
+            ;; parameters to pass to `special-display-function'.
+            (let ((pars (special-display-p (buffer-name buffer))))
+              (when pars
+                (funcall special-display-function
+                         buffer (if (listp pars) pars)))))
+       (and use-pop-up-frames
+            (display-buffer-pop-up-frame buffer alist))
+       (and pop-up-windows
+            (display-buffer-pop-up-window buffer alist)))))
+
+(defun display-buffer-use-some-window (buffer alist)
+  "Display BUFFER in an existing window.
+Search for a usable window, set that window to the buffer, and
+return the window.  If no suitable window is found, return nil."
+  (let* ((not-this-window (cdr (assq 'inhibit-same-window alist)))
+        (window-to-undedicate
+         ;; When NOT-THIS-WINDOW is non-nil, temporarily dedicate the
+         ;; selected window to its buffer, to prevent any of the
+         ;; `get-' routines below from choosing it.  (Bug#1415)
+         (and not-this-window (not (window-dedicated-p))
+              (set-window-dedicated-p (selected-window) t)
+              (selected-window)))
+        (frame (or (window--frame-usable-p (selected-frame))
+                   (window--frame-usable-p (last-nonminibuffer-frame))))
+        (use-pop-up-frames (if (eq pop-up-frames 'graphic-only)
+                               (display-graphic-p)
+                             pop-up-frames))
+        window popped-up-frame)
+    (unwind-protect
+       (setq window
+             ;; Reuse an existing window.
+             (or (get-lru-window frame)
+                 (let ((window (get-buffer-window buffer 'visible)))
+                   (unless (and not-this-window
+                                (eq window (selected-window)))
+                     window))
+                 (get-largest-window 'visible)
+                 (let ((window (get-buffer-window buffer 0)))
+                   (unless (and not-this-window
+                                (eq window (selected-window)))
+                     window))
+                 (get-largest-window 0)
+                 (and use-pop-up-frames
+                      (prog1
+                          (frame-selected-window (funcall pop-up-frame-function))
+                        (setq popped-up-frame t)))))
+      (when (window-live-p window-to-undedicate)
+       ;; Restore dedicated status of selected window.
+       (set-window-dedicated-p window-to-undedicate nil)))
+    (when window
+      (display-buffer-record-window
+       (if popped-up-frame 'pop-up-frame 'reuse-window) window buffer)
+      (window--even-window-heights window)
+      (window--display-buffer-2 buffer window))))
 
 ;;; Display + selection commands:
 
@@ -4808,12 +4871,11 @@ for `pop-to-buffer'."
            ;; Based on the WINDOW-CHOICE argument, choose an action
            ;; argument to pass to `display-buffer'.
            (cond
-            ((null window-choice)
-             '((display-buffer-other-window display-buffer-same-window)))
             ((eq window-choice 'same-window)
-             '((display-buffer-same-window display-buffer-other-window)))
-            (t
-             '((display-buffer-other-window)))))
+             '((display-buffer-reuse-selected-window
+                display-buffer-same-window)))
+            (window-choice
+             '(nil (inhibit-same-window . t)))))
           (window (display-buffer (current-buffer) action))
           (frame (window-frame window)))
       (if (eq frame old-frame)