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.

View in manual

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)))))))))