unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* window groups
@ 2008-05-28 12:22 martin rudalics
  2008-05-29  1:39 ` Richard M Stallman
                   ` (2 more replies)
  0 siblings, 3 replies; 46+ messages in thread
From: martin rudalics @ 2008-05-28 12:22 UTC (permalink / raw)
  To: emacs-devel

Here is my proposal:

(1) A window group is a collection of windows displayed within the root
     window of a frame.  For any window group there exists one designated
     window - the root window of that group.  A group root window is
     either the frame's root window or is a window whose parent window
     does not belong to any group (hence groups don't nest).  Every other
     window of a group is a subwindow of the group root window.  Internal
     windows of a group have at least two children (so a group contains
     at least two leaf windows).

(2) Window groups can be created by `split-window' which gets three
     additional parameters:

     Optional argument SAFE non-nil means ignore actual settings for
     `window-min-height' and `window-min-weight' but use safe defaults
     for minimum sizes instead.

     Optional argument INVERT non-nil means create the new window above
     or left of WINDOW, leave SIZE lines or columns in the original
     window, and return the newly created window.  The lower or rightmost
     window is the original window and remains selected if it was
     selected before.

     Optional argument GROUP non-nil means if the original window does
     not belong to a window group yet, create a new window group with the
     original and the new window as its only members.  If GROUP is
     non-nil and the original window already belongs to a group, the new
     window is obtained by splitting the original window and becomes a
     member of the original window's group.

     If GROUP is nil and the original window belongs to a group, the new
     window is obtained by splitting the root window of that group.  In
     this case the new window does not become a member of the original
     window's group.  The original window remains selected if it was
     selected before.  When INVERT is nil the new window is created below
     or to the right of the root window.  INVERT non-nil means the new
     window is created above or to the left of the root window.

     If GROUP is nil and the original window does not belong to a group,
     split the original window as usual.

     As a special case, GROUP `root' means assume the root window of the
     current frame forms a window group and proceed as with GROUP set to
     nil.  Thus with HORIZONTAL and INVERT non-nil and GROUP `root' the
     new window is created above all other windows of WINDOW's frame, the
     group status of the new window is set to nil, and the group status
     of all other windows remains unchanged.

(3) A group automatically ceases to exist when the number of its leaf
     windows becomes less than two.  The function `dissolve-window-group'
     dissolves the group an arbitrary window belongs to.

(4) All windows of a group share the same group number.  Windows
     belonging to different groups have different group numbers (unless
     you create more groups than an integer can hold).  For any window
     the function `window-group' returns the number of the group the
     window belongs to or nil if the window does not belong to any group.

(5) The function `clone-window-configuration' puts a window group or the
     root window of a frame into an arbitrary target frame's root window,
     window group, or window.  `clone-window-configuration' takes three
     arguments - CONFIGURATION, OLD and NEW.  CONFIGURATION must be a
     value previously returned by `current-window-configuration'.
     Optional argument OLD nil or omitted means clone the root window of
     that configuration.  If OLD is a window group (a value previously
     returned by `window-group') only windows belonging to that group are
     cloned.  An error is signalled if that group is empty.  Optional
     argument NEW nil or omitted means display the clone in the selected
     frame's root window.  NEW non-nil means display the clone in the
     selected window, or, if that window is part of a window group, in
     the root window of that group.

     Note that cloning does not reuse any windows or groups.  Rather, all
     windows and groups are created anew.

(6) The function `frame-root-window-tree' returns a list structure
     representing the layout of the root window of a frame including the
     group status of all subwindows and the buffer names of leaf windows.
     The function `clone-frame-root-window-tree' restores that layout
     from such a list structure in the root window of an arbitrary frame.

Conceptually, (2) should be sufficient to satisfy the requirements of
most IDE layouts like those of ECB or Eclipse "perspectives".

- IDEs would typically specify one window group ("edit-area" in ECB,
   "editor" in Eclipse) for each frame.  Splitting any window of that
   group would be done by setting the GROUP argument for `split-window'
   to t.  Other applications would not interfere with the layout of that
   group since, by default, their GROUP argument would not be t.

- IDE windows around that group (Eclipse "views") would be created as
   follows: For the first such window either (i) call `split-window' with
   GROUP set to `root' to obtain a full-height|width view, or (ii) call
   `split-window' with GROUP set to nil to obtain a window just as
   high|wide as the window group.  Further windows would be created by
   splitting an existing window with GROUP set to nil (or t for the more
   complex layout-outlines of ECB ).

   Approach (i) appears best for displaying views on the left or right of
   the edit area (file or tag views like the speedbar).  Approach (ii)
   might be given preference for displaying windows above or below the
   edit area (compile, shell, or grep views).

`current-window-configuration', `set-window-configuration', and
`save-window-excursion' retain their traditional semantics modulo saving
and restoring any window groups present in the configuration.

Cloning window configuration (5) is useful to restore a layout earlier
used in the same Emacs session or to switch between a layout where only
the edit area is seen and a layout displaying all sorts of views around
it.

Cloning the root window of a frame (6) is needed only to store a layout
in a desktop (or IDE specific) file to restore that root window in
another Emacs session.  Ideally, an IDE would come with preconfigured
layouts created via `frame-root-window-tree'.





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

* Re: window groups
  2008-05-28 12:22 window groups martin rudalics
@ 2008-05-29  1:39 ` Richard M Stallman
  2008-05-29  9:26   ` martin rudalics
  2008-05-29 15:18 ` Chong Yidong
  2008-05-29 16:10 ` Chong Yidong
  2 siblings, 1 reply; 46+ messages in thread
From: Richard M Stallman @ 2008-05-29  1:39 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

Could you describe the purpose of the window groups feature
in a few lines of English?  If the feature does not have
a simple conceptual description, it is not a good feature.

Using a number to designate each group is un-Lispy.

It seems unclean that the group disappears if you happen
to reduce it to just one window.

    - IDEs would typically specify one window group ("edit-area" in ECB,
       "editor" in Eclipse) for each frame.  Splitting any window of that
       group would be done by setting the GROUP argument for `split-window'
       to t.  Other applications would not interfere with the layout of that
       group since, by default, their GROUP argument would not be t.

I cannot follow why this does the right thing for them.
Can you explain?




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

* Re: window groups
  2008-05-29  1:39 ` Richard M Stallman
@ 2008-05-29  9:26   ` martin rudalics
  2008-05-29 16:30     ` Stefan Monnier
                       ` (2 more replies)
  0 siblings, 3 replies; 46+ messages in thread
From: martin rudalics @ 2008-05-29  9:26 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel

 > Could you describe the purpose of the window groups feature
 > in a few lines of English?  If the feature does not have
 > a simple conceptual description, it is not a good feature.

Window groups provide an abstraction of Emacs' internal windows.  By
design, internal windows (with the exception of `frame-root-window') are
not accessible to Elisp functions and cannot be manipulated directly by
them.  Window groups enable Elisp functions to access and operate on
internal windows in a clean and safe way.

As a consequence, Elisp based window managers can specify and manipulate
the layout of an Emacs frame by operating on collections of windows on
that frame rather than on single windows.  Typical needs of such window
managers are:

- Subdivide an Emacs frame into multiple areas (typically an "edit area"
   and one or multiple "view areas") thus specifying the basic layout of
   a frame.

- Assert that layouts change in a conceivable way.  For example, buffers
   visiting files should be always displayed in the edit area, the
   "compile window" should always appear below the edit area, other
   applications should not be allowed to change the layout of the edit
   area or the view areas.

- Make it possible to save layouts and restore them later.  For example,
   restore a layout in the same or a different frame, or in an arbitrary
   window of a frame.  It should be also possible to save layouts to a
   file and restore them from there in this or another Emacs session.

 > Using a number to designate each group is un-Lispy.

The only use of group numbers currently is to provide the second
argument for the function `clone-window-configuration' since I wanted to
avoid that applications must keep a reference to deleted windows.  In
all other cases applications are supposed to reference a window group by
specifying a visible window belonging to that group.

Technically, group numbers get assigned like window numbers.  It would
be possible, albeit inefficient, to avoid using numbers: Some group
identifier must get stored together with each window-configuration.
When creating a new group, we would always have to scan all stored
window configurations to find out whether a group with that id already
exists.  Otherwise, a `set-window-configuration' could violate the
invariant that group ids must be unique.

 > It seems unclean that the group disappears if you happen
 > to reduce it to just one window.

Currently, an invariant requires that group root windows are internal
Emacs windows.  Hence `delete-window' automatically dissolves a group as
soon as it has one visible member.  I suppose it wouldn't be difficult
to relax that invariant.

 >     - IDEs would typically specify one window group ("edit-area" in ECB,
 >        "editor" in Eclipse) for each frame.  Splitting any window of that
 >        group would be done by setting the GROUP argument for `split-window'
 >        to t.  Other applications would not interfere with the layout of that
 >        group since, by default, their GROUP argument would not be t.
 >
 > I cannot follow why this does the right thing for them.
 > Can you explain?

One of the problems of integrating ECB into Emacs is to avoid that
"other" Emacs operations interfere with those of ECB (where other
operations include popping up a *help*, *info*, or *backtrace* window).
By default `display-buffer' does not invoke `split-window' with GROUP
set to t - hence these windows always appear outside the rectangular
ares reserved for group windows.  The same holds for any application
that is not aware of the group the selected window belongs to.

On the other hand, applications based on window groups must be group
aware.  This means they can always invoke `split-window' with GROUP set
to t to add the new window to the group the original window belongs to.

Interactively, `split-window-horizontally' and `split-window-vertically'
would call `split-window' with GROUP set to t iff WINDOW is part of a
group.  Similarly, `delete-window' would always select a window of the
same group as the deleted one, `delete-other-windows' would delete all
other windows of that group, `other-window' move to another window of
that group, ...





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

* Re: window groups
  2008-05-28 12:22 window groups martin rudalics
  2008-05-29  1:39 ` Richard M Stallman
@ 2008-05-29 15:18 ` Chong Yidong
  2008-05-30  7:06   ` martin rudalics
  2008-05-29 16:10 ` Chong Yidong
  2 siblings, 1 reply; 46+ messages in thread
From: Chong Yidong @ 2008-05-29 15:18 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

martin rudalics <rudalics@gmx.at> writes:

> (1) A window group is a collection of windows displayed within the root
>     window of a frame.  For any window group there exists one designated
>     window - the root window of that group.  A group root window is
>     either the frame's root window or is a window whose parent window
>     does not belong to any group (hence groups don't nest).  Every other
>     window of a group is a subwindow of the group root window.  Internal
>     windows of a group have at least two children (so a group contains
>     at least two leaf windows).
>
> (2) Window groups can be created by `split-window' which gets three
>     additional parameters:
>
>     Optional argument SAFE non-nil means ignore actual settings for
>     `window-min-height' and `window-min-weight' but use safe defaults
>     for minimum sizes instead.
>
>     Optional argument INVERT non-nil means create the new window above
>     or left of WINDOW, leave SIZE lines or columns in the original
>     window, and return the newly created window.  The lower or rightmost
>     window is the original window and remains selected if it was
>     selected before.

What do these arguments have to do with the window group feature?

> (3) A group automatically ceases to exist when the number of its leaf
>     windows becomes less than two.  The function `dissolve-window-group'
>     dissolves the group an arbitrary window belongs to.

Why this restriction?  It seem unnecessary.





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

* Re: window groups
  2008-05-28 12:22 window groups martin rudalics
  2008-05-29  1:39 ` Richard M Stallman
  2008-05-29 15:18 ` Chong Yidong
@ 2008-05-29 16:10 ` Chong Yidong
  2008-05-29 19:11   ` Miles Bader
  2008-05-30  7:07   ` martin rudalics
  2 siblings, 2 replies; 46+ messages in thread
From: Chong Yidong @ 2008-05-29 16:10 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

martin rudalics <rudalics@gmx.at> writes:

> Conceptually, (2) should be sufficient to satisfy the requirements of
> most IDE layouts like those of ECB or Eclipse "perspectives".
>
> - IDEs would typically specify one window group ("edit-area" in ECB,
>   "editor" in Eclipse) for each frame.  Splitting any window of that
>   group would be done by setting the GROUP argument for `split-window'
>   to t.  Other applications would not interfere with the layout of that
>   group since, by default, their GROUP argument would not be t.
>
> - IDE windows around that group (Eclipse "views") would be created as
>   follows: For the first such window either (i) call `split-window' with
>   GROUP set to `root' to obtain a full-height|width view, or (ii) call
>   `split-window' with GROUP set to nil to obtain a window just as
>   high|wide as the window group.  Further windows would be created by
>   splitting an existing window with GROUP set to nil (or t for the more
>   complex layout-outlines of ECB ).
>
>   Approach (i) appears best for displaying views on the left or right of
>   the edit area (file or tag views like the speedbar).  Approach (ii)
>   might be given preference for displaying windows above or below the
>   edit area (compile, shell, or grep views).

It seems to me that, in practice, any Elisp application that needs to
control the window configuration will probably want to control over the
entire frame.  Otherwise, the resulting windows will likely be too
small.  WDYT?  If so, maybe all that needs to be done, infrastructure
wise, is a few functions for, e.g., creating window configurations from
scratch, rather than window groups.

I also think that the main problem here is the *user interface* to allow
the user to choose one of several window configurations, akin to the
"perspectives browser".  Have you thought about how that might be
implemented?




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

* Re: window groups
  2008-05-29  9:26   ` martin rudalics
@ 2008-05-29 16:30     ` Stefan Monnier
  2008-05-30  7:05       ` martin rudalics
  2008-05-30  0:59     ` Richard M Stallman
  2008-05-30  0:59     ` Richard M Stallman
  2 siblings, 1 reply; 46+ messages in thread
From: Stefan Monnier @ 2008-05-29 16:30 UTC (permalink / raw)
  To: martin rudalics; +Cc: rms, emacs-devel

>> Could you describe the purpose of the window groups feature
>> in a few lines of English?  If the feature does not have
>> a simple conceptual description, it is not a good feature.

> Window groups provide an abstraction of Emacs' internal windows.  By
> design, internal windows (with the exception of `frame-root-window') are
> not accessible to Elisp functions and cannot be manipulated directly by
> them.  Window groups enable Elisp functions to access and operate on
> internal windows in a clean and safe way.

Could you contrast your proposal with Joakim's `group' window parameter?
An obvious difference is that his proposal allows groups that do not
form a rectangle (e.g. ECB could use a group for all the windows around
the editing area).


        Stefan




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

* Re: window groups
  2008-05-29 16:10 ` Chong Yidong
@ 2008-05-29 19:11   ` Miles Bader
  2008-05-29 21:40     ` Chong Yidong
  2008-05-30  7:07     ` martin rudalics
  2008-05-30  7:07   ` martin rudalics
  1 sibling, 2 replies; 46+ messages in thread
From: Miles Bader @ 2008-05-29 19:11 UTC (permalink / raw)
  To: Chong Yidong; +Cc: martin rudalics, emacs-devel

Chong Yidong <cyd@stupidchicken.com> writes:
> It seems to me that, in practice, any Elisp application that needs to
> control the window configuration will probably want to control over the
> entire frame.  Otherwise, the resulting windows will likely be too
> small.  WDYT?

Do you have any support for such an assumption?  It seems wrong to me,
simply based on personal experience.

> If so, maybe all that needs to be done, infrastructure wise, is a few
> functions for, e.g., creating window configurations from scratch,
> rather than window groups.

I don't think that's going to work in Emacs (or at least, work well),
because Emacs is not well-behaved like other apps.  Users _will_ do
stuff to mess up your nice arrangement.  Lots of packages go to some
trouble to create nicely layed out windows, but this tends to decay with
time unless you stick strictly to operations that know about it -- and
people don't do that (and shouldn't have to).

I think what's really needed is not just a way to create window
configurations (in fact, that's relatively easy I guess), but a way to
direct the flow of window creation/deletion to _maintain_ desired window
layout constraints.

-Miles

-- 
(\(\
(^.^)
(")")
*This is the cute bunny virus, please copy this into your sig so it can spread.




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

* Re: window groups
  2008-05-29 19:11   ` Miles Bader
@ 2008-05-29 21:40     ` Chong Yidong
  2008-05-29 22:33       ` Miles Bader
  2008-05-30  7:07     ` martin rudalics
  1 sibling, 1 reply; 46+ messages in thread
From: Chong Yidong @ 2008-05-29 21:40 UTC (permalink / raw)
  To: Miles Bader; +Cc: martin rudalics, emacs-devel

Miles Bader <miles@gnu.org> writes:

> Chong Yidong <cyd@stupidchicken.com> writes:
>> It seems to me that, in practice, any Elisp application that needs to
>> control the window configuration will probably want to control over the
>> entire frame.  Otherwise, the resulting windows will likely be too
>> small.  WDYT?
>
> Do you have any support for such an assumption?  It seems wrong to me,
> simply based on personal experience.

I'm not sure.  But look at the typical Emacs frame where you're running
Gnus, with the frame is divided into a summary window and an article
window.  Is there any space left for, e.g., a GDB session?  On my
machine, if the GDB session were to split the Gnus article window and
squeeze its windows in there, I wouldn't be able to see much in those
windows.




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

* Re: window groups
  2008-05-29 21:40     ` Chong Yidong
@ 2008-05-29 22:33       ` Miles Bader
  2008-05-29 23:53         ` Thomas Lord
  2008-05-30  7:07         ` martin rudalics
  0 siblings, 2 replies; 46+ messages in thread
From: Miles Bader @ 2008-05-29 22:33 UTC (permalink / raw)
  To: Chong Yidong; +Cc: martin rudalics, emacs-devel

Chong Yidong <cyd@stupidchicken.com> writes:
>>> It seems to me that, in practice, any Elisp application that needs to
>>> control the window configuration will probably want to control over the
>>> entire frame.  Otherwise, the resulting windows will likely be too
>>> small.  WDYT?
>>
>> Do you have any support for such an assumption?  It seems wrong to me,
>> simply based on personal experience.
>
> I'm not sure.  But look at the typical Emacs frame where you're running
> Gnus, with the frame is divided into a summary window and an article
> window.  Is there any space left for, e.g., a GDB session?  On my
> machine, if the GDB session were to split the Gnus article window and
> squeeze its windows in there, I wouldn't be able to see much in those
> windows.

I think the main issue is not multiple giant apps running in the same
frame[*], but rather:

 (1) Little special purpose windows that you want in particular places,
     and want to protect from being stomped on by other activities
     (whether normal editing or a special-purpose app such as Gnus).

     The most common example would be an in-frame speedbar, which is
     something people (including me) want, but which is not offered by
     the version of speedbar in Emacs because it just doesn't work well
     with Emacs' primitive management of in-frame windows.

     Another example might be something like an Emacs audio player,
     which you might want to always occupy a 1-line window at the
     bottom of your frame.

 (2) When one _is_ inside an Emacs app that tries to maintain a certain
     window arrangement, the handling of window management outside the
     domain of that app.

     For instance, you're in Gnus or whatever, and ask for help, where
     should the window showing the help buffer go?


[*]  Though I don't think this case should be ignored -- there _are_
     people who run Emacs in large windows and prefer to use Emacs
     windows for management rather than frames.


[I don't know offhand whether Martin's proposal is the best way to deal
with these issues (I found the writeup a bit hard to digest), but when
I've thought about this sort of thing before, my thoughts tended towards
making the existing Emacs window tree more visible to lisp code, and
adding some mechanism for specifying where in the tree various
operations would be directed by default.]

-Miles

-- 
Learning, n. The kind of ignorance distinguishing the studious.




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

* Re: window groups
  2008-05-29 22:33       ` Miles Bader
@ 2008-05-29 23:53         ` Thomas Lord
  2008-05-30  7:07           ` martin rudalics
  2008-05-30  7:07         ` martin rudalics
  1 sibling, 1 reply; 46+ messages in thread
From: Thomas Lord @ 2008-05-29 23:53 UTC (permalink / raw)
  To: Miles Bader; +Cc: martin rudalics, Chong Yidong, emacs-devel

Miles Bader wrote:
>  when
> I've thought about this sort of thing before, my thoughts tended towards
> making the existing Emacs window tree more visible to lisp code, and
> adding some mechanism for specifying where in the tree various
> operations would be directed by default.]
>   

The very tree-centric primitives for window management and the
limited nature of window configurations has been a long-standing
source of frustration, I agree.    Lots of more flexible approaches to
geometry management have come along in the last 20 years.   Emacs
adds to the geometry management problem the constant (but rewarding)
challenge of not breaking terminal support, yet this area still seems
just stuck in the distant past (not because of terminal support -- just
because it could be much nicer).

However, for some simple ideas not requiring radical revision:

The first one should be very easy.   The second one is a little harder:

Temporary windows (e.g., completion, help) would be less of a problem
if there was support for splitting a frame at the *top* of the window
tree.   Ditto for toolbars.    I admit I don't run the current almost
released emacs but, as far as I know, there is no clean way to split
a frame that way.    For example, split a frame vertically.   Split each
half horizontally.   Then invoke a complex command that will pop up
a completion helper.     Ideally the completion helper would split the
entire frame, adding a new temporary window just above the minibuffer.
Instead, one of your four windows is taken over.   In the case of a 
persistent
pop-up (like a help window), it would be nice to take some care so that if
the window config doesn't change other than by that window being deleted,
the former windows return precisely to their former sizes and locations.
Similarly, frame-wide toolbars could be popped up as frame-level window
splits -- this would make the minibuffer less special.   (It might even be
worth exploring the practicality of making complex command invocation
a *non*-recursive operation -- it might be significantly easier than adding
cooperative threads and even if threads come along it could still be a
beneficial thing to do.)

Window-local variables would also be handy.   "Apps" can search
window bindings to find which window to take over for a particular
buffer being popped up.   And, as I earlier argued, window-local variables
could help make the point, mark, and selection cleaner -- so now I've
got two arguments in favor of the long-contemplated window-local vars.

-t






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

* Re: window groups
  2008-05-29  9:26   ` martin rudalics
  2008-05-29 16:30     ` Stefan Monnier
@ 2008-05-30  0:59     ` Richard M Stallman
  2008-05-30  7:08       ` martin rudalics
  2008-05-30  0:59     ` Richard M Stallman
  2 siblings, 1 reply; 46+ messages in thread
From: Richard M Stallman @ 2008-05-30  0:59 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

    - Assert that layouts change in a conceivable way.

I am not sure what distinction is meant by "a conceivable way".
Did you mean some other word instead of "conceivable"?

    Technically, group numbers get assigned like window numbers.  It would
    be possible, albeit inefficient, to avoid using numbers: Some group
    identifier must get stored together with each window-configuration.

Can you create an object (even a cons cell) to represent the window
group?  It just has to be unique, different from the cons cell used
for any other window group.

     > It seems unclean that the group disappears if you happen
     > to reduce it to just one window.

    Currently, an invariant requires that group root windows are internal
    Emacs windows.  Hence `delete-window' automatically dissolves a group as
    soon as it has one visible member.  I suppose it wouldn't be difficult
    to relax that invariant.

I think that change is essential for practical use, and also needed
for simplicity.




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

* Re: window groups
  2008-05-29  9:26   ` martin rudalics
  2008-05-29 16:30     ` Stefan Monnier
  2008-05-30  0:59     ` Richard M Stallman
@ 2008-05-30  0:59     ` Richard M Stallman
  2008-05-30  7:08       ` martin rudalics
  2 siblings, 1 reply; 46+ messages in thread
From: Richard M Stallman @ 2008-05-30  0:59 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

    One of the problems of integrating ECB into Emacs is to avoid that
    "other" Emacs operations interfere with those of ECB (where other
    operations include popping up a *help*, *info*, or *backtrace* window).

This is an attempt to design a feature to distinguish between the
"editing area" and other add-ons, it seems.  Is that right?

But it also attempts to generalize this by allowing for more than one
group.  Do you see a scenario in which having more than one window
group in one frame would be used?  Without such a scenario, we have no
basis to think about what operations ought to do in such a case, and thus
no basis for the generalization.

Based on what you've said, it seems that there are three kinds of
buffers that might appear in something like ECB.  (I am partly guessing,
since I have not seen ECB itself.)

* File buffers

* Special buffers of ECB

* Other buffers such as *Help*, *Info*, and so on.

I think the right way to design this feature is to figure out the
right thing to do with windows for these three kinds of buffers,
and then design an interface to request that.

But we should not try to make it any more general than that
until we have use cases to guide our thinking about them.

    By default `display-buffer' does not invoke `split-window' with GROUP
    set to t - hence these windows always appear outside the rectangular
    ares reserved for group windows.  The same holds for any application
    that is not aware of the group the selected window belongs to.

    ...

    Interactively, `split-window-horizontally' and `split-window-vertically'
    would call `split-window' with GROUP set to t iff WINDOW is part of a
    group.

What about C-x 4 C-f?  If you do that inside ECB, should the new window
be part of the ECB group?




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

* Re: window groups
  2008-05-29 16:30     ` Stefan Monnier
@ 2008-05-30  7:05       ` martin rudalics
  2008-05-30 13:58         ` Stefan Monnier
  0 siblings, 1 reply; 46+ messages in thread
From: martin rudalics @ 2008-05-30  7:05 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: rms, emacs-devel

 > Could you contrast your proposal with Joakim's `group' window parameter?

AFAIK Joakim leaves the responsibility to set the group parameter to the
application (ECB).  I make Emacs responsible for keeping track of
groups.  To me this means two things:

(1) Groups should conform to internal windows.  Klaus Berndl told me that
     this is the case for ECB's edit area.

(2) `split-window' should be the single interface for creating groups.

 > An obvious difference is that his proposal allows groups that do not
 > form a rectangle (e.g. ECB could use a group for all the windows around
 > the editing area).

Even for rectangles the case is not entirely clear.  In the following
four windows frame

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

we know well that the internal windows differ according to how the first
split was executed.  If the first `split-window' did not have GROUP set
to t and the subsequent ones did there are either two vertically aligned
groups or two horizontally aligned one.

The situation becomes much more complicated when groups may comprise
arbitrary windows of a frame - just think of cloning such a group.  More
problems will arise as soon as two different applications will attempt
to manage their private groups simultaneously in the same Emacs session.






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

* Re: window groups
  2008-05-29 15:18 ` Chong Yidong
@ 2008-05-30  7:06   ` martin rudalics
  0 siblings, 0 replies; 46+ messages in thread
From: martin rudalics @ 2008-05-30  7:06 UTC (permalink / raw)
  To: Chong Yidong; +Cc: emacs-devel

 >>    Optional argument SAFE non-nil means ignore actual settings for
 >>    `window-min-height' and `window-min-weight' but use safe defaults
 >>    for minimum sizes instead.
 >>
 >>    Optional argument INVERT non-nil means create the new window above
 >>    or left of WINDOW, leave SIZE lines or columns in the original
 >>    window, and return the newly created window.  The lower or rightmost
 >>    window is the original window and remains selected if it was
 >>    selected before.
 >
 >
 > What do these arguments have to do with the window group feature?

SAFE is set by the `clone-frame-root-window-tree' to avoid that windows
present in the original configration get deleted during cloning because
they are too small.  Traditionally, this is achieved by binding
window-min-height|width to 1 but I don't like that (mainly because I
want to hanlde buffer-local values for window-min-height|width).

INVERT is for example needed to create a view window on the left side of
an editor area built from vertically split windows.

 >>(3) A group automatically ceases to exist when the number of its leaf
 >>    windows becomes less than two.  The function `dissolve-window-group'
 >>    dissolves the group an arbitrary window belongs to.
 >
 > Why this restriction?  It seem unnecessary.

It's because window groups are currently rooted at internal windows.
Richard already convinced me that it shall be removed.  But I have to
revise my invariants first before changing my code.






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

* Re: window groups
  2008-05-29 16:10 ` Chong Yidong
  2008-05-29 19:11   ` Miles Bader
@ 2008-05-30  7:07   ` martin rudalics
  1 sibling, 0 replies; 46+ messages in thread
From: martin rudalics @ 2008-05-30  7:07 UTC (permalink / raw)
  To: Chong Yidong; +Cc: emacs-devel

 > It seems to me that, in practice, any Elisp application that needs to
 > control the window configuration will probably want to control over the
 > entire frame.  Otherwise, the resulting windows will likely be too
 > small.  WDYT?

One operation of ECB is to make the editor area comprise the entire
frame and revert that operation to make view windows visible again.
This can be done on-the-fly with `clone-window-configuration'.

 > If so, maybe all that needs to be done, infrastructure
 > wise, is a few functions for, e.g., creating window configurations from
 > scratch, rather than window groups.

The major problem with window configurations "created from scratch" is
that you have to devise that configuration first, memorize it, and
eventually recall it.  Personally, I prefer an approach where I can
change the layout of windows in an ad hoc manner without having to
resort to predefined configurations frequently.

 > I also think that the main problem here is the *user interface* to allow
 > the user to choose one of several window configurations, akin to the
 > "perspectives browser".  Have you thought about how that might be
 > implemented?

I thought about using the layout engine provided by ECB.





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

* Re: window groups
  2008-05-29 19:11   ` Miles Bader
  2008-05-29 21:40     ` Chong Yidong
@ 2008-05-30  7:07     ` martin rudalics
  1 sibling, 0 replies; 46+ messages in thread
From: martin rudalics @ 2008-05-30  7:07 UTC (permalink / raw)
  To: Miles Bader; +Cc: Chong Yidong, emacs-devel

 > I think what's really needed is not just a way to create window
 > configurations (in fact, that's relatively easy I guess), but a way to
 > direct the flow of window creation/deletion to _maintain_ desired window
 > layout constraints.

That was my intention when I wrote the window groups code.  With the
additional twist that occasionally (when the layout has deteriorated
severely or during startup) predefined configurations can be useful.





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

* Re: window groups
  2008-05-29 22:33       ` Miles Bader
  2008-05-29 23:53         ` Thomas Lord
@ 2008-05-30  7:07         ` martin rudalics
  1 sibling, 0 replies; 46+ messages in thread
From: martin rudalics @ 2008-05-30  7:07 UTC (permalink / raw)
  To: Miles Bader; +Cc: Chong Yidong, emacs-devel

 >      The most common example would be an in-frame speedbar, which is
 >      something people (including me) want, but which is not offered by
 >      the version of speedbar in Emacs because it just doesn't work well
 >      with Emacs' primitive management of in-frame windows.

I wrote my own sidebar to show various things like files, buffers, tags,
bookmarks or search results.  For example, I browse tags by moving
up-/downwards in the tag-sidebar and, after a short timeout, have the
window on the right move point to the location referenced by the tag.
This movement is synchronized in a way that the line showing the tag and
the line showing the defun always occupy the same screen line.

All this worked well but was continuously screwed up by `display-buffer'
splitting the right window and breaking my line-to-line correspondence.
Now I have sidebar and main window form a window group and the problem
is gone.





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

* Re: window groups
  2008-05-29 23:53         ` Thomas Lord
@ 2008-05-30  7:07           ` martin rudalics
  2008-05-30 16:42             ` Thomas Lord
  0 siblings, 1 reply; 46+ messages in thread
From: martin rudalics @ 2008-05-30  7:07 UTC (permalink / raw)
  To: Thomas Lord; +Cc: Chong Yidong, emacs-devel, Miles Bader

 > Temporary windows (e.g., completion, help) would be less of a problem
 > if there was support for splitting a frame at the *top* of the window
 > tree.  Ditto for toolbars.

Could you explain what you mean here?  The toolbar is not part of a
frame's root window.

 > I admit I don't run the current almost
 > released emacs but, as far as I know, there is no clean way to split
 > a frame that way.    For example, split a frame vertically.   Split each
 > half horizontally.   Then invoke a complex command that will pop up
 > a completion helper.     Ideally the completion helper would split the
 > entire frame, adding a new temporary window just above the minibuffer.
 > Instead, one of your four windows is taken over.   In the case of a
 > persistent
 > pop-up (like a help window), it would be nice to take some care so that if
 > the window config doesn't change other than by that window being deleted,
 > the former windows return precisely to their former sizes and locations.
 > Similarly, frame-wide toolbars could be popped up as frame-level window
 > splits -- this would make the minibuffer less special.

Returning "precisely" to former sizes is non-trivial.

 > (It might even be
 > worth exploring the practicality of making complex command invocation
 > a *non*-recursive operation -- it might be significantly easier than adding
 > cooperative threads and even if threads come along it could still be a
 > beneficial thing to do.)

Do you mean to pop-up a new window for each command invocation?

 > Window-local variables would also be handy.   "Apps" can search
 > window bindings to find which window to take over for a particular
 > buffer being popped up.   And, as I earlier argued, window-local variables
 > could help make the point, mark, and selection cleaner -- so now I've
 > got two arguments in favor of the long-contemplated window-local vars.

I always wanted them.  However, as Stefan points out in another thread,
this seems to be difficult.





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

* Re: window groups
  2008-05-30  0:59     ` Richard M Stallman
@ 2008-05-30  7:08       ` martin rudalics
  2008-05-31  2:07         ` Richard M Stallman
  0 siblings, 1 reply; 46+ messages in thread
From: martin rudalics @ 2008-05-30  7:08 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel

 >     - Assert that layouts change in a conceivable way.
 >
 > I am not sure what distinction is meant by "a conceivable way".
 > Did you mean some other word instead of "conceivable"?

I meant "predictable".

 >     Technically, group numbers get assigned like window numbers.  It would
 >     be possible, albeit inefficient, to avoid using numbers: Some group
 >     identifier must get stored together with each window-configuration.
 >
 > Can you create an object (even a cons cell) to represent the window
 > group?  It just has to be unique, different from the cons cell used
 > for any other window group.

I can - but what should the cons cell store?  I want to compare group
identifiers quickly in C code and I want to store them as list structure
on file.

 >      > It seems unclean that the group disappears if you happen
 >      > to reduce it to just one window.
 >
 >     Currently, an invariant requires that group root windows are internal
 >     Emacs windows.  Hence `delete-window' automatically dissolves a group as
 >     soon as it has one visible member.  I suppose it wouldn't be difficult
 >     to relax that invariant.
 >
 > I think that change is essential for practical use, and also needed
 > for simplicity.

OK





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

* Re: window groups
  2008-05-30  0:59     ` Richard M Stallman
@ 2008-05-30  7:08       ` martin rudalics
  0 siblings, 0 replies; 46+ messages in thread
From: martin rudalics @ 2008-05-30  7:08 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel

 >     One of the problems of integrating ECB into Emacs is to avoid that
 >     "other" Emacs operations interfere with those of ECB (where other
 >     operations include popping up a *help*, *info*, or *backtrace* window).
 >
 > This is an attempt to design a feature to distinguish between the
 > "editing area" and other add-ons, it seems.  Is that right?

It's merely keeping apart IDE specific objects like the editing area or
the IDE's own help system from Emacs specific *help* or *info* buffers.

 > But it also attempts to generalize this by allowing for more than one
 > group.  Do you see a scenario in which having more than one window
 > group in one frame would be used?

All IDEs I know of use just one edit area.  Stefan mentioned that view
areas could be considered a group as well and there are some ECB layouts
where views are split both horizontally _and_ vertically.  In that case
using groups within the view area might be useful.

 > Without such a scenario, we have no
 > basis to think about what operations ought to do in such a case, and thus
 > no basis for the generalization.

One scenario is that of multiple speedbar/window combinations appearing
simultaneously on a frame.  Every such combination would form a separate
window group.

 > Based on what you've said, it seems that there are three kinds of
 > buffers that might appear in something like ECB.  (I am partly guessing,
 > since I have not seen ECB itself.)

I'm guessing as well.

 > * File buffers
 >
 > * Special buffers of ECB
 >
 > * Other buffers such as *Help*, *Info*, and so on.
 >
 > I think the right way to design this feature is to figure out the
 > right thing to do with windows for these three kinds of buffers,
 > and then design an interface to request that.

Yes.

 > But we should not try to make it any more general than that
 > until we have use cases to guide our thinking about them.
 >
 >     By default `display-buffer' does not invoke `split-window' with GROUP
 >     set to t - hence these windows always appear outside the rectangular
 >     ares reserved for group windows.  The same holds for any application
 >     that is not aware of the group the selected window belongs to.
 >
 >     ...
 >
 >     Interactively, `split-window-horizontally' and `split-window-vertically'
 >     would call `split-window' with GROUP set to t iff WINDOW is part of a
 >     group.
 >
 > What about C-x 4 C-f?  If you do that inside ECB, should the new window
 > be part of the ECB group?

I think so but it should be customizable.  The default value would have
to be decided individually for each function.





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

* Re: window groups
  2008-05-30  7:05       ` martin rudalics
@ 2008-05-30 13:58         ` Stefan Monnier
  2008-05-30 19:27           ` martin rudalics
  0 siblings, 1 reply; 46+ messages in thread
From: Stefan Monnier @ 2008-05-30 13:58 UTC (permalink / raw)
  To: martin rudalics; +Cc: rms, emacs-devel

>> Could you contrast your proposal with Joakim's `group' window parameter?
> AFAIK Joakim leaves the responsibility to set the group parameter to the
> application (ECB).

I'm not sure I understand what you mean here.  AFAICT, Joakim's proposal
requires the application to (set-window-parameter WIN 'group GID) to
create the group, but after that, I'd expect this parameter to
be inherited (tho I don't know whether that's implemented or even if he
intend(s|ed) to do that).  So that'd be similar to your proposal,
wouldn't it?

> The situation becomes much more complicated when groups may comprise
> arbitrary windows of a frame - just think of cloning such a group.

That's a good point.  Joakim's approach makes it difficult (or even
impossible?) to take a group and turn it into a window-configuration, or
to take a window-configuration and apply it to a group.

BTW: why is it that we do not expose internal windows to Elisp?

> More problems will arise as soon as two different applications will
> attempt to manage their private groups simultaneously in the same
> Emacs session.

Like...?


        Stefan




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

* Re: window groups
  2008-05-30 16:42             ` Thomas Lord
@ 2008-05-30 16:08               ` Stefan Monnier
  2008-05-31  9:10               ` martin rudalics
  1 sibling, 0 replies; 46+ messages in thread
From: Stefan Monnier @ 2008-05-30 16:08 UTC (permalink / raw)
  To: Thomas Lord; +Cc: martin rudalics, Chong Yidong, emacs-devel, Miles Bader

>> > Window-local variables would also be handy.   "Apps" can search
>> I always wanted them.  However, as Stefan points out in another thread,
>> this seems to be difficult.
> Is it difficult because it would be hard or have strange semantics to
> mix up lisp scoping that way?

Because of the strange semantics and nasty implementation.

> If so:  window property lists (not X11 properties - lisp property lists
> attached to windows) might be enough.

It's about to be installed (called `set-window-parameter' and
`window-parameter').


        Stefan




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

* Re: window groups
  2008-05-30  7:07           ` martin rudalics
@ 2008-05-30 16:42             ` Thomas Lord
  2008-05-30 16:08               ` Stefan Monnier
  2008-05-31  9:10               ` martin rudalics
  0 siblings, 2 replies; 46+ messages in thread
From: Thomas Lord @ 2008-05-30 16:42 UTC (permalink / raw)
  To: martin rudalics; +Cc: Chong Yidong, Miles Bader, emacs-devel

martin rudalics wrote:
> > Temporary windows (e.g., completion, help) would be less of a problem
> > if there was support for splitting a frame at the *top* of the window
> > tree.  Ditto for toolbars.
>
> Could you explain what you mean here?  The toolbar is not part of a
> frame's root window.

By "splitting at the top of the window tree":   As far as I know,
right now the only way to create a new window (in an existing
frame) is to split an existing window horizontally or vertically.
New windows are always created by dividing a leaf node of the
window tree.    The new functionality would be to support
splitting the root window of a frame.

Consider (standard keybings): C-x 2 C-x 3 C-x o C-x o C-x 3

Compared to: C-x 2 C-x 2 C-x o C-x 3 C-x o C-x o C-x 3
                or C-x 2 C-x 3 C-x o C-x o C-x 2 C-x 3
                or C-x 3 C-x o C-x 2 C-x o C-x o C-x 3
                or C-x 3 C-x 2 C-x 3 C-x o C-x o C-x 3

Given the window configuration from the first key-sequence,
I'm suggesting a function to get to basically the same configuration
as any of the other four (not necessarily with the same window
sizes, though).   Miles suggested wanting to better expose the
window tree to lisp.   This suggestion is an intermediate step:
it doesn't further expose the whole window tree - it just adds some
functions that work on the root of the tree.

That kind of splitting could be handy for many kinds of pop-ups,
such as completion windows, especially when the rest of the
window configuration is created by an app that wants to use
each of the other windows in only a specific way.

I guess I shouldn't have said "tool-bar" since that creates confusion
with tool-bars as currently implemented.   I meant that that kind
of pop-up (full-frame split) could be used for something "tool-bar
like".   Instead of tool-bar functionality being built-in as a primitive
concept of the display, it could be done as special buffers that
contain widgets.

Doing tool-bar functionality as a buffer could be convenient.  For
example, consider the "location" bar in a typical web browser (say,
firefox).  There are a few buttons.   A text field for a URL.  More
buttons.  A text field for search.  And more buttons.  That'd be natural
to do in a buffer but very ad hoc as more and more primitive functions
added to display.

Continuing the location-bar example:  Consider how browsers often
create "drop down" windows for completion as a URL field or
search field is filled in.   If a location bar is implemented as an emacs
buffer, instead of a new "drop down" the window showing the buffer
could be temporarily enlarged, showing completions in the 2nd and
further lines of the buffer.



> > pop-up (like a help window), it would be nice to take some care so 
> that if
> > the window config doesn't change other than by that window being 
> deleted,
> > the former windows return precisely to their former sizes and 
> locations.
>
> Returning "precisely" to former sizes is non-trivial.

How so?


>
> > (It might even be
> > worth exploring the practicality of making complex command invocation
> > a *non*-recursive operation -- it might be significantly easier than 
> adding
> > cooperative threads and even if threads come along it could still be a
> > beneficial thing to do.)
>
> Do you mean to pop-up a new window for each command invocation?

I mean: 

Currently, when a complex command is selected by input events
Emacs (essentially) invokes the command loop recursively from
within a "save-window-excursion".   That's deeply built-in to both
C code and lisp code, I realize.   It's very natural, in many cases.
It is awkward in other cases, though.   For example, because of the
way it relies on the C stack, if you start two complex commands at
the same time - say, in two different frames - the second one that
you start has to run before the first one can run.

My "might even be worth exploring" notion is that perhaps complex
commands don't really need a recursive edit -- don't need to use the
C stack that way.   Instead, when the command loop wants to begin
collecting arguments for a complex command it can create a minibuffer
for that invocation, display that buffer in the minibuffer window, sure.
Save the current buffer, window, point location, etc. in buffer local
variables in that minibuffer.   Make that minibuffer the current buffer -
and return.   After the return, editing continues in that minibuffer,
collecting arguments.   When all arguments are collected, the command
is invoked.

*If* - and I realize that this is a "big if" that happens to not be too hard
to make work, *then* fancier things should fall out trivially.   Firefox
again provides an example:   Firefox has a "search" feature that is
in some ways like Emacs' i-search.   A difference in the firefox approach
is that the incremental search command doesn't invoke a recursive
interaction loop - it "pops up" (in the emacs sense, not the X11 sense) a
special purpose, minibuffer-like tool with a text field in which to edit
the string searched for, buttons to move to previous and next match, etc.

It could be elegant if Emacs arrived at similar functionality "for free,"
and for all complex commands, just by changing the low-level way
in which all complex commands are invoked.

There would be numerous UI details to get right.   It could be very
nice.   It would go well with "top level frame splitting" and "tool-bar
like buffers".



>
> > Window-local variables would also be handy.   "Apps" can search
> > window bindings to find which window to take over for a particular
> > buffer being popped up.   And, as I earlier argued, window-local 
> variables
> > could help make the point, mark, and selection cleaner -- so now I've
> > got two arguments in favor of the long-contemplated window-local vars.
>
> I always wanted them.  However, as Stefan points out in another thread,
> this seems to be difficult.

Is it difficult because it would be hard or have strange semantics to
mix up lisp scoping that way?

If so:  window property lists (not X11 properties - lisp property lists
attached to windows) might be enough.

-t






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

* Re: window groups
  2008-05-30 13:58         ` Stefan Monnier
@ 2008-05-30 19:27           ` martin rudalics
  2008-05-31  4:52             ` Stefan Monnier
  0 siblings, 1 reply; 46+ messages in thread
From: martin rudalics @ 2008-05-30 19:27 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: rms, emacs-devel

 > I'm not sure I understand what you mean here.  AFAICT, Joakim's proposal
 > requires the application to (set-window-parameter WIN 'group GID) to
 > create the group, but after that, I'd expect this parameter to
 > be inherited (tho I don't know whether that's implemented or even if he
 > intend(s|ed) to do that).  So that'd be similar to your proposal,
 > wouldn't it?

Yes.

 > BTW: why is it that we do not expose internal windows to Elisp?

I know XEmacs does that.  However, over the past two weeks I was able to
crash Emacs more often than over the past two years.  Practically all
these crashes were due to malformed window-trees.  Hence I suppose
exposing internal windows to Elisp might make it possible to crash Emacs
from Elisp quite easily.

 >>More problems will arise as soon as two different applications will
 >>attempt to manage their private groups simultaneously in the same
 >>Emacs session.
 >
 > Like...?

... citing Eric Ludlam from an earlier thread:

     What if there is an ECB and a second program like Speedbar, that
     both want to do the same thing.  How do they work together?

... and ...

     I'd like to know how ECB, and Speedbar can work at the same time,
     without being aware of eachother.  Would the solution really be that
     Speedbar needs some ECB client code?





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

* Re: window groups
  2008-05-30  7:08       ` martin rudalics
@ 2008-05-31  2:07         ` Richard M Stallman
  2008-05-31  6:17           ` Daniel Colascione
  2008-05-31  9:10           ` martin rudalics
  0 siblings, 2 replies; 46+ messages in thread
From: Richard M Stallman @ 2008-05-31  2:07 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

     > Can you create an object (even a cons cell) to represent the window
     > group?  It just has to be unique, different from the cons cell used
     > for any other window group.

    I can - but what should the cons cell store?

It does not HAVE to store anything.  (The number doesn't store
anything.)  Its function is to be unique.  But there is probably
something useful that could be put in it.




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

* Re: window groups
  2008-05-30 19:27           ` martin rudalics
@ 2008-05-31  4:52             ` Stefan Monnier
  2008-05-31  9:10               ` martin rudalics
  0 siblings, 1 reply; 46+ messages in thread
From: Stefan Monnier @ 2008-05-31  4:52 UTC (permalink / raw)
  To: martin rudalics; +Cc: rms, emacs-devel

> I know XEmacs does that.  However, over the past two weeks I was able to
> crash Emacs more often than over the past two years.  Practically all
> these crashes were due to malformed window-trees.  Hence I suppose
> exposing internal windows to Elisp might make it possible to crash Emacs
> from Elisp quite easily.

I guess that would be an advantage of Joakim's approach, which works
more "on the surface".

>>> More problems will arise as soon as two different applications will
>>> attempt to manage their private groups simultaneously in the same
>>> Emacs session.
>> Like...?
> ... citing Eric Ludlam from an earlier thread:

>     What if there is an ECB and a second program like Speedbar, that
>     both want to do the same thing.  How do they work together?

> ... and ...

>     I'd like to know how ECB, and Speedbar can work at the same time,
>     without being aware of eachother.  Would the solution really be that
>     Speedbar needs some ECB client code?

I'm not sure I understand enough of those problems and of your proposal
and Joakim's to understand how one proposal would make it easier to
address those situations.


        Stefan




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

* Re: window groups
  2008-05-31  2:07         ` Richard M Stallman
@ 2008-05-31  6:17           ` Daniel Colascione
  2008-05-31  7:09             ` Miles Bader
  2008-05-31  9:10           ` martin rudalics
  1 sibling, 1 reply; 46+ messages in thread
From: Daniel Colascione @ 2008-05-31  6:17 UTC (permalink / raw)
  To: rms; +Cc: martin rudalics, emacs-devel


On May 30, 2008, at 10:07 PM, Richard M Stallman wrote:
> It does not HAVE to store anything.  (The number doesn't store
> anything.)  Its function is to be unique.

What about using gensym?




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

* Re: window groups
  2008-05-31  6:17           ` Daniel Colascione
@ 2008-05-31  7:09             ` Miles Bader
  0 siblings, 0 replies; 46+ messages in thread
From: Miles Bader @ 2008-05-31  7:09 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: martin rudalics, rms, emacs-devel

Daniel Colascione <danc@merrillpress.com> writes:
>> It does not HAVE to store anything.  (The number doesn't store
>> anything.)  Its function is to be unique.
>
> What about using gensym?

(1) it's a cl function, and
(2) afaik, symbols take _more_ space than conses...

But if it doesn't matter very much what you use, as long as they're
unique, you can just leave it unspecified, and say that it returns a
"unique cookie" or something.

-Miles
-- 
Accord, n. Harmony.




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

* Re: window groups
  2008-05-30 16:42             ` Thomas Lord
  2008-05-30 16:08               ` Stefan Monnier
@ 2008-05-31  9:10               ` martin rudalics
  2008-05-31 11:52                 ` Juanma Barranquero
  1 sibling, 1 reply; 46+ messages in thread
From: martin rudalics @ 2008-05-31  9:10 UTC (permalink / raw)
  To: Thomas Lord; +Cc: Chong Yidong, Miles Bader, emacs-devel

 > By "splitting at the top of the window tree":   As far as I know,
 > right now the only way to create a new window (in an existing
 > frame) is to split an existing window horizontally or vertically.
 > New windows are always created by dividing a leaf node of the
 > window tree.    The new functionality would be to support
 > splitting the root window of a frame.

Here

(split-window nil nil nil nil t 'root)

gets me a new window above all others regardless how complex my
window-layout is.

 >> Returning "precisely" to former sizes is non-trivial.
 >
 > How so?

Because your context might have changed in between.  For example, when
leaving a `save-window-excursion' you don't want your frame get resized.





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

* Re: window groups
  2008-05-31  2:07         ` Richard M Stallman
  2008-05-31  6:17           ` Daniel Colascione
@ 2008-05-31  9:10           ` martin rudalics
  1 sibling, 0 replies; 46+ messages in thread
From: martin rudalics @ 2008-05-31  9:10 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel

 > It does not HAVE to store anything.  (The number doesn't store
 > anything.)  Its function is to be unique.  But there is probably
 > something useful that could be put in it.

I lost you here.  Do you mean the car of that cons cell should get the
integer I generate and the cdr be left to the caller's disposition?
Group numbers are used for (1) uniquely identifying groups and (2) for
internal bookkeeping.  The user is _not_ allowed to manipulate them.
Anything else would permit a user to make one group pretend the identity
of another by simply assigning it the same id.  I suppose that an
application that wants to keep track of groups can simply define its own
alist mapping Emacs generated numbers to whatever they want.





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

* Re: window groups
  2008-05-31  4:52             ` Stefan Monnier
@ 2008-05-31  9:10               ` martin rudalics
  0 siblings, 0 replies; 46+ messages in thread
From: martin rudalics @ 2008-05-31  9:10 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: rms, emacs-devel

 >>I know XEmacs does that.  However, over the past two weeks I was able to
 >>crash Emacs more often than over the past two years.  Practically all
 >>these crashes were due to malformed window-trees.  Hence I suppose
 >>exposing internal windows to Elisp might make it possible to crash Emacs
 >>from Elisp quite easily.
 >
 > I guess that would be an advantage of Joakim's approach, which works
 > more "on the surface".

I got most of these crashes when restoring window trees from the
structures stored in save_window, in particular from the values stored
in the parent and prev fields.  This task is fairly easy when you're
allowed to change the window field of saved_window directly as in
`set-window-configuration'.  It's tricky when you use make_window to
make a copy of the window as `clone-window-configuration' does and the
window field still has to refer to the original window (dead or alive).

Anyway, if you want to clone window-configurations from the structures
created by `current-window-configuration' you probably won't be able to
stay any longer "on the surface" ;-)

 > I'm not sure I understand enough of those problems and of your proposal
 > and Joakim's to understand how one proposal would make it easier to
 > address those situations.

If a window group is identic to an internal window of an Emacs frame,
you can write down all invariants you need in a couple of lines.  As a
consequence, you can rewrite the window management code (`split-window'
and `delete-window' mainly) and devise any new routines quite easily.

If window groups are allowed to comprise arbitrary windows or you don't
check that applications maintain a one-to-one correspondency of internal
windows and groups it's IMHO much better to _not_ touch the windows
management code and leave alone the current advice mechanism of ECB.





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

* Re: window groups
  2008-05-31  9:10               ` martin rudalics
@ 2008-05-31 11:52                 ` Juanma Barranquero
  2008-05-31 13:36                   ` martin rudalics
  0 siblings, 1 reply; 46+ messages in thread
From: Juanma Barranquero @ 2008-05-31 11:52 UTC (permalink / raw)
  To: martin rudalics; +Cc: Thomas Lord, emacs-devel, Chong Yidong, Miles Bader

> Here
>
> (split-window nil nil nil nil t 'root)
>
> gets me a new window above all others regardless how complex my
> window-layout is.

Where is "here"? Your local changes? Because that's at least three
more args than the standard split-window accepts.

 Juanma




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

* Re: window groups
  2008-05-31 11:52                 ` Juanma Barranquero
@ 2008-05-31 13:36                   ` martin rudalics
  2008-05-31 17:22                     ` Thomas Lord
  0 siblings, 1 reply; 46+ messages in thread
From: martin rudalics @ 2008-05-31 13:36 UTC (permalink / raw)
  To: Juanma Barranquero; +Cc: Thomas Lord, emacs-devel, Chong Yidong, Miles Bader

 > Where is "here"? Your local changes? Because that's at least three
 > more args than the standard split-window accepts.

My local changes.  Have a look at the description that started this
thread.





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

* Re: window groups
  2008-05-31 13:36                   ` martin rudalics
@ 2008-05-31 17:22                     ` Thomas Lord
  2008-05-31 22:37                       ` martin rudalics
  0 siblings, 1 reply; 46+ messages in thread
From: Thomas Lord @ 2008-05-31 17:22 UTC (permalink / raw)
  To: martin rudalics
  Cc: Juanma Barranquero, Chong Yidong, emacs-devel, Miles Bader

martin rudalics wrote:
> > Where is "here"? Your local changes? Because that's at least three
> > more args than the standard split-window accepts.
>
> My local changes.  Have a look at the description that started this
> thread.
>

Aha!  That's why I couldn't find it.

I have a suggestion about the description that started this
thread but, first, to clear up a misunderstanding:

In the other message you answered one of my questions:

 >>> Returning "precisely" to former sizes is non-trivial.
 
 >> How so?

 > Because your context might have changed in between.  For example, when
 > leaving a `save-window-excursion' you don't want your frame get resized.


Context got lost in the quoting there and caused confusion.

When a temporary window or a pop-up created by splitting the root
of a frame is deleted *and* the user hasn't otherwise touched the
window configuration, *then* precise sizes should be restored.
So, if a user resizes a frame or explicitly resizes, deletes, or splits
a window it doesn't matter as much.   But if none of those things have
happened since the pop-up, the precise sizes should be restored.

That would *almost* happens automatically but not quite.

Currently, if you delete one of the windows in (say) a horizontal
stack, then by default the new space is allocated proportionally among
the remaining windows.   That won't always DTRT in the case of
pop-ups that split the root of the frame.   For example, before the
pop-up, a stack of windows may have each had an exactly equal
number of lines.   When the pop-up appears, the remaining lines
might not divide evenly among the other windows in the stack -
so they are no longer all the same size.   When the pop-up disappears,
Emacs won't always restore them to be all the same size.

That's the case I was talking about fixing and I was talking about
fixing it only in a very narrow case: that the user hasn't done anything
to change the window configuration other than triggering the pop-up
window and then dismissing the pop-up window.

So, back to the original description:

For various reasons I found the original description really difficult
to understand and believe in.   Other people have already pointed out
some ways in which it "isn't lispy".   I would add that it is pretty
complicated but only a weak rationale is given for the complexity.
It's complicated because it adds 3 parameters (that seem hard to
explain) to split-window.   It's complicated because it adds a new
primitive concept (window groups) and that concept comes with
non-intuitive restrictions (like the non-nesting of groups and the
non-existence of single-window groups).

I take your word for it that, given those new features, you can implement
something that looks a lot like certain other IDEs.   On the other hand,
these features don't obviously have many other uses besides that - they
aren't very "general," at least as far as I can tell from the description.

Here is the thing, though:

Presumably you want to use the new features you're working on and then
build higher-level application code to actually implement IDE features.
Let's just assume that all of your higher level code (actual or planned) is
just fine but ask: is there a simpler, more general substitute for the 
low-level
changes?

Stefan tells me that "window properties" are being added at this time.

Emacs already has a lot of handy "hooks" to catch significant events
as, for example, the window-configuration-change-hook

Well, how about this?   Modify split-window with just one new additional
parameter which, if that parameter is 'root, then a top-level split is 
implied.
If that parameter is nil, current behavior is implied.   No other values for
that parameter should be defined yet.

I *suspect* (and its only a suspicion) that those alone are sufficient to
accomplish everything you are trying to do with window groups, without
even very much pain (and, perhaps with some added flexibility).

No?

Not to confuse things too much but let me also suggest how, in the future,
the new split-window parameter that might be 'root could take on other
values.   Every window is conceptually part of both a horizontal and
vertical stack of windows, containing 1 or more windows.   One possibility
is that if the new split-window parameter is a window, then the pop-up
splits off the entire horizontal or vertical stack of which that window is
a part.   This is a sneaky way to "expose the window tree to lisp" as Mile's
puts it.   (Additional sneakiness would be a function that, given a window,
returns an ordered list of all windows in the same horizontal or vertical
stack.)

That would have use in IDE-style interfaces.   For example, suppose that
down the screen on the left are a series of narrow "navigation" windows
and on the right there is an edit area, an interaction area, and a debugger
area.    A "help window pop-up" could usefully be constrained to take
up space just on the right of the screen.   That would be a natural 
generalization
of using 'root and having it take up space on the whole screen.

-t





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

* Re: window groups
  2008-05-31 17:22                     ` Thomas Lord
@ 2008-05-31 22:37                       ` martin rudalics
  2008-06-02  3:49                         ` Thomas Lord
  0 siblings, 1 reply; 46+ messages in thread
From: martin rudalics @ 2008-05-31 22:37 UTC (permalink / raw)
  To: Thomas Lord; +Cc: Juanma Barranquero, Chong Yidong, emacs-devel, Miles Bader

 > When a temporary window or a pop-up created by splitting the root
 > of a frame is deleted *and* the user hasn't otherwise touched the
 > window configuration, *then* precise sizes should be restored.
 > So, if a user resizes a frame or explicitly resizes, deletes, or splits
 > a window it doesn't matter as much.   But if none of those things have
 > happened since the pop-up, the precise sizes should be restored.

Yes.  `set-window-configuration' frequently restores a configuration
without users noticing.

 > Currently, if you delete one of the windows in (say) a horizontal
 > stack, then by default the new space is allocated proportionally among
 > the remaining windows.

When you delete a window its space is only given to the window above or
on the left (if no such window exists it's given to the window below or
on the right).  I once thought about changing that behavior in the way
you describe it but realized that it wouldn't make sense for temporary
windows you want to get rid off soon.

 > That won't always DTRT in the case of
 > pop-ups that split the root of the frame.   For example, before the
 > pop-up, a stack of windows may have each had an exactly equal
 > number of lines.   When the pop-up appears, the remaining lines
 > might not divide evenly among the other windows in the stack -
 > so they are no longer all the same size.   When the pop-up disappears,
 > Emacs won't always restore them to be all the same size.

What you describe here is what happens when you delete a window and the
window above/on the left (below/on the right) is an internal window.  In
that case subwindows are resized proportionally.  Small windows that are
not fixed-size may get larger than they were before creating the window
you delete.

 > That's the case I was talking about fixing and I was talking about
 > fixing it only in a very narrow case: that the user hasn't done anything
 > to change the window configuration other than triggering the pop-up
 > window and then dismissing the pop-up window.

But that's the typical use case of `save-window-excursion'.  Or am I
missing something?

 > For various reasons I found the original description really difficult
 > to understand and believe in.   Other people have already pointed out
 > some ways in which it "isn't lispy".   I would add that it is pretty
 > complicated but only a weak rationale is given for the complexity.
 > It's complicated because it adds 3 parameters (that seem hard to
 > explain) to split-window.

The SAFE argument is something I need to get rid of these strange
window-min-height|width bindings you find in Elisp code.  These bindings
are misleading because people sometimes believe that they will prevent
the emanating windows from being deleted later on.  While the SAFE
parameter comes handy for resizing window groups these can happily live
without it.

The INVERT argument is used for creating the new window on the "other
side" of the original window.  I could merge it into the HORIZONTAL
parameter by providing two new values 'left and 'above in addition to
nil and t and we are left with one argument I have to add.

One additional argument would be needed anyway if you want to split the
frame root window instead of a visible one.

 > It's complicated because it adds a new
 > primitive concept (window groups) and that concept comes with
 > non-intuitive restrictions (like the non-nesting of groups and the
 > non-existence of single-window groups).

Rather, these restrictions simplify both semantics and implementation.
Try to write down the semantics of nested groups in a few sentences.
The single-window restriction can be removed (though talking about a
window group when there's only one window doesn't strike me as overly
intuitive).

 > I take your word for it that, given those new features, you can implement
 > something that looks a lot like certain other IDEs.   On the other hand,
 > these features don't obviously have many other uses besides that - they
 > aren't very "general," at least as far as I can tell from the description.

Well I use them all the time and I never use IDEs.

 > Presumably you want to use the new features you're working on and then
 > build higher-level application code to actually implement IDE features.
 > Let's just assume that all of your higher level code (actual or planned) is
 > just fine but ask: is there a simpler, more general substitute for the
 > low-level
 > changes?

I don't intend to implement any IDE features.  But I think that if and
when such features were integrated into Emacs it should be done in a
sane and safe way.

 > Well, how about this?   Modify split-window with just one new additional
 > parameter which, if that parameter is 'root, then a top-level split is
 > implied.
 > If that parameter is nil, current behavior is implied.   No other values
 > for
 > that parameter should be defined yet.
 >
 > I *suspect* (and its only a suspicion) that those alone are sufficient to
 > accomplish everything you are trying to do with window groups, without
 > even very much pain (and, perhaps with some added flexibility).

Modifying `split-window' to do what I described was straightforward.
The only twist was writing a subroutine to shift edges of subwindows
appropriately - something you have to do anyway when you split the frame
root window.

The more complicated part was cloning a configuration previously saved
by `current-window-configuration'.  People asked for such a thing
although I personally don't use it.

 > Not to confuse things too much but let me also suggest how, in the future,
 > the new split-window parameter that might be 'root could take on other
 > values.   Every window is conceptually part of both a horizontal and

I suppose you mean "either" here not "both".

 > vertical stack of windows, containing 1 or more windows. One possibility
 > is that if the new split-window parameter is a window, then the pop-up
 > splits off the entire horizontal or vertical stack of which that window is
 > a part.   This is a sneaky way to "expose the window tree to lisp" as
 > Mile's
 > puts it.   (Additional sneakiness would be a function that, given a window,
 > returns an ordered list of all windows in the same horizontal or vertical
 > stack.)

Would be very easy to implement but hardly useful.  People don't think
in terms of "stacks of windows".  That's why I propose groups as some
sort of abstraction.

 > That would have use in IDE-style interfaces.   For example, suppose that
 > down the screen on the left are a series of narrow "navigation" windows
 > and on the right there is an edit area, an interaction area, and a debugger
 > area.    A "help window pop-up" could usefully be constrained to take
 > up space just on the right of the screen.   That would be a natural
 > generalization
 > of using 'root and having it take up space on the whole screen.

If your edit area were split horizontally you'd be stuck.  My proposal
defines the edit area as a group and you will get your "help window"
below (or above) that group.





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

* Re: window groups
  2008-05-31 22:37                       ` martin rudalics
@ 2008-06-02  3:49                         ` Thomas Lord
  2008-06-02  9:34                           ` martin rudalics
  0 siblings, 1 reply; 46+ messages in thread
From: Thomas Lord @ 2008-06-02  3:49 UTC (permalink / raw)
  To: martin rudalics
  Cc: Juanma Barranquero, Chong Yidong, emacs-devel, Miles Bader

martin rudalics wrote:
> > That's the case I was talking about fixing and I was talking about
> > fixing it only in a very narrow case: that the user hasn't done 
> anything
> > to change the window configuration other than triggering the pop-up
> > window and then dismissing the pop-up window.
>
> But that's the typical use case of `save-window-excursion'.  Or am I
> missing something?

About "missing something" on more than just this qusetion -- er, yes.
No blame, unless to me.  I'm a stranger here, more or less.  And I'm 
only just starting
to return to paying attention to Emacs internals.  I gather I'm not 
explaining
myself with contextually effective clarity.   Oh well.  I won't dwell on it.

About "save-window-excursion" -- yes, you're missing something there,
too.   When a help window pops up (say, for describe-function) it persists
outside of any save-window-excursion.   I am proposing that, using window
properties and various hooks, a user should be able to delete that window
and restore the previous window configuration of the same frame provided
that the user has not otherwise modified the window configuration.

I'm implying a one-level-undo, of sorts and in limited cases, for the window
configuration of a frame.   Data for such an "undo" could be saved as
window properties and tended by hook functions.



>
> > For various reasons I found the original description really difficult
> > to understand and believe in.   Other people have already pointed out
> > some ways in which it "isn't lispy".   I would add that it is pretty
> > complicated but only a weak rationale is given for the complexity.
> > It's complicated because it adds 3 parameters (that seem hard to
> > explain) to split-window.
>
> The SAFE argument is something I need to get rid of these strange
> window-min-height|width bindings you find in Elisp code.  These bindings
> are misleading because people sometimes believe that they will prevent
> the emanating windows from being deleted later on.  While the SAFE
> parameter comes handy for resizing window groups these can happily live
> without it.


It sounds like you are addressing confusion by adding confusingness.
In your original description, what does "safe defaults" mean?


>
> The INVERT argument is used for creating the new window on the "other
> side" of the original window.  I could merge it into the HORIZONTAL
> parameter by providing two new values 'left and 'above in addition to
> nil and t and we are left with one argument I have to add.

I see.   My own counter-proposal fails to address that very need.   So
I can agree something like that is desirable.



>
> One additional argument would be needed anyway if you want to split the
> frame root window instead of a visible one.

Well, I proposed *one*.   And you've got me convinced on a boolean
parameter for INVERT.

(I do appreciate your patience here.   I hope the worst case is that I'm
helping you simply explicate your proposal.  I still think it is too
complicated and these new agreements we've found are only a small
fraction of that complexity.   Again, consider the power of window
properties + hooks for most of what you want to do.   Right now we're
only agreeing on some API for editing the window tree but not agreeing
on anything close to "groups".    And, please: I do mean to exude humility
here.  I was pretty darn deep into Emacs internals a few years back and
pretty darn deep into Emacs applications and, for that matter, rather deep
into working on a rewrite before rudely interrupted.   I don't pretend
to be fully up to speed on the current mindset of the main developers
and state of the code -- just trying to get back closer to that state.)



>
> > It's complicated because it adds a new
> > primitive concept (window groups) and that concept comes with
> > non-intuitive restrictions (like the non-nesting of groups and the
> > non-existence of single-window groups).
>
> Rather, these restrictions simplify both semantics and implementation.
> Try to write down the semantics of nested groups in a few sentences.
> The single-window restriction can be removed (though talking about a
> window group when there's only one window doesn't strike me as overly
> intuitive).


I'm just not sure "groups" are needed at all.  If something like groups are
needed, then one would want a nestable version.   They probably aren't
needed.   I think you're adding a new abstraction where none is needed.
That the semantics of nested groups may not have a reasonable solution
is a hint that groups may not be needed at all.

Emacs doesn't need to be able to precisely emulate Eclipse, especially if
in a simpler and more extensible way it can create a close substitute.
Emacs may well come out *better*.


>
> > I take your word for it that, given those new features, you can 
> implement
> > something that looks a lot like certain other IDEs.   On the other 
> hand,
> > these features don't obviously have many other uses besides that - they
> > aren't very "general," at least as far as I can tell from the 
> description.
>
> Well I use them all the time and I never use IDEs.

If you'll indulge me -- and again, who am *I* to ask -- could you
explain a bit?    I made that claim that these are obscure and not
general and you're making the opposite claim.   Yours is easier to
prove.   What examples should I look at, please?



> I don't intend to implement any IDE features.  But I think that if and
> when such features were integrated into Emacs it should be done in a
> sane and safe way.
>

We agree about "safe and sane" -- the only question is what exactly
that means :-)



> > Well, how about this?   Modify split-window with just one new 
> additional
> > parameter which, if that parameter is 'root, then a top-level split is
> > implied.
> > If that parameter is nil, current behavior is implied.   No other 
> values
> > for
> > that parameter should be defined yet.
> >
> > I *suspect* (and its only a suspicion) that those alone are 
> sufficient to
> > accomplish everything you are trying to do with window groups, without
> > even very much pain (and, perhaps with some added flexibility).
>
> Modifying `split-window' to do what I described was straightforward.
> The only twist was writing a subroutine to shift edges of subwindows
> appropriately - something you have to do anyway when you split the frame
> root window.

Lots of things that are "straightforward" can come back and bite you in
the rear end down the line.   That's the main problem.  There's an 
embarrassing
over-supply of the "straightforward change" but, experience shows, only a
tiny fraction of those changes are comfortable in the long run -- the others
become "legacy" (some examples of which you are wrestling with -- so
don't make more if you can avoid it).



>
> The more complicated part was cloning a configuration previously saved
> by `current-window-configuration'.  People asked for such a thing
> although I personally don't use it.

Some of the GUI apps that I use, unrelated to Emacs, make use of a similar
feature and I find it to be one of the things I like about those apps.

I don't know that I would tie that cloning to Emacs' current concept of
window-configuration, though.



>
> > Not to confuse things too much but let me also suggest how, in the 
> future,
> > the new split-window parameter that might be 'root could take on other
> > values.   Every window is conceptually part of both a horizontal and
>
> I suppose you mean "either" here not "both".

I mean "both" in this way:

Each window is part of a horizontal stack of H members and a
vertical stack of V members subject to the invariant that:

  (H >= 1 and V == 1) or (H == 1 and V >= 1)




>
> > vertical stack of windows, containing 1 or more windows. One 
> possibility
> > is that if the new split-window parameter is a window, then the pop-up
> > splits off the entire horizontal or vertical stack of which that 
> window is
> > a part.   This is a sneaky way to "expose the window tree to lisp" as
> > Mile's
> > puts it.   (Additional sneakiness would be a function that, given a 
> window,
> > returns an ordered list of all windows in the same horizontal or 
> vertical
> > stack.)
>
> Would be very easy to implement but hardly useful.  People don't think
> in terms of "stacks of windows".  That's why I propose groups as some
> sort of abstraction.

I don't know (and I don't think you do, either) what "people think" in
some free-floating general way.  

The "model" -- the mathematical abstraction -- of a window config is
a tree and there's just a few ways to characterize it.    What I tend to 
believe
is that the more lucidly APIs and UIs can present the actual model, the
more clearly people will think and do useful things with it.   Are you
familiar with XDM as in DOM or XPATH?   To "present the window tree"
in APIs more than is already done we need a similar approach -- a way
to assign "addresses" to the tree in ways that correspond to how algorithms
navigate the tree.    This would be a lot easier to talk about at higher 
bandwidth
with a whiteboard at hand :-)




>
> > That would have use in IDE-style interfaces.   For example, suppose 
> that
> > down the screen on the left are a series of narrow "navigation" windows
> > and on the right there is an edit area, an interaction area, and a 
> debugger
> > area.    A "help window pop-up" could usefully be constrained to take
> > up space just on the right of the screen.   That would be a natural
> > generalization
> > of using 'root and having it take up space on the whole screen.
>
> If your edit area were split horizontally you'd be stuck.  My proposal
> defines the edit area as a group and you will get your "help window"
> below (or above) that group.
>

Excuse my brain-fart there and swap "horizontal" and "vertical" in
what I said and it should make perfect sense.

-t








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

* Re: window groups
  2008-06-02  3:49                         ` Thomas Lord
@ 2008-06-02  9:34                           ` martin rudalics
  2008-06-02 21:32                             ` Thomas Lord
  2008-06-03  5:52                             ` Miles Bader
  0 siblings, 2 replies; 46+ messages in thread
From: martin rudalics @ 2008-06-02  9:34 UTC (permalink / raw)
  To: Thomas Lord; +Cc: Juanma Barranquero, Chong Yidong, emacs-devel, Miles Bader

 > About "save-window-excursion" -- yes, you're missing something there,
 > too.   When a help window pops up (say, for describe-function) it persists
 > outside of any save-window-excursion.

By design.  Incidentally, I hate those save-window-excursions throwing
me back to some unwanted state of affairs I forgot about long ago ...

 > I am proposing that, using window
 > properties and various hooks, a user should be able to delete that window
 > and restore the previous window configuration of the same frame provided
 > that the user has not otherwise modified the window configuration.

`View-quit' should do that.  If it doesn't, please complain.  I spent
some time on making it DTRT.

 > I'm implying a one-level-undo, of sorts and in limited cases, for the
 > window
 > configuration of a frame.   Data for such an "undo" could be saved as
 > window properties and tended by hook functions.

A one-level-undo is equivalent to saving `current-window-configuration'
followed by `set-window-configuration' to the saved value.  It works
reliably provided the frame still exists but is used a bit too often for
my taste.  IIRC ECB has a complete undo-history for window configuration
changes.

 > It sounds like you are addressing confusion by adding confusingness.
 > In your original description, what does "safe defaults" mean?

"safe defaults" are values that don't crash Emacs.  For some reasons,
the display engine is not able to digest windows smaller than a certain
size.  In general, I use "safe" for "anything that's not bad" and
consider crashing Emacs "bad" in this context.  (On the other hand, a
person who wrote a program to crash Emcas would consider her program
"safe" iff it were able to crash Emacs by noon say.)

 > Again, consider the power of window
 > properties + hooks for most of what you want to do.

Window properties are not powerful per se.  You have to modify Emacs'
primitives to give them power.  Currently, a package like ECB does this
by advising these primitives.  Hooks are something I use in my private
programs.  As for functions shipped with Emacs I prefer them _not_ use
any hook unless there's no other way.

 > I'm just not sure "groups" are needed at all.  If something like groups are
 > needed, then one would want a nestable version.   They probably aren't
 > needed.   I think you're adding a new abstraction where none is needed.
 > That the semantics of nested groups may not have a reasonable solution
 > is a hint that groups may not be needed at all.

I didn't say they "don't have a reasonable solution".  I said it's hard
to specify them in a few lines.  What's worse, in my opinion, is that we
currently don't have any visual feedback.  A user who wants to operate
on a group of windows usually can tell the members of that group only by
intuition.  If you already don't recognize plain groups then how about
nested ones?  What's the purpose of a concept if the user can't grasp
it?

 > Emacs doesn't need to be able to precisely emulate Eclipse, especially if
 > in a simpler and more extensible way it can create a close substitute.
 > Emacs may well come out *better*.

It certainly should.  That's why I don't like a solution which always
throws me back to a static (previously defined and explicitly saved)
window configuration.  I want dynamic configurations much as Emacs
permits me to create them now, possibly embedded in an edit area and
surrounded by view windows I can create and dismiss at will.

 >> Well I use them all the time and I never use IDEs.
 >
 > If you'll indulge me -- and again, who am *I* to ask -- could you
 > explain a bit?    I made that claim that these are obscure and not
 > general and you're making the opposite claim.   Yours is easier to
 > prove.   What examples should I look at, please?

For obvious reasons these examples reside on my system only.  Most of
these are concerned with usually two or three sidebars (narrow windows)
distributed all over my frame.  Each of these sidebars is the left
window in a combination with some client window and gives me details of
what I show or eventually might want to show in the client window
(files, buffers, tags, bookmarks, search results).  Sidebar and client
window form a group and their relationship can't get broken by
extraneous functions like `display-buffer' or `split-window'.  And I can
have as many such groups as the resolution of my screen and my eyesight
permit.

 >> I don't intend to implement any IDE features.  But I think that if and
 >> when such features were integrated into Emacs it should be done in a
 >> sane and safe way.
 >>
 > We agree about "safe and sane" -- the only question is what exactly
 > that means :-)

I use "safe" for "not breaking Emacs" and "sane" for "not breaking the
editing habits of Emacs users".

 > Lots of things that are "straightforward" can come back and bite you in
 > the rear end down the line.   That's the main problem.  There's an
 > embarrassing
 > over-supply of the "straightforward change" but, experience shows, only a
 > tiny fraction of those changes are comfortable in the long run -- the
 > others
 > become "legacy" (some examples of which you are wrestling with -- so
 > don't make more if you can avoid it).

The `split-window' changes are sane since they are based on three
optional argument.  If you don't set eiher of them, the behavior of
`split-window' is unaffected.  "straightforward" here just stands for
"it wasn't difficult to do that".

 >> The more complicated part was cloning a configuration previously saved
 >> by `current-window-configuration'.  People asked for such a thing
 >> although I personally don't use it.
 >
 > Some of the GUI apps that I use, unrelated to Emacs, make use of a similar
 > feature and I find it to be one of the things I like about those apps.
 >
 > I don't know that I would tie that cloning to Emacs' current concept of
 > window-configuration, though.

IMHO cloning must come in two flavors: The first means to recreate a
layout in one and the same session.  In this case you want cloning to
happen quickly and match the original layout as sincerely as possible
(just like `set-window-configuration').  The second flavor comes for
recreating frame layouts in another session, on another system, for
another user.  In that case cloning may be slower since it's based on
recursively applying `split-window' and maybe less faithful to the
original because the enironment might have changed.

 > Each window is part of a horizontal stack of H members and a
 > vertical stack of V members subject to the invariant that:
 >
 >  (H >= 1 and V == 1) or (H == 1 and V >= 1)
[...]
 >
 > The "model" -- the mathematical abstraction -- of a window config is
 > a tree and there's just a few ways to characterize it.    What I tend to
 > believe
 > is that the more lucidly APIs and UIs can present the actual model, the
 > more clearly people will think and do useful things with it.   Are you
 > familiar with XDM as in DOM or XPATH?   To "present the window tree"
 > in APIs more than is already done we need a similar approach -- a way
 > to assign "addresses" to the tree in ways that correspond to how algorithms
 > navigate the tree.    This would be a lot easier to talk about at higher
 > bandwidth
 > with a whiteboard at hand :-)

Window groups are an abstraction.  Their purpose is to provide some of
the functionality of window trees.  But users should not be aware of
thses underlying trees at all.  I give you an example: Create a layout
by subdividing a fresh frame via C-x 2 C-x 3 C-x 2 C-x 3.  Go to the
upper right window and repeatedly call the function

(defun my-enlarge-window-horizontally ()
   (interactive)
   (let ((window-min-width 1))
     (enlarge-window 1 t)))

You will observe the upper left windows shrink and, at a certain moment,
the three windows in the upper left corner disappear all together
although it would have been sufficient to delete just one of the two
smallest windows.  Explaining this behavior is very difficult and
intrinsically tied to the fact that the shrink_windows routine in
window.c does not recurse but operate on window combinations only.

Now don't get me wrong.  I don't consider this behavior a bug.  After
all, if a window gets deleted because there's no other way out, why not
delete a couple of other windows as well.  I still consider Emacs'
behavior quite sane here.  The point I wanted to make is that
understanding and implementing window trees is already pretty hard for
developers.  Exposing them to the user simply doesn't make sense, IMHO.

 >> If your edit area were split horizontally you'd be stuck.  My proposal
 >> defines the edit area as a group and you will get your "help window"
 >> below (or above) that group.
 >
 > Excuse my brain-fart there and swap "horizontal" and "vertical" in
 > what I said and it should make perfect sense.

If your edit area appears like this

  -----
|  |  |
|  |  |
  -----

and you consider it a "stack" (actually a "deque") you supply the
connotation that any further split has to occur on one of each sides.
But what if you want to split one of these windows vertically?  What if
you want a compile, shell, or help window at the bottom?  You'll tell me
that you'd create another stack embedded in or on top of the previous
one.  In my parlance any combination of such stacks is a window group.





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

* Re: window groups
  2008-06-02  9:34                           ` martin rudalics
@ 2008-06-02 21:32                             ` Thomas Lord
  2008-06-03  5:52                             ` Miles Bader
  1 sibling, 0 replies; 46+ messages in thread
From: Thomas Lord @ 2008-06-02 21:32 UTC (permalink / raw)
  To: martin rudalics
  Cc: Juanma Barranquero, Chong Yidong, emacs-devel, Miles Bader

martin rudalics wrote:
> > About "save-window-excursion" -- yes, you're missing something there,
> > too.   When a help window pops up (say, for describe-function) it 
> persists
> > outside of any save-window-excursion.
>
> By design.  Incidentally, I hate those save-window-excursions throwing
> me back to some unwanted state of affairs I forgot about long ago ...

I hate that too.  And, yes, help windows work that way by design.

All I'm saying is that you have interaction that goes:

   1. User does something that causes....
   2. Help window to pop up....
   3. User does stuff but nothing effecting window config...
   4. Use deletes the help window

then the resulting window config should be as at step 0.

(Well, that and as we agree there should be *some*
mechanism to pop-up other than by splitting a leaf
window.)


>
> > I am proposing that, using window
> > properties and various hooks, a user should be able to delete that 
> window
> > and restore the previous window configuration of the same frame 
> provided
> > that the user has not otherwise modified the window configuration.
>
> `View-quit' should do that.  If it doesn't, please complain.  I spent
> some time on making it DTRT.

Uh... where is that?   I've been doing this blind, just on general
principles.   I was thinking I'd probably build the latest 23.x snapshot
this week sometime.



>
> > I'm implying a one-level-undo, of sorts and in limited cases, for the
> > window
> > configuration of a frame.   Data for such an "undo" could be saved as
> > window properties and tended by hook functions.
>
> A one-level-undo is equivalent to saving `current-window-configuration'
> followed by `set-window-configuration' to the saved value.  It works
> reliably provided the frame still exists but is used a bit too often for
> my taste.  IIRC ECB has a complete undo-history for window configuration
> changes.

A complete undo history or, hey, how about a ring of saved configs,
could be nice.   Only experience with failed experiments in that area,
imo, can arrive at a nice UI.


>
> > It sounds like you are addressing confusion by adding confusingness.
> > In your original description, what does "safe defaults" mean?
>
> "safe defaults" are values that don't crash Emacs.  For some reasons,
> the display engine is not able to digest windows smaller than a certain
> size.  In general, I use "safe" for "anything that's not bad" and
> consider crashing Emacs "bad" in this context.  (On the other hand, a
> person who wrote a program to crash Emcas would consider her program
> "safe" iff it were able to crash Emacs by noon say.)


Uh.. I guess I'll just say "hrrmmm" and suggest some fresh air.


>
> > Again, consider the power of window
> > properties + hooks for most of what you want to do.
>
> Window properties are not powerful per se.  You have to modify Emacs'
> primitives to give them power.  Currently, a package like ECB does this
> by advising these primitives.  Hooks are something I use in my private
> programs.  As for functions shipped with Emacs I prefer them _not_ use
> any hook unless there's no other way.

Maybe a rule of thumb is that it is reasonable to use a hook if
it also makes sense to remove the hook function you are installing.

That is, a hook function whose absence would break emacs suggests
a function that shouldn't be run from the hook but in some other way.
But, aren't there even exceptions to that rule of thumb in the core?  I
don't clearly remember that detail.




>
> > I'm just not sure "groups" are needed at all.  If something like 
> groups are
> > needed, then one would want a nestable version.   They probably aren't
> > needed.   I think you're adding a new abstraction where none is needed.
> > That the semantics of nested groups may not have a reasonable solution
> > is a hint that groups may not be needed at all.
>
> I didn't say they "don't have a reasonable solution".  I said it's hard
> to specify them in a few lines.

Sorry, those two are almost (*almost*) synonymous to me :-)
The really charming bits of Emacs seem to me to be the
startlingly simple yet powerful/general/flexible bits.


> What's worse, in my opinion, is that we
> currently don't have any visual feedback.  A user who wants to operate
> on a group of windows usually can tell the members of that group only by
> intuition.  If you already don't recognize plain groups then how about
> nested ones?  What's the purpose of a concept if the user can't grasp
> it?


We agree on some aspects of UI.  I like the way you put that.

If you want to get to a UI that presents easy concepts for users to grasp,
the thing that works well (especially in the Emacs tradition) is for
the underlying program to have very simple-minded data structures.
Then, the UI is just "drawing pictures" of something that is already
simple.

The way people go wrong is when they think of some "simple for
users" concept that, it turns out, requires a lot of strange complexity
in the code.   What often happens there is that the UI is then drawing
a falsely simple picture -- illustrating a fantasy -- and the underlying 
code
can "fake it" to an extent but never quite live up to it.  I call these 
"user
interfaces that lie".

You're a little too casual, in my opinion, with the notion of a "group".
I think you might be adding hair to the code and a UI that dissembles a
bit.   But I do strongly agree that the ultimate aim here is just to give
a gadget (underlying code) whose form and therefore function is transparent
(UI) to the users.   (Geeze, I sound like from Palo Alto with this
level of pretension :-)


>
> > Emacs doesn't need to be able to precisely emulate Eclipse, 
> especially if
> > in a simpler and more extensible way it can create a close substitute.
> > Emacs may well come out *better*.
>
> It certainly should.  That's why I don't like a solution which always
> throws me back to a static (previously defined and explicitly saved)
> window configuration.  I want dynamic configurations much as Emacs
> permits me to create them now, possibly embedded in an edit area and
> surrounded by view windows I can create and dismiss at will.

So do I and I think that's what I've been sketching.


>
> >> Well I use them all the time and I never use IDEs.
> >
> > If you'll indulge me -- and again, who am *I* to ask -- could you
> > explain a bit?    I made that claim that these are obscure and not
> > general and you're making the opposite claim.   Yours is easier to
> > prove.   What examples should I look at, please?
>
> For obvious reasons these examples reside on my system only.  Most of
> these are concerned with usually two or three sidebars (narrow windows)
> distributed all over my frame.  Each of these sidebars is the left
> window in a combination with some client window and gives me details of
> what I show or eventually might want to show in the client window
> (files, buffers, tags, bookmarks, search results).  Sidebar and client
> window form a group and their relationship can't get broken by
> extraneous functions like `display-buffer' or `split-window'.  And I can
> have as many such groups as the resolution of my screen and my eyesight
> permit.

Ok, if I understand that right I'm pretty sure that "groups" aren't
the most parsimonious approach although I can see why they would
work.

I'd like to suggest that the windows you want to "protect" with
groups don't actually need protection.   If the user does stuff
that f-s with them, so be it.   I think that instead of that kind of
protection you just want "encouragement" for normal commands
to not perturb them.  Pop-ups other than leaf nodes and window props
should do the trick.

It's ok for a fancy, app-defined window-config to sometimes
"fall apart" if there's an easy way to restore it and it doesn't
fall apart accidentally very often, especially if the return for that
is keeping the "concept model" of the display simple.


>
> > Lots of things that are "straightforward" can come back and bite you in
> > the rear end down the line.   That's the main problem.  There's an
> > embarrassing
> > over-supply of the "straightforward change" but, experience shows, 
> only a
> > tiny fraction of those changes are comfortable in the long run -- the
> > others
> > become "legacy" (some examples of which you are wrestling with -- so
> > don't make more if you can avoid it).
>
> The `split-window' changes are sane since they are based on three
> optional argument.  If you don't set eiher of them, the behavior of
> `split-window' is unaffected.  "straightforward" here just stands for
> "it wasn't difficult to do that".


Their sane in that they preserve a default behavior.     One view
of the problem is:  will your successor, in 10 years, feel good about
preserving the behavior of these three new parameters plus all the
twisted, unanticipated uses people have put them to?


>
> > Each window is part of a horizontal stack of H members and a
> > vertical stack of V members subject to the invariant that:
> >
> >  (H >= 1 and V == 1) or (H == 1 and V >= 1)
> [...]
> >
> > The "model" -- the mathematical abstraction -- of a window config is
> > a tree and there's just a few ways to characterize it.    What I 
> tend to
> > believe
> > is that the more lucidly APIs and UIs can present the actual model, the
> > more clearly people will think and do useful things with it.   Are you
> > familiar with XDM as in DOM or XPATH?   To "present the window tree"
> > in APIs more than is already done we need a similar approach -- a way
> > to assign "addresses" to the tree in ways that correspond to how 
> algorithms
> > navigate the tree.    This would be a lot easier to talk about at 
> higher
> > bandwidth
> > with a whiteboard at hand :-)
>
> Window groups are an abstraction.  Their purpose is to provide some of
> the functionality of window trees.  But users should not be aware of
> thses underlying trees at all.  I give you an example: Create a layout
> by subdividing a fresh frame via C-x 2 C-x 3 C-x 2 C-x 3.  Go to the
> upper right window and repeatedly call the function
>
> (defun my-enlarge-window-horizontally ()
>   (interactive)
>   (let ((window-min-width 1))
>     (enlarge-window 1 t)))
>
> You will observe the upper left windows shrink and, at a certain moment,
> the three windows in the upper left corner disappear all together
> although it would have been sufficient to delete just one of the two
> smallest windows.  Explaining this behavior is very difficult and
> intrinsically tied to the fact that the shrink_windows routine in
> window.c does not recurse but operate on window combinations only.

See above about "protection".



>
> Now don't get me wrong.  I don't consider this behavior a bug.  After
> all, if a window gets deleted because there's no other way out, why not
> delete a couple of other windows as well.  I still consider Emacs'
> behavior quite sane here.  The point I wanted to make is that
> understanding and implementing window trees is already pretty hard for
> developers.  Exposing them to the user simply doesn't make sense, IMHO.
>
> >> If your edit area were split horizontally you'd be stuck.  My proposal
> >> defines the edit area as a group and you will get your "help window"
> >> below (or above) that group.
> >
> > Excuse my brain-fart there and swap "horizontal" and "vertical" in
> > what I said and it should make perfect sense.
>
> If your edit area appears like this
>
>  -----
> |  |  |
> |  |  |
>  -----
>
> and you consider it a "stack" (actually a "deque") you supply the
> connotation that any further split has to occur on one of each sides.
> But what if you want to split one of these windows vertically?  What if
> you want a compile, shell, or help window at the bottom?  You'll tell me
> that you'd create another stack embedded in or on top of the previous
> one.  In my parlance any combination of such stacks is a window group.
>
>

I don't see any reason for "groups" to be a first-class notion in lisp
or in the "user's cognitive model".   

It's just tiling.   It's not too complicated for non-programmer users to
get, is the experience here.

Finally: thank you for taking the time to reply.  I think I want to back
off this topic a little bit and, perhaps, tinker with setting up a dev tree
for myself.   *If* I get around to that, it might make these 
conversations easier.



-t





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

* Re: window groups
  2008-06-02  9:34                           ` martin rudalics
  2008-06-02 21:32                             ` Thomas Lord
@ 2008-06-03  5:52                             ` Miles Bader
  2008-06-03  9:02                               ` martin rudalics
  1 sibling, 1 reply; 46+ messages in thread
From: Miles Bader @ 2008-06-03  5:52 UTC (permalink / raw)
  To: martin rudalics
  Cc: Juanma Barranquero, Thomas Lord, Chong Yidong, emacs-devel

martin rudalics <rudalics@gmx.at> writes:
>> I am proposing that, using window
>> properties and various hooks, a user should be able to delete that window
>> and restore the previous window configuration of the same frame provided
>> that the user has not otherwise modified the window configuration.
>
> `View-quit' should do that.  If it doesn't, please complain.  I spent
> some time on making it DTRT.

Whoa ... view-quit sometimes does the right thing?!

-Miles

-- 
Mayonnaise, n. One of the sauces that serve the French in place of a state
religion.




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

* Re: window groups
  2008-06-03  5:52                             ` Miles Bader
@ 2008-06-03  9:02                               ` martin rudalics
  2008-06-03  9:51                                 ` René Kyllingstad
  0 siblings, 1 reply; 46+ messages in thread
From: martin rudalics @ 2008-06-03  9:02 UTC (permalink / raw)
  To: Miles Bader; +Cc: emacs-devel

 > Whoa ... view-quit sometimes does the right thing?!

Don't panic.  Just sometimes in the context of help windows maybe.





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

* Re: window groups
  2008-06-03  9:02                               ` martin rudalics
@ 2008-06-03  9:51                                 ` René Kyllingstad
  2008-06-03 11:26                                   ` martin rudalics
  0 siblings, 1 reply; 46+ messages in thread
From: René Kyllingstad @ 2008-06-03  9:51 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel, Miles Bader

* martin rudalics:
>   > Whoa ... view-quit sometimes does the right thing?!
>  
>  Don't panic.  Just sometimes in the context of help windows maybe.

It doesn't even handle the case where you have 2 windows in a frame and you
invoke help.  Instead of burying the help buffer it closes the window.
Thank you view mode.

Ie, in Emacs 22.2 -Q: C-x 3 C-h f i f RET C-x o q gives me a one window
configuration, and in an older emacs session often even changes the buffer
displayed in that window. It feels like it goes out of its way to disrupt
my work.


-- René





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

* Re: window groups
  2008-06-03  9:51                                 ` René Kyllingstad
@ 2008-06-03 11:26                                   ` martin rudalics
  2008-06-03 11:54                                     ` Stephen Berman
  0 siblings, 1 reply; 46+ messages in thread
From: martin rudalics @ 2008-06-03 11:26 UTC (permalink / raw)
  To: René Kyllingstad; +Cc: emacs-devel, Miles Bader

 > It doesn't even handle the case where you have 2 windows in a frame and you
 > invoke help.  Instead of burying the help buffer it closes the window.
 > Thank you view mode.
 >
 > Ie, in Emacs 22.2 -Q: C-x 3 C-h f i f RET C-x o q gives me a one window
 > configuration, and in an older emacs session often even changes the buffer
 > displayed in that window. It feels like it goes out of its way to disrupt
 > my work.

This should work with Emacs 23.  Can someone try?





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

* Re: window groups
  2008-06-03 11:26                                   ` martin rudalics
@ 2008-06-03 11:54                                     ` Stephen Berman
  2008-06-03 13:21                                       ` René Kyllingstad
  0 siblings, 1 reply; 46+ messages in thread
From: Stephen Berman @ 2008-06-03 11:54 UTC (permalink / raw)
  To: emacs-devel

On Tue, 03 Jun 2008 13:26:39 +0200 martin rudalics <rudalics@gmx.at> wrote:

>> It doesn't even handle the case where you have 2 windows in a frame and you
>> invoke help.  Instead of burying the help buffer it closes the window.
>> Thank you view mode.
>>
>> Ie, in Emacs 22.2 -Q: C-x 3 C-h f i f RET C-x o q gives me a one window
>> configuration, and in an older emacs session often even changes the buffer
>> displayed in that window. It feels like it goes out of its way to disrupt
>> my work.
>
> This should work with Emacs 23.  Can someone try?

Works for me in GNU Emacs 23.0.60.9 (i686-pc-linux-gnu, GTK+ Version
2.12.0) of 2008-05-29 on escher.

Steve Berman





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

* Re: window groups
  2008-06-03 11:54                                     ` Stephen Berman
@ 2008-06-03 13:21                                       ` René Kyllingstad
  2008-06-08  2:39                                         ` Stefan Monnier
  0 siblings, 1 reply; 46+ messages in thread
From: René Kyllingstad @ 2008-06-03 13:21 UTC (permalink / raw)
  To: emacs-devel

* Stephen Berman:
>  On Tue, 03 Jun 2008 13:26:39 +0200 martin rudalics <rudalics@gmx.at>
>  wrote:
>  
> >> It doesn't even handle the case where you have 2 windows in a frame
> >> and you invoke help.  Instead of burying the help buffer it closes the
> >> window.  Thank you view mode.
> >>
> >> Ie, in Emacs 22.2 -Q: C-x 3 C-h f i f RET C-x o q gives me a one
> >> window configuration, and in an older emacs session often even changes
> >> the buffer displayed in that window. It feels like it goes out of its
> >> way to disrupt my work.
> >
> > This should work with Emacs 23.  Can someone try?
>  
>  Works for me in GNU Emacs 23.0.60.9 (i686-pc-linux-gnu, GTK+ Version
>  2.12.0) of 2008-05-29 on escher.

Sweet. Thank you Martin!


That was one thing that has annoyed me since switching from XEmacs. I also
miss the compact disiplay of hyper-apropos bound to C-h a in XEmacs.  Here
is an example as was recently asked for:

Apropos search for: "upcase"

* = command (M-x) or user-variable.
a = autoloaded, b = byte-compiled, i = internal, l = lambda, m = macro.

Functions and Macros:

b  cl-upcase-arg                 
a* dired-upcase                   - Rename all marked (or next ARG) files to upper case.
i  upcase                         - Convert STRING-OR-CHAR to upper case and return that.
i  upcase-initials                - Convert the initial of each word in STRING-OR-CHAR to upper case.
i* upcase-initials-region         - Upcase the initial of each word in the region.
i* upcase-region                  - Convert the region to upper case.  In programs, wants two arguments.
b* upcase-region-or-word          - Upcase the selected region or the following word (or ARG words).
i* upcase-word                    - Convert following word (or COUNT words) to upper case, moving over.
b* wdired-upcase-word             - Wdired version of `upcase-word'.


Variables and Constants:

   byte-upcase                   

---end-of-XEmacs-output---

Compare with M-x apropos on GNU Emacs 22.2:

If moving the mouse over text changes the text's color, you can click
mouse-2 (second button from right) on that text to get more information.
In this buffer, go to the name of the command, or function, or variable,
and type RET to get full documentation.

byte-upcase
  Variable: (not documented)
  Plist: risky-local-variable emacs19-opcode byte-opcode-invert
dired-upcase
  Command: Rename all marked (or next ARG) files to upper case.
  Plist: autoload event-symbol-element-mask event-symbol-elements modifier-cache
get-upcase-table
  Function: Return the upcase table of CASE-TABLE.
set-upcase-syntax
  Function: Make character UC an upcase of character LC.
upcase
  Function: Convert argument to upper case and return that.
  Plist: event-symbol-element-mask event-symbol-elements modifier-cache byte-compile byte-opcode side-effect-free
upcase-initials
  Function: Convert the initial of each word in the argument to upper case.
upcase-initials-region
  Command: Upcase the initial of each word in the region.
  Plist: event-symbol-element-mask event-symbol-elements modifier-cache
upcase-region
  Command: Convert the region to upper case.  In programs, wants two arguments.
  Plist: disabled event-symbol-element-mask event-symbol-elements modifier-cache
upcase-word
  Command: Convert following word (or ARG words) to upper case, moving over.
  Plist: event-symbol-element-mask event-symbol-elements modifier-cache
wdired-upcase-word
  Command: WDired version of `upcase-word'.
  Plist: event-symbol-element-mask event-symbol-elements modifier-cache

---end-of-GNU-Emacs-output---

I find the tabular format of XEmacs easier to parse.


-- René





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

* Re: window groups
  2008-06-03 13:21                                       ` René Kyllingstad
@ 2008-06-08  2:39                                         ` Stefan Monnier
  2008-08-18 15:37                                           ` René Kyllingstad
  0 siblings, 1 reply; 46+ messages in thread
From: Stefan Monnier @ 2008-06-08  2:39 UTC (permalink / raw)
  To: René Kyllingstad, John S. Yates, Jr.; +Cc: emacs-devel

> That was one thing that has annoyed me since switching from XEmacs.  I also
> miss the compact disiplay of hyper-apropos bound to C-h a in XEmacs.  Here
> is an example as was recently asked for:
<as well as>
> The key virtue is columnar layout which is visually easier to parse and
> faster to navigate.  My final sample shows that gnu emacs does not eschew
> long lines.

The patch below adds an apropos-compact-layout customization to get
something similar to what XEmacs provides.  Check it out,


        Stefan



--- apropos.el.~1.127.~	2008-05-06 23:35:06.000000000 -0400
+++ apropos.el	2008-06-07 22:31:01.000000000 -0400
@@ -190,6 +190,7 @@
 
 (define-button-type 'apropos-function
   'apropos-label "Function"
+  'apropos-short-label "<f>"
   'help-echo "mouse-2, RET: Display more help on this function"
   'follow-link t
   'action (lambda (button)
@@ -197,6 +198,7 @@
 
 (define-button-type 'apropos-macro
   'apropos-label "Macro"
+  'apropos-short-label "<m>"
   'help-echo "mouse-2, RET: Display more help on this macro"
   'follow-link t
   'action (lambda (button)
@@ -204,6 +206,7 @@
 
 (define-button-type 'apropos-command
   'apropos-label "Command"
+  'apropos-short-label "<c>"
   'help-echo "mouse-2, RET: Display more help on this command"
   'follow-link t
   'action (lambda (button)
@@ -216,6 +219,7 @@
 ;; Likewise for `customize-face-other-window'.
 (define-button-type 'apropos-variable
   'apropos-label "Variable"
+  'apropos-short-label "<v>"
   'help-echo "mouse-2, RET: Display more help on this variable"
   'follow-link t
   'action (lambda (button)
@@ -223,6 +227,7 @@
 
 (define-button-type 'apropos-face
   'apropos-label "Face"
+  'apropos-short-label "<F>"
   'help-echo "mouse-2, RET: Display more help on this face"
   'follow-link t
   'action (lambda (button)
@@ -230,6 +235,7 @@
 
 (define-button-type 'apropos-group
   'apropos-label "Group"
+  'apropos-short-label "<g>"
   'help-echo "mouse-2, RET: Display more help on this group"
   'follow-link t
   'action (lambda (button)
@@ -238,6 +244,7 @@
 
 (define-button-type 'apropos-widget
   'apropos-label "Widget"
+  'apropos-short-label "<w>"
   'help-echo "mouse-2, RET: Display more help on this widget"
   'follow-link t
   'action (lambda (button)
@@ -245,6 +252,7 @@
 
 (define-button-type 'apropos-plist
   'apropos-label "Plist"
+  'apropos-short-label "<p>"
   'help-echo "mouse-2, RET: Display more help on this plist"
   'follow-link t
   'action (lambda (button)
@@ -402,6 +410,10 @@
 
 \\{apropos-mode-map}")
 
+(defvar apropos-multi-type t
+  "If non-nil, this apropos query concerns multiple types.
+This is used to decide whether to print the result's type or not.")
+
 ;;;###autoload
 (defun apropos-variable (pattern &optional do-all)
   "Show user variables that match PATTERN.
@@ -487,7 +499,8 @@
 					  (string-match "\n" doc)))))))
 	(setcar (cdr (car p)) score)
 	(setq p (cdr p))))
-    (and (apropos-print t nil nil t)
+    (and (let ((apropos-multi-type do-all))
+           (apropos-print t nil nil t))
 	 message
 	 (message "%s" message))))
 
@@ -617,7 +658,8 @@
 						     (apropos-score-str p))
 						  f v p)
 					    apropos-accumulator))))))
-  (apropos-print nil "\n----------------\n"))
+   (let ((apropos-multi-type do-all))
+     (apropos-print nil "\n----------------\n")))
 
 
 ;;;###autoload
@@ -844,6 +886,9 @@
       nil
     function))
 
+(defcustom apropos-compact-layout nil
+  "If non-nil, use a single line per binding."
+  :type 'boolean)
 
 (defun apropos-print (do-keys spacing &optional text nosubst)
   "Output result of apropos searching into buffer `*Apropos*'.
@@ -885,12 +930,10 @@
 		(substitute-command-keys
 		 "and type \\[apropos-follow] to get full documentation.\n\n"))
 	(if text (insert text "\n\n"))
-	(while (consp p)
+	(dolist (apropos-item p)
 	  (when (and spacing (not (bobp)))
 	    (princ spacing))
-	  (setq apropos-item (car p)
-		symbol (car apropos-item)
-		p (cdr p))
+	  (setq symbol (car apropos-item))
 	  ;; Insert dummy score element for backwards compatibility with 21.x
 	  ;; apropos-item format.
 	  (if (not (numberp (cadr apropos-item)))
@@ -905,22 +948,25 @@
 			      'face apropos-symbol-face)
 	  (if (and (eq apropos-sort-by-scores 'verbose)
 		   (cadr apropos-item))
-	      (insert " (" (number-to-string (cadr apropos-item)) ") "))
+	      (insert " (" (number-to-string (cadr apropos-item)) ")"))
 	  ;; Calculate key-bindings if we want them.
+          (unless apropos-compact-layout
 	  (and do-keys
 	       (commandp symbol)
 	       (not (eq symbol 'self-insert-command))
 	       (indent-to 30 1)
 	       (if (let ((keys
-			  (save-excursion
-			    (set-buffer old-buffer)
+                            (with-current-buffer old-buffer
 			    (where-is-internal symbol)))
 			 filtered)
 		     ;; Copy over the list of key sequences,
 		     ;; omitting any that contain a buffer or a frame.
-		     (while keys
-		       (let ((key (car keys))
-			     (i 0)
+                       ;; FIXME: Why omit keys that contain buffers and
+                       ;; frames?  This looks like a bad workaround rather
+                       ;; than a proper fix.  Does anybod know what problem
+                       ;; this is trying to address?  --Stef
+                       (dolist (key keys)
+                         (let ((i 0)
 			     loser)
 			 (while (< i (length key))
 			   (if (or (framep (aref key i))
@@ -928,8 +974,7 @@
 			       (setq loser t))
 			   (setq i (1+ i)))
 			 (or loser
-			     (setq filtered (cons key filtered))))
-		       (setq keys (cdr keys)))
+                               (push key filtered))))
 		     (setq item filtered))
 		   ;; Convert the remaining keys to a string and insert.
 		   (insert
@@ -950,7 +995,7 @@
 				      'face apropos-keybinding-face)
 		   (put-text-property (- (point) 3) (point)
 				      'face apropos-keybinding-face))))
-	  (terpri)
+            (terpri))
 	  (apropos-print-doc 2
 			     (if (commandp symbol)
 				 'apropos-command
@@ -963,11 +1008,12 @@
 	  (apropos-print-doc 6 'apropos-face t)
 	  (apropos-print-doc 5 'apropos-widget t)
 	  (apropos-print-doc 4 'apropos-plist nil))
+        (set (make-local-variable 'truncate-partial-width-windows) t)
+        (set (make-local-variable 'truncate-lines) t)
 	(setq buffer-read-only t))))
   (prog1 apropos-accumulator
     (setq apropos-accumulator ())))	; permit gc
 
-
 (defun apropos-macrop (symbol)
   "Return t if SYMBOL is a Lisp macro."
   (and (fboundp symbol)
@@ -980,20 +1026,26 @@
 
 
 (defun apropos-print-doc (i type do-keys)
-  (if (stringp (setq i (nth i apropos-item)))
-      (progn
-	(insert "  ")
-	(insert-text-button (button-type-get type 'apropos-label)
+  (when (stringp (setq i (nth i apropos-item)))
+    (if apropos-compact-layout
+        (insert (propertize "\t" 'display '(space :align-to 32)) " ")
+      (insert "  "))
+    ;; If the query is only for a single type, there's
+    ;; no point writing it over and over again.
+    (when apropos-multi-type
+      (insert-text-button (button-type-get type
+                                           (if apropos-compact-layout
+                                               'apropos-short-label
+                                             'apropos-label))
 			    'type type
 			    ;; Can't use the default button face, since
 			    ;; user may have changed the variable!
 			    ;; Just say `no' to variables containing faces!
 			    'face apropos-label-face
 			    'apropos-symbol (car apropos-item))
-	(insert ": ")
+      (insert (if apropos-compact-layout " " ": ")))
 	(insert (if do-keys (substitute-command-keys i) i))
-	(or (bolp) (terpri)))))
-
+    (or (bolp) (terpri))))
 
 (defun apropos-follow ()
   "Invokes any button at point, otherwise invokes the nearest label button."




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

* Re: window groups
  2008-06-08  2:39                                         ` Stefan Monnier
@ 2008-08-18 15:37                                           ` René Kyllingstad
  0 siblings, 0 replies; 46+ messages in thread
From: René Kyllingstad @ 2008-08-18 15:37 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel, John S. Yates, Jr.

* Stefan Monnier:
> > That was one thing that has annoyed me since switching from XEmacs.  I
> > also miss the compact disiplay of hyper-apropos bound to C-h a in
> > XEmacs.  Here is an example as was recently asked for:
>  <as well as>
> > The key virtue is columnar layout which is visually easier to parse and
> > faster to navigate.  My final sample shows that gnu emacs does not
> > eschew long lines.
>  
>  The patch below adds an apropos-compact-layout customization to get
>  something similar to what XEmacs provides.  Check it out,

This looks great - thank you!  I find it much easier to read.

I'd prefer to use the short labels for the compact representation, so that
they line up, and it basically becomes a table.

Meaning, in apropos-print-doc I'd change:

       (if apropos-compact-layout
           (button-type-get type 'apropos-label)
to

       (if apropos-compact-layout
           (button-type-get type 'apropos-short-label)


-- René




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

end of thread, other threads:[~2008-08-18 15:37 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-28 12:22 window groups martin rudalics
2008-05-29  1:39 ` Richard M Stallman
2008-05-29  9:26   ` martin rudalics
2008-05-29 16:30     ` Stefan Monnier
2008-05-30  7:05       ` martin rudalics
2008-05-30 13:58         ` Stefan Monnier
2008-05-30 19:27           ` martin rudalics
2008-05-31  4:52             ` Stefan Monnier
2008-05-31  9:10               ` martin rudalics
2008-05-30  0:59     ` Richard M Stallman
2008-05-30  7:08       ` martin rudalics
2008-05-31  2:07         ` Richard M Stallman
2008-05-31  6:17           ` Daniel Colascione
2008-05-31  7:09             ` Miles Bader
2008-05-31  9:10           ` martin rudalics
2008-05-30  0:59     ` Richard M Stallman
2008-05-30  7:08       ` martin rudalics
2008-05-29 15:18 ` Chong Yidong
2008-05-30  7:06   ` martin rudalics
2008-05-29 16:10 ` Chong Yidong
2008-05-29 19:11   ` Miles Bader
2008-05-29 21:40     ` Chong Yidong
2008-05-29 22:33       ` Miles Bader
2008-05-29 23:53         ` Thomas Lord
2008-05-30  7:07           ` martin rudalics
2008-05-30 16:42             ` Thomas Lord
2008-05-30 16:08               ` Stefan Monnier
2008-05-31  9:10               ` martin rudalics
2008-05-31 11:52                 ` Juanma Barranquero
2008-05-31 13:36                   ` martin rudalics
2008-05-31 17:22                     ` Thomas Lord
2008-05-31 22:37                       ` martin rudalics
2008-06-02  3:49                         ` Thomas Lord
2008-06-02  9:34                           ` martin rudalics
2008-06-02 21:32                             ` Thomas Lord
2008-06-03  5:52                             ` Miles Bader
2008-06-03  9:02                               ` martin rudalics
2008-06-03  9:51                                 ` René Kyllingstad
2008-06-03 11:26                                   ` martin rudalics
2008-06-03 11:54                                     ` Stephen Berman
2008-06-03 13:21                                       ` René Kyllingstad
2008-06-08  2:39                                         ` Stefan Monnier
2008-08-18 15:37                                           ` René Kyllingstad
2008-05-30  7:07         ` martin rudalics
2008-05-30  7:07     ` martin rudalics
2008-05-30  7:07   ` martin rudalics

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