+(defcustom display-buffer-function nil
+ "If non-nil, function to call to handle `display-buffer'.
+It will receive two args, the buffer and a flag which if non-nil
+means that the currently selected window is not acceptable. It
+should choose or create a window, display the specified buffer in
+it, and return the window.
+
+Commands such as `switch-to-buffer-other-window' and
+`find-file-other-window' work using this function."
+ :type '(choice
+ (const nil)
+ (function :tag "function"))
+ :group 'windows)
+
+(defcustom special-display-buffer-names nil
+ "List of names of buffers that should be displayed specially.
+Displaying a buffer with `display-buffer' or `pop-to-buffer', if
+its name is in this list, displays the buffer in a way specified
+by `special-display-function'. `special-display-popup-frame'
+\(the default for `special-display-function') usually displays
+the buffer in a separate frame made with the parameters specified
+by `special-display-frame-alist'. If `special-display-function'
+has been set to some other function, that function is called with
+the buffer as first, and nil as second argument.
+
+Alternatively, an element of this list can be specified as
+\(BUFFER-NAME FRAME-PARAMETERS), where BUFFER-NAME is a buffer
+name and FRAME-PARAMETERS an alist of \(PARAMETER . VALUE) pairs.
+`special-display-popup-frame' will interpret such pairs as frame
+parameters when it creates a special frame, overriding the
+corresponding values from `special-display-frame-alist'.
+
+As a special case, if FRAME-PARAMETERS contains (same-window . t)
+`special-display-popup-frame' displays that buffer in the
+selected window. If FRAME-PARAMETERS contains (same-frame . t),
+it displays that buffer in a window on the selected frame.
+
+If `special-display-function' specifies some other function than
+`special-display-popup-frame', that function is called with the
+buffer named BUFFER-NAME as first, and FRAME-PARAMETERS as second
+argument.
+
+Finally, an element of this list can be also specified as
+\(BUFFER-NAME FUNCTION OTHER-ARGS). In that case,
+`special-display-popup-frame' will call FUNCTION with the buffer
+named BUFFER-NAME as first argument, and OTHER-ARGS as the
+second. If `special-display-function' specifies some other
+function, that function is called with the buffer named
+BUFFER-NAME as first, and the element's cdr as second argument.
+
+If this variable appears \"not to work\", because you added a
+name to it but the corresponding buffer is displayed in the
+selected window, look at the values of `same-window-buffer-names'
+and `same-window-regexps'. Those variables take precedence over
+this one.
+
+See also `special-display-regexps'."
+ :type '(repeat
+ (choice :tag "Buffer"
+ :value ""
+ (string :format "%v")
+ (cons :tag "With parameters"
+ :format "%v"
+ :value ("" . nil)
+ (string :format "%v")
+ (repeat :tag "Parameters"
+ (cons :format "%v"
+ (symbol :tag "Parameter")
+ (sexp :tag "Value"))))
+ (list :tag "With function"
+ :format "%v"
+ :value ("" . nil)
+ (string :format "%v")
+ (function :tag "Function")
+ (repeat :tag "Arguments" (sexp)))))
+ :group 'windows
+ :group 'frames)
+
+;;;###autoload
+(put 'special-display-buffer-names 'risky-local-variable t)
+
+(defcustom special-display-regexps nil
+ "List of regexps saying which buffers should be displayed specially.
+Displaying a buffer with `display-buffer' or `pop-to-buffer', if
+any regexp in this list matches its name, displays it specially
+using `special-display-function'. `special-display-popup-frame'
+\(the default for `special-display-function') usually displays
+the buffer in a separate frame made with the parameters specified
+by `special-display-frame-alist'. If `special-display-function'
+has been set to some other function, that function is called with
+the buffer as first, and nil as second argument.
+
+Alternatively, an element of this list can be specified as
+\(REGEXP FRAME-PARAMETERS), where REGEXP is a regexp as above and
+FRAME-PARAMETERS an alist of (PARAMETER . VALUE) pairs.
+`special-display-popup-frame' will then interpret these pairs as
+frame parameters when creating a special frame for a buffer whose
+name matches REGEXP, overriding the corresponding values from
+`special-display-frame-alist'.
+
+As a special case, if FRAME-PARAMETERS contains (same-window . t)
+`special-display-popup-frame' displays buffers matching REGEXP in
+the selected window. \(same-frame . t) in FRAME-PARAMETERS means
+to display such buffers in a window on the selected frame.
+
+If `special-display-function' specifies some other function than
+`special-display-popup-frame', that function is called with the
+buffer whose name matched REGEXP as first, and FRAME-PARAMETERS
+as second argument.
+
+Finally, an element of this list can be also specified as
+\(REGEXP FUNCTION OTHER-ARGS). `special-display-popup-frame'
+will then call FUNCTION with the buffer whose name matched
+REGEXP as first, and OTHER-ARGS as second argument. If
+`special-display-function' specifies some other function, that
+function is called with the buffer whose name matched REGEXP
+as first, and the element's cdr as second argument.
+
+If this variable appears \"not to work\", because you added a
+name to it but the corresponding buffer is displayed in the
+selected window, look at the values of `same-window-buffer-names'
+and `same-window-regexps'. Those variables take precedence over
+this one.
+
+See also `special-display-buffer-names'."
+ :type '(repeat
+ (choice :tag "Buffer"
+ :value ""
+ (regexp :format "%v")
+ (cons :tag "With parameters"
+ :format "%v"
+ :value ("" . nil)
+ (regexp :format "%v")
+ (repeat :tag "Parameters"
+ (cons :format "%v"
+ (symbol :tag "Parameter")
+ (sexp :tag "Value"))))
+ (list :tag "With function"
+ :format "%v"
+ :value ("" . nil)
+ (regexp :format "%v")
+ (function :tag "Function")
+ (repeat :tag "Arguments" (sexp)))))
+ :group 'windows
+ :group 'frames)
+
+(defun special-display-p (buffer-name)
+ "Return non-nil if a buffer named BUFFER-NAME gets a special frame.
+More precisely, return t if `special-display-buffer-names' or
+`special-display-regexps' contain a string entry equaling or
+matching BUFFER-NAME. If `special-display-buffer-names' or
+`special-display-regexps' contain a list entry whose car equals
+or matches BUFFER-NAME, the return value is the cdr of that
+entry."
+ (let (tmp)
+ (cond
+ ((not (stringp buffer-name)))
+ ((member buffer-name special-display-buffer-names)
+ t)
+ ((setq tmp (assoc buffer-name special-display-buffer-names))
+ (cdr tmp))
+ ((catch 'found
+ (dolist (regexp special-display-regexps)
+ (cond
+ ((stringp regexp)
+ (when (string-match-p regexp buffer-name)
+ (throw 'found t)))
+ ((and (consp regexp) (stringp (car regexp))
+ (string-match-p (car regexp) buffer-name))
+ (throw 'found (cdr regexp))))))))))
+
+(defcustom special-display-function 'special-display-popup-frame
+ "Function to call for displaying special buffers.
+This function is called with two arguments - the buffer and,
+optionally, a list - and should return a window displaying that
+buffer. The default value usually makes a separate frame for the
+buffer using `special-display-frame-alist' to specify the frame
+parameters. See the definition of `special-display-popup-frame'
+for how to specify such a function.
+
+A buffer is special when its name is either listed in
+`special-display-buffer-names' or matches a regexp in
+`special-display-regexps'."
+ :type 'function
+ :group 'frames)
+
+(defcustom same-window-buffer-names nil
+ "List of names of buffers that should appear in the \"same\" window.
+`display-buffer' and `pop-to-buffer' show a buffer whose name is
+on this list in the selected rather than some other window.
+
+An element of this list can be a cons cell instead of just a
+string. In that case, the cell's car must be a string specifying
+the buffer name. This is for compatibility with
+`special-display-buffer-names'; the cdr of the cons cell is
+ignored.
+
+See also `same-window-regexps'."
+ :type '(repeat (string :format "%v"))
+ :group 'windows)
+
+(defcustom same-window-regexps nil
+ "List of regexps saying which buffers should appear in the \"same\" window.
+`display-buffer' and `pop-to-buffer' show a buffer whose name
+matches a regexp on this list in the selected rather than some
+other window.
+
+An element of this list can be a cons cell instead of just a
+string. In that case, the cell's car must be a regexp matching
+the buffer name. This is for compatibility with
+`special-display-regexps'; the cdr of the cons cell is ignored.
+
+See also `same-window-buffer-names'."
+ :type '(repeat (regexp :format "%v"))
+ :group 'windows)
+
+(defun same-window-p (buffer-name)
+ "Return non-nil if a buffer named BUFFER-NAME would be shown in the \"same\" window.
+This function returns non-nil if `display-buffer' or
+`pop-to-buffer' would show a buffer named BUFFER-NAME in the
+selected rather than \(as usual\) some other window. See
+`same-window-buffer-names' and `same-window-regexps'."
+ (cond
+ ((not (stringp buffer-name)))
+ ;; The elements of `same-window-buffer-names' can be buffer
+ ;; names or cons cells whose cars are buffer names.
+ ((member buffer-name same-window-buffer-names))
+ ((assoc buffer-name same-window-buffer-names))
+ ((catch 'found
+ (dolist (regexp same-window-regexps)
+ ;; The elements of `same-window-regexps' can be regexps
+ ;; or cons cells whose cars are regexps.
+ (when (or (and (stringp regexp)
+ (string-match regexp buffer-name))
+ (and (consp regexp) (stringp (car regexp))
+ (string-match-p (car regexp) buffer-name)))
+ (throw 'found t)))))))
+
+(defcustom pop-up-frames nil
+ "Whether `display-buffer' should make a separate frame.
+If nil, never make a separate frame.
+If the value is `graphic-only', make a separate frame
+on graphic displays only.
+Any other non-nil value means always make a separate frame."
+ :type '(choice
+ (const :tag "Never" nil)
+ (const :tag "On graphic displays only" graphic-only)
+ (const :tag "Always" t))
+ :group 'windows)
+
+(defcustom display-buffer-reuse-frames nil
+ "Non-nil means `display-buffer' should reuse frames.
+If the buffer in question is already displayed in a frame, raise
+that frame."
+ :type 'boolean
+ :version "21.1"
+ :group 'windows)
+
+(defcustom pop-up-windows t
+ "Non-nil means `display-buffer' should make a new window."
+ :type 'boolean
+ :group 'windows)
+
+(defcustom split-window-preferred-function 'split-window-sensibly
+ "Function called by `display-buffer' routines to split a window.
+This function is called with a window as single argument and is
+supposed to split that window and return the new window. If the
+window can (or shall) not be split, it is supposed to return nil.
+The default is to call the function `split-window-sensibly' which
+tries to split the window in a way which seems most suitable.
+You can customize the options `split-height-threshold' and/or
+`split-width-threshold' in order to have `split-window-sensibly'
+prefer either vertical or horizontal splitting.
+
+If you set this to any other function, bear in mind that the
+`display-buffer' routines may call this function two times. The
+argument of the first call is the largest window on its frame.
+If that call fails to return a live window, the function is
+called again with the least recently used window as argument. If
+that call fails too, `display-buffer' will use an existing window
+to display its buffer.
+
+The window selected at the time `display-buffer' was invoked is
+still selected when this function is called. Hence you can
+compare the window argument with the value of `selected-window'
+if you intend to split the selected window instead or if you do
+not want to split the selected window."
+ :type 'function
+ :version "23.1"
+ :group 'windows)
+
+(defcustom split-height-threshold 80
+ "Minimum height for splitting windows sensibly.
+If this is an integer, `split-window-sensibly' may split a window
+vertically only if it has at least this many lines. If this is
+nil, `split-window-sensibly' is not allowed to split a window
+vertically. If, however, a window is the only window on its
+frame, `split-window-sensibly' may split it vertically
+disregarding the value of this variable."
+ :type '(choice (const nil) (integer :tag "lines"))
+ :version "23.1"
+ :group 'windows)
+
+(defcustom split-width-threshold 160
+ "Minimum width for splitting windows sensibly.
+If this is an integer, `split-window-sensibly' may split a window
+horizontally only if it has at least this many columns. If this
+is nil, `split-window-sensibly' is not allowed to split a window
+horizontally."
+ :type '(choice (const nil) (integer :tag "columns"))
+ :version "23.1"
+ :group 'windows)
+
+(defun window-splittable-p (window &optional horizontal)
+ "Return non-nil if `split-window-sensibly' may split WINDOW.
+Optional argument HORIZONTAL nil or omitted means check whether
+`split-window-sensibly' may split WINDOW vertically. HORIZONTAL
+non-nil means check whether WINDOW may be split horizontally.
+
+WINDOW may be split vertically when the following conditions
+hold:
+- `window-size-fixed' is either nil or equals `width' for the
+ buffer of WINDOW.
+- `split-height-threshold' is an integer and WINDOW is at least as
+ high as `split-height-threshold'.
+- When WINDOW is split evenly, the emanating windows are at least
+ `window-min-height' lines tall and can accommodate at least one
+ line plus - if WINDOW has one - a mode line.
+
+WINDOW may be split horizontally when the following conditions
+hold:
+- `window-size-fixed' is either nil or equals `height' for the
+ buffer of WINDOW.
+- `split-width-threshold' is an integer and WINDOW is at least as
+ wide as `split-width-threshold'.
+- When WINDOW is split evenly, the emanating windows are at least
+ `window-min-width' or two (whichever is larger) columns wide."
+ (when (window-live-p window)
+ (with-current-buffer (window-buffer window)
+ (if horizontal
+ ;; A window can be split horizontally when its width is not
+ ;; fixed, it is at least `split-width-threshold' columns wide
+ ;; and at least twice as wide as `window-min-width' and 2 (the
+ ;; latter value is hardcoded).
+ (and (memq window-size-fixed '(nil height))
+ ;; Testing `window-full-width-p' here hardly makes any
+ ;; sense nowadays. This can be done more intuitively by
+ ;; setting up `split-width-threshold' appropriately.
+ (numberp split-width-threshold)
+ (>= (window-width window)
+ (max split-width-threshold
+ (* 2 (max window-min-width 2)))))
+ ;; A window can be split vertically when its height is not
+ ;; fixed, it is at least `split-height-threshold' lines high,
+ ;; and it is at least twice as high as `window-min-height' and 2
+ ;; if it has a modeline or 1.
+ (and (memq window-size-fixed '(nil width))
+ (numberp split-height-threshold)
+ (>= (window-height window)
+ (max split-height-threshold
+ (* 2 (max window-min-height
+ (if mode-line-format 2 1))))))))))
+
+(defun split-window-sensibly (window)
+ "Split WINDOW in a way suitable for `display-buffer'.
+If `split-height-threshold' specifies an integer, WINDOW is at
+least `split-height-threshold' lines tall and can be split
+vertically, split WINDOW into two windows one above the other and
+return the lower window. Otherwise, if `split-width-threshold'
+specifies an integer, WINDOW is at least `split-width-threshold'
+columns wide and can be split horizontally, split WINDOW into two
+windows side by side and return the window on the right. If this
+can't be done either and WINDOW is the only window on its frame,
+try to split WINDOW vertically disregarding any value specified
+by `split-height-threshold'. If that succeeds, return the lower
+window. Return nil otherwise.
+
+By default `display-buffer' routines call this function to split
+the largest or least recently used window. To change the default
+customize the option `split-window-preferred-function'.
+
+You can enforce this function to not split WINDOW horizontally,
+by setting \(or binding) the variable `split-width-threshold' to
+nil. If, in addition, you set `split-height-threshold' to zero,
+chances increase that this function does split WINDOW vertically.
+
+In order to not split WINDOW vertically, set \(or bind) the
+variable `split-height-threshold' to nil. Additionally, you can
+set `split-width-threshold' to zero to make a horizontal split
+more likely to occur.
+
+Have a look at the function `window-splittable-p' if you want to
+know how `split-window-sensibly' determines whether WINDOW can be
+split."
+ (or (and (window-splittable-p window)
+ ;; Split window vertically.
+ (with-selected-window window
+ (split-window-vertically)))
+ (and (window-splittable-p window t)
+ ;; Split window horizontally.
+ (with-selected-window window
+ (split-window-horizontally)))
+ (and (eq window (frame-root-window (window-frame window)))
+ (not (window-minibuffer-p window))
+ ;; If WINDOW is the only window on its frame and is not the
+ ;; minibuffer window, try to split it vertically disregarding
+ ;; the value of `split-height-threshold'.
+ (let ((split-height-threshold 0))
+ (when (window-splittable-p window)
+ (with-selected-window window
+ (split-window-vertically)))))))
+
+(defun window--try-to-split-window (window)
+ "Try to split WINDOW.
+Return value returned by `split-window-preferred-function' if it
+represents a live window, nil otherwise."
+ (and (window-live-p window)
+ (not (frame-parameter (window-frame window) 'unsplittable))
+ (let ((new-window
+ ;; Since `split-window-preferred-function' might
+ ;; throw an error use `condition-case'.
+ (condition-case nil
+ (funcall split-window-preferred-function window)
+ (error nil))))
+ (and (window-live-p new-window) new-window))))
+
+(defun window--frame-usable-p (frame)
+ "Return FRAME if it can be used to display a buffer."
+ (when (frame-live-p frame)
+ (let ((window (frame-root-window frame)))
+ ;; `frame-root-window' may be an internal window which is considered
+ ;; "dead" by `window-live-p'. Hence if `window' is not live we
+ ;; implicitly know that `frame' has a visible window we can use.
+ (unless (and (window-live-p window)
+ (or (window-minibuffer-p window)
+ ;; If the window is soft-dedicated, the frame is usable.
+ ;; Actually, even if the window is really dedicated,
+ ;; the frame is still usable by splitting it.
+ ;; At least Emacs-22 allowed it, and it is desirable
+ ;; when displaying same-frame windows.
+ nil ; (eq t (window-dedicated-p window))
+ ))
+ frame))))
+
+(defcustom even-window-heights t
+ "If non-nil `display-buffer' will try to even window heights.
+Otherwise `display-buffer' will leave the window configuration
+alone. Heights are evened only when `display-buffer' chooses a
+window that appears above or below the selected window."
+ :type 'boolean
+ :group 'windows)
+
+(defun window--even-window-heights (window)
+ "Even heights of WINDOW and selected window.
+Do this only if these windows are vertically adjacent to each
+other, `even-window-heights' is non-nil, and the selected window
+is higher than WINDOW."
+ (when (and even-window-heights
+ (not (eq window (selected-window)))
+ ;; Don't resize minibuffer windows.
+ (not (window-minibuffer-p (selected-window)))
+ (> (window-height (selected-window)) (window-height window))
+ (eq (window-frame window) (window-frame (selected-window)))
+ (let ((sel-edges (window-edges (selected-window)))
+ (win-edges (window-edges window)))
+ (and (= (nth 0 sel-edges) (nth 0 win-edges))
+ (= (nth 2 sel-edges) (nth 2 win-edges))
+ (or (= (nth 1 sel-edges) (nth 3 win-edges))
+ (= (nth 3 sel-edges) (nth 1 win-edges))))))
+ (let ((window-min-height 1))
+ ;; Don't throw an error if we can't even window heights for
+ ;; whatever reason.
+ (condition-case nil
+ (enlarge-window (/ (- (window-height window) (window-height)) 2))
+ (error nil)))))
+
+(defun window--display-buffer-1 (window)
+ "Raise the frame containing WINDOW.
+Do not raise the selected frame. Return WINDOW."
+ (let* ((frame (window-frame window))
+ (visible (frame-visible-p frame)))
+ (unless (or (not visible)
+ ;; Assume the selected frame is already visible enough.
+ (eq frame (selected-frame))
+ ;; Assume the frame from which we invoked the minibuffer
+ ;; is visible.
+ (and (minibuffer-window-active-p (selected-window))
+ (eq frame (window-frame (minibuffer-selected-window)))))
+ (raise-frame frame))
+ window))
+
+(defun window--display-buffer-2 (buffer window &optional dedicated)
+ "Display BUFFER in WINDOW and make its frame visible.
+Set `window-dedicated-p' to DEDICATED if non-nil.
+Return WINDOW."
+ (when (and (buffer-live-p buffer) (window-live-p window))
+ (set-window-buffer window buffer)
+ (when dedicated
+ (set-window-dedicated-p window dedicated))
+ (window--display-buffer-1 window)))
+
+(defvar display-buffer-mark-dedicated nil
+ "If non-nil, `display-buffer' marks the windows it creates as dedicated.
+The actual non-nil value of this variable will be copied to the
+`window-dedicated-p' flag.")
+
+(defun display-buffer (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.
+
+0 - consider windows on all visible or iconified frames.
+
+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."
+ (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)
+ (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.
+ (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.
+ (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.
+ (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.
+ (let ((win (frame-selected-window (funcall pop-up-frame-function))))
+ (window--display-buffer-2 buffer win display-buffer-mark-dedicated)))
+ ((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)))))
+ (window--display-buffer-2 buffer window-to-use
+ display-buffer-mark-dedicated))
+ ((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)
+ (frame-selected-window (funcall pop-up-frame-function))))
+ (when (window-live-p window-to-undedicate)
+ ;; Restore dedicated status of selected window.
+ (set-window-dedicated-p window-to-undedicate nil))))
+ (window--even-window-heights window-to-use)
+ (window--display-buffer-2 buffer window-to-use)))))
+
+(defun pop-to-buffer (buffer-or-name &optional other-window norecord)
+ "Select buffer BUFFER-OR-NAME in some window, preferably a different one.
+BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
+nil. If BUFFER-OR-NAME is a string not naming an existent
+buffer, create a buffer with that name. If BUFFER-OR-NAME is
+nil, choose some other buffer.
+
+If `pop-up-windows' is non-nil, windows can be split to display
+the buffer. If optional second arg OTHER-WINDOW is non-nil,
+insist on finding another window even if the specified buffer is
+already visible in the selected window, and ignore
+`same-window-regexps' and `same-window-buffer-names'.
+
+If the window to show BUFFER-OR-NAME is not on the selected
+frame, raise that window's frame and give it input focus.
+
+This function returns the buffer it switched to. This uses the
+function `display-buffer' as a subroutine; see the documentation
+of `display-buffer' for additional customization information.
+
+Optional third arg NORECORD non-nil means do not put this buffer
+at the front of the list of recently selected ones."
+ (let ((buffer
+ ;; FIXME: This behavior is carried over from the previous C version
+ ;; of pop-to-buffer, but really we should use just
+ ;; `get-buffer' here.
+ (if (null buffer-or-name) (other-buffer (current-buffer))
+ (or (get-buffer buffer-or-name)
+ (let ((buf (get-buffer-create buffer-or-name)))
+ (set-buffer-major-mode buf)
+ buf))))
+ (old-window (selected-window))
+ (old-frame (selected-frame))
+ new-window new-frame)
+ (set-buffer buffer)
+ (setq new-window (display-buffer buffer other-window))
+ (unless (eq new-window old-window)
+ ;; `display-buffer' has chosen another window, select it.
+ (select-window new-window norecord)
+ (setq new-frame (window-frame new-window))
+ (unless (eq new-frame old-frame)
+ ;; `display-buffer' has chosen another frame, make sure it gets
+ ;; input focus and is risen.
+ (select-frame-set-input-focus new-frame)))
+ buffer))
+