Handle window-height and window-width alist entries in `display-buffer'.

In buffer display functions handle window-height/window-width
alist entries.  Suggested by Juri Linkov as fix for Bug#1806.
* window.el (window--display-buffer): New argument ALIST.  Obey
window-height and window-width alist entries.
(window--try-to-split-window): New argument ALIST.  Bind
window-combination-limit to t when the window's size shall be
changed and window-combination-limit equals `window-size'.
(display-buffer-in-atom-window)
(display-buffer-in-major-side-window)
(display-buffer-in-side-window, display-buffer-same-window)
(display-buffer-reuse-window, display-buffer-pop-up-frame)
(display-buffer-pop-up-window, display-buffer-below-selected)
(display-buffer-at-bottom, display-buffer-in-previous-window)
(display-buffer-use-some-window): Adjust all callers of
window--display-buffer and window--try-to-split-window.
(fit-frame-to-buffer): New option.
(fit-window-to-buffer): Can resize frames if fit-frame-to-buffer
is non-nil.
(display-buffer-in-major-side-window): Evaluate window-height /
window-width alist entries.

* help.el (temp-buffer-resize-frames)
(temp-buffer-resize-regexps): Remove options.
(temp-buffer-resize-mode): Adjust doc-string.
(resize-temp-buffer-window): Don't consult
temp-buffer-resize-regexps.  Use fit-frame-to-buffer instead of
temp-buffer-resize-frames.

* dired.el (dired-mark-pop-up): Call
display-buffer-below-selected with a fit-window-to-buffer alist
entry.

* window.c (Vwindow_combination_limit): New default value.
(Qwindow_size): New symbol replacing Qtemp_buffer_resize.
This commit is contained in:
Martin Rudalics 2012-09-30 11:10:59 +02:00
parent a97dc38060
commit 5938d5196d
7 changed files with 295 additions and 202 deletions

View file

@ -738,14 +738,11 @@ now accept a third argument to avoid choosing the selected window.
*** New macro `with-temp-buffer-window'.
*** 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'.
*** New function `fit-frame-to-buffer' and new options
`fit-frame-to-buffer' and `fit-frame-to-buffer-bottom-margin'.
*** New display action functions `display-buffer-below-selected',
`display-buffer-at-bottom' and `display-buffer-in-previous-window'.
@ -760,6 +757,9 @@ non-nil, specifies frame parameters to give any newly-created frame.
*** New display action alist entry `previous-window', if non-nil,
specifies window to reuse in `display-buffer-in-previous-window'.
*** New display action alist entries `window-height' and `window-width'
to specify size of new window created by `display-buffer'.
*** The following variables are obsolete, as they can be replaced by
appropriate entries in the `display-buffer-alist' function introduced
in Emacs 24.1:

View file

@ -1,3 +1,37 @@
2012-09-30 Martin Rudalics <rudalics@gmx.at>
In buffer display functions handle window-height/window-width
alist entries. Suggested by Juri Linkov as fix for Bug#1806.
* window.el (window--display-buffer): New argument ALIST. Obey
window-height and window-width alist entries.
(window--try-to-split-window): New argument ALIST. Bind
window-combination-limit to t when the window's size shall be
changed and window-combination-limit equals `window-size'.
(display-buffer-in-atom-window)
(display-buffer-in-major-side-window)
(display-buffer-in-side-window, display-buffer-same-window)
(display-buffer-reuse-window, display-buffer-pop-up-frame)
(display-buffer-pop-up-window, display-buffer-below-selected)
(display-buffer-at-bottom, display-buffer-in-previous-window)
(display-buffer-use-some-window): Adjust all callers of
window--display-buffer and window--try-to-split-window.
(fit-frame-to-buffer): New option.
(fit-window-to-buffer): Can resize frames if fit-frame-to-buffer
is non-nil.
(display-buffer-in-major-side-window): Evaluate window-height /
window-width alist entries.
* help.el (temp-buffer-resize-frames)
(temp-buffer-resize-regexps): Remove options.
(temp-buffer-resize-mode): Adjust doc-string.
(resize-temp-buffer-window): Don't consult
temp-buffer-resize-regexps. Use fit-frame-to-buffer instead of
temp-buffer-resize-frames.
* dired.el (dired-mark-pop-up): Call
display-buffer-below-selected with a fit-window-to-buffer alist
entry.
2012-09-30 Chong Yidong <cyd@gnu.org>
* simple.el (delete-trailing-whitespace): Avoid an unnecessary

View file

@ -2997,7 +2997,8 @@ argument or confirmation)."
(let ((split-height-threshold 0))
(with-temp-buffer-window
buffer
(cons 'display-buffer-below-selected nil)
(cons 'display-buffer-below-selected
'((window-height . fit-window-to-buffer)))
#'(lambda (window _value)
(with-selected-window window
(unwind-protect

View file

@ -981,26 +981,6 @@ function is called, the window to be resized is selected."
:group 'help
:version "24.2")
(defcustom temp-buffer-resize-frames nil
"Non-nil means `temp-buffer-resize-mode' can resize frames.
A frame can be resized if and only if its root window is a live
window. The height of the root window is subject to the values of
`temp-buffer-max-height' and `window-min-height'."
:type 'boolean
: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
@ -1014,9 +994,8 @@ fit the buffer's contents, but never more than
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.
resized. A frame is resized only if `fit-frame-to-buffer' is
non-nil.
This mode is used by `help', `apropos' and `completion' buffers,
and some others."
@ -1034,33 +1013,28 @@ 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. Do nothing if the name of WINDOW's buffer matches an
expression in `temp-buffer-resize-regexps'."
view."
(setq window (window-normalize-window window t))
(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)))))))))
(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 fit-frame-to-buffer
(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

@ -508,7 +508,7 @@ failed."
(window-make-atom (window-parent window))
;; Display BUFFER in NEW and return NEW.
(window--display-buffer
buffer new 'window display-buffer-mark-dedicated))))
buffer new 'window alist display-buffer-mark-dedicated))))
(defun window--atom-check-1 (window)
"Subroutine of `window--atom-check'."
@ -677,12 +677,6 @@ The new window automatically becomes the \"major\" side window on
SIDE. Return the new window, nil if its creation window failed."
(let* ((root (frame-root-window))
(left-or-right (memq side '(left right)))
(size (or (assq 'size alist)
(/ (window-total-size (frame-root-window) left-or-right)
;; By default use a fourth of the size of the
;; frame's root window. This has to be made
;; customizable via ALIST.
4)))
(major (window--major-side-window side))
(selected-window (selected-window))
(on-side (cond
@ -694,7 +688,7 @@ SIDE. Return the new window, nil if its creation window failed."
;; parent window unless needed.
(window-combination-resize 'side)
(window-combination-limit nil)
(new (split-window major (- size) on-side))
(new (split-window major nil on-side))
fun)
(when new
;; Initialize `window-side' parameter of new window to SIDE.
@ -705,8 +699,22 @@ SIDE. Return the new window, nil if its creation window failed."
;; the new window is deleted, a side window on the opposite side
;; does not get resized.
(set-window-parameter new 'delete-window 'delete-side-window)
;; Auto-adjust height/width of new window unless a size has been
;; explicitly requested.
(unless (if left-or-right
(cdr (assq 'window-width alist))
(cdr (assq 'window-height alist)))
(setq alist
(cons
(cons
(if left-or-right 'window-width 'window-height)
(/ (window-total-size (frame-root-window) left-or-right)
;; By default use a fourth of the size of the
;; frame's root window.
4))
alist)))
;; Install BUFFER in new window and return NEW.
(window--display-buffer buffer new 'window 'side))))
(window--display-buffer buffer new 'window alist 'side))))
(defun delete-side-window (window)
"Delete side window WINDOW."
@ -814,7 +822,7 @@ following symbols can be used:
;; ALIST (or, better, avoided in the "other" functions).
(or (and this-window
;; Reuse `this-window'.
(window--display-buffer buffer this-window 'reuse 'side))
(window--display-buffer buffer this-window 'reuse alist 'side))
(and (or (not max-slots) (< slots max-slots))
(or (and next-window
;; Make new window before `next-window'.
@ -839,13 +847,14 @@ following symbols can be used:
window 'delete-window 'delete-side-window)
window)))
(set-window-parameter window 'window-slot slot)
(window--display-buffer buffer window 'window 'side))
(window--display-buffer buffer window 'window alist 'side))
(and best-window
;; Reuse `best-window'.
(progn
;; Give best-window the new slot value.
(set-window-parameter best-window 'window-slot slot)
(window--display-buffer buffer best-window 'reuse 'side)))))))))
(window--display-buffer
buffer best-window 'reuse alist 'side)))))))))
(defun window--side-check (&optional frame)
"Check the side window configuration of FRAME.
@ -5077,7 +5086,7 @@ split."
(with-selected-window window
(split-window-below))))))))
(defun window--try-to-split-window (window)
(defun window--try-to-split-window (window &optional alist)
"Try to split WINDOW.
Return value returned by `split-window-preferred-function' if it
represents a live window, nil otherwise."
@ -5085,9 +5094,14 @@ represents a live window, nil otherwise."
(not (frame-parameter (window-frame window) 'unsplittable))
(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)
;; `display-buffer' or equals `resize-window' and a
;; `window-height' or `window-width' alist entry are
;; present, bind it to t so resizing steals space
;; preferably from the window that was split.
(if (or (eq window-combination-limit 'display-buffer)
(and (eq window-combination-limit 'window-size)
(or (cdr (assq 'window-height alist))
(cdr (assq 'window-width alist)))))
t
window-combination-limit))
(new-window
@ -5144,7 +5158,7 @@ is higher than WINDOW."
(/ (- (window-total-height window) (window-total-height)) 2))
(error nil))))
(defun window--display-buffer (buffer window type &optional dedicated)
(defun window--display-buffer (buffer window type &optional alist dedicated)
"Display BUFFER in WINDOW and make its frame visible.
TYPE must be one of the symbols `reuse', `window' or `frame' and
is passed unaltered to `display-buffer-record-window'. Set
@ -5159,6 +5173,58 @@ BUFFER and WINDOW are live."
(set-window-dedicated-p window dedicated))
(when (memq type '(window frame))
(set-window-prev-buffers window nil)))
(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))
(and (eq (car parameter) 'same)
(memq (nth 1 parameter) '(window frame))))
;; Adjust height of new window or frame.
(cond
((not height))
((numberp height)
(let* ((new-height
(if (integerp height)
height
(round
(* (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))))))
((functionp height)
(ignore-errors (funcall height window))))
;; Adjust width of a window or frame.
(cond
((not width))
((numberp width)
(let* ((new-width
(if (integerp width)
width
(round
(* (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))))))
((functionp width)
(ignore-errors (funcall width window))))))
window))
(defun window--maybe-raise-frame (frame)
@ -5400,7 +5466,7 @@ selected window."
(unless (or (cdr (assq 'inhibit-same-window alist))
(window-minibuffer-p)
(window-dedicated-p))
(window--display-buffer buffer (selected-window) 'reuse)))
(window--display-buffer buffer (selected-window) 'reuse alist)))
(defun display-buffer--maybe-same-window (buffer alist)
"Conditionally display BUFFER in the selected window.
@ -5448,7 +5514,7 @@ that frame."
(get-buffer-window-list buffer 'nomini
frames))))))
(when (window-live-p window)
(prog1 (window--display-buffer buffer window 'reuse)
(prog1 (window--display-buffer buffer window 'reuse alist)
(unless (cdr (assq 'inhibit-switch-frame alist))
(window--maybe-raise-frame (window-frame window)))))))
@ -5485,8 +5551,8 @@ new frame."
(when (and fun
(setq frame (funcall fun))
(setq window (frame-selected-window frame)))
(prog1 (window--display-buffer buffer window
'frame display-buffer-mark-dedicated)
(prog1 (window--display-buffer
buffer window 'frame alist display-buffer-mark-dedicated)
(unless (cdr (assq 'inhibit-switch-frame alist))
(window--maybe-raise-frame frame))))))
@ -5511,11 +5577,11 @@ raising the frame."
(not (frame-parameter frame 'unsplittable))))
;; Attempt to split largest or least recently used window.
(setq window (or (window--try-to-split-window
(get-largest-window frame t))
(get-largest-window frame t) alist)
(window--try-to-split-window
(get-lru-window frame t)))))
(prog1 (window--display-buffer buffer window
'window display-buffer-mark-dedicated)
(get-lru-window frame t) alist))))
(prog1 (window--display-buffer
buffer window 'window alist display-buffer-mark-dedicated)
(unless (cdr (assq 'inhibit-switch-frame alist))
(window--maybe-raise-frame (window-frame window)))))))
@ -5534,21 +5600,21 @@ again with `display-buffer-pop-up-window'."
(and pop-up-windows
(display-buffer-pop-up-window buffer alist))))
(defun display-buffer-below-selected (buffer _alist)
(defun display-buffer-below-selected (buffer alist)
"Try displaying BUFFER in a window below the selected window.
This either splits the selected window or reuses the window below
the selected one."
(let (window)
(or (and (not (frame-parameter nil 'unsplittable))
(setq window (window--try-to-split-window (selected-window)))
(setq window (window--try-to-split-window (selected-window) alist))
(window--display-buffer
buffer window 'window display-buffer-mark-dedicated))
buffer window 'window alist display-buffer-mark-dedicated))
(and (setq window (window-in-direction 'below))
(not (window-dedicated-p window))
(window--display-buffer
buffer window 'reuse display-buffer-mark-dedicated)))))
buffer window 'reuse alist display-buffer-mark-dedicated)))))
(defun display-buffer-at-bottom (buffer _alist)
(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
@ -5556,20 +5622,20 @@ 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))
(setq window (window--try-to-split-window bottom-window alist))
(window--display-buffer
buffer window 'window display-buffer-mark-dedicated))
buffer window 'window alist 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))
buffer window 'window alist display-buffer-mark-dedicated))
(and (setq window bottom-window)
(not (window-dedicated-p window))
(window--display-buffer
buffer window 'reuse display-buffer-mark-dedicated)))))
buffer window 'reuse alist display-buffer-mark-dedicated)))))
(defun display-buffer-in-previous-window (buffer alist)
"Display BUFFER in a window previously showing it.
@ -5625,7 +5691,7 @@ above, even if that window never showed BUFFER before."
(setq best-window window)))
;; Return best or second best window found.
(when (setq window (or best-window second-best-window))
(window--display-buffer buffer window 'reuse))))
(window--display-buffer buffer window 'reuse alist))))
(defun display-buffer-use-some-window (buffer alist)
"Display BUFFER in an existing window.
@ -5653,7 +5719,7 @@ that frame."
(get-largest-window 0 not-this-window))))
(when (window-live-p window)
(prog1
(window--display-buffer buffer window 'reuse)
(window--display-buffer buffer window 'reuse alist)
(window--even-window-heights window)
(unless (cdr (assq 'inhibit-switch-frame alist))
(window--maybe-raise-frame (window-frame window)))))))
@ -5923,108 +5989,14 @@ WINDOW must be a live window and defaults to the selected one."
window))))
;;; Resizing buffers to fit their contents exactly.
(defun fit-window-to-buffer (&optional window max-height min-height)
"Adjust height of WINDOW to display its buffer's contents exactly.
WINDOW must be a live window and defaults to the selected one.
Optional argument MAX-HEIGHT specifies the maximum height of
WINDOW and defaults to the height of WINDOW's frame. Optional
argument MIN-HEIGHT specifies the minimum height of WINDOW and
defaults to `window-min-height'. Both MAX-HEIGHT and MIN-HEIGHT
are specified in lines and include the mode line and header line,
if any.
Return the number of lines by which WINDOW was enlarged or
shrunk. If an error occurs during resizing, return nil but don't
signal an error.
Note that even if this function makes WINDOW large enough to show
_all_ lines of its buffer you might not see the first lines when
WINDOW was scrolled."
(interactive)
(setq window (window-normalize-window window t))
;; Can't resize a full height or fixed-size window.
(unless (or (window-size-fixed-p window)
(window-full-height-p window))
(with-selected-window window
(let* ((height (window-total-size))
(min-height
;; Adjust MIN-HEIGHT.
(if (numberp min-height)
;; Can't get smaller than `window-safe-min-height'.
(max min-height window-safe-min-height)
;; Preserve header and mode line if present.
(window-min-size nil nil t)))
(max-height
;; Adjust MAX-HEIGHT.
(if (numberp max-height)
;; Can't get larger than height of frame.
(min max-height
(window-total-size (frame-root-window window)))
;, Don't delete other windows.
(+ height (window-max-delta nil nil window))))
;; Make `desired-height' the height necessary to show
;; all of WINDOW's buffer, constrained by MIN-HEIGHT
;; and MAX-HEIGHT.
(desired-height
(max
(min
(+ (count-screen-lines)
;; For non-minibuffers count the mode line, if any.
(if (and (not (window-minibuffer-p window))
mode-line-format)
1
0)
;; Count the header line, if any.
(if header-line-format 1 0))
max-height)
min-height))
(desired-delta
(- desired-height (window-total-size window)))
(delta
(if (> desired-delta 0)
(min desired-delta
(window-max-delta window nil window))
(max desired-delta
(- (window-min-delta window nil window))))))
(condition-case nil
(if (zerop delta)
;; Return zero if DELTA became zero in the process.
0
;; Don't try to redisplay with the cursor at the end on its
;; own line--that would force a scroll and spoil things.
(when (and (eobp) (bolp) (not (bobp)))
;; It's silly to put `point' at the end of the previous
;; line and so maybe force horizontal scrolling.
(set-window-point window (line-beginning-position 0)))
;; Call `window-resize' with OVERRIDE argument equal WINDOW.
(window-resize window delta nil window)
;; Check if the last line is surely fully visible. If
;; not, enlarge the window.
(let ((end (save-excursion
(goto-char (point-max))
(when (and (bolp) (not (bobp)))
;; Don't include final newline.
(backward-char 1))
(when truncate-lines
;; If line-wrapping is turned off, test the
;; beginning of the last line for
;; visibility instead of the end, as the
;; end of the line could be invisible by
;; virtue of extending past the edge of the
;; window.
(forward-line 0))
(point))))
(set-window-vscroll window 0)
;; This loop might in some rare pathological cases raise
;; an error - another reason for the `condition-case'.
(while (and (< desired-height max-height)
(= desired-height (window-total-size))
(not (pos-visible-in-window-p end)))
(window-resize window 1 nil window)
(setq desired-height (1+ desired-height)))))
(error (setq delta nil)))
delta))))
(defcustom fit-frame-to-buffer nil
"Non-nil means `fit-window-to-buffer' can resize frames.
A frame can be resized if and only if its root window is a live
window. The height of the root window is subject to the values
of `fit-frame-to-buffer-max-height' and `window-min-height'."
:type 'boolean
:version "24.2"
:group 'help)
(defcustom fit-frame-to-buffer-bottom-margin 4
"Bottom margin for `fit-frame-to-buffer'.
@ -6108,6 +6080,112 @@ FRAME."
(error (setq delta nil))))
delta))
(defun fit-window-to-buffer (&optional window max-height min-height)
"Adjust height of WINDOW to display its buffer's contents exactly.
WINDOW must be a live window and defaults to the selected one.
Optional argument MAX-HEIGHT specifies the maximum height of
WINDOW and defaults to the height of WINDOW's frame. Optional
argument MIN-HEIGHT specifies the minimum height of WINDOW and
defaults to `window-min-height'. Both MAX-HEIGHT and MIN-HEIGHT
are specified in lines and include the mode line and header line,
if any.
Return the number of lines by which WINDOW was enlarged or
shrunk. If an error occurs during resizing, return nil but don't
signal an error.
Note that even if this function makes WINDOW large enough to show
_all_ lines of its buffer you might not see the first lines when
WINDOW was scrolled."
(interactive)
(setq window (window-normalize-window window t))
(cond
((window-size-fixed-p window))
((window-full-height-p window)
(when fit-frame-to-buffer
(fit-frame-to-buffer (window-frame window))))
(t
(with-selected-window window
(let* ((height (window-total-size))
(min-height
;; Adjust MIN-HEIGHT.
(if (numberp min-height)
;; Can't get smaller than `window-safe-min-height'.
(max min-height window-safe-min-height)
;; Preserve header and mode line if present.
(window-min-size nil nil t)))
(max-height
;; Adjust MAX-HEIGHT.
(if (numberp max-height)
;; Can't get larger than height of frame.
(min max-height
(window-total-size (frame-root-window window)))
;; Don't delete other windows.
(+ height (window-max-delta nil nil window))))
;; Make `desired-height' the height necessary to show
;; all of WINDOW's buffer, constrained by MIN-HEIGHT
;; and MAX-HEIGHT.
(desired-height
(max
(min
(+ (count-screen-lines)
;; For non-minibuffers count the mode line, if any.
(if (and (not (window-minibuffer-p window))
mode-line-format)
1
0)
;; Count the header line, if any.
(if header-line-format 1 0))
max-height)
min-height))
(desired-delta
(- desired-height (window-total-size window)))
(delta
(if (> desired-delta 0)
(min desired-delta
(window-max-delta window nil window))
(max desired-delta
(- (window-min-delta window nil window))))))
(condition-case nil
(if (zerop delta)
;; Return zero if DELTA became zero in the process.
0
;; Don't try to redisplay with the cursor at the end on its
;; own line--that would force a scroll and spoil things.
(when (and (eobp) (bolp) (not (bobp)))
;; It's silly to put `point' at the end of the previous
;; line and so maybe force horizontal scrolling.
(set-window-point window (line-beginning-position 0)))
;; Call `window-resize' with OVERRIDE argument equal WINDOW.
(window-resize window delta nil window)
;; Check if the last line is surely fully visible. If
;; not, enlarge the window.
(let ((end (save-excursion
(goto-char (point-max))
(when (and (bolp) (not (bobp)))
;; Don't include final newline.
(backward-char 1))
(when truncate-lines
;; If line-wrapping is turned off, test the
;; beginning of the last line for
;; visibility instead of the end, as the
;; end of the line could be invisible by
;; virtue of extending past the edge of the
;; window.
(forward-line 0))
(point))))
(set-window-vscroll window 0)
;; This loop might in some rare pathological cases raise
;; an error - another reason for the `condition-case'.
(while (and (< desired-height max-height)
(= desired-height (window-total-size))
(not (pos-visible-in-window-p end)))
(window-resize window 1 nil window)
(setq desired-height (1+ desired-height)))))
(error (setq delta nil)))
delta)))))
(defun window-safely-shrinkable-p (&optional window)
"Return t if WINDOW can be shrunk without shrinking other windows.
WINDOW defaults to the selected window."

View file

@ -1,3 +1,8 @@
2012-09-30 Martin Rudalics <rudalics@gmx.at>
* window.c (Vwindow_combination_limit): New default value.
(Qwindow_size): New symbol replacing Qtemp_buffer_resize.
2012-09-30 Paul Eggert <eggert@cs.ucla.edu>
* syssignal.h (PROFILER_CPU_SUPPORT): Don't define if PROFILING.
@ -131,6 +136,7 @@
(redisplay_internal): Record itself in backtrace_list.
(syms_of_xdisp): Define Qautomatic_redisplay.
2012-09-25 Eli Zaretskii <eliz@gnu.org>
2012-09-25 Juanma Barranquero <lekktu@gmail.com>
* makefile.w32-in ($(BLD)/callproc.$(O)): Update dependencies.

View file

@ -60,7 +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, Qtemp_buffer_resize, Qclone_of;
static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of;
static int displayed_window_lines (struct window *);
static int count_windows (struct window *);
@ -6704,7 +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 (Qwindow_size, "window-size");
DEFSYM (Qtemp_buffer_show_hook, "temp-buffer-show-hook");
DEFSYM (Qabove, "above");
DEFSYM (Qbelow, "below");
@ -6804,19 +6804,19 @@ This variable takes no effect if `window-combination-limit' is non-nil. */);
The following values are recognized:
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.
window has no parent window or the window shall become part of a
combination orthogonal to the one it is part of.
`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.
`window-size' means that splitting a window for displaying a buffer
makes a new parent window provided `display-buffer' is supposed to
explicitly set the window's size due to the presence of a
`window-height' or `window-width' entry in the alist used by
`display-buffer'. Otherwise, this value is handled like nil.
`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
@ -6829,7 +6829,7 @@ t means that splitting a window always creates a new parent window. If
sibling.
Other values are reserved for future use. */);
Vwindow_combination_limit = Qtemp_buffer_resize;
Vwindow_combination_limit = Qwindow_size;
DEFVAR_LISP ("window-persistent-parameters", Vwindow_persistent_parameters,
doc: /* Alist of persistent window parameters.