unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Re: balance-windows again
       [not found] <4328B58E.6010103@student.lu.se>
@ 2005-09-16  7:01 ` Lennart Borgman
  2005-09-16  8:20   ` Kim F. Storm
  0 siblings, 1 reply; 7+ 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] 7+ messages in thread

* Re: balance-windows again
  2005-09-16  7:01 ` balance-windows again Lennart Borgman
@ 2005-09-16  8:20   ` Kim F. Storm
  2005-09-16 12:44     ` Lennart Borgman
  0 siblings, 1 reply; 7+ 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] 7+ 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; 7+ 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] 7+ 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  2:42         ` Richard M. Stallman
  2005-09-29 12:34         ` Kim F. Storm
  0 siblings, 2 replies; 7+ 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] 7+ messages in thread

* Re: balance-windows again
  2005-09-27 22:57       ` Kim F. Storm
@ 2005-09-29  2:42         ` Richard M. Stallman
  2005-09-29 12:34         ` Kim F. Storm
  1 sibling, 0 replies; 7+ messages in thread
From: Richard M. Stallman @ 2005-09-29  2:42 UTC (permalink / raw)
  Cc: lennart.borgman.073, emacs-devel

It occurs to me that the nicest way to do this
would be to turn the window-configuration data structure
into a transparent structure from which this info can
be extracted.

I think the data structure as you've designed it
won't do that job, but you could probably adapt
it easily enough to do that job.  Would you like to try that?

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

* Re: balance-windows again
  2005-09-27 22:57       ` Kim F. Storm
  2005-09-29  2:42         ` Richard M. Stallman
@ 2005-09-29 12:34         ` Kim F. Storm
  2005-09-30 12:03           ` Lennart Borgman
  1 sibling, 1 reply; 7+ 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] 7+ 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; 7+ 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] 7+ messages in thread

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

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <4328B58E.6010103@student.lu.se>
2005-09-16  7:01 ` balance-windows again 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  2:42         ` Richard M. Stallman
2005-09-29 12:34         ` Kim F. Storm
2005-09-30 12:03           ` Lennart Borgman

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