the current buffer.
The replacement buffer in each window is chosen via
-@code{switch-to-prev-buffer} (@pxref{Window History}). Any dedicated
-window displaying @var{buffer-or-name} is deleted if possible
-(@pxref{Dedicated Windows}). If such a window is the only window on its
-frame and there are other frames on the same terminal, the frame is
-deleted as well. If the dedicated window is the only window on the only
-frame on its terminal, the buffer is replaced anyway.
+@code{switch-to-prev-buffer} (@pxref{Window History}). With the
+exception of side windows (@pxref{Side Windows}), any dedicated window
+displaying @var{buffer-or-name} is deleted if possible (@pxref{Dedicated
+Windows}). If such a window is the only window on its frame and there
+are other frames on the same terminal, the frame is deleted as well.
+If the dedicated window is the only window on the only frame on its
+terminal, the buffer is replaced anyway.
@end deffn
any window it creates as dedicated to its buffer (@pxref{Dedicated
Windows}). It does that by calling @code{set-window-dedicated-p} with
the chosen window as first argument and the entry's value as second.
+Side windows are by default dedicated with the value @code{side}
+((@pxref{Side Window Options and Functions}).
@vindex preserve-size@r{, a buffer display action alist entry}
@item preserve-size
Functions supposed to remove a buffer from a window or a window from
a frame can behave specially when a window they operate on is dedicated.
-We will distinguish three basic cases, namely where (1) the window is
+We will distinguish four basic cases, namely where (1) the window is
not the only window on its frame, (2) the window is the only window on
-its frame but there are other frames on the same terminal left, and (3)
-the window is the only window on the only frame on the same terminal.
+its frame but there are other frames on the same terminal left, (3)
+the window is the only window on the only frame on the same terminal,
+and (4) the dedication's value is @code{side}
+(@pxref{Displaying Buffers in Side Windows}).
In particular, @code{delete-windows-on} (@pxref{Deleting Windows})
-handles case (2) by deleting the associated frame and case (3) by
-showing another buffer in that frame's only window. The function
+handles case (2) by deleting the associated frame and cases (3) and (4)
+by showing another buffer in that frame's only window. The function
@code{replace-buffer-in-windows} (@pxref{Buffers and Windows}) which is
called when a buffer gets killed, deletes the window in case (1) and
behaves like @code{delete-windows-on} otherwise.
-@c FIXME: Does replace-buffer-in-windows _delete_ a window in case (1)?
When @code{bury-buffer} (@pxref{Buffer List}) operates on the
selected window (which shows the buffer that shall be buried), it
middle slot. Hence, all windows on a specific side are ordered by their
@code{slot} value. If unspecified, the window is located in the middle
of the specified side.
+
+@item dedicated
+The dedicated flag (@pxref{Dedicated Windows}) has a slightly different
+meaning for side windows. When a side window is created, that flag is
+set to the value @code{side} to prevent @code{display-buffer} to use the
+window in other action functions. Its value persists across invocations
+of @code{quit-window}, @code{kill-buffer}, @code{previous-buffer} and
+@code{next-buffer}.
+
+In particular, these commands will refrain from showing, in a side
+window, buffers that have not been displayed in that window before.
+They will also refrain from having a normal, non-side window show a
+buffer that has been already displayed in a side window. A notable
+exception to the latter rule occurs when an application, after
+displaying a buffer, resets that buffer’s local variables. To override
+these rules and always delete a side window with @code{quit-window} or
+@code{kill-buffer}, and eventually prevent the use of
+@code{previous-buffer} and @code{next-buffer}, set this value to
+@code{t} or specify a value via @code{display-buffer-mark-dedicated}.
@end table
If you specify the same slot on the same side for two or more different
action. Note also that @code{delete-other-windows} cannot make a side
window the only window on its frame (@pxref{Deleting Windows}).
- Once set up, side windows also change the behavior of the commands
-@code{switch-to-prev-buffer} and @code{switch-to-next-buffer}
-(@pxref{Window History}). In particular, these commands will refrain
-from showing, in a side window, buffers that have not been displayed in
-that window before. They will also refrain from having a normal,
-non-side window show a buffer that has been already displayed in a side
-window. A notable exception to the latter rule occurs when an
-application, after displaying a buffer, resets that buffer's local
-variables.
-
@node Side Window Options and Functions
@subsection Side Window Options and Functions
before was current this also makes BUFFER the current buffer."
(setq window (window-normalize-window window t))
(let ((selected (eq window (selected-window)))
- (current (eq (window-buffer window) (current-buffer))))
+ (current (eq (window-buffer window) (current-buffer)))
+ (dedicated-side (eq (window-dedicated-p window) 'side)))
(set-window-buffer window buffer)
+ (and dedicated-side (set-window-dedicated-p window 'side))
(when (and selected current)
(set-buffer buffer))
(when start
;; Scan WINDOW's previous buffers first, skipping entries of next
;; buffers.
(dolist (entry (window-prev-buffers window))
- (when (and (setq new-buffer (car entry))
+ (when (and (not (eq (car entry) old-buffer))
+ (setq new-buffer (car entry))
(or (buffer-live-p new-buffer)
(not (setq killed-buffers
(cons new-buffer killed-buffers))))
- (not (eq new-buffer old-buffer))
(or (null pred) (funcall pred new-buffer))
;; When BURY-OR-KILL is nil, avoid switching to a
;; buffer in WINDOW's next buffers list.
;; Scan WINDOW's reverted previous buffers last (must not use
;; nreverse here!)
(dolist (entry (reverse (window-prev-buffers window)))
- (when (and (setq new-buffer (car entry))
+ (when (and (not (eq new-buffer (car entry)))
+ (setq new-buffer (car entry))
(or (buffer-live-p new-buffer)
(not (setq killed-buffers
(cons new-buffer killed-buffers))))
- (not (eq new-buffer old-buffer))
(or (null pred) (funcall pred new-buffer)))
(if (switch-to-prev-buffer-skip-p skip window new-buffer)
(setq skipped (or skipped new-buffer))
(all-frames (cond ((not frame) t) ((eq frame t) nil) (t frame))))
(dolist (window (window-list-1 nil nil all-frames))
(if (eq (window-buffer window) buffer)
- (let ((deletable (window-deletable-p window)))
+ (let ((deletable (window-deletable-p window))
+ (dedicated (window-dedicated-p window)))
(cond
- ((and (eq deletable 'frame) (window-dedicated-p window))
+ ((and (eq deletable 'frame) dedicated)
;; Delete frame if and only if window is dedicated.
(delete-frame (window-frame window)))
((eq deletable t)
(t
;; In window switch to previous buffer.
(set-window-dedicated-p window nil)
- (switch-to-prev-buffer window 'bury))))
+ (switch-to-prev-buffer window 'bury)
+ ;; Restore the dedicated 'side' flag.
+ (when (eq dedicated 'side)
+ (set-window-dedicated-p window 'side)))))
;; If a window doesn't show BUFFER, unrecord BUFFER in it.
(unrecord-window-buffer window buffer)))))
BUFFER-OR-NAME may be a buffer or the name of an existing buffer
and defaults to the current buffer.
-When a window showing BUFFER-OR-NAME is dedicated, that window is
-deleted. If that window is the only window on its frame, the
-frame is deleted too when there are other frames left. If there
-are no other frames left, some other buffer is displayed in that
+With the exception of side windows, when a window showing BUFFER-OR-NAME
+is dedicated, that window is deleted. If that window is the only window
+on its frame, the frame is deleted too when there are other frames left.
+If there are no other frames left, some other buffer is displayed in that
window.
This function removes the buffer denoted by BUFFER-OR-NAME from
(let ((buffer (window-normalize-buffer buffer-or-name)))
(dolist (window (window-list-1 nil nil t))
(if (eq (window-buffer window) buffer)
- (unless (window--delete window t t)
- ;; Switch to another buffer in window.
- (set-window-dedicated-p window nil)
- (switch-to-prev-buffer window 'kill))
+ ;; Delete a dedicated window unless it is a side window.
+ (let ((dedicated-side (eq (window-dedicated-p window) 'side)))
+ (when (or dedicated-side (not (window--delete window t t)))
+ ;; Switch to another buffer in that window.
+ (set-window-dedicated-p window nil)
+ (if (switch-to-prev-buffer window 'kill)
+ (and dedicated-side (set-window-dedicated-p window 'side))
+ (window--delete window nil 'kill))))
;; Unrecord BUFFER in WINDOW.
(unrecord-window-buffer window buffer)))))
parameter to nil. 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.
+
Optional second argument BURY-OR-KILL tells how to proceed with
the buffer of WINDOW. The following values are handled:
(dolist (buf (window-prev-buffers window))
(unless (eq (car buf) buffer)
(throw 'prev-buffer (car buf))))))
+ (dedicated (window-dedicated-p window))
quad entry)
(cond
+ ;; First try to delete dedicated windows that are not side windows.
+ ((and dedicated (not (eq dedicated 'side))
+ (window--delete window 'dedicated (eq bury-or-kill 'kill))))
((and (not prev-buffer)
(eq (nth 1 quit-restore) 'tab)
(eq (nth 3 quit-restore) buffer))
;; 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))))
(set-window-parameter window 'quit-restore nil)
;; Make sure that WINDOW is no more dedicated.
(set-window-dedicated-p window nil)
- (unless (switch-to-prev-buffer window bury-or-kill)
- ;; Delete WINDOW if there is no previous buffer (Bug#48367).
- (window--delete window nil (eq bury-or-kill 'kill)))))
+ ;; 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 (eq bury-or-kill 'kill))
+ (when (window-live-p (nth 2 quit-restore))
+ (select-window (nth 2 quit-restore))))))
;; Deal with the buffer.
(cond