diff options
| author | Richard M. Stallman | 2001-12-25 10:34:39 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 2001-12-25 10:34:39 +0000 |
| commit | 0d6c5d184966a74f3d44d05b63cd244d9f02b199 (patch) | |
| tree | 3618bb52d1703940ddc1a2c9f3a1afea2af48cd5 /lisp | |
| parent | d0fd26dd0b254aa7e796be7e68e61790ac5b3f24 (diff) | |
| download | emacs-0d6c5d184966a74f3d44d05b63cd244d9f02b199.tar.gz emacs-0d6c5d184966a74f3d44d05b63cd244d9f02b199.zip | |
(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.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/window.el | 98 |
1 files changed, 61 insertions, 37 deletions
diff --git a/lisp/window.el b/lisp/window.el index 532a1cc0009..1b8830fb190 100644 --- a/lisp/window.el +++ b/lisp/window.el | |||
| @@ -162,47 +162,71 @@ If WINDOW is nil or omitted, it defaults to the currently selected window." | |||
| 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 |