@c -*-texinfo-*-
@c This is part of the GNU Emacs Lisp Reference Manual.
@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2001,
-@c 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+@c 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
@c Free Software Foundation, Inc.
@c See the file elisp.texi for copying conditions.
@setfilename ../../info/windows
@menu
* Basic Windows:: Basic information on using windows.
-* Frames and Windows:: Relating windows to the frame they appear on.
+* Windows and Frames:: Relating windows to the frame they appear on.
* Window Sizes:: Accessing a window's size.
* Resizing Windows:: Changing the sizes of windows.
* Splitting Windows:: Splitting one window into two windows.
converting coordinates to windows.
* Window Configurations:: Saving and restoring the state of the screen.
* Window Parameters:: Associating additional information with windows.
-* Composite Windows:: Composing aggregations of windows.
-* Compound Windows:: Making several windows behave like a single one.
-* Window Groups:: Implementing IDE style window compositions.
+* Atomic Windows:: Gluing windows together.
+* Side Windows:: Grouping side windows around a main window.
* Window Hooks:: Hooks for scrolling, window size changes,
redisplay going past a certain point,
or window configuration changes.
For historical reasons a window is considered @dfn{live} if and only
if it currently displays a buffer; see @ref{Buffers and Windows}. In
order to show multiple windows within one and the same frame, Emacs
-organizes them in form of a tree called window tree; see @ref{Frames and
-Windows}. The internal nodes of a window tree are called internal
+organizes them in form of a tree called window tree; see @ref{Windows
+and Frames}. The internal nodes of a window tree are called internal
windows and are not considered live. The leaf nodes of a window tree
constitute the windows displaying buffers and only they will be called
live here. The selected window (@pxref{Selecting Windows}) is always a
@defun window-live-p object
This function returns @code{t} if @var{object} is a live window and
-@code{nil} otherwise. A live window is a window that is currently used
-to display a buffer.
+@code{nil} otherwise. A live window is a window that displays a buffer.
@end defun
@defun window-internal-p object
This function returns @code{t} if @var{object} denotes an internal
window and @code{nil} otherwise. An internal window is a window that
-currently has at least two child windows, see @ref{Frames and Windows}.
+has at least two child windows, see @ref{Windows and Frames}.
@end defun
@defun window-any-p object
The window handling functions can be roughly grouped into functions
operating on live windows only and functions that accept any window as
-argument. Many of these function accept the value @code{nil} to specify
-the selected window. The two functions below can be used to
+argument. Many of these functions accept the value @code{nil} to
+specify the selected window. The two functions below can be used to
``normalize'' arguments specifying windows in a uniform manner.
@defun normalize-any-window window
nor a live window this function signals an error.
@end defun
-@node Frames and Windows
-@section Frames and Windows
+
+@node Windows and Frames
+@section Windows and Frames
Each window is part of one and only one frame (@pxref{Frames}); you can
-get that frame with the following function.
+get that frame with the function described next.
@defun window-frame window
This function returns the frame that @var{window} is on. The argument
@var{window} can be any window and defaults to the selected one.
@end defun
-A list of all live windows on a specific frame can be obtained by
-calling the following function.
+The following function returns a list of all live windows on a specific
+frame.
@defun window-list &optional frame minibuf window
This function returns a list of @var{frame}'s live windows, starting
minibuffer window as argument. Also, the minibuffer window is listed by
the function @code{window-tree} described at the end of this section.
- Most window functions can be used without understanding the internals
-of window trees. Some aspects, in particular the implementation of
-compound windows (@pxref{Compound Windows}) and window groups
-(@pxref{Window Groups}) require, however, a basic understanding of
-window trees.
-
A window tree is rooted at the root window of its frame.
@defun frame-root-window &optional frame-or-window
@cindex subwindow
All other windows of a frame with the exception of the minibuffer window
are subwindows of the frame's root window. A window is considered a
-@dfn{subwindow} of another window if and only if it occupies a part of
-that other window's screen area.
+@dfn{subwindow} of another window if it occupies a part of that other
+window's screen area.
The functions described next allow to access the members of a window
-tree with an arbitrary window as argument.
+tree and take an arbitrary window as argument.
@cindex parent window
@defun window-parent &optional window
Return @var{window}'s parent in the window tree. The optional argument
@var{window} can denote an arbitrary window and defaults to the selected
-one. The return value is either an internal window or @code{nil} if
-@var{window} is a minibuffer window or the root window of its frame.
+one. The return value is @code{nil} if @var{window} is a minibuffer
+window or the root window of its frame and an internal window otherwise.
@end defun
@cindex child window
Parent windows do not appear on the screen. The screen area of a
parent window is the rectangular part of the window's frame occupied by
-the window's @dfn{child windows}, that is the set of windows having that
-window as their parent. Each parent window has at least two child
+the window's @dfn{child windows}, that is, the set of windows having
+that window as their parent. Each parent window has at least two child
windows, so there are no ``Matryoshka'' windows. Minibuffer windows do
not have child windows.
combination of windows. A @dfn{vertical combination} is a set of
windows arranged one above each other. A @dfn{horizontal combination}
is a set of windows arranged side by side. For any parent window, the
-first child window is accessible by the functions given next.
+first child window can be retrieved by the functions given next.
@defun window-vchild &optional window
This function returns @var{window}'s first vertical child window. The
of a vertical or horizontal combination.
@defun window-iso-combined-p &optional window horizontal
-This function returns a non-@code{nil} value if and only if @var{window}
-is vertically combined. The argument @var{window} can specify any
-window and defaults to the selected one. The actual return value is the
-first vertical child of window.
+This function returns non-@code{nil} if and only if @var{window} is
+vertically combined. The argument @var{window} can specify any window
+and defaults to the selected one. The actual return value is the first
+vertical child of window.
If the optional argument @var{horizontal} is non-@code{nil}, this means
to return non-@code{nil} if and only if @var{window} is horizontally
@cindex sibling window
For any window that is part of a combination, the other windows in that
combination are called the window's @dfn{siblings}. The only windows
-that do not have any siblings are the frames' root windows and the
-minibuffer windows. A window's siblings can be retrieved with the
-following two functions.
+that do not have siblings are root windows of frames and minibuffer
+windows. A window's siblings can be retrieved with the following two
+functions.
@defun window-next &optional window
This function returns @var{window}'s right sibling. The optional
The text area constitutes the body of the window. In its most simple
form, a window consists of its body alone. LS and RS stand for the left
and right scroll bar (@pxref{Scroll Bars}) respectively. Only one of
-them can be present, in practice. LF and RF denote the left and right
+them can be present at any time. LF and RF denote the left and right
fringe, see @ref{Fringes}. LM and RM, finally, stand for the left and
-right display margin, see @ref{Display Margins}. Any header line is
-located above theses areas, any mode line below, see @ref{Mode Line
-Format}.
+right display margin, see @ref{Display Margins}. The header line, if
+present, is located above theses areas, the mode line below, see
+@ref{Mode Line Format}.
@cindex window height
@cindex total window height
The @dfn{total width of a window} denotes the total number of columns of
the window. Any scroll bar and the column of @samp{|} characters that
separate the window from its right sibling are included in a window's
-total width. On a window-system also fringes and display margins are
-included in a window's total width. For an internal window, the total
-width is calculated recursively from the total widths of its child
+total width. On a window-system, fringes and display margins are
+included in a window's total width too. For an internal window, the
+total width is calculated recursively from the total widths of its child
windows.
@cindex total size of a window
provided these are vertically combined and the height of @var{window}'s
first child if they are horizontally combined.
-If optional argument @var{horizontal} is non-@code{nil}, this function
-returns the total number of columns of @var{window}. If @var{window} is
-live, the return value includes any vertical divider column or scroll
-bars owned by @var{window}. On a window-system the return value also
-includes the space occupied by any margins and fringes of @var{window}.
-If @var{window} is internal, the return value is the sum of the total
-widths of @var{window}'s child windows provided these are horizontally
-combined and the width of @var{window}'s first child otherwise.
+ If the optional argument @var{horizontal} is non-@code{nil}, this
+function returns the total number of columns of @var{window}. If
+@var{window} is live, the return value includes any vertical divider
+column or scroll bars of @var{window}. On a window-system, the return
+value includes the space occupied by any margins and fringes of
+@var{window} too. If @var{window} is internal, the return value is the
+sum of the total widths of @var{window}'s child windows provided these
+are horizontally combined and the width of @var{window}'s first child
+otherwise.
@end defun
Alternatively, the following two functions can be used to retrieve
@end defun
The total height of any window is usually less than the height of the
-associated frame, because the latter may also include the minibuffer
+window's frame, because the latter may also include the minibuffer
window. Depending on the toolkit in use, the frame height can also
include the menu bar and the tool bar (@pxref{Size and Position}).
Therefore, in general it is not straightforward to compare window and
-frame heights. The following function can be used to determine whether
-a window is as high as the containing frame:
+frame heights. The following function is useful to determine whether
+there are no other windows above or below a specified window.
@cindex full-height window
@defun window-full-height-p &optional window
This function returns non-@code{nil} if there is no other window above
or below @var{window} on the containing frame. More precisely, this
function returns @code{t} if and only if the total height of
-@var{window} equals the total height of the root window (@pxref{Frames
-and Windows}) of @var{window}'s frame. The @var{window} argument may
+@var{window} equals the total height of the root window (@pxref{Windows
+and Frames}) of @var{window}'s frame. The @var{window} argument may
denote any window and defaults to the selected one.
@end defun
@cindex full-width window
-The following function can be used to determine whether a window is as
-wide as the containing frame.
+The following function can be used to determine whether there are no
+other windows on the left or right of a specified window.
@defun window-full-width-p &optional window
-This function returns non-@code{nil} if @var{window} is as wide as the
-frame that contains it; otherwise @code{nil}. More precisely, this
-function returns @code{t} if and only if the total width of @var{window}
-equals the total width of the root window (@pxref{Frames and Windows})
-of @var{window}'s frame. The @var{window} argument may denote any
-window and defaults to the selected one.
+This function returns non-@code{nil} if there are no other windows on
+the left or right of @var{window}; @code{nil} otherwise. More
+precisely, this function returns @code{t} if and only if the total width
+of @var{window} equals the total width of the root window
+(@pxref{Windows and Frames}) of @var{window}'s frame. The @var{window}
+argument may denote any window and defaults to the selected one.
@end defun
@cindex top line of window
@cindex left column of window
- Each window in a frame is unambiguously characterized by the
-combination of its top line and its left column within that frame.
+ The windows of a frame are unambiguously characterized by the
+combination of their top line and left column within that frame.
@defun window-top-line &optional window
This function returns the top line of @var{window}. The argument
@cindex window body height
@cindex body height of a window
The @dfn{body height of a window} is specified as the total number of
-lines occupied by the window's text area. Any mode or header line is
-not included in a window's body height.
+lines occupied by the window's text area. Mode or header lines are not
+included in a window's body height.
@cindex window body width
@cindex body width of a window
The @dfn{body width of a window} denotes the total number of columns
-occupied by the window's text area. Any scroll bar or column of
-@samp{|} characters that separates side-by-side windows is not included
-in a window's body width.
+occupied by the window's text area. Scroll bars or columns of @samp{|}
+characters that separates side-by-side windows are not included in a
+window's body width.
@cindex body size of a window
@cindex window body size
@cindex minimum window size
The following two options constrain the sizes of windows to a minimum
height and width. Their values are honored when windows are split
-(@pxref{Splitting Windows}) or resized. Any request to make a window
-smaller than specified here will usually result in an error.
+(@pxref{Splitting Windows}) or resized (@pxref{Resizing Windows}). Any
+request to make a window smaller than specified here will usually result
+in an error.
@defopt window-min-height
The value of this variable specifies how short a window may be. The
value is measured in line units and has to account for any header or
-mode line. The default value for this option is @code{4}. Any value
-less than @code{1} is ignored.
+mode line. The default value for this option is @code{4}. Values less
+than @code{1} are ignored.
@end defopt
@defopt window-min-width
option is @code{10}. A value less than @code{2} is ignored.
@end defopt
-An application should not rebind these variables. To shrink a specific
-window to a height or width less than the one specified here, it should
-rather invoke @code{resize-window} with a non-@code{nil} @var{ignore}
-argument. The function @code{split-window} (@pxref{Splitting Windows})
-can make a window smaller than specified here by setting its @var{size}
-argument to a non-@code{nil} value. Interactively, the values specified
-here cannot be overridden.
+Applications should not rebind these variables. To shrink a specific
+window to a height or width less than the one specified here, they
+should rather invoke @code{resize-window} (@pxref{Resizing Windows})
+with a non-@code{nil} @var{ignore} argument. The function
+@code{split-window} (@pxref{Splitting Windows}) can make a window
+smaller than specified here by calling it with a non-@code{nil}
+@var{size} argument. Interactively, the values specified here cannot be
+overridden.
Earlier versions of Emacs could delete a window when its size dropped
-below @code{window-min-height} or @code{window-min-width}. The current
-version of Emacs does no more implicitly delete windows. The only
-exception to this rule are requests to resize a frame which may
+below @code{window-min-height} or @code{window-min-width}. As a rule,
+the current version of Emacs does no more delete windows by side-effect.
+The only exception to this rule are requests to resize a frame which may
implicitly delete windows when they do not fit on the frame any more,
see @ref{Size and Position}.
Commands supposed to explicitly change the size of windows such as
@code{enlarge-window} (@pxref{Resizing Windows}) get an error if they
-would have to change a window size which is fixed. Other functions like
+had to change a window size which is fixed. Other functions like
@code{resize-window} (@pxref{Resizing Windows}) have an optional
@var{ignore} argument which allows to change the size of fixed-size
windows.
Emacs does not permit overlapping windows or gaps between windows, so
changing the size of a window always affects at least one other window.
When a frame contains just one window, that window can be resized only
-implicitly by resizing the window's frame. The functions described
-below are therefore meaningful exclusively in the context of a frame
-containing at least two windows. The size of that frame never changes
-when invoking a function described in this section.
+by resizing the window's frame. The functions described below are
+therefore meaningful only in the context of a frame containing at least
+two windows. The size of the corresponding frame never changes when
+invoking a function described in this section.
The routines changing window sizes always operate in one dimension at
a time. This means that windows can be resized only either vertically
full-width and/or full-height windows. If @var{window-or-frame}
specifies a frame, it balances all windows on that frame. If
@var{window-or-frame} specifies a window, it balances that window and
-its siblings (@pxref{Frames and Windows}) only.
+its siblings (@pxref{Windows and Frames}) only.
@end deffn
@deffn Command balance-windows-area
@cindex maximizing windows
The following function can be used to give a window the maximum possible
-size on its frame.
+size without deleting other ones.
@deffn Command maximize-window &optional window
This function maximizes @var{window}. More precisely, this makes
The functions described below are the primitives needed for creating a
new window. They do not accept a buffer as an argument. Rather, they
-apparently ``split'' an existing window into two halves, both displaying
-the buffer previously visible in the window that was split.
+``split'' an existing window into two halves, both displaying the buffer
+previously visible in the window that was split.
@deffn Command split-window &optional window size horizontal
This function creates a new window adjacent to @var{window}. It returns
If splitting would result in making a window smaller than
@code{window-min-height} or @code{window-min-width} (@pxref{Window
Sizes}), this function usually signals an error. However, if @var{size}
-is negative and its absolute value is valid, a new window of the
-requested size is created. (A size value would be invalid if it
-assigned less than one line or less than two columns to the new window.)
+is non-@code{nil} and valid, a new window of the requested size is
+created. (A size value would be invalid if it assigned less than one
+line or less than two columns to the new window.)
Optional third argument @var{horizontal} @code{nil} (or @code{below})
specifies that the new window shall be located below @var{window}. The
new window, are inherited from the window selected on @var{window}'s
frame.
-This function respects the variable @code{ignore-window-parameters}
-(@pxref{Window Parameters}) when processing window parameters so any
-processing of @var{window}'s parameters may be suppressed.
-
-If the @code{split-window} parameter of @var{window} equals @code{t},
-any other parameters for @var{window} are ignored and @var{window} is
-split as described above. If the @code{split-window} parameter of
-@var{window} specifies a function, that function is called with the
-@var{window}, @var{size}, and @var{horizontal} arguments to do the
-split. If that function is @code{ignore}, nothing is done. It's the
-responsibility of that function to adjust all window parameters.
-
-If neither @code{ignore-window-parameters} nor the @code{split-window}
-parameter come in the way, this function may behave specially when
-@var{window} is a composite window or part of a composite window, see
-@ref{Composite Windows}. If @var{window} is a component of a compound
-window (@pxref{Compound Windows}) this function operates on the root of
-the compound window instead. The new window does not become a member of
-the compound window. If @var{window} is a main window of a window group
-(@pxref{Window Groups}), the new window becomes a main window in that
-window group. If @var{window} is a non-main component of a window group
-this function signals an error.
+If @code{ignore-window-parameters} is non-@code{nil}, this function
+ignores window parameters (@pxref{Window Parameters}). Otherwise, if
+the @code{split-window-function} parameter of @var{window} is @code{t},
+it splits the window disregarding any other window parameters. If the
+@code{split-window-function} parameter specifies a function, that
+function is called with the arguments @var{window}, @var{size}, and
+@var{horizontal} to split @var{window}. If that function is
+@code{ignore}, nothing is done.
+
+Otherwise, if @var{window} is a subwindow of an atomic window
+(@pxref{Atomic Windows}) this function splits the root of the atomic
+window instead. The new window does not become a subwindow of the
+atomic window. If @var{window} is a non-side window (@pxref{Side
+Windows}), the new window becomes a non-side window too. If
+@var{window} is a side window, the new window becomes a side window too.
@end deffn
The following example starts with one window on a screen that is 50
display table can specify alternative border characters; see @ref{Display
Tables}.
-The following option affects the behavior of a number of functions
+ The following option affects the behavior of a number of functions
operating on a window that is part of a window combination, see
-@ref{Frames and Windows}.
+@ref{Windows and Frames}.
@defopt window-splits
If this variable is @code{nil}, @code{split-window} creates a new parent
@var{window}'s right sibling. @code{delete-window} preferably returns
space to @var{window}'s left sibling.
-If this variable equals @code{nest}, @code{split-window} always creates
-a new parent window. As a consequence, any frame's window tree is a
-binary tree and every window has at most one (left or right) sibling.
-@code{resize-window} preferably resizes @var{window}'s sibling.
-@code{delete-window} preferably returns space to @var{window}'s sibling.
+ If this variable equals @code{nest}, @code{split-window} always
+creates a new parent window. As a consequence, any frame's window tree
+is a binary tree and every window has at most one (left or right)
+sibling. @code{resize-window} preferably resizes @var{window}'s
+sibling. @code{delete-window} preferably returns space to
+@var{window}'s sibling. Functions creating atomic or view windows bind
+this variable temporarily to @code{nest} in order to make sure that
+subwindows of the same type are glued together.
-If this variable equals @code{resize}, @code{split-window} tries to
+ If this variable equals @code{resize}, @code{split-window} tries to
resize all windows belnging to the same combination as @var{window} to
accomodate the new window. Hence, the new window can be also created if
@var{window} is otherwise too small to be split. Resizing or deleting
any window of a combination tries to distribute space proportionally
among all other windows of the combination.
-Application programs should never rebind this variable to any value but
-@code{nest}.
+ Application programs should never rebind this variable to any value
+but @code{nest}.
@end defopt
@deffn Command split-window-vertically &optional size
@code{split-window-keep-point} (see below) is @code{nil}, then either
window can be selected.
-In other respects, this function is similar to @code{split-window}.
-In particular, the upper window is the original one and the return
-value is the new, lower window.
+ In other respects, this function is similar to @code{split-window}.
+In particular, the upper window is the original one and the return value
+is the new, lower window.
@end deffn
@defopt split-window-keep-point
If this variable is non-@code{nil} (the default), then
@code{split-window-vertically} behaves as described above.
-If it is @code{nil}, then @code{split-window-vertically} adjusts point
-in each of the two windows to avoid scrolling. (This is useful on
+ If it is @code{nil}, then @code{split-window-vertically} adjusts
+point in each of the two windows to avoid scrolling. (This is useful on
slow terminals.) It selects whichever window contains the screen line
that point was previously on.
-This variable affects the behavior of @code{split-window-vertically}
+ This variable affects the behavior of @code{split-window-vertically}
only. It has no effect on the other functions described here.
@end defopt
there are no references to it. There is no way to cancel the deletion
of a window aside from restoring a saved window configuration
(@pxref{Window Configurations}). Restoring a window configuration also
-deletes any windows that aren't part of that configuration.
-
-@strong{Warning:} Erroneous information or fatal errors may result from
-using a deleted window as if it were live.
+deletes any windows that aren't part of that configuration. Erroneous
+information may result from using a deleted window as if it were live.
@deffn Command delete-window &optional window
This function removes @var{window} from display and returns @code{nil}.
The argument @var{window} can denote any window and defaults to the
selected one. An error is signaled if @var{window} is the only window
on its frame. Hence @var{window} must have at least one sibling window
-(@pxref{Frames and Windows}) in order to get deleted.
+(@pxref{Windows and Frames}) in order to get deleted.
If @code{window-splits} is @code{nil}, the space @var{window} took up is
given to its left sibling if such a window exists and to its right
sibling otherwise. If @code{window-splits} equals @code{nest} that
-space is given to the sole remaining sibling of @var{window}. If
+space is given to the remaining sibling of @var{window}. If
@code{window-splits} equals @code{resize}, the space occupied by
-@var{window} is distributed proportionally among the other windows in
-the same combination as @var{window}.
-
-This function respects the variable @code{ignore-window-parameters}
-(@pxref{Window Parameters}) when processing window parameters. If
-parameters are not ignored and the @code{delete-window} parameter of
-@var{window} equals @code{t}, this function deletes @var{window}
-ignoring any other window parameters. If the @code{delete-window}
-parameter specifies a function, that function is called with
-@var{window} as its sole argument. It's the responsibility of that
-function to adjust the parameters of all remaining windows.
-
-Otherwise, if @var{window} is part of a compound window (@pxref{Compound
-Windows}), this function is called with the root of the compound window
-as its argument. If @var{window} is a support window or the last main
-window of a window group (@pxref{Window Groups}), this function signals
-an error.
+@var{window} is proportionally distributed among the remaining windows
+in the same combination.
+
+If @code{ignore-window-parameters} (@pxref{Window Parameters}) is
+non-@code{nil}, this function ignores window parameters. Otherwise, if
+the @code{delete-window-function} parameter of @var{window} is @code{t},
+it deletes the window disregarding other window parameters. If the
+@code{delete-window-function} parameter specifies a function, that
+function is called with @var{window} as its sole argument.
+
+If @var{window} is part of an atomic window (@pxref{Atomic Windows}),
+this function is called with the root of the atomic window as its
+argument. If that window is the root window of its frame, an error is
+signalled. If @var{window} is the last non-side window on its frame
+(@pxref{Side Windows}), this function signals an error too.
@end deffn
@deffn Command delete-other-windows &optional window
The argument @var{window} can denote an arbitrary window and defaults to
the selected one.
-This function respects the variable @code{ignore-window-parameters}
-when processing window parameters so any processing of @var{window}'s
-parameters may be suppressed.
-
-If the @code{delete-other-windows} parameter of @var{window} equals
-@code{t}, this function deletes the remaining windows ignoring all other
-parameters. If the @code{delete-other-windows} parameter specifies a
+If @code{ignore-window-parameters} (@pxref{Window Parameters}) is
+non-@code{nil}, this function ignores window parameters. Otherwise, if
+the @code{delete-other-windows-function} parameter equals @code{t}, it
+deletes all other windows disregarding any remaining window parameters.
+If the @code{delete-other-windows-function} parameter specifies a
function, it calls that function with @var{window} as its sole argument.
-Otherwise, if @var{window} is part of a compound window, it calls this
-function with the root of the compound window as its argument. If
-@var{window} is a main window in a window group, it makes @var{window}
-the only main window in that group. Any support windows of the group
-are left alone. If @var{window} is a support window of a window group,
-this function signals an error and doesn't delete any windows.
+If @var{window} is part of an atomic window (@pxref{Atomic Windows}), it
+calls this function with the root of the atomic window as its argument.
+If @var{window} is a non-side window (@pxref{Side Windows}), it makes
+@var{window} the only non-side window on its frame and leaves side
+windows alone. If @var{window} is a side window, this function signals
+an error.
@end deffn
@deffn Command delete-windows-on &optional buffer-or-name frame
the space. If all windows in some frame are showing
@var{buffer-or-name} (including the case where there is only one
window), then the frame winds up with a single window showing another
-buffer chosen with @code{other-buffer}, see @ref{The Buffer List}. If,
-however, that last remaining window is dedicated to the buffer specified
-by @var{buffer-or-name} (@pxref{Dedicated Windows}), and there are other
-frames left, that window's frame is deleted.
+buffer. If, however, that last remaining window is dedicated to the
+buffer specified by @var{buffer-or-name} (@pxref{Dedicated Windows}),
+and there are other frames left, that window's frame is deleted.
The optional argument @var{frame} specifies which frames to operate on.
This function does not use it in quite the same way as the other
called the @dfn{cyclic ordering of windows}.
For a particular frame, this ordering is determined by the window
-tree of that frame, see @ref{Frames and Windows}. More precisely, the
+tree of that frame, see @ref{Windows and Frames}. More precisely, the
ordering is obtained by a depth-first traversal of the frame's window
tree supplemented, if requested, by the frame's minibuffer window.
@defun next-window &optional window minibuf all-frames
@cindex minibuffer window, and @code{next-window}
This function returns the window following @var{window} in the cyclic
-ordering of windows. This is the window @kbd{C-x o} selects if typed
-when @var{window} is selected. The argument @var{window} must specify a
-live window and defaults to the selected one.
+ordering of windows. The argument @var{window} must specify a live
+window and defaults to the selected one.
The optional argument @var{minibuf} specifies whether minibuffer windows
shall be included in the cyclic ordering. Normally, when @var{minibuf}
The optional argument @var{all-frames} has the same meaning as in
@code{next-window}, but the @var{minibuf} argument of @code{next-window}
is always effectively @code{nil}. This function returns @code{nil}.
+
+This function does not select a window that has a non-@code{nil}
+@code{no-other-window} window parameter (@pxref{Window Parameters}).
@end deffn
The following function returns a copy of the list of windows in the
@code{nil}.
@end defun
-Next we describe the basic, low-level function to associate a window
-with a buffer. Higher-level functions like @code{display-buffer} try to
-obey a number of user customizations regulating which windows are
-supposed to display which buffers. When writing an application,
-programmers should therefore carefully evaluate whether they really need
-the power of this function.
+The basic, low-level function to associate a window with a buffer is
+@code{set-window-buffer}. Higher-level functions like
+@code{display-buffer} try to obey a number of user customizations
+regulating which windows are supposed to display which buffers. When
+writing an application, programmers should therefore carefully evaluate
+whether they really need the power of this @code{set-window-buffer}.
@defun set-window-buffer window buffer-or-name &optional keep-margins
This function makes @var{window} display @var{buffer-or-name} and
start and point positions of buffers which should handle viewing one and
the same buffer in multiple windows more easily.
+
@node Displaying Buffers
@section Choosing a Window for Displaying a Buffer
works, how to customize its behavior, and how to get rid of the chosen
window once it is no more needed.
-@deffn Command display-buffer &optional buffer-or-name specifiers ignore
+@deffn Command display-buffer &optional buffer-or-name specifiers label
This command makes the buffer specified by @var{buffer-or-name} appear
in some window, but it does not necessarily select that window or make
-the buffer current. It returns the window chosen to display the buffer
-or @code{nil} if no such window can be found.
+the buffer current. It returns the window chosen to display the buffer,
+@code{nil} if no such window can be found.
- The optional argument @var{buffer-or-name} has to specify a buffer or
+The optional argument @var{buffer-or-name} has to specify a buffer or
the name of a buffer and defaults to the current buffer. If
@var{buffer-or-name} is a string that does not name an existing buffer,
@code{display-buffer} creates a buffer with that name. When called
interactively, it prompts for a buffer name in the minibuffer.
- The optional argument @var{specifiers} is usually a list of buffer
-display specifiers, see below. For convenience, @var{specifiers} may
-also consist of a single location specifier or @code{t}, where the
-latter means to display the buffer in any but the selected window. If
-@var{specifiers} is @code{nil} or omitted, this means to exclusively use
-the values provided by the variables @code{display-buffer-names} and
-@code{display-buffer-regexps} described below. If their values are nil
+The optional argument @var{specifiers} is usually a list of buffer
+display specifiers, see the description of @code{display-buffer-alist}
+below. For convenience, @var{specifiers} may also consist of a single
+macro specifier or @code{t}, where the latter means to display the
+buffer in any but the selected window. If @var{specifiers} is
+@code{nil} or omitted, this means to exclusively use the values provided
+by the variable @code{display-buffer-alist}. If that variable is nil
too, default specifiers are used.
- The @code{not-this-window} specifier described below allows as
-@sc{cdr} also to specify an arbitrary window. This means that the
-window specified here shall not be used for displaying the buffer. The
-@code{not-this-frame} specifier described below allows as @sc{cdr} to
-also specify an arbitrary frame. This means that the frame specified
-here shall not be used for displaying the buffer.
-
-The optional third argument @var{ignore} is ignored.
+The optional third argument @var{label}, if non-@code{nil}, is a symbol
+specifiying the buffer display label. Applications should set this when
+the buffer shall be displayed in some special way but
+@var{buffer-or-name} alone does not identify the buffer as special.
+Typical buffers that fit into this category are those whose names are
+derived from the name of the file they are visiting. A user can then
+override @var{specifiers} by adding an entry to
+@code{display-buffer-alist} whose @sc{car} contains @var{label} and
+whose @sc{cdr} specifies the preferred alternative display method.
@end deffn
Precisely how @code{display-buffer} finds or creates a window depends on
-the @var{specifiers} argument and the three variables described next.
-
-@defopt display-buffer-names
-The value of this option is a list associating buffer names with buffer
-display specifiers. The @sc{car} of each element of this list is a list
-specifying a set of buffer names. A buffer whose name is a member of
-that set is handled by @code{display-buffer} according to the list of
-specifiers that form the @sc{cdr} of the element.
+the @var{specifiers} argument and the two variables described next.
-@cindex buffer display specifier
-@cindex location specifier
-A @dfn{buffer display specifier} is a symbol, a cons cell, or a list,
-telling @code{display-buffer} where or how to display a given buffer. A
-buffer display specifier that is a symbol provides the location where
-the buffer shall be displayed. Three location specifiers are
-predefined:
+@defopt display-buffer-alist
+@cindex buffer identifier
+The value of this option is a list associating buffer identifiers with
+buffer display specifiers. The @sc{car} of each element of this list is
+built from cons cells called @dfn{buffer identifiers}. The function
+@code{display-buffer} shows a buffer according to the display specifiers
+in the element's @sc{cdr} (elements are true lists) if at least one of
+these buffer identifiers matches the first or third argument of
+@code{display-buffer}. Such a match occurs in one of the following
+three cases:
@itemize @bullet
@item
-@code{same-window} stands for the selected window,
+The @sc{car} of the buffer identifier is the symbol @code{name} and its
+@sc{cdr} is a string equalling the name of the buffer specified by the
+@var{buffer-or-name} argument of @code{display-buffer}.
@item
-@code{same-frame} for a window on the selected frame,
+The @sc{car} is the symbol @code{regexp} and the @sc{cdr} is a regular
+expression matching the name of the buffer specified by the first
+@var{buffer-or-name} argument of @code{display-buffer}.
@item
-@code{other-frame} for a window on another frame.
+The @sc{car} is the symbol @code{label} and the @sc{cdr} is a symbol
+equalling the @var{label} argument of @code{display-buffer}.
@end itemize
-Any other symbol with a function definition means to call that function
-to display the buffer. The function is called with two arguments - the
-buffer to display and a list of specifiers - and is supposed to display
-the buffer and return the window used for that purpose. That function
-is also responsible for giving the variable @code{display-buffer-window}
-a meaningful value, see below for an explanation. Moreover, the
-function should set up the @code{quit-restore} window parameter which is
-required for proper functioning of the command
-@code{quit-restore-window}, see below.
-
- It's in general a bad idea to call @code{display-buffer} within the
-body of this function since this might lead to infinite recursion. If
-you do need to call @code{display-buffer} from it, consider setting the
-option @code{display-buffer-function} described below.
+@cindex buffer display specifier
+@cindex method specifier
+A @dfn{buffer display specifier} is a symbol, a cons cell, or a list,
+telling @code{display-buffer} where and how to display a given buffer.
+Four specifiers allow to indicate the basic method for displaying the
+buffer: @code{reuse-window}, @code{pop-up-window}, @code{pop-up-frame}
+and @code{use-side-window}.
- The remaining buffer display specifiers are cons cells or lists whose
-@sc{car} is one of the symbols listed next.
+ A list whose @sc{car} is the symbol @code{reuse-window} indicates
+that an existing window shall be reused for displaying the buffer. The
+second element of this list specifies the window to reuse and can be one
+of the following symbols:
@itemize @bullet
@item
-@code{not-this-window} with a non-@code{nil} @sc{cdr} means that the
-selected window shall not be used for displaying the buffer.
+@code{nil} stands for any window.
@item
-@code{reuse-buffer-window} specifies whether a window currently showing
-the buffer may be returned and which frame that window must be on. The
-possible values for the @sc{cdr} and their meanings are:
+@code{same} stands for the selected window.
-@itemize @minus
@item
-@code{never} means to never reuse a window showing the buffer.
+@code{other} stands for any but the selected window.
+@end itemize
-@item
-@code{nil} means to stay on the selected frame.
+The third element specifies whether the buffer shown in the window that
+shall be reused must be the same buffer that shall be displayed or
+another buffer and can be one of the following:
+@itemize @bullet
@item
-@code{visible} means to consider visible frames only.
+@code{nil} means to not care about the window's buffer.
@item
-0 (the number zero) means that any such window must be on a visible or
-iconified frame.
+@code{same} means the window must show the buffer already.
@item
-@code{t} means the window may be on an arbitrary frame, including
-invisible ones.
+@code{other} means the window must not show the buffer yet.
@end itemize
- Observe that the @code{not-this-window} specifier (and the
-@code{not-this-frame} specifier described below) with a non-@code{nil}
-@sc{cdr} forbid reusing the selected window disregarding what is
-specified here.
+The fourth element specifies the set of frames to search for a suitable
+window and can be one of the following:
+@itemize @bullet
@item
-@code{reuse-other-window} specifies whether a window currently
-@emph{not} showing the buffer may be returned and which frame that
-window must be on. The possible values for the @sc{cdr} are the same
-as for the @code{reuse-buffer-window} specifier.
-@end itemize
+@code{nil} to stay on the selected frame.
@item
-@code{even-window-sizes} with a non-@code{nil} @sc{cdr} means to even
-the sizes of any window reused for displaying the buffer with the size
-of the selected window, provided these windows are adjacent to each
-other and the selected window is larger than the reused one.
+@code{visible} to search visible frames only.
-The additional specifiers listed so far are useful if the location
-specifier equals @code{same-frame} or @code{other-frame}. The
-specifiers we describe next are mainly useful in the @code{same-frame}
-case.
+@item
+@code{other} stands for any visible frame but the selected one.
-@itemize @bullet
@item
-@code{new-window} specifies how a new window shall be made on the
-selected frame. This specifier is a list whose @sc{car} is the symbol
-@code{new-window}. The @sc{cdr} consists of window/side pairings, that
-is, cons cells whose @sc{car} identifies the window that shall be split.
-Currently recognized are the symbols @code{largest}, @code{lru},
-@code{selected}, @code{root} and @code{first} to respectively split the
-largest, least recently used, selected, root or first window of the
-selected frame.
+0 (the number zero) to search visible and iconified frames.
- The @sc{cdr} of such a pairing specifies on which side of the window
-to split the new window shall appear and can be one of the symbols
-@code{below}, @code{right}, @code{above}, or @code{left} with the
-obvious meanings. If the @sc{cdr} is @code{nil}, the window is split in
-a fashion suitable for the current dimensions of the window to split.
-If the @sc{cdr} specifies a function, that function is called with two
-arguments - the window to split and a list of buffer display specifiers.
-The function is supposed to split that window and return the new window.
+@item
+@code{t} to search arbitrary frames including invisible ones.
+@end itemize
- The pairings will be tried by @code{display-buffer} in turn until
-either a suitable window is found or creating a new window fails. The
-default value for the option @code{display-buffer-regexps}, see below,
-uses
+If more than one window fits the constraints imposed by these elements,
+the least recently used among them is chosen. A side window
+(@pxref{Side Windows}) is reused if and only if it already shows the
+buffer that shall be displayed.
-@example
-@code{(new-window (largest . nil) (lru . nil))}
-@end example
+Two specifiers are useful when the method equals @code{reuse-window}:
-in order to try splitting the largest window first and, if that fails,
-the least recently used one.
+@itemize @bullet
+@item
+A cons cell whose @sc{car} is the symbol @code{reuse-window-even-sizes}
+and whose @sc{cdr} is non-@code{nil} means to even out the sizes of the
+reused and the selected window provided they (1) are adjacent to each
+other and (2) the selected window is larger than the window chosen. If
+the @sc{cdr} is @code{nil}, this means that the window sizes are left
+alone.
@item
-The symbols @code{min-height} and @code{min-width}. In this case, the
-@sc{cdr} must be a number specifying the minimum height or width of a
-new window to display the buffer. An integer number specifies the
-minimum number of lines or columns of the new window. A floating point
-number gives the minimum fraction of the window's size with respect to
-the frame's root window.
+A cons cell whose @sc{car} is the symbol @code{reuse-window-dedicated}
+and whose @sc{cdr} is non-@code{nil} means that a window can be reused
+even if it's dedicated to its buffer. If the @sc{cdr} is @code{t}, a
+strongly dedicated window can be reused to show the buffer. Any other
+non-@code{nil} value means only weakly dedicated windows can be reused.
+If the @sc{cdr} is @code{nil}, dedicated windows are not reused.
+
+This specifier should be used in special cases only since windows are
+usually made dedicated in order to prevent @code{display-buffer} from
+reusing them.
+@end itemize
-A new window will be made if and only if it can be made at least as
-large as specified by the number. As a special case, if a window is the
-only window on its frame, it can be split vertically regardless of the
-value specified by the @code{min-height} specifier. Reusing a window or
-making a new frame are not affected by these specifiers.
+A list whose @sc{car} is the symbol @code{pop-up-window} and whose
+@sc{cdr} is built from window/side tuples indicates that a new window
+shall be made for displaying the buffer on the selected frame.
+
+Window/side tuples are cons cells. The @sc{car} of such a tuple
+identifies the window that shall be split. Possible values are
+@code{largest}, @code{lru}, @code{selected}, and @code{root} to
+respectively split the largest, least recently used, selected or root
+window of the selected frame.
+
+The @sc{cdr} of each pair specifies on which side of the window to split
+the new window shall appear and can be one of @code{below},
+@code{right}, @code{above}, or @code{left} with the obvious meanings.
+If the @sc{cdr} is @code{nil}, the window is split in a fashion suitable
+for its current dimensions. If the @sc{cdr} specifies a function, that
+function is called with two arguments - the window to split and a list
+of display specifiers. The function is supposed to split that window
+and return the new window.
+
+The function @code{display-buffer} scans these tuples until it can
+either produce a suitable window or fails. The default value for
+@code{display-buffer-alist} contains the tuples
+@smallexample
+(largest . nil) (lru . nil)
+@end smallexample
+
+in order to split the largest window first and, if that fails, the least
+recently used one.
+
+The following additional specifiers are useful with the
+@code{pop-up-window} method specifier.
+
+@itemize @bullet
+@item
+A cons cell whose @sc{car} is the symbol @code{pop-up-window-min-height}
+specifies the minimum height of the new window. If the @sc{cdr} is an
+integer number, it specifies the minimum number of lines of the window.
+A floating point number gives the minimum fraction of the window height
+with respect to the height of the frame's root window. A new window is
+created only if it can be made at least as high as specified by the
+number. If the @sc{cdr} is @code{nil}, this means to use the value of
+@code{window-min-height}.
@item
-The symbol @code{split-unsplittable-frame} with a non-@code{nil}
-@sc{cdr} allows to make a new window on an unsplittable frame. This
-specifier should be used in special cases only since frames are usually
-unsplittable in order to prevent @code{display-buffer} from splitting
-them (@pxref{Buffer Parameters}).
+A cons cell whose @sc{car} is the symbol @code{pop-up-window-min-width}
+specifies the minimum width of the new window. If the @sc{cdr} is an
+integer number, it specifies the minimum number of columns of the
+window. A floating point number gives the minimum fraction of the
+window width with respect to the width of the frame's root window. A
+new window is created only if it can be made at least as wide as
+specified by the number. If the @sc{cdr} is @code{nil}, the value of
+@code{window-min-width} is used.
@item
-@code{adjust-height} with the following semantics for the @sc{cdr}:
+A cons cell whose @sc{car} is @code{pop-up-window-set-height} with
+the following interpretations for the @sc{cdr}:
@itemize @minus
@item
-@code{nil} means do not adjust the height of the new window.
+@code{nil} means leave the height of the new window alone.
@item
-A number specifies the height of the new window. An integer number
-specifies the desired number of lines of the new window. A floating
-point number gives the desired fraction of the window's height with
-respect to the frame's root window.
+A number specifies the desired height of the new window. An integer
+number specifies the number of lines of the window. A floating point
+number gives the fraction of the window's height with respect to the
+height of the frame's root window.
@item
-A function to call for adjusting the height of the new window. The
-function is called with one argument, the new window. Its return value
-is ignored. Suitable candidates are
-@code{shrink-window-if-larger-than-buffer} and
-@code{fit-window-to-buffer}.
+If the @sc{cdr} specifies a function, that function is called with one
+argument - the new window. The function is supposed to adjust the
+height of the window; its return value is ignored. Suitable functions
+to call here are @code{shrink-window-if-larger-than-buffer} and
+@code{fit-window-to-buffer}, see @ref{Resizing Windows}.
@end itemize
@item
-@code{adjust-width} with the following semantics for the @sc{cdr}:
+A cons cell whose @sc{car} equals @code{pop-up-window-set-width}
+with the following interpretations for the cdr:
@itemize @minus
@item
-@code{nil} means do not adjust the width of the new window.
+@code{nil} means leave the width of the new window alone.
@item
-A number specifies the width of the new window. An integer number
-specifies the desired number of columns of the new window. A floating
-point number gives the desired fraction of the window's width with
-respect to the frame's root window.
+A number specifies the desired width of the new window. An integer
+number specifies the number of columns of the window. A floating point
+number gives the fraction of the window's width with respect to the
+width of the frame's root window.
@item
-A function to call for adjusting the width of the new window. The
-function is called with one argument, the new window. Its return value
-is ignored.
+If the @sc{cdr} specifies a function, that function is called with one
+argument - the new window. The function is supposed to adjust the width
+of the window; its return value is ignored.
@end itemize
-Observe that a non-@code{nil} value for the @sc{cdr} of
-@code{adjust-height} or @code{adjust-width} can override restrictions
-given earlier by the @code{min-height} and @code{min-width} specifiers.
+Observe that specifying @code{pop-up-window-set-height} and
+@code{pop-up-window-set-width} may override restrictions given by the
+@code{pop-up-window-min-height} and @code{pop-up-window-min-width}
+specifiers.
+
+@item
+A cons cell whose @sc{car} is @code{pop-up-window-split-unsplittable}
+and whose @sc{cdr} is non-@code{nil} allows to make a new window on an
+unsplittable frame. If the @sc{cdr} is @code{nil}, unsplittable frames
+are not split. This specifier should be used in special cases only
+since frames are usually made unsplittable in order to prevent
+@code{display-buffer} from splitting them.
+@end itemize
+
+A list of two elements whose @sc{car} is the symbol @code{pop-up-frame}
+states that a new frame shall be made for displaying the buffer. The
+second element of this list, if non-nil, allows to make a new frame on
+graphic displays only.
+
+The following additional specifiers are useful with the
+@code{pop-up-frame} method specifier.
+
+@itemize @bullet
+@item
+A list whose @sc{car} is the symbol @code{popup-frame-function} together
+with a valid function as @sc{cdr} specifies the function for creating a
+new frame. If the @sc{cdr} is @code{nil}, the default function
+@code{make-frame} is called. The function is called with the parameters
+and values provided by the specifier described next.
+
+@item
+A list whose @sc{car} is the symbol @code{popup-frame-alist} followed by
+an arbitrary number of frame parameter/value tuples, each given as a
+cons cell, specifies the parameters passed to the popup frame function.
@end itemize
-The following specifiers are useful when the location is specified as
-@code{other-frame}:
+A list of three elements whose @sc{car} is the symbol
+@code{use-side-window} specifies that the buffer shall be displayed in a
+side window (@pxref{Side Windows}) of the selected frame. The second
+element denotes the side of the frame where the window shall appear and
+must be one of @code{left}, @code{top}, @code{right} and @code{bottom}.
+If no window on the specified side exists yet, @code{display-buffer}
+creates one.
+
+The third element is a number and denotes the slot within the specified
+side. Slots are numbers where the number zero stands for the window in
+the middle of the side. A slot less than zero indicates that the window
+shall be shown on the left (for the top and bottom side window) or above
+(for the left and right side window) of the window in the middle. A
+slot larger than zero indicates that the window shall be shown on the
+right (for the top and bottom side window) or below (for the left and
+right side window) of the window in the middle.
+
+If a side window with the specified slot exists already and is not
+dedicated to its buffer, @code{display-buffer} reuses that window. If
+no such window exists, @code{display-buffer} tries to make a new window
+with the specified slot by splitting the side window with the nearest
+matching slot. If creating a new side window is impossible,
+@code{display-buffer} tries to reuse the side window with the nearest
+matching slot. The option @code{window-sides-slots} (@pxref{Side
+Windows}) can be used to restrict the number of windows on each side.
+
+In conjunction with the @code{use-side-window} method specifier, the
+specifiers @code{reuse-window-dedicated},
+@code{pop-up-window-min-height}, @code{pop-up-window-min-width},
+@code{pop-up-window-set-height} and @code{pop-up-window-set-width}
+described above can be used.
+
+Instead of writing method specifiers it's often more convenient to use a
+predefined macro specifier. The following macro specifiers are
+provided:
@itemize @bullet
@item
-@code{not-this-frame} with a non-@code{nil} @sc{cdr} means that the
-selected frame shall not be used for displaying the buffer.
+@code{same-frame} to make or use a window on the selected frame.
@item
-@code{graphic-only} with a non-@code{nil} @sc{cdr} means that a new
-frame shall be made on graphic displays only.
+@code{other-window} to make or use any window but the selected one.
@item
-@code{popup-frame-function} together with a valid function as @sc{cdr}
-specifies the function for creating a new frame. By default,
-@code{make-frame} is called here. The function is called with the
-parameters and values provided by the specifier described next.
+@code{same-frame-other-window} to make or use any window on the
+selected frame with exception of the selected window.
@item
-@code{popup-frame-alist} followed by an arbitrary number of frame
-parameter/value pairs, each given as a cons cell, specifies the
-parameters passed to the popup frame function. For convenience, this
-specifier is not a cons cell but a list whose first element is the
-symbol @code{popup-frame-alist} and whose remaining elements are pairs
-of parameters and values.
+@code{other-visible-frame} to make sure the window appears on any
+visible frame but the selected one.
+
+@item
+@code{default} to use the specifier of the default value of
+@code{display-buffer-alist} as described below.
@end itemize
- It's also possible to specify whether the window chosen shall become
-dedicated to the buffer (@pxref{Dedicated Windows}). This is
+In addition it's possible to specify whether the window chosen shall
+become dedicated to the buffer (@pxref{Dedicated Windows}). This is
accomplished with the help of a cons cell whose @sc{car} is the symbol
@code{dedicated} and whose @sc{cdr} is one of the following values:
@code{nil} which means to not dedicate the window to the buffer,
@item
-@code{weak} which means the window shall be weakly dedicated to
-its buffer, or
+@code{weak} which means the window shall be weakly dedicated to its
+buffer, or
@item
@code{t} to strongly dedicate the window to the buffer.
@end itemize
- In general, an application is free to ignore the specifiers of
-@code{display-buffer-names} by explicitly passing a non-@code{nil}
+Moreover you can specify whether the function @code{other-window}
+(@pxref{Cyclic Window Ordering}) is allowed to select the window used
+for displaying the buffer. This is accomplished with the help of a cons
+cell whose @sc{car} is the symbol @code{no-other-window} and whose
+@sc{cdr} is non-@code{nil}.
+
+In general, an application is free to ignore the specifiers of
+@code{display-buffer-alist} by explicitly passing a non-@code{nil}
second argument to @code{display-buffer}. For any
-@code{display-buffer-names} entry one can, however, add a cons cell
+@code{display-buffer-alist} entry one can, however, add a cons cell
whose @sc{car} is the symbol @code{override} and whose @sc{cdr} is
non-@code{nil} to explicitly override the value supplied by the
application.
- Overriding arguments supplied by the calling application is, in
-general, not advisable. It permits, for example, to change the
-semantics of a command like @code{switch-to-buffer-other-window} by
-setting the method specifier to @code{same-window} or
-@code{other-frame}.
+Overriding arguments supplied by the calling application is, in general,
+not advisable. It permits, for example, to change the semantics of
+commands like @code{switch-to-buffer-other-window} by setting the method
+specifier to @code{same-window} or @code{other-frame}.
@end defopt
-@defopt display-buffer-regexps
-The value of this option is a list associating regular expressions with
-buffer display specifiers. The @sc{car} of each element of this list is
-a list of regular expressions. Buffers whose names match that
-expression are displayed according to the list of specifiers
-constituting the @sc{cdr} of the element. For a description of the
-@sc{cdr} see the description of @code{display-buffer-names} above.
-
-This variable has the following default value:
+The value of @code{display-buffer-alist} may contain scalar elements
+which are used by the customization interface and are ignored by
+@code{display-buffer}. The normalized default specifiers are:
@example
-(((".*")
- same-frame
- (reuse-buffer-window)
- (adjust-height . even-window-sizes)
- (largest) (lru)
- (min-height . 24) (min-width . 60)
- other-frame
- (reuse-buffer-window . visible)
- (graphic-only . t)
- (popup-frame-alist
- (height . 24) (width . 80) (unsplittable . t))))
+ ((reuse-window nil same visible)
+ (pop-up-window
+ (largest)
+ (lru))
+ (pop-up-frame)
+ (pop-up-frame-alist
+ (height . 24)
+ (width . 80)
+ (unsplittable . t))
+ (reuse-window nil other visible)
+ (reuse-window-even-sizes . t))
@end example
-It means that buffers shall be displayed preferably on the selected
-frame. If the buffer is already shown on that frame,
-@code{display-buffer} returns the corresponding window. Otherwise, it
-tries to split the largest or the least recently used window with the
-new window below or on the right of the window that is split. The
-minimum height of the new window shall be 24 lines, its minimum width 60
-columns. If a window above or below the selected window is used, the
-heights of both windows shall be evened out.
-
- If these specifiers fail to produce a window, @code{display-buffer}
-tries to show the buffer on a new frame unless a window showing the
-buffer can be found on some visible frame. The default function to pop
-up a new frame (@code{make-frame}) is given three parameters: A height
-of 24 lines, a width of 80 columns, and a non-@code{nil} unsplittable
-property. On text-only displays, @code{display-buffer} will not try to
-show the buffer on another frame.
-@end defopt
+It means to proceed as follows:
-@defopt display-buffer-function
-This variable is the most flexible way to customize the behavior of
-@code{display-buffer}. If it is non-@code{nil}, it should be a function
-that @code{display-buffer} calls to do the work. The function must
-accept two arguments, the buffer to display and a list of buffer display
-specifiers.
+@itemize @bullet
+@item
+First try reusing a window showing the buffer on the selected frame
+(provided it's visible). If a window above or below the selected window
+is reused, the heights of those windows are evened out.
- It should choose or create a window, display the specified buffer in
-it, and then return the window. It is also responsible for giving the
-variable @code{display-buffer-window} a meaningful value, see below for
-an explanation. Moreover, the function should set up the
-@code{quit-restore} window parameter which is required for proper
-functioning of the command @code{quit-restore-window}, see below.
+@item
+Next try to pop up a window on the selected frame by splitting either
+the largest or the least recently used window in a system dependent way.
- The function specified here is free to ignore any specifiers passed to
-it as second argument. If you intend to call @code{display-buffer}
-within the body of that function, it's a good idea to bind
-@code{display-buffer-function} to @code{nil} around each such call to
-avoid running into an infinite recursion.
-@end defopt
+@item
+Try to pop up a new frame. The default function to pop up a new frame
+(@code{make-frame}) is given three parameters: A height of 24 lines, a
+width of 80 columns, and a non-@code{nil} unsplittable property.
+@end itemize
- In order to understand how @code{display-buffer} combines the values
-of @code{display-buffer-names} and @code{display-buffer-regexps} with
-the @var{specifiers} argument consider the following settings (in our
-examples we generally assume that @code{display-buffer-function}
-is @code{nil}). Suppose the value of @code{display-buffer-names} has
-been specified as
+If these specifiers fail to produce a suitable window,
+@code{display-buffer} uses a number of heuristics that do not
+necessarily observe the value of @code{display-buffer-alist}.
+
+An application calling @code{display-buffer} can, in some cases, replace
+static references to windows or buffers within display specifiers by
+dynamic references to objects like windows or buffers. In particular
+the following are possible:
+
+@itemize @bullet
+@item
+The @code{reuse-window} specifier accepts as second element a live
+window and as third element a live buffer.
+
+@item
+In window/side tuples of the @code{pop-up-window} specifier an arbitrary
+window can be used as first element.
+@end itemize
+
+In order to understand how @code{display-buffer} combines the values of
+@code{display-buffer-alist} with the @var{specifiers} argument suppose
+the following element
@example
-((("*text*")
- same-frame (reuse-buffer-window . none)
- (new-window (selected . below) (root . below))
+(((name . "*text*"))
+ ((pop-up-window (selected . below) (root . below))
(override . t)))
@end example
-the value of @code{display-buffer-regexps} is the default value, and
-@code{display-buffer} is called as
+has been added to @code{display-buffer-alist} and @code{display-buffer}
+is called as
@example
-(display-buffer "*text*" 'same-window)
+(display-buffer "*text*" '((reuse-window same)))
@end example
-Since the entry from @code{display-buffer-names} matches the buffer name
+Since the entry from @code{display-buffer-alist} matches the buffer name
and has the @code{override} specifier set, @code{display-buffer} will
-first try to display the buffer on the selected frame. Reusing any
-window showing the buffer is forbidden, so @code{display-buffer} will
-try to split either the selected or the frame's root window (if the
-frame has only one window these are one and the same window). The
-minimum height (width) of the new window is 24 lines (60 columns) and
-are taken from @code{display-buffer-regexps} since
-@code{display-buffer-names} does not supply any values for these
-specifiers.
+first try to split either the selected or the root window of the
+selected frame.
If neither of these windows can be split, @code{display-buffer} will
try to display the buffer in the selected window as requested by the
@var{specifiers} argument. If this fails as well, for example, because
the selected window is dedicated to another buffer,
@code{display-buffer} will apply the default specifiers from
-@code{display-buffer-regexps} as sketched above. Observe that in this
+@code{display-buffer-alist} as sketched above. Observe that in this
case @code{display-buffer} will not necessarily try to split the
selected or the frame's root window because the corresponding specifiers
-from @code{display-buffer-names} have been already consumed at that
+from @code{display-buffer-alist} have been already consumed at that
time.
So the order of precedence is to try the overriding specifiers from
-@code{display-buffer-names} first, followed by overriding specifiers
-from @code{display-buffer-regexps}. Next come the specifiers from the
+@code{display-buffer-alist} first. Next come the specifiers from the
@var{specifiers} argument of @code{display-buffer}. Finally,
-non-overriding specifiers from @code{display-buffer-names} and
-@code{display-buffer-regexps} are tried.
-
- If neither of these methods is able to produce a suitable window,
-@code{display-buffer} applies a number of built-in methods, overriding
-specifiers like @code{reuse-buffer-window} or @code{reuse-other-window},
-if necessary.
+non-overriding specifiers from @code{display-buffer-alist} are tried.
In case you observe any unexpected behavior of @code{display-buffer}
-keep in mind the following issues:
+keep in mind the following:
@itemize @bullet
@item
-Specifiers are consumed in the order sketched above. When
-@code{display-buffer} applies a location specifier, any specifiers
-preceding that location specifier have been consumed already, that is
-they do not affect the work of @code{display-buffer} any more.
-
- Specifiers following a location specifier are applied in the order
-given, which means that the value of the first specifier encountered
-prevails. If you want to make sure that, for example, buffer windows
-are not reused as specified by the default value of
-@code{display-buffer-regexps}, use a @code{reuse-buffer-window}
-specifier with a @code{none} @sc{cdr} as in the display-buffer-names
-example above.
+Specifiers are consumed in the order sketched above, which means that
+the value of the first specifier found prevails. When
+@code{display-buffer} applies a method specifier, any specifiers
+preceding the method specifier have been consumed already and do no more
+affect the work of @code{display-buffer}.
@item
Displaying a buffer on a new or other frame will always raise that frame
-and give it input focus. This contrasts with earlier definitions of
+and give it input focus. This contrasts with the behavior of
@code{display-buffer} up to Emacs 22. While not raising the frame seems
like a worthwhile scope in this case, it has not been pursued any longer
-due to possible bad interaction with window mangers on various
+due to possible bad interaction with window managers on various
platforms.
@item
The customization interface does not allow to assign every conceivable
-value to the options @code{display-buffer-names} and
-@code{display-buffer-regexps}. You have to set these by hand to achieve
-more exotic behavior.
+value to the option @code{display-buffer-alist}. You have to set these
+by hand to achieve more exotic behavior.
@end itemize
Next we describe how to transcribe the buffer display options of
-Emacs 23 with @code{display-buffer-names} and
-@code{display-buffer-regexps}.
+Emacs 23 with @code{display-buffer-alist}.
@itemize @bullet
@item
-For @code{display-buffer-function} supply the function named there as
-location specifier.
-
-@item
-@code{same-window-buffer-names} and @code{same-window-regexps} are
-handled by adding a @code{same-window} specifier.
+The options @code{same-window-buffer-names} and
+@code{same-window-regexps} are handled by the @code{same-window} macro
+specifier.
@item
-For @code{display-buffer-reuse-frames} use the
-@code{reuse-buffer-window} specifier with an appropriate @sc{cdr}.
+For @code{display-buffer-reuse-frames} use the @code{reuse-window}
+specifier with a non-@code{nil} third element and as fourth element the
+set of frames that should be considered.
@item
-@code{special-display-buffer-names} and @code{special-display-regexps}
-are replaced by @code{display-buffer-names} and
-@code{display-buffer-names} because, in a sense, all buffers are special
-now.
+The options @code{special-display-buffer-names} and
+@code{special-display-regexps} are replaced by
+@code{display-buffer-alist} itself because, in a sense, all buffers are
+special now.
@item
-@code{special-display-function} is emulated either by using a function
-as location specifier or by setting the @code{pop-up-frame-function}
-specifier appropriately.
+The @code{special-display-function} option is emulated by setting the
+@code{pop-up-frame-function} specifier.
@item
-@code{special-display-frame-alist} is now handled by the
+The @code{special-display-frame-alist} option is now handled by the
@code{popup-frame-alist} specifier.
@item
-To handle @code{pop-up-frames} use the @code{other-frame} location
-specifier and the @code{graphic-only} specifier.
+The option @code{pop-up-frames} is replaced by the @code{pop-up-frame}
+method specifier.
@item
-@code{pop-up-frame-function} has become the homonymous specifier. It
-must now handle arguments as specified by the @code{pop-up-frame-alist}
-specifier, though.
+The option @code{pop-up-frame-function} has become the homonymous
+specifier.
@item
-@code{pop-up-frame-alist} has become the homonymous specifier.
+The option @code{pop-up-frame-alist} has become the homonymous specifier.
@item
-@code{pop-up-windows} is handled by the @code{new-window} specifier.
+The option @code{pop-up-windows} is replaces by the @code{pop-up-window}
+method specifier.
@item
-@code{split-window-preferred-function} can be specified as second
-argument of window / side pairings. The semantics of the argument have
-not changed.
+A @code{split-window-preferred-function} can be specified as the second
+in a window/side tuple of the @code{pop-up-window} specifier.
@item
-@code{split-height-threshold} and
-@code{split-width-threshold} are handled by the @code{min-height} and
-@code{min-width} specifiers respectively. The sizes you specify there
-are, however, no more the original sizes of the window to split but
-the desired minimum sizes of the new window.
+@code{split-height-threshold} and @code{split-width-threshold} are
+handled by the @code{pop-up-window-min-height} and
+@code{pop-up-window-min-width} specifiers respectively. The sizes you
+specify there are, however, no more the original sizes of the window to
+split but the desired minimum sizes of the new window.
@item
@code{even-window-heights} is handled by setting the @sc{cdr} of the
-@code{even-window-sizes} specifier to a non-@code{nil} value.
+@code{reuse-window-even-sizes} specifier to a non-@code{nil} value.
@end itemize
-The following functions are simple variations of @code{display-buffer}.
+@defopt display-buffer-function
+This variable is the most flexible way to customize the behavior of
+@code{display-buffer}. If it is non-@code{nil}, it should be a function
+that @code{display-buffer} calls to do the work. The function must
+accept two arguments, the buffer to display and a list of normalized
+buffer display specifiers as produced by
+@code{display-buffer-normalize-specifiers}, see below.
+
+It should choose or create a window, display the specified buffer in it,
+and then return the window. It is also responsible for giving the
+variable @code{display-buffer-window} a meaningful value, see below for
+an explanation. Moreover, the function should set up the
+@code{quit-restore} window parameter which is required for proper
+functioning of the command @code{quit-restore-window}, see below.
+
+The function specified here is free to ignore any specifiers passed to
+it as second argument. If you intend to call @code{display-buffer}
+within the body of the function specified here, it's a good idea to bind
+@code{display-buffer-function} to @code{nil} around each such call to
+avoid running into an infinite recursion.
+@end defopt
+
+The function @code{display-buffer} tries hard to find a new window for
+displaying the buffer and fails (that is, returns @code{nil}) only in
+rare cases. The functions described next are called by
+@code{display-buffer} but can be occasionally useful for applications
+that want more deterministic behavior. These functions must be called
+with normalized specifiers which means that all macro specifiers must
+have been already expanded and the scalar symbols used by the
+customization interface removed. To get normalized specifiers you can
+use the function described next.
+
+@defun display-buffer-normalize-specifiers buffer-name specifiers label
+This function returns the normalized specifiers for a buffer matching
+@var{buffer-name} or @var{label}. The argument @var{buffer-name} must
+be a string specifying a valid buffer name. The arguments
+@var{specifiers} and @var{label} are the homonymous arguments of
+@code{display-buffer}.
+@end defun
+
+In the four functions described next, the optional argument
+@var{specifiers} must be a list of normalized buffer display specifiers
+as returned by @code{display-buffer-normalize-specifiers}. These
+functions return the window displaying the @var{buffer} if they
+succeeded, @code{nil} otherwise.
+
+@defun display-buffer-reuse-window buffer method &optional specifiers
+This function tries to display @var{buffer} in an existing window. The
+argument @var{method} must be a list in the form of the @sc{cdr} of a
+@code{reuse-window} buffer display specifier. The first element must
+specifiy the window to use, and can be either @code{nil}, @code{same},
+@code{other}, or a live window. The second element specifies whether
+the window's buffer must be the same as @var{buffer} or another one and
+can be either @code{nil}, @code{same}, @code{other}. It can be also a
+live buffer which means to reuse a window only if @var{buffer} is the
+buffer it displays. The third element is the frame to use - either
+@code{nil}, 0 (the number zero), @code{visible}, @code{t}, or a live
+frame.
+@end defun
+
+@defun display-buffer-pop-up-window buffer methods &optional specifiers
+This function tries to display @var{buffer} in a new window. The
+argument @var{methods} must be a list of window/side tuples like those
+forming the @sc{cdr} of the @code{pop-up-window} buffer display
+specifier. As a special case, the @sc{car} of such a tuple can be also
+a live window.
+@end defun
+
+@defun display-buffer-pop-up-frame buffer &optional graphic-only specifiers
+This function tries to make a new frame for displaying @var{buffer}.
+The optional argument @var{graphic-only} non-@code{nil} means to make a
+new frame on graphic displays only.
+@end defun
+
+@defun display-buffer-in-side-window buffer side &optional slot specifiers
+This function tries to display @var{buffer} in a window on @var{side} of
+the selected frame (@pxref{Side Windows}). The argument @var{slot}, if
+non-@code{nil}, specifies the window slot where to display the
+@var{buffer}. If @var{slot} is zero or @code{nil}, this means use the
+central slot on @var{side}. A negative value means to use a slot
+preceding the central window. A positive value means to use a slot
+following the central window.
+@end defun
+
+The following functions are simple interfaces to @code{display-buffer}.
@defun display-buffer-same-window &optional buffer-or-name
This function is like @code{display-buffer} but preferably displays the
has been reused), @code{reuse-other-window} (some other window has been
reused).
- If the location specifier is one of @code{same-window},
-@code{same-frame}, or @code{other-frame}, the @code{display-buffer} code
-itself sets the value of this variable. If the location specifier is a
-function, that function becomes responsible for assigning a meaningful
-value to this variable.
+If @code{display-buffer-function} is non-@code{nil}, the function called
+here becomes responsible for assigning a meaningful value to this
+variable. Otherwise, the @code{display-buffer} code takes care of this.
@end defvar
The command described next allows to quit the window chosen by
buffer.
The optional second argument @var{specifiers} must be a list of
-buffer display specifiers or a single location specifier, see the
-documentations of @code{display-buffer} and @code{display-buffer-names}.
+buffer display specifiers or a single macro specifier, see the
+documentations of @code{display-buffer} and @code{display-buffer-alist}.
If @var{specifiers} is @code{t}, it means to pop to the buffer in any
but the selected window. If @var{specifiers} is @code{nil} or omitted,
this means to exclusively use the values provided by
-@code{display-buffer-names} and @code{display-buffer-regexps}
-(@pxref{Displaying Buffers}). If their values are nil too, default
-specifiers are used.
+@code{display-buffer-alist} (@pxref{Displaying Buffers}). If their
+values are nil too, default specifiers are used.
The optional argument @var{norecord} is handled just as by
@code{switch-to-buffer}.
is the selected window.
@end defun
-Some functions, notably @code{split-window}, @code{delete-window}, and
-@code{delete-other-windows} behave specially when their @var{window}
-argument has a parameter set. The special behavior consists of a
-pre-operation step and a post-operation step.
+ A list of windows whose parameter equals some value is produced by
+the following function.
+
+@defun windows-with-parameter parameter &optional value frame any values
+This function returns a list of all windows on @var{frame} whose
+@var{parameter} is non-@code{nil}. The optional argument @var{frame}
+must denote a live frame and defaults to the selected one.
+
+If the optional argument @var{value} is non-@code{nil}, this means to
+only return windows whose @var{parameter} equals @var{value} (comparison
+is done using @code{equal}). Optional argument @var{any} non-@code{nil}
+means list internal windows a well. Optional argument @var{values}
+non-@code{nil} means return a list of cons cells whose @sc{car} is the
+value of the parameter and whose @sc{cdr} is the window.
+@end defun
-In the @dfn{pre-operation step}, the value of the parameter is analyzed
-and, if its value prescribes some special action, that action is
-executed. For example, the pre-operation step of @code{delete-window}
-when invoked on the main window of a compound window (@pxref{Compound
-Windows}) calls @code{delete-window} with the root window of the
-compound window as argument instead.
+ The first window with a specified parameter can be retrieved with the
+following function.
+
+@defun window-with-parameter parameter &optional value frame any
+This function returns the first window on @var{frame} whose
+@var{parameter} is non-@code{nil}. The optional argument @var{frame}
+must denote a live frame and defaults to the selected one.
+
+If the optional argument @var{value} is non-@code{nil}, this means to
+only return a window whose @var{parameter} equals @var{value}
+(comparison is done with @code{equal}). If the optional argument
+@var{any} is non-@code{nil}, this means to consider internal windows
+too.
+@end defun
-In the @dfn{post-operation step}, the parameters of all windows forming
-the new configuration are adjusted. For example, @code{split-window}
-when invoked on a main window of a window group (@pxref{Window Groups}),
-sets in this step the corresponding parameter of the new window.
+Some functions, notably @code{split-window}, @code{delete-window}, and
+@code{delete-other-windows} behave specially when their @var{window}
+argument has a parameter set. For example, @code{delete-window} when
+invoked on the main window of an atomic window (@pxref{Atomic Windows})
+calls @code{delete-window} with the root window of the atomic window as
+argument instead. The entire information for retrieving the appropriate
+root window is maintained with the help of window parameters.
You can override that special behavior by binding the following variable
to a non-@code{nil} value:
@code{split-window}, @code{delete-window}, @code{delete-other-windows}
and @code{other-window}.
-When this variable equals @code{pre}, the pre-operation step is skipped
-but the post-operation step is executed. When this variable equals
-@code{post}, the pre-operation step is executed and thee post-operation
-step is skipped.
-
-The value @code{t} means pre- and post-operation steps are skipped.
-Currently any other non-@code{nil} value is handled like @code{t}.
-
An application can bind this variable to a non-@code{nil} value around
-calls to these functions. If it does so and the value is not
-@code{pre}, the application is fully responsible for correctly setting
-the parameters of all remaining windows after the function exited.
+calls to these functions. If it does so, the application is fully
+responsible for correctly assigning the parameters of windows when
+exiting that function.
@end defvar
-Window parameters are mainly used for implementing composite windows,
-@xref{Composite Windows}. In particular, the @code{compound},
-@code{group} and @code{composite} parameters are reserved for that
-purpose.
+The following parameters are currently used by the window management
+code.
+
+@table @asis
+@item @code{window-atom}
+This symbol designates the associated window as part of an atomic
+window (@pxref{Atomic Windows}).
+
+@item @code{window-side}
+This symbol designates the associated window as part of a side or
+non-side window (@pxref{Side Windows}).
+
+@item @code{delete-window-function}
+This parameter is used by @code{delete-window} (@pxref{Deleting
+Windows}).
+
+@item @code{delete-other-windows-function}
+This parameter is used by @code{delete-other-windows} (@pxref{Deleting
+Windows}).
+
+@item @code{split-window-function}
+This parameter is used by @code{split-window} (@pxref{Splitting
+Windows}).
+
+@item @code{other-window-function}
+This parameter is used by @code{other-window} (@pxref{Cyclic Window
+Ordering}).
+
+@item @code{no-other-window}
+This parameter marks the window as not selectable by @code{other-window}
+(@pxref{Cyclic Window Ordering}).
+@end table
The @code{quit-restore} parameter tells how to proceed with a window
when the user ``quits'' it by invoking @code{quit-restore-window}, see
Quitting the window will then try to display the indicated buffer with
the given start position and point in that window.
-The fourth element, if non-@code{nil}, must denote a live buffer. If
+ The fourth element, if non-@code{nil}, must denote a live buffer. If
specified, quitting will restore the previous window contents if and
only if the buffer shown in the window is the buffer named by this
element.
-The fifth element, if non-@code{nil}, should specify the desired height
-of the window when its buffer is restored. This value is applied if the
-buffer temporarily shown in the window was in
+ The fifth element, if non-@code{nil}, should specify the desired
+height of the window when its buffer is restored. This value is applied
+if the buffer temporarily shown in the window was in
@code{temp-buffer-resize-mode} to restore the original height of the
window.
@end table
-@node Composite Windows
-@section Composite Windows
-@cindex composite windows
-
-A @dfn{composite window} is a rectangular frame area, typically composed
-of one or more so-called support windows grouped around one or more
-so-called main windows. Some applications allow degenerate composite
-windows consisting of one live window only. Currently, two types of
-composite windows are supported: Compound windows (@pxref{Compound
-Windows}) and window groups (@pxref{Window Groups}).
-
-@cindex composite root window
-Each composite window has one and only one composite root window. That
-root window is usually an internal window (@pxref{Frames and Windows})
-but may be a live window in the degenerate case where the composite
-window is a live window. All other windows of a composite window are
-subwindows of the composite root window.
-
-@defun composite-root-window-p window
-This function return non-@code{nil} if @var{window} is the root window
-of a composite window. The return value is the type of that composite
-window, currently either @code{compound} or @code{group}.
-@end defun
-
-@defun composite-window-p window
-This function returns non-@code{nil} if @var{window} is a subwindow of a
-composite window. The return value is the value of the @code{composite}
-window parameter (@pxref{Window Parameters}) of @var{window}.
-
-Note that a composite root window that is not part of a composite window
-does not have its @code{composite} window parameter set. That parameter
-is reserved for subwindows of a composite window only. A root window is
-not a subwindow of the composite window rooted at it.
-@end defun
-
-@cindex main window
-Each composite window must contain at least one @dfn{main window}. A
-main window can be either a live window or an internal window. Live
-main windows are the places where ``normal'' editing activities take
-place. An internal main window is either a window whose subwindows are
-all main windows of the same composite window, or the root window of
-another composite window.
-
-@defun composite-main-window-p window
-Ths function returns @code{t} if @var{window} is a main window of a
-composite window.
-@end defun
-
-@cindex support window
-Composite windows may also contain an arbitrary number of @dfn{support
-windows}. A support window can be either a live window or an internal
-window. Live support windows usually supply information like lists of
-files, buffers, tags, or bookmarks, a toolbar, tabs, or compiler and
-system messages. An internal support window is either a window whose
-subwindows are all support windows of the same composite window, or the
-root window of another composite window.
-
-@defun composite-support-window-p window
-Ths function returns @code{t} if @var{window} is a support window of a
-composite window.
-@end defun
-
-For technical reasons, composite windows may contain internal subwindows
-that are neither main nor support windows. These windows are supposed
-to have at least one main and one support window among their child
-windows. The functions @code{composite-main-window-p} and
-@code{composite-support-window-p} return @code{nil} for such windows.
-
-Composite windows are implemented with the help of three reserved window
-parameters, see @ref{Window Parameters}. Applications should never use
-these parameters for any other purposes than the ones described below.
-@table @asis
-@item @code{compound}
-If non-@code{nil}, this parameter designates the associated window as
-the root window of a compound window, see @ref{Compound Windows}.
-
-@item @code{group}
-If the value of this parameter is non-@code{nil}, the associated window
-is the root window of a window group, see @ref{Window Groups}.
-
-@item @code{composite}
-If this parameter is non-@code{nil}, the associated window is a
-subwindow of a composite window. The value must be a cons cell whose
-@sc{car} denotes the @dfn{type} of the composite window, either
-@code{compound} or @code{group}.
-
-The @sc{cdr} denotes the @dfn{role} of the associated window within the
-composite window and should be either @code{main}, @code{support} or
-@code{t}. The value @code{t} usually designates the associated window
-as an internal window with at least one main and one support window
-among its children.
-@end table
-
-For any subwindow @sc{w} of a composite window there has to exist a
-unique path from @sc{w} to the root window @sc{r} of the composite
-window such that the following property holds invariantly:
-
-@enumerate
-@item
-The parent window @sc{p} of @sc{w} is either @sc{r} or a subwindow of
-@sc{r}.
+@node Atomic Windows
+@section Atomic Windows
+@cindex atomic windows
+
+An @dfn{atomic window} is an internal window (@pxref{Basic Windows})
+built from two or more subwindows. For any subwindow of an atomic
+window the behavior of a number of operations changes in the sense that
+the operation is suitably applied to the entire atomic window instead.
+
+ Atomic windows are useful when you're using two side-by-side windows
+to compare or merge buffers. In this case, you probably don't want
+commands like @code{display-buffer} or @kbd{C-x 2} break your window
+layout by splitting one of these windows. Making these windows part of
+an atomic window guarantees that the entire atomic window is split
+instead.
+
+ Another use of atomic windows is that of a sidebar, toolbar or tabbar
+appearing on the left or above a ``main'' window. In this case,
+splitting the main window should not break the correspondence between
+the bar and the main window. With atomic windows the relationship
+between the bar and the main window remains untouched.
+
+ Atomic windows can be created by calling @code{display-buffer}
+(@pxref{Displaying Buffers}) with a non-@code{nil} @code{pop-up-window}
+and @code{atomic} specifier. The following call displays a buffer named
+``*bar*'' in a 10 columns wide window on the left of the selected
+window.
-@item
-The types of @sc{w} and @sc{p} must match: This means that if @sc{p}
-is @sc{r} then either the type of @sc{w} must be @code{compound} and
-the @code{compound} parameter of @sc{r} must be @code{t} or the type of
-@sc{w} must be @code{group} and the @code{group} parameter of @sc{r}
-must be @code{t}.
+@example
+(display-buffer
+ (get-buffer-create "*bar*")
+ '((pop-up-window (selected . left))
+ (pop-up-window-set-width . 10)
+ (atomic . t)))
+@end example
-@item
-If @sc{p} is not @sc{r} either the roles of @sc{w} and @sc{p} are
-the same or @sc{p} is neither a main nor a support window.
-@end enumerate
+Alternatively, applications can use @code{display-buffer-pop-up-window}
+(@pxref{Displaying Buffers}) in order to make sure that the buffer is
+not displayed in some other window provided the selected window can't be
+split.
-Violating this property usually breaks subsequent operations on the
-composite window.
+@example
+(display-buffer-pop-up-window
+ (get-buffer-create "*bar*")
+ '((selected . left))
+ '((pop-up-window-set-width . 10) (atomic . nest)))
+@end example
-@defun composite-root-window window
-This function returns the root window of the composite window that
-contains @var{window} as a subwindow. It returns @code{nil} if
-@var{window} is not a subwindow of a composite window or the path from
-@var{window} to the root of the composite window is broken.
+To make an internal window atomic use the following function:
-When @var{window} is a subwindow of two or more composite windows, this
-function returns the ``innermost'' root window, that is the first root
-window found following the path from @var{window} to the root window of
-its frame.
+@defun make-window-atom window
+This function make @var{window} an atomic window. The argument
+@var{window} must be an internal window. It returns @var{window}.
@end defun
-@cindex major window
-Usually, each composite window has one @dfn{major window} comprising all
-other main windows of the composite window. Any composite window should
-have only one major window to make sure that functions on its component
-windows behave ``as intended''. The major window can be retrieved via
-the following function:
+ Atomic windows are implemented by setting their @code{window-atom}
+parameter (@pxref{Window Parameters}) and that of their subwindows to
+@code{t}. To check whether a given window is or is part of an atomic
+window simply look at that parameter. If
+
+@smallexample
+(window-parameter window 'window-atom)
+@end smallexample
-@defun composite-major-window window
-This function returns the major window of the composite window
-@var{window} belongs to. The major window is the last main or root
-window found by following the path from @var{window} to the root of the
-composite window @var{window} belongs to.
+returns @code{t}, the window is part of an atomic window. To find the
+atomic window a given window is part of, use the following function:
-This function returns a meaningful result if and only if @var{window} is
-a main window.
+@defun window-atom-root window
+This function returns the atomic window @var{window} belongs to;
+@code{nil} if @var{window} is not part of an atomic window.
@end defun
-Note also the following aspects of composite windows:
+ By default, the behavior of the following commands changes when their
+window argument is a member of an atomic window and the variable
+@code{ignore-window-parameters} is non-@code{nil}.
-@itemize @bullet
-@item
-In degenerate cases one and the same window can be the root window of a
-compound window and a window group.
+@table @asis
+@item @code{split-window} (@pxref{Splitting Windows})
+When @var{window} is part of an atomic window, @code{split-window} tries
+to split the atomic window instead.
-@item
-Composite windows can be nested. This means that the root window of a
-composite window can also be a subwindow of another composite window.
-@end itemize
+@item @code{delete-window} (@pxref{Deleting Windows})
+When @var{window} is part of an atomic window, @code{delete-window}
+deletes the atomic window instead. If that window is the root window of
+its containing frame, an error is signalled.
-Uusally, the fact that a window is a subwindow of a composite window
-changes the semantics of a number of functions called with that window
-as argument. See @ref{Compound Windows} for a list of functions whose
-semantics change in compound windows. See @ref{Window Groups} for a
-corresponding list of functions that behave specially in window groups.
+@item @code{delete-other-windows} (@pxref{Deleting Windows})
+When @var{window} is part of an atomic window,
+@code{delete-other-windows} makes the atomic window fill its frame. If
+the atomic window is a non-side window (@pxref{Side Windows}), all other
+non-side windows are removed. If the atomic window is a side window, an
+error is signalled.
+@end table
-You can override the special behavior of any of these functions for a
-particular window in one of two ways:
+You can override the default behavior of these commands by using an
+appropriate @code{split-window-function}, @code{delete-window-function}
+or @code{delete-other-windows-function}.
-@itemize @bullet
-@item
-Set a window parameter denoting the function in question to @code{t}.
-This makes the function ``behave as usual''. For example
-
-@smallexample
-(set-window-parameter W 'split-window t)
-@end smallexample
-
-will cause @code{split-window} split the window @sc{w} as if @sc{w}
-did not have any parameters.
+The following two invariants must be maintained by all operations on
+atomic windows:
+@itemize @bullet
@item
-Specify the function to be called instead. For example
-
-@smallexample
-(set-window-parameter W 'split-window 'my-split-window)
-@end smallexample
-
-will have @code{split-window} call the function @code{my-split-window}
-with the original arguments to do the real work. As a special case
-
-@smallexample
-(set-window-parameter W 'split-window 'ignore)
-@end smallexample
-
-will do nothing and return @code{nil}.
+An atomic window must contain at least two subwindows.
@item
-Bind the value of @var{ignore-window-parameters} (@pxref{Window
-Parameters}) to non-@code{nil} around a call to the function.
+The @code{window-atom} parameter of an atomic window and of any of its
+subwindows must be @code{t}.
@end itemize
-The command @code{other-window} usually does not select a support
-window. You can override this behavior by specifying
+Atomic windows violating these invariants are automatically dissolved.
+Their component windows continue to exist as normal windows. Operating
+on them, however, is no more different from operating on any other
+window.
-@smallexample
-(set-window-parameter W 'maybe-other-window t)
-@end smallexample
-in which case @code{other-window} can select @sc{w} just like any other
-window. To specify that a main window does not get selected by
-@code{other-window}, set its @code{no-other-window} parameter to
-@code{t} as
+@node Side Windows
+@section Side Windows
+@cindex side windows
+@cindex non-side windows
-@smallexample
-(set-window-parameter W 'no-other-window t)
-@end smallexample
+A @dfn{side window} is a special window located at one of the four sides
+of a frame. Side windows are useful for assigning buffers always the
+same location within a frame whenever they are shown there. Typically,
+side windows would be used for viewing compiler or grep output, buffer
+or file listings, completions, or system messages. They would be
+arranged around a set of ``non-side'' windows used for buffers that are
+edited.
-Creating a new support window can be tricky. The following function
-should handle this.
-
-@defun make-support-window window support &optional size horizontal
-This function adds a support window of type @var{support} to
-@var{window}. The argument @var{window} must specify either a root
-window or a subwindow of a composite window. The argument @var{window}
-must be one of @code{compound} or @code{group}. The optional arguments
-@var{SIZE} and @var{HORIZONTAL} are as for @code{split-window}. The
-return value is the new support window.
-
-This function behaves like @code{split-window} but makes sure that the
-parameters of all involved windows are set correctly. In particular,
-the new leaf window becomes a support window of the composite window.
-@end defun
-
-
-@node Compound Windows
-@section Compound Windows
-@cindex compound windows
-
-A @dfn{compound window} is a composite window (@pxref{Composite
-Windows}) built from two or more subwindows. For any subwindow of a
-compound window the semantics of a number of operations usually changes
-in the sense that the operation is suitably applied to the entire
-compound window instead.
-
- One typical use of a compound window is that of providing a sidebar
-(like the speedbar) attached to a single ``main'' window. Splitting the
-main window vertically then guarantees that the new window appears below
-(or above) the compound window thus not disrupting the relationship
-between the sidebar and the main window. Another use of compound
-windows is that of a support window displaying a toolbar or tabs above a
-main window. In this case splitting the main window horizontally will
-not break the relationship between the supporting and the main window.
-
- Compound windows must have at least two subwindows. When
-@code{delete-window} deletes a subwindow of a compound window and there
-is only one more subwindow left, the compound window is dissolved
-automatically and ceases to have any impact on subsequent operations on
-the last remaining subwindow. Apart from this restriction a compound
-window may have any number of subwindows. Deleting the last main window
-of a compound window deletes the entire compound window instead (recall
-that a composite window must have at least one main subwindow).
-
- Application programs are supposed to preserve the types assigned to
-members of compound windows. If they don't, they risk to break the
-semantics of operations on the compound window. Note also that any
-subwindow of a compound window can be the root of another composite
-window since the latter can be nested.
-
- In addition to the functions giving meaningful results for any
-composite window (@pxref{Composite Windows}) the following functions
-have been designed specifically to operate on a subwindow of a compound
-window.
+ The following option specifies the layout of side windows on a frame.
-@defun compound-window-p window
-This function returns non-@code{nil} if @var{window} is a subwindow of a
-compound window.
-@end defun
+@defopt window-sides-vertical
+If non-@code{nil}, this variable specifies that left and right side
+windows are as high as the containing frame. Otherwise, top and bottom
+side windows are as wide as the containing frame.
-@defun compound-main-window-p window
-This function returns non-@code{nil} if @var{window} is a main window of
-a compound window.
-@end defun
+Changing this option while side-windows are displayed may lead to
+unexpected layouts and should be avoided.
+@end defopt
-A compound window can be created with the following function:
+If @code{window-sides-vertical} is @code{nil}, side windows appear as
+follows:
-@defun make-compound-window &optional window main size horizontal
-This functions behaves like @code{split-window} (@pxref{Splitting
-Windows}) with the additional twist that it makes @var{window} the main
-window of a new compound window. For this purpose, it creates a new
-internal window with @var{window} and a new leaf window as its only
-children. @var{window} must be a leaf window and defaults to the
-selected window.
+@smallexample
+@group
+ ______________________________________
+ | |
+ | Top Window |
+ |______________________________________|
+ | | | |
+ | Left | | Right |
+ | Side | Non-side Window | Side |
+ | Window | | Window |
+ |________|____________________|________|
+ | |
+ | Bottom Window |
+ |______________________________________|
-If the optional argument @var{main} is non-@code{nil}, this means the
-new leaf window becomes a main window. Argument @var{main} @code{nil}
-or not provided means the new leaf window becomes a support window. The
-original window @var{window} always becomes a main window.
+@end group
+@end smallexample
-The optional arguments @var{size} and @var{horizontal} are as for
-@code{split-window}. The return value is the new leaf window.
-@end defun
+If @code{window-sides-vertical} is non-@code{nil}, side windows are
+displayed as follows:
-Alternatively, a compound window can be constructed ``manually'' by
-splitting some live window and setting the @code{root} and
-@code{composite} parameters of the involved windows. Look at how
-@code{make-compound-window} sets these parameters for an example.
+@smallexample
+@group
+ ______________________________________
+ | | | |
+ | | Top Window | |
+ | |____________________| |
+ | | | |
+ | Left | | Right |
+ | Side | Non-side Window | Side |
+ | Window | | Window |
+ | |____________________| |
+ | | | |
+ | | Bottom Window | |
+ |________|____________________|________|
-Currently, the semantics of the following commands and functions change
-when their window argument is a member of a compound window:
+@end group
+@end smallexample
-@table @asis
-@item @code{split-window} (@pxref{Splitting Windows})
-When @var{window} is a component of a compound window,
-@code{split-window} is invoked with the root window of the compound
-window as argument instead.
+ Side windows can be arbitrarily subdivided. For each side of a frame
+there exists at most one dominating side window which contains all other
+windows on the same side as subwindows. As a rule, windows on the left
+or right side of a frame should be vertical combinations. Windows on
+the top or bottom of a frame should be horizontal combinations. This
+makes it easier to assign each life side window a corresponding slot.
+
+@cindex side window slot
+A @dfn{side window slot} indicates the relative position of a side
+window within the dominating window on that side. Slots are arbitrary
+numbers where the value zero roughly stands for a window in the middle
+of that side. Negative numbers indicate a position above the middle
+window (for left and right side windows) or on the left (for the top and
+bottom side windows). Positive numbers stand for windows below the
+middle window (for left and right side windows) or on the right (for top
+and bottom side windows).
+
+The example below depicts a layout with three subwindows on the top and
+two subwindows at the bottom of the frame.
-@item @code{delete-window} (@pxref{Deleting Windows})
-When @var{window} is a component of a compound window,
-@code{delete-window} deletes the entire compound window instead. If the
-root window of the compound window is the root window of its containing
-frame, or a support window or the only main window of a window group
-(@pxref{Window Groups}) an error is signalled.
+@smallexample
+@group
+ ______________________________________
+ | Left Top | Middle Top | Right Top |
+ | Window | Window | Window |
+ |____________|____________|____________|
+ | | | |
+ | Left | | Right |
+ | Side | Non-side Window | Side |
+ | Window | | Window |
+ |________|____________________|________|
+ | Left Bottom | Right Bottom |
+ | Window | Window |
+ |__________________|___________________|
-@item @code{delete-other-windows} (@pxref{Deleting Windows})
-When @var{window} belongs to a compound window,
-@code{delete-other-windows} makes the compound window fill its frame or,
-if present, the innermost enclosing major window of a window group, see
-@ref{Window Groups}. If the root window of the compound window is the
-root window of its containing frame, or a support window or the only
-main window of a window group (@pxref{Window Groups}) nothing is done.
-@end table
+@end group
+@end smallexample
-@node Window Groups
-@section Window Groups
-@cindex window groups
+The following option can be used to limit the number of subwindows that
+may appear on any side of a frame.
-A @dfn{window group} is a composite window (@pxref{Composite Windows})
-built from one or more subwindows. The main application area of window
-groups is in the implementation of Integrated Development Environments
-(IDEs) where a rectangular subarea of a frame constitutes the editing
-environment proper. The remaining windows are used for displaying
-supporting information and are not intended for editing.
+@defopt window-sides-slots
+This is a list of four elements specifying the number of side window
+slots on (in this order) the left, top, right and bottom side of each
+frame. If an element is a number, this means to display at most that
+many side windows on the corresponding side. If an element is
+@code{nil}, this means there's no bound on the number of slots on that
+side.
+@end defopt
-Each window group must contain at least one main window which must be
-either live or an internal window which should comprise all other main
-windows of the group. Note that the latter restriction is not checked
-by the routines operating on window groups but it's better if
-application preserve it since some operations inherently rely on it.
+ Side windows are implemented with the help of @code{window-side}
+parameters (@pxref{Window Parameters}). This parameter is @code{left},
+@code{top}, @code{right} or @code{bottom} for a window on the
+corresponding side and @code{none} for a non-side window. The
+dominating window on each side as well as the dominating non-side window
+have parents whose @code{window-side} parameter is nil. To get the
+dominating side window on the left, for example, use the function
+@code{window-with-parameter} like
-Usually, the root window of a window group is also the root window of
-the containing frame (@pxref{Frames and Windows}). Note, however, that
-window groups (and compound windows) can be arbitrarily nested.
+@smallexample
+(window-with-parameter 'window-side 'left nil t)
+@end smallexample
-@defun group-window-p window
-This function returns non-@code{nil} if @var{window} is a subwindow of a
-window group.
-@end defun
+ If you create side windows by calling @code{display-buffer}
+(@pxref{Displaying Buffers}) with the @code{use-side-window} specifier,
+this will set up these parameters automatically. If you want to manage
+side windows manually, you should preserve the following invariants:
-@defun group-window-main-p window
-This function returns non-@code{nil} if @var{window} is a main window of
-a window group.
-@end defun
+@itemize @bullet
+@item
+If a frame has a side window, a non-side window must exist on that frame
+as well. If a frame has a non-side window, at least one side window
+must exist on that frame too.
-@defun group-root-window window
-This function returns the root window of the window group @var{window}
-belongs to. If @var{window} is part of a compound window, it returns
-the root window of the group the root of the compound window belongs
-too.
-@end defun
+@item
+If a window has a non-@code{nil} @code{window-side} parameter, it must
+have a parent window and the parent window's @code{window-side}
+parameter must be either @code{nil} or the same as for the window.
-You can create a new window group with the following function:
+@item
+For any of the values @code{left}, @code{top}, @code{right},
+@code{bottom} and @code{none} there can be only one dominating window
+whose @code{window-side} parameter equals that value. More precisely,
+this means that at most one window can have its @code{window-side}
+parameter set to such a value and have a parent window whose
+@code{window-side} parameter is @code{nil}.
-@defun make-window-group &optional window
-This functions makes @var{window} the main and root window of a new
-window group. The argument @var{window} must be a live window and
-defaults to the selected one. This function returns @var{window}.
-@end defun
+@item
+Live windows whose @code{window-side} parameter is @code{nil} are
+invalid.
+@end itemize
-Alternatively, you can construct a window group ``manually'' by
-appropriately setting the @code{root} parameter of any live window.
+If a setup of @code{window-side} parameters fails to satisfy these
+invariants, Emacs will reset all @code{window-side} parameters on that
+frame to @code{nil}. Otherwise, the window configuration remains
+unchanged.
-Currently, the semantics of the following commands and functions change
-when their window argument is a member of a window group:
+The behavior of the following commands and functions changes in the
+presence of side windows.
@table @asis
@item @code{split-window} (@pxref{Splitting Windows})
-@code{split-window} is allowed to split main windows of a window group
-only. It will signal an error when invoked with a support window as
-argument.
+If the function @code{split-window} splits a window with a
+non-@code{nil} @code{window-side} parameter it assigns the new window
+the same parameter value.
@item @code{delete-window} (@pxref{Deleting Windows})
-@code{delete-window} is allowed to delete a main window of a window
-group only. It will signal an error when invoked with a support window
-or the last main window of the group as argument
-
-If a window group contains two disjoint main windows that are not
-subwindows of another main window of the group, @code{delete-window} may
-signal an error even if the window group contains other main windows.
+The function @code{delete-window} signal an error when it is invoked
+with a non-side window as argument and there are side windows on the
+associated frame.
@item @code{delete-other-windows} (@pxref{Deleting Windows})
-When @code{delete-other-windows} is invoked with a main window of a
-window group as argument, it will delete all main windows of that group
-that are neither the argument window itself nor a subwindow of the
-argument window. Support windows are not affected by this operation.
-An error is signalled when @code{delete-other-windows} is invoked with a
-support window as its argument.
-
-If a window group contains two disjoint main windows that are not
-subwindows of another main window of the group,
-@code{delete-other-windows} will not be able to remove all main windows
-but the argument window and its subwindows.
+When @code{delete-other-windows} is invoked with a non-side window as
+argument, it will delete all other non-side windows (for an internal
+window all non-side windows that are not a subwindow of this window),
+When @code{delete-other-windows} is called with a side window as
+argument it signals an error.
@end table
+
@node Window Hooks
@section Hooks for Window Scrolling and Changes
@cindex hooks for window operations
"Return WINDOW's first child window."
(or (window-vchild window) (window-hchild window)))
+(defun window-child-count (window)
+ "Return number of WINDOW's children."
+ (let ((count 0))
+ (when (and (windowp window) (setq window (window-child window)))
+ (while window
+ (setq count (1+ count))
+ (setq window (window-next window))))
+
+ count))
+
(defsubst window-internal-p (object)
"Return t if OBJECT is an internal window and nil otherwise.
An internal window is a window that has either a vertical or a
(setq child (window-right child)))
count))))
+(defun walk-window-tree-1 (proc walk-window-tree-window any &optional sub-only)
+ "Helper function for `walk-window-tree' and `walk-window-subtree'."
+ (let (walk-window-tree-buffer)
+ (while walk-window-tree-window
+ (setq walk-window-tree-buffer
+ (window-buffer walk-window-tree-window))
+ (when (or walk-window-tree-buffer any)
+ (funcall proc walk-window-tree-window))
+ (unless walk-window-tree-buffer
+ (walk-window-tree-1
+ proc (window-hchild walk-window-tree-window) any)
+ (walk-window-tree-1
+ proc (window-vchild walk-window-tree-window) any))
+ (if sub-only
+ (setq walk-window-tree-window nil)
+ (setq walk-window-tree-window
+ (window-right walk-window-tree-window))))))
+
+(defun walk-window-tree (proc &optional frame any)
+ "Run function PROC on each live window of FRAME.
+PROC must be a function with one argument - a window. FRAME must
+be a live frame and defaults to the selected one. ANY, if
+non-nil means to run PROC on all live and internal windows of
+FRAME.
+
+This function performs a pre-order, depth-first traversal of the
+window tree. If PROC changes the window tree, the result is
+unpredictable."
+ (let ((walk-window-tree-frame (normalize-live-frame frame)))
+ (walk-window-tree-1
+ proc (frame-root-window walk-window-tree-frame) any)))
+
+(defun walk-window-subtree (proc &optional window any)
+ "Run function PROC on each live subwindow of WINDOW.
+WINDOW defaults to the selected window. PROC must be a function
+with one argument - a window. ANY, if non-nil means to run PROC
+on all live and internal subwindows of WINDOW.
+
+This function performs a pre-order, depth-first traversal of the
+window tree rooted at WINDOW. If PROC changes that window tree,
+the result is unpredictable."
+ (setq window (normalize-any-window window))
+ (walk-window-tree-1 proc window any t))
+
+(defun windows-with-parameter (parameter &optional value frame any values)
+ "Return a list of all windows on FRAME with PARAMETER non-nil.
+FRAME defaults to the selected frame. Optional argument VALUE
+non-nil means only return windows whose window-parameter value of
+PARAMETER equals VALUE \(comparison is done using `equal').
+Optional argument ANY non-nil means consider internal windows
+too. Optional argument VALUES non-nil means return a list of cons
+cells whose car is the value of the parameter and whose cdr is
+the window."
+ (let (this-value windows)
+ (walk-window-tree
+ (lambda (window)
+ (when (and (setq this-value (window-parameter window parameter))
+ (or (not value) (or (equal value this-value))))
+ (setq windows
+ (if values
+ (cons (cons this-value window) windows)
+ (cons window windows)))))
+ frame any)
+
+ (nreverse windows)))
+
+(defun window-with-parameter (parameter &optional value frame any)
+ "Return first window on FRAME with PARAMETER non-nil.
+FRAME defaults to the selected frame. Optional argument VALUE
+non-nil means only return a window whose window-parameter value
+for PARAMETER equals VALUE \(comparison is done with `equal').
+Optional argument ANY non-nil means consider internal windows
+too."
+ (let (this-value windows)
+ (catch 'found
+ (walk-window-tree
+ (lambda (window)
+ (when (and (setq this-value (window-parameter window parameter))
+ (or (not value) (equal value this-value)))
+ (throw 'found window)))
+ frame any))))
+
+;;; Atomic windows.
+(defun window-atom-root (&optional window)
+ "Return root of atomic window WINDOW is a part of.
+WINDOW can be any window and defaults to the selected one.
+Return nil if WINDOW is not part of a atomic window."
+ (setq window (normalize-any-window window))
+ (let (root)
+ (while (and window (window-parameter window 'window-atom))
+ (setq root window)
+ (setq window (window-parent window)))
+ root))
+
+(defun make-window-atom (window)
+ "Make WINDOW an atomic window.
+WINDOW must be an internal window. Return WINDOW."
+ (if (not (window-internal-p window))
+ (error "Window %s is not an internal window" window)
+ (walk-window-subtree
+ (lambda (window)
+ (set-window-parameter window 'window-atom t))
+ window t)
+ window))
+
+
+(defun window-atom-check-1 (window)
+ "Subroutine of `window-atom-check'."
+ (when window
+ (if (window-parameter window 'window-atom)
+ (let ((count 0))
+ (when (or (catch 'reset
+ (walk-window-subtree
+ (lambda (window)
+ (if (window-parameter window 'window-atom)
+ (setq count (1+ count))
+ (throw 'reset t)))
+ window t))
+ (zerop count))
+ ;; Dissolve atomic window.
+ (walk-window-subtree
+ (lambda (window)
+ (set-window-parameter window 'window-atom nil))
+ window t)))
+ ;; Check children.
+ (unless (window-buffer window)
+ (window-atom-check-1 (window-hchild window))
+ (window-atom-check-1 (window-vchild window)))
+ ;; Check right sibling
+ (window-atom-check-1 (window-right window)))))
+
+(defun window-atom-check (&optional frame)
+ "Check atomicity of all windows on FRAME.
+FRAME defaults to the selected frame. If an atomic window is
+wrongly configured, reset the atomicity of all its subwindows to
+nil. An atomic window is wrongly configured if it has no
+subwindows or one of its subwindows is not atomic."
+ (window-atom-check-1 (frame-root-window frame)))
+
+;; Side windows.
+(defvar window-sides '(left top right bottom)
+ "Window sides.")
+
+(defcustom window-sides-vertical nil
+ "If non-nil, left and right side windows are full height.
+Otherwise, top and bottom side windows are full width."
+ :type 'boolean
+ :group 'windows
+ :version "24.1")
+
+(defcustom window-sides-slots '(nil nil nil nil)
+ "Maximum number of side window slots.
+The value is a list of four elements specifying the number of
+side window slots on \(in this order) the left, top, right and
+bottom side of each frame. If an element is a number, this means
+to display at most that many side windows on the corresponding
+side. If an element is nil, this means there's no bound on the
+number of slots on that side."
+ :risky t
+ :type
+ '(list
+ :value (nil nil nil nil)
+ (choice
+ :tag "Left"
+ :help-echo "Maximum slots of left side window."
+ :value nil
+ :format "%[Left%] %v\n"
+ (const :tag "Unlimited" :format "%t" nil)
+ (integer :tag "Number" :value 2 :size 5))
+ (choice
+ :tag "Top"
+ :help-echo "Maximum slots of top side window."
+ :value nil
+ :format "%[Top%] %v\n"
+ (const :tag "Unlimited" :format "%t" nil)
+ (integer :tag "Number" :value 3 :size 5))
+ (choice
+ :tag "Right"
+ :help-echo "Maximum slots of right side window."
+ :value nil
+ :format "%[Right%] %v\n"
+ (const :tag "Unlimited" :format "%t" nil)
+ (integer :tag "Number" :value 2 :size 5))
+ (choice
+ :tag "Bottom"
+ :help-echo "Maximum slots of bottom side window."
+ :value nil
+ :format "%[Bottom%] %v\n"
+ (const :tag "Unlimited" :format "%t" nil)
+ (integer :tag "Number" :value 3 :size 5)))
+ :group 'windows
+ :group 'display-buffer)
+
+(defcustom window-sides-alist nil
+ "Association list for side windows.
+Each entry of this list must be a list whose first element is
+either `left', `top', `right' or`bottom'. The second element of
+each entry specifies the minimum size of windows on that side
+\(either the default value, a number of lines or columns, or a
+fraction of the frame size). The third element specifies the
+desired size of windows on that side \(either the default value,
+a number of lines or columns, or a fraction of the frame size).
+The fourth element specifies the upper bound on the number of
+slots on that side, nil if there's no bound."
+ :risky t
+ :type
+ '(set
+ ;;; :format "%v %t"
+ :inline t
+ ;; Left side window.
+ (list
+ :value (left nil nil nil)
+ :format "Left: %v\n"
+ (const :format "" left)
+ ;; Minimum width of left side windows.
+ (choice
+ :tag "Minimum width"
+ :help-echo "The minimum width of left side windows."
+ :value nil
+ :format "%[Minimum%] %v"
+ (const :tag "Default" :format "%t" nil)
+ (integer :tag "Columns" :value 12 :size 5)
+ (float :tag "Fraction" :value .25 :size 5))
+ ;; Desired width of left side windows.
+ (choice
+ :tag "Desired width"
+ :help-echo "The desired width of left side windows."
+ :value nil
+ :format " %[Desired%] %v"
+ (const :tag "Default" :format "%t" nil)
+ (integer :tag "Columns" :value 12 :size 5)
+ (float :tag "Fraction" :value .25 :size 5))
+ ;; The maximum number of slots of left side windows.
+ (choice
+ :tag "Slots"
+ :help-echo "The maximum number of slots in left side windows."
+ :value nil
+ :format " %[Slots%] %v"
+ (const :tag "Unspecified" :format "%t" nil)
+ (integer :tag "Number" :format "%v" :value 3 :size 5)))
+ ;; Top side windows.
+ (list
+ :value (top nil nil nil)
+ :format "Top: %v\n"
+ (const :format "" top)
+ ;; Minimum height of top windows.
+ (choice
+ :tag "Minimum height"
+ :help-echo "The minimum height of top windows."
+ :value nil
+ :format "%[Minimum%] %v"
+ (const :tag "Default" :format "%t" nil)
+ (integer :tag "Lines" :value 6 :size 5)
+ (float :tag "Fraction" :value .25 :size 5))
+ ;; Desired size of left side windows.
+ (choice
+ :tag "Desired height"
+ :help-echo "The desired height of top windows."
+ :value nil
+ :format " %[Desired%] %v"
+ (const :tag "Default" :format "%t" nil)
+ (integer :tag "Lines" :value 6 :size 5)
+ (float :tag "Fraction" :value .25 :size 5))
+ ;; The maximum number of slots of top windows.
+ (choice
+ :tag "Slots"
+ :help-echo "The maximum number of slots in top windows."
+ :value nil
+ :format " %[Slots%] %v"
+ (const :tag "Unspecified" :format "%t" nil)
+ (integer :tag "Number" :value 3 :format "%v" :size 5)))
+ ;; Right side windows.
+ (list
+ :value (right nil nil nil)
+ :format "Right: %v\n"
+ (const :format "" right)
+ ;; Minimum width of right side windows.
+ (choice
+ :tag "Minimum width"
+ :help-echo "The minimum width of windows on the right."
+ :value nil
+ :format "%[Minimum%] %v"
+ (const :tag "Default" :format "%t" nil)
+ (integer :tag "Columns" :value 12 :size 5)
+ (float :tag "Fraction" :value .25 :size 5))
+ ;; Desired width of right side windows.
+ (choice
+ :tag "Desired width"
+ :help-echo "The desired width of windows on the left."
+ :value nil
+ :format " %[Desired%] %v"
+ (const :tag "Default" :format "%t" nil)
+ (integer :tag "Columns" :value 12 :size 5)
+ (float :tag "Fraction" :value .25 :size 5))
+ ;; The maximum number of slots of right side windows.
+ (choice
+ :tag "Slots"
+ :help-echo "The maximum number of slots in right side windows."
+ :value nil
+ :format " %[Slots%] %v"
+ (const :tag "Unspecified" :format "%t" nil)
+ (integer :tag "Number" :value 3 :format "%v" :size 5)))
+ ;; Bottom side windows.
+ (list
+ :value (bottom nil nil nil)
+ :format "Bottom: %v\n"
+ (const :format "" bottom)
+ ;; Minimum height of bottom windows.
+ (choice
+ :tag "Minimum height"
+ :help-echo "The minimum height of bottom windows."
+ :value nil
+ :format "%[Minimum%] %v"
+ (const :tag "Default" :format "%t" nil)
+ (integer :tag "Lines" :value 6 :size 5)
+ (float :tag "Fraction" :value .25 :size 5))
+ ;; Desired height of bottom windows.
+ (choice
+ :tag "Desired height"
+ :help-echo "The desired height of bottom windows."
+ :value nil
+ :format " %[Desired%] %v"
+ (const :tag "Default" :format "%t" nil)
+ (integer :tag "Lines" :value 6 :size 5)
+ (float :tag "Fraction" :value .25 :size 5))
+ ;; The maximum number of slots of bottom windows.
+ (choice
+ :tag "Slots"
+ :help-echo "The maximum number of slots in botom windows."
+ :value nil
+ :format " %[Slots%] %v"
+ (const :tag "Unspecified" :format "%t" nil)
+ (integer :tag "Number" :value 3 :format "%v" :size 5))))
+ :group 'windows
+ :group 'display-buffer)
+
+(defun window-side-check (&optional frame)
+ "Check the window-side parameter of all windows on FRAME.
+FRAME defaults to the selected frame. If the configuration is
+invalid, reset all window-side parameters to nil.
+
+A valid configuration has to preserve the following invariant:
+
+- If a window has a non-nil window-side parameter, it must have a
+ parent window and the parent window's window-side parameter
+ must be either nil or the same as for window.
+
+- If windows with non-nil window-side parameters exist, there
+ must be at most one window of each side and non-side with a
+ parent whose window-side parameter is nil and there must be no
+ leaf window whose window-side parameter is nil."
+ (let (normal none left top right bottom
+ side parent parent-side code)
+ (when (or (catch 'reset
+ (walk-window-tree
+ (lambda (window)
+ (setq side (window-parameter window 'window-side))
+ (setq parent (window-parent window))
+ (setq parent-side
+ (and parent (window-parameter parent 'window-side)))
+ ;; The following `cond' seems a bit tedious, but I'd
+ ;; rather stick to using just the stack.
+ (cond
+ (parent-side
+ (when (not (eq parent-side side))
+ ;; A parent whose window-side is non-nil must
+ ;; have a child with the same window-side.
+ (throw 'reset t)))
+ ;; Now check that there's more than one main window
+ ;; for any of none, left, top, right and bottom.
+ ((eq side 'none)
+ (if none
+ (throw 'reset t)
+ (setq none t)))
+ ((eq side 'left)
+ (if left
+ (throw 'reset t)
+ (setq left t)))
+ ((eq side 'top)
+ (if top
+ (throw 'reset t)
+ (setq top t)))
+ ((eq side 'right)
+ (if right
+ (throw 'reset t)
+ (setq right t)))
+ ((eq side 'bottom)
+ (if bottom
+ (throw 'reset t)
+ (setq bottom t)))
+ ((window-buffer window)
+ ;; A leaf window without window-side parameter,
+ ;; record its existence.
+ (setq normal t))))
+ frame t))
+ (if none
+ ;; At least one non-side window exists, so there must
+ ;; be at least one side-window and no normal window.
+ (or (not (or left top right bottom)) normal)
+ ;; No non-side window exists, so there must be no side
+ ;; window either.
+ (or left top right bottom)))
+ (walk-window-tree
+ (lambda (window)
+ (set-window-parameter window 'window-side nil))
+ frame t))))
+
+(defun window-check (&optional frame)
+ "Check atomic and side windows on FRAME.
+FRAME defaults to the selected frame."
+ (window-side-check frame)
+ (window-atom-check frame))
+
+;;; Window sizes.
(defvar window-size-fixed nil
"Non-nil in a buffer means windows displaying the buffer are fixed-size.
If the value is `height', then only the window's height is fixed.
(dolist (walk-windows-window (window-list-1 nil minibuf all-frames))
(funcall proc walk-windows-window))))
-(defun walk-window-tree-1 (proc walk-window-tree-window any)
- "Helper function for `walk-window-tree'."
- (let (walk-window-tree-buffer)
- (while walk-window-tree-window
- (setq walk-window-tree-buffer
- (window-buffer walk-window-tree-window))
- (when (or walk-window-tree-buffer any)
- (funcall proc walk-window-tree-window))
- (unless walk-window-tree-buffer
- (walk-window-tree-1
- proc (window-hchild walk-window-tree-window) any)
- (walk-window-tree-1
- proc (window-vchild walk-window-tree-window) any))
- (setq walk-window-tree-window
- (window-right walk-window-tree-window)))))
-
-(defun walk-window-tree (proc &optional frame any)
- "Run function PROC on each live window of FRAME.
-PROC must be a function with one argument - a window. FRAME must
-be a live frame and defaults to the selected one. ANY, if
-non-nil means to run PROC on all live and internal windows of
-FRAME.
-
-This function performs a pre-order, depth-first traversal of the
-window tree. If PROC changes the window tree, the result is
-unpredictable."
- (let ((walk-window-tree-frame (normalize-live-frame frame)))
- (walk-window-tree-1
- proc (frame-root-window walk-window-tree-frame) any)))
-
(defun window-in-direction-2 (window posn &optional horizontal)
"Support function for `window-in-direction'."
(if horizontal
(setq frame (normalize-live-frame frame))
(window-tree-1 (frame-root-window frame) t))
\f
-;;; Composite Windows
-
-;; The basic invariant of the composite window code is:
-
-;; \A window \in Windows:
-;; \A sibling \in Siblings [window]:
-;; composite-window-p [window] =>
-;; /\ composite-window-p [sibling]
-;; /\ composite-root-window [window] = composite-root-window [sibling]
-
-;; that is, for any window that is part of a composite window, any
-;; sibling of that window is a subwindow of the same composite window.
-
-;; This is usually not called as a "predicate" but it's more consistent
-;; to maintain our defsubsts as predicate.
-(defsubst composite-window-p (window)
- "Return non-nil if WINDOW is a subwindow of a composite window.
-The return value is the value of the `composite' window parameter
-of WINDOW."
- (window-parameter window 'composite))
-
-(defsubst composite-root-window-p (window)
- "Return non-nil if WINDOW is the root of a composite window.
-The return value is the type of that composite window, either
-`compound' or `group'."
- (or (window-parameter window 'compound)
- (window-parameter window 'group)))
-
-(defsubst composite-main-window-p (window)
- "Return t if WINDOW is a main window of a composite window."
- (eq (cdr-safe (composite-window-p window)) 'main))
-
-(defsubst composite-support-window-p (window)
- "Return t if WINDOW is a support window of a composite window."
- (eq (cdr-safe (composite-window-p window)) 'support))
-
-(defun composite-root-window (window)
- "Return root window of the composite window WINDOW is a part of.
-Return nil if WINDOW is not part of a composite window or the
-path from WINDOW to the root of the composite window is broken."
- (let ((type (car-safe (window-parameter window 'composite))))
- (when type
- (setq window (window-parent window))
- (catch 'done
- (while window
- (cond
- ((window-parameter window type)
- (throw 'done window))
- ((eq (car-safe (window-parameter window 'composite)) type))
- (t
- ;; Broken path.
- (throw 'done nil)))
- (setq window (window-parent window)))))))
-
-(defun composite-major-window (window)
- "Return major window of composite window WINDOW belongs to.
-The major window is the last main or root window found by
-following the path from WINDOW to the root of the composite
-window WINDOW belongs to. Each composite window should have one
-and only one major window to make sure that functions on its
-component windows behave \"as intended\".
-
-This function returns a meaningful result if and only if WINDOW
-is a main window."
- (let ((main window))
- (setq window (window-parent window))
- (while (and window (composite-main-window-p window)
- (not (composite-root-window-p window)))
- (setq main window)
- (setq window (window-parent window)))
- ;; We can't go up any further but maybe the window we're looking at
- ;; is the root window.
- (when (composite-root-window-p window)
- (let ((sibling (window-child window)))
- ;; Make sure that all children of the group root window are main
- ;; windows.
- (catch 'done
- (while sibling
- (if (not (composite-main-window-p sibling))
- (throw 'done nil)
- (setq sibling (window-right sibling))))
- (setq main window))))
- main))
-
-(defun composite-main-sibling (window)
- "Return first \"main\" sibling of WINDOW.
-A main sibling is a main window of a composite window. Both,
-WINDOW and the main sibling must have the same parent window and
-thus be part of one and the same composite window. Return nil if
-no such window can be found."
- (let ((parent (window-parent window))
- sibling)
- (when parent
- (setq sibling (window-child parent))
- (catch 'done
- (while sibling
- (if (and (not (eq sibling window))
- (eq (cdr-safe (window-parameter sibling 'composite)) 'main))
- (throw 'done sibling)
- (setq sibling (window-right sibling))))))))
-
-(defun composite-lowest-child-role (window)
- "Return lowest \"non-main\" role among WINDOW's children."
- (let ((sibling (window-child window))
- (highest 'main)
- role)
- (catch 'done
- (while sibling
- (setq role (cdr-safe (window-parameter sibling 'composite)))
- (cond
- ((eq role t)
- (setq highest t))
- ((eq role 'support)
- (throw 'done 'support)))
- (setq sibling (window-right sibling)))
- highest)))
-
-(defsubst compound-window-p (window)
- "Return non-nil if WINDOW is a subwindow of a compound window."
- (eq (car-safe (window-parameter window 'composite)) 'compound))
-
-(defsubst compound-main-window-p (window)
- "Return non-nil if WINDOW is a main window of a compound window."
- (let ((composite (composite-window-p window)))
- (and (eq (car-safe composite) 'compound)
- (eq (cdr-safe composite) 'main))))
-
-(defun compound-root-window (window)
- "Return topmost root window of compound window WINDOW belongs to."
- (while (and window (compound-window-p window))
- (setq window (window-parent window)))
- (when (window-parameter window 'compound)
- window))
-
-(defsubst group-window-p (window)
- "Return non-nil if WINDOW is a subwindow of a window group."
- (eq (car-safe (window-parameter window 'composite)) 'group))
-
-(defsubst group-window-main-p (window)
- "Return non-nil if WINDOW is a main window of a window group."
- (let ((composite (composite-window-p window)))
- (and (eq (car-safe composite) 'group)
- (eq (cdr-safe composite) 'main))))
-
-(defun group-root-window (window)
- "Return root window of window group WINDOW belongs to.
-If WINDOW is part of a compound window, return the root window of
-the group the root of the compound window belongs too."
- (while (and window (compound-window-p window))
- (setq window (window-parent window)))
- (while (and window (group-window-p window)
- (not (composite-root-window-p window)))
- (setq window (window-parent window)))
- (when (window-parameter window 'group)
- window))
-
;;; Getting the "other" window.
;; FIXME: Handle `ignore-window-parameters' and some other things maybe.
(defun other-window (count &optional all-frames)
window, so select the selected window. In an interactive call,
COUNT is the numeric prefix argument. Return nil.
-This function does not select a window whose `no-other-window'
-parameter is non-nil. Also, this function never selects the
-support window of a composite window unless the support window's
-`maybe-other-window' parameter is non-nil.
+Do not select a window whose `no-other-window' window parameter
+is non-nil. If the `other-window-function' parameter of WINDOW
+is a function call that function with the arguments COUNT and
+ALL-FRAMES.
This function uses `next-window' for finding the window to
select. The argument ALL-FRAMES has the same meaning as in
always effectively nil."
(interactive "p")
(let* ((window (selected-window))
- (function (window-parameter window 'other-window))
+ (function (window-parameter window 'other-window-function))
old-window old-count)
(if (functionp function)
(funcall function count all-frames)
;; Keep out of infinite loops. When COUNT has not changed
;; since we last looked at `window' we're probably in one.
(throw 'exit nil)))
- ((or (and (composite-support-window-p window)
- (not (window-parameter window 'maybe-other-window)))
- (window-parameter window 'no-other-window))
- ;; The first non-selectable window `next-window' got us:
- ;; Remember it and the current value of COUNT.
+ ((window-parameter window 'no-other-window)
(unless old-window
+ ;; The first non-selectable window `next-window' got us:
+ ;; Remember it and the current value of COUNT.
(setq old-window window)
(setq old-count count)))
(t
;; Keep out of infinite loops. When COUNT has not changed
;; since we last looked at `window' we're probably in one.
(throw 'exit nil)))
- ((or (and (composite-support-window-p window)
- (not (window-parameter window 'maybe-other-window)))
- (window-parameter window 'no-other-window))
- ;; The first non-selectable window `previous-window' got us:
- ;; Remember it and the current value of COUNT.
+ ((window-parameter window 'no-other-window)
(unless old-window
+ ;; The first non-selectable window `previous-window' got
+ ;; us: Remember it and the current value of COUNT.
(setq old-window window)
(setq old-count count)))
(t
(setq count (1+ count)))))
+
(select-window window)
nil))))
;; This should probably return non-nil when the selected window is part
-;; of a compound window whose root is the frame's root window.
+;; of an atomic window whose root is the frame's root window.
(defun one-window-p (&optional nomini all-frames)
"Return non-nil if the selected window is the only window.
Optional arg NOMINI non-nil means don't count the minibuffer
Return `frame' if deleting WINDOW should delete its frame
instead."
(setq window (normalize-any-window window))
- (let ((frame (window-frame window))
+ (unless ignore-window-parameters
+ ;; Handle atomicity.
+ (when (window-parameter window 'window-atom)
+ (setq window (window-atom-root window))))
+ (let ((parent (window-parent window))
+ (frame (window-frame window))
(dedicated (and (window-buffer window) (window-dedicated-p window)))
- (quit-restore (window-parameter window 'quit-restore))
- composite type role root)
+ (quit-restore (window-parameter window 'quit-restore)))
(cond
((frame-root-window-p window)
(when (and (or dedicated
;; is new-frame and the window still displays the same buffer
;; and (2) there are other frames left.
'frame))
- ((setq composite (window-parameter window 'composite))
- (setq type (car-safe composite))
- (setq role (cdr-safe composite))
- (setq root (composite-root-window window))
- (cond
- ;; When `ignore-window-parameters' or the `delete-window'
- ;; parameter say or WINDOW is part of a broken composite window,
- ;; WINDOW is deletable. We cannot handle the case where WINDOW's
- ;; `delete-window' parameter is a function (that's impossible).
- ((or (not (memq ignore-window-parameters '(nil post)))
- (eq (window-parameter window 'delete-window) t)
- (not root) (not type) (not role))
- t)
- ((eq type 'compound)
- ;; A component of a compound window is deletable if and only if
- ;; its root is deletable.
- (window-deletable-p root))
- ((eq type 'group)
- ;; In a window group only a main window with a main sibling is
- ;; deletable.
- (and (eq role 'main) (composite-main-sibling window)))))
+ ((and (not ignore-window-parameters)
+ (eq (window-parameter window 'window-side) 'none)
+ (or (not parent)
+ (not (eq (window-parameter parent 'window-side) 'none))))
+ ;; Can't delete last main window.
+ nil)
(t))))
(defun window-or-subwindow-p (subwindow window)
WINDOW can be an arbitrary window and defaults to the selected
one. Return nil.
-This function respects the variable `ignore-window-parameters'
-when processing window parameters so any processing of WINDOW's
-parameters may be suppressed.
-
-If the `delete-window' parameter WINDOW equals t, delete WINDOW
-ignoring any other window parameters. If the `delete-window'
-parameter specifies a function, call that function with WINDOW as
-its sole argument. It's the responsibility of that function to
-adjust the parameters of all remaining windows.
-
-Otherwise, if WINDOW is part of a compound window, call this
-function with the root of the compound window as its argument.
-If WINDOW is either the only window on its frame, or a support
-window or the last main window of a window group, signal an error
-and don't delete WINDOW.
-
-This function makes sure that window parameters are reset or
-inherited when WINDOW is part of a combination of two windows."
+If `ignore-window-parameters' is non-nil any parameters of WINDOW
+are ignored. Otherwise, if the `delete-window-function'
+parameter of WINDOW equals t, delete WINDOW ignoring any other
+window parameters. If the `delete-window-function' parameter
+specifies a function, call that function with WINDOW as its sole
+argument. It's the responsibility of that function to adjust the
+parameters of all remaining windows.
+
+Otherwise, if WINDOW is part of an atomic window, call
+`delete-window' with the root of the atomic window as its
+argument. If WINDOW is the only window on its frame or the last
+non-side window, signal an error."
(interactive)
(setq window (normalize-any-window window))
- (let* ((function (window-parameter window 'delete-window))
- ;; COMPOSITE non-nil means WINDOW is part of a composite
- ;; window.
- (composite (window-parameter window 'composite))
- ;; TYPE is the type of the composite window (either `compound'
- ;; or `group'). ROLE is the role of WINDOW within the
- ;; composite window (either `main', `support', or t). ROOT is
- ;; the root window of the composite window.
- (type (car-safe composite))
- (role (cdr-safe composite))
- (root (and composite (composite-root-window window)))
- parent)
+ (let* ((frame (window-frame window))
+ (function (window-parameter window 'delete-window-function))
+ (parent (window-parent window))
+ atom-root)
+ (window-check frame)
(catch 'done
;; Handle window parameters.
(cond
;; Ignore window parameters if `ignore-window-parameters' tells
- ;; so or the `delete-window' parameter equals t.
- ((or (not (memq ignore-window-parameters '(nil post)))
- (eq function t)))
+ ;; us so or `delete-window-function' equals t.
+ ((or ignore-window-parameters (eq function t)))
((functionp function)
- ;; The `delete-window' parameter specifies the function to call
- ;; instead. If that function is `ignore' nothing is done. It's
+ ;; The `delete-window-function' parameter specifies the function
+ ;; to call. If that function is `ignore' nothing is done. It's
;; up to the function called here to avoid infinite recursion.
(throw 'done (funcall function window)))
- (composite
- (cond
- ((or (not root) (not type) (not role))
- ;; Something is broken in this composite window. Signal a
- ;; message but let the deletion pass through (we might signal
- ;; an error here but for everday work this is too nasty).
- (message "Broken component %s of composite window" window))
- ((eq type 'compound)
- ;; Deleting a component of a compound window deletes the
- ;; entire compound window.
- (throw 'done (delete-window root)))
- ((eq type 'group)
- (cond
- ((not (eq role 'main))
- ;; WINDOW is _not_ a main window of a window group. There's
- ;; no rule for deleting such a window so we signal an error.
- ;; We might swallow this error silently.
- (error "Cannot delete non-main window of a window group"))
- ((not (composite-main-sibling window))
- ;; WINDOW has no main sibling and we can't delete the last
- ;; main window of a window group. We might swallow this
- ;; error silently.
- (error "Cannot delete last main window of a window group")))))))
-
- ;; Set PARENT to WINDOW's parent in the window tree. If there's
- ;; no such parent signal an error.
- (unless (setq parent (window-parent window))
- (error "Attempt to delete minibuffer or sole ordinary window"))
+ ((and (window-parameter window 'window-atom)
+ (setq atom-root (window-atom-root window))
+ (not (eq atom-root window)))
+ (throw 'done (delete-window atom-root)))
+ ((and (eq (window-parameter window 'window-side) 'none)
+ (or (not parent)
+ (not (eq (window-parameter parent 'window-side) 'none))))
+ (error "Attempt to delete last non-side window"))
+ ((not parent)
+ (error "Attempt to delete minibuffer or sole ordinary window")))
(let* ((horizontal (window-hchild parent))
(size (window-total-size window horizontal))
- (frame (window-frame window))
(frame-selected
(window-or-subwindow-p (frame-selected-window frame) window))
;; LEFT is WINDOW's _left_ sibling - traditionally LEFT
;; child windows of PARENT.
(sibling
(or (and left (not right) (not (window-left left)) left)
- (and right (not left) (not (window-right right)) right)))
- ;; Record some of PARENT's parameters (just in case we have
- ;; WINDOW replace it in the window tree).
- (parent-compound
- (and sibling (window-parameter parent 'compound)))
- (parent-group
- (and sibling (window-parameter parent 'group)))
- (parent-composite
- (and sibling (window-parameter parent 'composite))))
+ (and right (not left) (not (window-right right)) right))))
(resize-window-reset frame horizontal)
(cond
((or (and (eq window-splits 'nest)
(window-parameter
(frame-selected-window frame) 'no-other-window))
;; `delete-window-internal' has selected a window that should
- ;; not be selected, fix this here (I hate `other-window').
+ ;; not be selected, fix this here.
(other-window -1 frame))
- ;; Handle composite windows (unless we ignore window
- ;; parameters).
- (when (and (memq ignore-window-parameters '(nil pre))
- sibling (not (eq parent (window-parent sibling)))
- (or parent-compound parent-group))
- ;; At this moment we know that WINDOW and SIBLING are part of
- ;; a composite window and the _sole_ child windows of PARENT.
- ;; SIBLING replaces PARENT.
- (when parent-group
- ;; SIBLING becomes the new root of the window group earlier
- ;; headed by PARENT. If PARENT was the root of a compound
- ;; window that compound window gets dissolved.
- (set-window-parameter sibling 'group t))
- (if parent-composite
- ;; `sibling' inherits composite state of `parent'.
- (set-window-parameter sibling 'composite parent-composite)
- ;; `sibling' is no longer part of a composite window.
- (set-window-parameter sibling 'composite nil)))
+
(run-window-configuration-change-hook frame)
+ (window-check frame)
nil))))
(defun delete-other-windows (&optional window)
"Make WINDOW fill its frame.
WINDOW may be any window and defaults to the selected one.
-This function respects the variable `ignore-window-parameters'
-when processing window parameters so any processing of WINDOW's
-parameters may be suppressed.
-
-If the `delete-other-windows' parameter of WINDOW equals t,
-delete WINDOW ignoring any other window parameters. If the
-`delete-other-windows' parameter specifies a function, call that
-function with WINDOW as its sole argument. It's the
+If the variable `ignore-window-parameters' is non-nil do not
+process any parameters of WINDOW. Otherwise, if the
+`delete-other-windows-function' parameter of WINDOW equals t,
+delete WINDOW ignoring other window parameters. If the
+`delete-other-windows-function' parameter specifies a function,
+call that function with WINDOW as its sole argument. It's the
responsibility of that function to adjust the parameters of all
remaining windows.
-Otherwise, if WINDOW is part of a compound window, call this
-function with the root of the compound window as its argument.
-If WINDOW is a main window in a window group, make WINDOW the
-only main window in this group. Any support windows of the group
-are left alone. If WINDOW is a support window of a window group,
-signal an error and don't delete any windows."
+Otherwise, if WINDOW is part of an atomic window, call this
+function with the root of the atomic window as its argument. If
+WINDOW is a non-side window, make WINDOW the only non-side window
+on the frame. Side windows are not deleted. If WINDOW is a side
+window signal an error."
(interactive)
(setq window (normalize-any-window window))
- (let* ((function (window-parameter window 'delete-other-windows))
- (composite (window-parameter window 'composite))
- ;; COMPOSITE non-nil means WINDOW is part of a composite
- ;; window.
- (type (car-safe composite))
- (role (cdr-safe composite))
- (root (and composite (composite-root-window window)))
- ;; TYPE is the type of the composite window (either `compound'
- ;; or `group'). ROLE is the role of WINDOW within the
- ;; composite window (either `main', `support', or t). ROOT is
- ;; the root window of the composite window.
- main)
+ (let* ((frame (window-frame window))
+ (function (window-parameter window 'delete-other-windows-function))
+ (window-side (window-parameter window 'window-side))
+ atom-root side-main)
+ (window-check frame)
(catch 'done
- ;; Handle composite window parameter.
(cond
- ;; Ignore window parameters if `ignore-window-parameters' tells
- ;; so or the `delete-other-windows' parameter equals t.
- ((or (not (memq ignore-window-parameters '(nil post)))
- (eq function t)))
+ ;; Ignore window parameters if `ignore-window-parameters' is t or
+ ;; `delete-other-windows-function' is t.
+ ((or ignore-window-parameters (eq function t)))
((functionp function)
- ;; The `delete-other-windows' parameter specifies the function
- ;; to call instead. If the function is `ignore' no windows are
+ ;; The `delete-other-windows-function' parameter specifies the
+ ;; function to call. If the function is `ignore' no windows are
;; deleted. It's up to the function called to avoid infinite
;; recursion.
(throw 'done (funcall function window)))
- (composite
- (cond
- ((or (not root) (not type) (not role))
- ;; Something is broken in this composite window. Signal a
- ;; message but let the deletion pass through (we might signal
- ;; an error here but for everday work this is too nasty).
- (message "Broken composite window"))
- ((eq type 'compound)
- ;; In a compound window call `delete-other-windows' with the
- ;; root window as its argument.
- (throw 'done (delete-other-windows root)))
- ((eq type 'group)
- (if (eq role 'main)
- ;; In a window group we are allowed to delete main windows
- ;; only. Moreover we need an ancestor which is the last
- ;; main window found when following the path to the group
- ;; root window.
- (progn
- (setq main (composite-major-window window))
- (when (or (not main) (eq main window))
- ;; If we don't find an ancestor or the ancestor is
- ;; WINDOW itself there's nothing we can delete.
- ;; Swallow this quietly.
- (throw 'done nil))
- (when (and (eq main root)
- (memq ignore-window-parameters '(nil pre)))
- ;; If we delete right up to the root of this group
- ;; (that is, there are no support windows around) give
- ;; WINDOW the parameters of `root'.
- (set-window-parameter window 'group t)
- (set-window-parameter
- window 'composite (window-parameter root 'composite))))
- ;; We might swallow this message.
- (error
- "Cannot delete other windows for non-main window %s" window))))))
-
- (delete-other-windows-internal window main)
- (when (and (memq ignore-window-parameters '(nil pre))
- (frame-root-window-p window))
- ;; Clean up for the case where we did something special.
- (set-window-parameter window 'composite nil))
+ ((and (window-parameter window 'window-atom)
+ (setq atom-root (window-atom-root window))
+ (not (eq atom-root window)))
+ (throw 'done (delete-other-windows atom-root)))
+ ((eq window-side 'none)
+ ;; Set side-main to the major non-side window.
+ (setq side-main (window-with-parameter 'window-side 'none nil t)))
+ ((memq window-side window-sides)
+ (error "Cannot make side window the only window")))
+
+ (unless (eq window side-main)
+ (delete-other-windows-internal window side-main)
+ (run-window-configuration-change-hook frame)
+ (window-check frame))
nil)))
(defun delete-other-windows-vertically (&optional window)
;; If a window doesn't show BUFFER, unrecord it nevertheless.
(unrecord-window-buffer window buffer)))))
+;;; (defun delete-buffer-window (&optional buffer-or-name frames)
+;;; .... WRITE THIS
+
(defun replace-buffer-in-windows (&optional buffer-or-name)
"Replace BUFFER-OR-NAME with some other buffer in all windows showing it.
BUFFER-OR-NAME may be a buffer or the name of an existing buffer
small as one line or two columns. SIZE defaults to half of
WINDOW's size. The variable `window-splits' determines whether
the size of other windows is affected by this function.
+Interactively, SIZE is the prefix argument.
Optional third argument HORIZONTAL nil (or `below') specifies
that the new window shall be located below WINDOW. HORIZONTAL
fringes and the scrollbar or a divider column. Any other non-nil
value for HORIZONTAL is currently handled like t (or `right').
-If WINDOW is a component of a compound window \"split\" the root
-of the compound window instead. The new window does not become a
-member of the compound window. If WINDOW is a main window of a
-window group, the new window becomes a main window in that window
-group. If WINDOW is a non-main component of a window group
-signal an error.
+If WINDOW is part of an atomic window, \"split\" the root of the
+atomic window instead. The new window does not become a member
+of the atomic window. If WINDOW is a die window, signal an
+error.
If you split a live window, properties of the new window like
margins and scrollbars are inherited from WINDOW. If you split
an internal window, these properties as well as the buffer
-displayed in the new window are inherited from the selected
-window on WINDOW's frame."
+displayed in the new window are inherited from the window
+selected on WINDOW's frame."
(interactive "i")
(setq window (normalize-any-window window))
(let* ((horflag (and horizontal (not (memq horizontal '(below above)))))
- (function (window-parameter window 'split-window))
+ (frame (window-frame window))
+ (function (window-parameter window 'split-window-function))
;; Rebind this locally since in some cases we do have to nest.
(window-splits window-splits)
- ;; COMPOSITE non-nil means WINDOW is part of a composite
- ;; window. TYPE is the type of the composite window (either
- ;; `compound' or `group'). ROLE is the role of WINDOW within
- ;; the composite window (either `main', `support', or t). ROOT
- ;; is the root window of the composite window.
- (composite (window-parameter window 'composite))
- (type (car-safe composite))
- (role (cdr-safe composite))
- (root (and composite (composite-root-window window)))
- old-composite new-root new-main)
+ atom-root)
+ (window-check frame)
(catch 'done
(cond
- ;; Ignore window parameters if `ignore-window-parameters' tells
- ;; so or the `split-window' window parameter equals t.
- ((or (not (memq ignore-window-parameters '(nil post)))
- (eq function t)))
+ ;; Ignore window parameters if `ignore-window-parameters' is t or
+ ;; `split-window-function' is t.
+ ((or ignore-window-parameters (eq function t)))
((functionp function)
- ;; The `split-window' parameter specifies the function to call
- ;; instead. If this is `ignore', WINDOW won't be split.
+ ;; The `split-window-function' parameter specifies the function
+ ;; to call instead. If this is `ignore', WINDOW won't be split.
(throw 'done (funcall function window size horizontal)))
- ((and (not composite) (window-parameter window 'group)
- (window-live-p window))
- ;; WINDOW is a live group root window and not part of a
- ;; composite window so we need a new group root window. Note
- ;; that if WINDOW is also the root of a compound window, that
- ;; part remains unaffected by what we do here - WINDOW remains
- ;; root of the compound window which is now a component of a
- ;; window group.
- (setq window-splits 'nest)
- (setq new-root t))
- (composite
- (cond
- ((or (not root) (not type) (not role))
- ;; Something is broken in this composite window. Signal a
- ;; message but let the split pass through (we might signal
- ;; an error here but for everday work this is too nasty).
- (message "Broken component %s of composite window" window))
- ((eq type 'compound)
- ;; In a compound window split the root window.
- (throw 'done (split-window root size horizontal)))
- ((eq type 'group)
- (cond
- ((not (eq role 'main))
- ;; In a window group we are only allowed to split main
- ;; windows. We might swallow this error silently.
- (error "Cannot split non-main window %s in a window group" window))
- ((or (not (window-parent window)) ; Should have been handled above.
- (not (eq (composite-lowest-child-role (window-parent window))
- 'main)))
- (setq new-main t)
- ;; We must nest since otherwise we might end up with a
- ;; window group having two dominating main windows.
- (setq window-splits 'nest)))))))
-
- ;; The following line is hopefully not needed ...
- ;; (setq window-splits (if (eq window root) 'nest window-splits))
- (let* ((frame (window-frame window))
- (parent (window-parent window))
+ ;; For an atomic window split the entire atomic window instead.
+ ((and (window-parameter window 'window-atom)
+ (setq atom-root (window-atom-root window))
+ (not (eq atom-root window)))
+ (throw 'done (split-window atom-root size horizontal))))
+
+ (let* ((parent (window-parent window))
;; Size calculations.
(parent-size
(when parent (window-total-size parent horflag)))
(t
;; SIZE negative specifies the size of the new window.
(- size))))
- (root (window-parameter window 'root)))
+ (root (window-parameter window 'root))
+ (window-side (window-parameter window 'window-side)))
+ ;; Check window types and handle `window-splits' with sides.
+ (when (and window-side
+ (or (not parent)
+ (not (window-parameter parent 'window-side))))
+ ;; A side root window. Make sure a new parent gets created.
+ ;; Reset `resize' to nil too.
+ (setq window-splits 'nest)
+ (setq resize nil))
+
;; Check the sizes.
(cond
((not size)
(if horflag window-safe-min-width window-safe-min-height)))
(error "Cannot resize %s" window)))
- (resize-window-reset (window-frame window) horflag)
+ (resize-window-reset frame horflag)
(cond
(resize
;; Try to get space from OLD's siblings. We could go "up" and
(let* ((new (split-window-internal window new-size horizontal))
(new-parent (window-parent new)))
- (when (memq ignore-window-parameters '(nil pre))
- (cond
- ((and new-root (not (eq parent new-parent)))
- ;; `new-parent' becomes the new group root window
- ;; inheriting WINDOW's composite status. WINDOW and `new'
- ;; become main windows of that group.
- (set-window-parameter new-parent 'group t)
- (set-window-parameter new-parent 'composite composite)
- (set-window-parameter window 'group nil)
- (set-window-parameter window 'composite (cons 'group 'main))
- (set-window-parameter new 'composite (cons 'group 'main)))
- ((and new-main (not (eq parent new-parent)))
- ;; `new-parent' becomes the new dominating main window of
- ;; WINDOW's group.
- (set-window-parameter new-parent 'composite (cons 'group 'main))
- (set-window-parameter window 'composite (cons 'group 'main))
- (set-window-parameter new 'composite (cons 'group 'main)))
- (composite
- ;; `new' inherits parameters from WINDOW.
- (set-window-parameter new 'composite composite)
- (when (not (eq parent new-parent))
- ;; `new-parent' "inherits" the parameters as well
- (set-window-parameter new-parent 'composite composite)))))
- ;; We have to check once more how often these hooks are run.
+ (when window-side
+ ;; Inherit window-side parameters, if necessary.
+ (unless (eq parent new-parent)
+ (set-window-parameter new-parent 'window-side window-side))
+ (set-window-parameter new 'window-side window-side))
+
(run-window-configuration-change-hook frame)
- ;; Return the new window.
+ (window-check frame)
new)))))
;; I think this should be the default; I think people will prefer it--rms.
(set-window-parameter new-window 'quit-restore quit-restore)))
new-window))
\f
-;;; Composite windows.
-(defun make-compound-window (&optional window main size horizontal)
- "Make WINDOW the main window of a new compound window.
-This function creates a new internal window with WINDOW and a new
-leaf window as its only children. WINDOW must be a leaf window
-and defaults to the selected window.
-
-Optional argument MAIN non-nil makes the new leaf window a main
-window. MAIN nil or not provided means the new leaf window
-becomes a support window. WINDOW itself becomes a main window.
-
-Optional arguments SIZE and HORIZONTAL are as for `split-window'.
-
-Return the new leaf window."
- (setq window (normalize-any-window window))
- (unless (or (window-live-p window) (composite-root-window-p window))
- (error "Window %s must be live or a composite root window" window))
- (let* ((composite (window-parameter window 'composite))
- ;; FORCE and NEST.
- (ignore-window-parameters t)
- (window-splits 'nest)
- (new (split-window window size horizontal))
- (new-parent (window-parent new)))
- (set-window-parameter new-parent 'compound t)
- (when composite (set-window-parameter new-parent 'composite composite))
- (set-window-parameter window 'composite (cons 'compound 'main))
- (set-window-parameter
- new 'composite (cons 'compound (if main 'main 'support)))
- new))
-
-(defun make-window-group (&optional window)
- "Make WINDOW main and root window of a new window group.
-WINDOW must be a live window and defaults to the selected one.
-Return WINDOW."
- (setq window (normalize-live-window window))
- (set-window-parameter window 'composite (cons 'group 'main)))
-
-(defun make-support-window (window support &optional size horizontal)
- "Add support window of type SUPPORT to WINDOW."
- (let* ((compound (window-parameter window 'compound))
- (group (window-parameter window 'group))
- (composite (window-parameter window 'composite))
- (type (car-safe composite))
- (role (cdr-safe composite))
- ;; `type' is the type of the composite window (either
- ;; `compound' or `group'). `role' is the role of WINDOW within
- ;; the composite window (either `main', `support', or t).
- (root (when composite (composite-root-window window)))
- (parent (window-parent window))
- (ignore-window-parameters t)
- (window-splits 'nest)
- new new-parent)
- (cond
- ((not (memq support '(compound group)))
- (error "Invalid support argument %s" support))
- ((and (eq support 'compound) (not compound) (not (eq type 'compound)))
- (error "Window %s is not a component of a compound window" window))
- ((and (eq support 'group) (not group) (not (eq type 'group)))
- (error "Window %s is not a component of a window group" window))
- ((and (eq type 'main) (not (eq window (composite-major-window window))))
- (error "Can't embed support window in main window")))
- (setq new (split-window window size horizontal))
- (unless (eq parent (window-parent window))
- (setq new-parent (window-parent window)))
- (cond
- ;; This conditional looks incredibly tedious but let's keep the
- ;; distinct cases self-contained to avoid further confusion.
- ((and compound (eq support 'compound))
- (when new-parent
- ;; `new-parent' inherits the compound status of `window'
- (set-window-parameter new-parent 'compound t)
- (set-window-parameter window 'compound nil)
- (when composite
- ;; `new-parent' inherits the composite status of `window'.
- (set-window-parameter new-parent 'composite composite)
- (set-window-parameter
- ;; Give `window' the highest role of its children.
- window 'composite (cons 'compound
- (composite-lowest-child-role window)))))
- (when group
- ;; `new-parent' does not inherit the group status of `window'
- ;; (but make sure `window' retains it).
- (set-window-parameter window 'group t))
- (set-window-parameter new 'composite (cons 'compound 'support)))
- ((and group (eq support 'group))
- (when new-parent
- ;; `new-parent' inherits the group status of `window'
- (set-window-parameter new-parent 'group t)
- (set-window-parameter window 'group nil)
- (when composite
- ;; `new-parent' inherits the composite status of `window'.
- (set-window-parameter new-parent 'composite composite)
- (set-window-parameter
- ;; Give `window' the highest role of its children.
- window 'composite (cons 'group
- (composite-lowest-child-role window)))))
- (when compound
- ;; `new-parent' does not inherit the compound status of `window'
- ;; (but make sure `window' retains it).
- (set-window-parameter window 'compound t))
- (set-window-parameter new 'composite (cons 'group 'support)))
- ((and (eq type 'compound) (eq support 'compound))
- (cond
- (new-parent
- (let ((role (if (eq role 'support) 'support t)))
- (set-window-parameter new-parent 'composite (cons 'compound role))))
- ((not (compound-window-p parent))
- (let ((role (if (composite-support-window-p parent) 'support t)))
- (set-window-parameter parent 'composite (cons 'compound role)))))
- (when group
- ;; `new-parent' does not inherit the group status of `window'
- ;; (but make sure `window' retains it).
- (set-window-parameter window 'group t))
- (set-window-parameter window 'composite composite)
- (set-window-parameter new 'composite (cons 'compound 'support)))
- ((and (eq type 'group) (eq support 'group))
- (cond
- (new-parent
- (let ((role (if (eq role 'support) 'support t)))
- (set-window-parameter new-parent 'composite (cons 'group role))))
- ((not (compound-window-p parent))
- (let ((role (if (composite-support-window-p parent) 'support t)))
- (set-window-parameter parent 'composite (cons 'group role)))))
- (when compound
- ;; `new-parent' does not inherit the compound status of `window'
- ;; (but make sure `window' retains it).
- (set-window-parameter window 'compound t))
- (set-window-parameter window 'composite composite)
- (set-window-parameter new 'composite (cons 'group 'support))))
- new))
-\f
;;; Balancing windows.
(defun balance-windows (&optional window-or-frame)
"Balance the sizes of subwindows of WINDOW-OR-FRAME.
:version "24.1"
:group 'windows)
-(defcustom display-buffer-names nil
- "List associating buffer names with buffer display specifiers.
-The car of each element of this list specifies a set of buffer
-names. `display-buffer' displays a buffer whose name is a member
-of that set according to the display specifiers in the element's
-cdr \(note that elements are true lists).
-
-Valid display specifiers are symbols, cons cells, or lists.
-Buffer display specifiers that are symbols specify the location
-for showing the buffer. Three such specifiers are predefined:
-
-- `same-window' to preferably use the selected window,
-
-- `same-frame' to show the buffer on the selected frame, or
-
-- `other-frame' to show the buffer on another frame.
-
-Any other symbol with a function definition means to call that
-function to display the buffer. The function is called with two
-arguments - the buffer to display and a list of specifiers - and
-is supposed to display the buffer and return the window used for
-that purpose. The function is also responsible for giving the
-variable `display-buffer-window' and the
-`quit-restore' parameter of the window used a meaningful value.
-
-The remaining display specifiers are cons cells \(occasionally
-also true lists) whose components are listed below. The
-specifiers listed below are useful if the location specifier
-equals either `same-frame' or `other-frame':
-
-- `not-this-window' with a non-nil cdr can be used to specify
- that the selected window must not be used for displaying the
- buffer regardless of whether it shows that buffer or any other
- buffer.
-
-- `reuse-buffer-window' is used to specify whether a window
- currently showing the buffer may be reused and where to look
- for such a window. The possible values for the cdr are
-
- - `none', to never reuse a window showing the buffer,
-
- - nil, a reused window must be on the selected frame,
-
- - `visible', any such window must be on a visible frame,
-
- - 0 \(the number zero), meaning that any such window must be on
- a visible or iconified frame, and
-
- - t, the window may be on an arbitrary frame, including
- invisible ones.
-
-- `reuse-other-window' is used to specify whether a window
- currently _not_ showing the buffer may be reused and where to
- look for such a window. The possible values for the cdr are
- the same as for the `reuse-buffer-window' specifier.
-
-- `even-window-sizes' with a non-nil cdr means even out the sizes
- of a reused window and the selected window provided they (1)
- appear adjacent to each other and (2) the selected window is
- larger than the window chosen.
-
-The following display specifiers are useful if the location
-specifier equals 'same-frame:
-
-- `new-window' specifies whether a new window shall be made on
- the selected frame. For convenience, this specifier is
- represented by a true list. The cdr of the specifier is built
- from cons cells representing window/side pairings. The car of
- each cell identifies the window that shall be split. Possible
- values are `largest', `lru', `selected', `root' and `first' to
- split the largest, least recently used, selected, root or first
- window of the selected frame.
-
- The cdr specifies on which side of the window to split the new
- window shall appear and can be one of `below', `right',
- `above', or `left' with the obvious meanings. If the cdr is
- nil, the window is split in a fashion suitable for its current
- dimensions. If the cdr specifies a function, that function is
- called with two arguments - the window to split and a list of
- display specifiers. The function is supposed to split that
- window and return the new window.
-
- `display-buffer' scans these pairings until it can either
- produce a suitable window or fails. The default value for
- `display-buffer-regexps' contains (split-largest . nil) and
- (split-lru . nil) in order to make `display-buffer' try
- splitting the largest window first and, if that fails, the
- least recently used one.
-
-- The symbol `split-unsplittable-frame' with a non-nil cdr allows
- to make a new window on an unsplittable frame. This specifier
- should be used in special cases only since frames are usually
- made unsplittable in order to prevent `display-buffer' from
- splitting them.
-
-- `min-height' specifies the minimum height of a new window used
- for displaying the buffer. An integer number specifies the
- minimum number of lines of the window. A floating point number
- gives the minimum fraction of the window height with respect to
- the frame's root window. A new window will be made if and only
- if it can be made at least as high as specified by the number.
-
-- `min-width' specifies the minimum width of a new window used
- for displaying the buffer. An integer number specifies the
- minimum number of columns of the window. A floating point
- number gives the minimum fraction of the window width with
- respect to the frame's root window. A new window will be made
- if and only if it can be made at least as wide as specified by
- the number.
-
-- `adjust-height' with the following interpretations for the cdr:
-
- - nil means do not adjust the height of the new window.
-
- - A number specifying the desided height of the new window. An
- integer number specifies the minimum number of lines of the
- window. A floating point number gives the minimum fraction
- of the window height with respect to the frame's root window.
-
- - `even-window-heights' means to even the height of the new
- window with the height of the selected window provided these
- windows appear above each other.
+(defconst display-buffer-method-specifiers '(reuse-window pop-up-window pop-up-frame)
+ "Buffer display method specifiers.")
+
+(defconst display-buffer-default-specifiers
+ '((reuse-window nil same visible)
+ (pop-up-window (largest . nil) (lru . nil))
+ (pop-up-frame)
+ (pop-up-frame-alist
+ (height . 24) (width . 80) (unsplittable . t))
+ (reuse-window nil other visible)
+ (reuse-window-even-sizes . t))
+ "Buffer display default specifiers.
+The value specified here is used when no other specifiers have
+been specified by the user or the application. Consult the
+documentation of `display-buffer-alist' for a description of
+buffer display specifiers.")
+
+(defconst display-buffer-macro-specifiers
+ '((same-window
+ ;; Use the same window.
+ (reuse-window same nil nil))
+ (same-frame
+ ;; Avoid other frames.
+ (reuse-window nil same nil)
+ (pop-up-window (largest . nil) (lru . nil))
+ (reuse-window nil other nil))
+ (other-window
+ ;; Avoid selected window.
+ (reuse-window other same visible)
+ (pop-up-window (largest . nil) (lru . nil))
+ (pop-up-frame)
+ (reuse-window other other visible))
+ (same-frame-other-window
+ ;; Avoid other frames and selected window.
+ (reuse-window other same nil)
+ (pop-up-window (largest . nil) (lru . nil))
+ (reuse-window other other nil))
+ (other-visible-frame
+ ;; Avoid selected frame.
+ (reuse-window nil same other)
+ (pop-up-frame)
+ (reuse-window nil other other))
+ (default
+ ;; The default specifiers.
+ display-buffer-default-specifiers))
+ "Buffer display macro specifiers.")
+
+(defcustom display-buffer-alist
+ '((((regexp . ".*"))
+ reuse-window (reuse-window nil same visible)
+ pop-up-window
+ (pop-up-window (largest . nil) (lru . nil))
+ (pop-up-window-min-height . 24)
+ (pop-up-window-min-width . 60)
+ pop-up-frame
+ (pop-up-frame)
+ (pop-up-frame-alist
+ (height . 24) (width . 80) (unsplittable . t))
+ reuse-window (reuse-window nil other visible)
+ (reuse-window-even-sizes . t)))
+ "List associating buffer identifiers with display specifiers.
+The car of each element of this list is built from a set of cons
+cells called buffer identifiers. `display-buffer' shows a buffer
+according to the display specifiers in the element's cdr
+\(elements are true lists) if at least one of the identifiers
+matches the first or third argument of `display-buffer'. Such a
+match occurs in one of the following three cases:
+
+- The car of the buffer identifier is the symbol `name' and its
+ cdr is a string equalling the name of the buffer specified by
+ the first \(BUFFER-OR-NAME) argument of `display-buffer'.
+
+- The car is the symbol `regexp' and the cdr is a regular
+ expression matching the name of the buffer specified by the
+ first \(BUFFER-OR-NAME) argument of `display-buffer'.
+
+- The car is the symbol `label' and the cdr is a symbol equalling
+ the third \(LABEL) argument of `display-buffer'.
+
+Display specifiers are either symbols, cons cells, or lists.
+Three specifiers indicate the basic method for displaying the
+buffer: `reuse-window', `pop-up-window', `pop-up-frame' and
+`use-side-window'.
+
+A list whose car is the symbol `reuse-window' indicates that an
+existing window shall be reused for displaying the buffer. The
+second element of this list specifies the window to use and can
+be one of the following symbols:
+
+ nil stands for any window.
+
+ `same' stands for the selected window.
+
+ `other' stands for any but the selected window.
+
+The third element specifies whether the buffer shown in a window
+that shall be reused must be the same buffer that shall be
+displayed or another buffer and can be one of the following:
+
+ nil means to not care about the window's buffer.
+
+ `same' means the window must show the buffer already.
+
+ `other' means the window must not show the buffer yet.
+
+The fourth element specifies the set of frames to search for a
+suitable window and can be one of the following:
+
+ nil to reuse a window on the selected frame.
+
+ `visible' to search visible frames only.
+
+ `other' stands for any visible frame but the selected one.
+
+ 0 \(the number zero) to search visible and iconified frames.
+
+ t to search arbitrary frames including invisible ones.
+
+If more than one window fits the constraints imposed by these
+elements, the least recently used candidate is chosen. A side
+window is never reused unless it already shows the buffer.
+
+The following two specifiers are useful when the method equals
+`reuse-window':
+
+- A cons cell whose car is the symbol `reuse-window-even-sizes'
+ and whose cdr is non-nil means to even out the sizes of a
+ reused window and the selected window provided they (1) appear
+ adjacent to each other and (2) the selected window is larger
+ than the window chosen. If the cdr is nil, this means that the
+ window sizes are left alone.
+
+- A cons cell whose car is the symbol `reuse-window-dedicated'
+ and whose cdr is non-nil means that a window can be reused even
+ if it's weakly dedicated to its buffer. If the cdr is t, a
+ strongly dedicated window can be reused to show the buffer.
+ Any other non-nil value means only weakly dedicated windows can
+ be reused. If the cdr is nil, dedicated windows are not
+ reused.
+
+ This specifier should be used in emergency cases only since
+ windows are usually made dedicated in order to prevent
+ `display-buffer' from reusing them.
+
+A list whose car is the symbol `pop-up-window' and whose cdr is
+built from cons cells representing window/side tuples indicates
+that a new window shall be made for displaying the buffer on the
+selected frame.
+
+Window/side tuples are cons cells. The car of such a tuple
+identifies the window that shall be split. Possible values are
+`largest', `lru', `selected', and `root' to split the largest,
+least recently used, selected or root window of the selected
+frame.
+
+If the frame has side windows, these values do allow to split
+only the selected frame's main window or one of its subwindows.
+Setting the car to one of `left', `top', `right' and `bottom'
+splits the corresponding side window, provided such a window
+exists.
+
+The cdr of each pair specifies on which side of the window to
+split the new window shall appear and can be one of `below',
+`right', `above', or `left' with the obvious meanings. If the
+cdr is nil, the window is split in a fashion suitable for its
+current dimensions. If the cdr specifies a function, that
+function is called with two arguments - the window to split and a
+list of display specifiers. The function is supposed to split
+that window and return the new window.
+
+`display-buffer' scans these tuples until it can either produce a
+suitable window or fails. The default value for
+`display-buffer-alist' contains the tuples \(largest . nil) and
+\(lru . nil) in order to split the largest window first and, if
+that fails, the least recently used one.
+
+The following specifiers are useful if the method specifier is
+`pop-up-window'.
+
+- A cons cell whose car is the symbol `pop-up-window-min-height'
+ specifiies the minimum height of the new window. If the cdr is
+ an integer number, it specifies the minimum number of lines of
+ the window. A floating point number gives the minimum fraction
+ of the window height with respect to the height of the frame's
+ root window. A new window is created only if it can be made at
+ least as high as specified by the number. If the cdr is nil,
+ this means to use the value of `window-min-height'.
+
+- A cons cell whose car is the symbol `pop-up-window-min-width'
+ specifies the minimum width of the new window. If the cdr is
+ an integer number, it specifies the minimum number of columns
+ of the window. A floating point number gives the minimum
+ fraction of the window width with respect to the width of the
+ frame's root window. A new window is created only if it can be
+ made at least as wide as specified by the number. If the cdr
+ is nil, this means to use the value of `window-min-width'.
+
+- A cons cell whose car is `pop-up-window-set-height' with
+ the following interpretations for the cdr:
+
+ - nil means leave the height of the new window alone.
+
+ - A number specifies the desired height of the new window. An
+ integer number specifies the number of lines of the window.
+ A floating point number gives the fraction of the window
+ height with respect to the height of the frame's root window.
- If the cdr specifies a function, that function is called with
one argument - the new window. The function is supposed to
Suitable functions are `shrink-window-if-larger-than-buffer'
and `fit-window-to-buffer'.
-- `adjust-width' with the following interpretations for the cdr:
-
- - nil means do not adjust the width of the new window.
+- A cons cell whose car equals `pop-up-window-set-width' with
+ the following interpretations for the cdr:
- - A number specifying the desided width of the new window. An
- integer number specifies the minimum number of columns of the
- window. A floating point number gives the minimum fraction
- of the window width with respect to the frame's root window.
+ - nil means leave the width of the new window alone.
- - `even-window-widths' means to even the wdith of the new
- window with the width of the selected window provided these
- windows appear besides ach other.
+ - A number specifies the desired width of the new window. An
+ integer number specifies the number of columns of the window.
+ A floating point number gives the fraction of the window
+ width with respect to the width of the frame's root window.
- If the cdr specifies a function, that function is called with
one argument - the new window. The function is supposed to
- adjust the width of the window, its return value is ignored.
+ adjust the width of the window; its return value is ignored.
+
+ Observe that specifying `pop-up-window-height' or
+ `pop-up-window-height' may override restrictions given by the
+ `pop-up-min-height' or `pop-up-min-width' specifiers.
+
+- A cons cell whose car is `pop-up-window-split-unsplittable' and
+ whose cdr is non-nil allows to make a new window on an
+ unsplittable frame. If the cdr is nil, unsplittable frames are
+ not split. This specifier should be used in special cases only
+ since frames are usually made unsplittable in order to prevent
+ `display-buffer' from splitting them.
+
+A list whose car is the symbol `pop-up-frame' specifies that a
+new frame shall be made for displaying the buffer. The second
+element, if non-nil, allows popping up a new frame on graphic
+displays only.
+
+The following specifiers are useful if the method specifier is
+`pop-up-frame'.
+
+- A list whose car is the symbol `popup-frame-function' together
+ with a valid function as cdr specifies the function for
+ creating a new frame. If the cdr is nil, the default function
+ `make-frame' is called. The function is called with the
+ parameters and values provided by the specifier described next.
- Observe that specifying `adjust-height' or `adjust-width' may
- override restrictions given by the `min-height' or `min-width'
- specifiers.
+- A list whose car is the symbol `popup-frame-alist' followed by
+ an arbitrary number of frame parameter/value tuples, each given
+ as a cons cell, specifies the parameters passed to the popup
+ frame function.
-The specifiers listed next are useful if the location specifier
-equals 'other-frame:
+A list of three elements whose car is the symbol
+`use-side-window' specifies that the buffer shall be displayed in
+a side window of the selected frame. The second element denotes
+the side of the frame where the window appears or shall be made.
+The third element denotes the slot used by the window. If a side
+window with the specified slot exists already, that window is
+reused. If no such window exists it is created.
-- `not-this-frame' with a non-nil cdr means that the selected
- frame shall not be used for displaying the buffer.
+The following specifiers are useful in connection with the
+`use-side-window' method specifier: `reuse-window-dedicated',
+`pop-up-window-min-height', `pop-up-window-min-width',
+`pop-up-window-set-height' and `pop-up-window-set-width'.
-- `graphic-only' with a non-nil cdr means that a new frame shall
- be made on graphic displays only.
+Instead of supplying basic method specifiers, it's sometimes more
+convenient to use macro specifiers. They provide some commonly
+used display methods but do not support the fine control provided
+by the basic method specifiers. Macro specifiers are symbols.
+The following macro specifiers are provided:
-- `popup-frame-function' together with a valid function as cdr
- specifies the function for creating a new frame. The default
- function is `make-frame'. The function is called with the
- parameters and values provided by the specifier described next.
+ `same-window' to display the buffer in the selected window.
+
+ `same-frame' to display the buffer on the selected frame.
+
+ `other-window' to display the buffer in any window but the
+ selected one.
-- `popup-frame-alist' followed by an arbitrary number of frame
- parameter/value pairs, each given as a cons cell, specifies the
- parameters passed to the popup frame function. For
- convenience, this specifier is not a cons cell but a list whose
- first element is the symbol `popup-frame-alist' and whose
- remaining elements are pairs of parameters and values.
+ `same-frame-other-window' as `other-window' but stay on the
+ selected frame.
-One specifier is useful with any of the 'same-window,
-'same-frame, 'other-frame location specifiers: `dedicated' with a
-non-nil cdr can be used to dedicate a new window to the buffer.
-The cdr is either
+ `other-visible-frame' to display the buffer on another visible
+ frame.
-- nil, to not dedicate the window to the buffer,
+ `default' to use the default value of `display-buffer-alist'.
-- `weak', the window shall be weakly dedicated to its buffer, or
+One specifier is useful with any method specifier: A list whose
+car is the symbol `dedicate' and whose cdr is non-nil will
+dedicate the window to its buffer. The following values are
+supported:
-- t, to strongly dedicate the window to the buffer.
+- nil to not dedicate the window to the buffer.
+
+- `weak' to weakly dedicate the window to the buffer.
+
+- t to strongly dedicate the window to the buffer.
Usually, applications are free to override the specifiers of
-`display-buffer-names' by passing its own specifiers as second
-argument of `display-buffer'. For every `display-buffer-names'
+`display-buffer-alist' by passing their own specifiers as second
+argument of `display-buffer'. For every `display-buffer-alist'
entry you can, however, add a cons cell whose car is the symbol
`override' and whose cdr is non-nil, to explicitly override any
value supplied by the application.
Overriding specifiers supplied by the calling application is, in
general, not advisable. It permits, for example, to change the
-semantics of a function like `switch-to-buffer-other-window' by
+semantics of a function like `display-buffer-other-window' by
using the location specifiers `same-window' or `other-frame'."
:risky t
:type
'(repeat
:offset 9
+ ;; Associations of buffer identifiers and display specifiers.
(list
- :tag "Association"
+ :format "%v"
+ ;; Buffer identifiers.
(repeat
- :tag "Buffer names"
- (string :format "%v\n" :size 24))
+ :tag "Buffer identifiers"
+ (choice
+ :tag "Identifier"
+ :format "%[%t%] %v" :size 15
+ (cons
+ :tag "Name"
+ :format "%v"
+ :help-echo "A buffer name."
+ (const :format "" name)
+ (string :format "Name: %v\n" :size 32))
+ (cons
+ :tag "Regexp"
+ :format "%v"
+ :help-echo "A regular expression matching buffer names."
+ (const :format "" regexp)
+ (string :format "Regexp: %v\n" :size 32))
+ (cons
+ :tag "Label"
+ :format "%v"
+ :help-echo "A symbol equalling the buffer display label."
+ (const :format "" symbol)
+ (symbol :format "Label: %v\n" :size 32))))
+
+ ;; Display specifiers.
(repeat
:offset 9
:tag "Display specifiers"
:inline t
(list
- :tag "Specifiers"
:inline t
:format "%v"
(choice
- :tag "Locations"
+ :tag "Method"
+ :value (reuse-window
+ (reuse-window nil same nil)
+ (reuse-window-even-sizes . t))
:inline t
- :help-echo "Choose a location for displaying the buffer(s)."
- :value (same-frame
- (reuse-buffer-window . nil)
- (even-window-sizes . t)
- (new-window (largest . nil) (lru . nil))
- (min-height . 24) (min-width . 60))
- :format "%[Location%] %v" :size 15
-
- ;; Same window.
- (list
- :tag "Same window"
- :format "%t%v"
- :inline t
- (const :format "\n" same-window)
- (set
- :format "%v" :inline t
- (cons
- :format "%v"
- (const :format "" dedicated)
- (choice
- :tag "Dedicate window to buffer" :value nil
- :help-echo "Mark window as dedicated to its buffer."
- :format "%[%t%] %v\n" :size 15
- (const :tag "Off" :format "%t" nil)
- (const :tag "Weak" :format "%t" weak)
- (const :tag "Strong" :format "%t" t)))))
+ :help-echo "Method for displaying the buffer."
+ :format "%[Method%] %v" :size 15
- ;; Same frame.
+ ;; Reuse window specifiers.
(list
- :tag "Same frame"
- :value (same-frame
- (reuse-buffer-window . nil)
- (even-window-sizes . t)
- (new-window (largest . nil) (lru . nil))
- (min-height . 24) (min-width . 60))
- :format "%t%v"
+ :tag "Reuse window"
+ :value (reuse-window
+ (reuse-window nil same nil)
+ (reuse-window-even-sizes . t))
+ :format "%t\n%v"
:inline t
- (const :format "\n" same-frame)
+ ;; For customization purposes only.
+ (const :format "" reuse-window)
(set
- :format "%v" :inline t
- (cons
- :tag "Avoid selected window"
- :format "%v%t\n"
- (const :format "" not-this-window)
- (const :format "" t))
- (cons
- :format "%v"
- (const
- :format "" reuse-buffer-window)
+ :format "%v"
+ :inline t
+ ;; The window to reuse.
+ (list
+ :format "%v\n"
+ (const :format "" reuse-window)
+ ;; The window type.
(choice
- :tag "Reuse buffer window"
- :help-echo "Frames to search for a window showing the buffer."
- :value nil :format "%[Reuse buffer window%] %v\n" :size 15
- (const :tag "None" :format "%t" none)
- (const :tag "Selected frame only" :format "%t" nil)
- (const :tag "Visible frames" :format "%t" visible)
- (const :tag "Visible and iconified frames" :format "%t" 0)
- (const :tag "All frames" :format "%t" t)))
- (cons
- :format "%v"
- (const
- :format "" reuse-other-window)
+ :tag "Window"
+ :help-echo "Window to reuse."
+ :value nil
+ :format "%[Window%] %v" :size 15
+ (const :tag "Any" :format "%t" nil)
+ (const :tag "Selected only" :format "%t" same)
+ (const :tag "Any but selected" :format "%t" other))
+ ;; The window's buffer.
(choice
- :tag "Reuse other window"
- :help-echo "Frames to search for a window not showing the buffer."
- :value nil :format "%[Reuse other window%] %v\n" :size 15
- (const :tag "None" :format "%t" none)
+ :tag "Buffer"
+ :help-echo "Buffer shown by reused window."
+ :value t
+ :format " %[Buffer%] %v" :size 15
+ (const :tag "Any buffer" :format "%t" nil)
+ (const :tag "Same buffer" :format "%t" same)
+ (const :tag "Other buffer" :format "%t" other))
+ ;; The window's frame.
+ (choice
+ :help-echo "Frame to search for a window to reuse."
+ :tag "Frame"
+ :value nil
+ :format " %[Frame%] %v" :size 15
(const :tag "Selected frame only" :format "%t" nil)
(const :tag "Visible frames" :format "%t" visible)
- (const :tag "Visible and iconified frames" :format "%t" 0)
- (const :tag "All frames" :format "%t" t)))
+ (const :tag "Visible but unselected" :format "%t" other)
+ (const :tag "Visible and iconified" :format "%t" 0)
+ (const :tag "Any frame" :format "%t" t)))
+ ;; Whether window sizes should be evened out.
(cons
+ :format "%v\n"
:tag "Even window sizes"
- :format "%v%t\n"
- (const :format "" even-window-sizes)
- (const :format "" t))
+ (const :format "" reuse-window-even-sizes)
+ (choice
+ :tag "Even window sizes"
+ :help-echo "Whether to even sizes of selected and reused window."
+ :value t
+ :format "%[Even window sizes%] %v" :size 15
+ (const :tag "Off" :format "%t" nil)
+ (const :tag "Even window sizes" :format "%t" t)))
+ ;; Whether to reuse a dedicated window
+ (cons
+ :format "%v\n"
+ (const :format "" reuse-window-dedicated)
+ (choice
+ :tag "Reuse dedicated window" :value nil
+ :help-echo "Reuse a window even if it is dedicated to its buffer."
+ :format "%[Reuse dedicated window%] %v" :size 15
+ (const :tag "Off" :format "%t" nil)
+ (const :tag "Reuse weakly dedicated windows" :format "%t" weak)
+ (const :tag "Reuse any dedicated window" :format "%t" t)))))
+
+ ;; Pop-up window specifiers.
+ (list
+ :tag "Pop-up window"
+ :value (pop-up-window (pop-up-window (largest . nil) (lru . nil)))
+ :format "%t\n%v"
+ :inline t
+ (const :format "" pop-up-window)
+ (set
+ :format "%v"
+ :inline t
+ ;; Pop-up window list.
(list
:format "%v"
- :value (new-window (largest . nil) (lru . nil))
- (const :format "" new-window)
+ :value (pop-up-window (largest . nil) (lru . nil))
+ (const :format "" pop-up-window)
(repeat
+ :tag "Window / Side tuples"
:inline t
- :tag "Window / Side pairings"
(cons
- :format "%v"
+ :format "%v\n"
(choice
- :tag "Window" :help-echo "The window to split."
- :value largest :format "%[Window%] %v" :size 15
+ :tag "Window"
+ :help-echo "The window to split."
+ :value largest
+ :format "%[Window%] %v"
(const :tag "Largest" :format "%t" largest)
(const :tag "Least recently used" :format "%t" lru)
(const :tag "Selected" :format "%t" selected)
(const :tag "Root" :format "%t" root)
- (const :tag "First" :format "%t" first))
+ (const :tag "Left" :format "%t" left)
+ (const :tag "Top" :format "%t" top)
+ (const :tag "Right" :format "%t" right)
+ (const :tag "Bottom" :format "%t" bottom))
(choice
:tag "Side"
:help-echo "The position of the new window with respect to the window to split."
- :value nil :format " %[Side%] %v" :size 15
- (const :tag "Dynamic" nil)
- (const :tag "Below" below)
- (const :tag "Right" right)
- (const :tag "Above" above)
- (const :tag "Left" left)
+ :value nil
+ :format " %[Side%] %v"
+ (const :tag "Dynamic" :format "%t" nil)
+ (const :tag "Below" :format "%t" below)
+ (const :tag "Right" :format "%t" right)
+ (const :tag "Above" :format "%t" above)
+ (const :tag "Left" :format "%t" left)
(function
- :tag "Function" :format "%v\n" :size 25)))))
- (cons
- :tag "Make new window even if frame is unsplittable" :size 5
- :format "%v%t\n"
- (const :format "" split-unsplittable-frame)
- (const :format "" t))
+ :tag "Function" :format "%v" :size 25)))))
+ ;; Minimum height of pop-up windows.
(cons
:format "%v\n"
- (const :format "" min-height)
- (number
- :tag "Minimum height of new window" :value 12 :size 5))
+ (const :format "" pop-up-window-min-height)
+ (choice
+ :help-echo "Minimum height of popped-up window."
+ :format "%[Minimum height%] %v"
+ (const :tag "Default" :format "%t" :value nil)
+ (integer :tag "Number of lines" :value 12 :size 5)
+ (float :tag "Fraction of frame height" :value .25 :size 5)))
+ ;; Minimum width of pop-up windows.
(cons
:format "%v\n"
- (const :format "" min-width)
- (number
- :tag "Minimum width of new window" :value 60 :size 5))
+ (const :format "" pop-up-window-min-width)
+ (choice
+ :help-echo "Minimum width of popped-up window."
+ :format "%[Minimum width%] %v"
+ (const :tag "Default" :format "%t" :value nil)
+ (integer :tag "Number of columns" :value 12 :size 5)
+ (float :tag "Fraction of frame width" :value .25 :size 5)))
+ ;; Desired height of pop-up windows.
(cons
- :format "%v"
- (const :format "" adjust-height)
+ :format "%v\n"
+ (const :format "" pop-up-window-set-height)
(choice
- :tag "Adjust window height"
- :help-echo "Whether window height shall be adjusted."
- :format "%[Adjust height%] %v\n" :size 15
- ;; nil matters when we want to override.
- (const :tag "Do not adjust heights" :format "%t" nil)
- (number :tag "Desired height" :value 60 :size 5)
+ :help-echo "Desired height of popped-up window."
+ :format "%[Desired height%] %v"
+ (const :tag "Default" :format "%t" :value nil)
+ (integer :tag "Number of lines" :value 12 :size 5)
+ (float :tag "Fraction of frame height" :value .25 :size 5)
(function :tag "Function" :size 25)))
+ ;; Desired width of pop-up windows.
(cons
- :format "%v"
- (const :format "" adjust-width)
+ :format "%v\n"
+ (const :format "" pop-up-window-set-width)
(choice
- :tag "Adjust window width" :value nil
- :help-echo "Whether window width shall be adjusted."
- :format "%[Adjust width%] %v\n" :size 15
- ;; nil matters when we want to override.
- (const :tag "Do not adjust widths" :format "%t" nil)
- (number :tag "Desired width" :value 120 :size 5)
+ :help-echo "Desired width of popped-up window."
+ :format "%[Desired width%] %v"
+ (const :tag "Default" :format "%t" :value nil)
+ (integer :tag "Number of column" :value 12 :size 5)
+ (float :tag "Fraction of frame width" :value .25 :size 5)
(function :tag "Function" :size 25)))
+ ;; Split unsplittable frames.
(cons
- :format "%v"
- :inline t
- (const :format "" dedicated)
+ :format "%v\n"
+ (const :format "" pop-up-window-unsplittable)
(choice
- :tag "Dedicate window to buffer" :value nil
- :help-echo "Mark window as dedicated to its buffer."
- :format "%[%t%] %v\n" :size 15
+ :help-echo "Allow popping up a window on \"unsplittable\" frames."
+ :format "%[Split unsplittable frame%] %v"
(const :tag "Off" :format "%t" nil)
- (const :tag "Weak" :format "%t" weak)
- (const :tag "Strong" :format "%t" t)))))
+ (const :tag "Allow" :format "%t" t)))))
- ;; Other frame.
+ ;; Pop-up frame specifiers.
(list
- :tag "Other frame"
- :value (other-frame
- (reuse-buffer-window . visible)
- (graphic-only . t)
- (popup-frame-alist
+ :tag "Pop-up frame"
+ :value (pop-up-frame
+ (pop-up-frame)
+ (pop-up-frame-alist
(height . 24) (width . 80) (unsplittable . t)))
- :format "%t%v"
+ :format "%t\n%v"
:inline t
- (const :format "\n" other-frame)
+ (const :format "" pop-up-frame)
(set
:format "%v"
:inline t
- (cons
- :tag "Avoid selected window"
- :format "%v%t\n"
- (const :format "" other-window)
- (const :format "" t))
- (cons
+ ;; Pop-up frame.
+ (list
+ :tag "Pop-up a new frame"
+ :value (pop-up-frame)
:format "%v"
- (const
- :format "" reuse-buffer-window)
+ (const :format "" pop-up-frame)
(choice
- :tag "Reuse buffer window"
- :help-echo "Frames to search for a window showing the buffer."
- :value nil :format "%[Reuse buffer window%] %v\n" :size 15
- (const :tag "None" :format "%t" none)
- (const :tag "Selected frame only" :format "%t" nil)
- (const :tag "Visible frames" :format "%t" visible)
- (const :tag "Visible and iconified frames" :format "%t" 0)
- (const :tag "All frames" :format "%t" t)))
+ :tag "Pop-up a new frame"
+ :help-echo "Whether to pop-up a new frame on a display."
+ :format "%[Display%] %v\n" :size 15
+ (const :tag "On any display" :format "%t" nil)
+ (const :tag "On graphic displays only" :format "%t" t)))
+ ;; Pop-up frame function
(cons
- :format "%v"
- (const
- :format "" reuse-other-window)
+ :format "%v\n"
+ (const :format "" pop-up-frame-function)
(choice
- :tag "Reuse other window"
- :help-echo "Frames to search for a window not showing the buffer."
- :value nil :format "%[Reuse other window%] %v\n" :size 15
- (const :tag "None" :format "%t" none)
- (const :tag "Selected frame only" :format "%t" nil)
- (const :tag "Visible frames" :format "%t" visible)
- (const :tag "Visible and iconified frames" :format "%t" 0)
- (const :tag "All frames" :format "%t" t)))
- (cons
- :tag "Even window sizes"
- :format "%v%t\n"
- (const :format "" even-window-sizes)
- (const :format "" t))
- (cons
- :tag "Avoid selected frame"
- :format "%v%t\n"
- (const :format "" not-this-frame)
- (const :format "" t))
- (cons
- :tag "Switch to another frame on graphic displays only"
- :format "%v%t\n"
- (const :format "" graphic-only)
- (const :format "" t))
- (cons
- :format "%v"
- (const :format "" popup-frame-function)
- (function
- :tag "Popup frame function"
- :value make-frame
- :format "%t: %v\n"
- :size 25))
+ :tag "Pop-up frame function"
+ :value nil
+ :help-echo "Function to use to pop-up a new frame."
+ :format "%[Function%] %v" :size 15
+ (const :tag "Default" :format "%t" nil)
+ (function
+ :value make-frame
+ :format "%t: %v"
+ :size 25)))
+ ;; Pop-up frame alist.
(list
:format "%v"
- :value (popup-frame-alist (height . 24) (width . 80) (unsplittable . t))
- (const :format "" popup-frame-alist)
+ (const :format "" pop-up-frame-alist)
(repeat
- :tag "Parameter / Value pairings"
- :inline t
+ :tag "Parameter / Value tuples"
+ :inline t
(cons
:format "%v\n"
(symbol
(sexp
:tag "Value"
:format " Value: %v"
- :size 8))))
+ :size 8))))))
+
+ ;; Use side-window specifiers.
+ (list
+ :tag "Use side-window"
+ :value (use-side-window (use-side-window bottom 0))
+ :format "%t\n%v"
+ :inline t
+ ;; For customization purposes only.
+ (const :format "" use-side-window)
+ (set
+ :format "%v"
+ :inline t
+ ;; Side and slot.
+ (list
+ :format "%v\n"
+ :value (use-side-window bottom 0)
+ (const :format "" use-side-window)
+ ;; The side.
+ (choice
+ :tag "Side"
+ :help-echo "Side of frame."
+ :value bottom
+ :format "%[Side%] %v" :size 15
+ (const :tag "Left" :format "%t" left)
+ (const :tag "Top" :format "%t" top)
+ (const :tag "Right" :format "%t" right)
+ (const :tag "Bottom" :format "%t" bottom))
+ ;; The slot
+ (number
+ :tag "Slot"
+ :help-echo "The slot (an arbitrary number, where 0 stands for the center slot)."
+ :value 0
+ :format " Slot: %v" :size 8))
+ ;; Whether to reuse a dedicated side window
(cons
- :format "%v"
- (const :format "" dedicated)
+ :format "%v\n"
+ (const :format "" reuse-window-dedicated)
(choice
- :tag "Dedicate window to buffer" :value nil
- :help-echo "Mark window as dedicated to its buffer."
- :format "%[%t%] %v\n" :size 15
+ :tag "Reuse dedicated side window" :value nil
+ :help-echo "Reuse a side window even if it is dedicated to its buffer."
+ :format "%[Reuse dedicated side window%] %v" :size 15
(const :tag "Off" :format "%t" nil)
- (const :tag "Weak" :format "%t" weak)
- (const :tag "Strong" :format "%t" t)))))
-
- ;; Function.
+ (const :tag "Reuse weakly dedicated side windows" :format "%t" weak)
+ (const :tag "Reuse any dedicated side window" :format "%t" t)))
+ ;; Minimum height of pop-up side windows.
+ (cons
+ :format "%v\n"
+ (const :format "" pop-up-window-min-height)
+ (choice
+ :help-echo "Minimum height of popped-up side window."
+ :format "%[Minimum height%] %v"
+ (const :tag "Default" :format "%t" :value nil)
+ (integer :tag "Number of lines" :value 12 :size 5)
+ (float :tag "Fraction of frame height" :value .25 :size 5)))
+ ;; Minimum width of pop-up windows.
+ (cons
+ :format "%v\n"
+ (const :format "" pop-up-window-min-width)
+ (choice
+ :help-echo "Minimum width of popped-up side window."
+ :format "%[Minimum width%] %v"
+ (const :tag "Default" :format "%t" :value nil)
+ (integer :tag "Number of columns" :value 12 :size 5)
+ (float :tag "Fraction of frame width" :value .25 :size 5)))
+ ;; Desired height of pop-up windows.
+ (cons
+ :format "%v\n"
+ (const :format "" pop-up-window-set-height)
+ (choice
+ :help-echo "Desired height of popped-up side window."
+ :format "%[Desired height%] %v"
+ (const :tag "Default" :format "%t" :value nil)
+ (integer :tag "Number of lines" :value 12 :size 5)
+ (float :tag "Fraction of frame height" :value .25 :size 5)
+ (function :tag "Function" :size 25)))
+ ;; Desired width of pop-up windows.
+ (cons
+ :format "%v\n"
+ (const :format "" pop-up-window-set-width)
+ (choice
+ :help-echo "Desired width of popped-up side window."
+ :format "%[Desired width%] %v"
+ (const :tag "Default" :format "%t" :value nil)
+ (integer :tag "Number of column" :value 12 :size 5)
+ (float :tag "Fraction of frame width" :value .25 :size 5)
+ (function :tag "Function" :size 25)))))
+
+ ;; Macro specifiers.
(list
- :tag "Function"
- :format "%t%v\n"
+ :tag "Same frame only"
+ :format "%t%v"
:inline t
- (function
- :tag ""
- :size 25)))))
-
- ;; Specifiers that are not location specific.
- (set
- :format "%v"
- :inline t
- (cons
- :tag "Override other specifiers"
- :format "%v%t\n"
- (const :format "" override)
- (const :format "" t)))))
- :group 'windows
- :group 'frames)
-
-(defcustom display-buffer-regexps
- '(((".*")
- same-frame
- (reuse-buffer-window . nil)
- (new-window (largest . nil) (lru . nil))
- (min-height . 24) (min-width . 60)
- (even-window-sizes . t)
- other-frame
- (reuse-buffer-window . visible)
- (graphic-only . t)
- (popup-frame-alist
- (height . 24) (width . 80) (unsplittable . t))))
- "List associating regexps with buffer display specifiers.
-The car of each element of this list is a list of regular
-expressions. Buffers whose name matches that expression are
-displayed according to the list of buffer display specifiers
-constituting the cdr of the element. Consult the documentation
-of the variable `display-buffer-names' for a description of valid
-display specifiers.
-
-The default value of this variable provides one element matching
-all buffers. It states that any buffer shall be displayed
-preferably on the selected frame. If, however, there already
-exists a window showing the buffer on the selected frame,
-`display-buffer' returns that window. Otherwise, it tries to
-split either the largest or the least recently used window with
-the new window below or on the right of the window that is split.
-The minimum height of the new window shall be 24 lines, its
-minimum width 60 columns. If a window above or below the
-selected window is used, the heights of both windows shall be
-evened out.
-
-If these specifiers fail to produce a suitable window and a
-graphic display is used, then the buffer shall be displayed on a
-new frame unless a window showing the buffer can be found on some
-visible. The function to pop up a new frame is given three
-parameters: A frame height of 24 lines, a frame width of 80
-lines, and a non-nil unsplittable property."
- :risky t
- :type
- '(repeat
- :offset 9
- (list
- :tag "Association"
- (repeat
- :tag "Regular expressions that match buffer names"
- (string :format "%v\n" :size 48))
- (repeat
- :offset 9
- :tag "Display specifiers"
- :inline t
- (list
- :tag "Specifiers"
- :inline t
- :format "%v"
- (choice
- :tag "Locations"
- :inline t
- :help-echo "Choose a location for displaying the buffer(s)."
- :value (same-frame
- (reuse-buffer-window . nil)
- (even-window-sizes . t)
- (new-window (largest . nil) (lru . nil))
- (min-height . 24) (min-width . 60))
- :format "%[Location%] %v" :size 15
-
- ;; Same window.
+ (const :format "\n" same-frame))
(list
- :tag "Same window"
+ :tag "Other window"
:format "%t%v"
:inline t
- (const :format "\n" same-window)
- (set
- :format "%v" :inline t
- (cons
- :format "%v"
- (const :format "" dedicated)
- (choice
- :tag "Dedicate window to buffer" :value nil
- :help-echo "Mark window as dedicated to its buffer."
- :format "%[%t%] %v\n" :size 15
- (const :tag "Off" :format "%t" nil)
- (const :tag "Weak" :format "%t" weak)
- (const :tag "Strong" :format "%t" t)))))
-
- ;; Same frame.
+ (const :format "\n" other-window))
(list
- :tag "Same frame"
- :value (same-frame
- (reuse-buffer-window . nil)
- (even-window-sizes . t)
- (new-window (largest . nil) (lru . nil))
- (min-height . 24) (min-width . 60))
+ :tag "Same frame other window"
:format "%t%v"
:inline t
- (const :format "\n" same-frame)
- (set
- :format "%v" :inline t
- (cons
- :tag "Avoid selected window"
- :format "%v%t\n"
- (const :format "" not-this-window)
- (const :format "" t))
- (cons
- :format "%v"
- (const
- :format "" reuse-buffer-window)
- (choice
- :tag "Reuse buffer window"
- :help-echo "Frames to search for a window showing the buffer."
- :value nil :format "%[Reuse buffer window%] %v\n" :size 15
- (const :tag "None" :format "%t" none)
- (const :tag "Selected frame only" :format "%t" nil)
- (const :tag "Visible frames" :format "%t" visible)
- (const :tag "Visible and iconified frames" :format "%t" 0)
- (const :tag "All frames" :format "%t" t)))
- (cons
- :format "%v"
- (const
- :format "" reuse-other-window)
- (choice
- :tag "Reuse other window"
- :help-echo "Frames to search for a window not showing the buffer."
- :value nil :format "%[Reuse other window%] %v\n" :size 15
- (const :tag "None" :format "%t" none)
- (const :tag "Selected frame only" :format "%t" nil)
- (const :tag "Visible frames" :format "%t" visible)
- (const :tag "Visible and iconified frames" :format "%t" 0)
- (const :tag "All frames" :format "%t" t)))
- (cons
- :tag "Even window sizes"
- :format "%v%t\n"
- (const :format "" even-window-sizes)
- (const :format "" t))
- (list
- :format "%v"
- :value (new-window (largest . nil) (lru . nil))
- (const :format "" new-window)
- (repeat
- :inline t
- :tag "Window / Side pairings"
- (cons
- :format "%v"
- (choice
- :tag "Window" :help-echo "The window to split."
- :value largest :format "%[Window%] %v" :size 15
- (const :tag "Largest" :format "%t" largest)
- (const :tag "Least recently used" :format "%t" lru)
- (const :tag "Selected" :format "%t" selected)
- (const :tag "Root" :format "%t" root)
- (const :tag "First" :format "%t" first))
- (choice
- :tag "Side"
- :help-echo "The position of the new window with respect to the window to split."
- :value nil :format " %[Side%] %v" :size 15
- (const :tag "Dynamic" nil)
- (const :tag "Below" below)
- (const :tag "Right" right)
- (const :tag "Above" above)
- (const :tag "Left" left)
- (function
- :tag "Function" :format "%v\n" :size 25)))))
- (cons
- :tag "Make new window even if frame is unsplittable" :size 5
- :format "%v%t\n"
- (const :format "" split-unsplittable-frame)
- (const :format "" t))
- (cons
- :format "%v\n"
- (const :format "" min-height)
- (number
- :tag "Minimum height of new window" :value 12 :size 5))
- (cons
- :format "%v\n"
- (const :format "" min-width)
- (number
- :tag "Minimum width of new window" :value 60 :size 5))
- (cons
- :format "%v"
- (const :format "" adjust-height)
- (choice
- :tag "Adjust window height"
- :help-echo "Whether window height shall be adjusted."
- :format "%[Adjust height%] %v\n" :size 15
- ;; nil matters when we want to override.
- (const :tag "Do not adjust heights" :format "%t" nil)
- (number :tag "Desired height" :value 60 :size 5)
- (function :tag "Function" :size 25)))
- (cons
- :format "%v"
- (const :format "" adjust-width)
- (choice
- :tag "Adjust window width" :value nil
- :help-echo "Whether window width shall be adjusted."
- :format "%[Adjust width%] %v\n" :size 15
- ;; nil matters when we want to override.
- (const :tag "Do not adjust widths" :format "%t" nil)
- (number :tag "Desired width" :value 120 :size 5)
- (function :tag "Function" :size 25)))
- (cons
- :format "%v"
- :inline t
- (const :format "" dedicated)
- (choice
- :tag "Dedicate window to buffer" :value nil
- :help-echo "Mark window as dedicated to its buffer."
- :format "%[%t%] %v\n" :size 15
- (const :tag "Off" :format "%t" nil)
- (const :tag "Weak" :format "%t" weak)
- (const :tag "Strong" :format "%t" t)))))
-
- ;; Other frame.
+ (const :format "\n" same-frame-other-window))
(list
- :tag "Other frame"
- :value (other-frame
- (reuse-buffer-window . visible)
- (graphic-only . t)
- (popup-frame-alist
- (height . 24) (width . 80) (unsplittable . t)))
+ :tag "Other frame only"
:format "%t%v"
:inline t
- (const :format "\n" other-frame)
- (set
- :format "%v"
- :inline t
- (cons
- :tag "Avoid selected window"
- :format "%v%t\n"
- (const :format "" other-window)
- (const :format "" t))
- (cons
- :format "%v"
- (const
- :format "" reuse-buffer-window)
- (choice
- :tag "Reuse buffer window"
- :help-echo "Frames to search for a window showing the buffer."
- :value nil :format "%[Reuse buffer window%] %v\n" :size 15
- (const :tag "None" :format "%t" none)
- (const :tag "Selected frame only" :format "%t" nil)
- (const :tag "Visible frames" :format "%t" visible)
- (const :tag "Visible and iconified frames" :format "%t" 0)
- (const :tag "All frames" :format "%t" t)))
- (cons
- :format "%v"
- (const
- :format "" reuse-other-window)
- (choice
- :tag "Reuse other window"
- :help-echo "Frames to search for a window not showing the buffer."
- :value nil :format "%[Reuse other window%] %v\n" :size 15
- (const :tag "None" :format "%t" none)
- (const :tag "Selected frame only" :format "%t" nil)
- (const :tag "Visible frames" :format "%t" visible)
- (const :tag "Visible and iconified frames" :format "%t" 0)
- (const :tag "All frames" :format "%t" t)))
- (cons
- :tag "Even window sizes"
- :format "%v%t\n"
- (const :format "" even-window-sizes)
- (const :format "" t))
- (cons
- :tag "Avoid selected frame"
- :format "%v%t\n"
- (const :format "" not-this-frame)
- (const :format "" t))
- (cons
- :tag "Switch to another frame on graphic displays only"
- :format "%v%t\n"
- (const :format "" graphic-only)
- (const :format "" t))
- (cons
- :format "%v"
- (const :format "" popup-frame-function)
- (function
- :tag "Popup frame function"
- :value make-frame
- :format "%t: %v\n"
- :size 25))
- (list
- :format "%v"
- :value (popup-frame-alist (height . 24) (width . 80) (unsplittable . t))
- (const :format "" popup-frame-alist)
- (repeat
- :tag "Parameter / Value pairings"
- :inline t
- (cons
- :format "%v\n"
- (symbol
- :tag "Parameter"
- :format "Parameter: %v"
- :size 16)
- (sexp
- :tag "Value"
- :format " Value: %v"
- :size 8))))
- (cons
- :format "%v"
- (const :format "" dedicated)
- (choice
- :tag "Dedicate window to buffer" :value nil
- :help-echo "Mark window as dedicated to its buffer."
- :format "%[%t%] %v\n" :size 15
- (const :tag "Off" :format "%t" nil)
- (const :tag "Weak" :format "%t" weak)
- (const :tag "Strong" :format "%t" t)))))
-
- ;; Function.
+ (const :format "\n" other-visible-frame))
(list
- :tag "Function"
- :format "%t%v\n"
+ :tag "Default"
+ :format "%t%v"
:inline t
- (function
- :tag ""
- :size 25)))))
+ (const :format "\n" default)))))
- ;; Specifiers that are not location specific.
(set
:format "%v"
:inline t
+ ;; Dedicate window to buffer.
(cons
- :tag "Override other specifiers"
- :format "%v%t\n"
+ :format "%v"
+ (const :format "" dedicate)
+ (choice
+ :help-echo "Mark window as dedicated to its buffer."
+ :format "%[Dedicate window to buffer%] %v\n" :size 15
+ (const :tag "Off" :format "%t" nil)
+ (const :tag "Weak" :format "%t" weak)
+ (const :tag "Strong" :format "%t" t)))
+ ;; No other window.
+ (cons
+ :format "%v"
+ (const :format "" no-other-window)
+ (choice
+ :help-echo "Whether `other-window' shall ignore the window."
+ :format "%[No other window%] %v\n" :size 15
+ (const :tag "Off" :format "%t" nil)
+ (const :tag "Ignore" :format "%t" t)))
+ ;; Overriding.
+ (cons
+ :format "%v\n"
(const :format "" override)
- (const :format "" t)))))
+ (choice
+ :help-echo "Override application supplied specifiers."
+ :format "%[Override%] %v"
+ (const :tag "Off" :format "%t" nil)
+ (const :tag "Override" :format "%t" t))))))
:group 'windows
:group 'frames)
-;; Minibuffer-only frames should be documented better. They really
-;; deserve a separate section in the manual. Also
-;; `last-nonminibuffer-frame' is nowhere documented in the manual.
-(defun display-buffer-frame (&optional frame)
- "Return FRAME if it is live and not a minibuffer-only frame.
-Return the value of `last-nonminibuffer-frame' otherwise."
- (setq frame (normalize-live-frame frame))
- (if (and (frame-live-p frame)
- ;; A not very nice way to get that information.
- (not (window-minibuffer-p (frame-root-window frame))))
- frame
- (last-nonminibuffer-frame)))
-
-(defconst display-buffer-locations '(same-window same-frame other-frame)
- "Buffer display location specifiers.")
-
-(defconst display-buffer-default-specifiers
- '(same-frame
- (reuse-buffer-window . nil)
- (new-window (largest . nil) (lru . nil))
- (min-height . 24) (min-width . 60)
- other-frame
- (reuse-buffer-window . visible)
- (popup-frame-alist
- (height . 24) (width . 80) (unsplittable . t)))
- "The default buffer display specifiers.
-The value specified here is used when no other specifiers have
-been specified by the user or the application. Consult the
-documentation of `display-buffer-names' for a description of
-buffer display specifiers.")
-
-(defconst display-buffer-other-window-specifiers
- '(same-frame (reuse-buffer-window . nil)
- other-frame (reuse-buffer-window . visible)
- (not-this-window . t))
- "Specifiers for displaying a buffer in any but the selected window.
-These are the specifiers applied when `display-buffer' is called
-with the second argument equal t.")
-
-(defconst display-buffer-same-frame-specifiers
- '(same-frame (reuse-buffer-window . nil))
- "Specifiers for displaying a buffer in a window on the selected frame.")
-
-(defconst display-buffer-other-window-same-frame-specifiers
- '(same-frame (reuse-buffer-window . nil) (not-this-window . t))
- "Specifiers for displaying a buffer in another window on the selected frame.")
-
-(defconst display-buffer-other-frame-specifiers
- '(other-frame (reuse-buffer-window . visible)
- (not-this-window . t) (not-this-frame . t))
- "Specifiers for displaying a buffer in any but the selected frame.
-These should avoid the selected window and the selected frame.")
-
-(defun display-buffer-normalize-specifiers-1 (specifiers)
- "Subroutine of `display-buffer-normalize-specifiers'.
-SPECIFIERS is the homonymous argument for `display-buffer'."
- (cond
- ((memq specifiers '(t other-window))
- ;; Historically t means "other window". 'other-window is
- ;; occasionally used with the same meaning.
- display-buffer-other-window-specifiers)
- ((or (memq specifiers display-buffer-locations)
- (functionp specifiers))
- ;; A single specifier à la 'same-window - make it a list.
- (list specifiers))
- ((or (not specifiers) (not (listp specifiers)))
- ;; Not a valid specifier.
- nil)
- (t specifiers)))
-
-(defun display-buffer-normalize-specifiers (buffer-name specifiers)
- "Return normalized specifiers for displaying a buffer called BUFFER-NAME.
-BUFFER-NAME must be a string specifying a valid buffer name.
-SPECIFIERS is the homonymous argument of `display-buffer'.
-
-The method for displaying the buffer specified by BUFFER-NAME is
-established by appending the following five lists of specifiers:
-
-- The specifiers in `display-buffer-names' whose name component
- contains BUFFER-NAME and whose 'override component is set.
+(defcustom display-buffer-function nil
+ "If non-nil, function to call to display a buffer.
+`display-buffer' calls this function with two arguments, the
+buffer to display and a list of buffer display specifiers, see
+`display-buffer-alist'.
-- The specifiers in `display-buffer-regexps' whose name component
- matches BUFFER-NAME and whose 'override component is set.
+The function is supposed to choose or create a window, display
+the specified buffer in it, and return the window. It is also
+responsible for giving the variable `display-buffer-window' and
+the `quit-restore' parameter of the window used a meaningful
+value.
-- SPECIFIERS.
+The function specified here overrides all specifiers of the
+variable `display-buffer-alist' any specifiers passed to
+`display-buffer'.
-- The list of specifiers in `display-buffer-names' whose name
- component contains BUFFER-NAME and whose 'override component is
- not set.
-
-- The list of specifiers in `display-buffer-regexps' whose name
- component matches BUFFER-NAME and whose 'override component is
- not set.
-
-The return value is always a list. The first element of that
-list is not necessarily a location specifier."
- (let (names-over regexps-over names-no regexps-no)
- (dolist (entry display-buffer-names)
- (when (and (listp entry) (member buffer-name (car entry)))
- (let ((specifier (cdr entry)))
- (if (assq 'override specifier)
- (setq names-over
- (if names-over
- (append names-over specifier)
- specifier))
- (setq names-no
- (if names-no
- (append names-no specifier)
- specifier))))))
- (dolist (entry display-buffer-regexps)
- (when (and (listp entry)
- (catch 'match
- (dolist (regexp (car entry))
- (when (and (stringp regexp)
- (string-match-p regexp buffer-name))
- (throw 'match t)))))
- (let ((specifier (cdr entry)))
- (if (assq 'override specifier)
- (setq regexps-over
- (if regexps-over
- (append regexps-over specifier)
- specifier))
- (setq regexps-no
- (if regexps-no
- (append regexps-no specifier)
- specifier))))))
- (append
- names-over regexps-over
- (display-buffer-normalize-specifiers-1 specifiers)
- names-no regexps-no
- ;; Append the default specifiers.
- display-buffer-default-specifiers)))
+If you call `display-buffer' within the body of the function,
+bind the value of `display-buffer-function' to nil around that
+call to avoid that the function recursively calls itself."
+ :type '(choice
+ (const nil)
+ (function :tag "Function"))
+ :group 'display-buffer)
;; The following is a global variable which is used externally (by
;; help.el) to (1) know which window was used for displaying a buffer
assign the value of this variable. If the location specifier is
a function, that function becomes responsible for assigning a
meaningful value to this variable. See the functions
-`display-buffer-in-lru-buffer-window',
-`display-buffer-in-lru-window', `display-buffer-in-new-window'
-and `display-buffer-in-new-frame' for how this is done.")
+`display-buffer-reuse-window', `display-buffer-pop-up-window' and
+`display-buffer-pop-up-frame' for how this can be done.")
(defun display-buffer-even-sizes (window specifiers)
"Even sizes of WINDOW and selected window according to SPECIFIERS.
SPECIFIERS must be a list of buffer display specifiers, see the
-documentation of `display-buffer-names' for a description.
+documentation of `display-buffer-alist' for a description.
Sizes are evened out if and only if WINDOW and the selected
window appear next to each other and the selected window is
window (/ (- (window-total-width) (window-total-width window))
2) t))))))
-(defun display-buffer-adjust-height (window specifiers)
+(defun display-buffer-set-height (window specifiers)
"Adjust height of WINDOW according to SPECIFIERS.
SPECIFIERS must be a list of buffer display specifiers, see the
-documentation of `display-buffer-names' for a description."
- (let ((adjust-height (cdr (assq 'adjust-height specifiers))))
+documentation of `display-buffer-alist' for a description."
+ (let ((set-height (cdr (assq 'pop-up-window-set-height specifiers))))
(cond
- ((numberp adjust-height)
- (let* ((height (if (integerp adjust-height)
- adjust-height
- (* (window-total-size (frame-root-window window))
- adjust-height)))
+ ((numberp set-height)
+ (let* ((height (if (integerp set-height)
+ set-height
+ (round
+ (* (window-total-size (frame-root-window window))
+ set-height))))
(delta (- height (window-total-size window))))
- (when (and (window-resizable-p window delta)
+ (when (and (window-resizable-p window delta nil 'safe)
(window-iso-combined-p window))
- (resize-window window delta))))
- ((functionp adjust-height)
- (ignore-errors (funcall adjust-height window))))))
+ (resize-window window delta nil 'safe))))
+ ((functionp set-height)
+ (ignore-errors (funcall set-height window))))))
-(defun display-buffer-adjust-width (window specifiers)
+(defun display-buffer-set-width (window specifiers)
"Adjust width of WINDOW according to SPECIFIERS.
SPECIFIERS must be a list of buffer display specifiers, see the
-documentation of `display-buffer-names' for a description."
- (let ((adjust-width (cdr (assq 'adjust-width specifiers))))
+documentation of `display-buffer-alist' for a description."
+ (let ((set-width (cdr (assq 'pop-up-window-set-width specifiers))))
(cond
- ((numberp adjust-width)
- (let* ((width (if (integerp adjust-width)
- adjust-width
- (* (window-total-size (frame-root-window window) t)
- adjust-width)))
+ ((numberp set-width)
+ (let* ((width (if (integerp set-width)
+ set-width
+ (round
+ (* (window-total-size (frame-root-window window) t)
+ set-width))))
(delta (- width (window-total-size window t))))
- (when (and (window-resizable-p window delta t)
+ (when (and (window-resizable-p window delta t 'safe)
(window-iso-combined-p window t))
- (resize-window window delta t))))
- ((functionp adjust-width)
- (ignore-errors (funcall adjust-width window))))))
-
+ (resize-window window delta t 'safe))))
+ ((functionp set-width)
+ (ignore-errors (funcall set-width window))))))
+
+;; We have to work around the deficiency that the command loop does not
+;; preserve the selected window when it is on a frame that hasn't been
+;; raised or given input focus. So we have to (1) select the window
+;; used for displaying a buffer and (2) raise its frame if necessary,
+;; thus defeating one primary principle of `display-buffer' namely to
+;; _not_ select the window chosen for displaying the buffer :-(
(defun display-buffer-select-window (window &optional norecord)
- "Select WINDOW and make sure it's frame is risen."
+ "Select WINDOW and raise its frame if necessary."
(let ((old-frame (selected-frame))
(new-frame (window-frame window)))
+ ;; Select WINDOW _before_ raising the frame to assure that the mouse
+ ;; cursor moves into the correct window.
(select-window window norecord)
(unless (eq old-frame new-frame)
(select-frame-set-input-focus new-frame))))
(defun display-buffer-in-window (buffer window specifiers)
- "Display BUFFER in WINDOW and raise its frame.
+ "Display BUFFER in WINDOW and raise its frame if needed.
WINDOW must be a live window and defaults to the selected one.
Return WINDOW.
SPECIFIERS must be a list of buffer display specifiers, see the
-documentation of `display-buffer-names' for a description."
+documentation of `display-buffer-alist' for a description."
(setq buffer (normalize-live-buffer buffer))
(setq window (normalize-live-window window))
(let* ((old-frame (selected-frame))
(new-frame (window-frame window))
- (dedicated (cdr (assq 'dedicated specifiers))))
+ (dedicated (cdr (assq 'dedicated specifiers)))
+ (no-other-window (cdr (assq 'no-other-window specifiers))))
;; Show BUFFER in WINDOW.
(set-window-dedicated-p window nil)
(set-window-buffer window buffer)
(when dedicated
(set-window-dedicated-p window dedicated))
- ;; Raise the frame if it's new (no use to check all sorts of things
- ;; as we did earlier). I'm not sure what gets broken by this but at
- ;; least the case where the buffer is already shown on another frame
- ;; should be handled correctly this time (Emacs 23 apparently always
- ;; raises the frame and selects the window).
-
- ;; The "do not raise new frame" case is too difficult to handle (see
- ;; also the problems with the old `display-buffer-other-frame').
+ (when no-other-window
+ (set-window-parameter window 'no-other-window t))
(unless (eq old-frame new-frame)
- ;; Maybe we should call this with NORECORD non-nil.
(display-buffer-select-window window))
;; Return window.
window))
-(defun display-buffer-in-lru-buffer-window (buffer frames &optional specifiers)
- "Display BUFFER in least recently used window showing BUFFER.
-FRAMES specifies the set of frames to consider. Return the
-window displaying BUFFER if done, nil otherwise.
-
-Optional argument SPECIFIERS must be a list of buffer display
-specifiers, see the documentation of `display-buffer-names' for a
-description."
- ;; Try to return the least recently used window showing BUFFER
- ;; avoiding the selected window. `get-buffer-window-list' starts with
- ;; the first window on the selected frame showing BUFFER (provided
- ;; there is such a window).
- (let ((windows (get-buffer-window-list buffer 'nomini frames))
- (not-this-window
- (let ((spec-cdr (cdr (assq 'not-this-window specifiers))))
- (cond
- ((eq spec-cdr t)
- (selected-window))
- (spec-cdr))))
- (not-this-frame
- (let ((spec-cdr (cdr (assq 'not-this-frame specifiers))))
- (cond
- ((eq spec-cdr t)
- (selected-frame))
- (spec-cdr))))
- best-window best-time time)
- (dolist (window windows)
- ;; Take care of `not-this-window' and `not-this-frame' specifiers.
- (unless (or (eq window not-this-window)
- (eq (window-frame window) not-this-frame)
- (window-minibuffer-p window))
- (setq time (window-use-time window))
- (when (or (not best-window) (< time best-time))
- (setq best-window window)
- (setq best-time time))))
+(defun display-buffer-reuse-window (buffer method &optional specifiers)
+ "Display BUFFER in an existing window.
+METHOD must be a list in the form of the cdr of a `reuse-window'
+buffer display specifier, see `display-buffer-alist' for an
+explanation. The first element must specifiy the window to use,
+and can be either nil, `same', `other', or a live window. The
+second element must specify the window's buffer and can be either
+nil, `same', `other', or a live buffer. The third element is the
+frame to use - either nil, 0, `visible', `other', t, or a live
+frame.
+
+Optional argument SPECIFIERS must be a list of valid display
+specifiers. Return the window chosen to display BUFFER, nil if
+none was found."
+ (let* ((method-window (nth 0 method))
+ (method-buffer (nth 1 method))
+ (method-frame (nth 2 method))
+ (reuse-dedicated (assq 'reuse-window-dedicated specifiers))
+ windows other-frame dedicated time best-window best-time)
+ (when (eq method-frame 'other)
+ ;; `other' is not handled by `window-list-1'.
+ (setq other-frame t)
+ (setq method-frame t))
+ (dolist (window (window-list-1 nil 'nomini method-frame))
+ (let ((window-buffer (window-buffer window)))
+ (when (and (not (window-minibuffer-p window))
+ ;; Don't reuse a side window.
+ (or (not (eq (window-parameter window 'window-side) 'side))
+ (eq window-buffer buffer))
+ (or (not method-window)
+ (and (eq method-window 'same)
+ (eq window (selected-window)))
+ (and (eq method-window 'other)
+ (not (eq window (selected-window))))
+ ;; Special case for applications that specifiy
+ ;; the window explicitly.
+ (eq method-window window))
+ (or (not method-buffer)
+ (and (eq method-buffer 'same)
+ (eq window-buffer buffer))
+ (and (eq method-buffer 'other)
+ (not (eq window-buffer buffer)))
+ ;; Special case for applications that specifiy
+ ;; the window's buffer explicitly.
+ (eq method-buffer window-buffer))
+ (or (not other-frame)
+ (not (eq (window-frame window) (selected-frame))))
+ ;; Handle dedicatedness.
+ (or (eq window-buffer buffer)
+ ;; The window does not show the same buffer.
+ (not (setq dedicated (window-dedicated-p window)))
+ ;; If the window is weakly dedicated to its
+ ;; buffer, reuse-dedicated must be non-nil.
+ (and (not (eq dedicated t)) reuse-dedicated)
+ ;; If the window is strongly dedicated to its
+ ;; buffer, reuse-dedicated must be t.
+ (eq reuse-dedicated t)))
+ (setq windows (cons window windows)))))
+
+ (if (eq method-buffer 'same)
+ ;; When reusing a window on the same buffer use the lru one.
+ (dolist (window windows)
+ (setq time (window-use-time window))
+ (when (or (not best-window) (< time best-time))
+ (setq best-window window)
+ (setq best-time time)))
+ ;; Otherwise, sort windows according to their use-time.
+ (setq windows
+ (sort windows
+ '(lambda (window-1 window-2)
+ (<= (window-use-time window-1)
+ (window-use-time window-2)))))
+ (setq best-window
+ ;; Try to get a full-width window (this is silly and can
+ ;; get us to another frame but let's ignore these issues
+ ;; for the moment).
+ (catch 'found
+ (dolist (window windows)
+ (when (window-full-width-p window)
+ (throw 'found window)))
+ ;; If there's no full-width window return the lru window.
+ (car windows))))
(when best-window
(display-buffer-even-sizes best-window specifiers)
;; Never change the quit-restore parameter of a window here.
- (setq display-buffer-window
- (cons best-window 'reuse-buffer-window))
+ (if (eq (window-buffer best-window) buffer)
+ (setq display-buffer-window
+ (cons best-window 'reuse-buffer-window))
+ (setq display-buffer-window
+ (cons best-window 'reuse-other-window))
+ (unless (window-parameter best-window 'quit-restore)
+ ;; Don't overwrite an existing quit-restore entry.
+ (set-window-parameter
+ best-window 'quit-restore
+ (list (window-buffer best-window) (window-start best-window)
+ (window-point best-window) buffer
+ (window-total-size best-window) (selected-window)))))
+
(display-buffer-in-window buffer best-window specifiers))))
-(defun display-buffer-in-lru-window (buffer frames &optional specifiers)
- "Display BUFFER in least recently used window.
-FRAMES specifies the set of frames to consider. Return the
-window displaying BUFFER if done, nil otherwise.
+(defconst display-buffer-split-specifiers '(largest lru selected root left top right bottom)
+ "List of symbols identifying window that shall be split.")
-Optional argument SPECIFIERS must be a list of buffer display
-specifiers, see the documentation of `display-buffer-names' for a
-description."
- (let ((window
- (catch 'found
- (let ((windows
- (window-list-1
- (frame-first-window (display-buffer-frame)) 'nomini frames))
- (not-this-window
- (let ((spec-cdr (cdr (assq 'not-this-window specifiers))))
- (cond
- ((eq spec-cdr t)
- (selected-window))
- (spec-cdr))))
- (not-this-frame
- (let ((spec-cdr (cdr (assq 'not-this-frame specifiers))))
- (cond
- ((eq spec-cdr t)
- (selected-frame))
- (spec-cdr))))
- ;; lru-windows is a list of (window . use-time) pairs.
- lru-windows)
- (dolist (window windows)
- ;; Take care of `not-this-window' and `not-this-frame'
- ;; specifiers.
- (unless (or (eq window not-this-window)
- (eq (window-frame window) not-this-frame)
- (window-minibuffer-p window)
- (window-dedicated-p window))
- (setq lru-windows (cons (cons window (window-use-time window))
- lru-windows))))
- ;; Sort pairs according to their use-time.
- (setq lru-windows
- (sort lru-windows '(lambda (pair1 pair2)
- (<= (cdr pair1) (cdr pair2)))))
- ;; Try to get a full-width window.
- (dolist (pair lru-windows)
- (when (window-full-width-p (car pair))
- (throw 'found (car pair))))
-
- ;; If there's no full-width window return the lru window.
- (caar lru-windows)))))
- (when window
- (display-buffer-even-sizes window specifiers)
- (unless (window-parameter window 'quit-restore)
- ;; Don't overwrite an existing quit-restore entry.
- (set-window-parameter
- window 'quit-restore
- (list (window-buffer window) (window-start window)
- (window-point window) buffer
- (window-total-size window) (selected-window))))
- (setq display-buffer-window
- (cons window 'reuse-other-window))
- (display-buffer-in-window buffer window specifiers))))
+(defconst display-buffer-side-specifiers '(below right above left nil)
+ "List of symbols identifying side of split-off window.")
(defun display-buffer-split-window-1 (window side min-size)
"Subroutine of `display-buffer-split-window'."
Optional argument SIDE must be a side specifier \(one of the
symbols below, right, above, left, or nil). SPECIFIERS must be a
list of buffer display specifiers, see the documentation of
-`display-buffer-names' for a description.
+`display-buffer-alist' for a description.
Return the new window, nil if it could not be created."
- (let ((min-height (cdr (assq 'min-height specifiers)))
- (min-width (cdr (assq 'min-width specifiers)))
+ (let ((min-height (cdr (assq 'pop-up-window-min-height specifiers)))
+ (min-width (cdr (assq 'pop-up-window-min-width specifiers)))
size)
;; Normalize min-height and min-width, we might need both.
(setq min-height
(display-buffer-split-window-1
window (or side 'below) window-min-height)))))
-(defconst display-buffer-split-specifiers '(largest lru selected root first)
- "Buffer display window split specifiers.")
-
-(defconst display-buffer-side-specifiers '(below right above left nil)
- "Buffer display window side specifiers.")
-
-(defun display-buffer-in-new-window (buffer specifiers)
+(defun display-buffer-split-atom-window (window &optional side nest specifiers)
+ "Make WINDOW part of an atomic window."
+ (let ((ignore-window-parameters t)
+ (window-splits 'nest)
+ (selected-window (selected-window))
+ root new new-parent)
+
+ ;; We are in an atomic window.
+ (when (and (window-parameter window 'window-atom) (not nest))
+ ;; Split the root window.
+ (setq window (window-atom-root window)))
+
+ (when (setq new (display-buffer-split-window window side specifiers))
+ (setq new-parent (window-parent window))
+ ;; WINDOW is or becomes atomic.
+ (unless (window-parameter window 'window-atom)
+ (walk-window-subtree
+ (lambda (window)
+ (set-window-parameter window 'window-atom t))
+ window t))
+ ;; New window and any new parent get their window-atom parameter
+ ;; set too.
+ (set-window-parameter new 'window-atom t)
+ (set-window-parameter new-parent 'window-atom t)
+ new)))
+
+(defun display-buffer-pop-up-window (buffer methods &optional specifiers)
"Display BUFFER in a new window.
-Return the window displaying BUFFER if creating the new window
-was successful, nil otherwise.
+Return the window displaying BUFFER, nil if popping up the window
+failed. METHODS must be a list of window/side tuples like those
+forming the cdr of the `pop-up-window' buffer display specifier.
+As a special case, the car of such a tuple can be also a live
+window.
-SPECIFIERS must be a list of buffer display specifiers, see the
-documentation of `display-buffer-names' for a description."
+Optional argument SPECIFIERS must be a list of buffer display
+specifiers, see the doc-string of `display-buffer-alist' for a
+description."
(let* ((frame (display-buffer-frame))
(selected-window (frame-selected-window frame))
- window window-specifier side-specifier)
- (unless (or (and (cdr (assq 'unsplittable (frame-parameters frame)))
- ;; Don't split an unsplittable frame unless
- ;; SPECIFIERS allow it.
- (not (cdr (assq 'split-unsplittable-frame specifiers))))
- (let ((spec-cdr (cdr (assq 'not-this-frame specifiers))))
- ;; Don't split a window on the selected frame if
- ;; `not-this-frame' disallows it.
- (or (eq spec-cdr t) (eq spec-cdr (selected-frame)))))
+ window side atomic)
+ (unless (and (cdr (assq 'unsplittable (frame-parameters frame)))
+ ;; Don't split an unsplittable frame unless
+ ;; SPECIFIERS allow it.
+ (not (cdr (assq 'split-unsplittable-frame specifiers))))
(catch 'done
- (dolist (specifier specifiers)
- (when (and (consp specifier) (eq (car specifier) 'new-window))
- (dolist (window-side-specifier (cdr specifier))
- (setq window-specifier (car window-side-specifier))
- (setq side-specifier (cdr window-side-specifier))
- (setq window
- (cond
- ((eq window-specifier 'largest)
- (get-largest-window frame t))
- ((eq window-specifier 'lru)
- (get-lru-window frame t))
- ((eq window-specifier 'selected)
- (frame-selected-window frame))
- ((eq window-specifier 'root)
- (frame-root-window frame))
- ((eq window-specifier 'first)
- (frame-first-window frame))))
- (and window (eq (window-frame window) frame)
- (not (window-minibuffer-p window))
- (setq window
- (cond
- ((memq
- side-specifier display-buffer-side-specifiers)
- (display-buffer-split-window
- window side-specifier specifiers))
- ((functionp side-specifier)
- (ignore-errors
- (funcall side-specifier window (cdr specifiers))))))
- (throw 'done window))))))
+ (dolist (method methods)
+ (setq window (car method))
+ (setq side (cdr method))
+ (and (setq window
+ (cond
+ ((eq window 'largest)
+ (get-largest-window frame t))
+ ((eq window 'lru)
+ (get-lru-window frame t))
+ ((eq window 'selected)
+ (frame-selected-window frame))
+ ((eq window 'root)
+ ;; If there are side windows, split the main
+ ;; window else the frame root window.
+ (or (window-with-parameter 'window-side 'none nil t)
+ (frame-root-window frame)))
+ ((memq window window-sides)
+ ;; This should gets us the "root" side
+ ;; window if there exists more than one.
+ (window-with-parameter 'window-side window nil t))
+ ((windowp window)
+ ;; A window, directly specified.
+ window)))
+ ;; The window must be on the selected frame,
+ (eq (window-frame window) frame)
+ ;; and must be neither a minibuffer window,
+ (not (window-minibuffer-p window))
+ ;; nor a side window.
+ (not (eq (window-parameter window 'window-side) 'side))
+ (setq window
+ (cond
+ ((memq side display-buffer-side-specifiers)
+ (if (and (window-buffer window)
+ (setq atomic (cdr (assq 'atomic specifiers))))
+ (display-buffer-split-atom-window
+ window side (eq atomic 'nest) specifiers)
+ (display-buffer-split-window window side specifiers)))
+ ((functionp side)
+ (ignore-errors
+ (funcall side window specifiers)))))
+ (throw 'done window))))
+
(when window
;; Adjust sizes if asked for.
- (display-buffer-adjust-height window specifiers)
- (display-buffer-adjust-width window specifiers)
+ (display-buffer-set-height window specifiers)
+ (display-buffer-set-width window specifiers)
(set-window-parameter
window 'quit-restore (list 'new-window buffer selected-window))
(setq display-buffer-window (cons window 'new-window))
(display-buffer-in-window buffer window specifiers)))))
-(defun display-buffer-in-new-frame (buffer specifiers)
+(defun display-buffer-pop-up-frame (buffer &optional graphic-only specifiers)
"Make a new frame for displaying BUFFER.
Return the window displaying BUFFER if creating the new frame was
-successful, nil otherwise.
+successful, nil otherwise. Optional argument GRAPHIC-ONLY
+non-nil means to make a new frame on graphic displays only.
SPECIFIERS must be a list of buffer display specifiers, see the
-documentation of `display-buffer-names' for a description."
- (unless (and (cdr (assq 'graphic-only specifiers))
- (not (display-graphic-p)))
+documentation of `display-buffer-alist' for a description."
+ (unless (and graphic-only (not (display-graphic-p)))
(let* ((selected-window (selected-window))
(function (or (cdr (assq 'popup-frame-function specifiers))
'make-frame))
(setq display-buffer-window (cons window 'new-frame))
(display-buffer-in-window buffer window specifiers))))))
+(defun display-buffer-pop-up-side-window (buffer side slot &optional specifiers)
+ "Display BUFFER in a new window on SIDE of the selected frame.
+SLOT specifies the slot to use. SPECIFIERS must be a list of
+buffer display specifiers.
+
+Return the window displaying BUFFER, nil if popping up the window
+failed."
+ (let* ((root (frame-root-window))
+ (main (window-with-parameter 'window-side 'none nil t))
+ (left-or-right (memq side '(left right)))
+ (main-or-root
+ (if (and main
+ (or (and left-or-right (not window-sides-vertical))
+ (and (not left-or-right) window-sides-vertical)))
+ main
+ root))
+ (selected-window (selected-window))
+ (on-side (cond
+ ((eq side 'top) 'above)
+ ((eq side 'bottom) 'below)
+ (t side)))
+ (window
+ (display-buffer-split-window main-or-root on-side specifiers))
+ fun)
+ (when window
+ (unless main
+ (walk-window-subtree
+ (lambda (window)
+ ;; Make all main-or-root subwindows main windows.
+ (set-window-parameter window 'window-side 'none))
+ main-or-root t))
+ ;; Make sure that parent's window-side is nil.
+ (set-window-parameter (window-parent window) 'window-side nil)
+ ;; Initialize side.
+ (set-window-parameter window 'window-side side)
+ ;; Adjust sizes if asked for.
+ (display-buffer-set-height window specifiers)
+ (display-buffer-set-width window specifiers)
+ ;; Set window parameters.
+ (set-window-parameter
+ window 'quit-restore (list 'new-window buffer selected-window))
+ (setq display-buffer-window (cons window 'new-window))
+ (set-window-parameter window 'window-slot slot)
+ (display-buffer-in-window buffer window specifiers))))
+
+(defun display-buffer-in-side-window (buffer side &optional slot specifiers)
+ "Display BUFFER in a window on SIDE of the selected frame.
+SLOT, if non-nil, specifies the window slot where to display the
+BUFFER. SLOT zero or nil means use the central slot on SIDE.
+SLOT negative means use a slot preceding the central window.
+SLOT positive means use a slot following the central window.
+
+SPECIFIERS must be a list of buffer display specifiers."
+ (unless (memq side window-sides)
+ (error "Invalid side %s specified" side))
+ (let* ((major (window-with-parameter 'window-side side nil t))
+ ;; `major' is the major window on SIDE, `windows' the life
+ ;; windows on SIDE.
+ (windows (when major (windows-with-parameter 'window-side side)))
+ (slots (when major (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))
+ (selected-window (selected-window))
+ window this-window this-slot prev-window next-window
+ best-window best-slot abs-slot)
+
+ (unless (numberp slot)
+ (setq slot 0))
+ (if (not windows)
+ ;; No suitable side window exists, make one.
+ (display-buffer-pop-up-side-window buffer side slot specifiers)
+ ;; Scan windows on SIDE.
+ (catch 'found
+ (dolist (window windows)
+ (setq this-slot (window-parameter window 'window-slot))
+ (cond
+ ((not (numberp this-slot)))
+ ((and (= this-slot slot)
+ ;; Dedicatedness check.
+ (or (not (window-dedicated-p window))
+ (assq 'reuse-window-dedicated specifiers)))
+ ;; Window with matching SLOT, use it.
+ (setq this-window window)
+ (throw 'found t))
+ (t
+ (setq abs-slot (abs (- (abs slot) (abs this-slot))))
+ (unless (and best-slot (<= best-slot abs-slot))
+ (setq best-window window)
+ (setq best-slot abs-slot))
+ (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.
+ (prog1
+ (setq window this-window)
+ (if (eq (window-buffer window) buffer)
+ (setq display-buffer-window
+ (cons window 'reuse-buffer-window))
+ (setq display-buffer-window
+ (cons window 'reuse-other-window))
+ (unless (window-parameter window 'quit-restore)
+ ;; Don't overwrite an existing quit-restore entry.
+ (set-window-parameter
+ window 'quit-restore
+ (list (window-buffer window) (window-start window)
+ (window-point window) buffer
+ (window-total-size window) (selected-window)))))))
+ (and (or (not max-slots) (< slots max-slots))
+ (or (and next-window
+ ;; Make new window before next-window.
+ (let ((next-side
+ (if (memq side '(left right)) 'above 'left)))
+ (setq window (display-buffer-split-window
+ next-window next-side specifiers))))
+ (and prev-window
+ ;; Make new window after prev-window.
+ (let ((prev-side
+ (if (memq side '(left right)) 'below 'right)))
+ (setq window (display-buffer-split-window
+ prev-window prev-side specifiers)))))
+ (progn
+ (display-buffer-set-height window specifiers)
+ (display-buffer-set-width window specifiers)
+ (set-window-parameter
+ window 'quit-restore
+ (list 'new-window buffer selected-window))
+ (setq display-buffer-window (cons window 'new-window))
+ window))
+ (and best-window
+ (setq window best-window)
+ ;; Reuse best window (the window nearest to SLOT).
+ (if (eq (window-buffer window) buffer)
+ (setq display-buffer-window
+ (cons window 'reuse-buffer-window))
+ (setq display-buffer-window
+ (cons window 'reuse-other-window))
+
+ (unless (window-parameter window 'quit-restore)
+ ;; Don't overwrite an existing quit-restore entry.
+ (set-window-parameter
+ window 'quit-restore
+ (list (window-buffer window) (window-start window)
+ (window-point window) buffer
+ (window-total-size window) (selected-window)))))
+ window))
+
+ (when window
+ (unless (window-parameter window 'window-slot)
+ ;; Don't change exisiting slot value.
+ (set-window-parameter window 'window-slot slot))
+ (display-buffer-in-window buffer window specifiers)))))
+
(defun normalize-buffer-to-display (buffer-or-name)
"Normalize BUFFER-OR-NAME argument for buffer display functions.
If BUFFER-OR-NAME is nil, return the curent buffer. Else, if a
buffer))
(current-buffer)))
-(defun display-buffer (&optional buffer-or-name specifiers ignore)
+(defun display-buffer-normalize-specifiers-1 (specifiers)
+ "Subroutine of `display-buffer-normalize-specifiers'."
+ (let (normalized)
+ (cond
+ ((listp specifiers)
+ (dolist (specifier specifiers)
+ (cond
+ ((consp specifier)
+ (setq normalized (cons specifier normalized)))
+ ((symbolp specifier)
+ ;; Might be a macro specifier, try to expand it (the cdr is a
+ ;; list and we have to reverse it later, so do it one at a
+ ;; time).
+ (let ((entry (assq specifier display-buffer-macro-specifiers)))
+ (dolist (item (cdr entry))
+ (setq normalized (cons item normalized)))))))
+ ;; Reverse list.
+ (setq normalized (nreverse normalized)))
+ ;; The two cases below must come from the SPECIFIERS argument of
+ ;; `display-buffer'.
+ ((eq specifiers 't)
+ ;; Historically t means "other window". Eventually we should get
+ ;; rid of this.
+ (setq normalized
+ (cdr (assq 'other-window display-buffer-macro-specifiers))
+ normalized))
+ ((symbolp specifiers)
+ ;; We allow scalar specifiers in calls of `display-buffer'.
+ (let ((entry (assq specifiers display-buffer-macro-specifiers)))
+ (when entry (setq normalized (cdr entry))))))
+
+ normalized))
+
+(defun display-buffer-normalize-specifiers (buffer-name specifiers label)
+ "Return normalized specifiers for a buffer matching BUFFER-NAME or LABEL.
+BUFFER-NAME must be a string specifying a valid buffer name.
+SPECIFIERS and LABEL are the homonymous arguments of
+`display-buffer'.
+
+The method for displaying the buffer specified by BUFFER-NAME or
+LABEL is established by appending the following four lists of
+specifiers:
+
+- The specifiers in `display-buffer-alist' whose buffer
+ identifier matches BUFFER-NAME or LABEL and whose 'override
+ component is set.
+
+- SPECIFIERS.
+
+- The specifiers in `display-buffer-alist' whose buffer
+ identifier matches BUFFER-NAME or LABEL and whose 'override
+ component is not set.
+
+- `display-buffer-default-specifiers'."
+ (let (list-1 list-2)
+ (dolist (entry display-buffer-alist)
+ (when (and (listp entry)
+ (catch 'match
+ (dolist (id (car entry))
+ (when (consp id)
+ (let ((type (car id))
+ (value (cdr id)))
+ (when (or (and (eq type 'name) (stringp value)
+ (equal value buffer-name))
+ (and (eq type 'regexp) (stringp value)
+ (string-match-p value buffer-name))
+ (and (eq type 'label) (eq value label)))
+ (throw 'match t)))))))
+ (let* ((raw (cdr entry))
+ (normalized (display-buffer-normalize-specifiers-1 raw)))
+ (if (assq 'override raw)
+ (setq list-1
+ (if list-1
+ (append list-1 normalized)
+ normalized))
+ (setq list-2
+ (if list-2
+ (append list-2 normalized)
+ normalized))))))
+
+ (append
+ list-1
+ (display-buffer-normalize-specifiers-1 specifiers)
+ list-2
+ ;; Append the default specifiers.
+ display-buffer-default-specifiers)))
+
+;; Minibuffer-only frames should be documented better. They really
+;; deserve a separate section in the manual. Also
+;; `last-nonminibuffer-frame' is nowhere documented in the manual.
+(defun display-buffer-frame (&optional frame)
+ "Return FRAME if it is live and not a minibuffer-only frame.
+Return the value of `last-nonminibuffer-frame' otherwise."
+ (setq frame (normalize-live-frame frame))
+ (if (and (frame-live-p frame)
+ ;; A not very nice way to get that information.
+ (not (window-minibuffer-p (frame-root-window frame))))
+ frame
+ (last-nonminibuffer-frame)))
+
+(defun display-buffer (&optional buffer-or-name specifiers label)
"Make the buffer specified by BUFFER-OR-NAME appear in some window.
Optional argument BUFFER-OR-NAME may be a buffer, a string \(a
buffer name), or nil. If BUFFER-OR-NAME is a string not naming
Interactively, prompt for the buffer name using the minibuffer.
Return the window chosen to display the buffer or nil if no such
-window is found. Do not change the selected window unless a new
-frame is created.
+window is found. Do not change the selected window unless the
+buffer is shown on a different frame than the selected one.
Optional argument SPECIFIERS must be a list of buffer display
-specifiers, see the documentation of `display-buffer-names' for a
+specifiers, see the documentation of `display-buffer-alist' for a
description.
For convenience, SPECIFIERS may also consist of a single buffer
display location specifier or t, where the latter means to
display the buffer in any but the selected window. If SPECIFIERS
-is nil or omitted, this means to exclusively use the values
-provided by `display-buffer-names' and `display-buffer-regexps'.
-If these values are nil too, all specifiers are provided by the
-constant `display-buffer-default-specifiers'.
-
-In addition, the `not-this-window' specifier allows as cdr to
-specify an arbitrary window in order to not use that window for
-displaying the buffer. The `not-this-frame' specifier allows as
-cdr to also specify an arbitrary frame in order to not use that
-frame for displaying the buffer.
-
-The optional third argument IGNORE is ignored.
+is nil or omitted, this means to exclusively use the specifiers
+provided by `display-buffer-alist'. If the value of the latter
+is nil too, all specifiers are provided by the constant
+`display-buffer-default-specifiers'.
+
+As a special case, the `reuse-window' specifier allows to specify
+as second element an arbitrary window, as third element an
+arbitrary buffer, and as fourth element an arbitrary frame. As
+first element of a window/side pair of the `pop-up-window'
+specifier you can specifiy an arbitrary window.
+
+The optional third argument LABEL, if non-nil, must be a symbol
+specifiying the buffer display label. Applications should set
+this when the buffer shall be displayed in some special way but
+BUFFER-OR-NAME does not identify the buffer as special. Typical
+buffers that fit into this category are those whose names are
+derived from the name of the file they are visiting. A user can
+override SPECIFIERS by adding an entry to `display-buffer-alist'
+whose car contains LABEL and whose cdr specifies the preferred
+alternative display method.
The method to display the buffer is derived by combining the
-values of `display-buffer-names', `display-buffer-regexps', and
-SPECIFIERS. Highest priority is given to overriding elements of
-`display-buffer-names' followed by overriding elements of
-`display-buffer-regexps'. Next come the elements specified by
+values of `display-buffer-alist' and SPECIFIERS. Highest
+priority is given to overriding elements of
+`display-buffer-alist'. Next come the elements specified by
SPECIFIERS, followed by the non-overriding elements of
-`display-buffer-names' and the non-overriding elements of
-`display-buffer-regexps'.
+`display-buffer-alist'.
The result must be a list of valid buffer display specifiers. If
`display-buffer-function' is non-nil, call it with the buffer and
-this list as arguments. Otherwise, `display-buffer' scans this
-list from front to back until it finds a location specifier and
-attempts to use that specifier in order to produce a suitable
-window. For this purpose, all non-symbolic specifiers following
-the location specifier in the list are considered additional
-specifiers. If an attempt fails to produce a window,
-`display-buffer' continues with the next location specifier on
-the list. Additional specifiers preceding the currently chosen
-location specifier in the list are ignored."
+this list as arguments."
(interactive "BDisplay buffer:\nP")
(let* ((buffer (normalize-buffer-to-display buffer-or-name))
(buffer-name (buffer-name buffer))
(specifiers
;; Normalize specifiers.
- (display-buffer-normalize-specifiers buffer-name specifiers))
+ (display-buffer-normalize-specifiers buffer-name specifiers label))
;; Don't use a minibuffer frame.
(frame (display-buffer-frame))
;; `window' is the window we use for showing `buffer'.
- specifier location window type
- reuse-buffer-window reuse-other-window)
+ window specifier method)
;; Reset this.
(setq display-buffer-window nil)
(if display-buffer-function
- ;; Let `display-buffer-function' do the job handing it the list
- ;; of our specifiers.
+ ;; Let `display-buffer-function' do the job.
(funcall display-buffer-function buffer specifiers)
;; Retrieve the next location specifier while there a specifiers
;; left and we don't have a valid window.
- (while (and specifiers (or (not window) (not (window-live-p window))))
- (setq location (car specifiers))
+ (while (and specifiers (not (window-live-p window)))
+ (setq specifier (car specifiers))
(setq specifiers (cdr specifiers))
- (when (symbolp location)
- (setq window
- (or (and (eq location 'same-window)
- (or (not (window-dedicated-p))
- (eq (window-buffer) buffer))
- (let ((selected-window
- ;; If the selected window is a minibuffer
- ;; window, use the selected window of the
- ;; last nonminibuffer frame instead.
- (if (window-minibuffer-p)
- (frame-selected-window
- (last-nonminibuffer-frame))
- (selected-window))))
- (display-buffer-in-window
- buffer selected-window specifiers)))
- (and (memq location '(same-frame other-frame))
- (not (eq (setq reuse-buffer-window
- (cdr
- (assq 'reuse-buffer-window specifiers)))
- 'never))
- ;; Try to reuse a window showing BUFFER. If
- ;; reuse-buffer-window was set, it will specify
- ;; the frames to consider, otherwise look at the
- ;; selected frame's windows only.
- (display-buffer-in-lru-buffer-window
- buffer reuse-buffer-window specifiers))
- (and (eq location 'same-frame)
- (not (frame-parameter frame 'unsplittable))
- (cdr (assq 'new-window specifiers))
- ;; Try making a new window.
- (display-buffer-in-new-window buffer specifiers))
- (and (eq location 'other-frame)
- ;; Try making a new frame.
- (display-buffer-in-new-frame buffer specifiers))
- (and (eq location 'same-frame)
- (not (eq (setq reuse-other-window
- (cdr
- (assq 'reuse-other-window specifiers)))
- 'never))
- ;; Try to reuse a window not showing BUFFER. If
- ;; reuse-buffer-window was set, it will specify
- ;; the frames to consider, otherwise look at the
- ;; selected frame's windows only.
- (display-buffer-in-lru-window
- buffer reuse-other-window specifiers))
- (and (not (memq location display-buffer-locations))
- (functionp location)
- ;; Separate function.
- (funcall location buffer specifiers))))))
-
- ;; If we don't have a window yet, try a fallback method. Note: All
+ (setq method (car specifier))
+ (setq window
+ (cond
+ ((eq method 'reuse-window)
+ (display-buffer-reuse-window
+ buffer (cdr specifier) specifiers))
+ ((eq method 'pop-up-window)
+ (display-buffer-pop-up-window
+ buffer (cdr specifier) specifiers))
+ ((eq method 'pop-up-frame)
+ (display-buffer-pop-up-frame
+ buffer (cdr specifier) specifiers))
+ ((eq method 'use-side-window)
+ (display-buffer-in-side-window
+ buffer (nth 1 specifier) (nth 2 specifier) specifiers)))))
+
+ ;; If we don't have a window yet, try a fallback method. All
;; specifiers have been used up by now.
(or (and (window-live-p window) window)
- ;; Try reusing any window showing BUFFER on a visible or
+ ;; Try reusing a window showing BUFFER on any visible or
;; iconfied frame.
- (display-buffer-in-lru-buffer-window buffer 0)
- ;; Try reusing a window on the selected frame.
- (display-buffer-in-lru-window buffer nil)
- ;; Try reusing a window on a visible frame.
- (display-buffer-in-lru-window buffer 'visible)
- ;; Try reusing a window on a visible or iconified frame.
- (display-buffer-in-lru-window buffer 0)
- ;; Try reusing any window showing BUFFER on any frame.
- (display-buffer-in-lru-buffer-window buffer t)
- ;; Try reusing a window on any frame.
- (display-buffer-in-lru-window buffer t)
- ;; Try making a new window.
- (display-buffer-in-new-window buffer nil)
- ;; Try making a new frame
- (display-buffer-in-new-frame buffer nil)
- ;; Use the selected window and let errors show trough.
- (display-buffer-in-window buffer (selected-window) nil)))))
-
-(defun display-buffer-same-window (&optional buffer-or-name)
+ (display-buffer-reuse-window buffer '(nil buffer 0))
+ ;; Try reusing a window not showing BUFFER on any visible or
+ ;; iconified frame.
+ (display-buffer-reuse-window buffer '(nil other 0))
+ ;; Try making a new frame.
+ (display-buffer-pop-up-frame buffer)
+ ;; Try using weakly dedicated windows.
+ (display-buffer-reuse-window
+ buffer '(nil nil t) '((reuse-window-dedicated . weak)))
+ ;; Try using strongly dedicated windows.
+ (display-buffer-reuse-window
+ buffer '(nil nil t) '((reuse-window-dedicated . t)))))))
+
+(defsubst display-buffer-same-window (&optional buffer-or-name label)
"Display buffer specified by BUFFER-OR-NAME in the selected window.
Another window will be used only if the buffer can't be shown in
the selected window, usually because it is dedicated to another
-buffer.
+buffer. Optional argument BUFFER-OR-NAME and LABEL are as for
+`display-buffer'."
+ (display-buffer buffer-or-name 'same-window label))
-Optional argument BUFFER-OR-NAME may be a buffer, a string \(a
-buffer name), or nil. If BUFFER-OR-NAME is a string not naming
-an existent buffer, create a buffer with that name. If
-BUFFER-OR-NAME is nil or omitted, display the current buffer.
-
-Return the window chosen to display BUFFER-OR-NAME or
-nil if no such window is found. Do not change the selected
-window unless a new frame is created."
- (display-buffer buffer-or-name 'same-window))
-
-(defun display-buffer-same-frame (&optional buffer-or-name)
+(defsubst display-buffer-same-frame (&optional buffer-or-name label)
"Display buffer specified by BUFFER-OR-NAME in a window on the same frame.
Another frame will be used only if there is no other choice.
+Optional argument BUFFER-OR-NAME and LABEL are as for
+`display-buffer'."
+ (display-buffer buffer-or-name 'same-frame label))
-Optional argument BUFFER-OR-NAME may be a buffer, a string \(a
-buffer name), or nil. If BUFFER-OR-NAME is a string not naming
-an existent buffer, create a buffer with that name. If
-BUFFER-OR-NAME is nil or omitted, display the current buffer.
-
-Return the window chosen to display BUFFER-OR-NAME or
-nil if no such window is found. Do not change the selected
-window unless a new frame is created."
- (display-buffer
- buffer-or-name display-buffer-same-frame-specifiers))
-
-(defun display-buffer-other-window (&optional buffer-or-name)
+(defsubst display-buffer-other-window (&optional buffer-or-name label)
"Display buffer specified by BUFFER-OR-NAME in another window.
The selected window will be used only if there is no other
choice. Windows on the selected frame are preferred to windows
-on other frames.
+on other frames. Optional argument BUFFER-OR-NAME and LABEL are as
+for `display-buffer'."
+ (display-buffer buffer-or-name 'other-window label))
-Optional argument BUFFER-OR-NAME may be a buffer, a string \(a
-buffer name), or nil. If BUFFER-OR-NAME is a string not naming
-an existent buffer, create a buffer with that name. If
-BUFFER-OR-NAME is nil or omitted, display the current buffer.
-
-Return the window chosen to display BUFFER-OR-NAME or
-nil if no such window is found. Do not change the selected
-window unless a new frame is created."
- (display-buffer
- buffer-or-name display-buffer-other-window-specifiers))
-
-(defun display-buffer-other-window-same-frame (&optional buffer-or-name)
+(defun display-buffer-same-frame-other-window (&optional buffer-or-name label)
"Display buffer specified by BUFFER-OR-NAME in another window on the same frame.
The selected window or another frame will be used only if there
-is no other choice.
-
-Optional argument BUFFER-OR-NAME may be a buffer, a string \(a
-buffer name), or nil. If BUFFER-OR-NAME is a string not naming
-an existent buffer, create a buffer with that name. If
-BUFFER-OR-NAME is nil or omitted, display the current buffer.
+is no other choice. Optional argument BUFFER-OR-NAME and LABEL are
+as for `display-buffer'."
+ (display-buffer buffer-or-name 'same-frame-other-window label))
-Return the window chosen to display BUFFER-OR-NAME or
-nil if no such window is found. Do not change the selected
-window unless a new frame is created."
- (display-buffer
- buffer-or-name display-buffer-other-window-same-frame-specifiers))
-
-(defun pop-to-buffer (&optional buffer-or-name specifiers norecord)
+(defun pop-to-buffer (&optional buffer-or-name specifiers norecord label)
"Display buffer specified by BUFFER-OR-NAME and select the window used.
Optional argument BUFFER-OR-NAME may be a buffer, a string \(a
buffer name), or nil. If BUFFER-OR-NAME is a string not naming
do not make the window displaying it the most recently selected
one.
+The optional argument LABEL, if non-nil, is a symbol specifying the
+display purpose. Applications should set this when the buffer
+shall be displayed in a special way but BUFFER-OR-NAME does not
+identify the buffer as special. Buffers that typically fit into
+this category are those whose names have been derived from the
+name of the file they are visiting.
+
Return the buffer specified by BUFFER-OR-NAME or nil if
displaying the buffer failed.
This uses the function `display-buffer' as a subroutine; see the
-documentations of `display-buffer', `display-buffer-names' and
-`display-buffer-regexps' for additional information."
+documentations of `display-buffer' and `display-buffer-alist' for
+additional information."
(interactive "BPop to buffer:\nP")
(let ((buffer (normalize-buffer-to-display buffer-or-name))
window)
(set-buffer buffer)
- (when (setq window (display-buffer buffer specifiers))
- (display-buffer-select-window window norecord)
+ (when (setq window (display-buffer buffer specifiers label))
+ (select-window window norecord)
buffer)))
-(defun pop-to-buffer-same-window (&optional buffer-or-name norecord)
+(defsubst pop-to-buffer-same-window (&optional buffer-or-name norecord label)
"Pop to buffer specified by BUFFER-OR-NAME in the selected window.
Another window will be used only if the buffer can't be shown in
the selected window, usually because it is dedicated to another
-buffer. Select the window used for displaying the buffer and
-return the buffer specified by BUFFER-OR-NAME or nil if
-displaying the buffer failed.
-
-Optional arguments BUFFER-OR-NAME and NORECORD are as for
-`pop-to-buffer'."
+buffer. Optional arguments BUFFER-OR-NAME, NORECORD and LABEL are
+as for `pop-to-buffer'."
(interactive "BPop to buffer in selected window:\nP")
- (pop-to-buffer buffer-or-name 'same-window norecord))
+ (pop-to-buffer buffer-or-name 'same-window norecord label))
-(defun pop-to-buffer-same-frame (&optional buffer-or-name norecord)
+(defsubst pop-to-buffer-same-frame (&optional buffer-or-name norecord label)
"Pop to buffer specified by BUFFER-OR-NAME in a window on the selected frame.
Another frame will be used only if there is no other choice.
-Select the window used for displaying the buffer and return the
-buffer specified by BUFFER-OR-NAME or nil if displaying the
-buffer failed.
-
-Optional arguments BUFFER-OR-NAME and NORECORD are as for
+Optional arguments BUFFER-OR-NAME, NORECORD and LABEL are as for
`pop-to-buffer'."
(interactive "BPop to buffer in another window:\nP")
- (pop-to-buffer
- buffer-or-name display-buffer-same-frame-specifiers norecord))
+ (pop-to-buffer buffer-or-name 'same-frame norecord label))
-(defun pop-to-buffer-other-window (&optional buffer-or-name norecord)
+(defsubst pop-to-buffer-other-window (&optional buffer-or-name norecord label)
"Pop to buffer specified by BUFFER-OR-NAME in another window.
The selected window will be used only if there is no other
choice. Windows on the selected frame are preferred to windows
-on other frames. Select the window used for displaying the
-buffer and return the buffer specified by BUFFER-OR-NAME or nil
-if displaying the buffer failed.
-
-Optional arguments BUFFER-OR-NAME and NORECORD are as for
-`pop-to-buffer'."
+on other frames. Optional arguments BUFFER-OR-NAME, NORECORD and
+LABEL are as for `pop-to-buffer'."
(interactive "BPop to buffer in another window:\nP")
- (pop-to-buffer
- buffer-or-name display-buffer-other-window-specifiers norecord))
+ (pop-to-buffer buffer-or-name 'other-window norecord))
-(defun pop-to-buffer-other-window-same-frame (&optional buffer-or-name norecord)
+(defsubst pop-to-buffer-same-frame-other-window (&optional buffer-or-name norecord label)
"Pop to buffer specified by BUFFER-OR-NAME in another window on the selected frame.
The selected window or another frame will be used only if there
-is no other choice. Select the window used for displaying the
-buffer and return the buffer specified by BUFFER-OR-NAME or nil
-if displaying the buffer failed.
-
-Optional arguments BUFFER-OR-NAME and NORECORD are as for
-`pop-to-buffer'."
+is no other choice. Optional arguments BUFFER-OR-NAME, NORECORD
+and LABEL are as for `pop-to-buffer'."
(interactive "BPop to buffer in another window:\nP")
- (pop-to-buffer
- buffer-or-name display-buffer-other-window-same-frame-specifiers norecord))
+ (pop-to-buffer buffer-or-name 'same-frame-other-window norecord label))
-(defun pop-to-buffer-other-frame (&optional buffer-or-name norecord)
+(defsubst pop-to-buffer-other-frame (&optional buffer-or-name norecord label)
"Pop to buffer specified by BUFFER-OR-NAME on another frame.
The selected frame will be used only if there's no other choice.
-Select the window used for displaying the buffer and return the
-buffer specified by BUFFER-OR-NAME or nil if displaying the
-buffer failed.
-
-Optional arguments BUFFER-OR-NAME and NORECORD are as for
+Optional arguments BUFFER-OR-NAME, NORECORD and LABEL are as for
`pop-to-buffer'."
(interactive "BPop to buffer on another frame:\nP")
- (pop-to-buffer
- buffer-or-name display-buffer-other-frame-specifiers norecord))
+ (pop-to-buffer buffer-or-name 'other-frame norecord label))
(defun read-buffer-to-switch (prompt)
"Read the name of a buffer to switch to, prompting with PROMPT.
do not make the window displaying it the most recently selected
one. Return the buffer switched to.
-This function is intended for interactive use. Lisp functions
-should call `pop-to-buffer-same-window' instead."
+This function is intended for interactive use only. Lisp
+functions should call `pop-to-buffer-same-window' instead."
(interactive
(list (read-buffer-to-switch "Switch to buffer: ")))
(let ((buffer (normalize-buffer-to-switch-to buffer-or-name)))
(defun switch-to-buffer-same-frame (buffer-or-name &optional norecord)
"Switch to buffer BUFFER-OR-NAME in a window on the selected frame.
Another frame will be used only if there is no other choice.
+Optional arguments BUFFER-OR-NAME and NORECORD have the same
+meaning as for `switch-to-buffer'.
-If called interactively, prompt for the buffer name using the
-minibuffer. The variable `confirm-nonexistent-file-or-buffer'
-determines whether to request confirmation before creating a new
-buffer.
-
-When called from Lisp, BUFFER-OR-NAME may be a buffer, a string
-\(a buffer name), or nil. If BUFFER-OR-NAME is a string that
-does not identify an existing buffer, create a buffer with that
-name. If BUFFER-OR-NAME is nil, switch to the buffer returned by
-`other-buffer'.
-
-Optional argument NORECORD non-nil means do not put the buffer
-specified by BUFFER-OR-NAME at the front of the buffer list and
-do not make the window displaying it the most recently selected
-one. Return the buffer switched to.
-
-This uses the function `display-buffer' as a subroutine; see the
-documentations of `display-buffer', `display-buffer-names' and
-`display-buffer-regexps' for additional information.
-
-This function is intended for interactive use. Lisp functions
-should call `pop-to-buffer-other-window' instead."
+This function is intended for interactive use only. Lisp
+functions should call `pop-to-buffer-same-frame' instead."
(interactive
(list (read-buffer-to-switch "Switch to buffer in other window: ")))
(let ((buffer (normalize-buffer-to-switch-to buffer-or-name)))
- (pop-to-buffer
- buffer display-buffer-same-frame-specifiers norecord)))
+ (pop-to-buffer buffer 'same-frame norecord)))
(defun switch-to-buffer-other-window (buffer-or-name &optional norecord)
"Switch to buffer BUFFER-OR-NAME in another window.
The selected window will be used only if there is no other
choice. Windows on the selected frame are preferred to windows
-on other frames.
+on other frames. Optional arguments BUFFER-OR-NAME and NORECORD
+have the same meaning as for `switch-to-buffer'.
-If called interactively, prompt for the buffer name using the
-minibuffer. The variable `confirm-nonexistent-file-or-buffer'
-determines whether to request confirmation before creating a new
-buffer.
-
-When called from Lisp, BUFFER-OR-NAME may be a buffer, a string
-\(a buffer name), or nil. If BUFFER-OR-NAME is a string that
-does not identify an existing buffer, create a buffer with that
-name. If BUFFER-OR-NAME is nil, switch to the buffer returned by
-`other-buffer'.
-
-Optional argument NORECORD non-nil means do not put the buffer
-specified by BUFFER-OR-NAME at the front of the buffer list and
-do not make the window displaying it the most recently selected
-one. Return the buffer switched to.
-
-This uses the function `display-buffer' as a subroutine; see the
-documentations of `display-buffer', `display-buffer-names' and
-`display-buffer-regexps' for additional information.
-
-This function is intended for interactive use. Lisp functions
-should call `pop-to-buffer-other-window' instead."
+This function is intended for interactive use only. Lisp
+functions should call `pop-to-buffer-other-window' instead."
(interactive
(list (read-buffer-to-switch "Switch to buffer in other window: ")))
(let ((buffer (normalize-buffer-to-switch-to buffer-or-name)))
- (pop-to-buffer
- buffer display-buffer-other-window-specifiers norecord)))
+ (pop-to-buffer buffer 'other-window norecord)))
(defun switch-to-buffer-other-window-same-frame (buffer-or-name &optional norecord)
"Switch to buffer BUFFER-OR-NAME in another window on the selected frame.
The selected window or another frame will be used only if there
-is no other choice.
-
-If called interactively, prompt for the buffer name using the
-minibuffer. The variable `confirm-nonexistent-file-or-buffer'
-determines whether to request confirmation before creating a new
-buffer.
-
-When called from Lisp, BUFFER-OR-NAME may be a buffer, a string
-\(a buffer name), or nil. If BUFFER-OR-NAME is a string that
-does not identify an existing buffer, create a buffer with that
-name. If BUFFER-OR-NAME is nil, switch to the buffer returned by
-`other-buffer'.
-
-Optional argument NORECORD non-nil means do not put the buffer
-specified by BUFFER-OR-NAME at the front of the buffer list and
-do not make the window displaying it the most recently selected
-one. Return the buffer switched to.
-
-This uses the function `display-buffer' as a subroutine; see the
-documentations of `display-buffer', `display-buffer-names' and
-`display-buffer-regexps' for additional information.
+is no other choice. Optional arguments BUFFER-OR-NAME and
+NORECORD have the same meaning as for `switch-to-buffer'.
-This function is intended for interactive use. Lisp functions
-should call `pop-to-buffer-other-window' instead."
+This function is intended for interactive use only. Lisp
+functions should call `pop-to-buffer-other-window-same-frame'
+instead."
(interactive
(list (read-buffer-to-switch "Switch to buffer in other window: ")))
(let ((buffer (normalize-buffer-to-switch-to buffer-or-name)))
- (pop-to-buffer
- buffer display-buffer-other-window-same-frame-specifiers norecord)))
+ (pop-to-buffer buffer 'same-frame-other-window norecord)))
(defun switch-to-buffer-other-frame (buffer-or-name &optional norecord)
"Switch to buffer BUFFER-OR-NAME on another frame.
-If called interactively, prompt for the buffer name using the
-minibuffer. The variable `confirm-nonexistent-file-or-buffer'
-determines whether to request confirmation before creating a new
-buffer.
-
-When called from Lisp, BUFFER-OR-NAME may be a buffer, a string
-\(a buffer name), or nil. If BUFFER-OR-NAME is a string that
-does not identify an existing buffer, create a buffer with that
-name. If BUFFER-OR-NAME is nil, switch to the buffer returned by
-`other-buffer'.
-
-Optional argument NORECORD non-nil means do not put the buffer
-specified by BUFFER-OR-NAME at the front of the buffer list and
-do not make the window displaying it the most recently selected
-one. Return the buffer switched to.
-
-This uses the function `display-buffer' as a subroutine; see the
-documentations of `display-buffer', `display-buffer-names' and
-`display-buffer-regexps' for additional information.
+The same frame will be used only if there is no other choice.
+Optional arguments BUFFER-OR-NAME and NORECORD have the same
+meaning as for `switch-to-buffer'.
-This function is intended for interactive use. Lisp functions
-should call `pop-to-buffer-other-frame' instead."
+This function is intended for interactive use only. Lisp
+functions should call `pop-to-buffer-other-frame' instead."
(interactive
(list (read-buffer-to-switch "Switch to buffer in other frame: ")))
(let ((buffer (normalize-buffer-to-switch-to buffer-or-name)))
- (pop-to-buffer buffer display-buffer-other-frame-specifiers norecord)))
-
-(defcustom display-buffer-function nil
- "If non-nil, function to call to display a buffer.
-`display-buffer' calls this function with two arguments, the
-buffer to display and a list of buffer display specifiers, see
-`display-buffer-names'.
-
-The function is supposed to choose or create a window, display
-the specified buffer in it, and return the window. It is also
-responsible for giving the variable `display-buffer-window' and
-the `quit-restore' parameter of the window used a meaningful
-value.
-
-The function specified here overrides all specifiers of the
-variables `display-buffer-names' and `display-buffer-regexps' and
-any specifiers passed to `display-buffer'.
-
-If you call `display-buffer' within the body of the function,
-bind the value of `display-buffer-function' to nil around that
-call to avoid that the function recursively calls itself."
- :type '(choice
- (const nil)
- (function :tag "Function"))
- :group 'display-buffer)
+ (pop-to-buffer buffer 'other-frame norecord)))
;;; Obsolete definitions of `display-buffer' below.
(defcustom special-display-buffer-names nil
:group 'frames)
(make-obsolete-variable
'special-display-buffer-names
- "use `display-buffer-names', `display-buffer-regexps' or 2nd arg of `display-buffer' instead."
+ "use `display-buffer-alist' or 2nd arg of `display-buffer' instead."
"24.1")
;;;###autoload
:group 'frames)
(make-obsolete-variable
'special-display-regexps
- "use `display-buffer-names', `display-buffer-regexps' or 2nd arg of `display-buffer' instead."
+ "use `display-buffer-alist' or 2nd arg of `display-buffer' instead."
"24.1")
(defun special-display-p (buffer-name)
"Return non-nil if a buffer named BUFFER-NAME gets a special frame.
-More precisely, return t if `special-display-buffer-names' or
-`special-display-regexps' contain a string entry equaling or
-matching BUFFER-NAME. If `special-display-buffer-names' or
-`special-display-regexps' contain a list entry whose car equals
-or matches BUFFER-NAME, the return value is the cdr of that
-entry."
- (let (tmp)
- (cond
- ((not (stringp buffer-name)))
- ((member buffer-name special-display-buffer-names)
- t)
- ((setq tmp (assoc buffer-name special-display-buffer-names))
- (cdr tmp))
- ((catch 'found
- (dolist (regexp special-display-regexps)
- (cond
- ((stringp regexp)
- (when (string-match-p regexp buffer-name)
- (throw 'found t)))
- ((and (consp regexp) (stringp (car regexp))
- (string-match-p (car regexp) buffer-name))
- (throw 'found (cdr regexp))))))))))
+More precisely, return t if `display-buffer-alist' would ask for
+displayin BUFFER-NAME in a special way."
+ (catch 'found
+ (dolist (entry display-buffer-alist)
+ (when (and (listp entry)
+ (catch 'match
+ (dolist (id (car entry))
+ (when (consp id)
+ (let ((type (car id))
+ (value (cdr id)))
+ (when (or (and (eq type 'name) (stringp value)
+ (equal value buffer-name))
+ (and (eq type 'regexp) (stringp value)
+ (string-match-p value buffer-name)))
+ (throw 'match t)))))))
+ (throw 'found (cdr entry))))))
(make-obsolete 'special-display-p "pass argument to buffer display function instead." "24.1")
(defcustom special-display-function 'special-display-popup-frame
:group 'frames)
(make-obsolete-variable
'special-display-function
- "use `display-buffer-names', `display-buffer-regexps' or 2nd arg of `display-buffer' instead."
+ "use `display-buffer-alist' or 2nd arg of `display-buffer' instead."
"24.1")
(defcustom same-window-buffer-names nil
:group 'display-buffer)
(make-obsolete-variable
'same-window-buffer-names
- "use `display-buffer-names', `display-buffer-regexps' or 2nd arg of `display-buffer' instead."
+ "use `display-buffer-alist' or 2nd arg of `display-buffer' instead."
"24.1")
(defcustom same-window-regexps nil
:group 'display-buffer)
(make-obsolete-variable
'same-window-regexps
- "use `display-buffer-names', `display-buffer-regexps' or 2nd arg of `display-buffer' instead."
+ "use `display-buffer-alist' or 2nd arg of `display-buffer' instead."
"24.1")
(defun same-window-p (buffer-name)
"Return non-nil if a buffer named BUFFER-NAME would be shown in the \"same\" window.
-This function returns non-nil if `display-buffer' or
-`pop-to-buffer' would show a buffer named BUFFER-NAME in the
-selected rather than \(as usual\) some other window. See
-`same-window-buffer-names' and `same-window-regexps'."
- (cond
- ((not (stringp buffer-name)))
- ;; The elements of `same-window-buffer-names' can be buffer
- ;; names or cons cells whose cars are buffer names.
- ((member buffer-name same-window-buffer-names))
- ((assoc buffer-name same-window-buffer-names))
- ((catch 'found
- (dolist (regexp same-window-regexps)
- ;; The elements of `same-window-regexps' can be regexps
- ;; or cons cells whose cars are regexps.
- (when (or (and (stringp regexp)
- (string-match regexp buffer-name))
- (and (consp regexp) (stringp (car regexp))
- (string-match-p (car regexp) buffer-name)))
- (throw 'found t)))))))
+This function returns non-nil if `display-buffer-alist' contains
+an entry stating that a buffer named BUFFER-NAME should be
+displayed in the selected rather than some other window."
+ (catch 'found
+ (dolist (entry display-buffer-alist)
+ (when (and (listp entry)
+ (catch 'match
+ (dolist (id (car entry))
+ (when (consp id)
+ (let ((type (car id))
+ (value (cdr id)))
+ (when (or (and (eq type 'name) (stringp value)
+ (equal value buffer-name))
+ (and (eq type 'regexp) (stringp value)
+ (string-match-p value buffer-name)))
+ (throw 'match t)))))))
+ (when (eq (cadr entry) 'same-window)
+ (throw 'found t))))))
(make-obsolete 'same-window-p "pass argument to buffer display function instead." "24.1")
(defcustom pop-up-frames nil
:group 'frames)
(make-obsolete-variable
'pop-up-frames
- "use `display-buffer-names', `display-buffer-regexps' or 2nd arg of `display-buffer' instead."
+ "use `display-buffer-alist' or 2nd arg of `display-buffer' instead."
"24.1")
(defcustom display-buffer-reuse-frames nil
:group 'frames)
(make-obsolete-variable
'display-buffer-reuse-frames
- "use `display-buffer-names', `display-buffer-regexps' or 2nd arg of `display-buffer' instead."
+ "use `display-buffer-alist' or 2nd arg of `display-buffer' instead."
"24.1")
(defcustom pop-up-windows t
:group 'display-buffer)
(make-obsolete-variable
'pop-up-windows
- "use `display-buffer-names', `display-buffer-regexps' or 2nd arg of `display-buffer' instead."
+ "use `display-buffer-alist' or 2nd arg of `display-buffer' instead."
"24.1")
(defcustom split-window-preferred-function 'split-window-sensibly
:group 'display-buffer)
(make-obsolete-variable
'split-window-preferred-function
- "use `display-buffer-names', `display-buffer-regexps' or 2nd arg of `display-buffer' instead."
+ "use `display-buffer-alist' or 2nd arg of `display-buffer' instead."
"24.1")
(defcustom split-height-threshold 80
:group 'display-buffer)
(make-obsolete-variable
'split-height-threshold
- "use `display-buffer-names', `display-buffer-regexps' or 2nd arg of `display-buffer' instead."
+ "use `display-buffer-alist' or 2nd arg of `display-buffer' instead."
"24.1")
(defcustom split-width-threshold 160
:group 'display-buffer)
(make-obsolete-variable
'split-width-threshold
- "use `display-buffer-names', `display-buffer-regexps' or 2nd arg of `display-buffer' instead."
+ "use `display-buffer-alist' or 2nd arg of `display-buffer' instead."
"24.1")
(defcustom even-window-heights t
:group 'display-buffer)
(make-obsolete-variable
'even-window-heights
- "use `display-buffer-names', `display-buffer-regexps' or 2nd arg of `display-buffer' instead."
+ "use `display-buffer-alist' or 2nd arg of `display-buffer' instead."
"24.1")
(defvar display-buffer-mark-dedicated nil
`window-dedicated-p' flag.")
(make-obsolete-variable
'display-buffer-mark-dedicated
- "use `display-buffer-names', `display-buffer-regexps' or 2nd arg of `display-buffer' instead."
+ "use `display-buffer-alist' or 2nd arg of `display-buffer' instead."
"24.1")
\f
(defun set-window-text-height (window height)