Function: switch-to-buffer

switch-to-buffer is an interactive and byte-compiled function defined in window.el.gz.

Signature

(switch-to-buffer BUFFER-OR-NAME &optional NORECORD FORCE-SAME-WINDOW)

Documentation

Display buffer BUFFER-OR-NAME in the selected window.

WARNING: This is NOT the way to work on another buffer temporarily
within a Lisp program! Use set-buffer instead. That avoids
messing with the window-buffer correspondences.

If the selected window cannot display the specified buffer because it is a minibuffer window or strongly dedicated to another buffer, call pop-to-buffer to select the buffer in another window. In interactive use, if the selected window is strongly dedicated to its buffer, the value of the option switch-to-buffer-in-dedicated-window specifies how to proceed.

If called interactively, read the buffer name using read-buffer. The variable confirm-nonexistent-file-or-buffer(var)/confirm-nonexistent-file-or-buffer(fun) determines whether to request confirmation before creating a new buffer. See read-buffer for features related to input and completion of buffer names.

BUFFER-OR-NAME may be a buffer, a string (a buffer name), or nil. If BUFFER-OR-NAME is a string that does not identify an existing buffer, create a buffer with that name. If BUFFER-OR-NAME is nil, switch to the buffer returned by other-buffer.

If optional argument NORECORD is non-nil, do not put the buffer at the front of the buffer list, and do not make the window displaying it the most recently selected one.

If optional argument FORCE-SAME-WINDOW is non-nil, the buffer must be displayed in the selected window when called non-interactively; if that is impossible, signal an error rather than calling pop-to-buffer. It has no effect when the option switch-to-buffer-obey-display-actions is non-nil.

The option switch-to-buffer-preserve-window-point can be used to make the buffer appear at its last position in the selected window.

If the option switch-to-buffer-obey-display-actions is non-nil, run the function pop-to-buffer-same-window instead. This may display the buffer in another window as specified by display-buffer-overriding-action, display-buffer-alist and other display related variables. If this results in displaying the buffer in the selected window, window start and point are adjusted as prescribed by the option switch-to-buffer-preserve-window-point. Otherwise, these are left alone.

In either case, call display-buffer-record-window to avoid disrupting a sequence of display-buffer operations using this window.

Return the buffer switched to.

View in manual

Probably introduced at or before Emacs version 17.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/window.el.gz
(defun switch-to-buffer (buffer-or-name &optional norecord force-same-window)
  "Display buffer BUFFER-OR-NAME in the selected window.

WARNING: This is NOT the way to work on another buffer temporarily
within a Lisp program!  Use `set-buffer' instead.  That avoids
messing with the `window-buffer' correspondences.

If the selected window cannot display the specified buffer
because it is a minibuffer window or strongly dedicated to
another buffer, call `pop-to-buffer' to select the buffer in
another window.  In interactive use, if the selected window is
strongly dedicated to its buffer, the value of the option
`switch-to-buffer-in-dedicated-window' specifies how to proceed.

If called interactively, read the buffer name using `read-buffer'.
The variable `confirm-nonexistent-file-or-buffer' determines
whether to request confirmation before creating a new buffer.
See `read-buffer' for features related to input and completion
of buffer names.

BUFFER-OR-NAME may be a buffer, a string (a buffer name), or nil.
If BUFFER-OR-NAME is a string that does not identify an existing
buffer, create a buffer with that name.  If BUFFER-OR-NAME is
nil, switch to the buffer returned by `other-buffer'.

If optional argument NORECORD is non-nil, do not put the buffer
at the front of the buffer list, and do not make the window
displaying it the most recently selected one.

If optional argument FORCE-SAME-WINDOW is non-nil, the buffer
must be displayed in the selected window when called
non-interactively; if that is impossible, signal an error rather
than calling `pop-to-buffer'.  It has no effect when the option
`switch-to-buffer-obey-display-actions' is non-nil.

The option `switch-to-buffer-preserve-window-point' can be used
to make the buffer appear at its last position in the selected
window.

If the option `switch-to-buffer-obey-display-actions' is non-nil,
run the function `pop-to-buffer-same-window' instead.
This may display the buffer in another window as specified by
`display-buffer-overriding-action', `display-buffer-alist' and
other display related variables.  If this results in displaying
the buffer in the selected window, window start and point are adjusted
as prescribed by the option `switch-to-buffer-preserve-window-point'.
Otherwise, these are left alone.

In either case, call `display-buffer-record-window' to avoid disrupting
a sequence of `display-buffer' operations using this window.

Return the buffer switched to."
  (interactive
   (let ((force-same-window
          (unless switch-to-buffer-obey-display-actions
            (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))
        (set-window-start-and-point (not switch-to-buffer-obey-display-actions)))
    (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).
     ((and (eq buffer (window-buffer))
           ;; pop-to-buffer-same-window might decide to display
           ;; the same buffer in another window
           (not switch-to-buffer-obey-display-actions)))
     ((and (window-minibuffer-p)
           (not switch-to-buffer-obey-display-actions))
      (if force-same-window
          (user-error "Cannot switch buffers in minibuffer window")
        (pop-to-buffer buffer norecord)))
     ((and (eq (window-dedicated-p) t)
           (not switch-to-buffer-obey-display-actions))
      (if force-same-window
          (user-error "Cannot switch buffers in a dedicated window")
        (pop-to-buffer buffer norecord)))
     (t
      (when switch-to-buffer-obey-display-actions
        (let* ((selected-window (selected-window))
	       (old-window-buffer (window-buffer selected-window)))
          (pop-to-buffer-same-window buffer norecord)
	  ;; Do not ask for setting start and point when showing the
	  ;; same buffer in the old selected window (Bug#71616).
          (when (and (eq (selected-window) selected-window)
		     (not (eq (window-buffer selected-window)
			      old-window-buffer)))
            (setq set-window-start-and-point t))))

      (when set-window-start-and-point
        (let* ((entry (assq buffer (window-prev-buffers)))
               (preserve-win-point
                (buffer-local-value 'switch-to-buffer-preserve-window-point
                                    buffer))
	       (displayed (and (eq preserve-win-point 'already-displayed)
			       (get-buffer-window buffer 0))))

	  ;; Make sure quitting the window works.
	  (unless switch-to-buffer-obey-display-actions
	    (display-buffer-record-window 'reuse (selected-window) buffer))

	  (set-window-buffer nil buffer)
	  (when (and entry (or (eq preserve-win-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)))
    (set-buffer buffer)))