Function: display-buffer-in-side-window
display-buffer-in-side-window is a byte-compiled function defined in
window.el.gz.
Signature
(display-buffer-in-side-window BUFFER ALIST)
Documentation
Display BUFFER in a side window of the selected frame.
ALIST is an association list of action symbols and values. See Info node (elisp) Buffer Display Action Alists for details of such alists. The following two symbols, when used in ALIST, have a special meaning:
side denotes the side of the frame where the new window shall
be located. Valid values are bottom, right, top and
left. The default is bottom.
slot if non-nil, specifies the window slot where to display
BUFFER. A value of zero or nil means use the middle slot on
the specified side. A negative value means use a slot
preceding (that is, above or on the left of) the middle slot.
A positive value means use a slot following (that is, below or
on the right of) the middle slot. The default is zero.
If the current frame size or the settings of window-sides-slots
do not permit making a new window, a suitable existing window may
be reused and have its window-slot parameter value accordingly
modified.
Unless display-buffer-mark-dedicated is non-nil, dedicate the
side window used to BUFFER so that it does not get reused by
other display-buffer action functions. Return the window used
for displaying BUFFER, nil if no suitable window can be found.
This function installs the window-side and window-slot
parameters and makes them persistent. It neither modifies ALIST
nor installs any other window parameters unless they have been
explicitly provided via a window-parameters entry in ALIST.
This is an action function for buffer display, see Info
node (elisp) Buffer Display Action Functions. It should be
called only by display-buffer or a function directly or
indirectly called by the latter.
Probably introduced at or before Emacs version 26.1.
Source Code
;; Defined in /usr/src/emacs/lisp/window.el.gz
(defun display-buffer-in-side-window (buffer alist)
"Display BUFFER in a side window of the selected frame.
ALIST is an association list of action symbols and values. See
Info node `(elisp) Buffer Display Action Alists' for details of
such alists. The following two symbols, when used in ALIST, have
a special meaning:
`side' denotes the side of the frame where the new window shall
be located. Valid values are `bottom', `right', `top' and
`left'. The default is `bottom'.
`slot' if non-nil, specifies the window slot where to display
BUFFER. A value of zero or nil means use the middle slot on
the specified side. A negative value means use a slot
preceding (that is, above or on the left of) the middle slot.
A positive value means use a slot following (that is, below or
on the right of) the middle slot. The default is zero.
If the current frame size or the settings of `window-sides-slots'
do not permit making a new window, a suitable existing window may
be reused and have its `window-slot' parameter value accordingly
modified.
Unless `display-buffer-mark-dedicated' is non-nil, dedicate the
side window used to BUFFER so that it does not get reused by
other `display-buffer' action functions. Return the window used
for displaying BUFFER, nil if no suitable window can be found.
This function installs the `window-side' and `window-slot'
parameters and makes them persistent. It neither modifies ALIST
nor installs any other window parameters unless they have been
explicitly provided via a `window-parameters' entry in ALIST.
This is an action function for buffer display, see Info
node `(elisp) Buffer Display Action Functions'. It should be
called only by `display-buffer' or a function directly or
indirectly called by the latter."
(let* ((side (or (cdr (assq 'side alist)) 'bottom))
(slot (or (cdr (assq 'slot alist)) 0))
(left-or-right (memq side '(left right))))
(cond
((not (memq side '(top bottom left right)))
(error "Invalid side %s specified" side))
((not (numberp slot))
(error "Invalid slot %s specified" slot)))
(let* ((major (window-with-parameter 'window-side side nil t))
;; `major' is the major window on SIDE, `windows' the list of
;; life windows on SIDE.
(reversed (window--sides-reverse-on-frame-p (selected-frame)))
(windows
(cond
((window-live-p major)
(list major))
((window-valid-p major)
(let* ((first (window-child major))
(next (window-next-sibling first))
(windows (list next first)))
(setq reversed (> (window-parameter first 'window-slot)
(window-parameter next 'window-slot)))
(while (setq next (window-next-sibling next))
(setq windows (cons next windows)))
(if reversed windows (nreverse windows))))))
(slots (when major (max 1 (window-child-count major))))
(max-slots
(nth (cond
((eq side 'left) 0)
((eq side 'top) 1)
((eq side 'right) 2)
((eq side 'bottom) 3))
window-sides-slots))
(window--sides-inhibit-check t)
(alist (if (assq 'dedicated alist)
alist
(cons `(dedicated . ,(or display-buffer-mark-dedicated 'side))
alist)))
window this-window this-slot prev-window next-window
best-window best-slot abs-slot)
(cond
((and (numberp max-slots) (<= max-slots 0))
;; No side-slots available on this side. Don't raise an error,
;; just return nil.
nil)
((not windows)
;; No major side window exists on this side, make one.
(window--make-major-side-window buffer side slot alist))
(t
;; Scan windows on SIDE.
(catch 'found
(dolist (window windows)
(setq this-slot (window-parameter window 'window-slot))
(cond
;; The following should not happen and probably be checked
;; by window--sides-check.
((not (numberp this-slot)))
((= this-slot slot)
;; A window with a matching slot has been found.
(setq this-window window)
(throw 'found t))
(t
;; Check if this window has a better slot value wrt the
;; slot of the window we want.
(setq abs-slot
(if (or (and (> this-slot 0) (> slot 0))
(and (< this-slot 0) (< slot 0)))
(abs (- slot this-slot))
(+ (abs slot) (abs this-slot))))
(unless (and best-slot (<= best-slot abs-slot))
(setq best-window window)
(setq best-slot abs-slot))
(if reversed
(cond
((<= this-slot slot)
(setq next-window window))
((not prev-window)
(setq prev-window window)))
(cond
((<= this-slot slot)
(setq prev-window window))
((not next-window)
(setq next-window window))))))))
;; `this-window' is the first window with the same SLOT.
;; `prev-window' is the window with the largest slot < SLOT. A new
;; window will be created after it.
;; `next-window' is the window with the smallest slot > SLOT. A new
;; window will be created before it.
;; `best-window' is the window with the smallest absolute difference
;; of its slot and SLOT.
(or (and this-window
;; Reuse `this-window'.
(with-current-buffer buffer
(setq window--sides-shown t))
(window--display-buffer buffer this-window 'reuse alist))
(and (or (not max-slots) (< slots max-slots))
(or (and next-window
;; Make new window before `next-window'.
(let ((next-side (if left-or-right 'above 'left))
(window-combination-resize 'side))
(setq window (split-window-no-error
next-window nil next-side))))
(and prev-window
;; Make new window after `prev-window'.
(let ((prev-side (if left-or-right 'below 'right))
(window-combination-resize 'side))
(setq window (split-window-no-error
prev-window nil prev-side)))))
(set-window-parameter window 'window-slot slot)
(with-current-buffer buffer
(setq window--sides-shown t))
(window--display-buffer buffer window 'window alist))
(and best-window
;; Reuse `best-window'.
(progn
;; Give best-window the new slot value.
(set-window-parameter best-window 'window-slot slot)
(with-current-buffer buffer
(setq window--sides-shown t))
(window--display-buffer
buffer best-window 'reuse alist)))))))))