From: Martin Rudalics Date: Thu, 4 Nov 2010 13:26:46 +0000 (+0100) Subject: Merge with trunk. Add even-window-sizes and adjust-width buffer display X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=97c4d32332d615276ea12545b49aa0072d7224fd;p=emacs.git Merge with trunk. Add even-window-sizes and adjust-width buffer display specifiers. Redesign adjust-height buffer display specifier. Adjust callers in compile.el. * window.el (display-buffer-names, display-buffer-regexps): Make even-window-sizes a seperate specifier. Allow numbers and functions in the cdr of the adjust-height specifier and remove even-window-heights and the special handling of fit-window-to-buffer and shrink-window-if-larger-than-buffer. Add new specifier adjust-width similar to adjust-height. (display-buffer-normalize-specifiers-1): Fix typo. (display-buffer-even-sizes, display-buffer-adjust-height) (display-buffer-adjust-width): New functions to handle size adjustment of new window. (display-buffer-adjust-heights): Remove. (display-buffer-in-window): Don't call display-buffer-adjust-heights any more. (display-buffer-in-lru-buffer-window) (display-buffer-in-lru-window): Call display-buffer-even-sizes. (display-buffer-in-new-window): Use functionp instead of fboundp. Call display-buffer-adjust-height and display-buffer-adjust-width. (display-buffer): Use functionp instead of fboundp. (fit-window-to-buffer): Rename argument IGNORE to OVERRIDE. * progmodes/compile.el (compilation-start) (compilation-goto-locus): Use adjust-height specifier in display-buffer calls. --- 97c4d32332d615276ea12545b49aa0072d7224fd diff --cc doc/lispref/ChangeLog index 95e7f92c188,5607d179aad..9977c2ef4ef --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@@ -1,16 -1,7 +1,27 @@@ ++2010-11-04 Martin Rudalics ++ ++ * windows.texi (Resizing Windows): Explain OVERRIDE argumet for ++ fit-window-to-buffer. ++ (Displaying Buffers): Describe even-window-sizes, adjust-height ++ and adjust-width buffer display specifiers. ++ +2010-11-02 Martin Rudalics + + * windows.texi (Displaying Buffers): Describe special handling + of `not-this-window' and `not-this-frame' specifiers for + `display-buffer'. + + 2010-10-31 Glenn Morris + + * maps.texi (Standard Keymaps): Update File menu description. + +2010-10-30 Martin Rudalics + + * windows.texi (Buffers and Windows, Displaying Buffers): Adapt + to new semantics of quit-restore window parameter and + display-buffer-window (was display-buffer-window-and-buffer) + semantics. + 2010-10-28 Glenn Morris * Makefile.in (elisp.dvi, elisp.pdf): Also include $emacsdir. diff --cc doc/lispref/windows.texi index 95bcf4571b2,704f3ad3321..2b905cc9b17 --- a/doc/lispref/windows.texi +++ b/doc/lispref/windows.texi @@@ -81,778 -98,10 +81,782 @@@ which Emacs creates new windows (@pxref them (@pxref{Resizing Windows}), not all conceivable tilings of windows on an Emacs frame are actually possible. + For practical purposes, a window exists only while it is displayed in +a frame. Once removed from the frame, the window is effectively deleted +and should not be used, @emph{even though there may still be references +to it} from other Lisp objects; see @ref{Deleting Windows}. Restoring a +saved window configuration is the only way for a window no longer on the +screen to come back to life; see @ref{Window Configurations}. + @defun windowp object -This function returns @code{t} if @var{object} is a window. +This function returns @code{t} if @var{object} is a window and +@code{nil} otherwise. +@end defun + +@cindex live windows +@cindex internal windows + 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 +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 +live window. + +@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. +@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}. +@end defun + +@defun window-any-p object +This function returns @code{t} if @var{object} denotes a live or an +internal window and @code{nil} otherwise. In particular, this function +returns @code{nil} if @var{object} is a window that has been +deleted. +@end defun + + 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 +``normalize'' arguments specifying windows in a uniform manner. + +@defun normalize-any-window window +This function returns the normalized value for @var{window} which can be +any window that has not been deleted. More precisely, if @var{window} +is @code{nil} it returns the selected window. If @var{window} is +non-@code{nil} and denotes a live or an internal window, this function +returns @var{window}. In any other case this function signals an error. +@end defun + +@defun normalize-live-window window +This functions returns the normalized value for a live window +@var{window}. More precisely, if @var{window} is @code{nil} it returns +the selected window. Otherwise, if @var{window} is a live window this +function returns @var{window}. If @var{window} is neither @code{nil} +nor a live window this function signals an error. +@end defun + +@node Frames and Windows +@section Frames and Windows + +Each window is part of one and only one frame (@pxref{Frames}); you can +get that frame with the following function. + +@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. + +@defun window-list &optional frame minibuf window +This function returns a list of @var{frame}'s live windows, starting +with @var{window}. The argument @var{frame} has to denote a live frame +and defaults to the selected frame. The argument @var{window} has to +denote a live window on the frame specified by @var{frame} and defaults +to the selected one. + +The argument @var{minibuf} specifies if the minibuffer window shall be +included in the return value. If @var{minibuf} is @code{t}, the result +always includes the minibuffer window. If @var{minibuf} is @code{nil} +or omitted, that includes the minibuffer window only if it is active. +If @var{minibuf} is neither @code{nil} nor @code{t}, the result never +includes the minibuffer window. +@end defun + +@cindex window tree +Windows within one and the same frame are organized in form of a tree +called @dfn{window tree}. The leaf nodes of a window tree constitute +the windows visible to the user. These are the windows associated with +buffers and are usually called live or leaf windows. The internal nodes +of a window tree are needed for finding, traversing and displaying the +leaf windows. + + A minibuffer window (@pxref{Minibuffer Windows}) is not considered +part of its frame's window tree unless the frame is a minibuffer-only +frame. Most functions covered in this section accept, however, the +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 +This function returns the root window of @var{frame-or-window}. The +argument @var{frame-or-window} has to denote either a window or a frame +and defaults to the selected frame. If @var{frame-or-window} denotes a +window, the return value is the root window of that window's frame. +This function always returns a window; a live window if the frame +specified by @var{frame-or-window} contains no other live windows and an +internal window otherwise. +@end defun + +@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. + +The functions described next allow to access the members of a window +tree with 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. +@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 +windows, so there are no ``Matryoshka'' windows. Minibuffer windows do +not have child windows. + +@cindex window combination +@cindex vertical combination +@cindex horizontal combination +The children of any parent window form either a vertical or a horizontal +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. + +@defun window-vchild &optional window +This function returns @var{window}'s first vertical child window. The +optional argument @var{window} can be an arbitrary window and defaults +to the selected one. The return value is @code{nil} if @var{window} is +a leaf window or its children form a horizontal combination. +@end defun + +@defun window-hchild &optional window +This function returns @var{window}'s first horizontal child window. The +optional argument @var{window} can be an arbitrary window and defaults +to the selected one. The return value is @code{nil} if @var{window} is +a leaf window or its children form a vertical combination. +@end defun + +@defun window-child window +This function return @var{window}'s first child window. The return +value is @code{nil} if @var{window} is a leaf window. +@end defun + +The following function is useful to determine whether a window is part +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. + +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 +combined. The actual return value is the first horizontal child of +window. +@end defun + +@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. + +@defun window-next &optional window +This function returns @var{window}'s right sibling. The optional +argument @var{window} can be an arbitrary window and defaults to the +selected window. It returns @code{nil} if @var{window} has no right +sibling. Applying this function recursively will eventually get you to +the last child of @var{window}'s parent. +@end defun + +@defun window-prev &optional window +This function returns @var{window}'s left sibling. The optional +argument @var{window} can be an arbitrary window and defaults to the +selected window. It returns @code{nil} if @var{window} has no left +sibling. Applying this function recursively will eventually get you to +the first child of @var{window}'s parent. +@end defun + +The functions @code{window-next} and @code{window-prev} should not be +confused with the functions @code{next-window} and +@code{previous-window} which respectively return the next and previous +window in the cyclic ordering of windows, see @ref{Cyclic Window +Ordering}. + + In order to find the first live window on a frame, the following +function can be used. + +@defun frame-first-window &optional frame-or-window +This function returns the window at the upper left corner of the frame +specified by @var{frame-or-window}. The argument @var{frame-or-window} +must denote a window or a live frame and defaults to the selected frame. +If @var{frame-or-window} specifies a window, this function returns the +first window on that window's frame. +@end defun + +You can get the window tree of a frame with the following function. + +@cindex window tree +@defun window-tree &optional frame +This function returns the window tree for frame @var{frame}. The +optional argument @var{frame} must be a live frame and defaults to the +selected one. + +The return value is a list of the form @code{(@var{root} @var{mini})}, +where @var{root} represents the window tree of the frame's +root window, and @var{mini} is the frame's minibuffer window. + +If the root window is live, @var{root} specifies the root window and +nothing else. Otherwise, @var{root} is a list @code{(@var{dir} +@var{edges} @var{w1} @var{w2} ...)} where @var{dir} is @code{nil} for a +horizontal combination, and @code{t} for a vertical combination, +@var{edges} gives the size and position of the combination, and the +remaining elements are the child windows. Each child window may again +be a live window or a list representing a window combination, and so on. +The @var{edges} element is a list @code{(@var{left}@var{ top}@var{ +right}@var{ bottom})} similar to the value returned by +@code{window-edges}, see @ref{Coordinates and Windows}. +@end defun + +@node Window Sizes +@section Window Sizes +@cindex window size +@cindex size of window + +Emacs windows are rectangular. The structure of a live window can be +roughly sketched as follows: + +@smallexample +@group + _________________________________________ + ^ |______________ Header Line_______________| + | |LS|LF|LM| |RM|RF|RS| ^ + | | | | | | | | | | + Window | | | | Text Area | | | | Window + Total | | | | (Window Body) | | | | Body + Height | | | | | | | | Height + | | | | |<- Window Body Width ->| | | | | + | |__|__|__|_______________________|__|__|__| v + v |_______________ Mode Line _______________| + + <----------- Window Total Width --------> + +@end group +@end smallexample + +@cindex window body +@cindex body of a window +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 +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}. + +@cindex window height +@cindex total window height +@cindex height of a window +@cindex total height of a window +The @dfn{total height of a window} is specified as the total number of +lines occupied by the window. Any mode or header line is included in a +window's total height. For an internal window, the total height is +calculated recursively from the total heights of its child windows. + +@cindex window width +@cindex total window width +@cindex width of a window +@cindex total width of a window +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 +windows. + +@cindex total size of a window +@cindex total window size +The following function is the standard interface for getting the total +size of any window: + +@defun window-total-size &optional window &optional horizontal +This function returns the total number of lines of @var{window}. The +argument @var{window} can denote any window and defaults to the selected +one. If @var{window} is live, the return value includes any header or +mode lines of @var{window}. If @var{window} is internal, the return +value is the sum of the total heights of @var{window}'s child windows +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. +@end defun + +Alternatively, the following two functions can be used to retrieve +either the total height of the total width of a window: + +@defun window-total-height &optional window +This function returns the total number of lines of @var{window}. +@var{window} can be any window and defaults to the selected one. The +return value includes @var{window}'s mode line and header line, if any. +If @var{window} is internal the return value is the sum of heights of +@var{window}'s child windows for a vertical combination and the height +of @var{window}'s first child otherwise. +@end defun + +@defun window-total-width &optional window +This function returns the total number of columns of @var{window}. +@var{window} can be any window and defaults to the selected one. The +return value includes any vertical dividers or scrollbars of +@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 widths of +@var{window}'s child windows for a horizontal combination and the width +of @var{window}'s first child otherwise. +@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. 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: + +@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 +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. + +@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. +@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. + +@defun window-top-line &optional window +This function returns the top line of @var{window}. The argument +@var{window} can denote any window and defaults to the selected one. +@end defun + +@defun window-left-column &optional window +This function returns the left column of @var{window}. The argument +@var{window} can denote any window and defaults to the selected one. +@end defun + +For a frame displaying one window only, that window's top line and left +column are both zero. When a frame displays a window @var{WB} below a +window @var{WA}, the top line of @var{WB} can be calculated by adding +the total height of @var{WA} to the top line of @var{WA}. When a frame +displays a window @var{WR} on the right of a window @var{WL}, the left +column of @var{WR} can be calculated by adding the total width of +@var{WL} to the left column of @var{WL}. + +@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. + +@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. + +@cindex body size of a window +@cindex window body size +The following functions retrieve height and width of the body of a live +window: + +@defun window-body-size &optional window horizontal +This function returns the number of lines of @var{window}'s text area. +@var{window} must be a live window and defaults to the selected one. +The return value does not count any mode or header line of @var{window}. + +Optional argument @var{horizontal} non-@code{nil} means to return the +number of columns of @var{window}'s text area. In this case the return +value does not include any vertical divider or scroll bar owned by +@var{window}. On a window-system the return value does not include the +number of columns used for @var{window}'s fringes or display margins +either. +@end defun + +@defun window-body-height &optional window +This function returns the number of lines of @var{window}'s body. +@var{window} must be a live window and defaults to the selected one. + +The return value does not include @var{window}'s mode line and header +line, if any. If a line at the bottom of the window is only partially +visible, that line is included in the return value. If you do not +want to include a partially visible bottom line in the return value, +use @code{window-text-height} instead. +@end defun + +@defun window-body-width &optional window +This function returns the number of columns of @var{window}'s body. +@var{window} must be a live window and defaults to the selected one. + +The return value does not include any vertical dividers or scroll bars +owned by @var{window}. On a window-system the return value does not +include the number of columns used for @var{window}'s fringes or +display margins either. +@end defun + +The following functions have been used in earlier versions of Emacs. +They are still supported but due to the confusing nomenclature they +should not be used any more in future code. + +@defun window-height &optional window +This function is an alias for `window-total-height', see above. +@end defun + +@defun window-width &optional window +This function is an alias for `window-body-width', see above. +@end defun + +@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. + +@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. +@end defopt + +@defopt window-min-width +The value of this variable specifies how narrow a window may be. The +value is measured in characters and includes any margins, fringes, +scroll bar and vertical divider column. The default value for this +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. + + 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 +implicitly delete windows when they do not fit on the frame any more, +see @ref{Size and Position}. + + The size of a window can be fixed which means that it cannot be split +(@pxref{Splitting Windows}) or resized (@pxref{Resizing Windows}). + +@cindex fixed-size window +@defvar window-size-fixed +If this variable is non-@code{nil}, in a given buffer, then the size of +any window displaying that buffer remains fixed unless you either +explicitly change it or Emacs has no other choice. + +If the value is @code{height}, then only the window's height is fixed; +if the value is @code{width}, then only the window's width is fixed. +Any other non-@code{nil} value fixes both the width and the height. + +This variable automatically becomes buffer-local when set. +@end defvar + +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 +@code{resize-window} (@pxref{Resizing Windows}) have an optional +@var{ignore} argument which allows to change the size of fixed-size +windows. + + Deleting a window or changing a frame's size may change the size of a +fixed-size window, if there is no other alternative. + + A vertical combination of windows cannot be resized when the height +of all windows in that combination is fixed. A horizontal combination +cannot be resized when the width of all windows in it is fixed. The +next function allows to check whether the size of an arbitrary window is +fixed. + +@defun window-size-fixed-p &optional window horizontal +This function returns non-@code{nil} if @var{window}'s height is fixed. +The argument @var{window} can be an arbitrary window and defaults to the +selected one. Optional argument @var{horizontal} non-@code{nil} means +return non-@code{nil} if @var{window}'s width is fixed. + +If this function returns @code{nil}, this does not necessarily mean that +@var{window} can be resized in the desired direction. The function +@code{window-resizable} (@pxref{Resizing Windows}) can tell that. +@end defun + +@node Resizing Windows +@section Resizing Windows +@cindex window resizing +@cindex resize window +@cindex changing window size +@cindex window size, changing + +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. + + The routines changing window sizes always operate in one dimension at +a time. This means that windows can be resized only either vertically +or horizontally. If a window shall be resized in both dimensions, it +must be resized in one dimension first and in the other dimension +afterwards. If the second resize operation fails, the frame might end +up in an unsatisfactory state. To avoid such states, it might be useful +to save the current window configuration (@pxref{Window Configurations}) +before attempting the first resize operation and restore the saved +configuration in case the second resize operation fails. + + Functions that resize windows are supposed to obey restrictions +imposed by window minimum sizes and fixed-size windows, see @ref{Window +Sizes}. In order to determine whether resizing a specific window is +possible in the first place, the following function can be used: + +@defun window-resizable window delta &optional horizontal ignore side noup nodown +This function returns @var{delta} if the size of @var{window} can be +changed vertically by @var{delta} lines. Optional argument +@var{horizontal} non-@code{nil} means to return @var{delta} if +@var{window} can be resized horizontally by @var{delta} columns. A +return value of zero means that @var{window} is not resizable. + +If @var{delta} is a positive number, this means that @var{window} shall +be enlarged by @var{delta} lines or columns. If @var{window} cannot be +enlarged by @var{delta} lines or columns this function returns the +maximum value in the range from 0 to @var{delta} by which @var{window} +can be enlarged. + +If @var{delta} is a negative number, this means that @var{window} shall +be shrunk by -@var{delta} lines or columns. If @var{window} cannot be +shrunk by -@var{delta} lines or columns, this function returns the +minimum value in the range from @var{delta} to 0 that can be used for +shrinking @var{window}. + +Optional argument @var{ignore} non-@code{nil} means ignore any +restrictions imposed by the variables @code{window-min-height} or +@code{window-min-width} and @code{window-size-fixed}. In this case the +minimum height of a window is specified as the minimum number of lines +that allow viewing any header or mode line and at least one line of the +text area of window. The minimum width of a window includes any +fringes, margins and the scroll bar as well as two text columns. + +If @var{ignore} denotes a window, this means to ignore restrictions for +that window only. If @var{ignore} equals the constant @code{safe}, this +means a live window may get as small as one line or two columns. + +Optional argument @var{noup} non-@code{nil} means don't go up in the +window tree but try to steal or distribute the space needed for the +resize operation among the other windows within @var{window}'s +combination. Optional argument @var{nodown} non-@code{nil} means don't +check whether @var{window} and its subwindows can be resized. +@end defun + +The function @code{window-resizable} does not change any window sizes. +The following function does: + +@defun resize-window window delta &optional horizontal ignore +This function resizes @var{window} vertically by @var{delta} lines. The +argument @var{window} can denote an arbitrary window and defaults to the +selected one. An attempt to resize the root window of a frame will +raise an error. + +Second argument @var{delta} a positive number means @var{window} shall +be enlarged by @var{delta} lines. If @var{delta} is negative, that +means @var{window} shall be shrunk by -@var{delta} lines. + +Optional argument @var{horizontal} non-@code{nil} means to resize +@var{window} horizontally by @var{delta} columns. In this case a +positive @var{delta} means enlarge @var{window} by @var{delta} columns. +A negative @var{delta} means @var{window} shall be shrunk by +-@var{delta} columns. + +Optional argument @var{ignore} has the same meaning as for the function +@code{window-resizable} above. + +This function resizes other windows proportionally and never deletes any +windows. If only the low (right) edge of @var{window} shall be moved, +the function @code{adjust-window-trailing-edge} described below should +be used. +@end defun + +The next four commands are simple interfaces to @code{resize-window}. +They always operate on the selected window, never delete any window, and +always raise an error when resizing would violate a restriction imposed +by @code{window-min-height}, @code{window-min-width}, or +@code{window-size-fixed}. + +@deffn Command enlarge-window delta &optional horizontal +This function makes the selected window @var{delta} lines taller. +Interactively, if no argument is given, it makes the selected window one +line taller. If optional argument @var{horizontal} is non-@code{nil}, +it makes the selected window wider by @var{delta} columns. If +@var{delta} is negative, it shrinks the selected window by -@var{delta} +lines or columns. The return value is @code{nil}. +@end deffn + +@deffn Command enlarge-window-horizontally delta +This function makes the selected window @var{delta} columns wider. +Interactively, if no argument is given, it makes the selected window one +column wider. +@end deffn + +@deffn Command shrink-window delta &optional horizontal +This function makes the selected window @var{delta} lines smaller. +Interactively, if no argument is given, it makes the selected window one +line smaller. If optional argument @var{horizontal} is non-@code{nil}, +it makes the selected window narrower by @var{delta} columns. If +@var{delta} is negative, it enlarges the selected window by -@var{delta} +lines or columns. The return value is @code{nil}. +@end deffn + +@deffn Command shrink-window-horizontally delta +This function makes the selected window @var{delta} columns narrower. +Interactively, if no argument is given, it makes the selected window one +column narrower. +@end deffn + +@defun adjust-window-trailing-edge window delta &optional horizontal +Move @var{window}'s bottom edge by @var{delta} lines. Optional +argument @var{horizontal} non-@code{nil} means move @var{window}'s +right edge by @var{delta} columns. @var{window} defaults to the +selected window. + +If the edge can't be moved by @var{delta} lines, move it as far as +possible in the desired direction. @end defun - @deffn Command fit-window-to-buffer &optional window max-height min-height ++@deffn Command fit-window-to-buffer &optional window max-height min-height override +This command makes @var{window} the right height to display its +contents exactly. The default for @var{window} is the selected window. + +The optional argument @var{max-height} specifies the maximum height the +window is allowed to be; @code{nil} means use the maximum permissible +height of a window on @var{window}'s frame. The optional argument +@var{min-height} specifies the minimum height for the window; @code{nil} +means use @code{window-min-height}. All these height values include the +mode line and/or header line. + ++If the optional argument @var{override} is non-@code{nil}, this means to ++ignore any restrictions imposed by @code{window-min-height} and ++@code{window-min-width} on the size of @var{window}. ++ +This function returns non-@code{nil} if it orderly resized @var{window}, +and @code{nil} otherwise. +@end deffn + +@deffn Command shrink-window-if-larger-than-buffer &optional window +This command shrinks @var{window} vertically to be as small as possible +while still showing the full contents of its buffer---but not less than +@code{window-min-height} lines. The argument @var{window} must denote +a live window and defaults to the selected one. + +However, this command does nothing if the window is already too small to +display the whole text of the buffer, or if part of the contents are +currently scrolled off screen, or if the window is not the full width of +its frame, or if the window is the only window in its frame. + +This command returns non-@code{nil} if it actually shrank the window +and @code{nil} otherwise. +@end deffn + +@cindex balancing window sizes +Emacs provides two functions to balance windows, that is, to even out +the sizes of windows on the same frame. The minibuffer window and +fixed-size windows are not resized by these functions. + +@deffn Command balance-windows &optional window-or-frame +This function balances windows in a way that gives more space to +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. +@end deffn + +@deffn Command balance-windows-area +This function attempts to give all windows on the selected frame +approximately the same share of the screen area. This means that +full-width or full-height windows are not given more space than other +windows. +@end deffn + +@cindex maximizing windows +The following function can be used to give a window the maximum possible +size on its frame. + +@deffn Command maximize-window &optional window +This function maximizes @var{window}. More precisely, this makes +@var{window} as large as possible without resizing its frame or deleting +other windows. @var{window} can be any window and defaults to the +selected one. +@end deffn + +@cindex minimizing windows +To make a window as small as possible without deleting it the +following function can be used. + +@deffn Command minimize-window &optional window +This function minimizes @var{window}. More precisely, this makes +@var{window} as small as possible without deleting it or resizing its +frame. @var{window} can be any window and defaults to the selected one. +@end deffn + @node Splitting Windows @section Splitting Windows @cindex splitting windows @@@ -1470,824 -490,289 +1474,830 @@@ consider as with @code{next-window}, se @cindex conditional selection of windows @defun get-window-with-predicate predicate &optional minibuf all-frames default This function returns a window satisfying @var{predicate}. It cycles -through all visible windows using @code{walk-windows} (@pxref{Cyclic -Window Ordering}), calling @var{predicate} on each one of them with that -window as its argument. The function returns the first window for which -@var{predicate} returns a non-@code{nil} value; if that never happens, -it returns @var{default} (which defaults to @code{nil}). +through all visible windows calling @var{predicate} on each one of them +with that window as its argument. The function returns the first window +for which @var{predicate} returns a non-@code{nil} value; if that never +happens, it returns @var{default} (which defaults to @code{nil}). The optional arguments @var{minibuf} and @var{all-frames} specify the -set of windows to include in the scan. See the description of -@code{next-window} in @ref{Cyclic Window Ordering}, for details. +set of windows to investigate. See the description of +@code{next-window} for details. @end defun -@node Cyclic Window Ordering -@comment node-name, next, previous, up -@section Cyclic Ordering of Windows -@cindex cyclic ordering of windows -@cindex ordering of windows, cyclic -@cindex window ordering, cyclic +@node Buffers and Windows +@section Buffers and Windows +@cindex examining windows +@cindex windows, controlling precisely +@cindex buffers, controlled in windows - When you use the command @kbd{C-x o} (@code{other-window}) to select -some other window, it moves through the windows on the screen in a -specific order. For any given configuration of windows, this order -never varies. It is called the @dfn{cyclic ordering of windows}. +To find out which buffer is displayed in a given window the following +function is used. - For a particular frame, this ordering generally goes from top to -bottom, and from left to right. But it may go down first or go right -first, depending on the order in which windows were split. +@defun window-buffer &optional window +This function returns the buffer that @var{window} is displaying. The +argument @var{window} can be any window and defaults to the selected +one. If @var{window} is an internal window, this function returns +@code{nil}. +@end defun - If the first split was vertical (into windows one above each other), -and then the subwindows were split horizontally, then the ordering is -left to right in the top of the frame, and then left to right in the -next lower part of the frame, and so on. If the first split was -horizontal, the ordering is top to bottom in the left part, and so on. -In general, within each set of siblings at any level in the window tree -(@pxref{Window Tree}), the order is left to right, or top to bottom. +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. -@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 default for @var{window} is the -selected window. +@defun set-window-buffer window buffer-or-name &optional keep-margins +This function makes @var{window} display @var{buffer-or-name} and +returns @code{nil}. The argument @var{window} has to denote a live +window and defaults to the selected one. The argument +@var{buffer-or-name} must specify a buffer or the name of an existing +buffer. -The value of the optional argument @var{minibuf} specifies whether the -minibuffer is included in the window order. Normally, when -@var{minibuf} is @code{nil}, the minibuffer is included only if it is -currently ``active''; this matches the behavior of @kbd{C-x o}. (The -minibuffer window is active while the minibuffer is in use; see -@ref{Minibuffers}.) +Normally, displaying @var{buffer-or-name} in @var{window} resets the +window's position, display margins, fringe widths, and scroll bar +settings based on the local variables of the specified buffer. However, +if the optional argument @var{keep-margins} is non-@code{nil}, display +margins and fringe widths of @var{window} remain unchanged. +@xref{Fringes}. -If @var{minibuf} is @code{t}, the cyclic ordering includes the -minibuffer window even if it is not active. If @var{minibuf} is neither -@code{t} nor @code{nil}, the minibuffer window is not included even if -it is active. +@code{set-window-buffer} is the fundamental primitive for changing which +buffer is displayed in a window, and all ways of doing that call this +function. Neither the selected window nor the current buffer are +changed by this function. -The optional argument @var{all-frames} specifies which frames to -consider. Here are the possible values and their meanings: +@code{set-window-buffer} signals an error when @var{window} is +@dfn{strongly} dedicated to its buffer (@pxref{Dedicated Windows}) and +does not already display @var{buffer-or-name}. -@table @asis -@item @code{nil} -Consider all the windows in @var{window}'s frame, plus the minibuffer -used by that frame even if it lies in some other frame. If the -minibuffer counts (as determined by @var{minibuf}), then all windows on -all frames that share that minibuffer count too. +This function runs @code{window-scroll-functions} before running +@code{window-configuration-change-hook}, see @ref{Window Hooks}. +@end defun + +@defvar buffer-display-count +This buffer-local variable records the number of times a buffer has been +displayed in a window. It is incremented each time +@code{set-window-buffer} is called for the buffer. +@end defvar + +@defvar buffer-display-time +This variable records the time at which a buffer was last made visible +in a window. It is always local in each buffer; each time +@code{set-window-buffer} is called, it sets this variable to +@code{(current-time)} in the specified buffer (@pxref{Time of Day}). +When a buffer is first created, @code{buffer-display-time} starts out +with the value @code{nil}. +@end defvar + +@defun get-buffer-window &optional buffer-or-name all-frames +This function returns a window displaying @var{buffer-or-name}, or +@code{nil} if there is none. If there are several such windows, then +the function returns the first one in the cyclic ordering of windows, +starting from the selected window, @xref{Cyclic Window Ordering}. + +The argument @var{BUFFER-OR-NAME} may be a buffer or a buffer name and +defaults to the current buffer. The optional argument @var{all-frames} +specifies which windows to consider: + +@itemize @bullet +@item +@code{nil} means consider windows on the selected frame. +@item +@code{t} means consider windows on all existing frames. +@item +@code{visible} means consider windows on all visible frames. +@item +0 means consider windows on all visible or iconified frames. +@item +A frame means consider windows on that frame only. +@end itemize + +Observe that the behavior of @code{get-buffer-window} may differ from +that of @code{next-window} (@pxref{Cyclic Window Ordering}) when +@var{all-frames} equals @code{nil} or any value not listed here. +Perhaps we will change @code{get-buffer-window} in the future to make it +compatible with the other functions. +@end defun + +@defun get-buffer-window-list &optional buffer-or-name minibuf all-frames +This function returns a list of all windows currently displaying +@var{buffer-or-name}. The argument @var{buffer-or-name} may be a buffer +or the name of an existing buffer and defaults to the current buffer. + +The two remaining arguments work like the same-named arguments of +@code{next-window} (@pxref{Cyclic Window Ordering}); they are @emph{not} +like the optional arguments of @code{get-buffer-window}. +@end defun + +The following command removes a buffer from all windows showing it. + +@deffn Command replace-buffer-in-windows &optional buffer-or-name +This function replaces @var{buffer-or-name} in all windows displaying it +with some other buffer. It uses @code{switch-to-prev-buffer}, see +below, to choose that other buffer which is usually the last buffer +displayed before @var{buffer-or-name} in the respective window. + +The argument @var{buffer-or-name} may be a buffer or the name of an +existing buffer and defaults to the current buffer. + +If a window displaying @var{buffer-or-name} is dedicated +(@pxref{Dedicated Windows}), and is not the only window on its frame, +that window is deleted. If that window is the only window on its frame +and there are other frames left, the window's frame is deleted too. If +there are no other frames left, some other buffer is displayed in that +window as explained above. + +This function returns @code{nil}. +@end deffn + + When @code{replace-buffer-in-windows} has to show another buffer in a +window, it tries to pick the buffer shown there before. For this +purpose each window remembers the buffers it has displayed earlier and +the order in which these buffers have been removed from it. + +The list of @dfn{previous buffers} of a window is an association list +where each entry specifies a buffer, the last start position of that +buffer in the window (@pxref{Window Start and End}) and the last +position of that buffer's point in the window (@pxref{Window Point}). +This list is ordered by the times of the removal of the respective +buffers from the window. In particular, the first element of the list +references the buffer removed most recently. The function +@code{set-window-buffer} pushes an entry for the old buffer of its +window argument on that list before it shows its buffer argument in the +window. + +The list of @dfn{next buffers} of a window is a list of buffers that +have been recently re-shown by the function @code{switch-to-prev-buffer} +and is used to avoid that that function switches to such a buffer again +before showing other interesting buffers. + +The lists of previous and next buffers and the global buffer list +(@pxref{The Buffer List}) allow to effectively display all buffers in a +window while giving preference to the buffers previously shown in that +window. The commands used for this purpose are +@code{switch-to-prev-buffer} and @code{switch-to-next-buffer} described +below. + +The following functions directly operate on the lists of previous and +next buffers. + +@defun window-prev-buffers &optional window +This function returns an alist specifying the buffers previously shown +in @var{window} together with their window start and point positions. +The argument @var{window} must be a live window and defaults to the +selected one. +@end defun + +@defun set-window-prev-buffers window prev-buffers +This function sets @var{window}'s previous buffers to the value of +@var{prev-buffers}. The argument @var{window} must be a live window and +defaults to the selected one. This function returns +@var{prev-buffers}. + +If non-@code{nil}, @var{prev-buffers} must specify an alist of triples +specifying a buffer and two markers for that buffer's start and point +position in @var{window}. +@end defun + +@defun window-next-buffers &optional window +This function returns the list of buffers recently re-shown in +@var{window}. The argument @var{window} must be a live window and +defaults to the selected one. +@end defun + +@defun set-window-next-buffers window next-buffers +This function sets @var{window}'s next buffers to @var{next-buffers}. +@var{window} must be a live window and defaults to the selected one. +This fucntion returns @var{next-buffers}. + +If non-@code{nil}, the argument @var{next-buffers} should specify a list +of buffers that shall be preferably not shown by the command +@code{switch-to-prev-buffer}, see below. +@end defun + +The following command is used by @code{replace-buffer-in-windows}, +@code{bury-buffer} and @code{quit-restore-window} to show another buffer +in a window. It can be also used interactively to cycle through the +list of all buffers in a window, preferably showing the buffers recently +shown (but not buried or killed) in that window. + +@deffn Command switch-to-prev-buffer &optional window bury-or-kill +This function displays the previous buffer in @var{window}. The +argument @var{window} must be a live window and defaults to the selected +one. If the optional argument @var{bury-or-kill} is non-@code{nil}, +this means that the buffer currently shown in @var{window} is about to +be buried or killed and consequently shall not be switched to in future +invocations of this command. + +The previous buffer is usually the buffer shown before the buffer +currently shown in @var{window}. However, a buffer that has been buried +or killed or has been already shown by a recent invocation of +@code{switch-to-prev-buffer} does not qualify as previous buffer. + +If repeated invocations of this command have already shown all buffers +previously shown in @var{window}, further invocations will show buffers +from the global buffer list starting with the buffer returned by +@code{last-buffer} (@pxref{The Buffer List}). +@end deffn + +The following command can be used to undo the effect of the last undone +@code{switch-to-prev-buffer} command. + +@deffn Command switch-to-next-buffer &optional window +This functions switches to the next buffer in @var{window} thus undoing +the effect of the last @code{switch-to-prev-buffer} command in +@var{window}. The argument @var{window} must be a live window and +defaults to the selected one. + +If there is no recent invocation of a @code{switch-to-prev-buffer} that +can be undone, @code{switch-to-next-buffer} will try to show the first +buffer from the global buffer list as returned by @code{other-buffer} +(@pxref{The Buffer List}). +@end deffn + + Together, @code{switch-to-prev-buffer} and +@code{switch-to-next-buffer} permit to navigate the global buffer list +much like @code{bury-buffer} and @code{unbury-buffer}. In contrast with +the latter, however, they may show a buffer even if it is already shown +in another window. Moreover, they try to restore the window specific +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 + +The basic facility to choose a window and display a buffer in it is +@code{display-buffer}. Many higher-level functions like +@code{pop-to-buffer} (@pxref{Switching Buffers}) and +@code{with-output-to-temp-buffer} (@pxref{Temporary Displays}) work by +calling this function. Here we describe how @code{display-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 +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 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 +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. - @end deffn ++The optional third argument @var{ignore} is ignored. ++@end deffn + +Precisely how @code{display-buffer} finds or creates a window depends on +the @var{specifiers} argument and the two 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. + +@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: + +@itemize @bullet +@item +@code{same-window} stands for the selected window, + +@item +@code{same-frame} for a window on the selected frame, + +@item +@code{other-frame} for a window on another frame. +@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. + + The remaining buffer display specifiers are cons cells or lists whose +@sc{car} is one of the symbols listed next. + +@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. + +@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: + +@itemize @minus +@item +@code{never} means to never reuse a window showing the buffer. + +@item +@code{nil} means to stay on the selected frame. + +@item +@code{visible} means to consider visible frames only. + +@item +0 (the number zero) means that any such window must be on a visible or +iconified frame. + +@item +@code{t} means the window may be on an arbitrary frame, including +invisible ones. +@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. + +@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 + ++@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. ++ +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. + +@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. + + 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. + + 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 + +@example +@code{(new-window (largest . nil) (lru . nil))} +@end example + +in order to try splitting the largest window first and, if that fails, +the least recently used one. + +@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 new window will be made if and only if it - can be made at least as large as specified by the number. - - Note that @code{min-height} and @code{min-width} (as well as the - specifiers @code{max-height} and @code{max-width} below) restrict the - size of new windows only. Reusing a window or making a new frame is not - affected by these specifiers. - - @item - The symbols @code{max-height} and @code{max-width}. In this case, the - @sc{cdr} must be a number specifying the maximum height or width of any - new window displaying the buffer. An integer number specifies the - maximum number of lines or columns of the new window. A floating point - number gives the maximum fraction of the window's size with respect to - the frame's root window. - - Setting @code{min-height} and @code{max-height} to the same value will - make a window of exactly that height. Conversely, setting - @code{min-width} and @code{max-width} to the same value will produce a - window of that width. Note, however, that specifying the exact size of - a new window might reduce the number of candidate windows that can be - suitably split. ++can be made at least as large as specified by the number. Reusing a ++window or making a new frame are not affected by these specifiers. + +@item +The symbol @code{split-unsplittable-frame} with a non-@code{nil} - @sc{cdr} allows to split a window on an unsplittable frame. This ++@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. ++them (@pxref{Buffer Parameters}). + +@item - @code{adjust-height} with the following interpretations for the - @sc{cdr}: ++@code{adjust-height} with the following semantics for the @sc{cdr}: + +@itemize @minus +@item - @code{nil} means do not adjust the height of a new window. ++@code{nil} means do not adjust the height of the new window. ++ ++@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. ++ ++@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}. ++@end itemize + +@item - The symbol @code{even-window-heights} means to even the height of the - window used for displaying the buffer with the height of the selected - window, provided these windows are full-width and appear above each - other. ++@code{adjust-width} with the following semantics for the @sc{cdr}: + ++@itemize @minus +@item - The symbols @code{shrink-window-if-larger-than-buffer} and - @code{fit-window-to-buffer} specify that the new window shall be - adjusted by the homonymous function. ++@code{nil} means do not adjust the width of the new window. + - Observe that a non-@code{nil} value for @code{adjust-height} can - override restrictions given by @code{min-height}, @code{min-width}, - @code{max-height}, and @code{max-width} specifiers. ++@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. + ++@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. +@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. +@end itemize + +The following specifiers are useful when the location is specified as +@code{other-frame}: + +@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. + +@item +@code{graphic-only} with a non-@code{nil} @sc{cdr} means that a new +frame shall be made on graphic displays only. + +@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. + +@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. +@end itemize + + It's also 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: + +@itemize @bullet +@item +@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 + +@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} +second argument to @code{display-buffer}. For any +@code{display-buffer-names} 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}. +@end defopt -@item @code{t} -Consider all windows in all existing frames. +@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. -@item @code{visible} -Consider all windows in all visible frames. (To get useful results, you -must ensure @var{window} is in a visible frame.) +This variable has the following default value: -@item 0 -Consider all windows in all visible or iconified frames. +@example +(((".*") + same-frame + (reuse-buffer-window) ++ (adjust-height . even-window-sizes) + (largest) (lru) + (min-height . 24) (min-width . 60) - (adjust-height . even-window-heights) + other-frame + (reuse-buffer-window . visible) + (graphic-only . t) + (popup-frame-alist + (height . 24) (width . 80) (unsplittable . t)))) +@end example -@item a frame -Consider all windows on that frame. +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 -@item anything else -Consider precisely the windows in @var{window}'s frame, and no others. -@end table + 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. Suppose +the value of @code{display-buffer-names} has been specified as -This example assumes there are two windows, both displaying the -buffer @samp{windows.texi}: +@example +((("*text*") + same-frame (reuse-buffer-window . none) + (new-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 @example -@group -(selected-window) - @result{} # -@end group -@group -(next-window (selected-window)) - @result{} # -@end group -@group -(next-window (next-window (selected-window))) - @result{} # -@end group +(display-buffer "*text*" 'same-window) @end example -@end defun -@defun previous-window &optional window minibuf all-frames -This function returns the window preceding @var{window} in the cyclic -ordering of windows. The other arguments specify which windows to -include in the cycle, as in @code{next-window}. -@end defun +Since the entry from @code{display-buffer-names} 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. + + 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 +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 +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 +@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. + + In case you observe any unexpected behavior of @code{display-buffer} +keep in mind the following issues: -@deffn Command other-window count &optional all-frames -This function selects another window in the cyclic ordering of windows. -@var{count} specifies the number of windows to skip in the ordering, -starting with the selected window, before making the selection. If -@var{count} is a positive number, it skips @var{count} windows forwards. -@var{count} negative means skip @minus{}@var{count} windows backwards. -If @var{count} is zero, it does not skip any window, thus re-selecting -the selected window. In an interactive call, @var{count} is the numeric -prefix argument. +@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. -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}. -@end deffn +@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 +@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 +platforms. -@c Emacs 19 feature -@defun walk-windows proc &optional minibuf all-frames -This function cycles through all windows. It calls the function -@code{proc} once for each window, with the window as its sole -argument. +@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. +@end itemize -The optional arguments @var{minibuf} and @var{all-frames} specify the -set of windows to include in the walk. See @code{next-window}, above, -for details. -@end defun + Next we describe how to transcribe the buffer display options of +Emacs 23 with @code{display-buffer-names} and +@code{display-buffer-regexps}. -@defun window-list &optional frame minibuf window -This function returns a list of all windows on @var{frame}, starting -with @var{window}. The default for @var{frame} is the selected frame; -the default for @var{window} is the selected window. +@itemize @bullet +@item +For @code{display-buffer-function} supply the function named there as +location specifier. -The value of @var{minibuf} specifies if the minibuffer window shall be -included in the result list. If @var{minibuf} is @code{t}, the result -always includes the minibuffer window. If @var{minibuf} is @code{nil} -or omitted, that includes the minibuffer window if it is active. If -@var{minibuf} is neither @code{nil} nor @code{t}, the result never -includes the minibuffer window. -@end defun +@item +@code{same-window-buffer-names} and @code{same-window-regexps} are +handled by adding a @code{same-window} specifier. -@node Buffers and Windows -@section Buffers and Windows -@cindex examining windows -@cindex windows, controlling precisely -@cindex buffers, controlled in windows +@item +For @code{display-buffer-reuse-frames} use the +@code{reuse-buffer-window} specifier with an appropriate @sc{cdr}. - This section describes low-level functions to examine windows or to -display buffers in windows in a precisely controlled fashion. -@iftex -See the following section for -@end iftex -@ifnottex -@xref{Displaying Buffers}, for -@end ifnottex -related functions that find a window to use and specify a buffer for it. -The functions described there are easier to use, but they employ -heuristics in choosing or creating a window; use the functions described -here when you need complete control. +@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. -@defun set-window-buffer window buffer-or-name &optional keep-margins -This function makes @var{window} display @var{buffer-or-name} as its -contents. It returns @code{nil}. The default for @var{window} is the -selected window. The argument @var{buffer-or-name} must specify a -buffer or the name of an existing buffer. +@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. -@code{set-window-buffer} is the fundamental primitive for changing which -buffer is displayed in a window, and all ways of doing that call this -function. +@item +@code{special-display-frame-alist} is now handled by the +@code{popup-frame-alist} specifier. -@example -@group -(set-window-buffer (selected-window) "foo") - @result{} nil -@end group -@end example +@item +To handle @code{pop-up-frames} use the @code{other-frame} location +specifier and the @code{graphic-only} specifier. -Normally, displaying @var{buffer-or-name} in @var{window} resets the -window's position, display margins, fringe widths, and scroll bar -settings based on the local variables of that buffer. -However, if @var{keep-margins} is non-@code{nil}, display margins and -fringe widths of @var{window} remain unchanged. @xref{Fringes}. +@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. -@code{set-window-buffer} signals an error when @var{window} is -@dfn{strongly} dedicated to its buffer (@pxref{Dedicated Windows}) and -does not already display @var{buffer-or-name}. +@item +@code{pop-up-frame-alist} has become the homonymous specifier. -Note that this function runs @code{window-scroll-functions} before -running @code{window-configuration-change-hook}. -@end defun +@item +@code{pop-up-windows} is handled by the @code{new-window} specifier. -@defvar buffer-display-count -This buffer-local variable records the number of times a buffer has been -displayed in a window. It is incremented each time -@code{set-window-buffer} is called for the buffer. -@end defvar +@item +@code{split-window-preferred-function} can be specified as second +argument of window / side pairings. The semantics of the argument have +not changed. -@defun window-buffer &optional window -This function returns the buffer that @var{window} is displaying. The -default for @var{window} is the selected window. +@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. -@example -@group -(window-buffer) - @result{} # -@end group -@end example +@item +@code{even-window-heights} is handled by setting the @sc{cdr} of the - @code{adjust-height} specifier to @code{even-window-heights}. ++@code{even-window-sizes} specifier to a non-@code{nil} value. +@end itemize + +The following two functions are simple variations of +@code{display-buffer}. + +@defun display-buffer-same-window &optional buffer-or-name +This function is like @code{display-buffer} but preferably displays the +buffer specified by @var{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 some other buffer. @end defun -@defun get-buffer-window &optional buffer-or-name all-frames -This function returns a window currently displaying -@var{buffer-or-name}, or @code{nil} if there is none. If there are -several such windows, then the function returns the first one in the -cyclic ordering of windows, starting from the selected window. -@xref{Cyclic Window Ordering}. +@defun display-buffer-other-window &optional buffer-or-name +This function is like @code{display-buffer} but tries to avoid using the +selected window. The selected window will be used if and only if there +is no other choice. +@end defun -The argument @var{BUFFER-OR-NAME} may be a buffer or a buffer name and -defaults to the current buffer. The optional argument @var{all-frames} -specifies which windows to consider: +The following variable conveys some information about the last +@code{display-buffer} action performed and is used mainly when popping +up a @samp{*Help*} buffer. + +@defvar display-buffer-window +After @code{display-buffer} has shown a buffer in some window this +variable should be a cons cell whose @sc{car} denotes the window used to +display the buffer. The @sc{cdr} is either @code{new-window} (which +means a new window has been made), @code{new-frame} (a new frame has +been created), @code{reuse-buffer-window} (a window showing the buffer +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. +@end defvar + +The command described next allows to quit the window chosen by +@code{display-buffer} and restore the previous state without undoing +changes to the window configuration that happend @emph{after} +@code{display-buffer} was called. A more drastic solution is to save +the window configuration before calling @code{display-buffer} and +eventually restoring the saved configuration, @ref{Window +Configurations}. That solution sometimes has the undesirable +side-effect that all changes that happened after the configuration was +saved are undone too. + +@deffn Command quit-restore-window &optional window kill +This command ``quits'' @var{window} restoring its previous contents if +possible. The argument @var{window} must be a live window and defaults +to the selected one. This function always returns @code{nil}. + +According to information stored in @var{window}'s @code{quit-restore} +window parameter (@pxref{Window Parameters}) this function performs one +of the following actions. @itemize @bullet + @item -@code{nil} means consider windows on the selected frame. -@item -@code{t} means consider windows on all existing frames. +Delete @var{window} and its frame. This action is useful when +@var{window} was created on a standalone frame and there are other +frames left. + @item -@code{visible} means consider windows on all visible frames. +Delete @var{window}. This action is usually taken when @var{window} was +obtained by splitting some existing window. + @item -0 means consider windows on all visible or iconified frames. +Restore the buffer previously displayed in @var{window}. This action +is taken when @var{window} was temporarily reused for displaying some +other buffer. + @item -A frame means consider windows on that frame only. +Make @var{window} display some other buffer. This action is usually +taken when the three preceding ones are not applicable. @end itemize -Observe that the behavior of @code{get-buffer-window} may differ from -that of @code{next-window} (@pxref{Cyclic Window Ordering}) when -@var{all-frames} equals @code{nil} or any value not listed here. -Perhaps we will change @code{get-buffer-window} in the future to make it -compatible with the other functions. -@end defun - -@defun get-buffer-window-list &optional buffer-or-name minibuf all-frames -This function returns a list of all windows currently displaying -@var{buffer-or-name}. The argument @var{buffer-or-name} may be a buffer -or the name of an existing buffer and defaults to the current buffer. - -The two remaining arguments work like the same-named arguments of -@code{next-window}; they are @emph{not} like the optional arguments of -@code{get-buffer-window}. -@end defun - -@defvar buffer-display-time -This variable records the time at which a buffer was last made visible -in a window. It is always local in each buffer; each time -@code{set-window-buffer} is called, it sets this variable to -@code{(current-time)} in the specified buffer (@pxref{Time of Day}). -When a buffer is first created, @code{buffer-display-time} starts out -with the value @code{nil}. -@end defvar +If the optional argument @var{kill} is non-@code{nil}, this means in +addition kill @var{window}'s buffer. If @var{kill} is @code{nil}, this +simply puts @var{window}'s buffer at the end of the buffer list. +Interactively, @var{kill} is the prefix argument. +@end deffn -@node Displaying Buffers -@section Displaying Buffers in Windows +@node Switching Buffers +@section Switching to a Buffer in Some Window @cindex switching to a buffer -@cindex displaying a buffer +@cindex popping to a buffer - In this section we describe convenient functions that choose a window -automatically and use it to display a specified buffer. These functions -can also split an existing window in certain circumstances. We also -describe variables that parameterize the heuristics used for choosing a -window. -@iftex -See the preceding section for -@end iftex -@ifnottex -@xref{Buffers and Windows}, for -@end ifnottex -low-level primitives that give you more precise control. All of these -functions work by calling @code{set-window-buffer}. - - Do not use the functions in this section in order to make a buffer +In this section we describe convenient functions for switching to a +specified buffer in some window. These functions can also split an +existing window or create a new frame in certain circumstances. In any +case, the window chosen becomes the selected window and the buffer +current. + + Do not use the functions in this section in order to make a buffer current so that a Lisp program can access or modify it; they are too drastic for that purpose, since they change the display of buffers in windows, which would be gratuitous and surprise the user. Instead, use diff --cc lisp/ChangeLog index fb1e1b0a24d,239f50c3c80..de7933d4478 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@@ -1,21 -1,146 +1,191 @@@ ++2010-11-04 Martin Rudalics ++ ++ * window.el (display-buffer-names, display-buffer-regexps): Make ++ even-window-sizes a seperate specifier. Allow numbers and ++ functions in the cdr of the adjust-height specifier and remove ++ even-window-heights and the special handling of ++ fit-window-to-buffer and shrink-window-if-larger-than-buffer. ++ Add new specifier adjust-width similar to adjust-height. ++ (display-buffer-normalize-specifiers-1): Fix typo. ++ (display-buffer-even-sizes, display-buffer-adjust-height) ++ (display-buffer-adjust-width): New functions to handle size ++ adjustment of new window. ++ (display-buffer-adjust-heights): Remove. ++ (display-buffer-in-window): Don't call ++ display-buffer-adjust-heights any more. ++ (display-buffer-in-lru-buffer-window) ++ (display-buffer-in-lru-window): Call display-buffer-even-sizes. ++ (display-buffer-in-new-window): Use functionp instead of ++ fboundp. Call display-buffer-adjust-height and ++ display-buffer-adjust-width. ++ (display-buffer): Use functionp instead of fboundp. ++ (fit-window-to-buffer): Rename argument IGNORE to OVERRIDE. ++ ++ * progmodes/compile.el (compilation-start) ++ (compilation-goto-locus): Use adjust-height specifier in ++ display-buffer calls. ++ +2010-11-02 Martin Rudalics + + * window.el (display-buffer-names): Describe `not-this-window' and + `not-this-frame' specifiers in doc-string. + (display-buffer-in-lru-buffer-window) + (display-buffer-in-lru-window, display-buffer-in-new-window): + Handle `not-this-window' and `not-this-frame' specifiers when + their cdr specifies a window or a frame. + (display-buffer): Explain in doc-string that the cdr of the + `not-this-window' and `not-this-frame' specifiers argument can + name a window. + + * progmodes/compile.el (compilation-start): When displaying outbuf + directly pass height parameters. + (compilation-goto-locus): Use specifiers in display-buffer and + pop-to-buffer calls. Simplify. + (compilation-find-file): Use specifiers in display-buffer calls. + + 2010-11-02 Chong Yidong + + * emacs-lisp/package.el (package-initialize): Ensure that + obsoleted built-in packages are not in package-activated-list + during activation. + (describe-package-1): Make the "installed" status override + "built-in". + + 2010-11-01 Vinicius Jose Latorre + + * subr.el (version-separator, version-regexp-alist): Remove '*' + from docstring. + (version-list-<=, version<=, version=): Doc fix. + + 2010-11-01 Kenichi Handa + + * faces.el (glyphless-char): Inherit underline for tty. + + 2010-11-01 Kenichi Handa + + Implement various display methods for glyphless characters. + + * international/characters.el (char-acronym-table): New variable. + (glyphless-char-control): New variable. + (update-glyphless-char-display): New funciton. + + * faces.el (glyphless-char): New face. + + 2010-11-01 Glenn Morris + + * calendar/holidays.el (general-holidays, oriental-holidays) + (local-holidays, other-holidays, hebrew-holidays, christian-holidays) + (islamic-holidays, bahai-holidays, solar-holidays): Move aliases before + the definitions of their targets. + + * emacs-lisp/smie.el (smie): New custom group. + (smie-blink-matching-inners, smie-indent-basic): Add :group. + + * faces.el (xw-defined-colors, x-setup-function-keys): + * mouse-sel.el (x-select-text): + * term/w32console.el (x-setup-function-keys): Update declarations. + + * progmodes/ruby-mode.el (ruby-syntax-propertize-heredoc): Declare. + + * textmodes/ispell.el (comment-add): Declare. + + * net/gnutls.el (gnutls-boot, gnutls-errorp, gnutls-error-string): + Declare. + + * info.el (finder-keywords-hash, package-alist): Declare. + + 2010-11-01 Chong Yidong + + * finder.el (finder-compile-keywords): Don't use intern-soft, + since package names may not yet exist in the obarray. + + 2010-11-01 Chong Yidong + + * vc/vc-arch.el (vc-arch-checkin): + * vc/vc-cvs.el (vc-cvs-checkin): + * vc/vc-mtn.el (vc-mtn-checkin): + * vc/vc-rcs.el (vc-rcs-checkin): + * vc/vc-sccs.el (vc-sccs-checkin): + * vc/vc-svn.el (vc-svn-checkin): Remove optional extra arg, unused + since 2010-04-21 commit by Stefan Monnier. + + 2010-11-01 Glenn Morris + + * emacs-lisp/bytecomp.el (byte-recompile-file): Fix previous change. + + * startup.el (package-enable-at-startup, package-initialize): + Silence compiler. + + * progmodes/ada-mode.el (ada-font-lock-syntactic-keywords): + Silence compiler. + + 2010-10-31 Julien Danjou + + * emacs-lisp/bytecomp.el (byte-recompile-file): New fun (bug#7297). + (byte-recompile-directory): + * emacs-lisp/lisp-mode.el (emacs-lisp-byte-compile-and-load): + Use `byte-recompile-file'. + + 2010-10-31 Glenn Morris + + * cus-start.el: Handle standard values via a keyword. + Only set version property if specified. + (cursor-in-non-selected-windows, menu-bar-mode) + (tool-bar-mode, show-trailing-whitespace): + Do not specify standard values. + (transient-mark-mode, temporary-file-directory): Use :standard. + + 2010-10-31 Jan Djärv + + * term/x-win.el (x-get-selection-value): New function that gets + PRIMARY with type as specified in x-select-request-type. (Bug#6802). + + 2010-10-31 Michael Albinus + + * net/tramp.el (tramp-handle-insert-file-contents): For root, + preserve owner and group when editing files. (Bug#7289) + + 2010-10-31 Glenn Morris + + * speedbar.el (speedbar-mode): + * play/fortune.el (fortune-in-buffer, fortune): + * play/gomoku.el (gomoku-mode): + * play/landmark.el (lm-mode): + * textmodes/bibtex.el (bibtex-validate, bibtex-validate-globally): + Replace inappropriate uses of toggle-read-only. (Bug#7292) + + * select.el (x-selection): Mark it as an obsolete alias. + + 2010-10-31 Aaron S. Hawley + + * vc/add-log.el (find-change-log): Use derived-mode-p rather than + major-mode (bug#7284). + + 2010-10-31 Glenn Morris + + * menu-bar.el (menu-bar-files-menu): Make it into an actual alias, + rather than just an unused variable that inherits from the real one. + + 2010-10-31 Alan Mackenzie + + * progmodes/cc-cmds.el (c-mask-paragraph): Fix an off-by-1 error. + This fixes bug #7185. + + 2010-10-30 Chong Yidong + + * startup.el (command-line): Search for package directories, and + don't load package.el if none are found. + + * emacs-lisp/package.el (describe-package, list-packages): Call + package-initialize if it has not been called yet. + + 2010-10-30 Alan Mackenzie + + * progmodes/cc-fonts.el (c-font-lock-enum-tail): New function + which fontifies the tail of an enum. + (c-basic-matchers-after): Insert a call to the above new function. + This fixes bug #7264. + 2010-10-30 Glenn Morris * cus-start.el: Add :set properties for minor modes menu-bar-mode, diff --cc lisp/cus-start.el index e6f46e9099e,750b6570158..5d334e57862 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@@ -363,18 -380,14 +378,18 @@@ since it could result in memory overflo (const :tag "Off (nil)" :value nil) (const :tag "Full screen (t)" :value t) (other :tag "Always" 1)) "22.1") - (recenter-redisplay windows - (choice - (const :tag "Never (nil)" :value nil) - (const :tag "Only on ttys" :value tty) - (other :tag "Always" t)) - "23.1") + (recenter-redisplay + windows (choice + (const :tag "Never (nil)" :value nil) + (const :tag "Only on ttys" :value tty) + (other :tag "Always" t)) "23.1") + (window-splits + windows (choice + (const :tag "Standard" :value nil) + (const :tag "Nest" :value nest) + (const :tag "Resize" :value resize)) "24.1") ;; xdisp.c - (show-trailing-whitespace whitespace-faces boolean nil nil + (show-trailing-whitespace whitespace-faces boolean nil :safe booleanp) (scroll-step windows integer) (scroll-conservatively windows integer) diff --cc lisp/progmodes/compile.el index 5a82c6b3b6a,dd30212085e..830e137c5d4 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@@ -1317,18 -1320,8 +1317,17 @@@ Returns the compilation buffer created. (list command mode name-function highlight-regexp)) (set (make-local-variable 'revert-buffer-function) 'compilation-revert-buffer) - (set-window-start outwin (point-min)) + ;; The setup function is called before compilation-set-window-height + ;; so it can set the compilation-window-height buffer locally. + (when compilation-process-setup-function + (funcall compilation-process-setup-function)) + (let ((height (buffer-local-value 'compilation-window-height outbuf))) + ;; Pop up the compilation buffer. + (setq outwin + (display-buffer - outbuf - `(same-frame (min-height . ,height) (max-height . ,height))))) ++ outbuf `(same-frame (adjust-height . ,height))))) + (set-window-start outwin (point-min)) ;; Position point as the user will see it. (let ((desired-visible-point ;; Put it at the end if `compilation-scroll-output' is set. @@@ -2096,27 -2094,37 +2095,26 @@@ displays at the top of the window; ther All arguments are markers. If END-MK is non-nil, mark is set there and overlay is highlighted between MK and END-MK." ;; Show compilation buffer in other window, scrolled to this error. - (let* ((from-compilation-buffer (eq (window-buffer (selected-window)) - (marker-buffer msg))) - ;; Use an existing window if it is in a visible frame. - (pre-existing (get-buffer-window (marker-buffer msg) 0)) - (w (if (and from-compilation-buffer pre-existing) - ;; Calling display-buffer here may end up (partly) hiding - ;; the error location if the two buffers are in two - ;; different frames. So don't do it if it's not necessary. - pre-existing - (let ((display-buffer-reuse-frames t) - (pop-up-windows t)) - ;; Pop up a window. - (display-buffer (marker-buffer msg))))) - (highlight-regexp (with-current-buffer (marker-buffer msg) + (let* ((msg-buffer (marker-buffer msg)) + (mk-buffer (marker-buffer mk)) + (msg-buffer-window + ;; Pop up a window, if possible reusing a window on a + ;; visible or iconified frame. + (let ((height (buffer-local-value + 'compilation-window-height msg-buffer))) + (display-buffer - msg-buffer - `(same-frame (reuse-buffer-window . 0) - (min-height . ,height) (max-height . ,height))))) ++ msg-buffer `(same-frame (reuse-buffer-window . 0) ++ (adjust-height . ,height))))) + (mk-buffer-window + (pop-to-buffer + mk-buffer + ;; Do not use msg-buffer-window. + `(same-frame (not-this-window . ,msg-buffer-window) + (reuse-buffer-window . 0)))) + (highlight-regexp (with-current-buffer msg-buffer ;; also do this while we change buffer - (compilation-set-window w msg) + (compilation-set-window msg-buffer-window msg) compilation-highlight-regexp))) - ;; Ideally, the window-size should be passed to `display-buffer' (via - ;; something like special-display-buffer) so it's only used when - ;; creating a new window. - (unless pre-existing (compilation-set-window-height w)) - - (if from-compilation-buffer - ;; If the compilation buffer window was selected, - ;; keep the compilation buffer in this window; - ;; display the source in another window. - (let ((pop-up-windows t)) - (pop-to-buffer (marker-buffer mk) 'other-window)) - (if (window-dedicated-p (selected-window)) - (pop-to-buffer (marker-buffer mk)) - (switch-to-buffer (marker-buffer mk)))) (unless (eq (goto-char mk) (point)) ;; If narrowing gets in the way of going to the right place, widen. (widen) diff --cc lisp/window.el index e6d2cd74968,45d7875cf20..a06ab993ccf --- a/lisp/window.el +++ b/lisp/window.el @@@ -3602,1702 -547,10 +3602,1790 @@@ specific buffers. )) +;;; Displaying buffers. +(defgroup display-buffer nil + "Displaying buffers in windows." + :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 symbols `min-height' and `min-width'. In this case the 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 - size 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 large as - specified by the number. - - Note that `min-height' and `min-width' \(as well as the - specifiers `max-height' and `max-width' below) restrict the - size of new windows only. Reusing an existing window or making - a new frame is not affected by these specifiers. - - - The symbols `max-height' and `max-width'. In this case the cdr - must be a number specifying the maximum height or width of any - new window displaying the buffer. An integer number specifies - the maximum number of lines or columns of the new window. A - floating point number gives the maximum fraction of the window - size with respect to the frame's root window. - - Setting `min-height' and `max-height' to the same value will - make a window of exactly that height. Conversely, setting - `min-width' and `max-width' to the same value will produce a - window of that width. Note, however, that specifying the exact - size of a new window this way may reduce the number of windows - that can be suitably split. - +- The symbol `split-unsplittable-frame' with a non-nil cdr allows - to split a window on an unsplittable frame. This specifier ++ 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 a new window. ++ - 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. + - - `even-window-heights' means to even the height of the window - used for displaying the buffer with the height of the - selected window provided these windows appear above each - other. ++ - If the 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 are `shrink-window-if-larger-than-buffer' ++ and `fit-window-to-buffer'. + - - The symbols `shrink-window-if-larger-than-buffer' and - `fit-window-to-buffer' specify that the new window shall be - adjusted by the homonymous function. ++- `adjust-width' with the following interpretations for the cdr: + - Observe that a non-nil value may override restrictions given by - the `min-height', `min-width', `max-height', and `max-width' - specifiers. Think of the latter being applied when the new - window is created and `adjust-height' being applied after that - window has been created. ++ - nil means do not adjust the width of the new window. ++ ++ - 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. ++ ++ - `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. ++ ++ - 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. ++ ++ Observe that specifying `adjust-height' or `adjust-width' may ++ override restrictions given by the `min-height' or `min-width' ++ specifiers. + +The specifiers listed next are useful if the location specifier +equals 'other-frame: + +- `not-this-frame' with a non-nil cdr means that the selected + frame shall not be used for displaying the buffer. + +- `graphic-only' with a non-nil cdr means that a new frame shall + be made on graphic displays only. + +- `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. + +- `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. + +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 + +- nil, to not dedicate the window to the buffer, + +- `weak', the window shall be weakly dedicated to its buffer, or + +- 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' +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 +using the location specifiers `same-window' or `other-frame'." + :risky t + :type + '(repeat + :offset 9 + (list + :tag "Association" + (repeat + :tag "Buffer names" + (string :format "%v\n" :size 24)) + (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. + (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))))) + + ;; Same frame. + (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) - (adjust-height . even-window-heights) - (reuse-buffer-window . nil)) ++ (min-height . 24) (min-width . 60)) + :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" :value 12 :size 5)) ++ :tag "Minimum height of new window" :value 12 :size 5)) + (cons + :format "%v\n" + (const :format "" min-width) + (number - :tag "Minimum width" :value 60 :size 5)) - (cons - :format "%v\n" - (const :format "" max-height) - (number - :tag "Maximum height" :value 48 :size 5)) - (cons - :format "%v\n" - (const :format "" max-width) - (number - :tag "Maximum width" :value 120 :size 5)) - (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 "Minimum width of new window" :value 60 :size 5)) + (cons + :format "%v" + (const :format "" adjust-height) + (choice - :tag "Adjust window height" :value even-window-heights ++ :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) - (const :tag "Even window heights" :format "%t" even-window-heights) - (const :tag "Shrink window if larger than buffer" - :format "%t" shrink-window-if-larger-than-buffer) - (const :tag "Fit window to buffer" :format "%t" fit-window-to-buffer))) ++ (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. + (list + :tag "Other frame" + :value (other-frame ++ (reuse-buffer-window . visible) + (graphic-only . t) + (popup-frame-alist - (height . 24) (width . 80) (unsplittable . t)) - (reuse-buffer-window . visible)) ++ (height . 24) (width . 80) (unsplittable . t))) + :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. + (list + :tag "Function" + :format "%t%v\n" + :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) - (adjust-height . even-window-heights) ++ (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. + (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))))) + + ;; Same frame. + (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) - (adjust-height . even-window-heights)) ++ (min-height . 24) (min-width . 60)) + :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" :value 12 :size 5)) ++ :tag "Minimum height of new window" :value 12 :size 5)) + (cons + :format "%v\n" + (const :format "" min-width) + (number - :tag "Minimum width" :value 60 :size 5)) - (cons - :format "%v\n" - (const :format "" max-height) - (number - :tag "Maximum height" :value 48 :size 5)) - (cons - :format "%v\n" - (const :format "" max-width) - (number - :tag "Maximum width" :value 120 :size 5)) - (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 "Minimum width of new window" :value 60 :size 5)) + (cons + :format "%v" + (const :format "" adjust-height) + (choice - :tag "Adjust window height" :value even-window-heights ++ :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) - (const :tag "Even window heights" :format "%t" even-window-heights) - (const :tag "Shrink window if larger than buffer" - :format "%t" shrink-window-if-larger-than-buffer) - (const :tag "Fit window to buffer" :format "%t" fit-window-to-buffer))) ++ (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. + (list + :tag "Other frame" + :value (other-frame ++ (reuse-buffer-window . visible) + (graphic-only . t) + (popup-frame-alist - (height . 24) (width . 80) (unsplittable . t)) - (reuse-buffer-window . visible)) ++ (height . 24) (width . 80) (unsplittable . t))) + :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. + (list + :tag "Function" + :format "%t%v\n" + :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) + +;; 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-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)) ++ (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. + +- The specifiers in `display-buffer-regexps' whose name component + matches BUFFER-NAME and whose 'override component is set. + +- SPECIFIERS. + +- 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))) + +;; The following is a global variable which is used externally (by +;; help.el) to (1) know which window was used for displaying a buffer +;; and (2) whether the window was new or reused. +(defvar display-buffer-window nil + "Window used by `display-buffer' and related information. +After `display-buffer' displays a buffer in some window this +variable is a cons cell whose car denotes the window used to +display the buffer. The cdr is supposed to be one of the symbols +`reuse-buffer-window', `reuse-other-window', `new-window' or +`new-frame'. + +If the buffer display location specifier is one of 'same-window, +'same-frame, or 'other-frame, the `display-buffer' routines +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.") + - (defun display-buffer-adjust-heights (window specifiers) - "Adjust height of WINDOW according to SPECIFIERS. ++(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." - (let ((adjust-height (cdr (assq 'adjust-height specifiers)))) ++documentation of `display-buffer-names' 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 ++larger than WINDOW." ++ (let ((even-window-sizes (cdr (assq 'even-window-sizes specifiers)))) + (cond - ((eq adjust-height 'even-window-heights) - (when (and (not (eq window (selected-window))) - ;; Don't resize minibuffer windows. - (not (window-minibuffer-p)) - ;; Resize iff the selected window is higher than WINDOW. - (> (window-total-size) (window-total-size window)) - ;; Resize vertical combinations only. - (and (window-parent) (window-iso-combined-p (window-parent)) - ;; WINDOW must be adjacent to the selected one. - (or (eq window (window-prev)) (eq window (window-next))))) ++ ((or (not even-window-sizes) ++ ;; Don't resize minibuffer windows. ++ (window-minibuffer-p) ++ ;; WINDOW must be adjacent to the selected one. ++ (not (or (eq window (window-prev)) ++ (eq window (window-next)))))) ++ ((and (window-iso-combined-p window) ++ ;; Resize iff the selected window is higher than WINDOW. ++ (> (window-total-height) (window-total-height window))) + ;; Don't throw an error if we can't even window heights for + ;; whatever reason. In any case, enlarging the selected window + ;; might fail anyway if there are other windows above or below + ;; WINDOW and the selected one. But for a simple two windows + ;; configuration the present behavior is good enough so why care? + (condition-case nil + (resize-window - window (/ (- (window-total-size window) (window-total-size)) 2)) - (error nil)))) - ((eq adjust-height 'shrink-window-if-larger-than-buffer) - (shrink-window-if-larger-than-buffer window)) - ((eq adjust-height 'fit-window-to-buffer) - (fit-window-to-buffer window))))) ++ window (/ (- (window-total-height) (window-total-height window)) ++ 2)) ++ (error nil))) ++ ((and (window-iso-combined-p window t) ++ ;; Resize iff the selected window is wider than WINDOW. ++ (> (window-total-width) (window-total-width window))) ++ ;; Don't throw an error if we can't even window widths, see ++ ;; comment above. ++ (condition-case nil ++ (resize-window ++ window (/ (- (window-total-width) (window-total-width window)) ++ 2) t) ++ (error nil)))))) ++ ++(defun display-buffer-adjust-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)))) ++ (cond ++ ((numberp adjust-height) ++ (let* ((height (if (integerp adjust-height) ++ adjust-height ++ (* (window-total-size (frame-root-window window)) ++ adjust-height))) ++ (delta (- height (window-total-size window)))) ++ (when (and (window-resizable-p window delta) ++ (window-iso-combined-p window)) ++ (resize-window window delta)))) ++ ((functionp adjust-height) ++ (condition-case nil ++ (funcall adjust-height window) ++ (error nil)))))) ++ ++(defun display-buffer-adjust-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)))) ++ (cond ++ ((numberp adjust-width) ++ (let* ((width (if (integerp adjust-width) ++ adjust-width ++ (* (window-total-size (frame-root-window window) t) ++ adjust-width))) ++ (delta (- width (window-total-size window t)))) ++ (when (and (window-resizable-p window delta t) ++ (window-iso-combined-p window t)) ++ (resize-window window delta t)))) ++ ((functionp adjust-width) ++ (condition-case nil ++ (funcall adjust-width window) ++ (error nil)))))) + +(defun display-buffer-select-window (window &optional norecord) + "Select WINDOW and make sure it's frame is risen." + (let ((old-frame (selected-frame)) + (new-frame (window-frame 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. +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." + (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)))) + ;; Show BUFFER in WINDOW. + (set-window-dedicated-p window nil) + (set-window-buffer window buffer) + (when dedicated + (set-window-dedicated-p window dedicated)) - ;; Adjust heights if necessary. - (display-buffer-adjust-heights window specifiers) + ;; 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 `display-buffer-other-frame'). ++ ;; also the problems with the old `display-buffer-other-frame'). + (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)))) + + (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)) + (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. + +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)))) + +(defun display-buffer-split-window-1 (window side min-size max-size) + "Subroutine of `display-buffer-split-window'." + (let* ((horflag (memq side '(left right))) + (parent (window-parent window)) + (resize (and (eq window-splits 'resize) + (window-iso-combined-p window horflag))) + (old-size + ;; We either resize WINDOW or its parent. + (window-total-size (if resize parent window) horflag)) + (new-size + ;; Don't make a window larger than MAX-SIZE, and not smaller + ;; than MIN-SIZE and the minimum size of a window. + (min max-size + (max min-size + (if resize + (min (- old-size (window-min-size parent horflag)) + (/ old-size + (1+ (window-iso-combinations parent horflag)))) + (/ old-size 2)))))) + ;; Check the sizes. + (when (if resize + (window-sizable-p parent (- new-size) horflag) + (window-sizable-p window (- new-size) horflag)) + ;; We don't call `split-window-vertically' any more here. If for + ;; some reason it seems appropriate we can always do so. + (split-window window (- new-size) side)))) + +(defun display-buffer-split-window (window &optional side specifiers) + "Split WINDOW in a way suitable for `display-buffer'. +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. + +Return the new window, nil if it could not be created." + ;; Normalize min-height / min-width, we might need both. + (let ((min-height (cdr (assq 'min-height specifiers))) + (min-width (cdr (assq 'min-width specifiers))) + (max-height (cdr (assq 'max-height specifiers))) + (max-width (cdr (assq 'max-width specifiers))) + (root-height (window-total-height + (frame-root-window (window-frame window)))) + (root-width (window-total-width + (frame-root-window (window-frame window)))) + size) + (setq min-height + (cond + ((and (integerp min-height) + ;; If min-height is specified, it can be as small + ;; `window-safe-min-height'. + (>= min-height window-safe-min-height)) + min-height) + ((and (floatp min-height) + (<= min-height 1) + (let ((height (round (* min-height root-height)))) + (when (>= height window-safe-min-height) + height)))) + (t window-min-height))) + (setq max-height + (cond + ((and (integerp max-height) + ;; If max-height is specified, it can be as large + ;; as root-height. + (>= max-height min-height) + (<= max-height root-height)) + max-height) + ((and (floatp max-height) + (<= max-height 1) + (let ((height (round (* max-height root-height)))) + (when (>= height min-height) + height)))) + (t root-height))) + (setq min-width + (cond + ((and (integerp min-width) + ;; If min-width is specified, it can be as small + ;; `window-safe-min-width'. + (>= min-width window-safe-min-width)) + min-width) + ((and (floatp min-width) + (<= min-width 1) + (let ((width (round (* min-width root-width)))) + (when (>= width window-safe-min-width) + width)))) + (t window-min-width))) + (setq max-width + (cond + ((and (integerp max-width) + ;; If max-width is specified, it can be as large as + ;; root-width. + (>= max-width min-width) + (<= max-width root-width)) + max-width) + ((and (floatp max-width) + (<= max-width 1) + (let ((width (round (* max-width root-width)))) + (when (>= width min-width) + width)))) + (t root-width))) + + (or (and (memq side '(nil above below)) + (display-buffer-split-window-1 + window (or side 'below) min-height max-height)) + ;; If SIDE is nil and vertical splitting failed, we try again + ;; splitting horizontally this time. For the SIDE nil case, we + ;; could also try to split horizontally if splitting vertically + ;; with proportional sizes fails and try the vertical split with + ;; minimum size afterwards - but this might be disconcerting. + (and (memq side '(nil left right)) + (display-buffer-split-window-1 + window (or side 'below) min-width max-width))))) + +(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) + "Display BUFFER in a new window. +Return the window displaying BUFFER if creating the new window +was successful, nil otherwise. + +SPECIFIERS must be a list of buffer display specifiers, see the +documentation of `display-buffer-names' 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))))) + (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)) - ((fboundp side-specifier) ++ ((functionp side-specifier) + (condition-case nil + (funcall + side-specifier window (cdr specifiers)) + (error nil))))) + (throw 'done window)))))) + (when window ++ ;; Adjust sizes if asked for. ++ (display-buffer-adjust-height window specifiers) ++ (display-buffer-adjust-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) + "Make a new frame for displaying BUFFER. +Return the window displaying BUFFER if creating the new frame was +successful, nil otherwise. + +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))) + (let* ((selected-window (selected-window)) + (function (or (cdr (assq 'popup-frame-function specifiers)) + 'make-frame)) + (parameters (cdr (assq 'popup-frame-alist specifiers))) + (frame (funcall function parameters))) + (when frame + (let ((window (frame-selected-window frame))) + (set-window-parameter + window 'quit-restore (list 'new-frame buffer selected-window)) + (setq display-buffer-window (cons window 'new-frame)) + (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 specified by BUFFER-OR-NAME exists, return that buffer. +If no such buffer exists, create a buffer with the name +BUFFER-OR-NAME and return that buffer." + (if buffer-or-name + (or (get-buffer buffer-or-name) + (let ((buffer (get-buffer-create buffer-or-name))) + (set-buffer-major-mode buffer) + buffer)) + (current-buffer))) + +(defun display-buffer (&optional buffer-or-name specifiers ignore) + "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 +an existent buffer, create a buffer with that name. If +BUFFER-OR-NAME is nil or omitted, display the current buffer. +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. + +Optional argument SPECIFIERS must be a list of buffer display +specifiers, see the documentation of `display-buffer-names' 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. + +The method to display a 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 +SPECIFIERS, followed by the non-overriding elements of +`display-buffer-names' and the non-overriding elements of +`display-buffer-regexps'. + +The result must be a list of valid buffer display specifiers. +`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." + (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)) + ;; 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) + ;; Reset this. + (setq display-buffer-window nil) + ;; 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)) + (setq specifiers (cdr specifiers)) + (when (symbolp location) + (setq window + (or (and (eq location 'same-window) + (or (not (window-dedicated-p)) + (not (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)) - (fboundp location) ++ (functionp location) + ;; Separate function. + (funcall location buffer specifiers)))))) + + ;; If we don't have a window yet, try a fallback method. Note: 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 + ;; 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 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, usualy because it is dedicated to another +buffer. + +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-other-window (&optional buffer-or-name) + "Display buffer specified by BUFFER-OR-NAME in another window. +The selected window will be used if and only if there is no other +choice. Windows on the selected frame are preferred to windows +on other frames. + +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 pop-to-buffer (&optional buffer-or-name specifiers norecord) + "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 +an existent buffer, create a buffer with that name. If +BUFFER-OR-NAME is nil or omitted, display the current buffer. +Interactively, prompt for the buffer name using the minibuffer. + +Optional second argument SPECIFIERS must be a list of buffer +display specifiers, a single location specifier, `t' which means +the latter means to display the buffer in any but the selected +window, or nil which means to exclusively apply the specifiers +customized by the user. + +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 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." + (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) + buffer))) + +(defun pop-to-buffer-same-window (&optional buffer-or-name norecord) + "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'." + (interactive "BPop to buffer in selected window:\nP") + (pop-to-buffer buffer-or-name 'same-window norecord)) + +(defun pop-to-buffer-other-window (&optional buffer-or-name norecord) + "Pop to buffer specified by BUFFER-OR-NAME in another window. +The selected window will be used if and 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'." + (interactive "BPop to buffer in another window:\nP") + (pop-to-buffer + buffer-or-name display-buffer-other-window-specifiers norecord)) + +(defun pop-to-buffer-other-frame (&optional buffer-or-name norecord) + "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 +`pop-to-buffer'." + (interactive "BPop to buffer on another frame:\nP") + (pop-to-buffer + buffer-or-name display-buffer-other-frame-specifiers norecord)) + +(defun read-buffer-to-switch (prompt) + "Read the name of a buffer to switch to, prompting with PROMPT. +Return the neame of the buffer as a string. + +This function is intended for the `switch-to-buffer' family of +commands since these need to omit the name of the current buffer +from the list of completions and default values." + (let ((rbts-completion-table (internal-complete-buffer-except))) + (minibuffer-with-setup-hook + (lambda () + (setq minibuffer-completion-table rbts-completion-table) + ;; Since rbts-completion-table is built dynamically, we + ;; can't just add it to the default value of + ;; icomplete-with-completion-tables, so we add it + ;; here manually. + (if (and (boundp 'icomplete-with-completion-tables) + (listp icomplete-with-completion-tables)) + (set (make-local-variable 'icomplete-with-completion-tables) + (cons rbts-completion-table + icomplete-with-completion-tables)))) + (read-buffer prompt (other-buffer (current-buffer)) + (confirm-nonexistent-file-or-buffer))))) + +(defun normalize-buffer-to-switch-to (buffer-or-name) + "Normalize BUFFER-OR-NAME argument of buffer switching functions. +If BUFFER-OR-NAME is nil, return the buffer returned by +`other-buffer'. Else, if a buffer specified by BUFFER-OR-NAME +exists, return that buffer. If no such buffer exists, create a +buffer with the name BUFFER-OR-NAME and return that buffer." + (if buffer-or-name + (or (get-buffer buffer-or-name) + (let ((buffer (get-buffer-create buffer-or-name))) + (set-buffer-major-mode buffer) + buffer)) + (other-buffer))) + +(defun switch-to-buffer (buffer-or-name &optional norecord) + "Switch to buffer BUFFER-OR-NAME in the selected window. +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. + +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 function is intended for interactive use. 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))) + (if (and (or (window-minibuffer-p) (eq (window-dedicated-p) t)) + (not (eq buffer (window-buffer)))) + ;; Cannot switch to another buffer in a minibuffer or strongly + ;; dedicated window that does not show the buffer already. Call + ;; `pop-to-buffer' instead. + (pop-to-buffer buffer 'same-window norecord) + (unless (eq buffer (window-buffer)) + ;; I'm not sure why we should NOT call `set-window-buffer' here, + ;; but let's keep things as they are (otherwise we could always + ;; call `pop-to-buffer-same-window' here). + (set-window-buffer nil buffer)) + (unless norecord + (select-window (selected-window))) + (set-buffer buffer)))) + +(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 if and only if there is no other +choice. Windows on the selected frame are preferred to windows +on other frames. + +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." + (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))) + +(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. + +This function is intended for interactive use. 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))) + +;;; Obsolete definitions of `display-buffer' below. (defcustom display-buffer-function nil - "If non-nil, function to call to handle `display-buffer'. -It will receive two args, the buffer and a flag which if non-nil -means that the currently selected window is not acceptable. It + "If non-nil, function to call to display a buffer. +`display-buffer' calls this function with two arguments, the +buffer to display and a flag which if non-nil means that the +selected window is not acceptable for displaying the buffer. It should choose or create a window, display the specified buffer in it, and return the window. @@@ -5768,99 -1413,80 +5856,99 @@@ in some window. (goto-char (point-min)) (1+ (vertical-motion (buffer-size) window)))))) -(defun fit-window-to-buffer (&optional window max-height min-height) +(defun window-buffer-height (window) + "Return the height (in screen lines) of the buffer that WINDOW is displaying." + (with-current-buffer (window-buffer window) + (max 1 + (count-screen-lines (point-min) (point-max) + ;; If buffer ends with a newline, ignore it when + ;; counting height unless point is after it. + (eobp) + window)))) + +;;; Resizing buffers to fit their contents exactly. - (defun fit-window-to-buffer (&optional window max-height min-height ignore) ++(defun fit-window-to-buffer (&optional window max-height min-height override) "Adjust height of WINDOW to display its buffer's contents exactly. -WINDOW defaults to the selected window. -Optional argument MAX-HEIGHT specifies the maximum height of the -window and defaults to the maximum permissible height of a window -on WINDOW's frame. -Optional argument MIN-HEIGHT specifies the minimum height of the -window and defaults to `window-min-height'. -Both, MAX-HEIGHT and MIN-HEIGHT are specified in lines and -include the mode line and header line, if any. - -Return non-nil if height was orderly adjusted, nil otherwise. - -Caution: This function can delete WINDOW and/or other windows -when their height shrinks to less than MIN-HEIGHT." +WINDOW can be any live window and defaults to the selected one. + +Optional argument MAX-HEIGHT specifies the maximum height of +WINDOW and defaults to the height of WINDOW's frame. Optional +argument MIN-HEIGHT specifies the minimum height of WINDOW and +defaults to `window-min-height'. Both, MAX-HEIGHT and MIN-HEIGHT +are specified in lines and include the mode line and header line, +if any. + - Optional argument IGNORE non-nil means ignore restrictions ++Optional argument OVERRIDE non-nil means override restrictions +imposed by `window-min-height' and `window-min-width' on the size +of WINDOW. + +Return the number of lines by which WINDOW was enlarged or +shrunk. If an error occurs during resizing, return nil but don't +signal an error. + +Note that even if this function makes WINDOW large enough to show +_all_ lines of its buffer you might not see the first lines when +WINDOW was scrolled." (interactive) ;; Do all the work in WINDOW and its buffer and restore the selected ;; window and the current buffer when we're done. - (let ((old-buffer (current-buffer)) - value) - (with-selected-window (or window (setq window (selected-window))) - (set-buffer (window-buffer)) - ;; Use `condition-case' to handle any fixed-size windows and other - ;; pitfalls nearby. - (condition-case nil - (let* (;; MIN-HEIGHT must not be less than 1 and defaults to - ;; `window-min-height'. - (min-height (max (or min-height window-min-height) 1)) - (max-window-height - ;; Maximum height of any window on this frame. - (min (window-height (frame-root-window)) (frame-height))) - ;; MAX-HEIGHT must not be larger than max-window-height and - ;; defaults to max-window-height. - (max-height - (min (or max-height max-window-height) max-window-height)) - (desired-height - ;; The height necessary to show all of WINDOW's buffer, - ;; constrained by MIN-HEIGHT and MAX-HEIGHT. - (max - (min - ;; For an empty buffer `count-screen-lines' returns zero. - ;; Even in that case we need one line for the cursor. - (+ (max (count-screen-lines) 1) - ;; For non-minibuffers count the mode line, if any. - (if (and (not (window-minibuffer-p)) mode-line-format) - 1 0) - ;; Count the header line, if any. - (if header-line-format 1 0)) - max-height) - min-height)) - (delta - ;; How much the window height has to change. - (if (= (window-height) (window-height (frame-root-window))) - ;; Don't try to resize a full-height window. - 0 - (- desired-height (window-height)))) - ;; Do something reasonable so `enlarge-window' can make - ;; windows as small as MIN-HEIGHT. - (window-min-height (min min-height window-min-height))) - ;; Don't try to redisplay with the cursor at the end on its - ;; own line--that would force a scroll and spoil things. - (when (and (eobp) (bolp) (not (bobp))) - (set-window-point window (1- (window-point)))) - ;; Adjust WINDOW's height to the nominally correct one - ;; (which may actually be slightly off because of variable - ;; height text, etc). - (unless (zerop delta) - (enlarge-window delta)) - ;; `enlarge-window' might have deleted WINDOW, so make sure - ;; WINDOW's still alive for the remainder of this. - ;; Note: Deleting WINDOW is clearly counter-intuitive in - ;; this context, but we can't do much about it given the - ;; current semantics of `enlarge-window'. - (when (window-live-p window) + (setq window (normalize-live-window window)) + ;; Can't resize a full height or fixed-size window. + (unless (or (window-size-fixed-p window) + (window-full-height-p window)) + ;; `with-selected-window' should orderly restore the current buffer. + (with-selected-window window + ;; We are in WINDOW's buffer now. + (let* ( ;; Adjust MIN-HEIGHT. + (min-height - (if ignore ++ (if override + (window-min-size window nil window) + (max (or min-height window-min-height) + window-safe-min-height))) + (max-window-height + (window-total-size (frame-root-window window))) + ;; Adjust MAX-HEIGHT. + (max-height - (if (or ignore (not max-height)) ++ (if (or override (not max-height)) + max-window-height + (min max-height max-window-height))) + ;; Make `desired-height' the height necessary to show + ;; all of WINDOW's buffer, constrained by MIN-HEIGHT + ;; and MAX-HEIGHT. + (desired-height + (max + (min + (+ (count-screen-lines) + ;; For non-minibuffers count the mode line, if any. + (if (and (not (window-minibuffer-p window)) + mode-line-format) + 1 + 0) + ;; Count the header line, if any. + (if header-line-format 1 0)) + max-height) + min-height)) + (desired-delta + (- desired-height (window-total-size window))) + (delta + (if (> desired-delta 0) + (min desired-delta + (window-max-delta window nil window)) + (max desired-delta + (- (window-min-delta window nil window)))))) + ;; This `condition-case' shouldn't be necessary, but who knows? + (condition-case nil + (if (zerop delta) + ;; Return zero if DELTA became zero in the proces. + 0 + ;; Don't try to redisplay with the cursor at the end on its + ;; own line--that would force a scroll and spoil things. + (when (and (eobp) (bolp) (not (bobp))) + ;; It's silly to put `point' at the end of the previous + ;; line and so maybe force horizontal scrolling. + (set-window-point window (line-beginning-position 0))) - ;; Call `resize-window' with IGNORE argument equal WINDOW. ++ ;; Call `resize-window' with OVERRIDE argument equal WINDOW. + (resize-window window delta nil window) ;; Check if the last line is surely fully visible. If ;; not, enlarge the window. (let ((end (save-excursion