Subject: bug#9875: 24.0.90; Confusing description of the "window tree" in ELisp manual

From: Eli Zaretskii <[email-masked]>
Date: Wed, 26 Oct 2011 20:54:36 +0200

> Date: Wed, 26 Oct 2011 16:23:05 +0200
> From: martin rudalics <[email-masked]>
> CC: [email-masked]
> 
>  > This node starts fine, by describing window-frame and window-list.
>  > Then it begins to describe the "window tree", and that's where things
>  > go wrong.  The main problem is that the non-leaf nodes of the window
>  > tree are referred to as "windows",
> 
> ... as "internal windows" more precisely  ...

No, as _windows_.  Here's a typical example:

     All other windows of a frame with the exception of the minibuffer
  window are subwindows of the frame's root window.  A window is
  considered a "subwindow" of another window if it occupies a part of
  that other window's screen area.

     The functions described next allow to access the members of a window
  tree and take an arbitrary window as argument.

   -- Function: window-parent &optional window
       Return WINDOW's parent in the window tree.  The optional argument
       WINDOW can denote an arbitrary window and defaults to the selected
       one.  The return value is `nil' if WINDOW is a minibuffer window
       or the root window of its frame and an internal window otherwise.

     Parent windows do not appear on the screen.  The screen area of a
  parent window is the rectangular part of the window's frame occupied by
  the window's "child windows", that is, the set of windows having that
  window as their parent.  Each parent window has at least two child
  windows, so there are no "Matryoshka" windows.  Minibuffer windows do
  not have child windows.

All this text freely talks about "windows" when it really means the
nodes of the window tree.

> Many important functions like `split-window', `delete-window', the
> window resize functions, and obviously the new window tree functions
> including `walk-window-tree' apply to both live and internal windows.

That's true, but it only makes the whole issue more confusing.  I can
easily and intuitively understand the expected effect of splitting a
live window.  But what does it mean to "split" a window that is not
displayed at all?  I don't know, and the manual doesn't explain.  It
only has this rather cryptic blurb:

     If WINDOW is live, properties of the new window like margins and
     scroll bars are inherited from WINDOW.  If WINDOW is an internal
     window, these properties, as well as the buffer shown in the new
     window, are inherited from the window selected on WINDOW's frame.

All the rest of the documentation of this function doesn't make any
sense for an "internal window"; the description can only be understood
in the context of a live window.  Take this part, for example:

     If SIDE is `t' or `right' the new window will be positioned on the
     right side of WINDOW.  The value `left' means the new window will
     be located on the left side of WINDOW.  In both cases SIZE
     specifies the new number of columns for WINDOW (or the new window
     provided SIZE is negative) including space reserved for margins,
     fringes and the scroll bar or a divider column.

I cannot interpret this for a non-live window.  I could try _guessing_
what this means in that case, but why should I need to guess when I'm
reading the manual?

More importantly, does Joe R. Hacker, a casual Lisp programmer, really
need to know what this does to an "internal" window?  And if he
doesn't, maybe we will be much better off not to include those
"internal" windows in the domain of these functions, simply by not
calling them "windows"?

>  > The confusion
>  > culminates in "Splitting Windows", where many issues are described via
>  > window-parent and what is called "creating a new parent".
> 
> Yes. And I probably gave too many examples for this in the expectation
> that readers would study them and get a feeling for what internal
> windows are needed for.  But what is the culminating confusion here?
> Could you provide at least one example?

How can one _create_ a _new_ parent?  A parent can only be a parent if
it has children.  You can create children of an existing parent, but
you cannot create a _new_ parent for existing children.  This is a
single most confusing sentence in this section.  It doesn't help that
is also the most important sentence for understanding what window-nest
does.

>  > I submit these confusing references to the nodes of the window tree as
>  > "windows" should be removed.  If we want to talk about the window
>  > tree, let's talk about a tree with nodes; let's not call them
>  > "windows".  I know that each node is exposed to Lisp as a window
>  > object, but (a) I'm not sure this is a good idea either, and (b) what
>  > harm will be done if we mention this factoid in some place and
>  > immediately forget about it?
> 
> Simply that functions accepting an internal window as argument would
> have to say "the argument can be a window or a node" which doesn't
> strike me as very constructive.  In particular not so because I then
> would have to explain in the doc-string what a "node" is.

I don't see any issue here.  Just say, somewhere close to the end of
the doc string, something like "the argument WINDOW can also be a node
of the frame's window tree".  It's very easy to understand.

> Let's take an example: I wrote two functions called `window-state-get'
> and `window-state-put' in the hope that eventually someone uses these
> functions in order to write window configurations to a file and reuse
> them in a later session.  If we find someone to do that, that person
> must be interested in internal windows, because these are part of the
> state and prescribe how to obtain the original configuration from that
> state.  Debugging or patching these functions without knowing about
> internal windows is virtually impossible.

I didn't suggest removing the information from the docs.  I only asked
to (1) rename "internal windows" into "nodes of the window tree",
which is what they are, and (2) have a single section in the manual
that describes the window tree and the functions that operate on it,
instead of spreading that over several sections.  The information you
want that person to have will still be available.  But it will be out
of the way of all the other 99% of Lisp programmers who have no need
to know all that, and don't need to be confused by these "internal"
windows.