displayed and current and its window selected.")
(defun temp-buffer-window-setup (buffer-or-name)
- "Set up temporary buffer specified by BUFFER-OR-NAME
+ "Set up temporary buffer specified by BUFFER-OR-NAME.
Return the buffer."
(let ((old-dir default-directory)
(buffer (get-buffer-create buffer-or-name)))
(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))
(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'."
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
;; 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.
;; 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."
;; 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'.
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.
(if right (throw 'reset t) (setq right t)))
((eq side 'bottom)
(if bottom (throw 'reset t) (setq bottom t)))
- (t
+ (t
(throw 'reset t))))
frame t))
;; If there's a side window, there must be at least one
Return the symbol `normalized' if new normal sizes have been
already set by this routine."
(let* ((first (window-child parent))
- (sub first)
+ (last (window-last-child parent))
(parent-total (+ (window-total-size parent horizontal) delta))
- best-window best-value)
+ sub best-window best-value)
(if (and edge (memq trail '(before after))
(progn
;; normal sizes have been already set.
'normalized)
;; Resize all windows proportionally.
- (setq sub first)
+ (setq sub last)
(while sub
(cond
((or (window--resize-child-windows-skip-p sub)
parent-total)
(window-normal-size sub horizontal)))))
- (setq sub (window-right sub)))
+ (setq sub (window-left sub)))
(cond
((< delta 0)
;; Shrink windows by delta.
(setq best-window t)
(while (and best-window (not (zerop delta)))
- (setq sub first)
+ (setq sub last)
(setq best-window nil)
(setq best-value most-negative-fixnum)
(while sub
(setq best-window sub)
(setq best-value (cdr (window-new-normal sub))))
- (setq sub (window-right sub)))
+ (setq sub (window-left sub)))
(when best-window
(setq delta (1+ delta)))
;; Enlarge windows by delta.
(setq best-window t)
(while (and best-window (not (zerop delta)))
- (setq sub first)
+ (setq sub last)
(setq best-window nil)
(setq best-value most-positive-fixnum)
(while sub
(setq best-window sub)
(setq best-value (window-new-normal sub)))
- (setq sub (window-right sub)))
+ (setq sub (window-left sub)))
(when best-window
(setq delta (1- delta)))
(window-normal-size best-window horizontal))))))
(when best-window
- (setq sub first)
+ (setq sub last)
(while sub
(when (or (consp (window-new-normal sub))
(numberp (window-new-normal sub)))
;; recursively even if it's size does not change.
(window--resize-this-window
sub delta horizontal ignore nil trail edge))))
- (setq sub (window-right sub)))))))
+ (setq sub (window-left sub)))))))
(defun window--resize-siblings (window delta &optional horizontal ignore trail edge)
"Resize other windows when WINDOW is resized vertically by DELTA lines.
This function is only called by the minibuffer window resizing
routines. It resizes windows proportionally and never deletes
any windows."
- (when (numberp delta)
- (let (ignore)
- (cond
- ((< delta 0)
- (setq delta (window-sizable window delta)))
- ((> delta 0)
- (unless (window-sizable window delta)
- (setq ignore t))))
-
- (window--resize-reset (window-frame window))
- ;; Ideally, we would resize just the last window in a combination
- ;; but that's not feasible for the following reason: If we grow
- ;; the minibuffer window and the last window cannot be shrunk any
- ;; more, we shrink another window instead. But if we then shrink
- ;; the minibuffer window again, the last window might get enlarged
- ;; and the state after shrinking is not the state before growing.
- ;; So, in practice, we'd need a history variable to record how to
- ;; proceed. But I'm not sure how such a variable could work with
- ;; repeated minibuffer window growing steps.
- (window--resize-this-window window delta nil ignore t)
- delta)))
+ (let ((frame (window-frame window))
+ ignore)
+ (cond
+ ((not (numberp delta))
+ (setq delta 0))
+ ((zerop delta))
+ ((< delta 0)
+ (setq delta (window-sizable window delta))
+ (window--resize-reset frame)
+ ;; When shrinking the root window, emulate an edge drag in order
+ ;; to not resize other windows if we can avoid it (Bug#12419).
+ (window--resize-this-window
+ window delta nil ignore t 'before
+ (+ (window-top-line window) (window-total-size window)))
+ ;; Don't record new normal sizes to make sure that shrinking back
+ ;; proportionally works as intended.
+ (walk-window-tree
+ (lambda (window) (set-window-new-normal window 'ignore)) frame t))
+ ((> delta 0)
+ (window--resize-reset frame)
+ (unless (window-sizable window delta)
+ (setq ignore t))
+ ;; When growing the root window, resize proportionally. This
+ ;; should give windows back their original sizes (hopefully).
+ (window--resize-this-window window delta nil ignore t)))
+ ;; Return the possibly adjusted DELTA.
+ delta))
(defun adjust-window-trailing-edge (window delta &optional horizontal)
"Move WINDOW's bottom edge by DELTA lines.
(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)
(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.
;; 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.
(function :tag "function"))
:group 'windows)
+(make-obsolete-variable 'display-buffer-function
+ 'display-buffer-alist "24.3")
+
;; Eventually, we want to turn this into a defvar; instead of
;; customizing this, the user should use a `pop-up-frame-parameters'
;; alist entry in `display-buffer-base-action'.
BUFFER in a window of the selected frame.
If ARGS is a list whose car is a symbol, use (car ARGS) as a
-function to do the work. Pass it BUFFER as first argument,
-and (cdr ARGS) as second."
+function to do the work. Pass it BUFFER as first argument, and
+pass the elements of (cdr ARGS) as the remaining arguments."
(if (and args (symbolp (car args)))
(apply (car args) buffer (cdr args))
(let ((window (get-buffer-window buffer 0)))
(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."
(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' 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
+ ;; 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)
(/ (- (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
(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)
(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.
(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)))))))
(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))))))
(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)))))))
(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)
+ "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 alist))
+ (window--display-buffer
+ 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 alist display-buffer-mark-dedicated))
+ (and (setq window bottom-window)
+ (not (window-dedicated-p window))
+ (window--display-buffer
+ buffer window 'reuse alist 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
+window is not eligible for reuse.
+
+If ALIST contains a `reusable-frames' entry, its value determines
+which frames to search for a reusable window:
+ nil -- the selected frame (actually the last non-minibuffer frame)
+ A frame -- just that frame
+ `visible' -- all visible frames
+ 0 -- all frames on the current terminal
+ t -- all frames.
+
+If ALIST contains no `reusable-frames' entry, search just the
+selected frame if `display-buffer-reuse-frames' and
+`pop-up-frames' are both nil; search all frames on the current
+terminal if either of those variables is non-nil.
+
+If ALIST has a `previous-window' entry, the window specified by
+that entry will override any other window found by the methods
+above, even if that window never showed BUFFER before."
+ (let* ((alist-entry (assq 'reusable-frames alist))
+ (inhibit-same-window
+ (cdr (assq 'inhibit-same-window alist)))
+ (frames (cond
+ (alist-entry (cdr alist-entry))
+ ((if (eq pop-up-frames 'graphic-only)
+ (display-graphic-p)
+ pop-up-frames)
+ 0)
+ (display-buffer-reuse-frames 0)
+ (t (last-nonminibuffer-frame))))
+ entry best-window second-best-window window)
+ ;; Scan windows whether they have shown the buffer recently.
+ (catch 'best
+ (dolist (window (window-list-1 (frame-first-window) 'nomini frames))
+ (when (and (assq buffer (window-prev-buffers window))
+ (not (window-dedicated-p window)))
+ (if (eq window (selected-window))
+ (unless inhibit-same-window
+ (setq second-best-window window))
+ (setq best-window window)
+ (throw 'best t)))))
+ ;; When ALIST has a `previous-window' entry, that entry may override
+ ;; anything we found so far.
+ (when (and (setq window (cdr (assq 'previous-window alist)))
+ (window-live-p window)
+ (not (window-dedicated-p window)))
+ (if (eq window (selected-window))
+ (unless inhibit-same-window
+ (setq second-best-window window))
+ (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 alist))))
(defun display-buffer-use-some-window (buffer alist)
"Display BUFFER in an existing window.
(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)))))))
(defun switch-to-buffer (buffer-or-name &optional norecord force-same-window)
"Switch to buffer BUFFER-OR-NAME in the selected window.
-If called interactively, prompt for the buffer name using the
+If the selected window cannot display the specified
+buffer (e.g. if it is a minibuffer window or strongly dedicated
+to another buffer), call `pop-to-buffer' to select the buffer in
+another window.
+
+If called interactively, read the buffer name using the
minibuffer. The variable `confirm-nonexistent-file-or-buffer'
determines whether to request confirmation before creating a new
buffer.
-BUFFER-OR-NAME may be a buffer, a string (a buffer name), or
-nil. If BUFFER-OR-NAME is a string that does not identify an
-existing buffer, create a buffer with that name. If
-BUFFER-OR-NAME is nil, switch to the buffer returned by
-`other-buffer'.
+BUFFER-OR-NAME may be a buffer, a string (a buffer name), or nil.
+If BUFFER-OR-NAME is a string that does not identify an existing
+buffer, create a buffer with that name. If BUFFER-OR-NAME is
+nil, switch to the buffer returned by `other-buffer'.
-Optional argument NORECORD non-nil means do not put the buffer
-specified by BUFFER-OR-NAME at the front of the buffer list and
-do not make the window displaying it the most recently selected
-one.
+If optional argument NORECORD is non-nil, do not put the buffer
+at the front of the buffer list, and do not make the window
+displaying it the most recently selected one.
-If FORCE-SAME-WINDOW is non-nil, BUFFER-OR-NAME must be displayed
-in the selected window; signal an error if that is
-impossible (e.g. if the selected window is minibuffer-only). If
-nil, BUFFER-OR-NAME may be displayed in another window.
+If optional argument FORCE-SAME-WINDOW is non-nil, the buffer
+must be displayed in the selected window; if that is impossible,
+signal an error rather than calling `pop-to-buffer'.
Return the buffer switched to."
(interactive
window))))
;;; Resizing buffers to fit their contents exactly.
+(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'.
+This is the number of lines `fit-frame-to-buffer' leaves free at the
+bottom of the display in order to not obscure the system task bar."
+ :type 'integer
+ :version "24.2"
+ :group 'windows)
+
+(defun fit-frame-to-buffer (&optional frame max-height min-height)
+ "Adjust height of FRAME to display its buffer's contents exactly.
+FRAME can be any live frame and defaults to the selected one.
+
+Optional argument MAX-HEIGHT specifies the maximum height of
+FRAME and defaults to the height of the display below the current
+top line of FRAME minus FIT-FRAME-TO-BUFFER-BOTTOM-MARGIN.
+Optional argument MIN-HEIGHT specifies the minimum height of
+FRAME."
+ (interactive)
+ (setq frame (window-normalize-frame frame))
+ (let* ((root (frame-root-window frame))
+ (frame-min-height
+ (+ (- (frame-height frame) (window-total-size root))
+ window-min-height))
+ (frame-top (frame-parameter frame 'top))
+ (top (if (consp frame-top)
+ (funcall (car frame-top) (cadr frame-top))
+ frame-top))
+ (frame-max-height
+ (- (/ (- (x-display-pixel-height frame) top)
+ (frame-char-height frame))
+ fit-frame-to-buffer-bottom-margin))
+ (compensate 0)
+ delta)
+ (when (and (window-live-p root) (not (window-size-fixed-p root)))
+ (with-selected-window root
+ (cond
+ ((not max-height)
+ (setq max-height frame-max-height))
+ ((numberp max-height)
+ (setq max-height (min max-height frame-max-height)))
+ (t
+ (error "%s is an invalid maximum height" max-height)))
+ (cond
+ ((not min-height)
+ (setq min-height frame-min-height))
+ ((numberp min-height)
+ (setq min-height (min min-height frame-min-height)))
+ (t
+ (error "%s is an invalid minimum height" min-height)))
+ ;; When tool-bar-mode is enabled and we have just created a new
+ ;; frame, reserve lines for toolbar resizing. This is needed
+ ;; because for reasons unknown to me Emacs (1) reserves one line
+ ;; for the toolbar when making the initial frame and toolbars
+ ;; are enabled, and (2) later adds the remaining lines needed.
+ ;; Our code runs IN BETWEEN (1) and (2). YMMV when you're on a
+ ;; system that behaves differently.
+ (let ((quit-restore (window-parameter root 'quit-restore))
+ (lines (tool-bar-lines-needed frame)))
+ (when (and quit-restore (eq (car quit-restore) 'frame)
+ (not (zerop lines)))
+ (setq compensate (1- lines))))
+ (message "%s" compensate)
+ (setq delta
+ ;; Always count a final newline - we don't do any
+ ;; post-processing, so let's play safe.
+ (+ (count-screen-lines nil nil t)
+ (- (window-body-size))
+ compensate)))
+ ;; Move away from final newline.
+ (when (and (eobp) (bolp) (not (bobp)))
+ (set-window-point root (line-beginning-position 0)))
+ (set-window-start root (point-min))
+ (set-window-vscroll root 0)
+ (condition-case nil
+ (set-frame-height
+ frame
+ (min (max (+ (frame-height frame) delta)
+ min-height)
+ max-height))
+ (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.
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))
+ (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
;; Can't get larger than height of frame.
(min max-height
(window-total-size (frame-root-window window)))
- ;, Don't delete other windows.
+ ;; 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
(window-resize window 1 nil window)
(setq desired-height (1+ desired-height)))))
(error (setq delta nil)))
- delta))))
-
-(defcustom fit-frame-to-buffer-bottom-margin 4
- "Bottom margin for `fit-frame-to-buffer'.
-This is the number of lines `fit-frame-to-buffer' leaves free at the
-bottom of the display in order to not obscure the system task bar."
- :type 'integer
- :version "24.2"
- :group 'windows)
-
-(defun fit-frame-to-buffer (&optional frame max-height min-height)
- "Adjust height of FRAME to display its buffer's contents exactly.
-FRAME can be any live frame and defaults to the selected one.
-
-Optional argument MAX-HEIGHT specifies the maximum height of
-FRAME and defaults to the height of the display below the current
-top line of FRAME minus FIT-FRAME-TO-BUFFER-BOTTOM-MARGIN.
-Optional argument MIN-HEIGHT specifies the minimum height of
-FRAME."
- (interactive)
- (setq frame (window-normalize-frame frame))
- (let* ((root (frame-root-window frame))
- (frame-min-height
- (+ (- (frame-height frame) (window-total-size root))
- window-min-height))
- (frame-top (frame-parameter frame 'top))
- (top (if (consp frame-top)
- (funcall (car frame-top) (cadr frame-top))
- frame-top))
- (frame-max-height
- (- (/ (- (x-display-pixel-height frame) top)
- (frame-char-height frame))
- fit-frame-to-buffer-bottom-margin))
- (compensate 0)
- delta)
- (when (and (window-live-p root) (not (window-size-fixed-p root)))
- (with-selected-window root
- (cond
- ((not max-height)
- (setq max-height frame-max-height))
- ((numberp max-height)
- (setq max-height (min max-height frame-max-height)))
- (t
- (error "%s is an invalid maximum height" max-height)))
- (cond
- ((not min-height)
- (setq min-height frame-min-height))
- ((numberp min-height)
- (setq min-height (min min-height frame-min-height)))
- (t
- (error "%s is an invalid minimum height" min-height)))
- ;; When tool-bar-mode is enabled and we have just created a new
- ;; frame, reserve lines for toolbar resizing. This is needed
- ;; because for reasons unknown to me Emacs (1) reserves one line
- ;; for the toolbar when making the initial frame and toolbars
- ;; are enabled, and (2) later adds the remaining lines needed.
- ;; Our code runs IN BETWEEN (1) and (2). YMMV when you're on a
- ;; system that behaves differently.
- (let ((quit-restore (window-parameter root 'quit-restore))
- (lines (tool-bar-lines-needed frame)))
- (when (and quit-restore (eq (car quit-restore) 'frame)
- (not (zerop lines)))
- (setq compensate (1- lines))))
- (message "%s" compensate)
- (setq delta
- ;; Always count a final newline - we don't do any
- ;; post-processing, so let's play safe.
- (+ (count-screen-lines nil nil t)
- (- (window-body-size))
- compensate)))
- ;; Move away from final newline.
- (when (and (eobp) (bolp) (not (bobp)))
- (set-window-point root (line-beginning-position 0)))
- (set-window-start root (point-min))
- (set-window-vscroll root 0)
- (condition-case nil
- (set-frame-height
- frame
- (min (max (+ (frame-height frame) delta)
- min-height)
- max-height))
- (error (setq delta nil))))
- delta))
+ delta)))))
(defun window-safely-shrinkable-p (&optional window)
"Return t if WINDOW can be shrunk without shrinking other windows.
(put 'scroll-down-line 'scroll-command t)
\f
-(defun scroll-other-window-down (lines)
+(defun scroll-other-window-down (&optional lines)
"Scroll the \"other window\" down.
For more details, see the documentation for `scroll-other-window'."
(interactive "P")