aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/window.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/window.el')
-rw-r--r--lisp/window.el396
1 files changed, 240 insertions, 156 deletions
diff --git a/lisp/window.el b/lisp/window.el
index 87817fb8773..811b1781b4c 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -84,7 +84,7 @@ This hook is run by `with-temp-buffer-window' with the buffer
84displayed and current and its window selected.") 84displayed and current and its window selected.")
85 85
86(defun temp-buffer-window-setup (buffer-or-name) 86(defun temp-buffer-window-setup (buffer-or-name)
87 "Set up temporary buffer specified by BUFFER-OR-NAME 87 "Set up temporary buffer specified by BUFFER-OR-NAME.
88Return the buffer." 88Return the buffer."
89 (let ((old-dir default-directory) 89 (let ((old-dir default-directory)
90 (buffer (get-buffer-create buffer-or-name))) 90 (buffer (get-buffer-create buffer-or-name)))
@@ -508,7 +508,7 @@ failed."
508 (window-make-atom (window-parent window)) 508 (window-make-atom (window-parent window))
509 ;; Display BUFFER in NEW and return NEW. 509 ;; Display BUFFER in NEW and return NEW.
510 (window--display-buffer 510 (window--display-buffer
511 buffer new 'window display-buffer-mark-dedicated)))) 511 buffer new 'window alist display-buffer-mark-dedicated))))
512 512
513(defun window--atom-check-1 (window) 513(defun window--atom-check-1 (window)
514 "Subroutine of `window--atom-check'." 514 "Subroutine of `window--atom-check'."
@@ -677,12 +677,6 @@ The new window automatically becomes the \"major\" side window on
677SIDE. Return the new window, nil if its creation window failed." 677SIDE. Return the new window, nil if its creation window failed."
678 (let* ((root (frame-root-window)) 678 (let* ((root (frame-root-window))
679 (left-or-right (memq side '(left right))) 679 (left-or-right (memq side '(left right)))
680 (size (or (assq 'size alist)
681 (/ (window-total-size (frame-root-window) left-or-right)
682 ;; By default use a fourth of the size of the
683 ;; frame's root window. This has to be made
684 ;; customizable via ALIST.
685 4)))
686 (major (window--major-side-window side)) 680 (major (window--major-side-window side))
687 (selected-window (selected-window)) 681 (selected-window (selected-window))
688 (on-side (cond 682 (on-side (cond
@@ -694,7 +688,7 @@ SIDE. Return the new window, nil if its creation window failed."
694 ;; parent window unless needed. 688 ;; parent window unless needed.
695 (window-combination-resize 'side) 689 (window-combination-resize 'side)
696 (window-combination-limit nil) 690 (window-combination-limit nil)
697 (new (split-window major (- size) on-side)) 691 (new (split-window major nil on-side))
698 fun) 692 fun)
699 (when new 693 (when new
700 ;; Initialize `window-side' parameter of new window to SIDE. 694 ;; Initialize `window-side' parameter of new window to SIDE.
@@ -705,8 +699,22 @@ SIDE. Return the new window, nil if its creation window failed."
705 ;; the new window is deleted, a side window on the opposite side 699 ;; the new window is deleted, a side window on the opposite side
706 ;; does not get resized. 700 ;; does not get resized.
707 (set-window-parameter new 'delete-window 'delete-side-window) 701 (set-window-parameter new 'delete-window 'delete-side-window)
702 ;; Auto-adjust height/width of new window unless a size has been
703 ;; explicitly requested.
704 (unless (if left-or-right
705 (cdr (assq 'window-width alist))
706 (cdr (assq 'window-height alist)))
707 (setq alist
708 (cons
709 (cons
710 (if left-or-right 'window-width 'window-height)
711 (/ (window-total-size (frame-root-window) left-or-right)
712 ;; By default use a fourth of the size of the
713 ;; frame's root window.
714 4))
715 alist)))
708 ;; Install BUFFER in new window and return NEW. 716 ;; Install BUFFER in new window and return NEW.
709 (window--display-buffer buffer new 'window 'side)))) 717 (window--display-buffer buffer new 'window alist 'side))))
710 718
711(defun delete-side-window (window) 719(defun delete-side-window (window)
712 "Delete side window WINDOW." 720 "Delete side window WINDOW."
@@ -814,7 +822,7 @@ following symbols can be used:
814 ;; ALIST (or, better, avoided in the "other" functions). 822 ;; ALIST (or, better, avoided in the "other" functions).
815 (or (and this-window 823 (or (and this-window
816 ;; Reuse `this-window'. 824 ;; Reuse `this-window'.
817 (window--display-buffer buffer this-window 'reuse 'side)) 825 (window--display-buffer buffer this-window 'reuse alist 'side))
818 (and (or (not max-slots) (< slots max-slots)) 826 (and (or (not max-slots) (< slots max-slots))
819 (or (and next-window 827 (or (and next-window
820 ;; Make new window before `next-window'. 828 ;; Make new window before `next-window'.
@@ -839,13 +847,14 @@ following symbols can be used:
839 window 'delete-window 'delete-side-window) 847 window 'delete-window 'delete-side-window)
840 window))) 848 window)))
841 (set-window-parameter window 'window-slot slot) 849 (set-window-parameter window 'window-slot slot)
842 (window--display-buffer buffer window 'window 'side)) 850 (window--display-buffer buffer window 'window alist 'side))
843 (and best-window 851 (and best-window
844 ;; Reuse `best-window'. 852 ;; Reuse `best-window'.
845 (progn 853 (progn
846 ;; Give best-window the new slot value. 854 ;; Give best-window the new slot value.
847 (set-window-parameter best-window 'window-slot slot) 855 (set-window-parameter best-window 'window-slot slot)
848 (window--display-buffer buffer best-window 'reuse 'side))))))))) 856 (window--display-buffer
857 buffer best-window 'reuse alist 'side)))))))))
849 858
850(defun window--side-check (&optional frame) 859(defun window--side-check (&optional frame)
851 "Check the side window configuration of FRAME. 860 "Check the side window configuration of FRAME.
@@ -903,7 +912,7 @@ of all windows on FRAME to nil."
903 (if right (throw 'reset t) (setq right t))) 912 (if right (throw 'reset t) (setq right t)))
904 ((eq side 'bottom) 913 ((eq side 'bottom)
905 (if bottom (throw 'reset t) (setq bottom t))) 914 (if bottom (throw 'reset t) (setq bottom t)))
906 (t 915 (t
907 (throw 'reset t)))) 916 (throw 'reset t))))
908 frame t)) 917 frame t))
909 ;; If there's a side window, there must be at least one 918 ;; If there's a side window, there must be at least one
@@ -2079,9 +2088,9 @@ preferably only resize windows adjacent to EDGE.
2079Return the symbol `normalized' if new normal sizes have been 2088Return the symbol `normalized' if new normal sizes have been
2080already set by this routine." 2089already set by this routine."
2081 (let* ((first (window-child parent)) 2090 (let* ((first (window-child parent))
2082 (sub first) 2091 (last (window-last-child parent))
2083 (parent-total (+ (window-total-size parent horizontal) delta)) 2092 (parent-total (+ (window-total-size parent horizontal) delta))
2084 best-window best-value) 2093 sub best-window best-value)
2085 2094
2086 (if (and edge (memq trail '(before after)) 2095 (if (and edge (memq trail '(before after))
2087 (progn 2096 (progn
@@ -2125,7 +2134,7 @@ already set by this routine."
2125 ;; normal sizes have been already set. 2134 ;; normal sizes have been already set.
2126 'normalized) 2135 'normalized)
2127 ;; Resize all windows proportionally. 2136 ;; Resize all windows proportionally.
2128 (setq sub first) 2137 (setq sub last)
2129 (while sub 2138 (while sub
2130 (cond 2139 (cond
2131 ((or (window--resize-child-windows-skip-p sub) 2140 ((or (window--resize-child-windows-skip-p sub)
@@ -2154,14 +2163,14 @@ already set by this routine."
2154 parent-total) 2163 parent-total)
2155 (window-normal-size sub horizontal))))) 2164 (window-normal-size sub horizontal)))))
2156 2165
2157 (setq sub (window-right sub))) 2166 (setq sub (window-left sub)))
2158 2167
2159 (cond 2168 (cond
2160 ((< delta 0) 2169 ((< delta 0)
2161 ;; Shrink windows by delta. 2170 ;; Shrink windows by delta.
2162 (setq best-window t) 2171 (setq best-window t)
2163 (while (and best-window (not (zerop delta))) 2172 (while (and best-window (not (zerop delta)))
2164 (setq sub first) 2173 (setq sub last)
2165 (setq best-window nil) 2174 (setq best-window nil)
2166 (setq best-value most-negative-fixnum) 2175 (setq best-value most-negative-fixnum)
2167 (while sub 2176 (while sub
@@ -2171,7 +2180,7 @@ already set by this routine."
2171 (setq best-window sub) 2180 (setq best-window sub)
2172 (setq best-value (cdr (window-new-normal sub)))) 2181 (setq best-value (cdr (window-new-normal sub))))
2173 2182
2174 (setq sub (window-right sub))) 2183 (setq sub (window-left sub)))
2175 2184
2176 (when best-window 2185 (when best-window
2177 (setq delta (1+ delta))) 2186 (setq delta (1+ delta)))
@@ -2188,7 +2197,7 @@ already set by this routine."
2188 ;; Enlarge windows by delta. 2197 ;; Enlarge windows by delta.
2189 (setq best-window t) 2198 (setq best-window t)
2190 (while (and best-window (not (zerop delta))) 2199 (while (and best-window (not (zerop delta)))
2191 (setq sub first) 2200 (setq sub last)
2192 (setq best-window nil) 2201 (setq best-window nil)
2193 (setq best-value most-positive-fixnum) 2202 (setq best-value most-positive-fixnum)
2194 (while sub 2203 (while sub
@@ -2197,7 +2206,7 @@ already set by this routine."
2197 (setq best-window sub) 2206 (setq best-window sub)
2198 (setq best-value (window-new-normal sub))) 2207 (setq best-value (window-new-normal sub)))
2199 2208
2200 (setq sub (window-right sub))) 2209 (setq sub (window-left sub)))
2201 2210
2202 (when best-window 2211 (when best-window
2203 (setq delta (1- delta))) 2212 (setq delta (1- delta)))
@@ -2209,7 +2218,7 @@ already set by this routine."
2209 (window-normal-size best-window horizontal)))))) 2218 (window-normal-size best-window horizontal))))))
2210 2219
2211 (when best-window 2220 (when best-window
2212 (setq sub first) 2221 (setq sub last)
2213 (while sub 2222 (while sub
2214 (when (or (consp (window-new-normal sub)) 2223 (when (or (consp (window-new-normal sub))
2215 (numberp (window-new-normal sub))) 2224 (numberp (window-new-normal sub)))
@@ -2227,7 +2236,7 @@ already set by this routine."
2227 ;; recursively even if it's size does not change. 2236 ;; recursively even if it's size does not change.
2228 (window--resize-this-window 2237 (window--resize-this-window
2229 sub delta horizontal ignore nil trail edge)))) 2238 sub delta horizontal ignore nil trail edge))))
2230 (setq sub (window-right sub))))))) 2239 (setq sub (window-left sub)))))))
2231 2240
2232(defun window--resize-siblings (window delta &optional horizontal ignore trail edge) 2241(defun window--resize-siblings (window delta &optional horizontal ignore trail edge)
2233 "Resize other windows when WINDOW is resized vertically by DELTA lines. 2242 "Resize other windows when WINDOW is resized vertically by DELTA lines.
@@ -2406,27 +2415,33 @@ Return the number of lines that were recovered.
2406This function is only called by the minibuffer window resizing 2415This function is only called by the minibuffer window resizing
2407routines. It resizes windows proportionally and never deletes 2416routines. It resizes windows proportionally and never deletes
2408any windows." 2417any windows."
2409 (when (numberp delta) 2418 (let ((frame (window-frame window))
2410 (let (ignore) 2419 ignore)
2411 (cond 2420 (cond
2412 ((< delta 0) 2421 ((not (numberp delta))
2413 (setq delta (window-sizable window delta))) 2422 (setq delta 0))
2414 ((> delta 0) 2423 ((zerop delta))
2415 (unless (window-sizable window delta) 2424 ((< delta 0)
2416 (setq ignore t)))) 2425 (setq delta (window-sizable window delta))
2417 2426 (window--resize-reset frame)
2418 (window--resize-reset (window-frame window)) 2427 ;; When shrinking the root window, emulate an edge drag in order
2419 ;; Ideally, we would resize just the last window in a combination 2428 ;; to not resize other windows if we can avoid it (Bug#12419).
2420 ;; but that's not feasible for the following reason: If we grow 2429 (window--resize-this-window
2421 ;; the minibuffer window and the last window cannot be shrunk any 2430 window delta nil ignore t 'before
2422 ;; more, we shrink another window instead. But if we then shrink 2431 (+ (window-top-line window) (window-total-size window)))
2423 ;; the minibuffer window again, the last window might get enlarged 2432 ;; Don't record new normal sizes to make sure that shrinking back
2424 ;; and the state after shrinking is not the state before growing. 2433 ;; proportionally works as intended.
2425 ;; So, in practice, we'd need a history variable to record how to 2434 (walk-window-tree
2426 ;; proceed. But I'm not sure how such a variable could work with 2435 (lambda (window) (set-window-new-normal window 'ignore)) frame t))
2427 ;; repeated minibuffer window growing steps. 2436 ((> delta 0)
2428 (window--resize-this-window window delta nil ignore t) 2437 (window--resize-reset frame)
2429 delta))) 2438 (unless (window-sizable window delta)
2439 (setq ignore t))
2440 ;; When growing the root window, resize proportionally. This
2441 ;; should give windows back their original sizes (hopefully).
2442 (window--resize-this-window window delta nil ignore t)))
2443 ;; Return the possibly adjusted DELTA.
2444 delta))
2430 2445
2431(defun adjust-window-trailing-edge (window delta &optional horizontal) 2446(defun adjust-window-trailing-edge (window delta &optional horizontal)
2432 "Move WINDOW's bottom edge by DELTA lines. 2447 "Move WINDOW's bottom edge by DELTA lines.
@@ -5071,7 +5086,7 @@ split."
5071 (with-selected-window window 5086 (with-selected-window window
5072 (split-window-below)))))))) 5087 (split-window-below))))))))
5073 5088
5074(defun window--try-to-split-window (window) 5089(defun window--try-to-split-window (window &optional alist)
5075 "Try to split WINDOW. 5090 "Try to split WINDOW.
5076Return value returned by `split-window-preferred-function' if it 5091Return value returned by `split-window-preferred-function' if it
5077represents a live window, nil otherwise." 5092represents a live window, nil otherwise."
@@ -5079,9 +5094,14 @@ represents a live window, nil otherwise."
5079 (not (frame-parameter (window-frame window) 'unsplittable)) 5094 (not (frame-parameter (window-frame window) 'unsplittable))
5080 (let* ((window-combination-limit 5095 (let* ((window-combination-limit
5081 ;; When `window-combination-limit' equals 5096 ;; When `window-combination-limit' equals
5082 ;; `display-buffer' bind it to t so resizing steals 5097 ;; `display-buffer' or equals `resize-window' and a
5083 ;; space preferably from the window that was split. 5098 ;; `window-height' or `window-width' alist entry are
5084 (if (eq window-combination-limit 'display-buffer) 5099 ;; present, bind it to t so resizing steals space
5100 ;; preferably from the window that was split.
5101 (if (or (eq window-combination-limit 'display-buffer)
5102 (and (eq window-combination-limit 'window-size)
5103 (or (cdr (assq 'window-height alist))
5104 (cdr (assq 'window-width alist)))))
5085 t 5105 t
5086 window-combination-limit)) 5106 window-combination-limit))
5087 (new-window 5107 (new-window
@@ -5138,7 +5158,7 @@ is higher than WINDOW."
5138 (/ (- (window-total-height window) (window-total-height)) 2)) 5158 (/ (- (window-total-height window) (window-total-height)) 2))
5139 (error nil)))) 5159 (error nil))))
5140 5160
5141(defun window--display-buffer (buffer window type &optional dedicated) 5161(defun window--display-buffer (buffer window type &optional alist dedicated)
5142 "Display BUFFER in WINDOW and make its frame visible. 5162 "Display BUFFER in WINDOW and make its frame visible.
5143TYPE must be one of the symbols `reuse', `window' or `frame' and 5163TYPE must be one of the symbols `reuse', `window' or `frame' and
5144is passed unaltered to `display-buffer-record-window'. Set 5164is passed unaltered to `display-buffer-record-window'. Set
@@ -5153,6 +5173,58 @@ BUFFER and WINDOW are live."
5153 (set-window-dedicated-p window dedicated)) 5173 (set-window-dedicated-p window dedicated))
5154 (when (memq type '(window frame)) 5174 (when (memq type '(window frame))
5155 (set-window-prev-buffers window nil))) 5175 (set-window-prev-buffers window nil)))
5176 (let ((parameter (window-parameter window 'quit-restore))
5177 (height (cdr (assq 'window-height alist)))
5178 (width (cdr (assq 'window-width alist))))
5179 (when (or (memq type '(window frame))
5180 (and (eq (car parameter) 'same)
5181 (memq (nth 1 parameter) '(window frame))))
5182 ;; Adjust height of new window or frame.
5183 (cond
5184 ((not height))
5185 ((numberp height)
5186 (let* ((new-height
5187 (if (integerp height)
5188 height
5189 (round
5190 (* (window-total-size (frame-root-window window))
5191 height))))
5192 (delta (- new-height (window-total-size window))))
5193 (cond
5194 ((and (window--resizable-p window delta nil 'safe)
5195 (window-combined-p window))
5196 (window-resize window delta nil 'safe))
5197 ((or (eq type 'frame)
5198 (and (eq (car parameter) 'same)
5199 (eq (nth 1 parameter) 'frame)))
5200 (set-frame-height
5201 (window-frame window)
5202 (+ (frame-height (window-frame window)) delta))))))
5203 ((functionp height)
5204 (ignore-errors (funcall height window))))
5205 ;; Adjust width of a window or frame.
5206 (cond
5207 ((not width))
5208 ((numberp width)
5209 (let* ((new-width
5210 (if (integerp width)
5211 width
5212 (round
5213 (* (window-total-size (frame-root-window window) t)
5214 width))))
5215 (delta (- new-width (window-total-size window t))))
5216 (cond
5217 ((and (window--resizable-p window delta t 'safe)
5218 (window-combined-p window t))
5219 (window-resize window delta t 'safe))
5220 ((or (eq type 'frame)
5221 (and (eq (car parameter) 'same)
5222 (eq (nth 1 parameter) 'frame)))
5223 (set-frame-width
5224 (window-frame window)
5225 (+ (frame-width (window-frame window)) delta))))))
5226 ((functionp width)
5227 (ignore-errors (funcall width window))))))
5156 window)) 5228 window))
5157 5229
5158(defun window--maybe-raise-frame (frame) 5230(defun window--maybe-raise-frame (frame)
@@ -5394,7 +5466,7 @@ selected window."
5394 (unless (or (cdr (assq 'inhibit-same-window alist)) 5466 (unless (or (cdr (assq 'inhibit-same-window alist))
5395 (window-minibuffer-p) 5467 (window-minibuffer-p)
5396 (window-dedicated-p)) 5468 (window-dedicated-p))
5397 (window--display-buffer buffer (selected-window) 'reuse))) 5469 (window--display-buffer buffer (selected-window) 'reuse alist)))
5398 5470
5399(defun display-buffer--maybe-same-window (buffer alist) 5471(defun display-buffer--maybe-same-window (buffer alist)
5400 "Conditionally display BUFFER in the selected window. 5472 "Conditionally display BUFFER in the selected window.
@@ -5442,7 +5514,7 @@ that frame."
5442 (get-buffer-window-list buffer 'nomini 5514 (get-buffer-window-list buffer 'nomini
5443 frames)))))) 5515 frames))))))
5444 (when (window-live-p window) 5516 (when (window-live-p window)
5445 (prog1 (window--display-buffer buffer window 'reuse) 5517 (prog1 (window--display-buffer buffer window 'reuse alist)
5446 (unless (cdr (assq 'inhibit-switch-frame alist)) 5518 (unless (cdr (assq 'inhibit-switch-frame alist))
5447 (window--maybe-raise-frame (window-frame window))))))) 5519 (window--maybe-raise-frame (window-frame window)))))))
5448 5520
@@ -5479,8 +5551,8 @@ new frame."
5479 (when (and fun 5551 (when (and fun
5480 (setq frame (funcall fun)) 5552 (setq frame (funcall fun))
5481 (setq window (frame-selected-window frame))) 5553 (setq window (frame-selected-window frame)))
5482 (prog1 (window--display-buffer buffer window 5554 (prog1 (window--display-buffer
5483 'frame display-buffer-mark-dedicated) 5555 buffer window 'frame alist display-buffer-mark-dedicated)
5484 (unless (cdr (assq 'inhibit-switch-frame alist)) 5556 (unless (cdr (assq 'inhibit-switch-frame alist))
5485 (window--maybe-raise-frame frame)))))) 5557 (window--maybe-raise-frame frame))))))
5486 5558
@@ -5505,11 +5577,11 @@ raising the frame."
5505 (not (frame-parameter frame 'unsplittable)))) 5577 (not (frame-parameter frame 'unsplittable))))
5506 ;; Attempt to split largest or least recently used window. 5578 ;; Attempt to split largest or least recently used window.
5507 (setq window (or (window--try-to-split-window 5579 (setq window (or (window--try-to-split-window
5508 (get-largest-window frame t)) 5580 (get-largest-window frame t) alist)
5509 (window--try-to-split-window 5581 (window--try-to-split-window
5510 (get-lru-window frame t))))) 5582 (get-lru-window frame t) alist))))
5511 (prog1 (window--display-buffer buffer window 5583 (prog1 (window--display-buffer
5512 'window display-buffer-mark-dedicated) 5584 buffer window 'window alist display-buffer-mark-dedicated)
5513 (unless (cdr (assq 'inhibit-switch-frame alist)) 5585 (unless (cdr (assq 'inhibit-switch-frame alist))
5514 (window--maybe-raise-frame (window-frame window))))))) 5586 (window--maybe-raise-frame (window-frame window)))))))
5515 5587
@@ -5528,21 +5600,21 @@ again with `display-buffer-pop-up-window'."
5528 (and pop-up-windows 5600 (and pop-up-windows
5529 (display-buffer-pop-up-window buffer alist)))) 5601 (display-buffer-pop-up-window buffer alist))))
5530 5602
5531(defun display-buffer-below-selected (buffer _alist) 5603(defun display-buffer-below-selected (buffer alist)
5532 "Try displaying BUFFER in a window below the selected window. 5604 "Try displaying BUFFER in a window below the selected window.
5533This either splits the selected window or reuses the window below 5605This either splits the selected window or reuses the window below
5534the selected one." 5606the selected one."
5535 (let (window) 5607 (let (window)
5536 (or (and (not (frame-parameter nil 'unsplittable)) 5608 (or (and (not (frame-parameter nil 'unsplittable))
5537 (setq window (window--try-to-split-window (selected-window))) 5609 (setq window (window--try-to-split-window (selected-window) alist))
5538 (window--display-buffer 5610 (window--display-buffer
5539 buffer window 'window display-buffer-mark-dedicated)) 5611 buffer window 'window alist display-buffer-mark-dedicated))
5540 (and (setq window (window-in-direction 'below)) 5612 (and (setq window (window-in-direction 'below))
5541 (not (window-dedicated-p window)) 5613 (not (window-dedicated-p window))
5542 (window--display-buffer 5614 (window--display-buffer
5543 buffer window 'reuse display-buffer-mark-dedicated))))) 5615 buffer window 'reuse alist display-buffer-mark-dedicated)))))
5544 5616
5545(defun display-buffer-at-bottom (buffer _alist) 5617(defun display-buffer-at-bottom (buffer alist)
5546 "Try displaying BUFFER in a window at the botom of the selected frame. 5618 "Try displaying BUFFER in a window at the botom of the selected frame.
5547This either splits the window at the bottom of the frame or the 5619This either splits the window at the bottom of the frame or the
5548frame's root window, or reuses an existing window at the bottom 5620frame's root window, or reuses an existing window at the bottom
@@ -5550,20 +5622,20 @@ of the selected frame."
5550 (let (bottom-window window) 5622 (let (bottom-window window)
5551 (walk-window-tree (lambda (window) (setq bottom-window window))) 5623 (walk-window-tree (lambda (window) (setq bottom-window window)))
5552 (or (and (not (frame-parameter nil 'unsplittable)) 5624 (or (and (not (frame-parameter nil 'unsplittable))
5553 (setq window (window--try-to-split-window bottom-window)) 5625 (setq window (window--try-to-split-window bottom-window alist))
5554 (window--display-buffer 5626 (window--display-buffer
5555 buffer window 'window display-buffer-mark-dedicated)) 5627 buffer window 'window alist display-buffer-mark-dedicated))
5556 (and (not (frame-parameter nil 'unsplittable)) 5628 (and (not (frame-parameter nil 'unsplittable))
5557 (setq window 5629 (setq window
5558 (condition-case nil 5630 (condition-case nil
5559 (split-window (frame-root-window)) 5631 (split-window (frame-root-window))
5560 (error nil))) 5632 (error nil)))
5561 (window--display-buffer 5633 (window--display-buffer
5562 buffer window 'window display-buffer-mark-dedicated)) 5634 buffer window 'window alist display-buffer-mark-dedicated))
5563 (and (setq window bottom-window) 5635 (and (setq window bottom-window)
5564 (not (window-dedicated-p window)) 5636 (not (window-dedicated-p window))
5565 (window--display-buffer 5637 (window--display-buffer
5566 buffer window 'reuse display-buffer-mark-dedicated))))) 5638 buffer window 'reuse alist display-buffer-mark-dedicated)))))
5567 5639
5568(defun display-buffer-in-previous-window (buffer alist) 5640(defun display-buffer-in-previous-window (buffer alist)
5569 "Display BUFFER in a window previously showing it. 5641 "Display BUFFER in a window previously showing it.
@@ -5619,7 +5691,7 @@ above, even if that window never showed BUFFER before."
5619 (setq best-window window))) 5691 (setq best-window window)))
5620 ;; Return best or second best window found. 5692 ;; Return best or second best window found.
5621 (when (setq window (or best-window second-best-window)) 5693 (when (setq window (or best-window second-best-window))
5622 (window--display-buffer buffer window 'reuse)))) 5694 (window--display-buffer buffer window 'reuse alist))))
5623 5695
5624(defun display-buffer-use-some-window (buffer alist) 5696(defun display-buffer-use-some-window (buffer alist)
5625 "Display BUFFER in an existing window. 5697 "Display BUFFER in an existing window.
@@ -5647,7 +5719,7 @@ that frame."
5647 (get-largest-window 0 not-this-window)))) 5719 (get-largest-window 0 not-this-window))))
5648 (when (window-live-p window) 5720 (when (window-live-p window)
5649 (prog1 5721 (prog1
5650 (window--display-buffer buffer window 'reuse) 5722 (window--display-buffer buffer window 'reuse alist)
5651 (window--even-window-heights window) 5723 (window--even-window-heights window)
5652 (unless (cdr (assq 'inhibit-switch-frame alist)) 5724 (unless (cdr (assq 'inhibit-switch-frame alist))
5653 (window--maybe-raise-frame (window-frame window))))))) 5725 (window--maybe-raise-frame (window-frame window)))))))
@@ -5917,6 +5989,97 @@ WINDOW must be a live window and defaults to the selected one."
5917 window)))) 5989 window))))
5918 5990
5919;;; Resizing buffers to fit their contents exactly. 5991;;; Resizing buffers to fit their contents exactly.
5992(defcustom fit-frame-to-buffer nil
5993 "Non-nil means `fit-window-to-buffer' can resize frames.
5994A frame can be resized if and only if its root window is a live
5995window. The height of the root window is subject to the values
5996of `fit-frame-to-buffer-max-height' and `window-min-height'."
5997 :type 'boolean
5998 :version "24.2"
5999 :group 'help)
6000
6001(defcustom fit-frame-to-buffer-bottom-margin 4
6002 "Bottom margin for `fit-frame-to-buffer'.
6003This is the number of lines `fit-frame-to-buffer' leaves free at the
6004bottom of the display in order to not obscure the system task bar."
6005 :type 'integer
6006 :version "24.2"
6007 :group 'windows)
6008
6009(defun fit-frame-to-buffer (&optional frame max-height min-height)
6010 "Adjust height of FRAME to display its buffer's contents exactly.
6011FRAME can be any live frame and defaults to the selected one.
6012
6013Optional argument MAX-HEIGHT specifies the maximum height of
6014FRAME and defaults to the height of the display below the current
6015top line of FRAME minus FIT-FRAME-TO-BUFFER-BOTTOM-MARGIN.
6016Optional argument MIN-HEIGHT specifies the minimum height of
6017FRAME."
6018 (interactive)
6019 (setq frame (window-normalize-frame frame))
6020 (let* ((root (frame-root-window frame))
6021 (frame-min-height
6022 (+ (- (frame-height frame) (window-total-size root))
6023 window-min-height))
6024 (frame-top (frame-parameter frame 'top))
6025 (top (if (consp frame-top)
6026 (funcall (car frame-top) (cadr frame-top))
6027 frame-top))
6028 (frame-max-height
6029 (- (/ (- (x-display-pixel-height frame) top)
6030 (frame-char-height frame))
6031 fit-frame-to-buffer-bottom-margin))
6032 (compensate 0)
6033 delta)
6034 (when (and (window-live-p root) (not (window-size-fixed-p root)))
6035 (with-selected-window root
6036 (cond
6037 ((not max-height)
6038 (setq max-height frame-max-height))
6039 ((numberp max-height)
6040 (setq max-height (min max-height frame-max-height)))
6041 (t
6042 (error "%s is an invalid maximum height" max-height)))
6043 (cond
6044 ((not min-height)
6045 (setq min-height frame-min-height))
6046 ((numberp min-height)
6047 (setq min-height (min min-height frame-min-height)))
6048 (t
6049 (error "%s is an invalid minimum height" min-height)))
6050 ;; When tool-bar-mode is enabled and we have just created a new
6051 ;; frame, reserve lines for toolbar resizing. This is needed
6052 ;; because for reasons unknown to me Emacs (1) reserves one line
6053 ;; for the toolbar when making the initial frame and toolbars
6054 ;; are enabled, and (2) later adds the remaining lines needed.
6055 ;; Our code runs IN BETWEEN (1) and (2). YMMV when you're on a
6056 ;; system that behaves differently.
6057 (let ((quit-restore (window-parameter root 'quit-restore))
6058 (lines (tool-bar-lines-needed frame)))
6059 (when (and quit-restore (eq (car quit-restore) 'frame)
6060 (not (zerop lines)))
6061 (setq compensate (1- lines))))
6062 (message "%s" compensate)
6063 (setq delta
6064 ;; Always count a final newline - we don't do any
6065 ;; post-processing, so let's play safe.
6066 (+ (count-screen-lines nil nil t)
6067 (- (window-body-size))
6068 compensate)))
6069 ;; Move away from final newline.
6070 (when (and (eobp) (bolp) (not (bobp)))
6071 (set-window-point root (line-beginning-position 0)))
6072 (set-window-start root (point-min))
6073 (set-window-vscroll root 0)
6074 (condition-case nil
6075 (set-frame-height
6076 frame
6077 (min (max (+ (frame-height frame) delta)
6078 min-height)
6079 max-height))
6080 (error (setq delta nil))))
6081 delta))
6082
5920(defun fit-window-to-buffer (&optional window max-height min-height) 6083(defun fit-window-to-buffer (&optional window max-height min-height)
5921 "Adjust height of WINDOW to display its buffer's contents exactly. 6084 "Adjust height of WINDOW to display its buffer's contents exactly.
5922WINDOW must be a live window and defaults to the selected one. 6085WINDOW must be a live window and defaults to the selected one.
@@ -5937,9 +6100,12 @@ _all_ lines of its buffer you might not see the first lines when
5937WINDOW was scrolled." 6100WINDOW was scrolled."
5938 (interactive) 6101 (interactive)
5939 (setq window (window-normalize-window window t)) 6102 (setq window (window-normalize-window window t))
5940 ;; Can't resize a full height or fixed-size window. 6103 (cond
5941 (unless (or (window-size-fixed-p window) 6104 ((window-size-fixed-p window))
5942 (window-full-height-p window)) 6105 ((window-full-height-p window)
6106 (when fit-frame-to-buffer
6107 (fit-frame-to-buffer (window-frame window))))
6108 (t
5943 (with-selected-window window 6109 (with-selected-window window
5944 (let* ((height (window-total-size)) 6110 (let* ((height (window-total-size))
5945 (min-height 6111 (min-height
@@ -5955,7 +6121,7 @@ WINDOW was scrolled."
5955 ;; Can't get larger than height of frame. 6121 ;; Can't get larger than height of frame.
5956 (min max-height 6122 (min max-height
5957 (window-total-size (frame-root-window window))) 6123 (window-total-size (frame-root-window window)))
5958 ;, Don't delete other windows. 6124 ;; Don't delete other windows.
5959 (+ height (window-max-delta nil nil window)))) 6125 (+ height (window-max-delta nil nil window))))
5960 ;; Make `desired-height' the height necessary to show 6126 ;; Make `desired-height' the height necessary to show
5961 ;; all of WINDOW's buffer, constrained by MIN-HEIGHT 6127 ;; all of WINDOW's buffer, constrained by MIN-HEIGHT
@@ -6018,89 +6184,7 @@ WINDOW was scrolled."
6018 (window-resize window 1 nil window) 6184 (window-resize window 1 nil window)
6019 (setq desired-height (1+ desired-height))))) 6185 (setq desired-height (1+ desired-height)))))
6020 (error (setq delta nil))) 6186 (error (setq delta nil)))
6021 delta)))) 6187 delta)))))
6022
6023(defcustom fit-frame-to-buffer-bottom-margin 4
6024 "Bottom margin for `fit-frame-to-buffer'.
6025This is the number of lines `fit-frame-to-buffer' leaves free at the
6026bottom of the display in order to not obscure the system task bar."
6027 :type 'integer
6028 :version "24.2"
6029 :group 'windows)
6030
6031(defun fit-frame-to-buffer (&optional frame max-height min-height)
6032 "Adjust height of FRAME to display its buffer's contents exactly.
6033FRAME can be any live frame and defaults to the selected one.
6034
6035Optional argument MAX-HEIGHT specifies the maximum height of
6036FRAME and defaults to the height of the display below the current
6037top line of FRAME minus FIT-FRAME-TO-BUFFER-BOTTOM-MARGIN.
6038Optional argument MIN-HEIGHT specifies the minimum height of
6039FRAME."
6040 (interactive)
6041 (setq frame (window-normalize-frame frame))
6042 (let* ((root (frame-root-window frame))
6043 (frame-min-height
6044 (+ (- (frame-height frame) (window-total-size root))
6045 window-min-height))
6046 (frame-top (frame-parameter frame 'top))
6047 (top (if (consp frame-top)
6048 (funcall (car frame-top) (cadr frame-top))
6049 frame-top))
6050 (frame-max-height
6051 (- (/ (- (x-display-pixel-height frame) top)
6052 (frame-char-height frame))
6053 fit-frame-to-buffer-bottom-margin))
6054 (compensate 0)
6055 delta)
6056 (when (and (window-live-p root) (not (window-size-fixed-p root)))
6057 (with-selected-window root
6058 (cond
6059 ((not max-height)
6060 (setq max-height frame-max-height))
6061 ((numberp max-height)
6062 (setq max-height (min max-height frame-max-height)))
6063 (t
6064 (error "%s is an invalid maximum height" max-height)))
6065 (cond
6066 ((not min-height)
6067 (setq min-height frame-min-height))
6068 ((numberp min-height)
6069 (setq min-height (min min-height frame-min-height)))
6070 (t
6071 (error "%s is an invalid minimum height" min-height)))
6072 ;; When tool-bar-mode is enabled and we have just created a new
6073 ;; frame, reserve lines for toolbar resizing. This is needed
6074 ;; because for reasons unknown to me Emacs (1) reserves one line
6075 ;; for the toolbar when making the initial frame and toolbars
6076 ;; are enabled, and (2) later adds the remaining lines needed.
6077 ;; Our code runs IN BETWEEN (1) and (2). YMMV when you're on a
6078 ;; system that behaves differently.
6079 (let ((quit-restore (window-parameter root 'quit-restore))
6080 (lines (tool-bar-lines-needed frame)))
6081 (when (and quit-restore (eq (car quit-restore) 'frame)
6082 (not (zerop lines)))
6083 (setq compensate (1- lines))))
6084 (message "%s" compensate)
6085 (setq delta
6086 ;; Always count a final newline - we don't do any
6087 ;; post-processing, so let's play safe.
6088 (+ (count-screen-lines nil nil t)
6089 (- (window-body-size))
6090 compensate)))
6091 ;; Move away from final newline.
6092 (when (and (eobp) (bolp) (not (bobp)))
6093 (set-window-point root (line-beginning-position 0)))
6094 (set-window-start root (point-min))
6095 (set-window-vscroll root 0)
6096 (condition-case nil
6097 (set-frame-height
6098 frame
6099 (min (max (+ (frame-height frame) delta)
6100 min-height)
6101 max-height))
6102 (error (setq delta nil))))
6103 delta))
6104 6188
6105(defun window-safely-shrinkable-p (&optional window) 6189(defun window-safely-shrinkable-p (&optional window)
6106 "Return t if WINDOW can be shrunk without shrinking other windows. 6190 "Return t if WINDOW can be shrunk without shrinking other windows.