emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: display-buffer-alist simplifications


From: martin rudalics
Subject: Re: display-buffer-alist simplifications
Date: Wed, 03 Aug 2011 18:23:45 +0200
User-agent: Thunderbird 2.0.0.21 (Windows/20090302)

> I'm not yet concerned about the ease of customizability.  I'm concerned
> about the complexity of the semantics.

When we are concerned about frightening inexperienced users we should be
concerned about the ease of customizability just as about anything else.

> And I'm concerned about the ease with which someone will be able to
> replace display-buffer-alist with something better 10 years from now
> while preserving the compatibility with your (then legacy) code.

`display-buffer-alist' has no built-in dependencies wrt `display-buffer'
like the Emacs 23 buffer display options had.  So you would have to tell
me why you're concerned: Is it the number of options the variable offers
or the "inheritance" rules?

> Ah, so that's what labels are for, now that makes more sense.  But then
> `switch-to-buffer' should not be a label.  The labels I want are about
> the "kind of buffer", not "the command used to display it".  The reason
> for such a label is that buffer-names aren't good enough.
> Maybe we can rely on major and minor modes instead, BTW.

We can rely on anything here.  And we can omit them.

> No.  Any reason it's not in the trunk yet?

Yes.  Whenever I start writing the ChangeLog I have to think about
changing the design of `display-buffer-alist'.

> I had the window-pub moved to old-branches because I thought it had
> been merged.

It had been merged but for the manual and the NEWS entries.

> I just looked at it but I don't see any rationale for the design.
> I only see a description of how the specifiers work (which is fine for
> the Lispref, BTW: what I'm asking is not documentation for users of the
> feature, but a rationale that explains how you got to this design).

It contains rationales for atomic windows and side window.  It's more
difficult to describe rationales for the remaining features.  The idea
of providing a function to adjust the size of popped-up windows, for
example, came from a comment I found in the sources and the discussion
inititated by Chong here as "Resizing windows after display-buffer".

> Note that I generally try to design things to be simpler and more
> expressive (I don't see a contradiction here, because the
> expressiveness is obtained by adding a few "hooks" where random elisp
> code can be plugged).

We have to care for people who are not able or not willing to write such
random code.

> - the same-frame and the same-window parameters are one needed
>   complexity.

These parameters are ill-suited for a number of reasons:

(1) They are presented as special cases within a context of
    "Alternatively, an element of this list can be specified as
    \(BUFFER-NAME FRAME-PARAMETERS), where BUFFER-NAME is a buffer ...".
    Calling them frame parameters is misleading.

(2) They are interpreted exclusively by a function ironically called
    `special-display-popup-frame'.  If the buffer is already displayed
    in some window, these options are ignored by that function.

(3) Users devising their own `special-display-function' have to ignore
    them or write their own code to handle them.

>   But these should be consolidated into a single `where'
>   parameter which could specify same-frame, same-window, and many other
>   things (e.g. near-minibuffer).

This should happen at one level above that handled by
`display-buffer-alist', for example, via macro specifiers.

> - I don't see how you can specify "reusing a window on another frame" in
>   special-display-buffer-names.

But it is done by `special-display-popup-frame' when it finds such a
window on a visible frame.  And you can turn that off and on by using
either another function via the \(BUFFER-NAME FUNCTION OTHER-ARGS) or
another `special-display-function'.

> So I don't see the enormous complexity.  It's basically just:
> - pop up a new frame and mark it dedicated.
> - except when `where' says otherwise.
> - and except for the hook case (where you can say "use this function to
>   display the buffer").
> The hook case gives you a lot of expressiveness since you get complete
> control, but it adds very little complexity to the design.

The complexity is built into the code of `special-display-popup-frame'.
You don't know what `special-display-buffer-names' does unless you read
the code of that function.  The correct doc-string of
`special-display-buffer-names' would have to explain in full what the
code of `special-display-popup-frame' does.

>> Atomic windows were discussed in a thread on how to implement tabs in a
>> separate window since you were opposed to using the headerline for them.
>
> I don't think we should try and provide support for atomic windows with
> display-buffer.  At least not yet.  I expect that any place where we
> might want to use atomic windows will need to set things up
> manually anyway.

OK.  Let's remove that part.

> BTW, I don't see any use of this feature in the window-pub branch.
> Do you have some sample code showing how it works (the minimap package
> in GNU ELPA seems like a good candidate)?

I was writing such code when you announced the feature freeze ;-)

> Same remark (don't integrate support for it in display-buffer, yet) and
> same question (do you have sample code using it, ideally some attempt at
> making ECB use that feature?) for side-windows.

I'm stronlgy for keeping this in `display-buffer-alist'.  Personally, I
think that side windows should be used in two ways only: Either by the
user via `display-buffer' - so she can display a window showing a
specific buffer always in the same place of the frame - or by special
window managing code like that of ECB.

I have no code showing how to use it but I experimented with it by
setting `display-buffer-alist' appropriately.  I expect that people who
ask for IDE-like behavior will eventually try it and provide some
feedback.

> I'm not asking for "what does it do" (that which needs to be in the
> manual), but "why did you add it, which use-case prompted you to add it
> and what alternative solutions did you throw out" (things which are
> typically not added in a manual, but could be welcome in the Commentary
> section of window.el).

I proceeded as follows:

- Base the design on that of `same-window-regexps' and
  `same-window-buffer-names'.

- Use one variable instead of the twenty or so options we had.

- Use a "what to do" paradigm instead of "what to avoid".

- Try to make the customization interface readable.

- Add things that have been asked for in our forums.

- Make it compatible with Emacs 23.

I don't recall what I threw out.  I had specifiers to set the maximum
size of popped-up window, adjust the size of reused windows, and tried
to improve reusing windows on other frames.

> To take a concrete example: what use-cases did you have in mind that
> required going from the 4 different cases of the old code
> (i.e. `same-frame', `same-window', `new-frame-non-dedicated' and
> `new-frame-dedicated), which in my mind should be something like
> 4 different values of the `where' parameter, to:
> - `reuse-window' with 3 extra parameters.

There are five basic methods: reuse-window, pop-up-window, pop-up-frame,
use-side-window and specifying a function.

`same-window' is provided as a macro specifier.  The semantics of
`same-frame' is difficult to capture as I already explained above: You
can specify it in `special-display-regexps' but if
`special-display-popup-frame' finds a window on another frame it uses
that.  Worse, same-frame will work only if I specify whether I shall
first try to reuse a window and then pop up another one and then ...  I
have same-frame-other-window as a macro specifier but am not overly
happy with it.

The difference between `new-frame-non-dedicated' and
`new-frame-dedicated' is not clear to me.  I suppose it stems mainly
from the fact that you see dedication as a way to specify what to do
with the window or frame when it's no more used.  I specially installed
the quit-restore parameter for this purpose but it's currently mostly
overridden by the dedicated status of the window.  Couldn't you try in
your private code whether you could use that parameter instead and leave
window dedication to what it should stand for according to its name:
Avoid that `display-buffer' and/or `set-window-buffer' reuse a window
for showing another buffer.

> - `reuse-window-dedicated' (AFAIK this is only used in switch-to-buffer
>   so it's not clear why it needs to be supported in display-buffer).

It can (and maybe should) be used for side windows where the IDE people
have that idea of windows that should always show the same buffer or one
of the same "group".

> - `pop-up-window' with a host of different values.

The `selected' window case is obvious, I think: It allows users a basic
control where to show the buffer (largest and lru are not very suitable
for that).  `root' allows to show the buffer in a very predictable
position on some side of the frame.

Combining `selected' and `above' you can, for example, to display the
ispell window without all the tribulations of the current code plus make
it possible to show that window on a separate frame instead.

Combining `root' and `left' allows, for example, to display the speedbar
in a window on the right of the frame.

> - `pop-up-window-split-unsplittable'.

A silly leftover from the old code, IIUC.  I'd do away with it at any
time.

> - `pop-up-frame'.
> - ...
>
> ...[time passes]...
> ...[BTW, could someone rewrite the docstring of display-buffer-alist to
> use things like "if it has the form (label LABEL)" rather than "if it is
> a cons cell whose car is `label'"?]...

Yes.  I'd really love if someone did that and all associated cleanups.

> IIUC the reason why you don't have just a single `where' parameter is so
> that the merge between the specifiers given in display-buffer and
> display-buffer-alist can be more fine-grained, right?  What were the
> use-cases where you thought that was important?

You understand correctly.  Once for compatibility with Emacs 23, once
for applications, and once for people who want fine-grained control.
Abstractions (like near-minibuffer and same-frame) would be built on
top of that.

>> The rule is simple.  You scan a list of expressions until you find the
>> first method specifier that delivers a result.  You scan the tail of the
>> list for the first additional specifier that is needed for implementing
>> a specific behavior like evening window sizes and use it.
>
> The problem I have with it is that the specifiers thingy acts in
> 2 different ways:
> - an alist for some kinds of parameters, like the old special-display-regexps.
> - an `or' that tries elements one after the other until one succeeds.
> That adds conceptual complexity.

I can't deny that.  But that's how `display-buffer' alway worked, in a
hard-coded form.  Even if you use a rule based system, the rules must
permit to specify that I want to pop up a window first and if that fails
try reusing another one.  Or am I missing something here?

> Along the same idea, some parameters that refine the way `reuse-window'
> works are passed as "args" to `reuse-window' while others are provided
> separately as specifiers.  That also adds conceptual complexity.

True.  I was too silly to do that better.  And I'm still too silly to
find a better solution.

> If we're willing to use a single `where' and give up on the finer
> grained merging, then the specifiers can really be an alist, the
> `where' parameter can be defined to always be a function (i.e. it's
> somewhat like your `function' specifier) and we can cut down the
> docstring of display-buffer-alist by a crap load, it just needs to
> mention typically useful values of this parameter, such as
> `display-buffer-same-window', or `display-buffer-same-frame' and those
> functions can then document that they understand params such as
> min-height.

Wouldn't this move options away from the user?  I think we know now how
many people passed their own function to `special-display-popup-frame',
namely two.  I'd like to know how many people wrote their own
`special-display-function'.  And most uses of `display-buffer-function'
were intended to avoid some special cases calling `display-buffer' with
`display-buffer-function' bound to nil again.

One thing we could do is provide a second option - some form of
simplified `display-buffer-alist'.  It would take precedence over
`display-buffer-alist' and relate only macro specifiers to the user.

> In my experience when the preferred method fails, it's sufficient to
> fallback on the default.  Do you have use-cases where this is not true?

In Emacs 23 the preferred method is to try some five methods in the
worst case.  There's no single default fallback.

martin



reply via email to

[Prev in Thread] Current Thread [Next in Thread]