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 | |
| 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.
| -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 |