Function: quit-restore-window

quit-restore-window is a byte-compiled function defined in window.el.gz.

Signature

(quit-restore-window &optional WINDOW BURY-OR-KILL)

Documentation

Quit WINDOW and deal with its buffer.

WINDOW must be a live window and defaults to the selected one.

According to information stored in WINDOW's quit-restore and quit-restore-prev parameters either (1) delete WINDOW and its frame, (2) delete WINDOW but leave its frame alone, (3) restore the buffer previously shown in WINDOW, or (4) make WINDOW display some other buffer. In case (3) set any of these parameters to nil if it has been used to restore the previously shown buffer. See Info node (elisp) Quitting Windows for more details.

If WINDOW's dedicated flag is t, try to delete WINDOW. If it equals the value side, restore that value when WINDOW is not deleted. Whether WINDOW or its frame get deleted can be further controlled via the option quit-restore-window-no-switch.

If running the abnormal hook window-deletable-functions returns nil, do not delete WINDOW but show some other buffer in it.

Optional second argument BURY-OR-KILL tells how to proceed with the buffer of WINDOW. The following values are handled:

nil means to not handle the buffer in a particular way. This
  means that if WINDOW is not deleted by this function, invoking
  switch-to-prev-buffer will usually show the buffer again.

append means that if WINDOW is not deleted, move its buffer to
  the end of WINDOW's previous buffers so it's less likely that a
  future invocation of switch-to-prev-buffer will switch to it.
  Also, move the buffer to the end of the frame's buffer list.

bury means that if WINDOW is not deleted, remove its buffer
  from WINDOW'S list of previous buffers. Also, move the buffer
  to the end of the frame's buffer list. This value provides the
  most reliable remedy to not have switch-to-prev-buffer switch
  to this buffer again without killing the buffer.

kill means to kill WINDOW's buffer.

killing is like kill but means that WINDOW's buffer will get killed elsewhere. This value is used by replace-buffer-in-windows and quit-windows-on.

burying is like bury but means that WINDOW's buffer will get buried elsewhere. This value is used by quit-windows-on.

View in manual

Probably introduced at or before Emacs version 31.1.

Source Code

;; Defined in /usr/src/emacs/lisp/window.el.gz
(defun quit-restore-window (&optional window bury-or-kill)
  "Quit WINDOW and deal with its buffer.
WINDOW must be a live window and defaults to the selected one.

According to information stored in WINDOW's `quit-restore' and
`quit-restore-prev' parameters either (1) delete WINDOW and its
frame, (2) delete WINDOW but leave its frame alone, (3) restore the
buffer previously shown in WINDOW, or (4) make WINDOW display some other
buffer.  In case (3) set any of these parameters to nil if it has been
used to restore the previously shown buffer.  See Info node `(elisp)
Quitting Windows' for more details.

If WINDOW's dedicated flag is t, try to delete WINDOW.  If it equals the
value `side', restore that value when WINDOW is not deleted.  Whether
WINDOW or its frame get deleted can be further controlled via the option
`quit-restore-window-no-switch'.

If running the abnormal hook `window-deletable-functions' returns nil,
do not delete WINDOW but show some other buffer in it.

Optional second argument BURY-OR-KILL tells how to proceed with
the buffer of WINDOW.  The following values are handled:

nil means to not handle the buffer in a particular way.  This
  means that if WINDOW is not deleted by this function, invoking
  `switch-to-prev-buffer' will usually show the buffer again.

`append' means that if WINDOW is not deleted, move its buffer to
  the end of WINDOW's previous buffers so it's less likely that a
  future invocation of `switch-to-prev-buffer' will switch to it.
  Also, move the buffer to the end of the frame's buffer list.

`bury' means that if WINDOW is not deleted, remove its buffer
  from WINDOW'S list of previous buffers.  Also, move the buffer
  to the end of the frame's buffer list.  This value provides the
  most reliable remedy to not have `switch-to-prev-buffer' switch
  to this buffer again without killing the buffer.

`kill' means to kill WINDOW's buffer.

`killing' is like `kill' but means that WINDOW's buffer will get killed
elsewhere.  This value is used by `replace-buffer-in-windows' and
`quit-windows-on'.

`burying' is like `bury' but means that WINDOW's buffer will get buried
elsewhere.  This value is used by `quit-windows-on'."
  (setq window (window-normalize-window window t))
  (let* ((buffer (window-buffer window))
	 (quit-restore (window-parameter window 'quit-restore))
	 (quit-restore-prev (window-parameter window 'quit-restore-prev))
	 (quit-restore-2 (nth 2 quit-restore))
	 (quit-restore-prev-2 (nth 2 quit-restore-prev))
         (prev-buffer (catch 'prev-buffer
                        (dolist (buf (window-prev-buffers window))
                          (unless (eq (car buf) buffer)
                            (throw 'prev-buffer (car buf))))))
         (dedicated (window-dedicated-p window))
	 (frame (window-frame window))
	 quad entry reset-prev)
    (cond
     ;; First try to delete dedicated windows that are not side windows.
     ((and dedicated (not (eq dedicated 'side))
           (window--delete
	    window 'dedicated (memq bury-or-kill '(kill killing))))
      ;; If the previously selected window is still alive, select it.
      (window--quit-restore-select-window quit-restore-2 frame))
     ((and (not prev-buffer)
	   (or (memq (nth 1 quit-restore) '(frame tab))
	       (and (eq (nth 1 quit-restore) 'window)
		    ;; If the window has been created on an existing
		    ;; frame and ended up as the sole window on that
		    ;; frame, do not delete it (Bug#12764).
		    (not (eq window (frame-root-window window)))))
	   (eq (nth 3 quit-restore) buffer)
	   ;; Delete WINDOW if possible.
	   (window--delete window nil (eq bury-or-kill 'kill)))
      ;; If the previously selected window is still alive, select it.
      (window--quit-restore-select-window quit-restore-2 frame))
     ((and (or (and quit-restore-window-no-switch (not prev-buffer))
	       ;; Ignore first of the previous buffers if
	       ;; 'quit-restore-window-no-switch' says so.
	       (and (eq quit-restore-window-no-switch 'skip-first)
		    (not (cdr (window-prev-buffers window)))))
	   ;; Delete WINDOW if possible.
	   (window--delete
	    window nil (memq bury-or-kill '(kill killing))))
      ;; If the previously selected window is still alive, select it.
      (window--quit-restore-select-window quit-restore-2 frame))
     ((or (and (listp (setq quad (nth 1 quit-restore-prev)))
	       (buffer-live-p (car quad))
	       (eq (nth 3 quit-restore-prev) buffer)
	       ;; Use selected window from quit-restore-prev.
	       (setq quit-restore-2 quit-restore-prev-2)
	       ;; We want to reset quit-restore-prev only.
	       (setq reset-prev t))
	  (and (listp (setq quad (nth 1 quit-restore)))
	       (buffer-live-p (car quad))
	       (eq (nth 3 quit-restore) buffer)))
      ;; Show another buffer stored in quit-restore(-prev) parameter.
      (when (and (integerp (nth 3 quad))
		 (if (window-combined-p window)
                     (/= (nth 3 quad) (window-total-height window))
                   (/= (nth 3 quad) (window-total-width window))))
	;; Try to resize WINDOW to its old height but don't signal an
	;; error.
	(condition-case nil
	    (window-resize
             window
             (- (nth 3 quad) (if (window-combined-p window)
                                 (window-total-height window)
                               (window-total-width window)))
             (window-combined-p window t))
	  (error nil)))
      (set-window-dedicated-p window nil)
      ;; Restore WINDOW's previous buffer, start and point position.
      (set-window-buffer-start-and-point
       window (nth 0 quad) (nth 1 quad) (nth 2 quad))
      ;; Restore the 'side' dedicated flag as well.
      (when (eq dedicated 'side)
        (set-window-dedicated-p window 'side))
      ;; Deal with the buffer we just removed from WINDOW.
      (setq entry (and (eq bury-or-kill 'append)
		       (assq buffer (window-prev-buffers window))))
      (when (memq bury-or-kill '(bury burying kill killing))
	;; Remove buffer from WINDOW's previous and next buffers.
	(unrecord-window-buffer window buffer))
      (when entry
	;; Append old buffer's entry to list of WINDOW's previous
	;; buffers so it's less likely to get switched to soon but
	;; `display-buffer-in-previous-window' can nevertheless find it.
	(set-window-prev-buffers
	 window (append (window-prev-buffers window) (list entry))))
      ;; Reset the quit-restore(-prev) parameter.
      (set-window-parameter window 'quit-restore-prev nil)
      (unless reset-prev
	;; If quit-restore-prev was not used, reset the quit-restore
	;; parameter
	(set-window-parameter window 'quit-restore nil))
      ;; If the previously selected window is still alive, select it.
      (window--quit-restore-select-window quit-restore-2))
     (t
      ;; Show some other buffer in WINDOW and leave the
      ;; quit-restore(-prev) parameters alone (Juri's idea).
      ;; Make sure that WINDOW is no more dedicated.
      (set-window-dedicated-p window nil)
      ;; Try to switch to a previous buffer.  Delete the window only if
      ;; that is not possible (Bug#48367).
      (if (switch-to-prev-buffer window bury-or-kill)
          (when (eq dedicated 'side)
            (set-window-dedicated-p window 'side))
        (window--delete
	 window nil (memq bury-or-kill '(kill killing))))))
    ;; Deal with the buffer.
    (cond
     ((not (buffer-live-p buffer)))
     ((eq bury-or-kill 'kill)
      (kill-buffer buffer))
     ((eq bury-or-kill 'bury)
      (bury-buffer-internal buffer)))))