+2012-11-16 Martin Rudalics <rudalics@gmx.at>
+
+ * windows.texi (Choosing Window): Rewrite description of
+ display-buffer-alist (Bug#12167).
+ (Display Action Functions): Mention inhibit-switch-frame. Fix
+ description of display-buffer-below-selected. Reorder actions.
+ Add example (Bug#12848).
+
2012-11-15 Stefan Monnier <monnier@iro.umontreal.ca>
* keymaps.texi (Translation Keymaps): Add a subsection "Interaction
unless @var{norecord} is non-@code{nil}.
@end deffn
+
@node Choosing Window
@section Choosing a Window for Display
@end defvar
@defopt display-buffer-alist
-The value of this option is an alist mapping regular expressions to
-display actions. If the name of the buffer passed to
-@code{display-buffer} matches a regular expression in this alist, then
-@code{display-buffer} uses the corresponding display action.
+The value of this option is an alist mapping conditions to display
+actions. Each condition may be either a regular expression matching a
+buffer name or a function that takes two arguments - a buffer name and
+the @var{action} argument passed to @code{display-buffer}. If the name
+of the buffer passed to @code{display-buffer} either matches a regular
+expression in this alist or the function specified by a condition
+returns non-@code{nil}, then @code{display-buffer} uses the
+corresponding display action to display the buffer.
@end defopt
@defopt display-buffer-base-action
@code{display-buffer} if no other display actions are given.
@end defvr
+
@node Display Action Functions
@section Action Functions for @code{display-buffer}
@code{pop-up-frames} is non-@code{nil}, it searches all frames on the
current terminal. @xref{Choosing Window Options}.
-If this function chooses a window on another frame, it makes that
-frame visible and raises it if necessary.
+If this function chooses a window on another frame, it makes that frame
+visible and, unless @var{alist} contains an @code{inhibit-switch-frame}
+entry (@pxref{Choosing Window Options}), raises that frame if necessary.
@end defun
@defun display-buffer-pop-up-frame buffer alist
@code{unsplittable} frame parameter; @pxref{Buffer Parameters}).
@end defun
-@defun display-buffer-use-some-window buffer alist
-This function tries to display @var{buffer} by choosing an existing
-window and displaying the buffer in that window. It can fail if all
-windows are dedicated to another buffer (@pxref{Dedicated Windows}).
-@end defun
-
@defun display-buffer-below-selected buffer alist
This function tries to display @var{buffer} in a window below the
-selected window. This means to either split the selected window or
-reuse the window below the selected one.
+selected window. This means to either split the selected window or use
+the window below the selected one. If it does create a new window, it
+will also adjust its size provided @var{alist} contains a suitable
+@code{window-height} or @code{window-width} entry, see above.
@end defun
@defun display-buffer-in-previous-window buffer alist
methods above, even if that window never showed @var{buffer} before.
@end defun
+@defun display-buffer-use-some-window buffer alist
+This function tries to display @var{buffer} by choosing an existing
+window and displaying the buffer in that window. It can fail if all
+windows are dedicated to another buffer (@pxref{Dedicated Windows}).
+@end defun
+
+To illustrate the use of action functions, consider the following
+example.
+
+@example
+@group
+(display-buffer
+ (get-buffer-create "*foo*")
+ '((display-buffer-reuse-window
+ display-buffer-pop-up-window
+ display-buffer-pop-up-frame)
+ (reusable-frames . 0)
+ (window-height . 10) (window-width . 40)))
+@end group
+@end example
+
+@noindent
+Evaluating the form above will cause @code{display-buffer} to proceed as
+follows: If `*foo*' already appears on a visible or iconified frame, it
+will reuse its window. Otherwise, it will try to pop up a new window
+or, if that is impossible, a new frame. If all these steps fail, it
+will try to use some existing window.
+
+ Furthermore, @code{display-buffer} will try to adjust a reused window
+(provided `*foo*' was put by @code{display-buffer} there before) or a
+popped-up window as follows: If the window is part of a vertical
+combination, it will set its height to ten lines. Note that if, instead
+of the number ``10'', we specified the function
+@code{fit-window-to-buffer}, @code{display-buffer} would come up with a
+one-line window to fit the empty buffer. If the window is part of a
+horizontal combination, it sets its width to 40 columns. Whether a new
+window is vertically or horizontally combined depends on the shape of
+the window split and the values of
+@code{split-window-preferred-function}, @code{split-height-threshold}
+and @code{split-width-threshold} (@pxref{Choosing Window Options}).
+
+ Now suppose we combine this call with a preexisting setup for
+`display-buffer-alist' as follows.
+
+@example
+@group
+(let ((display-buffer-alist
+ (cons
+ '("\\*foo\\*"
+ (display-buffer-reuse-window display-buffer-below-selected)
+ (reusable-frames)
+ (window-height . 5))
+ display-buffer-alist)))
+ (display-buffer
+ (get-buffer-create "*foo*")
+ '((display-buffer-reuse-window
+ display-buffer-pop-up-window
+ display-buffer-pop-up-frame)
+ (reusable-frames . 0)
+ (window-height . 10) (window-width . 40))))
+@end group
+@end example
+
+@noindent
+Evaluating this form will cause @code{display-buffer} to first try
+reusing a window showing @code{*foo*} on the selected frame.
+If no such window exists, it will try to split the selected window or,
+if that is impossible, use the window below the selected window.
+
+ If there's no window below the selected one, or the window below the
+selected one is dedicated to its buffer, @code{display-buffer} will
+proceed as described in the previous example. Note, however, that when
+it tries to adjust the height of any reused or popped-up window, it will
+in any case try to set its number of lines to ``5'' since that value
+overrides the corresponding specification in the @var{action} argument
+of @code{display-buffer}.
+
@node Choosing Window Options
@section Additional Options for Displaying Buffers
+2012-11-16 Martin Rudalics <rudalics@gmx.at>
+
+ * window.el (enlarge-window, shrink-window): Don't mention return
+ value in doc-string (Bug#12896).
+ (window--display-buffer): Don't resize frames - it won't work
+ with all window managers and defeat pop-up-frame-alist.
+ (display-buffer-alist): In doc-string explain that CONDITION can
+ be a function and which arguments are passed to it (Bug#12854).
+ (display-buffer-assq-regexp): New argument ACTION. Handle lambda
+ expressions (Bug#12854).
+ (display-buffer): Pass ACTION argument to
+ display-buffer-assq-regexp.
+
2012-11-16 Glenn Morris <rgm@gnu.org>
* window.el (fit-frame-to-buffer-bottom-margin)
Interactively, if no argument is given, make the selected window
one line taller. If optional argument HORIZONTAL is non-nil,
make selected window wider by DELTA columns. If DELTA is
-negative, shrink selected window by -DELTA lines or columns.
-Return nil."
+negative, shrink selected window by -DELTA lines or columns."
(interactive "p")
(let ((minibuffer-window (minibuffer-window)))
(cond
one line smaller. If optional argument HORIZONTAL is non-nil,
make selected window narrower by DELTA columns. If DELTA is
negative, enlarge selected window by -DELTA lines or columns.
-Also see the `window-min-height' variable.
-Return nil."
+Also see the `window-min-height' variable."
(interactive "p")
(let ((minibuffer-window (minibuffer-window)))
(cond
(error nil))))
(defun window--display-buffer (buffer window type &optional alist dedicated)
- "Display BUFFER in WINDOW and make its frame visible.
+ "Display BUFFER in WINDOW.
TYPE must be one of the symbols `reuse', `window' or `frame' and
-is passed unaltered to `display-buffer-record-window'. Set
-`window-dedicated-p' to DEDICATED if non-nil. Return WINDOW if
-BUFFER and WINDOW are live."
+is passed unaltered to `display-buffer-record-window'. ALIST is
+the alist argument of `display-buffer'. Set `window-dedicated-p'
+to DEDICATED if non-nil. Return WINDOW if BUFFER and WINDOW are
+live."
(when (and (buffer-live-p buffer) (window-live-p window))
(display-buffer-record-window type window buffer)
(unless (eq buffer (window-buffer window))
(let ((parameter (window-parameter window 'quit-restore))
(height (cdr (assq 'window-height alist)))
(width (cdr (assq 'window-width alist))))
- (when (or (memq type '(window frame))
+ (when (or (eq type 'window)
(and (eq (car parameter) 'same)
- (memq (nth 1 parameter) '(window frame))))
- ;; Adjust height of new window or frame.
+ (eq (nth 1 parameter) 'window)))
+ ;; Adjust height of window if asked for.
(cond
((not height))
((numberp height)
(* (window-total-size (frame-root-window window))
height))))
(delta (- new-height (window-total-size window))))
- (cond
- ((and (window--resizable-p window delta nil 'safe)
- (window-combined-p window))
- (window-resize window delta nil 'safe))
- ((or (eq type 'frame)
- (and (eq (car parameter) 'same)
- (eq (nth 1 parameter) 'frame)))
- (set-frame-height
- (window-frame window)
- (+ (frame-height (window-frame window)) delta))))))
+ (when (and (window--resizable-p window delta nil 'safe)
+ (window-combined-p window))
+ (window-resize window delta nil 'safe))))
((functionp height)
(ignore-errors (funcall height window))))
- ;; Adjust width of a window or frame.
+ ;; Adjust width of window if asked for.
(cond
((not width))
((numberp width)
(* (window-total-size (frame-root-window window) t)
width))))
(delta (- new-width (window-total-size window t))))
- (cond
- ((and (window--resizable-p window delta t 'safe)
- (window-combined-p window t))
- (window-resize window delta t 'safe))
- ((or (eq type 'frame)
- (and (eq (car parameter) 'same)
- (eq (nth 1 parameter) 'frame)))
- (set-frame-width
- (window-frame window)
- (+ (frame-width (window-frame window)) delta))))))
+ (when (and (window--resizable-p window delta t 'safe)
+ (window-combined-p window t))
+ (window-resize window delta t 'safe))))
((functionp width)
(ignore-errors (funcall width window))))))
+
window))
(defun window--maybe-raise-frame (frame)
"Alist of conditional actions for `display-buffer'.
This is a list of elements (CONDITION . ACTION), where:
- CONDITION is either a regexp matching buffer names, or a function
- that takes a buffer and returns a boolean.
+ CONDITION is either a regexp matching buffer names, or a
+ function that takes two arguments - a buffer name and the
+ ACTION argument of `display-buffer' - and returns a boolean.
ACTION is a cons cell (FUNCTION . ALIST), where FUNCTION is a
function or a list of functions. Each such function should
accept two arguments: a buffer to display and an alist of the
- same form as ALIST. See `display-buffer' for details."
+ same form as ALIST. See `display-buffer' for details.
+
+`display-buffer' scans this alist until it either finds a
+matching regular expression or the function specified by a
+condition returns non-nil. In any of these cases, it adds the
+associated action to the list of actions it will try."
:type `(alist :key-type
(choice :tag "Condition"
regexp
`display-buffer-base-action'. See `display-buffer'.")
(put 'display-buffer-fallback-action 'risky-local-variable t)
-(defun display-buffer-assq-regexp (buffer-name alist)
- "Retrieve ALIST entry corresponding to BUFFER-NAME."
+(defun display-buffer-assq-regexp (buffer-name alist action)
+ "Retrieve ALIST entry corresponding to BUFFER-NAME.
+ACTION is the action argument passed to `display-buffer'."
(catch 'match
(dolist (entry alist)
(let ((key (car entry)))
(when (or (and (stringp key)
(string-match-p key buffer-name))
- (and (symbolp key) (functionp key)
- (funcall key buffer-name alist)))
+ (and (functionp key)
+ (funcall key buffer-name action)))
(throw 'match (cdr entry)))))))
(defvar display-buffer--same-window-action
(funcall display-buffer-function buffer inhibit-same-window)
;; Otherwise, use the defined actions.
(let* ((user-action
- (display-buffer-assq-regexp (buffer-name buffer)
- display-buffer-alist))
+ (display-buffer-assq-regexp
+ (buffer-name buffer) display-buffer-alist action))
(special-action (display-buffer--special-action buffer))
;; Extra actions from the arguments to this function:
(extra-action