> After `balance-windows' After my new function > +-------+-------+-------+ +-------+-------+-------+ > | 9 | | | | | | | > | | | 19 | | 15 | | 20 | > +-------+ | | | | | | > | | 29 | | +-------+ 30 | | > | 19 | +-------+ | | +-------+ > | | | | | 15 | | | > | | | | | | | | > +----+--+-------+ 19 | +----+--+-------+ 20 | > | | | | | | | | | | > | 19 | | | | | 14 | | | | > | | | +-------+ | | | +-------+ > | | | 32 | | +----+--+ 31 | | > +----+--+ | | | | | | > | | | 22 | | 15 | | 20 | > | 12 | | | | | | | > | | | | | | | | > +-------+-------+-------+ +-------+-------+-------+
For what it's worth, here is another alternative I wrote a few years ago. Note how it iterates to try and get to a fix point without using the `preserve-before' argument (which didn't exist at that point). Stefan (defun balance-windows-area () "Make all visible windows use the same area (approximately)." (interactive) (save-selected-window (let* ((change t) (resizecount 0) (wins (window-list nil 'nomini)) (count (length wins)) minresize next (carry 0)) ;; Resizing a window changes the size of surrounding windows ;; in complex ways, so it's difficult to set the sizes in a single pass. ;; Instead, we just go through all the windows several times ;; until nothing needs to be CHANGEd. (while (and change (> count 1)) (setq change nil count (1- count)) (dolist (win wins) ;; We always have to check liveness because enlarging/shrinking ;; always risks deleting windows (although we are very careful ;; to avoid most such cases). (when (and (window-live-p win) (not (window-fixed-size-p win))) (select-window win) (setq next nil) (while (progn (setq next (next-window next)) (window-fixed-size-p next))) (let ((diff (- (* (window-height) (window-width)) (* (window-height next) (window-width next))))) (if (< (car (window-edges)) (car (window-edges next))) ;; The windows are side-by-side (unless (zerop (setq diff (/ diff (window-height) 2))) ;; Change things more smoothly. (if (or (> diff 1) (< diff -1)) (setq diff (/ diff 2))) (shrink-window diff) (setq change t)) (setq diff (/ diff (window-width) 2)) ;; Change things more smoothly. (if (or (> diff 1) (< diff -1)) (setq diff (/ diff 2))) (cond ((= diff 0)) ;; Try to shrink to balance out with a smaller next window. ;; Enlarging risks killing a window, but if the next-window ;; is adjacent, then it should be safe. ((or (and (> diff 0) (window-safely-shrinkable-p)) (and (< diff 0) (= (car (window-edges)) (car (window-edges next))) (not (eq next (frame-first-window))))) (shrink-window diff) (setq change t)) ;; Resizing is also safe if all windows are big enough. ((> (setq minresize (- (apply 'min (mapcar 'window-height wins)) window-min-height)) 0) (shrink-window (if (> diff 0) (min diff minresize) (max diff (- minresize)))) (setq change t)) ;; Let's try yet something else ((and (< diff 0) (window-safely-shrinkable-p next)) (select-window next) (shrink-window (- diff)) (setq change t))))))))))) _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel