unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* New balance-windows (Was Re: Making the width of three windows equal)
       [not found]     ` <87fytr3ea2.fsf@thalassa.informatimago.com>
@ 2005-08-06 11:59       ` Ehud Karni
  2005-08-06 13:27         ` New balance-windows Ehud Karni
  2005-08-07 17:15         ` New balance-windows (Was Re: Making the width of three windows equal) Richard M. Stallman
       [not found]       ` <mailman.2754.1123329756.20277.help-gnu-emacs@gnu.org>
  1 sibling, 2 replies; 12+ messages in thread
From: Ehud Karni @ 2005-08-06 11:59 UTC (permalink / raw)
  Cc: knipknap, help-gnu-emacs, spam

Following the recent discussion of `balance-windows' on help-gnu-emacs
I looked into it and wrote a replacement (new) function based on
somewhat different logic to achieve the balancing.

The logic is this: group all windows that has the same "left" (or "top"
for horizontal) edge, and balance their height (width).

The actual resizing is dependent on the window structure.
e.g. the two symmetrical window structures below will be balanced
differently (the diagrams are after vertical balancing):

       +-------+--------+             +-------+--------+
       |       |        |             |       |        |
       | 1 / 3 |        |             |       | 1 / 4  |
       |       |        |             | 1 / 2 +--------+
       +-------|  2 / 3 |             |       |        |
       |       |        |             |       | 1 / 4  |
       | 1 / 3 |        |             +-------+--------+
       |       |        |             |                |
       +-------+--------+             |                |
       |                |             |     1 / 2      |
       |     1 / 3      |             |                |
       |                |             |                |
       +-------+--------+             +-------+--------+

On the other hand if the windows are more "normally" built it works
fine (diagrams after horizontal balancing):

    +-----+-----+------+----+    +-------+-------+-------+
    | 1/4 | 1/4 | 1/4 | 1/4 |    | 1 / 3 | 1 / 3 | 1 / 3 |
    |     |     |     |     |    |       |       |       |
    +-----+-+---+---+-+-----+    +-----+-+---+---+-+-----+
    |       |       |       |    |     |     |     |     |
    | 1 / 3 | 1 / 3 | 1 / 3 |    | 1/4 | 1/4 | 1/4 | 1/4 |
    +-------+-------+-------+    +-----+-----+------+----+

To balance horizontally just add a prefix argument (i.e. C-u).

Note. I don't have CVS write permission, so if some of the developers
find this as adequate replacement to `balance-windows' please add it.


Ehud.


(defun balance-windows (&optional horizontally)
  "Make all visible windows on the current frame the same size (approximately).
If optional prefix arg is not given, \"same size\" is same height.
When prefix arg is given,  \"same size\" is same width."
  (interactive "P")
  (let* (count size w cmjr resize max rpt
         (edge (if horizontally 0 1))  ;; Minor field to sort by 0=LEFT, 1=TOP
         (mjr (- 1 edge))              ;; Major field to sort
         (far (+ 2 edge))              ;; far edge (right/bottom)
         (windows nil)                 ;; list of windows
         (ix 0)
         nwin                          ;; number of windows
         (pass 1)                      ;; pass number
         (curw (selected-window))      ;; selected window (to return to)
         )
    ;; Build and sort list of all windows on frame
       (save-window-excursion
           (walk-windows (function (lambda (w)
                               (let ((ltrb (window-edges w)))
                                   (setq windows (cons (list
                                       (nth mjr  ltrb)
                                       (nth edge ltrb)
                                       (nth far  ltrb)
                                       w) windows)))))
                         'nomini)
           (setq windows (sort windows (lambda (e1 e2)
                                         (if (< (nth 0 e1) (nth 0 e2))
                                               t
                                           (if (= (nth 0 e1) (nth 0 e2))
                                               (if (< (nth 1 e1) (nth 2 e2))
                                                   t)))))))
       (setq nwin (length windows))
       ;; add 1 extra entry (for while check)
       (setq windows (append windows '((-1 -1 -1 nil))))

       (while (< ix nwin)                      ; walk on all (sorted) windows
           (setq count 0)                      ; number of windows in 1 column (or row)
           (setq cmjr (car (nth ix windows)))  ; column / raw identification
           (while (= cmjr (car (nth (+ count ix) windows)))    ; same
               (setq count (1+ count)))        ; count them
           (if (= count 1)                     ; only one window in this column/row
               (setq ix (1+ ix))               ; skip it
             ; compute and resize windows
             (setq size (if (= pass 1)         ; on pass 1 the saved edges have not changed
                          (- (nth 2 (nth (1- (+ count ix)) windows))
                             (nth 1 (nth ix windows)))
                        ;; previous changes may changed the window edges
                        (- (nth far (window-edges (nth 3 (nth (1- (+ count ix)) windows))))
                           (nth edge (window-edges (nth 3 (nth ix windows)))))))
             (setq size (/ (+ size count -1) count)) ; average window size

             (setq max (+ ix count))           ; index of next column/row
             ;; the resizing loop must be done twice
             ;; because later change may resize previous window
             (setq rpt 2)
             (while (> rpt 0)
               (setq rpt (1- rpt))
               (while (< ix max)
                 (setq w (nth 3 (nth ix windows)))
                 (setq resize (- size (- (nth far (window-edges w))
                                         (nth edge (window-edges w)))))
                 ; don't resize by 1 character
                 (if (or (> resize 1)
                         (< resize -1))
                     (progn
                       (select-window w)       ; window to work on
                       (enlarge-window resize horizontally)))
                 (setq ix (1+ ix)))
               (setq ix (- max count)))
             (setq ix max)
             (setq pass 2)))
           (select-window curw)))



--
 Ehud Karni           Tel: +972-3-7966-561  /"\
 Mivtach - Simon      Fax: +972-3-7966-667  \ /  ASCII Ribbon Campaign
 Insurance agencies   (USA) voice mail and   X   Against   HTML   Mail
 http://www.mvs.co.il  FAX:  1-815-5509341  / \
 GnuPG: 98EA398D <http://www.keyserver.net/>    Better Safe Than Sorry

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: New balance-windows
  2005-08-06 11:59       ` New balance-windows (Was Re: Making the width of three windows equal) Ehud Karni
@ 2005-08-06 13:27         ` Ehud Karni
  2005-08-07 17:15         ` New balance-windows (Was Re: Making the width of three windows equal) Richard M. Stallman
  1 sibling, 0 replies; 12+ messages in thread
From: Ehud Karni @ 2005-08-06 13:27 UTC (permalink / raw)
  Cc: help-gnu-emacs, knipknap, spam

There was an error on my last post of the new `balance-windows'.
Thanks to Lennart Borgman <lennart.borgman.073@student.lu.se>
who spotted the small typo that is a big bug.

Bellow is the corrected code.

Ehud.


(defun balance-windows (&optional horizontally)
  "Make all visible windows on the current frame the same size (approximately).
If optional prefix arg is not given, \"same size\" is same height.
When prefix arg is given,  \"same size\" is same width."
  (interactive "P")
  (let* (count size w cmjr resize max rpt
         (edge (if horizontally 0 1))  ;; Minor field to sort by 0=LEFT, 1=TOP
         (mjr (- 1 edge))              ;; Major field to sort
         (far (+ 2 edge))              ;; far edge (right/bottom)
         (windows nil)                 ;; list of windows
         (ix 0)
         nwin                          ;; number of windows
         (pass 1)                      ;; pass number
         (curw (selected-window))      ;; selected window (to return to)
         )
    ;; Build and sort list of all windows on frame
       (save-window-excursion
           (walk-windows (function (lambda (w)
                               (let ((ltrb (window-edges w)))
                                   (setq windows (cons (list
                                       (nth mjr  ltrb)
                                       (nth edge ltrb)
                                       (nth far  ltrb)
                                       w) windows)))))
                         'nomini)
           (setq windows (sort windows (lambda (e1 e2)
                                         (if (< (nth 0 e1) (nth 0 e2))
                                               t
                                           (if (= (nth 0 e1) (nth 0 e2))
                                               (if (< (nth 1 e1) (nth 1 e2))
                                                   t)))))))
       (setq nwin (length windows))
       ;; add 1 extra entry (for while check)
       (setq windows (append windows '((-1 -1 -1 nil))))

       (while (< ix nwin)                      ; walk on all (sorted) windows
           (setq count 0)                      ; number of windows in 1 column (or row)
           (setq cmjr (car (nth ix windows)))  ; column / raw identification
           (while (= cmjr (car (nth (+ count ix) windows)))    ; same
               (setq count (1+ count)))        ; count them
           (if (= count 1)                     ; only one window in this column/row
               (setq ix (1+ ix))               ; skip it
             ; compute and resize windows
             (setq size (if (= pass 1)         ; on pass 1 the saved edges have not changed
                          (- (nth 2 (nth (1- (+ count ix)) windows))
                             (nth 1 (nth ix windows)))
                        ;; previous changes may changed the window edges
                        (- (nth far (window-edges (nth 3 (nth (1- (+ count ix)) windows))))
                           (nth edge (window-edges (nth 3 (nth ix windows)))))))
             (setq size (/ (+ size count -1) count)) ; average window size

             (setq max (+ ix count))           ; index of next column/row
             ;; the resizing loop must be done twice
             ;; because later change may resize previous window
             (setq rpt 2)
             (while (> rpt 0)
               (setq rpt (1- rpt))
               (while (< ix max)
                 (setq w (nth 3 (nth ix windows)))
                 (setq resize (- size (- (nth far (window-edges w))
                                         (nth edge (window-edges w)))))
                 ; don't resize by 1 character
                 (if (or (> resize 1)
                         (< resize -1))
                     (progn
                       (select-window w)       ; window to work on
                       (enlarge-window resize horizontally)))
                 (setq ix (1+ ix)))
               (setq ix (- max count)))
             (setq ix max)
             (setq pass 2)))
           (select-window curw)))



--
 Ehud Karni           Tel: +972-3-7966-561  /"\
 Mivtach - Simon      Fax: +972-3-7966-667  \ /  ASCII Ribbon Campaign
 Insurance agencies   (USA) voice mail and   X   Against   HTML   Mail
 http://www.mvs.co.il  FAX:  1-815-5509341  / \
 GnuPG: 98EA398D <http://www.keyserver.net/>    Better Safe Than Sorry

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: New balance-windows
       [not found]         ` <87vf2juij1.fsf@thalassa.informatimago.com>
@ 2005-08-06 21:05           ` Ehud Karni
  2005-08-06 23:22             ` Lennart Borgman
  2005-08-07  2:17           ` Lennart Borgman
  1 sibling, 1 reply; 12+ messages in thread
From: Ehud Karni @ 2005-08-06 21:05 UTC (permalink / raw)
  Cc: help-gnu-emacs

On Sat, 06 Aug 2005 18:39:14 +0200, Pascal Bourguignon wrote:
>
> "Ehud Karni" <ehud@unix.mvs.co.il> writes:
>
> > Following the recent discussion of `balance-windows' on help-gnu-emacs
> > I looked into it and wrote a replacement (new) function based on
> > somewhat different logic to achieve the balancing.
>

I think it is good as it can get until Emacs resizing is changed.

In Emacs 22.0.50 a 3rd argument was add to enlarge window:
    Optional third arg PRESERVE-BEFORE, if non-nil, means do not
    change the size of the siblings above or to the left of the
    selected window. Only siblings to the right or below are changed.

I tried using this argument but I found a problem (bug ?).
When you have a configuration like:

    +----------+----------+
    +   lw1    +   rw1    +
    +----------+          +
    +   lw2    +----------+
    +----------+   rw2    +
    +   lw3    +          +
    +----------+----------+
    +         fw6         +
    +----------+----------+

You can move the border between windows lw3/rw2 and fw6 with
enlarge-window command in lw3/rw2. i.e. the command
(enlarge-window 5 nil t) in lw3/rw2 does nothing.

Because the preserving is regarding only windows to the left and
above the current window (and there is no other way to specify the
size of a window) the "enlarging/shrinking" must be done from top
to bottom or left to right (which my function does).

Below is my latest version (using PRESERVE-BEFORE - available only
in 22.0) which is failing in such situation.

NOTE. This discussion really should be done in emacs-devel@gnu.org
list and not in help-gnu-emacs@gnu.org.

Ehud.


The lines with "^ ;; (" are for debugging, just drop the ";;" and
you'll see animation of the resizing with messages in the echo area.


(defun balance-windows (&optional horizontally)
  "Make all visible windows on the current frame the same size (approximately).
If optional prefix arg is not given, \"same size\" is same height.
When prefix arg is given,  \"same size\" is same width."
  (interactive "P")
  (let* (count size w cmjr resize
         (edge (if horizontally 0 1))  ;; Minor field to sort by 0=LEFT, 1=TOP
         (mjr (- 1 edge))              ;; Major field to sort
         (far (+ 2 edge))              ;; far edge (right/bottom) - for current size
         (windows nil)                 ;; list of windows
         (ix 0)
         nwin                          ;; number of windows
         (curw (selected-window))      ;; selected window (to return to)
         )
    ;; Build and sort list of all windows on frame
       (save-window-excursion
           (walk-windows (function (lambda (w)
                               (let ((ltrb (window-edges w)))
                                   (setq windows (cons (list
                                       (nth mjr  ltrb)
                                       (nth edge ltrb)
                                       (nth far  ltrb)
                                       w) windows)))))
                         'nomini)
           (setq windows (sort windows (lambda (e1 e2)
                                         (if (< (nth 0 e1) (nth 0 e2))
                                               t
                                           (if (= (nth 0 e1) (nth 0 e2))
                                               (if (< (nth 1 e1) (nth 1 e2))
                                                   t)))))))
       (setq nwin (length windows))
       ;; add 1 extra entry (for while check)
       (setq windows (append windows '((-1 -1 -1 nil))))

       (while (< ix nwin)                      ; walk on all (sorted) windows
           (setq count ix)                     ; count the windows in 1 column (or row)
           (setq cmjr (car (nth ix windows)))  ; column / raw identification
           (while (= cmjr (car (nth ix windows)))  ; same column / row
               (setq ix (1+ ix)))              ; next window
           (setq count (- ix count))
           (if (/= count 1)                    ; do only if more than one window in this column/row
               (let ((gix (- ix count)))
                 (setq size (- (nth far (window-edges (nth 3 (nth (1- ix) windows))))
                               (nth edge (window-edges (nth 3 (nth (- ix count) windows))))))
                 (setq size (/ (+ size count -1) count)) ; average window size

 ;; (message "Size=%d" size)

                 (while (< gix ix)
                   (setq w (nth 3 (nth gix windows)))
                   (setq resize (- size (- (nth far (window-edges w))
                                           (nth edge (window-edges w)))))

 ;; (message "Window=%s  resize=%d" w resize)
                   ; don't resize by 1 character/line
                   (if (or (> resize 1)
                           (< resize -1))
                       (progn

 ;; (sit-for 2)

                         (select-window w)       ; window to work on
                         (enlarge-window resize horizontally 'preserve)
 ;; (sit-for 2)
                         ))
                   (setq gix (1+ gix))))))

 ;; (message "")
       (select-window curw)))



--
 Ehud Karni           Tel: +972-3-7966-561  /"\
 Mivtach - Simon      Fax: +972-3-7966-667  \ /  ASCII Ribbon Campaign
 Insurance agencies   (USA) voice mail and   X   Against   HTML   Mail
 http://www.mvs.co.il  FAX:  1-815-5509341  / \
 GnuPG: 98EA398D <http://www.keyserver.net/>    Better Safe Than Sorry

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: New balance-windows
  2005-08-06 21:05           ` Ehud Karni
@ 2005-08-06 23:22             ` Lennart Borgman
  0 siblings, 0 replies; 12+ messages in thread
From: Lennart Borgman @ 2005-08-06 23:22 UTC (permalink / raw)
  Cc: emacs-devel

Ehud Karni wrote:

>I tried using this argument but I found a problem (bug ?).
>When you have a configuration like:
>
>    +----------+----------+
>    +   lw1    +   rw1    +
>    +----------+          +
>    +   lw2    +----------+
>    +----------+   rw2    +
>    +   lw3    +          +
>    +----------+----------+
>    +         fw6         +
>    +----------+----------+
>
>You can move the border between windows lw3/rw2 and fw6 with
>enlarge-window command in lw3/rw2. i.e. the command
>(enlarge-window 5 nil t) in lw3/rw2 does nothing.
>  
>
Seems like a bug to me too. I can see the same problem.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: New balance-windows
       [not found]         ` <87vf2juij1.fsf@thalassa.informatimago.com>
  2005-08-06 21:05           ` Ehud Karni
@ 2005-08-07  2:17           ` Lennart Borgman
  2005-08-08  9:36             ` Ehud Karni
       [not found]             ` <mailman.2988.1123495783.20277.help-gnu-emacs@gnu.org>
  1 sibling, 2 replies; 12+ messages in thread
From: Lennart Borgman @ 2005-08-07  2:17 UTC (permalink / raw)
  Cc: help-gnu-emacs, Emacs Devel

Pascal Bourguignon wrote:

>"Ehud Karni" <ehud@unix.mvs.co.il> writes:
>
>  
>
>>Following the recent discussion of `balance-windows' on help-gnu-emacs
>>I looked into it and wrote a replacement (new) function based on
>>somewhat different logic to achieve the balancing.
>>    
>>
>
>Thanks very much.  It's nice.  But it's not perfect, see at the end.
>
>  
>
>...
>I think a correct algorithm should recover the split tree, then make
>the balancing depending on the window counts in subtrees.
>  
>
I think Pascal is right. Though I think Ehud has made a very nice try I 
believe the split tree must be used. There is not enough information to 
solve the problem otherwise.

Could it perhaps be done like this?:

1) Walk the tree of windows and compute and remember a weight for the 
childs in the subtree of each window and store that.

2) Walk the tree of windows once again and resize according to the 
weights from the top of the tree towards the bottom in each branch 
(recursively of course)!

The weight could be computed as just the sum of childs but I think that 
should look odd and not be useful. Therefore I suggest that for each 
level in the subtree the weight is reduced by some factor. Naturally, in 
the usual mind of Emacs, this could be either a fixed fraction, say 0.7, 
or a list of fractions.

I believe this should be easy to implement but I might have forgotten 
something?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: New balance-windows (Was Re: Making the width of three windows equal)
  2005-08-06 11:59       ` New balance-windows (Was Re: Making the width of three windows equal) Ehud Karni
  2005-08-06 13:27         ` New balance-windows Ehud Karni
@ 2005-08-07 17:15         ` Richard M. Stallman
  2005-08-08  9:27           ` Ehud Karni
  1 sibling, 1 reply; 12+ messages in thread
From: Richard M. Stallman @ 2005-08-07 17:15 UTC (permalink / raw)
  Cc: knipknap, help-gnu-emacs, spam, emacs-devel

Why do you think this is better than the current balance-windows function?

(I would rather we focus attention on the steps needed to make a
release.)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: New balance-windows (Was Re: Making the width of three windows equal)
  2005-08-07 17:15         ` New balance-windows (Was Re: Making the width of three windows equal) Richard M. Stallman
@ 2005-08-08  9:27           ` Ehud Karni
  2005-08-09  0:27             ` Richard M. Stallman
  2005-08-10  0:05             ` New balance-windows Stefan Monnier
  0 siblings, 2 replies; 12+ messages in thread
From: Ehud Karni @ 2005-08-08  9:27 UTC (permalink / raw)
  Cc: knipknap, help-gnu-emacs, emacs-devel

On Sun, 07 Aug 2005 13:15:35 -0400, Richard M. Stallman <rms@gnu.org> wrote:
>
> Why do you think this is better than the current balance-windows function?

Two reasons: 1. because it fails in a complex windows arrangement.
  2. I added balancing horizontally option (by prefix argument).

Here are some examples of balancing complex windows configuration
(the number in each window is the of lines in the window):

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

In the above case mine is better.


    After `balance-windows'           After my new function
    +-----------+-----------+        +----------+------------+
    |           |   10      |        |          |     6      |
    |           |           |        |          +------------+
    |           +-----------+        |    19    |     6      |
    |   32      |   10      |        |          +------------+
    |           |           |        |          |     5      |
    |           +-----------+        +------+---+---+--------|
    |           |   10      |        |      |       |        |
    |           |           |        |  18  |       |  18    |
    +------+----+---+-------+        |      |       |        |
    |  10  |        |  10   |        |      |       |        |
    |      |        |       |        +------+-------+--------|
    +------+--------+-------+        |                       |
    |                       |        |         17            |
    |          12           |        |                       |
    |                       |        |                       |
    +-----------------------+        +-----------------------+

In this case the 22.0.50 balance-windows is better.


If 2 more splits are done, both functions fails:

    After `balance-windows'           After my new function
    +-----------+-----------+        +-----------+-----------+
    |           |    8      |        |           |   10      |
    |   17      |           |        |   14      |           |
    |           +-----------+        |           +-----------+
    |           |           |        +-----------+   10      |
    +-----------+           |        |           |           |
    |           |   17      |        |           +-----+-----+
    |   14      |           |        |   17      |     |     |
    |           +-----+-----+        |           | 10  | 10  |
    |           |  4  | 4   |        |           |     |     |
--> +------+----+---+-+-----+  -V-   +------+----+---+-+-----+ <---
    |   8  |        |  8    |        |      |        |       |
    |      |        |       |        |  12  |  12    |  12   |
    +------+--------+-------+        |      |        |       |
    |                       |        +------+--------+-------+
    |          14           |        |          10           |
    |                       |        |                       |
    +-----------------------+        +-----------------------+

The reason to the failure is that in this configuration the
vertical border (-V-) , although full length border, can NOT
be moved by resizing of any window.

I have looked into `enlarge-window' and I it is too complex for
me to fix it.

So, I'll work on my function some more. My proposed logic (for
vertical balancing) is to group the windows according to the
right edge AND the left edge (every window will be in 2 groups)
sort the groups by number of windows in each group, compute the
new size for this group and resize the windows in this group.
Now, repeat the whole process but ignore all the windows that
have already been resized. This approach is using ONLY the
geometry of the windows configuration. It sure will fail when
there is an unmovable edge.

Ehud.


--
 Ehud Karni           Tel: +972-3-7966-561  /"\
 Mivtach - Simon      Fax: +972-3-7966-667  \ /  ASCII Ribbon Campaign
 Insurance agencies   (USA) voice mail and   X   Against   HTML   Mail
 http://www.mvs.co.il  FAX:  1-815-5509341  / \
 GnuPG: 98EA398D <http://www.keyserver.net/>    Better Safe Than Sorry

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: New balance-windows
  2005-08-07  2:17           ` Lennart Borgman
@ 2005-08-08  9:36             ` Ehud Karni
       [not found]             ` <mailman.2988.1123495783.20277.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 12+ messages in thread
From: Ehud Karni @ 2005-08-08  9:36 UTC (permalink / raw)
  Cc: help-gnu-emacs, emacs-devel

On Sun, 07 Aug 2005 04:17:21 +0200, Lennart Borgman <lennart.borgman.073@student.lu.se> wrote:
>
> Pascal Bourguignon wrote:
>
> >...
> >I think a correct algorithm should recover the split tree, then make
> >the balancing depending on the window counts in subtrees.
> >
> >
> I think Pascal is right. Though I think Ehud has made a very nice try I
> believe the split tree must be used. There is not enough information to
> solve the problem otherwise.

I think that balancing the windows should be done based on geometry
ONLY. What do I care how this geometry was reached ?

The split tree may cause technical difficulties to the redisplay
engine, but it should be solved there.

The problem is with `enlarge-window' that can not move some edges,
otherwise there is pure geometry algorithm to resize the windows (see
my other reply).

Ehud.


--
 Ehud Karni           Tel: +972-3-7966-561  /"\
 Mivtach - Simon      Fax: +972-3-7966-667  \ /  ASCII Ribbon Campaign
 Insurance agencies   (USA) voice mail and   X   Against   HTML   Mail
 http://www.mvs.co.il  FAX:  1-815-5509341  / \
 GnuPG: 98EA398D <http://www.keyserver.net/>    Better Safe Than Sorry

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: New balance-windows
       [not found]               ` <85wtmw4tpu.fsf@lola.goethe.zz>
@ 2005-08-08 11:18                 ` Ehud Karni
  0 siblings, 0 replies; 12+ messages in thread
From: Ehud Karni @ 2005-08-08 11:18 UTC (permalink / raw)
  Cc: help-gnu-emacs, emacs-devel

On Mon, 08 Aug 2005 12:18:53 +0200, David Kastrup <dak@gnu.org> wrote:
>
> "Ehud Karni" <ehud@unix.mvs.co.il> writes:
>
> >
> > I think that balancing the windows should be done based on geometry
> > ONLY. What do I care how this geometry was reached ?
> >
> > The split tree may cause technical difficulties to the redisplay
> > engine, but it should be solved there.
> >
> > The problem is with `enlarge-window' that can not move some edges,
> > otherwise there is pure geometry algorithm to resize the windows (see
> > my other reply).
>
>
> Well, I can arrive at
>
> -------------------------
> |           |X          |
> |           |           |
> |           |           | configuration
> -------------------------      0
> |           |           |
> |           |           |
> |           |           |
> -------------------------
>
> with enlarge-window from either
>
> -------------------------
> |           |X          |
> |           |           |
> |           |-----------| configuration
> ------------|           |     1
> |           |           |
> |           |           |
> |           |           |
> -------------------------
>
> or
>
> -------------------------
> |            |X         |
> |            |          | configuration
> |            |          |      2
> -------------------------
> |           |           |
> |           |           |
> |           |           |
> -------------------------
>
> If I now do another enlarge-window, I would be surprised if the
> direction of enlargement would suddenly change.

The direction of enlargement (vertical or horizontal) is given by
the user, how could that be changed by the split tree.

As I said this is only a technical difficulty. I know Emacs behave
this way, but this is because of the design of Emacs.

I expect that when we have configuration 0 (even if we got there going
through configuration 2 and not from 1), and we do enlarge-window
(on window with X) we'll get:

 -------------------------
 |           |X          |
 |           |           |
 |           |           | expectation
 ------------|           |
 |           |-----------|
 |           |           |
 |           |           |
 -------------------------

And the way Emacs works is to move the whole border like this:

 -------------------------
 |           |X          |
 |           |           |
 |           |           | current behavior
 |           |           |
 ------------------------|
 |           |           |
 |           |           |
 -------------------------

Ehud.


--
 Ehud Karni           Tel: +972-3-7966-561  /"\
 Mivtach - Simon      Fax: +972-3-7966-667  \ /  ASCII Ribbon Campaign
 Insurance agencies   (USA) voice mail and   X   Against   HTML   Mail
 http://www.mvs.co.il  FAX:  1-815-5509341  / \
 GnuPG: 98EA398D <http://www.keyserver.net/>    Better Safe Than Sorry

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: New balance-windows (Was Re: Making the width of three windows equal)
  2005-08-08  9:27           ` Ehud Karni
@ 2005-08-09  0:27             ` Richard M. Stallman
  2005-08-10  0:05             ` New balance-windows Stefan Monnier
  1 sibling, 0 replies; 12+ messages in thread
From: Richard M. Stallman @ 2005-08-09  0:27 UTC (permalink / raw)
  Cc: knipknap, help-gnu-emacs, emacs-devel

    If 2 more splits are done, both functions fails:

    The reason to the failure is that in this configuration the
    vertical border (-V-) , although full length border, can NOT
    be moved by resizing of any window.

Why can't it?

Did you try passing t for the second argument of enlarge-window,
after calling it on one of the windows above the line to be moved?

Anyway, we recently discussed the idea of a way to represent
window configurations as transparent Lisp data, and I suggested
a way that this could be implemented safely.  That would eliminate
a lot of these problems, because you could compute the desired
arrangement as a window configuration and then install it.

All of this is for after the current release.  If you want to work on
it on the side noiw, by all means do.  However, I'd like to ask other
people to join in work needed for the release, rather than this.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: New balance-windows
  2005-08-08  9:27           ` Ehud Karni
  2005-08-09  0:27             ` Richard M. Stallman
@ 2005-08-10  0:05             ` Stefan Monnier
  2005-08-10  1:48               ` Stefan Monnier
  1 sibling, 1 reply; 12+ messages in thread
From: Stefan Monnier @ 2005-08-10  0:05 UTC (permalink / raw)
  Cc: knipknap, help-gnu-emacs, rms, emacs-devel

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

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: New balance-windows
  2005-08-10  0:05             ` New balance-windows Stefan Monnier
@ 2005-08-10  1:48               ` Stefan Monnier
  0 siblings, 0 replies; 12+ messages in thread
From: Stefan Monnier @ 2005-08-10  1:48 UTC (permalink / raw)
  Cc: knipknap, help-gnu-emacs, rms, emacs-devel

> 	      (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)
                                      ^^
                                       t

[ I mistakenly removed this second arg before posting my code, thinking I was
  using a local extension of shrink-window, but I later noticed that it was
  not the case (I dropped this local extension when it collided with
  preserve-before). ]


        Stefan

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2005-08-10  1:48 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <pan.2005.08.03.00.47.36.497219@debain.org>
     [not found] ` <87pssv3kai.fsf@thalassa.informatimago.com>
     [not found]   ` <1123035204.009217.187300@g14g2000cwa.googlegroups.com>
     [not found]     ` <87fytr3ea2.fsf@thalassa.informatimago.com>
2005-08-06 11:59       ` New balance-windows (Was Re: Making the width of three windows equal) Ehud Karni
2005-08-06 13:27         ` New balance-windows Ehud Karni
2005-08-07 17:15         ` New balance-windows (Was Re: Making the width of three windows equal) Richard M. Stallman
2005-08-08  9:27           ` Ehud Karni
2005-08-09  0:27             ` Richard M. Stallman
2005-08-10  0:05             ` New balance-windows Stefan Monnier
2005-08-10  1:48               ` Stefan Monnier
     [not found]       ` <mailman.2754.1123329756.20277.help-gnu-emacs@gnu.org>
     [not found]         ` <87vf2juij1.fsf@thalassa.informatimago.com>
2005-08-06 21:05           ` Ehud Karni
2005-08-06 23:22             ` Lennart Borgman
2005-08-07  2:17           ` Lennart Borgman
2005-08-08  9:36             ` Ehud Karni
     [not found]             ` <mailman.2988.1123495783.20277.help-gnu-emacs@gnu.org>
     [not found]               ` <85wtmw4tpu.fsf@lola.goethe.zz>
2005-08-08 11:18                 ` Ehud Karni

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).