Make Temp Buffer Resize Mode less intrusive (Bug#1806).

* window.c (Fsplit_window_internal): Handle only Qt value of
Vwindow_combination_limit separately.
(Qtemp_buffer_resize): New symbol.
(Vwindow_combination_limit): New default value.  Rewrite
doc-string.
* cus-start.el (window-combination-limit): Add new optional
values.
* window.el (temp-buffer-window-show)
(window--try-to-split-window): Obey new values of
window-combination-limit.
(split-window): Test window-combination-limit for t instead of
non-nil.
(display-buffer-at-bottom): New buffer display action function.
* help.el (temp-buffer-resize-regexps): New option.
(temp-buffer-resize-mode): Rewrite doc-string.
(resize-temp-buffer-window): Obey temp-buffer-resize-regexps.
Don't resize reused window.  Suggested by Glen Morris.
This commit is contained in:
Martin Rudalics 2012-09-22 14:56:08 +02:00
parent aa1fe812d3
commit 8e17c9ba14
7 changed files with 178 additions and 62 deletions

View file

@ -719,15 +719,21 @@ recursive invocations.
*** The functions get-lru-window, get-mru-window and get-largest-window
now accept a third argument to avoid choosing the selected window.
*** Additional values recognized for option `window-combination-limit'.
*** New macro `with-temp-buffer-window'.
*** New option `temp-buffer-resize-frames'.
*** New options `temp-buffer-resize-frames' and
`temp-buffer-resize-regexps'.
*** `temp-buffer-resize-mode' no longer resizes windows that have been
reused.
*** New function `fit-frame-to-buffer' and new option
`fit-frame-to-buffer-bottom-margin'.
`fit-frame-to-buffer-bottom-margin'.
*** New display action functions `display-buffer-below-selected' and
`display-buffer-in-previous-window'.
*** New display action functions `display-buffer-below-selected',
`display-buffer-at-bottom' and `display-buffer-in-previous-window'.
*** New display action alist entry `inhibit-switch-frame', if non-nil,
tells display action functions to avoid changing which frame is

View file

@ -1,3 +1,18 @@
2012-09-22 Martin Rudalics <rudalics@gmx.at>
* cus-start.el (window-combination-limit): Add new optional
values.
* window.el (temp-buffer-window-show)
(window--try-to-split-window): Handle new values of
window-combination-limit (Bug#1806).
(split-window): Test window-combination-limit for t instead of
non-nil.
(display-buffer-at-bottom): New buffer display action function.
* help.el (temp-buffer-resize-regexps): New option.
(temp-buffer-resize-mode): Rewrite doc-string.
(resize-temp-buffer-window): Obey temp-buffer-resize-regexps.
Don't resize reused window. Suggested by Glen Morris.
2012-09-22 Stefan Merten <smerten@oekonux.de>
* rst.el: Revamp section title faces.

View file

@ -422,7 +422,17 @@ since it could result in memory overflow and make Emacs crash."
(const :tag "Only on ttys" :value tty)
(other :tag "Always" t)) "23.1")
(window-combination-resize windows boolean "24.1")
(window-combination-limit windows boolean "24.1")
(window-combination-limit
windows (choice
(const :tag "Never (nil)" :value nil)
(const :tag "For Temp Buffer Resize mode (temp-buffer-resize)"
:value temp-buffer-resize)
(const :tag "For temporary buffers (temp-buffer)"
:value temp-buffer)
(const :tag "For buffer display (display-buffer)"
:value display-buffer)
(other :tag "Always (t)" :value t))
"24.3")
;; xdisp.c
(show-trailing-whitespace whitespace-faces boolean nil
:safe booleanp)

View file

@ -990,6 +990,17 @@ window. The height of the root window is subject to the values of
:version "24.2"
:group 'help)
(defcustom temp-buffer-resize-regexps nil
"List of regexps that inhibit Temp Buffer Resize mode.
Any window of a buffer whose name matches one of these regular
expressions is left alone by Temp Buffer Resize mode."
:type '(repeat
:tag "Buffer"
:value ""
(regexp :format "%v"))
:version "24.3"
:group 'help)
(define-minor-mode temp-buffer-resize-mode
"Toggle auto-resizing temporary buffer windows (Temp Buffer Resize Mode).
With a prefix argument ARG, enable Temp Buffer Resize mode if ARG
@ -1001,6 +1012,12 @@ show a temporary buffer are automatically resized in height to
fit the buffer's contents, but never more than
`temp-buffer-max-height' nor less than `window-min-height'.
A window is resized only if it has been specially created for the
buffer. Windows that have shown another buffer before are not
resized. A window showing a buffer whose name matches any of the
expressions in `temp-buffer-resize-regexps' is not resized. A
frame is resized only if `temp-buffer-resize-frames' is non-nil.
This mode is used by `help', `apropos' and `completion' buffers,
and some others."
:global t :group 'help
@ -1017,27 +1034,33 @@ WINDOW can be any live window and defaults to the selected one.
Do not make WINDOW higher than `temp-buffer-max-height' nor
smaller than `window-min-height'. Do nothing if WINDOW is not
vertically combined or some of its contents are scrolled out of
view."
view. Do nothing if the name of WINDOW's buffer matches an
expression in `temp-buffer-resize-regexps'."
(setq window (window-normalize-window window t))
(let ((height (if (functionp temp-buffer-max-height)
(with-selected-window window
(funcall temp-buffer-max-height (window-buffer)))
temp-buffer-max-height)))
(cond
((and (pos-visible-in-window-p (point-min) window)
(window-combined-p window))
(fit-window-to-buffer window height))
((and temp-buffer-resize-frames
(eq window (frame-root-window window))
(memq (car (window-parameter window 'quit-restore))
;; If 'same is too strong, we might additionally check
;; whether the second element is 'frame.
'(same frame)))
(let ((frame (window-frame window)))
(fit-frame-to-buffer
frame (+ (frame-height frame)
(- (window-total-size window))
height)))))))
(let ((buffer-name (buffer-name (window-buffer window))))
(unless (catch 'found
(dolist (regexp temp-buffer-resize-regexps)
(when (string-match regexp buffer-name)
(throw 'found t))))
(let ((height (if (functionp temp-buffer-max-height)
(with-selected-window window
(funcall temp-buffer-max-height (window-buffer)))
temp-buffer-max-height))
(quit-cadr (cadr (window-parameter window 'quit-restore))))
(cond
;; Don't resize WINDOW if it showed another buffer before.
((and (eq quit-cadr 'window)
(pos-visible-in-window-p (point-min) window)
(window-combined-p window))
(fit-window-to-buffer window height))
((and temp-buffer-resize-frames
(eq quit-cadr 'frame)
(eq window (frame-root-window window)))
(let ((frame (window-frame window)))
(fit-frame-to-buffer
frame (+ (frame-height frame)
(- (window-total-size window))
height)))))))))
;;; Help windows.
(defcustom help-window-select 'other

View file

@ -111,7 +111,19 @@ to `display-buffer'."
(set-buffer-modified-p nil)
(setq buffer-read-only t)
(goto-char (point-min))
(when (setq window (display-buffer buffer action))
(when (let ((window-combination-limit
;; When `window-combination-limit' equals
;; `temp-buffer' or `temp-buffer-resize' and
;; `temp-buffer-resize-mode' is enabled in this
;; buffer bind it to t so resizing steals space
;; preferably from the window that was split.
(if (or (eq window-combination-limit 'temp-buffer)
(and (eq window-combination-limit
'temp-buffer-resize)
temp-buffer-resize-mode))
t
window-combination-limit)))
(setq window (display-buffer buffer action)))
(setq frame (window-frame window))
(unless (eq frame (selected-frame))
(raise-frame frame))
@ -3678,9 +3690,8 @@ frame. The selected window is not changed by this function."
(parent (window-parent window))
(function (window-parameter window 'split-window))
(window-side (window-parameter window 'window-side))
;; Rebind `window-combination-limit' and
;; `window-combination-resize' since in some cases we may have
;; to override their value.
;; Rebind the following two variables since in some cases we
;; have to override their value.
(window-combination-limit window-combination-limit)
(window-combination-resize window-combination-resize)
atom-root)
@ -3738,7 +3749,7 @@ frame. The selected window is not changed by this function."
(and window-combination-resize
(or (window-parameter window 'window-side)
(not (eq window-combination-resize 'side)))
(not window-combination-limit)
(not (eq window-combination-limit t))
;; Resize makes sense in iso-combinations only.
(window-combined-p window horizontal)))
;; `old-size' is the current size of WINDOW.
@ -3818,7 +3829,7 @@ frame. The selected window is not changed by this function."
;; 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-combination-limit
(or (eq window-combination-limit t)
(not (window-combined-p window horizontal))))
(setq new-normal
;; Make new-normal the normal size of the new window.
@ -5066,12 +5077,19 @@ Return value returned by `split-window-preferred-function' if it
represents a live window, nil otherwise."
(and (window-live-p window)
(not (frame-parameter (window-frame window) 'unsplittable))
(let ((new-window
;; Since `split-window-preferred-function' might
;; throw an error use `condition-case'.
(condition-case nil
(funcall split-window-preferred-function window)
(error nil))))
(let* ((window-combination-limit
;; When `window-combination-limit' equals
;; `display-buffer' bind it to t so resizing steals
;; space preferably from the window that was split.
(if (eq window-combination-limit 'display-buffer)
t
window-combination-limit))
(new-window
;; Since `split-window-preferred-function' might
;; throw an error use `condition-case'.
(condition-case nil
(funcall split-window-preferred-function window)
(error nil))))
(and (window-live-p new-window) new-window))))
(defun window--frame-usable-p (frame)
@ -5524,6 +5542,29 @@ the selected one."
(window--display-buffer
buffer window 'reuse display-buffer-mark-dedicated)))))
(defun display-buffer-at-bottom (buffer _alist)
"Try displaying BUFFER in a window at the botom of the selected frame.
This either splits the window at the bottom of the frame or the
frame's root window, or reuses an existing window at the bottom
of the selected frame."
(let (bottom-window window)
(walk-window-tree (lambda (window) (setq bottom-window window)))
(or (and (not (frame-parameter nil 'unsplittable))
(setq window (window--try-to-split-window bottom-window))
(window--display-buffer
buffer window 'window display-buffer-mark-dedicated))
(and (not (frame-parameter nil 'unsplittable))
(setq window
(condition-case nil
(split-window (frame-root-window))
(error nil)))
(window--display-buffer
buffer window 'window display-buffer-mark-dedicated))
(and (setq window bottom-window)
(not (window-dedicated-p window))
(window--display-buffer
buffer window 'reuse display-buffer-mark-dedicated)))))
(defun display-buffer-in-previous-window (buffer alist)
"Display BUFFER in a window previously showing it.
If ALIST has a non-nil `inhibit-same-window' entry, the selected

View file

@ -1,3 +1,11 @@
2012-09-22 Martin Rudalics <rudalics@gmx.at>
* window.c (Fsplit_window_internal): Handle only Qt value of
Vwindow_combination_limit separately.
(Qtemp_buffer_resize): New symbol.
(Vwindow_combination_limit): New default value. Rewrite
doc-string.
2012-09-22 Eli Zaretskii <eliz@gnu.org>
* xdisp.c (next_overlay_string): Initialize it->end_charpos for

View file

@ -60,8 +60,7 @@ static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically;
static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
static Lisp_Object Qsafe, Qabove, Qbelow;
static Lisp_Object Qclone_of;
static Lisp_Object Qsafe, Qabove, Qbelow, Qtemp_buffer_resize, Qclone_of;
static int displayed_window_lines (struct window *);
static int count_windows (struct window *);
@ -613,10 +612,10 @@ WINDOW are never \(re-)combined with WINDOW's siblings. */)
DEFUN ("set-window-combination-limit", Fset_window_combination_limit, Sset_window_combination_limit, 2, 2, 0,
doc: /* Set combination limit of window WINDOW to LIMIT; return LIMIT.
WINDOW must be a valid window and defaults to the selected one.
If LIMIT is nil, child windows of WINDOW can be recombined with
WINDOW's siblings. LIMIT t means that child windows of WINDOW are
never \(re-)combined with WINDOW's siblings. Other values are reserved
for future use. */)
If LIMIT is nil, child windows of WINDOW can be recombined with WINDOW's
siblings. LIMIT t means that child windows of WINDOW are never
\(re-)combined with WINDOW's siblings. Other values are reserved for
future use. */)
(Lisp_Object window, Lisp_Object limit)
{
wset_combination_limit (decode_valid_window (window), limit);
@ -3466,7 +3465,7 @@ make_window (void)
allocate_window. */
wset_prev_buffers (w, Qnil);
wset_next_buffers (w, Qnil);
/* Initialize non-Lisp data. Note that allocate_window zeroes out all
non-Lisp data, so do it only for slots which should not be zero. */
w->nrows_scale_factor = w->ncols_scale_factor = 1;
@ -3848,7 +3847,7 @@ set correctly. See the code of `split-window' for how this is done. */)
We do that if either `window-combination-limit' is t, or OLD has no
parent, or OLD is ortho-combined. */
combination_limit =
!NILP (Vwindow_combination_limit)
EQ (Vwindow_combination_limit, Qt)
|| NILP (o->parent)
|| NILP (horflag
? (XWINDOW (o->parent)->hchild)
@ -3903,9 +3902,9 @@ set correctly. See the code of `split-window' for how this is done. */)
make_parent_window (old, horflag);
p = XWINDOW (o->parent);
/* Store value of `window-combination-limit' in new parent's
combination_limit slot. */
wset_combination_limit (p, Vwindow_combination_limit);
/* Store t in the new parent's combination_limit slot to avoid
that its children get merged into another window. */
wset_combination_limit (p, Qt);
/* These get applied below. */
wset_new_total (p, horflag ? o->total_cols : o->total_lines);
wset_new_normal (p, new_normal);
@ -6705,6 +6704,7 @@ syms_of_window (void)
DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows");
DEFSYM (Qrecord_window_buffer, "record-window-buffer");
DEFSYM (Qget_mru_window, "get-mru-window");
DEFSYM (Qtemp_buffer_resize, "temp-buffer-resize");
DEFSYM (Qtemp_buffer_show_hook, "temp-buffer-show-hook");
DEFSYM (Qabove, "above");
DEFSYM (Qbelow, "below");
@ -6800,23 +6800,36 @@ This variable takes no effect if `window-combination-limit' is non-nil. */);
Vwindow_combination_resize = Qnil;
DEFVAR_LISP ("window-combination-limit", Vwindow_combination_limit,
doc: /* If t, splitting a window makes a new parent window.
If this variable is nil, splitting a window will create a new parent
window only if the window has no parent window or the window shall
become a combination orthogonal to the one it is part of.
doc: /* If non-nil, splitting a window makes a new parent window.
The following values are recognized:
If this variable is t, splitting a window always creates a new parent
window. If all splits behave this way, each frame's window tree is a
binary tree and every window but the frame's root window has exactly one
sibling.
nil means splitting a window will create a new parent window only if the
window has no parent window or the window shall become a combination
orthogonal to the one it is part of.
Other values are reserved for future use.
`temp-buffer-resize' means that splitting a window for displaying a
temporary buffer makes a new parent window provided
`temp-buffer-resize-mode' is enabled. Otherwise, this value is
handled like nil.
The value of this variable is also assigned to the combination limit of
the new parent window. The combination limit of a window can be
retrieved via the function `window-combination-limit' and altered by the
function `set-window-combination-limit'. */);
Vwindow_combination_limit = Qnil;
`temp-buffer' means that splitting a window for displaying a temporary
buffer always makes a new parent window. Otherwise, this value is
handled like nil.
`display-buffer' means that splitting a window for displaying a buffer
always makes a new parent window. Since temporary buffers are
displayed by the function `display-buffer', this value is stronger
than `temp-buffer'. Splitting a window for other purpose makes a
new parent window only if needed.
t means that splitting a window always creates a new parent window. If
all splits behave this way, each frame's window tree is a binary
tree and every window but the frame's root window has exactly one
sibling.
Other values are reserved for future use. */);
Vwindow_combination_limit = Qtemp_buffer_resize;
DEFVAR_LISP ("window-persistent-parameters", Vwindow_persistent_parameters,
doc: /* Alist of persistent window parameters.