Subject: Re: bug#7368: display-buffer a softly dedicated window

From: martin rudalics <[email-masked]>
Date: Thu, 18 Nov 2010 09:03:36 +0100

> 1) In principle, set-window-buffer may fail.

When the window is strongly dedicated to its buffer and doesn't show the
buffer already.

 > 2) set-window-buffer doesn't fail in
 >
 > (let ((foo (get-buffer-create "foo"))
 >       (bar (get-buffer-create "bar"))
 >       (baz (get-buffer-create "baz")))
 >   (switch-to-buffer foo)
 >   (delete-other-windows)
 >   (let ((bar-window (display-buffer bar t)))
 >     (set-window-dedicated-p bar-window 'soft)
 >     (set-window-buffer bar-window baz)))
 >
 > 3) display-buffer uses set-window-buffer as a subroutine.
 >
 > 4) display-buffer checks some conditions before calling
 > set-window-buffer, because the latter may fail.

To avoid that `set-window-buffer' reports an error.

 > 5) display-buffer fails in
 >
 > (let ((foo (get-buffer-create "foo"))
 >       (bar (get-buffer-create "bar"))
 >       (baz (get-buffer-create "baz")))
 >   (switch-to-buffer foo)
 >   (delete-other-windows)
 >   (let ((bar-window (display-buffer bar t)))
 >     (set-window-dedicated-p bar-window 'soft))
 >   (display-buffer baz t))
 >

The fact that it doesn't use bar-window for displaying the buffer is not
a "failure" per se.

 > 6) This is because checks in display-buffer before calling
 > set-window-buffer and inside set-window-buffer are different.

Yes.

 > 7) I believe this is not logical and should be fixed.

Logic is in the mind of the beholder.  I can see two reasons for making
a window weakly dedicated:

(a) Give the application programmer a way to tell `display-buffer' that
     it should finding another window for displaying the buffer.  The
     user is allowed to switch to another buffer whenever she wants to.

(b) Make the window disappear when it's no more needed.

If there's consensus that (a) is not needed or useful I agree with your
conclusion.  Personally, I do not need weakly dedicated windows, so I
have no opinion about this.

 > 8) I think there is an easy way to fix it by checking for dedicated =
 > t instead of dedicated != nil inside get-lru-window and
 > get-largest-window (by the way, is there any chance those are
 > implemented in Lisp?).

They are implemented in ELisp on the window-pub branch.

 >> If the window is dedicated for the sole purpose to make it disappear
 >> when it's no more need I tend to agree.  There are better solutions.
 >
 > Please tell which.

Use a window parameter say `delete-window-when-buffer-is-buried'.  When
a window is created by `display-buffer', right after the
`set-window-buffer' call, set the parameter to the buffer argument.  In
`bury-buffer', `replace-buffer-in-windows', ... if the parameter value
of `delete-window-when-buffer-is-buried' equals the buffer of the
window, delete the window if possible.  Look at the quit-restore
parameter in the window-pub branch.

 > The minibuffer.el 's completion mechanism does not impose any
 > restrictions on what you can do while *Completions* is visible. That's
 > slightly off-topic, but I think it allows more user freedom and
 > clearer code.

If that's the case you can do away with the completions window whenever
you want to.  I see little difference between deleting the completions
window manually and having `display-buffer' use it for showing another
buffer.

 >> The _only_ purpose of weakly dedicated windows is to not allow
 >> `display-buffer' to use them.
 >
 > I disagree. As a matter of fact, weakly dedicated windows possess
 > another property: they are deleted when their buffer is killed.
 >
 > As a matter of personal opinion, "not allow `display-buffer' to use
 > them, but allow `set-window-buffer' to use them" is very hard concept
 > to understand. Especially given that `display-buffer' uses
 > `set-window-buffer' inside ;-) Even harder to understand is the
 > distinction between weakly and truly dedication.

The distinction is that the _user_ should be allowed to reuse a weakly
dedicated window, for example, when switching buffers in the selected
window.  Application programs should not be allowed to use them.

 >> IIUC the sequence of events is
 >>
 >> (1) the application issues a call for getting the name of a buffer,
 >>
 >> (2) the user enters the name with the assistance of the completion
 >>    routines,
 >>
 >> (3) the completion routines return the name,
 >>
 >> (4) the caller displays the buffer with that name.
 >>
 >
 > No. The command showing *Completions* and command calling
 > display-buffer are totally unrelated. See the first message.

This doesn't make sense to me.  I consider popping up a completions
window and subsequently deleting it one user interaction that should not
be disrupted by other activities like displaying some unrelated buffer.

martin