comparison lisp/window.el @ 42307:922f0ef2951b

(balance-windows): Use new PRESERVE-BEFORE arg to enlarge-window. Use save-selected-window. Don't try to resize windows that end at the bottom "level". Retry changing the sizes until the windows get the desired sizes. Discount the minibuffer when computing total height available.
author Richard M. Stallman <rms@gnu.org>
date Tue, 25 Dec 2001 10:34:39 +0000
parents 9736d12fa64c
children 55ed8ccce828
comparison
equal deleted inserted replaced
42306:58ac31906c29 42307:922f0ef2951b
160 (car (window-edges (next-window))))))) 160 (car (window-edges (next-window)))))))
161 161
162 (defun balance-windows () 162 (defun balance-windows ()
163 "Make all visible windows the same height (approximately)." 163 "Make all visible windows the same height (approximately)."
164 (interactive) 164 (interactive)
165 (let ((count -1) levels newsizes size 165 (let ((count -1) levels newsizes level-size
166 ;; Don't count the lines that are above the uppermost windows. 166 ;; Don't count the lines that are above the uppermost windows.
167 ;; (These are the menu bar lines, if any.) 167 ;; (These are the menu bar lines, if any.)
168 (mbl (nth 1 (window-edges (frame-first-window (selected-frame)))))) 168 (mbl (nth 1 (window-edges (frame-first-window (selected-frame)))))
169 (last-window (previous-window (frame-first-window (selected-frame))))
170 ;; Don't count the lines that are past the lowest main window.
171 total)
172 ;; Bottom edge of last window determines what size we have to work with.
173 (setq total
174 (+ (window-height last-window)
175 (nth 1 (window-edges last-window))))
176
169 ;; Find all the different vpos's at which windows start, 177 ;; Find all the different vpos's at which windows start,
170 ;; then count them. But ignore levels that differ by only 1. 178 ;; then count them. But ignore levels that differ by only 1.
171 (save-window-excursion 179 (let (tops (prev-top -2))
172 (let (tops (prev-top -2)) 180 (walk-windows (function (lambda (w)
173 (walk-windows (function (lambda (w) 181 (setq tops (cons (nth 1 (window-edges w))
174 (setq tops (cons (nth 1 (window-edges w)) 182 tops))))
175 tops)))) 183 'nomini)
176 'nomini) 184 (setq tops (sort tops '<))
177 (setq tops (sort tops '<)) 185 (while tops
178 (while tops 186 (if (> (car tops) (1+ prev-top))
179 (if (> (car tops) (1+ prev-top)) 187 (setq prev-top (car tops)
180 (setq prev-top (car tops) 188 count (1+ count)))
181 count (1+ count))) 189 (setq levels (cons (cons (car tops) count) levels))
182 (setq levels (cons (cons (car tops) count) levels)) 190 (setq tops (cdr tops)))
183 (setq tops (cdr tops))) 191 (setq count (1+ count)))
184 (setq count (1+ count)))) 192 ;; Subdivide the frame into desired number of vertical levels.
185 ;; Subdivide the frame into that many vertical levels. 193 (setq level-size (/ (- total mbl) count))
186 (setq size (/ (- (frame-height) mbl) count)) 194 (save-selected-window
187 (walk-windows (function 195 ;; Set up NEWSIZES to map windows to their desired sizes.
188 (lambda (w) 196 ;; If a window ends at the bottom level, don't include
189 (select-window w) 197 ;; it in NEWSIZES. Those windows get the right sizes
190 (let ((newtop (cdr (assq (nth 1 (window-edges)) 198 ;; by adjusting the ones above them.
191 levels))) 199 (walk-windows (function
192 (newbot (or (cdr (assq (+ (window-height) 200 (lambda (w)
193 (nth 1 (window-edges))) 201 (let ((newtop (cdr (assq (nth 1 (window-edges w))
194 levels)) 202 levels)))
195 count))) 203 (newbot (cdr (assq (+ (window-height w)
196 (setq newsizes 204 (nth 1 (window-edges w)))
197 (cons (cons w (* size (- newbot newtop))) 205 levels))))
198 newsizes))))) 206 (if newbot
199 'nomini) 207 (setq newsizes
200 (walk-windows (function (lambda (w) 208 (cons (cons w (* level-size (- newbot newtop)))
201 (select-window w) 209 newsizes)))))))
202 (let ((newsize (cdr (assq w newsizes)))) 210 'nomini)
203 (enlarge-window (- newsize 211 ;; Make walk-windows start with the topmost window.
204 (window-height)))))) 212 (select-window (previous-window (frame-first-window (selected-frame))))
205 'nomini))) 213 (let (done (count 0))
214 ;; Give each window its precomputed size, or at least try.
215 ;; Keep trying until they all get the intended sizes,
216 ;; but not more than 3 times (to prevent infinite loop).
217 (while (and (not done) (< count 3))
218 (setq done t)
219 (setq count (1+ count))
220 (walk-windows (function (lambda (w)
221 (select-window w)
222 (let ((newsize (cdr (assq w newsizes))))
223 (when newsize
224 (enlarge-window (- newsize
225 (window-height))
226 nil t)
227 (unless (= (window-height) newsize)
228 (setq done nil))))))
229 'nomini)))))
206 230
207 ;;; I think this should be the default; I think people will prefer it--rms. 231 ;;; I think this should be the default; I think people will prefer it--rms.
208 (defcustom split-window-keep-point t 232 (defcustom split-window-keep-point t
209 "*If non-nil, split windows keeps the original point in both children. 233 "*If non-nil, split windows keeps the original point in both children.
210 This is often more convenient for editing. 234 This is often more convenient for editing.