29.18 Quitting Windows

After a command uses display-buffer to put a buffer on the screen, the user may decide to hide it and return to the previous configuration of the Emacs display. We call that quitting the window. The way to do this is to call quit-window while the window used by display-buffer is the selected window.

The right way to restore the previous configuration of the display depends on what was done to the window where the buffer now appears. It might be right to delete that window, or delete its frame, or just display another buffer in that window. One complication is that the user may have changed the window configuration since the act of displaying that buffer, and it would be undesirable to undo the user’s explicitly requested changes.

To enable quit-window to do the right thing, display-buffer saves information about what it did in the window’s quit-restore parameter (see Window Parameters).

Command: quit-window &optional kill window

This command quits window and buries its buffer. (It could also kill the buffer, subject to quit-window-kill-buffer, see below.) The argument window must be a live window and defaults to the selected one. With prefix argument kill non-nil, it kills the buffer instead of burying it.

The function quit-window first runs quit-window-hook. Then it calls the function quit-restore-window, described below, which does the hard work.

The following option tells quit-window whether it should kill or bury window’s buffer when the kill argument is nil.

User Option: quit-window-kill-buffer

This variable controls whether quit-window kills the buffer of its window argument. If the value is nil (the default) quit-window will kill window’s buffer only if the kill argument is non-nil. If this is t, quit-window will try to kill window’s buffer regardless of the value of the kill argument. Otherwise, this should be a list of major modes; quit-window will kill the buffer of window regardless of the value of kill if that buffer’s major mode is either a member of this list or is derived from a member of this list. In any other case, quit-window will kill the buffer only if kill is non-nil and bury it otherwise.

You can get more control by calling quit-restore-window instead of quit-window.

Function: quit-restore-window &optional window bury-or-kill

This function handles window and its buffer after quitting. The optional argument window must be a live window and defaults to the selected one. The function takes account of the window’s quit-restore parameter.

The optional argument bury-or-kill specifies how to deal with window’s buffer. The following values are meaningful:

nil

This means to not deal with the buffer in any particular way. As a consequence, if window is not deleted, invoking switch-to-prev-buffer will usually show the buffer again.

append

This means that if window is not deleted, its buffer is moved to the end of window’s list of previous buffers (see Window History), so it’s less likely that future invocations of switch-to-prev-buffer will switch to it. Also, it moves the buffer to the end of the frame’s buffer list (see The Buffer List).

bury

This means that if window is not deleted, its buffer is removed from window’s list of previous buffers. Also, it moves the buffer to the end of the frame’s buffer list. This is the most reliable way to prevent switch-to-prev-buffer from switching to this buffer again, short of killing the buffer.

kill

This means to kill window’s buffer.

killing

This is handled like kill but assumes that window’s buffer gets killed elsewhere. This value is used by replace-buffer-in-windows and quit-windows-on.

burying

This is handled like bury but assumes that window’s buffer gets buried elsewhere. This value is used by quit-windows-on.

The argument bury-or-kill also specifies what to do with window’s frame when window should be deleted, if it is the only window on its frame, and there are other frames on that frame’s terminal. If bury-or-kill equals kill, it means to delete the frame. Otherwise, the fate of the frame is determined by calling frame-auto-hide-function (see below) with that frame as sole argument.

A window’s quit-restore and quit-restore-prev parameters (see Window Parameters) guide quit-restore-window through its process of dealing with its window argument. If such a parameter is absent or nil, this usually means that the window has been created by a command like split-window-below or split-window-right (see Split Window in The GNU Emacs Manual) and quit-restore-window will delete the window only if it was dedicated to its buffer.

If non-nil, any such parameter is a list of four elements:

(method obuffer owindow this-buffer)

The first element, method, is one of the four symbols window, frame, same and other. frame and window control how to delete window, while same and other control displaying some other buffer in it.

Specifically, window means that the window has been specially created by display-buffer; frame means that a separate frame has been created; same, that the window has only ever displayed this buffer; other, that the window showed another buffer before.

The second element, obuffer, is either one of the symbols window or frame, or a list of the form

(prev-buffer prev-window-start prev-window-point height)

which says which buffer was shown in window before, that buffer’s window start (see The Window Start and End Positions) and window point (see Windows and Point) positions at that time, and window’s height at that time. If prev-buffer is still live when quitting window, quitting the window may reuse window to display prev-buffer.

The third element, owindow, is the window that was selected just before the displaying was done. If quitting deletes window, it tries to select owindow.

The fourth element, this-buffer, is the buffer whose displaying set the quit-restore parameter. Quitting window will use the information stored by that parameter if and only if it still shows that buffer.

quit-restore-window tries to delete its window if (1) method is either window or frame, (2) the window has no history of previously-displayed buffers and (3) this-buffer equals the buffer currently displayed in window. If window is part of an atomic window (see Atomic Windows), it will try to delete the root of that atomic window instead. In either case, it tries to avoid signaling an error when window cannot be deleted.

If obuffer is a list, and prev-buffer is still live, quitting displays prev-buffer in window according to the rest of the elements of obuffer. This includes resizing the window to height if it was temporarily resized to display this-buffer.

Otherwise, if window was previously used for displaying other buffers (see Window History), the most recent buffer in that history will be displayed.

Conceptually, the quit-restore parameter is used for undoing the first buffer display operation for a specific window. The quit-restore-prev parameter is used for undoing the last buffer display operation in a row of such operations for a specific window. Any buffer display operation for that window that happened in between, is undone by displaying the buffer previously shown in that window.

display-buffer sets up the quit-restore parameter of any window it uses when that window has been either created by it or has no non-nil quit-restore parameter. If the window already has a quit-restore parameter, display-buffer adds a quit-restore-prev parameter whose method element is either same or other. In either case, if the window already has a quit-restore-prev or quit-restore parameter, it may update that parameter’s contents.

quit-restore-window now first tries to find a suitable quit-restore-prev parameter for its window telling which buffer to show instead. If it doesn’t find one, it will look for a suitable quit-restore parameter to either delete the window or show another buffer in it.

Once it has used one of these parameters, quit-restore-window resets it to nil. Parameters it did not use are left alone. Any of these parameters are also reset by replace-buffer-in-windows (see Buffers and Windows) when they reference a buffer that is about to be killed, either as the buffer specified by prev-buffer or as the buffer specified by this-buffer.

All operations on these parameters are supposed to preserve the following invariant: If a window has a non-nil quit-restore-prev parameter, it also has a non-nil quit-restore parameter.

The following option allows quit-restore-window to delete its window more aggressively.

User Option: quit-restore-window-no-switch

If this option is nil, quit-restore-window will always call switch-to-prev-buffer unless the window has been made by display-buffer. If this is t, quit-restore-window will try hard to switch only to buffers previously shown in that window. If this is the symbol skip-first, it will switch to a previous buffer if and only the window has at least two previous buffers.

In either case, if quit-restore-window doesn’t switch to a previous buffer, it will try to delete the window (and maybe its frame) instead. Note also that if a window is dedicated, quit-restore-window will usually not switch to a previous buffer in it either.

The following option specifies a function to do the right thing with a frame containing one window when quitting that window.

User Option: frame-auto-hide-function

The function specified by this option is called to automatically hide frames. This function is called with one argument—a frame.

The function specified here is called by bury-buffer (see The Buffer List) when the selected window is dedicated and shows the buffer to bury. It is also called by quit-restore-window (see above) when the frame of the window to quit has been specially created for displaying that window’s buffer and the buffer is not killed.

The default is to call iconify-frame (see Visibility of Frames). Alternatively, you may specify either delete-frame (see Deleting Frames) to remove the frame from its display, make-frame-invisible to make the frame invisible, ignore to leave the frame unchanged, or any other function that can take a frame as its sole argument.

Note that the function specified by this option is called only if the specified frame contains just one live window and there is at least one other frame on the same terminal.

For a particular frame, the value specified here may be overridden by that frame’s auto-hide-function frame parameter (see Frame Interaction Parameters).