unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* balance-windows again
@ 2005-09-14 23:43 Lennart Borgman
  2005-09-16  7:01 ` Lennart Borgman
  0 siblings, 1 reply; 9+ messages in thread
From: Lennart Borgman @ 2005-09-14 23:43 UTC (permalink / raw)


Some time ago I wrote some suggestions about how to rewrite 
balance-windows to use the windows split tree. I have tried to do that. 
The file bw.el at

   http://ourcomments.org/Emacs/DL/elisp/test/

contains my rewrite of balance-windows. Could those who are interested 
please test this version?

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

* RE: balance-windows again
@ 2005-09-15 17:13 Bingham, Jay
  2005-09-15 22:11 ` Lennart Borgman
  0 siblings, 1 reply; 9+ messages in thread
From: Bingham, Jay @ 2005-09-15 17:13 UTC (permalink / raw)


<Send replies only to the list not to this address>

On: Wednesday, September 14, 2005 at 6:43 PM Lennart Borgman wrote:

> Some time ago I wrote some suggestions about how to rewrite 
> balance-windows to use the windows split tree. I have tried to do
that. 
> The file bw.el at
> 
>    http://ourcomments.org/Emacs/DL/elisp/test/
> 
> contains my rewrite of balance-windows. Could those who are interested

> please test this version?

Lennart,

I tried your bw.el package on emacs 21.3 running on Win2K, and found the
following:

After evaluating the buffer containing the package and splitting window
into three uneven windows I executed bw-balance.  I received the
following message:
let: Wrong number of arguments: #<subr enlarge-window>, 3

Looking at the function bw-enlarge-window I saw that the invocation of
enlarge-window has three arguments (arg side preserve-before), the help
on enlarge window in emacs 21.3 says that the funciton requires at most
two arguments.  I removed the third argument (preserve-before) and
re-evaled the buffer.  When I executed the function bw-balance the
windows were balanced as expected.  I then tried some configurations
that were a little more complex and they balanced as expected.  The
following configurations balanced as expected:

+----------------------+    +----------+-----+-----+
|                      |    |          |     |     |
|                      |    |          |     |     |
|                      |    |          |     |     |
+----------------------+    |          |     |     |
|                      |    +----------+-----+-----+
|                      |    |                      |
|                      |    |                      |
+----------------------+    |                      |
|                      |    |                      |
|                      |    +----------------------+
|                      |    |                      |
|                      |    |                      |
|                      |    |                      |
|                      |    |                      |
+----------------------+    +----------------------+

+------+-------+-------+
|      |       |       |
|      |       |       |
|      |       |       |
|      |       |       |
+------+-------+-------+
|                      |
|                      |
|                      |
|                      |
+----------+-----+-----+
|          |     |     |
|          |     |     |
|          |     |     |
|          |     |     |
+----------+-----+-----+

However, when I tried some more complex configurations of windows, emacs
stopped responding and I would have to kill the process.

Here are two windows configurations that caused emacs to hang:

+------+-------+-------+	+------+-------+-------+
|      |       |       |	|      |       |       |
|      |       |       |	|      |       |       |
|      |       |       |	|      |       |       |
|      |       |       |	|      |       |       |
+------+-------+-------+	+------+-------+-------+
|                      |	|                      |
|                      |	|                      |
+----------------------+	+----------------------+
|                      |	|                      |
|                      |	|                      |
+----------+-----+-----+	+------+-------+-------+
|          |     |     |	|      |       |       |
|          |     |     |	|      |       |       |
|          |     |     |	|      |       |       |
|          |     |     |	|      |       |       |
+----------+-----+-----+	+------+-------+-------+

+----------------------+
|                      |
|                      |
+----------------------+
|                      |
|                      |
+------+-------+-------+
|      |       |       |
|      |       |       |
|      |       |       |
|      |       |       |
+------+---+---+-+-----+
|          |     |     |
|          |     |     |
|          |     |     |
|          |     |     |
+----------+-----+-----+

This not so complex configuration also caused a hang:

+----------------------+
|                      |
|                      |
|                      |
|                      |
+----------------------+
|                      |
|                      |
|                      |
|                      |
+------+---------------+
|      |               |
|      |               |
|      |               |
|      |               |
+------+---------------+

-_
J_)
C_)ingham
.    Hewlett-Packard
.    Austin, TX
. "Language is the apparel in which your thoughts parade in public.
.  Never clothe them in vulgar and shoddy attire."     -Dr. George W.
Crane-

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

* Re: balance-windows again
  2005-09-15 17:13 Bingham, Jay
@ 2005-09-15 22:11 ` Lennart Borgman
  0 siblings, 0 replies; 9+ messages in thread
From: Lennart Borgman @ 2005-09-15 22:11 UTC (permalink / raw)
  Cc: help-gnu-emacs

Bingham, Jay wrote:

><Send replies only to the list not to this address>
>
>On: Wednesday, September 14, 2005 at 6:43 PM Lennart Borgman wrote:
>
>  
>
>>Some time ago I wrote some suggestions about how to rewrite 
>>balance-windows to use the windows split tree. I have tried to do
>>    
>>
>that. 
>  
>
>>The file bw.el at
>>
>>   http://ourcomments.org/Emacs/DL/elisp/test/
>>
>>contains my rewrite of balance-windows. Could those who are interested please test this version?
>>    
>>
>
>Lennart,
>
>I tried your bw.el package on emacs 21.3 running on Win2K, and found the
>following:
>
>After evaluating the buffer containing the package and splitting window
>into three uneven windows I executed bw-balance.  I received the
>following message:
>let: Wrong number of arguments: #<subr enlarge-window>, 3
>

>However, when I tried some more complex configurations of windows, emacs
>stopped responding and I would have to kill the process.
>
>Here are two windows configurations that caused emacs to hang:
>  
>
Thanks Jay! I am only using CVS Emacs and missed that enlarge-window 
only take two args in 21.3.

The window configurations you tested works well in CVS Emacs. I guess 
they do not converge because my code depends on the third arg to 
enlarge-window. I have made some small changes that I hope will make the 
code work on 21.3 too, but the result will of course is some cases not 
be as good as in CVS Emacs though. The new version is 0.52 and I have 
just uploaded it.

I have however found a case where bw-balance does not work, but I 
believe it is a bug in CVS Emacs. I have told this on the Emacs Devel 
list and I am waiting for some answer.

Best wishes,
Lennart

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

* Re: balance-windows again
  2005-09-14 23:43 balance-windows again Lennart Borgman
@ 2005-09-16  7:01 ` Lennart Borgman
  2005-09-16  8:20   ` Kim F. Storm
  0 siblings, 1 reply; 9+ messages in thread
From: Lennart Borgman @ 2005-09-16  7:01 UTC (permalink / raw)
  Cc: help-gnu-emacs, Emacs Devel

Lennart Borgman wrote:

> Some time ago I wrote some suggestions about how to rewrite 
> balance-windows to use the windows split tree. I have tried to do 
> that. The file bw.el at
>
>   http://ourcomments.org/Emacs/DL/elisp/test/
>
> contains my rewrite of balance-windows. Could those who are interested 
> please test this version?

I have fixed some bugs (after feedback from Jay Bingham) and I believe 
it works ok now. It works a little bit better with CVS Emacs than 21.3.

bw.el balances windows both horizontally and vertically. I think 
bw-balance could be a replacement for the current balance-windows. 
(Though there seem to be other candidates too.)

Some heuristics are used to find the window split tree and those fails 
sometimes. It does not make the resulting window resizing awful, but it 
could be better if the split tree where known. However giving read 
access to the window split tree from elisp would simplify the code in 
bw.el a lot and make the result better in those cases.

Is there any possibility that access to the window split tree from elisp 
could be implemented in Emacs?

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

* Re: balance-windows again
  2005-09-16  7:01 ` Lennart Borgman
@ 2005-09-16  8:20   ` Kim F. Storm
  2005-09-16 12:44     ` Lennart Borgman
  0 siblings, 1 reply; 9+ messages in thread
From: Kim F. Storm @ 2005-09-16  8:20 UTC (permalink / raw)
  Cc: help-gnu-emacs, Emacs Devel

Lennart Borgman <lennart.borgman.073@student.lu.se> writes:

> Is there any possibility that access to the window split tree from
> elisp could be implemented in Emacs?

What format would you like the data to have ?

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

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

* Re: balance-windows again
  2005-09-16  8:20   ` Kim F. Storm
@ 2005-09-16 12:44     ` Lennart Borgman
  2005-09-27 22:57       ` Kim F. Storm
  0 siblings, 1 reply; 9+ messages in thread
From: Lennart Borgman @ 2005-09-16 12:44 UTC (permalink / raw)
  Cc: help-gnu-emacs, Emacs Devel

Kim F. Storm wrote:

>Lennart Borgman <lennart.borgman.073@student.lu.se> writes:
>
>  
>
>>Is there any possibility that access to the window split tree from
>>elisp could be implemented in Emacs?
>>    
>>
>
>What format would you like the data to have ?
>  
>
A tree where the nodes are the splits and the leaves are the windows.

This does not have to be fast and it is not big. In bw.el I use a 
representation where each node is an association list. Here is the tree 
after C-x 2, C-x 3, C-x 2, C-x 2:

 ((b . 60)
  (r . 160)
  (t . 0)
  (l . 0)
  (childs ((b . 30)
           (r . 160)
           (t . 0)
           (l . 0)
           (childs ((b . 30)
                    (r . 80)
                    (t . 0)
                    (l . 0)
                    (childs #<window 164 on window.el>
                            #<window 180 on window.el>
                            #<window 179 on window.el>)
                    (dir . ver))
                   #<window 177 on window.el>)
           (dir . hor))
          #<window 1 75 on window.el>)
  (dir . ver))

The keys l, t, r, b are the borders (left, top, right, bottom), similar 
to what `window-edges' returns. They should NOT be there in the list 
when you ask for the frames window split tree. (I compute these with 
bw-refresh-edges.)

A list representation like this is convenient I think. It should be easy 
to store weights there if someone wants another kind of balancing.

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

* Re: balance-windows again
  2005-09-16 12:44     ` Lennart Borgman
@ 2005-09-27 22:57       ` Kim F. Storm
  2005-09-29 12:34         ` Kim F. Storm
  0 siblings, 1 reply; 9+ messages in thread
From: Kim F. Storm @ 2005-09-27 22:57 UTC (permalink / raw)
  Cc: help-gnu-emacs, Emacs Devel

Lennart Borgman <lennart.borgman.073@student.lu.se> writes:

>>>Is there any possibility that access to the window split tree from
>>>elisp could be implemented in Emacs?
>>
> A tree where the nodes are the splits and the leaves are the windows.
>

The following patch adds a window-split-tree function which returns a simple
tree presentation of the window split.  You can use window-edges on the
elements of the tree to get the dimensions (and build your representation).



Index: window.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/window.c,v
retrieving revision 1.516
diff -c -r1.516 window.c
*** window.c	18 Sep 2005 16:28:53 -0000	1.516
--- window.c	27 Sep 2005 22:54:40 -0000
***************
*** 6225,6230 ****
--- 6226,6312 ----
    return unbind_to (count, val);
  }

+
+ \f
+ /***********************************************************************
+ 			    Window Split Tree
+  ***********************************************************************/
+
+ static Lisp_Object
+ window_split_tree (w)
+      struct window *w;
+ {
+   Lisp_Object tail = Qnil;
+   Lisp_Object result = Qnil;
+
+   while (w)
+     {
+       Lisp_Object wn;
+
+       XSETWINDOW (wn, w);
+       if (!NILP (w->hchild))
+ 	wn = Fcons (Qnil, Fcons (wn, window_split_tree (XWINDOW (w->hchild))));
+       else if (!NILP (w->vchild))
+ 	wn = Fcons (Qt, Fcons (wn, window_split_tree (XWINDOW (w->vchild))));
+
+       if (NILP (result))
+ 	{
+ 	  result = tail = Fcons (wn, Qnil);
+ 	}
+       else
+ 	{
+ 	  XSETCDR (tail, Fcons (wn, Qnil));
+ 	  tail = XCDR (tail);
+ 	}
+
+       w = NILP (w->next) ? 0 : XWINDOW (w->next);
+     }
+
+   return result;
+ }
+
+
+
+ DEFUN ("window-split-tree", Fwindow_split_tree, Swindow_split_tree,
+        0, 1, 0,
+        doc: /* Return the window split tree for frame FRAME.
+
+ The return value is a list of the form (ROOT MINI), where ROOT
+ represents the window split tree of the frame's root window, and MINI
+ is the frame's minibuffer window.
+
+ If the root window is not split, ROOT is the root window itself.
+ Otherwise, ROOT is a list (DIR W W1 W2 ...) where DIR is nil for a
+ horisontal split, and t for a vertical split, W is the container
+ window for the window split, and the rest of the elements are the
+ subwindows in the split.  Each of the subwindows may again be a window
+ or a list of subwindows, and so on.
+
+ The container windows are not live windows (see `window-live-p'), but
+ you can use `window-edges' and `window-inside-edges' on the container
+ windows to get the combined size of a sub-tree of the full window
+ split.
+
+ If FRAME is nil or omitted, return information on the currently
+ selected frame.  */)
+      (frame)
+      Lisp_Object frame;
+ {
+   Lisp_Object alist;
+   FRAME_PTR f;
+
+   if (NILP (frame))
+     frame = selected_frame;
+
+   CHECK_FRAME (frame);
+   f = XFRAME (frame);
+
+   if (!FRAME_LIVE_P (f))
+     return Qnil;
+
+   return window_split_tree (XWINDOW (FRAME_ROOT_WINDOW (f)));
+ }
+
  \f
  /***********************************************************************
  			    Marginal Areas
***************
*** 7031,7036 ****
--- 7113,7119 ----
    defsubr (&Sset_window_configuration);
    defsubr (&Scurrent_window_configuration);
    defsubr (&Ssave_window_excursion);
+   defsubr (&Swindow_split_tree);
    defsubr (&Sset_window_margins);
    defsubr (&Swindow_margins);
    defsubr (&Sset_window_fringes);
>

--
Kim F. Storm <storm@cua.dk> http://www.cua.dk

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

* Re: balance-windows again
  2005-09-27 22:57       ` Kim F. Storm
@ 2005-09-29 12:34         ` Kim F. Storm
  2005-09-30 12:03           ` Lennart Borgman
  0 siblings, 1 reply; 9+ messages in thread
From: Kim F. Storm @ 2005-09-29 12:34 UTC (permalink / raw)
  Cc: help-gnu-emacs, Emacs Devel

storm@cua.dk (Kim F. Storm) writes:

> The following patch adds a window-split-tree function which returns a simple
> tree presentation of the window split.  You can use window-edges on the
> elements of the tree to get the dimensions (and build your representation).

I think exposing the "container windows" as my previous patch did was
a really bad idea.  Instead, I prefer to explicitly include the
window-edges of those windows.  Below is a different patch which
implements this.

The new window-split-tree function doesn't return the format Lennart
requested, but it is trivial to convert it to his proposed format:

(defun balance-window-split (&optional frame)
  (balance-window-split-1 (car (window-split-tree frame))))

(defun balance-window-split-1 (split)
  (if (windowp split)
      split
    (let ((dir (car split))
	  (edges (car (cdr split)))
	  (childs (cdr (cdr split))))
      (list
       (cons 'dir (if dir 'ver 'hor))
       (cons 'b (nth 3 edges))
       (cons 'r (nth 2 edges))
       (cons 't (nth 1 edges))
       (cons 'l (nth 0 edges))
       (cons 'childs (mapcar #'balance-window-split-1 childs))))))


Here's the revised patch:

Index: window.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/window.c,v
retrieving revision 1.516
diff -c -r1.516 window.c
*** window.c	18 Sep 2005 16:28:53 -0000	1.516
--- window.c	29 Sep 2005 12:31:57 -0000
***************
*** 6225,6230 ****
--- 6226,6310 ----
    return unbind_to (count, val);
  }
  
+ 
+ \f
+ /***********************************************************************
+ 			    Window Split Tree
+  ***********************************************************************/
+ 
+ static Lisp_Object
+ window_split_tree (w)
+      struct window *w;
+ {
+   Lisp_Object tail = Qnil;
+   Lisp_Object result = Qnil;
+ 
+   while (w)
+     {
+       Lisp_Object wn;
+ 
+       XSETWINDOW (wn, w);
+       if (!NILP (w->hchild))
+ 	wn = Fcons (Qnil, Fcons (Fwindow_edges (wn),
+ 				 window_split_tree (XWINDOW (w->hchild))));
+       else if (!NILP (w->vchild))
+ 	wn = Fcons (Qt, Fcons (Fwindow_edges (wn),
+ 			       window_split_tree (XWINDOW (w->vchild))));
+ 
+       if (NILP (result))
+ 	{
+ 	  result = tail = Fcons (wn, Qnil);
+ 	}
+       else
+ 	{
+ 	  XSETCDR (tail, Fcons (wn, Qnil));
+ 	  tail = XCDR (tail);
+ 	}
+ 
+       w = NILP (w->next) ? 0 : XWINDOW (w->next);
+     }
+ 
+   return result;
+ }
+ 
+ 
+ 
+ DEFUN ("window-split-tree", Fwindow_split_tree, Swindow_split_tree,
+        0, 1, 0,
+        doc: /* Return the window split tree for frame FRAME.
+ 
+ The return value is a list of the form (ROOT MINI), where ROOT
+ represents the window split tree of the frame's root window, and MINI
+ is the frame's minibuffer window.
+ 
+ If the root window is not split, ROOT is the root window itself.
+ Otherwise, ROOT is a list (DIR EDGES W1 W2 ...) where DIR is nil for a
+ horisontal split, and t for a vertical split, EDGES gives the combined
+ size and position of the subwindows in the split, and the rest of the
+ elements are the subwindows in the split.  Each of the subwindows may
+ again be a window or a list representing a window split, and so on.
+ EDGES is a list \(LEFT TOP RIGHT BOTTOM) as returned by `window-edges'.
+ 
+ If FRAME is nil or omitted, return information on the currently
+ selected frame.  */)
+      (frame)
+      Lisp_Object frame;
+ {
+   Lisp_Object alist;
+   FRAME_PTR f;
+ 
+   if (NILP (frame))
+     frame = selected_frame;
+ 
+   CHECK_FRAME (frame);
+   f = XFRAME (frame);
+ 
+   if (!FRAME_LIVE_P (f))
+     return Qnil;
+ 
+   return window_split_tree (XWINDOW (FRAME_ROOT_WINDOW (f)));
+ }
+ 
  \f
  /***********************************************************************
  			    Marginal Areas
***************
*** 7031,7036 ****
--- 7111,7117 ----
    defsubr (&Sset_window_configuration);
    defsubr (&Scurrent_window_configuration);
    defsubr (&Ssave_window_excursion);
+   defsubr (&Swindow_split_tree);
    defsubr (&Sset_window_margins);
    defsubr (&Swindow_margins);
    defsubr (&Sset_window_fringes);

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

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

* Re: balance-windows again
  2005-09-29 12:34         ` Kim F. Storm
@ 2005-09-30 12:03           ` Lennart Borgman
  0 siblings, 0 replies; 9+ messages in thread
From: Lennart Borgman @ 2005-09-30 12:03 UTC (permalink / raw)
  Cc: help-gnu-emacs, Emacs Devel

Kim F. Storm wrote:

>storm@cua.dk (Kim F. Storm) writes:
>
>  
>
>>The following patch adds a window-split-tree function which returns a simple
>>tree presentation of the window split.  You can use window-edges on the
>>elements of the tree to get the dimensions (and build your representation).
>>    
>>
>
>I think exposing the "container windows" as my previous patch did was
>a really bad idea.  Instead, I prefer to explicitly include the
>window-edges of those windows.  Below is a different patch which
>implements this.
>
>The new window-split-tree function doesn't return the format Lennart
>requested, but it is trivial to convert it to his proposed format:
>
>(defun balance-window-split (&optional frame)
>  (balance-window-split-1 (car (window-split-tree frame))))
>
>(defun balance-window-split-1 (split)
>  (if (windowp split)
>      split
>    (let ((dir (car split))
>	  (edges (car (cdr split)))
>	  (childs (cdr (cdr split))))
>      (list
>       (cons 'dir (if dir 'ver 'hor))
>       (cons 'b (nth 3 edges))
>       (cons 'r (nth 2 edges))
>       (cons 't (nth 1 edges))
>       (cons 'l (nth 0 edges))
>       (cons 'childs (mapcar #'balance-window-split-1 childs))))))
>
>
>Here's the revised patch:
>  
>
Thanks Kim,

Very nice! I have tested a little bit now and done some trivial changes 
to bw.el to test your code. It seems to be working fine, but I have not 
tested very much yet. The new version of bw.el (where I have not cleaned 
up the old code yet) is here:

   http://ourcomments.org/Emacs/DL/elisp/test/

And now back to what I really have to do today...  ;-)

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

end of thread, other threads:[~2005-09-30 12:03 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-09-14 23:43 balance-windows again Lennart Borgman
2005-09-16  7:01 ` Lennart Borgman
2005-09-16  8:20   ` Kim F. Storm
2005-09-16 12:44     ` Lennart Borgman
2005-09-27 22:57       ` Kim F. Storm
2005-09-29 12:34         ` Kim F. Storm
2005-09-30 12:03           ` Lennart Borgman
  -- strict thread matches above, loose matches on Subject: below --
2005-09-15 17:13 Bingham, Jay
2005-09-15 22:11 ` Lennart Borgman

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