+2011-05-30 Martin Rudalics <rudalics@gmx.at>
+
+ * windows.texi (Windows and Frames, Window Sizes)
+ (Resizing Windows): Minor rewrites.
+ (Splitting Windows): Provide additional examples. Rewrite
+ parts on window-splits and window-nest.
+ (Deleting Windows, Window Parameters, Side Windows): Minor
+ rewrites.
+
2011-05-19 Glenn Morris <rgm@gnu.org>
* lists.texi (Sets And Lists): Mention cl provides union etc.
windows arranged one above each other. A @dfn{horizontal combination}
is a set of windows arranged side by side. Consider the frame shown
below (for simplicity we assume that the frame does not contain a
-minibuffer):
+minibuffer window):
@smallexample
@group
@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. In the example
-above @code{(window-child W3)} is @code{W4} while @code{(window-vchild
+above @code{(window-child W3)} is @code{W4} while @code{(window-child
W4)} is @code{W6}.
@end defun
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.
-
-In our canonical example @code{(window-iso-combined-p W5)} and
-@code{(window-iso-combined-p W6 t)} both evaluate to @code{t} while
-@code{(window-iso-combined-p W6)} is @code{nil}.
@end defun
@cindex sibling window
@end defun
Alternatively, the following two functions can be used to retrieve
-either the total height of the total width of a window:
+either the total height or the total width of a window:
@defun window-total-height &optional window
This function returns the total number of lines of @var{window}.
@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. Scroll bars or columns of @samp{|}
-characters that separates side-by-side windows are not included in a
+characters that separate side-by-side windows are not included in a
window's body width.
@cindex body size of a window
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
+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.
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.
+check whether @var{window} itself and its subwindows can be resized.
@end defun
The function @code{window-resizable} does not change any window sizes.
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.
+This function can simultaneously move two edges of WINDOW. Exactly
+which edges of @var{window} are moved and which other windows are
+resized along with @var{window} is determined by the splits and nest
+status of the involved windows (@pxref{Splitting 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}.
@var{window}'s right edge by @var{delta} columns. The argument
@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.
+If @var{delta} is greater zero, this moves the edge downwards or to the
+right. If @var{delta} is less than zero, this moves the edge upwards or
+to the left. If the edge can't be moved by @var{delta} lines or columns,
+it is moved as far as possible in the desired direction but no error is
+signalled.
+
+This function tries to resize windows adjacent to the edge that is
+moved. Only if this is insufficient, it will also resize windows not
+adjacent to that edge. As a consequence, if you move an edge in one
+direction and back in the other direction by the same amount, the
+resulting window configuration will not be necessarily identical to the
+one before the first move. So if your intend to just resize
+@var{window}, you should not use this function but call
+@code{resize-window} (see above) instead.
@end defun
@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.
+The optional argument @var{max-height} specifies the maximum total
+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 toatl 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
@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
+the sizes of all 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
If @code{ignore-window-parameters} is non-@code{nil}, this function
ignores window parameters (@pxref{Window Parameters}). Otherwise, if
-the @code{split-window-function} parameter of @var{window} is @code{t},
-it splits the window disregarding any other window parameters. If the
-@code{split-window-function} parameter specifies a function, that
-function is called with the arguments @var{window}, @var{size}, and
-@var{side} to split @var{window}. If that function is @code{ignore},
-nothing is done.
+the @code{split-window} parameter of @var{window} is @code{t}, it splits
+the window disregarding any other window parameters. If the
+@code{split-window} parameter specifies a function, that function is
+called with the arguments @var{window}, @var{size}, and @var{side} to
+split @var{window}. If that function is @code{ignore}, nothing is done.
Otherwise, if @var{window} is a subwindow of an atomic window
(@pxref{Atomic Windows}) this function splits the root of the atomic
Frames}) and how internal windows are created for this purpose. We
start with a frame containing one leaf window @code{W2} (in the
following scenarios window names are assigned in an arbitrary manner in
-order to match the names of the example).
-@smallexample
-@group
- ______________________________________
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- |__________________W2__________________|
-
-@end group
-@end smallexample
-
-Evaluating the form @code{(split-window W2 8 t)} creates a new internal
-window @code{W1} with two children---@code{W2} (the window we've split)
-and a new leaf window @code{W6}:
+order to match the names of the example). Evaluating the form
+@code{(split-window W2 8 t)} creates a new internal window @code{W1}
+with two children---@code{W2} (the window we've split) and a new leaf
+window @code{W6}:
@smallexample
@group
______________________________________
@end smallexample
Evaluating now @code{(split-window (window-parent W6) -8 'left)} or,
-equivalently, @code{(split-window W3 -8 'left)} should produce the
-familiar configuration
-@smallexample
-@group
- ______________________________________
- | ______ ____________________________ |
- || || __________________________ ||
- || ||| |||
- || ||| |||
- || ||| |||
- || ||| |||
- || ||| |||
- || |||____________W6____________|||
- || || __________________________ ||
- || ||| |||
- || |||____________W5____________|||
- ||__W2__||_____________W3_____________ |
- |__________________W1__________________|
-
-@end group
-@end smallexample
-
-from where we can continue as described in the previous scenario.
+equivalently, @code{(split-window W3 -8 'left)} should now produce the
+penultimate configuration from the previous scenario from where we can
+continue as described before.
Another strategy starts with splitting an inital window @code{W6} by
evaluating @code{(split-window W6 nil nil t)} with the following result:
@code{(split-window (window-parent W6) -3)} should produce the desired
configuration.
- The following two option can be used to tune the operation of
+ The two options described next can be used to tune the operation of
@code{split-window}.
@defopt window-splits
If this variable is nil, the function @code{split-window} can split a
window if and only if that window's screen estate is sufficiently large
-to accomodate both itself and the new window.
+to accomodate both--itself and the new window.
If this variable is non-@code{nil}, @code{split-window} tries to resize
-all windows belonging to the same combination as the old window in order
-to accomodate the new window. Hence, the new window can be also created
-if the old window is otherwise too small to split.
+all windows that are part of the same combination as the old window to
+accomodate the new window. Hence, the new window can be also created if
+the old window is of fixed size or too small to split (@pxref{Window
+Sizes}).
In any case, the value of this variable is assigned to the splits status
of the new window and, provided old and new window form a new
combination, of the old window as well. The splits status of a window
can be retrieved by invoking the function @code{window-splits} and
-altered by the function @code{set-window-splits}, see below.
+altered by the function @code{set-window-splits} described next.
If @code{window-nest} (see below) is non-@code{nil}, the space for the
new window is exclusively taken from the old window, but the splits
-status of any involved window is nevertheless set as descibed above.
-@end defopt
-
-@defopt window-nest
-If this variable is @code{nil}, @code{split-window} creates a new parent
-window if and only if the old window has no parent window or shall be
-split orthogonally to the combination it is part of. If this variable
-is non-@code{nil}, @code{split-window} always creates a new parent
-window. If this variable is always non-@code{nil}, a frame's window
-tree is a binary tree so every window but the frame's root window has
-exactly one sibling.
-
-The value of this variable is also assigned to the nest status of the
-new parent window. The nest status of any window can be retrieved via
-the function @code{window-nest} and altered by the function
-@code{set-window-nest}, see below.
+status of the involved windows is nevertheless set as described here.
@end defopt
@defun window-splits &optional window
@cindex splits status
The @dfn{splits status} of a window specifies how resizing and deleting
that window may affect the size of other windows in the same window
-combination. The splits status is initially set by @code{split-window}
-to the current value of the variable @code{window-splits} (see above)
+combination. More precisely, if @var{window}'s splits status is
+@code{nil} and @var{window} is resized, the corresponding space is
+preferably taken from (or given to) @var{window}'s right sibling. When
+@var{window} is deleted, its space is given to its left sibling. If
+@var{window}'s splits status is non-@code{nil}, resizing and deleting
+@var{window} may resize @emph{all} windows in @var{window}'s
+combination.
+
+The splits status is initially set by @code{split-window}
+from the current value of the variable @code{window-splits} (see above)
and can be reset by the function @code{set-window-splits} (see below).
-
-More precisely, if @var{window}'s splits status is @code{nil} and
-@var{window} is resized, the corresponding space is preferably taken
-from (or given to) @var{window}'s right sibling. When @var{window} is
-deleted, its space is given to its left sibling. If @var{window}'s
-splits status is non-@code{nil}, resizing and deleting @var{window} may
-resize all windows in @var{window}'s combination.
@end defun
@defun set-window-splits window &optional status
to the selected one. The return value is @var{status}.
@end defun
+To illustrate the use of @code{window-splits} consider the following
+window configuration:
+@smallexample
+@group
+ ______________________________________
+ | ____________________________________ |
+ || ||
+ || ||
+ || ||
+ || ||
+ ||_________________W2_________________||
+ | ____________________________________ |
+ || ||
+ || ||
+ || ||
+ || ||
+ ||_________________W3_________________||
+ |__________________W1__________________|
+
+@end group
+@end smallexample
+
+Splitting window @code{W3} with @code{window-splits} @code{nil}
+produces a configuration where the size of @code{W2} remains unchanged:
+@smallexample
+@group
+ ______________________________________
+ | ____________________________________ |
+ || ||
+ || ||
+ || ||
+ || ||
+ ||_________________W2_________________||
+ | ____________________________________ |
+ || ||
+ ||_________________W3_________________||
+ | ____________________________________ |
+ || ||
+ ||_________________W4_________________||
+ |__________________W1__________________|
+
+@end group
+@end smallexample
+
+Splitting @code{W3} with @code{window-splits} non-@code{nil} instead
+produces a configuration where all windows have approximately the same
+height:
+
+@smallexample
+@group
+ ______________________________________
+ | ____________________________________ |
+ || ||
+ || ||
+ ||_________________W2_________________||
+ | ____________________________________ |
+ || ||
+ || ||
+ ||_________________W3_________________||
+ | ____________________________________ |
+ || ||
+ || ||
+ ||_________________W4_________________||
+ |__________________W1__________________|
+
+@end group
+@end smallexample
+
+@defopt window-nest
+If this variable is @code{nil}, @code{split-window} creates a new parent
+window if and only if the old window has no parent window or shall be
+split orthogonally to the combination it is part of. If this variable
+is non-@code{nil}, @code{split-window} always creates a new parent
+window. If this variable is always non-@code{nil}, a frame's window
+tree is a binary tree so every window but the frame's root window has
+exactly one sibling.
+
+The value of this variable is also assigned to the nest status of the
+new parent window. The nest status of any window can be retrieved via
+the function @code{window-nest} and altered by the function
+@code{set-window-nest}, see below.
+@end defopt
+
@defun window-nest &optional window
This function returns the nest status of @var{window}. The argument
@var{window} can be any window and defaults to the selected one. Note,
windows only.
@cindex nest status
-The @dfn{nest status} of a window secifies whether that window may be
+The @dfn{nest status} of a window specifies whether that window may be
removed and its subwindows recombined with that window's siblings when
such a sibling's subwindow is deleted. The nest status is initially
-assigned by @code{split-window} to the current value of the variable
+assigned by @code{split-window} from the current value of the variable
@code{window-nest} (see above) and can be reset by the function
@code{set-window-nest} (see below).
for internal windows only. The return value is @var{status}.
@end defun
+To illustrate the use of @code{window-nest} consider the following
+configuration (throughout the following examples we shall assume that
+@code{window-splits} invariantly is @code{nil}).
+@smallexample
+@group
+ ______________________________________
+ | ____________________________________ |
+ || ||
+ || ||
+ || ||
+ || ||
+ || ||
+ || ||
+ ||_________________W2_________________||
+ | ____________________________________ |
+ || ||
+ || ||
+ ||_________________W3_________________||
+ |__________________W1__________________|
+
+@end group
+@end smallexample
+
+Splitting @code{W2} into two windows above each other with
+@code{window-nest} equal @code{nil} will get you a configuration like:
+@smallexample
+@group
+ ______________________________________
+ | ____________________________________ |
+ || ||
+ || ||
+ ||_________________W2_________________||
+ | ____________________________________ |
+ || ||
+ || ||
+ ||_________________W4_________________||
+ | ____________________________________ |
+ || ||
+ || ||
+ ||_________________W3_________________||
+ |__________________W1__________________|
+
+@end group
+@end smallexample
+
+If you now enlarge window @code{W4}, Emacs steals the necessary space
+from window @code{W3} resulting in a configuration like:
+@smallexample
+@group
+ ______________________________________
+ | ____________________________________ |
+ || ||
+ || ||
+ ||_________________W2_________________||
+ | ____________________________________ |
+ || ||
+ || ||
+ || ||
+ ||_________________W4_________________||
+ | ____________________________________ |
+ || ||
+ ||_________________W3_________________||
+ |__________________W1__________________|
+
+@end group
+@end smallexample
+
+Deleting window @code{W4}, will return its space to @code{W2} as
+follows:
+@smallexample
+@group
+ ______________________________________
+ | ____________________________________ |
+ || ||
+ || ||
+ || ||
+ || ||
+ || ||
+ || ||
+ || ||
+ ||_________________W2_________________||
+ | ____________________________________ |
+ || ||
+ ||_________________W3_________________||
+ |__________________W1__________________|
+
+@end group
+@end smallexample
+
+Hence, with respect to the initial configuration, window @code{W2} has
+grown at the expense of window @code{W3}. If, however, in the initial
+configuration you had split @code{W2} with @code{window-nest} bound to
+@code{t}, a new internal window @code{W5} would have been created as
+depicted below.
+@smallexample
+@group
+ ______________________________________
+ | ____________________________________ |
+ || __________________________________ ||
+ ||| |||
+ |||________________W2________________|||
+ || __________________________________ ||
+ ||| |||
+ |||________________W4________________|||
+ ||_________________W5_________________||
+ | ____________________________________ |
+ || ||
+ || ||
+ ||_________________W3_________________||
+ |__________________W1__________________|
+
+@end group
+@end smallexample
+
+Enlarging @code{W4} would now have stolen the necessary space from
+@code{W2} instead of @code{W3} as
+@smallexample
+@group
+ ______________________________________
+ | ____________________________________ |
+ || __________________________________ ||
+ |||________________W2________________|||
+ || __________________________________ ||
+ ||| |||
+ ||| |||
+ |||________________W4________________|||
+ ||_________________W5_________________||
+ | ____________________________________ |
+ || ||
+ || ||
+ ||_________________W3_________________||
+ |__________________W1__________________|
+
+@end group
+@end smallexample
+
+and the subsequent deletion of @code{W4} would have restored the initial
+configuration.
+
+For interactive use, Emacs provides two commands which always split the
+selected window.
+
@deffn Command split-window-above-each-other &optional size
This function splits the selected window into two windows, one above the
other, leaving the upper of the two windows selected, with @var{size}
on its frame. Hence @var{window} must have at least one sibling window
(@pxref{Windows and Frames}) in order to get deleted.
-If @code{window-splits} is @code{nil}, the space @var{window} took up is
-given to its left sibling if such a window exists and to its right
-sibling otherwise. If @code{window-splits} equals @code{nest} that
-space is given to the remaining sibling of @var{window}. If
-@code{window-splits} equals @code{resize}, the space occupied by
-@var{window} is proportionally distributed among the remaining windows
-in the same combination.
-
-If @code{ignore-window-parameters} (@pxref{Window Parameters}) is
-non-@code{nil}, this function ignores window parameters. Otherwise, if
-the @code{delete-window-function} parameter of @var{window} is @code{t},
-it deletes the window disregarding other window parameters. If the
-@code{delete-window-function} parameter specifies a function, that
-function is called with @var{window} as its sole argument.
-
-If @var{window} is part of an atomic window (@pxref{Atomic Windows}),
-this function is called with the root of the atomic window as its
-argument. If that window is the root window of its frame, an error is
-signalled. If @var{window} is the last non-side window on its frame
+If the variable @code{ignore-window-parameters} (@pxref{Window
+Parameters}) is non-@code{nil}, this function ignores all parameters of
+@var{window}. Otherwise, if the @code{delete-window} parameter of
+@var{window} is @code{t}, it deletes the window disregarding other
+window parameters. If the @code{delete-window} parameter specifies a
+function, that function is called with @var{window} as its sole
+argument.
+
+Otherwise, if @var{window} is part of an atomic window (@pxref{Atomic
+Windows}), this function is called with the root of the atomic window as
+its argument. If that window is the root window of its frame, an error
+is signalled. If @var{window} is the last non-side window on its frame
(@pxref{Side Windows}), this function signals an error too.
+
+If the splits status of @var{window} (@pxref{Splitting Windows}) is
+@code{nil}, the space @var{window} took up is given to its left sibling
+if such a window exists and to its right sibling otherwise. If the
+splits status of @var{window} is non-@code{nil}, its space is
+proportionally distributed among the remaining windows in the same
+combination.
@end deffn
@deffn Command delete-other-windows &optional window
The argument @var{window} can denote an arbitrary window and defaults to
the selected one.
-If @code{ignore-window-parameters} (@pxref{Window Parameters}) is
-non-@code{nil}, this function ignores window parameters. Otherwise, if
-the @code{delete-other-windows-function} parameter equals @code{t}, it
-deletes all other windows disregarding any remaining window parameters.
-If the @code{delete-other-windows-function} parameter specifies a
+If the variable @code{ignore-window-parameters} (@pxref{Window
+Parameters}) is non-@code{nil}, this function ignores all parameters of
+@var{window}. Otherwise, if the @code{delete-other-windows} parameter
+of @var{window} equals @code{t}, it deletes all other windows
+disregarding any remaining window parameters. If the
+@code{delete-other-windows} parameter of @var{window} specifies a
function, it calls that function with @var{window} as its sole argument.
-If @var{window} is part of an atomic window (@pxref{Atomic Windows}), it
-calls this function with the root of the atomic window as its argument.
-If @var{window} is a non-side window (@pxref{Side Windows}), it makes
-@var{window} the only non-side window on its frame and leaves side
-windows alone. If @var{window} is a side window, this function signals
-an error.
+Otherwise, if @var{window} is part of an atomic window (@pxref{Atomic
+Windows}), it calls this function with the root of the atomic window as
+its argument. If @var{window} is a non-side window (@pxref{Side
+Windows}), it makes @var{window} the only non-side window on its frame
+and leaves side windows alone. If @var{window} is a side window, this
+function signals an error.
@end deffn
@deffn Command delete-windows-on &optional buffer-or-name frame
@code{delete-window} for each window showing @var{buffer-or-name}. If a
frame has several windows showing different buffers, then those showing
@var{buffer-or-name} are removed, and the other windows expand to fill
-the space. If all windows in some frame are showing
-@var{buffer-or-name} (including the case where there is only one
-window), then the frame winds up with a single window showing another
-buffer. If, however, that last remaining window is dedicated to the
-buffer specified by @var{buffer-or-name} (@pxref{Dedicated Windows}),
-and there are other frames left, that window's frame is deleted.
+the space.
+
+If all windows in some frame are showing @var{buffer-or-name} (including
+the case where there is only one window), then that frame winds up with
+a single window showing another buffer. If, however, that last
+remaining window is dedicated to the buffer specified by
+@var{buffer-or-name} (@pxref{Dedicated Windows}) or that window's
+@code{quit-restore} parameter (@pxref{Window Parameters}) is set
+appropriately, that window's frame is deleted provided there are other
+frames left.
The optional argument @var{frame} specifies which frames to operate on.
This function does not use it in quite the same way as the other
@code{display-buffer} try to obey a number of user customizations
regulating which windows are supposed to display which buffers. When
writing an application, programmers should therefore carefully evaluate
-whether they really need the power of this @code{set-window-buffer}.
+whether they really need the power of @code{set-window-buffer}.
@defun set-window-buffer window buffer-or-name &optional keep-margins
This function makes @var{window} display @var{buffer-or-name} and
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.
+buffer. An error is signalled when @var{window} is @dfn{strongly}
+dedicated to its buffer (@pxref{Dedicated Windows}) and does not already
+display @var{buffer-or-name}.
Normally, displaying @var{buffer-or-name} in @var{window} resets the
window's position, display margins, fringe widths, and scroll bar
margins and fringe widths of @var{window} remain unchanged.
@xref{Fringes}.
-@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.
-
-@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}.
+This function 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.
This function runs @code{window-scroll-functions} before running
@code{window-configuration-change-hook}, see @ref{Window Hooks}.
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.
+(@pxref{Dedicated Windows}) or its @code{quit-restore} parameter
+(@pxref{Window Parameters}) is set appropriately, and the window 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
buffer that shall be displayed. The function is not passed any
specifiers.
-The function shoul choose or create a window, display the specified
+The function should choose or create a window, display the specified
buffer in it, and return the window. It is also responsible for giving
the variable @code{display-buffer-window} a meaningful value, see below
for an explanation. Moreover, the function should set up the
too.
@end defun
-Some functions, notably @code{split-window}, @code{delete-window}, and
-@code{delete-other-windows} behave specially when their @var{window}
-argument has a parameter set. For example, @code{delete-window} when
-invoked on the main window of an atomic window (@pxref{Atomic Windows})
-calls @code{delete-window} with the root window of the atomic window as
-argument instead. The entire information for retrieving the appropriate
-root window is maintained with the help of window parameters.
+Some functions, notably @code{delete-window},
+@code{delete-other-windows} and @code{split-window} may behave specially
+when their @var{window} argument has a parameter set. For example,
+@code{delete-window}, when invoked on a subwindow of an atomic window
+(@pxref{Atomic Windows}), calls itself with the root of the atomic
+window as argument instead.
-You can override that special behavior by binding the following variable
+You can override such special behavior by binding the following variable
to a non-@code{nil} value:
@defvar ignore-window-parameters
-If this variable is non-@code{nil}, some standard functions ignore
-window parameters. The functions currently affected by this are
+If this variable is non-@code{nil}, some standard functions do not
+process window parameters. The functions currently affected by this are
@code{split-window}, @code{delete-window}, @code{delete-other-windows}
and @code{other-window}.
An application can bind this variable to a non-@code{nil} value around
calls to these functions. If it does so, the application is fully
-responsible for correctly assigning the parameters of windows when
-exiting that function.
+responsible for correctly assigning the parameters of all involved
+windows when exiting that function.
@end defvar
The following parameters are currently used by the window management
@table @asis
@item @code{window-atom}
-This symbol designates the associated window as part of an atomic
+This parameter designates the associated window as part of an atomic
window (@pxref{Atomic Windows}).
@item @code{window-side}
-This symbol designates the associated window as part of a side or
+This parameter designates the associated window as part of a side or
non-side window (@pxref{Side Windows}).
-@item @code{delete-window-function}
-This parameter is used by @code{delete-window} (@pxref{Deleting
-Windows}).
+@item @code{delete-window}
+This parameter affects the execution of @code{delete-window}
+(@pxref{Deleting Windows}).
-@item @code{delete-other-windows-function}
-This parameter is used by @code{delete-other-windows} (@pxref{Deleting
-Windows}).
+@item @code{delete-other-windows}
+This parameter affects the execution of @code{delete-other-windows}
+(@pxref{Deleting Windows}).
-@item @code{split-window-function}
-This parameter is used by @code{split-window} (@pxref{Splitting
-Windows}).
+@item @code{split-window}
+This parameter affects the execution of @code{split-window}
+(@pxref{Splitting Windows}).
-@item @code{other-window-function}
-This parameter is used by @code{other-window} (@pxref{Cyclic Window
-Ordering}).
+@item @code{other-window}
+This parameter affects the execution of @code{other-window}
+(@pxref{Cyclic Window Ordering}).
@item @code{no-other-window}
This parameter marks the window as not selectable by @code{other-window}
@end table
The @code{quit-restore} parameter tells how to proceed with a window
-when the user ``quits'' it by invoking @code{quit-restore-window}, see
-@ref{Displaying Buffers}. The following non-@code{nil} values of this
-parameter have a special meaning.
-
-@table @asis
-@item @code{t}
-This means to delete the associated window. By default, @code{t} is
-used for a ``temporary'' window that was obtained by splitting an
-existing window.
-
-@item @code{frame}
-This means to delete the associated window's frame. This value
-indicates that the associated windows was obtained by popping up a new
-frame showing just this window. If the window is no more needed, it
-should be deleted together with the containing frame.
-
-@item A list
-This option is useful when the associated window was borrowed to
-temporarily display some buffer and quitting shall ``restore'' the
-previous contents of the window. The first three elements of the list
-must specify a buffer, a window start position, and a window point.
-Quitting the window will then try to display the indicated buffer with
-the given start position and point in that window.
-
- The fourth element, if non-@code{nil}, must denote a live buffer. If
-specified, quitting will restore the previous window contents if and
-only if the buffer shown in the window is the buffer named by this
-element.
-
- The fifth element, if non-@code{nil}, should specify the desired
-height of the window when its buffer is restored. This value is applied
-if the buffer temporarily shown in the window was in
-@code{temp-buffer-resize-mode} to restore the original height of the
-window.
-@end table
+when the buffer it shows is no more needed. This parameter is installed
+by the buffer display functions (@pxref{Displaying Buffers}) and
+consulted by functions that remove a buffer from display like
+@code{delete-windows-on} (@pxref{Deleting Windows}),
+@code{replace-buffer-in-windows} (@pxref{Buffers and Windows}), and
+@code{quit-restore-window} (@pxref{Displaying Buffers}). The parameter
+should be a list which is interpreted as sketched next.
+
+ If the first element of the list is the symbol @code{new-window},
+this means that the window was specially created for displaying a
+buffer. The second element of the list specifies that buffer, and the
+third element is the window selected at the time this window was
+created. The standard action in this case is to delete the window
+provided its frame contains at least on other window.
+
+ If the first element of the list is the symbol @code{new-frame}, this
+means that the associated frame was created for displaying a buffer.
+The remaining elements are as above. The standard action in this case
+is to delete the frame provided there are other frames left.
+
+ In any other case, the list should consist of five elements: A buffer
+that was shown in the window before, the start position of that buffer
+in the window, the position of @code{window-point} for that buffer in
+the window, the total height of the window before another buffer was
+displayed in it, and the window selected at the time that other buffer
+was displayed. The standard action here is to keep the window alive and
+to restore its contents to the state provided by these elements.
@node Atomic Windows
If you create side windows by calling @code{display-buffer}
(@pxref{Displaying Buffers}) with the @code{use-side-window} specifier,
-this will set up these parameters automatically. If you want to manage
-side windows manually, you should preserve the following invariants:
+this will set up these parameters automatically. For example
+
+@example
+(display-buffer
+ (get-buffer-create "*bar*")
+ '((use-side-window bottom 0)
+ (pop-up-window-set-height . 6)))
+@end example
+
+can be used to display a buffer ``*bar*'' in a six lines high
+side-window at the bottom of the selected frame.
+
+If you intend to manage side windows manually, you should preserve the
+following invariants:
@itemize @bullet
@item
@code{window-side} parameter is @code{nil}.
@item
-Live windows whose @code{window-side} parameter is @code{nil} are
-invalid.
+If a frame contains at least one window with a non-@code{nil}
+@code{window-side} parameter, the @code{window-side} parameter of all
+other live windows must be non-@code{nil} as well.
@end itemize
If a setup of @code{window-side} parameters fails to satisfy these
** The variable `focus-follows-mouse' now always defaults to nil.
++++
+** Window handling code.
+
+*** Window tree functions accessible in Elisp.
+You can use functions to return the parent, siblings or child windows of
+any window including internal windows (windows not associated with a
+buffer) in the window tree. `walk-window-tree' is a new function for
+traversing window trees.
+
+*** Window handling code moved to Elisp.
+Splitting, resizing, and deleting window is mostly done in Elisp now.
+The parts remaining in C deal only with checking the validity of these
+operations wrt the window tree and window sizes.
+
+*** Window manipulations can deal with internal windows.
+Many window handling functions like `split-window', `delete-window', or
+`delete-other-windows' as well as the window resizing functions can now
+act on any window including internal ones.
+
+*** window-total-height/-width vs window-body-height/-width.
+The function `window-height' has been renamed to `window-total-height'
+and `window-width' has been renamed to `window-body-width'. Two new
+functions `window-total-width' and `window-body-height' are provided.
+
+*** Window parameters specific to window handling functions.
+For each window you can specify a parameter to override the default
+behavior of a number of functions like `split-window', `delete-window'
+and `delete-other-windows'.
+
+*** New semantics of third argument of `split-window'.
+The third argument of `split-window' can be set to any of the values
+'below, 'right, 'above, or 'left to make the new window appear on the
+corresponding side of the window that shall be split.
+
+*** New option `window-nest'.
+The new option `window-nest' allows to return the space obtained for
+resizing or creating a window more reliably to the window from which
+such space was obtained.
+
+*** New option `window-splits'.
+The new option `window-splits' allows to split a window that otherwise
+cannot be split because it's too small by stealing space from other
+windows in the same combination.
+
+*** `split-window-above-each-other' and `split-window-side-by-side'.
+The commands `split-window-vertically' and `split-window-horizontally'
+have been renamed to `split-window-above-each-other' and
+`split-window-side-by-side' respectively. The old names are provided as
+aliases.
+
+*** Window resizing functions.
+A new standard function for resizing windows called `resize-window' has
+been introduced. This and all other functions for resizing windows no
+longer delete any windows when they become too small.
+
+*** Frame/window resizing.
+Resizing an Emacs frame now preserves the proportional sizes of
+subwindows modulo restrictions imposed by window minimum sizes and
+fixed-size windows.
+
+*** `adjust-window-trailing-edge' adjustments.
+`adjust-window-trailing-edge' can now deal with fixed-size windows and
+is able to resize other windows if a window adjacent to the trailing
+edge cannot be shrunk any more. This makes its behavior more similar to
+that of Emacs 21 without compromising, however, the latter's inability
+to delete windows which was introduced in Emacs 22.
+
+*** Commands for maximizing and minimizing windows.
+New functions to maximize and minimize a window within its frame are
+provided, namely `maximize-window' and `minimize-window'.
+
+*** Window-local buffer lists.
+Windows now have local buffer lists. This means that removing a buffer
+from display in a window will preferably show the buffer previously
+shown in that window with its previous window-start and window-point
+positions. This also means that the same buffer may be automatically
+shown twice even if it already appears in another window.
+
+*** New commands `switch-to-prev-buffer' and `switch-to-next-buffer'.
+These functions allow to navigate through the live buffers that have
+been shown in a specific window.
+
+*** New window parameter `quit-restore'.
+Functions to remove a buffer from display like `delete-windows-on' or
+`replace-buffer-in-windows' now respect the `quit-restore' window
+parameter which tells how to proceed with the window: Delete it, delete
+its frame, or display some previously shown buffer in it. This means
+that you don't have to dedicate a window to its buffer to obtain the
+corresponding behavior, setting its `quit-restore' parameter suffices.
+
+*** New command `quit-restore-window'.
+This function explicitly restores the state of one specific window
+consulting its `quit-restore' window parameter. Among others, it is
+now also called when exiting view-mode.
+
+*** Buffer display specifiers.
+Customizing the display of buffers is now handled with the help of
+buffer display specifiers. These specifiers are customizable via the
+option `display-buffer-alist' and completely obsolete all existing
+`display-buffer' related options like, `pop-up-windows', `pop-up-frames'
+`display-buffer-reuse-frames' or `split-height-threshold'. Buffer
+display specifiers also allow to specify a number of new options to
+choose, for example, the desired position of a new window or its size.
+
+*** Arguments of `display-buffer'.
+The second argument of `display-buffer' now accepts a list of buffer
+display specifiers. A new third argument accepts a label to identify
+buffers whose names are not expressive enough.
+
+*** Functions for displaying and popping and switching to buffers.
+The `display-buffer', `pop-to-buffer' and `switch-to-buffer' families of
+functions are all based on buffer display specifiers now. A number of
+new functions with unified mnemnonics like `display-buffer-same-frame',
+`pop-to-buffer-same-frame' and `switch-to-buffer-same-frame' have been
+added. By convention, functions in the `switch-to-buffer' family are
+now recommended for interactive use only. Application are supposed to
+use function from the `pop-to-buffer' family instead.
+
+*** Atomic windows.
+Atomic windows are internal windows that are treated by a number of
+functions like `split-window', `delete-window' and
+`delete-other-windows' atomically. This means that any of these
+operations when applied to a subwindow of the atomic window is applied
+to the entire atomic window instead. Atomic windows can be either
+created automatically with the help of buffer display specifiers or
+manually via the `window-atom' window parameter.
+
+*** Side windows.
+Side windows are special windows located at one of the four sides of a
+frame. Side windows are useful for assigning buffers always the same
+location within a frame whenever they are shown there. Side windows are
+by default semi-permanent which means that functions like
+`delete-other-windows' do not delete them. Side windows can be either
+created automatically with the help of buffer display specifiers or
+manually via the `window-side' window parameter.
\f
* Editing Changes in Emacs 24.1
+2011-05-30 Martin Rudalics <rudalics@gmx.at>
+
+ * window.el (ignore-window-parameters, window-size-fixed):
+ Rewrite doc-strings.
+ (window-min-delta-1, window-min-delta): Reorder. Minor rewrite.
+ (resize-subwindows-normal): Use zerop when checking other-delta.
+ Call window-min-delta with NODOWN argument nil.
+ (adjust-window-trailing-edge): Fix doc-string.
+ (other-window): Fix doc-string and respect
+ ignore-window-parameters.
+ (delete-window, delete-other-windows): Fix doc-strings. Remove
+ -function postfix from associated window parameters.
+ (quit-restore-window): Resize only if buffer was in
+ temp-buffer-resize-mode.
+ (window-split-min-size): Rewrite doc-string.
+ (split-window): Rewrite doc-string. Rename horflag to
+ horizontal. Major rewrite of size calculations. Remove
+ -function postfix from associated window parameter.
+ (window-state-put-1, display-buffer-split-window-1): Rename
+ horflag to horizontal.
+ (same-window-p): Remove call to non-existent function.
+
2011-05-21 Glenn Morris <rgm@gnu.org>
* image-mode.el (image-after-revert-hook):
;;;;;; dired-run-shell-command dired-do-shell-command dired-do-async-shell-command
;;;;;; dired-clean-directory dired-do-print dired-do-touch dired-do-chown
;;;;;; dired-do-chgrp dired-do-chmod dired-compare-directories dired-backup-diff
-;;;;;; dired-diff) "dired-aux" "dired-aux.el" "e34e1bbdb701078d52466c319d8e0cda")
+;;;;;; dired-diff) "dired-aux" "dired-aux.el" "7efcfe4f9e0913ae4a87be014010c27f")
;;; Generated autoloads from dired-aux.el
(autoload 'dired-diff "dired-aux" "\
(selected-window)))
(defvar ignore-window-parameters nil
- "If non-nil standard functions ignore window parameters.
+ "If non-nil, standard functions ignore window parameters.
The functions currently affected by this are `split-window',
`delete-window', `delete-other-windows' and `other-window'.
-When this variable equals `pre', parameters are not consulted
-before but are updated after performing the requested operation.
-When this variable equals `post', parameters are consulted before
-but are not updated after performing the requested operation.
-
-The value t means parameters are not consulted before and not
-updated after performing the requested operation. Currently any
-other non-nil value is handled like t.
-
An application may bind this to a non-nil value around calls to
-these functions. If it does so and the value is not `pre', the
-application is fully responsible for correctly setting the
-parameters of all windows participating in the function called.")
+these functions to inhibit processing of window parameters.")
(defconst window-safe-min-height 1
"The absolut minimum number of lines of a window.
If the value is `height', then only the window's height is fixed.
If the value is `width', then only the window's width is fixed.
Any other non-nil value fixes both the width and the height.
+
Emacs won't change the size of any window displaying that buffer,
-unless you explicitly change the size, or Emacs has no other
-choice \(like when deleting a neighboring window).")
+unless it has no other choice \(like when deleting a neighboring
+window).")
(make-variable-buffer-local 'window-size-fixed)
(defsubst window-size-ignore (window ignore)
(window-size-fixed-1
(normalize-any-window window) horizontal))
-(defun window-min-delta (&optional window horizontal ignore trail noup nodown)
- "Return number of lines by which WINDOW can be shrunk.
-WINDOW can be an arbitrary window and defaults to the selected
-window. Return zero if WINDOW cannot be shrunk.
-
-Optional argument HORIZONTAL non-nil means return number of
-columns by which WINDOW can be shrunk.
-
-Optional argument IGNORE non-nil means ignore any restrictions
-imposed by fixed size windows, `window-min-height' or
-`window-min-width' settings. IGNORE a window means ignore
-restrictions for that window only. IGNORE equal `safe' means
-live windows may get as small as `window-safe-min-height' lines
-and `window-safe-min-width' columns.
-
-Optional argument TRAIL `before' means only windows to the left
-of or above WINDOW can be enlarged. Optional argument TRAIL
-`after' means only windows to the right of or below WINDOW can be
-enlarged.
-
-Optional argument NOUP non-nil means don't go up in the window
-tree but try to enlarge windows within WINDOW's combination only.
-
-Optional argument NODOWN non-nil means don't check whether WINDOW
-and its subwindows can be shrunk."
- (setq window (normalize-any-window window))
- (let ((size (window-total-size window horizontal))
- (minimum (window-min-size window horizontal ignore)))
- (if (and (not nodown) (= size minimum))
- ;; Nothing to recover.
- 0
- (window-min-delta-1
- ;; Think positive.
- window (- size minimum) horizontal ignore trail noup))))
-
(defun window-min-delta-1 (window delta &optional horizontal ignore trail noup)
"Internal function for `window-min-delta'."
(if (not (window-parent window))
- 0 ; delta
- ;;; (min delta
- ;;; (- (window-total-size window horizontal)
- ;;; (window-min-size window horizontal ignore)))
+ ;; If we can't go up, return zero.
+ 0
+ ;; Else try to find a non-fixed-size sibling of WINDOW.
(let* ((parent (window-parent window))
(sub (window-child parent)))
(catch 'done
(if (window-iso-combined-p sub horizontal)
;; In an iso-combination throw DELTA if we find at least one
- ;; subwindow and that subwindow is either non-fixed-size or
- ;; we can ignore fixed-sizeness.
+ ;; subwindow and that subwindow is either not of fixed-size
+ ;; or we can ignore fixed-sizeness.
(let ((skip (eq trail 'after)))
(while sub
(cond
delta
(window-min-delta-1 parent delta horizontal ignore trail))))))
-(defun window-max-delta (&optional window horizontal ignore trail noup nodown)
- "Return maximum number of lines WINDOW by which WINDOW can be enlarged.
+(defun window-min-delta (&optional window horizontal ignore trail noup nodown)
+ "Return number of lines by which WINDOW can be shrunk.
WINDOW can be an arbitrary window and defaults to the selected
-window. The return value is zero if WINDOW cannot be enlarged.
+window. Return zero if WINDOW cannot be shrunk.
-Optional argument HORIZONTAL non-nil means return maximum number
-of columns by which WINDOW can be enlarged.
+Optional argument HORIZONTAL non-nil means return number of
+columns by which WINDOW can be shrunk.
Optional argument IGNORE non-nil means ignore any restrictions
imposed by fixed size windows, `window-min-height' or
and `window-safe-min-width' columns.
Optional argument TRAIL `before' means only windows to the left
-of or below WINDOW can be shrunk. Optional argument TRAIL
-`after' means only windows to the right of or above WINDOW can be
-shrunk.
+of or above WINDOW can be enlarged. Optional argument TRAIL
+`after' means only windows to the right of or below WINDOW can be
+enlarged.
Optional argument NOUP non-nil means don't go up in the window
-tree but try to obtain the entire space from windows within
-WINDOW's combination.
+tree but try to enlarge windows within WINDOW's combination only.
-Optional argument NODOWN non-nil means do not check whether
-WINDOW and its subwindows can be enlarged."
+Optional argument NODOWN non-nil means don't check whether WINDOW
+itself \(and its subwindows) can be shrunk; check only whether at
+least one other windows can be enlarged appropriately."
(setq window (normalize-any-window window))
- (if (and (not (window-size-ignore window ignore))
- (not nodown) (window-size-fixed-p window horizontal))
- 0
- (window-max-delta-1 window 0 horizontal ignore trail noup)))
+ (let ((size (window-total-size window horizontal))
+ (minimum (window-min-size window horizontal ignore)))
+ (cond
+ (nodown
+ ;; If NODOWN is t, try to recover the entire size of WINDOW.
+ (window-min-delta-1 window size horizontal ignore trail noup))
+ ((= size minimum)
+ ;; If NODOWN is nil and WINDOW's size is already at its minimum,
+ ;; there's nothing to recover.
+ 0)
+ (t
+ ;; Otherwise, try to recover whatever WINDOW is larger than its
+ ;; minimum size.
+ (window-min-delta-1
+ window (- size minimum) horizontal ignore trail noup)))))
(defun window-max-delta-1 (window delta &optional horizontal ignore trail noup)
"Internal function of `window-max-delta'."
(throw 'fixed delta))
(setq sub (window-right sub))))
(if noup
+ ;; When NOUP is nil, DELTA is all we can get.
delta
- ;; Try to go up.
+ ;; Else try with parent of WINDOW, passing the DELTA we
+ ;; recovered so far.
(window-max-delta-1 parent delta horizontal ignore trail))))))
+(defun window-max-delta (&optional window horizontal ignore trail noup nodown)
+ "Return maximum number of lines WINDOW by which WINDOW can be enlarged.
+WINDOW can be an arbitrary window and defaults to the selected
+window. The return value is zero if WINDOW cannot be enlarged.
+
+Optional argument HORIZONTAL non-nil means return maximum number
+of columns by which WINDOW can be enlarged.
+
+Optional argument IGNORE non-nil means ignore any restrictions
+imposed by fixed size windows, `window-min-height' or
+`window-min-width' settings. IGNORE a window means ignore
+restrictions for that window only. IGNORE equal `safe' means
+live windows may get as small as `window-safe-min-height' lines
+and `window-safe-min-width' columns.
+
+Optional argument TRAIL `before' means only windows to the left
+of or below WINDOW can be shrunk. Optional argument TRAIL
+`after' means only windows to the right of or above WINDOW can be
+shrunk.
+
+Optional argument NOUP non-nil means don't go up in the window
+tree but try to obtain the entire space from windows within
+WINDOW's combination.
+
+Optional argument NODOWN non-nil means do not check whether
+WINDOW itself \(and its subwindows) can be enlarged; check only
+whether other windows can be shrunk appropriately."
+ (setq window (normalize-any-window window))
+ (if (and (not (window-size-ignore window ignore))
+ (not nodown) (window-size-fixed-p window horizontal))
+ ;; With IGNORE and NOWDON nil return zero if WINDOW has fixed
+ ;; size.
+ 0
+ ;; WINDOW has no fixed size.
+ (window-max-delta-1 window 0 horizontal ignore trail noup)))
+
;; Make NOUP also inhibit the min-size check.
(defun window-resizable (window delta &optional horizontal ignore trail noup nodown)
"Return DELTA if WINDOW can be resized vertically by DELTA lines.
have been obtained from \(or returned to) an ancestor window of
PARENT in order to resize WINDOW."
(let* ((delta-normal
- (if (and (not other-delta)
- (= (- this-delta) (window-total-size window horizontal)))
- ;; When WINDOW gest deleted and we can return its entire
+ (if (and (= (- this-delta) (window-total-size window horizontal))
+ (zerop other-delta))
+ ;; When WINDOW gets deleted and we can return its entire
;; space to its siblings, use WINDOW's normal size as the
;; normal delta.
(- (window-normal-size window horizontal))
(set-window-new-normal
sub
(cons
- (window-min-delta sub horizontal ignore trail t t)
+ ;; We used to call this with NODOWN t, "fixed" 2011-05-11.
+ (window-min-delta sub horizontal ignore trail t) ; t)
(- (/ (float (window-total-size sub horizontal))
parent-total)
(window-normal-size sub horizontal)))))
Optional argument HORIZONTAL non-nil means move WINDOW's right
edge by DELTA columns. WINDOW defaults to the selected window.
-If the edge can't be moved by DELTA lines, move it as far as
-possible in the desired direction."
+If DELTA is greater zero, then move the edge downwards or to the
+right. If DELTA is less than zero, move the edge upwards or to
+the left. If the edge can't be moved by DELTA lines or columns,
+move it as far as possible in the desired direction."
(setq window (normalize-any-window window))
(let ((frame (window-frame window))
(right window)
(setq frame (normalize-live-frame frame))
(window-tree-1 (frame-root-window frame) t))
\f
-;;; Getting the "other" window.
-;; FIXME: Handle `ignore-window-parameters' and some other things maybe.
(defun other-window (count &optional all-frames)
"Select another window in cyclic ordering of windows.
COUNT specifies the number of windows to skip, starting with the
window, so select the selected window. In an interactive call,
COUNT is the numeric prefix argument. Return nil.
-Do not select a window whose `no-other-window' window parameter
-is non-nil. If the `other-window-function' parameter of WINDOW
-is a function call that function with the arguments COUNT and
-ALL-FRAMES.
+If the `other-window' parameter of WINDOW is a function and
+`ignore-window-parameters' is nil, call that function with the
+arguments COUNT and ALL-FRAMES.
+
+This function does not select a window whose `no-other-window'
+window parameter is non-nil.
This function uses `next-window' for finding the window to
select. The argument ALL-FRAMES has the same meaning as in
always effectively nil."
(interactive "p")
(let* ((window (selected-window))
- (function (window-parameter window 'other-window-function))
+ (function (and (not ignore-window-parameters)
+ (window-parameter window 'other-window)))
old-window old-count)
(if (functionp function)
(funcall function count all-frames)
(setq count (1+ count)))))
(select-window window)
+ ;; Always return nil.
nil))))
;; This should probably return non-nil when the selected window is part
WINDOW can be an arbitrary window and defaults to the selected
one. Return nil.
-If `ignore-window-parameters' is non-nil, ignore any parameters
-of WINDOW. Otherwise, if the `delete-window-function' parameter
-of WINDOW equals t, delete WINDOW ignoring any other window
-parameters. If the `delete-window-function' parameter specifies
-a function, call that function with WINDOW as its sole argument.
-It's the responsibility of that function to adjust the parameters
-of all remaining windows.
+If the variable `ignore-window-parameters' is non-nil or the
+`delete-window' parameter of WINDOW equals t, do not process any
+parameters of WINDOW. Otherwise, if the `delete-window'
+parameter of WINDOW specifies a function, call that function with
+WINDOW as its sole argument and return the value returned by that
+function.
Otherwise, if WINDOW is part of an atomic window, call
`delete-window' with the root of the atomic window as its
(interactive)
(setq window (normalize-any-window window))
(let* ((frame (window-frame window))
- (function (window-parameter window 'delete-window-function))
+ (function (window-parameter window 'delete-window))
(parent (window-parent window))
atom-root)
(window-check frame)
;; Handle window parameters.
(cond
;; Ignore window parameters if `ignore-window-parameters' tells
- ;; us so or `delete-window-function' equals t.
+ ;; us so or `delete-window' equals t.
((or ignore-window-parameters (eq function t)))
((functionp function)
- ;; The `delete-window-function' parameter specifies the function
- ;; to call. If that function is `ignore' nothing is done. It's
- ;; up to the function called here to avoid infinite recursion.
+ ;; The `delete-window' parameter specifies the function to call.
+ ;; If that function is `ignore' nothing is done. It's up to the
+ ;; function called here to avoid infinite recursion.
(throw 'done (funcall function window)))
((and (window-parameter window 'window-atom)
(setq atom-root (window-atom-root window))
sibling (+ (window-normal-size sibling horizontal)
(window-normal-size window horizontal))))
((window-resizable-p window (- size) horizontal nil nil nil t)
- ;; Can do it without resizing fixed-size windows.
+ ;; Can do without resizing fixed-size windows.
(resize-other-windows window (- size) horizontal))
(t
;; Can't do without resizing fixed-size windows.
;; `delete-window-internal' has selected a window that should
;; not be selected, fix this here.
(other-window -1 frame))
-
(run-window-configuration-change-hook frame)
(window-check frame)
+ ;; Always return nil.
nil))))
(defun delete-other-windows (&optional window)
WINDOW may be any window and defaults to the selected one.
Return nil.
-If the variable `ignore-window-parameters' is non-nil do not
+If the variable `ignore-window-parameters' is non-nil or the
+`delete-other-windows' parameter of WINDOW equals t, do not
process any parameters of WINDOW. Otherwise, if the
-`delete-other-windows-function' parameter of WINDOW equals t,
-delete WINDOW ignoring other window parameters. If the
-`delete-other-windows-function' parameter specifies a function,
-call that function with WINDOW as its sole argument. It's the
-responsibility of that function to adjust the parameters of all
-remaining windows.
+`delete-other-windows' parameter of WINDOW specifies a function,
+call that function with WINDOW as its sole argument and return
+the value returned by that function.
Otherwise, if WINDOW is part of an atomic window, call this
function with the root of the atomic window as its argument. If
(interactive)
(setq window (normalize-any-window window))
(let* ((frame (window-frame window))
- (function (window-parameter window 'delete-other-windows-function))
+ (function (window-parameter window 'delete-other-windows))
(window-side (window-parameter window 'window-side))
atom-root side-main)
(window-check frame)
(catch 'done
(cond
;; Ignore window parameters if `ignore-window-parameters' is t or
- ;; `delete-other-windows-function' is t.
+ ;; `delete-other-windows' is t.
((or ignore-window-parameters (eq function t)))
((functionp function)
- ;; The `delete-other-windows-function' parameter specifies the
- ;; function to call. If the function is `ignore' no windows are
- ;; deleted. It's up to the function called to avoid infinite
- ;; recursion.
+ ;; The `delete-other-windows' parameter specifies the function
+ ;; to call. If the function is `ignore' no windows are deleted.
+ ;; It's up to the function called to avoid infinite recursion.
(throw 'done (funcall function window)))
((and (window-parameter window 'window-atom)
(setq atom-root (window-atom-root window))
(setq side-main (window-with-parameter 'window-side 'none nil t)))
((memq window-side window-sides)
(error "Cannot make side window the only window")))
-
+ ;; If WINDOW is the main non-side window, do nothing.
(unless (eq window side-main)
(delete-other-windows-internal window side-main)
(run-window-configuration-change-hook frame)
(window-check frame))
+ ;; Always return nil.
nil)))
(defun delete-other-windows-vertically (&optional window)
;; In window switch to previous buffer.
(set-window-dedicated-p window nil)
(switch-to-prev-buffer window 'bury))))
- ;; If a window doesn't show BUFFER, unrecord it nevertheless.
+ ;; If a window doesn't show BUFFER, unrecord BUFFER in it.
(unrecord-window-buffer window buffer)))))
-;;; (defun delete-buffer-window (&optional buffer-or-name frames)
-;;; .... WRITE THIS
-
(defun replace-buffer-in-windows (&optional buffer-or-name)
"Replace BUFFER-OR-NAME with some other buffer in all windows showing it.
BUFFER-OR-NAME may be a buffer or the name of an existing buffer
(setq window (normalize-live-window window))
(let ((buffer (window-buffer window))
(quit-restore (window-parameter window 'quit-restore))
- deletable)
+ deletable resize)
(cond
((and (or (and (memq (car-safe quit-restore) '(new-window new-frame))
;; Check that WINDOW's buffer is still the same.
((and (buffer-live-p (nth 0 quit-restore))
;; The buffer currently shown in WINDOW must still be the
;; buffer shown when its `quit-restore' parameter was created
- ;; in the first place. Leave WINDOW's quit-restore parameter
- ;; alone, it can be reused later.
+ ;; in the first place.
(eq (window-buffer window) (nth 3 quit-restore)))
+ (setq resize (with-current-buffer buffer temp-buffer-resize-mode))
;; Unrecord buffer.
(unrecord-buffer buffer)
(unrecord-window-buffer window buffer)
(set-window-buffer window (nth 0 quit-restore))
(set-window-start window (nth 1 quit-restore))
(set-window-point window (nth 2 quit-restore))
- (unless (= (nth 4 quit-restore) (window-total-size window))
+ (when (and resize (/= (nth 4 quit-restore) (window-total-size window)))
(resize-window
window (- (nth 4 quit-restore) (window-total-size window))))
+ ;; Reset the quit-restore parameter.
(set-window-parameter window 'quit-restore nil)
(when (window-live-p (nth 5 quit-restore))
(select-window (nth 5 quit-restore))))
nil))
\f
;;; Splitting windows.
-(defsubst window-split-min-size (&optional horflag)
- "Return minimum height of any window.
-Optional argument HORFLAG non-nil means return minimum width."
- (if horflag
+(defsubst window-split-min-size (&optional horizontal)
+ "Return minimum height of any window when splitting windows.
+Optional argument HORIZONTAL non-nil means return minimum width."
+ (if horizontal
(max window-min-width window-safe-min-width)
(max window-min-height window-safe-min-height)))
(defun split-window (&optional window size side)
- "Create a new window adjacent to WINDOW.
-WINDOW can be any window and defaults to the selected one. If
-WINDOW was selected before invoking this function, it remains
-selected. Return the new window which is always a live window.
+ "Make a new window adjacent to WINDOW.
+WINDOW can be any window and defaults to the selected one.
+Return the new window which is always a live window.
Optional argument SIZE a positive number means make WINDOW SIZE
-lines/columns tall. If SIZE is negative, make the new window
--SIZE lines/columns tall. If and only if SIZE is non-nil, its
+lines or columns tall. If SIZE is negative, make the new window
+-SIZE lines or columns tall. If and only if SIZE is non-nil, its
absolute value can be less than `window-min-height' or
`window-min-width'; so this command can make a new window as
small as one line or two columns. SIZE defaults to half of
-WINDOW's size. The variable `window-splits' determines whether
-the size of any other windows is affected. Interactively, SIZE
-is the prefix argument.
+WINDOW's size. Interactively, SIZE is the prefix argument.
Optional third argument SIDE nil (or `below') specifies that the
new window shall be located below WINDOW. SIDE `above' means the
fringes and the scrollbar or a divider column. Any other non-nil
value for SIDE is currently handled like t (or `right').
-If WINDOW is part of an atomic window, \"split\" the root of the
-atomic window instead. The new window does not become a member
-of the atomic window. If WINDOW is a side window, signal an
-error.
-
-If you split a live window, properties of the new window like
-margins and scrollbars are inherited from WINDOW. If you split
-an internal window, these properties as well as the buffer
-displayed in the new window are inherited from the window
-selected on WINDOW's frame."
+If the variable `ignore-window-parameters' is non-nil or the
+`split-window' parameter of WINDOW equals t, do not process any
+parameters of WINDOW. Otherwise, if the `split-window' parameter
+of WINDOW specifies a function, call that function with all three
+arguments and return the value returned by that function.
+
+Otherwise, if WINDOW is part of an atomic window, \"split\" the
+root of that atomic window. The new window does not become a
+member of that atomic window.
+
+If WINDOW is live, properties of the new window like margins and
+scrollbars are inherited from WINDOW. If WINDOW is an internal
+window, these properties as well as the buffer displayed in the
+new window are inherited from the window selected on WINDOW's
+frame. The selected window is not changed by this function."
(interactive "i")
(setq window (normalize-any-window window))
- (let* ((horflag (and side (not (memq side '(below above)))))
+ (let* ((horizontal (not (memq side '(nil below above))))
(frame (window-frame window))
- (function (window-parameter window 'split-window-function))
- ;; Rebind this locally since in some cases we do have to nest.
+ (parent (window-parent window))
+ (function (window-parameter window 'split-window))
+ (window-side (window-parameter window 'window-side))
+ ;; Rebind `window-nest' since in some cases we may have to
+ ;; override its value.
(window-nest window-nest)
atom-root)
+
(window-check frame)
(catch 'done
(cond
- ;; Ignore window parameters if `ignore-window-parameters' is t or
- ;; `split-window-function' is t.
+ ;; Ignore window parameters if either `ignore-window-parameters'
+ ;; is t or the `split-window' parameter equals t.
((or ignore-window-parameters (eq function t)))
((functionp function)
- ;; The `split-window-function' parameter specifies the function
- ;; to call instead. If this is `ignore', WINDOW won't be split.
+ ;; The `split-window' parameter specifies the function to call.
+ ;; If that function is `ignore', do nothing.
(throw 'done (funcall function window size side)))
- ;; For an atomic window split the entire atomic window instead.
+ ;; If WINDOW is a subwindow of an atomic window, split the root
+ ;; window of that atomic window instead.
((and (window-parameter window 'window-atom)
(setq atom-root (window-atom-root window))
(not (eq atom-root window)))
(throw 'done (split-window atom-root size side))))
- (let* ((parent (window-parent window))
- ;; Size calculations.
- (parent-size
- (when parent (window-total-size parent horflag)))
- ;; Bind `old-size' to the current size of WINDOW and
- ;; `new-size' to the size of the new window.
- (old-size (window-total-size window horflag))
+ (when (and window-side
+ (or (not parent)
+ (not (window-parameter parent 'window-side))))
+ ;; WINDOW is a side root window. To make sure that a new parent
+ ;; window gets created set `window-nest' to t.
+ (setq window-nest t))
+
+ (when (and window-splits size (> size 0))
+ ;; If `window-splits' is non-nil and SIZE is a non-negative
+ ;; integer, we cannot reasonably resize other windows. Rather
+ ;; bind `window-nest' to t to make sure that subsequent window
+ ;; deletions are handled correctly.
+ (setq window-nest t))
+
+ (let* ((parent-size
+ ;; `parent-size' is the size of WINDOW's parent, provided
+ ;; it has one.
+ (when parent (window-total-size parent horizontal)))
+ ;; `resize' non-nil means we are supposed to resize other
+ ;; windows in WINDOW's combination.
(resize
(and window-splits (not window-nest)
;; Resize makes sense in iso-combinations only.
- (window-iso-combined-p window horflag)
- (or (not size) (< size 0)
- ;; If SIZE is a non-negative integer, we cannot
- ;; resize, bind `window-nest' to t instead to
- ;; make sure that subsequent window deletions are
- ;; handled correctly.
- (and (setq window-nest t) nil))))
+ (window-iso-combined-p window horizontal)))
+ ;; `old-size' is the current size of WINDOW.
+ (old-size (window-total-size window horizontal))
+ ;; `new-size' is the specified or calculated size of the
+ ;; new window.
(new-size
(cond
((not size)
- (max (window-split-min-size horflag)
+ (max (window-split-min-size horizontal)
(if resize
- ;; For a resizing split try to give the new
- ;; window the average size of a window in this
- ;; combination.
+ ;; When resizing try to give the new window the
+ ;; average size of a window in its combination.
(min (- parent-size
- (window-min-size parent horflag))
+ (window-min-size parent horizontal))
(/ parent-size
- (1+ (window-iso-combinations parent horflag))))
+ (1+ (window-iso-combinations
+ parent horizontal))))
;; Else try to give the new window half the size
;; of WINDOW (plus an eventual odd line).
(+ (/ old-size 2) (% old-size 2)))))
;; SIZE non-negative specifies the new size of WINDOW.
;; Note: Specifying a non-negative SIZE is practically
- ;; always done to have a workaround for making the new
- ;; window appear above or on the left of the new window
- ;; (the ispell window is a typical example of that). In
- ;; all these cases the SIDE argument should be set to
- ;; 'above or 'left in order to support the 'resize
- ;; option. Here we will nest the windows instead.
+ ;; always done as workaround for making the new window
+ ;; appear above or on the left of the new window (the
+ ;; ispell window is a typical example of that). In all
+ ;; these cases the SIDE argument should be set to 'above
+ ;; or 'left in order to support the 'resize option.
+ ;; Here we have to nest the windows instead, see above.
(- old-size size))
(t
;; SIZE negative specifies the size of the new window.
(- size))))
- (new-normal
- ;; The normal size of the new window.
- (cond
- (size (/ (float new-size)
- (or parent-size (window-total-size window horflag))))
- (resize (/ 1.0 (1+ (window-iso-combinations parent horflag))))
- (t (/ (window-normal-size window horflag) 2))))
- (root (window-parameter window 'root))
- (window-side (window-parameter window 'window-side)))
- ;; Check window types and handle `window-nest' with sides.
- (when (and window-side
- (or (not parent)
- (not (window-parameter parent 'window-side))))
- ;; A side root window. Make sure a new parent gets created.
- ;; Reset `resize' to nil too.
- (setq window-nest t)
- (setq resize nil))
-
- ;; Check the sizes.
+ new-parent new-normal)
+
+ ;; Check SIZE.
(cond
((not size)
(cond
(resize
- ;; Size unspecified, resizing.
- (when (and (not (window-sizable-p parent (- new-size) horflag))
- ;; Try agin with minimum acceptable size.
+ ;; SIZE unspecified, resizing.
+ (when (and (not (window-sizable-p parent (- new-size) horizontal))
+ ;; Try again with minimum split size.
(setq new-size
- (max new-size
- (window-split-min-size horflag)))
- (not (window-sizable-p parent (- new-size) horflag)))
- (error "Cannot resize %s" parent)))
- ((> (+ new-size (window-min-size window horflag)) old-size)
- ;; Size unspecified, no resizing.
- (error "Cannot resize %s" window))))
+ (max new-size (window-split-min-size horizontal)))
+ (not (window-sizable-p parent (- new-size) horizontal)))
+ (error "Window %s too small for splitting" parent)))
+ ((> (+ new-size (window-min-size window horizontal)) old-size)
+ ;; SIZE unspecified, no resizing.
+ (error "Window %s too small for splitting" window))))
((and (>= size 0)
(or (>= size old-size)
- (< new-size (if horflag
+ (< new-size (if horizontal
window-safe-min-width
window-safe-min-width))))
- ;; Size specified as new size of old window. If the new size
+ ;; SIZE specified as new size of old window. If the new size
;; is larger than the old size or the size of the new window
- ;; would be less than the safe minimum signal an error.
- (error "Cannot resize %s" window))
+ ;; would be less than the safe minimum, signal an error.
+ (error "Window %s too small for splitting" window))
(resize
- ;; Size specified, resizing.
- (unless (window-sizable-p parent (- new-size) horflag)
+ ;; SIZE specified, resizing.
+ (unless (window-sizable-p parent (- new-size) horizontal)
;; If we cannot resize the parent give up.
- (error "Cannot resize %s" parent)))
+ (error "Window %s too small for splitting" parent)))
((or (< new-size
- (if horflag window-safe-min-width window-safe-min-height))
+ (if horizontal window-safe-min-width window-safe-min-height))
(< (- old-size new-size)
- (if horflag window-safe-min-width window-safe-min-height)))
- (error "Cannot resize %s" window)))
+ (if horizontal window-safe-min-width window-safe-min-height)))
+ ;; SIZE specification violates minimum size restrictions.
+ (error "Window %s too small for splitting" window)))
- (resize-window-reset frame horflag)
- (cond
- (resize
- ;; Try to get space from OLD's siblings. We could go "up" and
- ;; try getting additional space from surrounding windows but
- ;; we won't be able to return space to those windows when we
- ;; delete the one we create here. Hence we do not go up.
- (resize-subwindows parent (- new-size) horflag)
- (let* ((normal (- 1 new-normal))
- (sub (window-child parent)))
- (while sub
- (set-window-new-normal
- sub (* (window-normal-size sub horflag) normal))
- (setq sub (window-right sub)))))
- (window-nest
- ;; Get entire space from WINDOW making sure that a new parent
- ;; windows gets created.
- (set-window-new-total window (- old-size new-size))
- (resize-this-window window (- new-size) horflag)
- (set-window-new-normal
- window (- (window-normal-size window horflag) new-normal)))
- (t
- ;; Get entire space from WINDOW making a new parent window only
- ;; if we need one.
+ (resize-window-reset frame horizontal)
+
+ (setq new-parent
+ ;; Make new-parent non-nil if we need a new parent window;
+ ;; either because we want to nest or because WINDOW is not
+ ;; iso-combined.
+ (or window-nest (not (window-iso-combined-p window horizontal))))
+ (setq new-normal
+ ;; Make new-normal the normal size of the new window.
+ (cond
+ (size (/ (float new-size) (if new-parent old-size parent-size)))
+ (new-parent 0.5)
+ (resize (/ 1.0 (1+ (window-iso-combinations parent horizontal))))
+ (t (/ (window-normal-size window horizontal) 2.0))))
+
+ (if resize
+ ;; Try to get space from OLD's siblings. We could go "up" and
+ ;; try getting additional space from surrounding windows but
+ ;; we won't be able to return space to those windows when we
+ ;; delete the one we create here. Hence we do not go up.
+ (progn
+ (resize-subwindows parent (- new-size) horizontal)
+ (let* ((normal (- 1.0 new-normal))
+ (sub (window-child parent)))
+ (while sub
+ (set-window-new-normal
+ sub (* (window-normal-size sub horizontal) normal))
+ (setq sub (window-right sub)))))
+ ;; Get entire space from WINDOW.
(set-window-new-total window (- old-size new-size))
- (resize-this-window window (- new-size) horflag)
+ (resize-this-window window (- new-size) horizontal)
(set-window-new-normal
- window (- (window-normal-size window horflag) new-normal))))
-
- (let* ((new (split-window-internal window new-size side new-normal))
- (new-parent (window-parent new)))
- (when window-side
- ;; Inherit window-side parameters, if necessary.
- (unless (eq parent new-parent)
- (set-window-parameter new-parent 'window-side window-side))
+ window (- (if new-parent 1.0 (window-normal-size window horizontal))
+ new-normal)))
+
+ (let* ((new (split-window-internal window new-size side new-normal)))
+ ;; Inherit window-side parameters, if any.
+ (when (and window-side new-parent)
+ (set-window-parameter (window-parent new) 'window-side window-side)
(set-window-parameter new 'window-side window-side))
(run-window-configuration-change-hook frame)
(window-check frame)
+ ;; Always return the new window.
new)))))
;; I think this should be the default; I think people will prefer it--rms.
(defalias 'split-window-horizontally 'split-window-side-by-side)
\f
;;; Balancing windows.
-(defun balance-windows (&optional window-or-frame)
- "Balance the sizes of subwindows of WINDOW-OR-FRAME.
-WINDOW-OR-FRAME is optional and defaults to the selected frame.
-If WINDOW-OR-FRAME denotes a frame, balance the sizes of all
-subwindows of that frame's root window. If WINDOW-OR-FRAME
-denots a window, balance the sizes of all subwindows of that
-window."
- (interactive)
- (let* ((window
- (cond
- ((or (not window-or-frame)
- (frame-live-p window-or-frame))
- (frame-root-window window-or-frame))
- ((or (window-live-p window-or-frame)
- (window-child window-or-frame))
- window-or-frame)
- (t
- (error "Not a window or frame %s" window-or-frame))))
- (frame (window-frame window)))
- ;; Balance vertically.
- (resize-window-reset (window-frame window))
- (balance-windows-1 window)
- (resize-window-apply frame)
- ;; Balance horizontally.
- (resize-window-reset (window-frame window) t)
- (balance-windows-1 window t)
- (resize-window-apply frame t)))
-(defun balance-windows-1 (window &optional horizontal)
- "Subroutine of `balance-windows'."
- (if (window-child window)
- (let ((sub (window-child window)))
- (if (window-iso-combined-p sub horizontal)
- (balance-windows-2 window horizontal)
- (let ((size (window-new-total window)))
- (while sub
- (set-window-new-total sub size)
- (balance-windows-1 sub horizontal)
- (setq sub (window-right sub))))))))
-
-;; The following routine uses the recycled code from the old version of
+;; The following routine uses the recycled code from an old version of
;; `resize-subwindows'. It's not very pretty, but coding it the way the
;; new `resize-subwindows' code does would hardly make it any shorter or
;; more readable (FWIW we'd need three loops - one to calculate the
(balance-windows-1 sub horizontal)
(setq sub (window-right sub)))))
+(defun balance-windows-1 (window &optional horizontal)
+ "Subroutine of `balance-windows'."
+ (if (window-child window)
+ (let ((sub (window-child window)))
+ (if (window-iso-combined-p sub horizontal)
+ (balance-windows-2 window horizontal)
+ (let ((size (window-new-total window)))
+ (while sub
+ (set-window-new-total sub size)
+ (balance-windows-1 sub horizontal)
+ (setq sub (window-right sub))))))))
+
+(defun balance-windows (&optional window-or-frame)
+ "Balance the sizes of subwindows of WINDOW-OR-FRAME.
+WINDOW-OR-FRAME is optional and defaults to the selected frame.
+If WINDOW-OR-FRAME denotes a frame, balance the sizes of all
+subwindows of that frame's root window. If WINDOW-OR-FRAME
+denots a window, balance the sizes of all subwindows of that
+window."
+ (interactive)
+ (let* ((window
+ (cond
+ ((or (not window-or-frame)
+ (frame-live-p window-or-frame))
+ (frame-root-window window-or-frame))
+ ((or (window-live-p window-or-frame)
+ (window-child window-or-frame))
+ window-or-frame)
+ (t
+ (error "Not a window or frame %s" window-or-frame))))
+ (frame (window-frame window)))
+ ;; Balance vertically.
+ (resize-window-reset (window-frame window))
+ (balance-windows-1 window)
+ (resize-window-apply frame)
+ ;; Balance horizontally.
+ (resize-window-reset (window-frame window) t)
+ (balance-windows-1 window t)
+ (resize-window-apply frame t)))
+
(defun window-fixed-size-p (&optional window direction)
"Return t if WINDOW cannot be resized in DIRECTION.
WINDOW defaults to the selected window. DIRECTION can be
(setq window-state-put-list
(cons (cons window state) window-state-put-list)))
((memq type '(vc hc))
- (let* ((horflag (eq type 'hc))
- (total (window-total-size window horflag))
+ (let* ((horizontal (eq type 'hc))
+ (total (window-total-size window horizontal))
(first t)
size new)
(dolist (item state)
(setq size
(if totals
;; Use total size.
- (cdr (assq (if horflag 'total-width 'total-height) item))
+ (cdr (assq (if horizontal 'total-width 'total-height) item))
;; Use normalized size and round.
(round (* total
(cdr (assq
- (if horflag 'normal-width 'normal-height)
+ (if horizontal 'normal-width 'normal-height)
item))))))
;; Use safe sizes, we try to resize later.
- (setq size (max size (if horflag
+ (setq size (max size (if horizontal
window-safe-min-height
window-safe-min-width)))
- (if (window-sizable-p window (- size) horflag 'safe)
+ (if (window-sizable-p window (- size) horizontal 'safe)
(let* ((window-nest (assq 'nest item)))
;; We must inherit the nesting, otherwise we might mess
;; up handling of atomic and side window.
- (setq new (split-window window size horflag)))
+ (setq new (split-window window size horizontal)))
;; Give up if we can't resize window down to safe sizes.
(error "Cannot resize window %s" window))
(defun display-buffer-split-window-1 (window side min-size)
"Subroutine of `display-buffer-split-window'."
- (let* ((horflag (memq side '(left right)))
+ (let* ((horizontal (memq side '(left right)))
(parent (window-parent window))
- (resize (and window-splits (window-iso-combined-p window horflag)))
+ (resize (and window-splits (window-iso-combined-p window horizontal)))
(old-size
;; We either resize WINDOW or its parent.
- (window-total-size (if resize parent window) horflag))
+ (window-total-size (if resize parent window) horizontal))
new-size)
;; We don't call split-window-vertically/-horizontally any more
;; here. If for some reason it's needed we can always do so
;; MIN-SIZE large after the split.
(setq new-size
(max min-size
- (min (- old-size (window-min-size parent horflag))
+ (min (- old-size (window-min-size parent horizontal))
(/ old-size
;; Try to make the size of the new window
;; proportional to the number of iso-arranged
;; windows in the combination.
- (1+ (window-iso-combinations parent horflag))))))
- (when (window-sizable-p parent (- new-size) horflag)
+ (1+ (window-iso-combinations parent horizontal))))))
+ (when (window-sizable-p parent (- new-size) horizontal)
(split-window window (- new-size) side)))
((window-live-p window)
(setq new-size (/ old-size 2))
;; When WINDOW is live, the old _and_ the new window must be at
;; least MIN-SIZE large after the split.
(when (and (>= new-size min-size)
- (window-sizable-p window (- new-size) horflag))
+ (window-sizable-p window (- new-size) horizontal))
;; Do an even split to make Stepan happy.
(split-window window nil side)))
(t
;; Try to make the size of the new window
;; proportional to the number of iso-arranged
;; subwindows of WINDOW.
- (1+ (window-iso-combinations window horflag)))))
- (when (window-sizable-p window (- new-size) horflag)
+ (1+ (window-iso-combinations window horizontal)))))
+ (when (window-sizable-p window (- new-size) horizontal)
(split-window window (- new-size) side))))))
(defun display-buffer-split-window (window &optional side specifiers)
`special-display-regexps' contain a list entry whose car equals
or matches BUFFER-NAME, the return value is the cdr of that
entry."
- (let ((buffer-names (with-no-warnings
- special-display-buffer-names))
- (regexps (with-no-warnings
- special-display-regexps))
+ (let ((buffer-names (with-no-warnings special-display-buffer-names))
+ (regexps (with-no-warnings special-display-regexps))
tmp)
(cond
((not (stringp buffer-name)))
`pop-to-buffer' would show a buffer named BUFFER-NAME in the
selected rather than \(as usual\) some other window. See
`same-window-buffer-names' and `same-window-regexps'."
- (let ((buffer-names (with-no-warnings
- (same-window-buffer-names)))
- (regexps (with-no-warnings
- (same-window-regexps))))
+ (let ((buffer-names (with-no-warnings special-display-buffer-names))
+ (regexps (with-no-warnings special-display-regexps)))
(cond
((not (stringp buffer-name)))
;; The elements of `same-window-buffer-names' can be buffer
+2011-05-30 Martin Rudalics <rudalics@gmx.at>
+
+ * window.c (Fsplit_window_internal): Make all arguments
+ mandatory. Rewrite doc-string. Simplify code.
+
2011-05-21 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
* dispnew.c (scrolling_window): Don't exclude the case that the
}
-DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 2, 4, 0,
- doc: /* Split window OLD vertically giving the new window SIZE lines.
-Optional argument SIDE non-nil means split OLD giving the new
-window SIZE columns. In any case SIZE must be a positive integer.
-
-Optional third argument SIDE nil (or `below') specifies that the
-new window shall be located below WINDOW. SIDE `above' means the
-new window shall be located above WINDOW. In these cases SIZE specifies
-the new number of lines for WINDOW (or the new window provided SIZE is
-negative) including space reserved for the mode and/or header line.
-
-SIDE t (or `right') specifies that the new window shall be located
-on the right side of WINDOW. SIDE `left' means the new window
-shall be located on the left of WINDOW. In these cases SIZE specifies
-the new number of columns for WINDOW (or the new window provided SIZE is
-negative) including space reserved for fringes and the scrollbar or a
-divder column.
-
-Optional fourth argument NORMAL-SIZE specifies the normal size of the
-new window. */)
- (Lisp_Object old, Lisp_Object size, Lisp_Object side, Lisp_Object normal_size)
+DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0,
+ doc: /* Split window OLD.
+Second argument TOTAL-SIZE specifies the number of lines or columns of the
+new window. In any case TOTAL-SIZE must be a positive integer
+
+Third argument SIDE nil (or `below') specifies that the new window shall
+be located below WINDOW. SIDE `above' means the new window shall be
+located above WINDOW. In both cases TOTAL-SIZE specifies the number of
+lines of the new window including space reserved for the mode and/or
+header line.
+
+SIDE t (or `right') specifies that the new window shall be located on
+the right side of WINDOW. SIDE `left' means the new window shall be
+located on the left of WINDOW. In both cases TOTAL-SIZE specifies the
+number of columns of the new window including space reserved for fringes
+and the scrollbar or a divider column.
+
+Fourth argument NORMAL-SIZE specifies the normal size of the new window
+according to the SIDE argument.
+
+The new total and normal sizes of all involved windows must have been
+set correctly. See the code of `split-window' for how this is done. */)
+ (Lisp_Object old, Lisp_Object total_size, Lisp_Object side, Lisp_Object normal_size)
{
/* OLD (*o) is the window we have to split. (*p) is either OLD's
parent window or an internal window we have to install as OLD's new
int horflag
/* HORFLAG is 1 when we split side-by-side, 0 otherwise. */
= EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright);
- int do_resize = 0;
int do_nest = 0;
CHECK_WINDOW (old);
frame = WINDOW_FRAME (o);
f = XFRAME (frame);
- CHECK_NUMBER (size);
+ CHECK_NUMBER (total_size);
- /* Set do_nest to 1 if either Vwindow_nest is non-nil, OLD has no
- parent, or OLD is ortho-combined. */
+ /* Set do_nest to 1 if we have to make a new parent window. We do
+ that if either `window-nest' is non-nil, or OLD has no parent, or
+ OLD is ortho-combined. */
do_nest =
!NILP (Vwindow_nest)
|| NILP (o->parent)
? (XWINDOW (o->parent)->hchild)
: (XWINDOW (o->parent)->vchild));
- /* Set do_resize to 1 iff do_nest was not set and Vwindow_splits is
- non-nil. */
- do_resize = !do_nest && !NILP (Vwindow_splits);
-
- /* We may need a live reference window to copy some parameters. */
+ /* We need a live reference window to initialize some parameters. */
if (WINDOW_LIVE_P (old))
+ /* OLD is live, use it as reference window. */
reference = old;
- else /* Neither REFERENCE nor OLD are alive. Use the frame's
- selected window as reference window. */
+ else
+ /* Use the frame's selected window as reference window. */
reference = FRAME_SELECTED_WINDOW (f);
r = XWINDOW (reference);
/* The following bugs are caught by `split-window'. */
if (MINI_WINDOW_P (o))
error ("Attempt to split minibuffer window");
- else if (XINT (size) < (horflag ? 2 : 1))
+ else if (XINT (total_size) < (horflag ? 2 : 1))
error ("Size of new window too small (after split)");
- else if (do_resize)
+ else if (!do_nest && !NILP (Vwindow_splits))
+ /* `window-splits' non-nil means try to resize OLD's siblings
+ proportionally. */
{
p = XWINDOW (o->parent);
/* Temporarily pretend we split the parent window. */
XSETINT (p->new_total,
- XINT (horflag ? p->total_cols : p->total_lines) - XINT (size));
+ XINT (horflag ? p->total_cols : p->total_lines)
+ - XINT (total_size));
if (!resize_window_check (p, horflag))
- error ("Sum of window sizes won't fit");
+ error ("Window sizes don't fit");
else
/* Undo the temporary pretension. */
p->new_total = horflag ? p->total_cols : p->total_lines;
{
if (!resize_window_check (o, horflag))
error ("Resizing old window failed");
- else if (XINT (size) + XINT (o->new_total)
+ else if (XINT (total_size) + XINT (o->new_total)
!= XINT (horflag ? o->total_cols : o->total_lines))
error ("Sum of sizes of old and new window don't fit");
}
/* This is our point of no return. */
- if (NILP (o->parent)
- || NILP (horflag
- ? (XWINDOW (o->parent)->hchild)
- : (XWINDOW (o->parent)->vchild))
- || !NILP (Vwindow_nest))
- /* Make a new parent window in the following cases:
-
- - OLD doesn't have a parent window, or
-
- - OLD is in a vertical (horizontal) combination and shall be
- split side-by-side (above-each-other), or
-
- - we want to nest the new parent window.
-
- Note that the new parent window is a matrjoshka window; so any
- matrjoshka window invariants are temporarily invalid now. */
+ if (do_nest)
{
/* Save the old value of o->normal_cols/lines. It gets corrupted
by make_parent_window and we need it below for assigning it to
p->new_normal. */
Lisp_Object new_normal = horflag ? o->normal_cols : o->normal_lines;
+
make_parent_window (old, horflag);
p = XWINDOW (o->parent);
- /* Store nesting in parent. */
+ /* Store value of `window-nest' in new parent's nest slot. */
p->nest = Vwindow_nest;
- /* Inherit splits from old. */
+ /* Have PARENT inherit splits slot value from OLD. */
p->splits = o->splits;
- /* Set splits in old window. */
+ /* Store value of `window-splits' in OLD's splits slot. */
o->splits = Vwindow_splits;
/* These get applied below. */
p->new_total = horflag ? o->total_cols : o->total_lines;
n->scroll_bar_width = r->scroll_bar_width;
n->vertical_scroll_bar_type = r->vertical_scroll_bar_type;
+ /* Store `window-splits' in NEW's splits slot. */
+ n->splits = Vwindow_splits;
+
+ /* Directly assign orthogonal coordinates and sizes. */
if (horflag)
{
n->top_line = o->top_line;
n->total_cols = o->total_cols;
}
- n->new_total = size;
+ /* Iso-coordinates and sizes are assigned by resize_window_apply,
+ get them ready here. */
+ n->new_total = total_size;
+ n->new_normal = normal_size;
BLOCK_INPUT;
resize_window_apply (p, horflag);
-
- /* Store actual value of `window-splits' for NEW. */
- n->splits = Vwindow_splits;
-
- /* Assign normal size of NEW. */
- if (horflag)
- n->normal_cols = normal_size;
- else
- n->normal_lines = normal_size;
-
adjust_glyphs (f);
- UNBLOCK_INPUT;
-
- /* Set buffer of new window to buffer of reference window. Don't run
+ /* Set buffer of NEW to buffer of reference window. Don't run
any hooks. */
set_window_buffer (new, r->buffer, 0, 1);
+ UNBLOCK_INPUT;
+
/* Maybe we should run the scroll functions in Elisp (which already
runs the configuration change hook). */
if (! NILP (Vwindow_scroll_functions))
run_hook_with_args_2 (Qwindow_scroll_functions, new,
Fmarker_position (n->start));
+ /* Return NEW. */
return new;
}
{
/* Put SIBLING into PARENT's place. */
replace_window (parent, sibling, 0);
- /* Inherit these three. */
+ /* Have SIBLING inherit the following three slot values from
+ PARENT (the nest slot is not inherited). */
s->normal_cols = p->normal_cols;
s->normal_lines = p->normal_lines;
s->splits = p->splits;