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

From: Андрей Парамонов<[email-masked]>
Date: Wed, 17 Nov 2010 18:09:34 +0300

2010/11/17 martin rudalics <[email-masked]>:
> It doesn't fail in your example.  I explained above how it can fail.

Yes, I agree that switch-to-buffer fails, for example, if there is a
single window on a single frame :-)  I wanted to say the following:

1) In principle, switch-to-buffer may fail.

2) switch-to-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)
  (select-window bar-window)
  (switch-to-buffer baz)))

3) display-buffer uses switch-to-buffer as a subroutine.

4) display-buffer checks some conditions before calling
switch-to-buffer, because the latter may fail.

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

6) This is because checks in display-buffer before calling
switch-to-buffer and inside switch-to-buffer are different.

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

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.

Do you agree with points 1-6?

> But rather than thinking about how to "fix" this I'd try to find out why
> `display-buffer' is called _before_ burying the completions buffer.  The
> plain fact that the completions buffer can be reused by `display-buffer'
> indicates that it is no more useful at the time `display-buffer' gets
> called.

You are right, completions buffer is not useful at the time
display-buffer is executed. Now completions buffer doesn't get buried
because no one buries it.

To bury it before display-buffer is my plan B actually ;-)  The
problem with this solution is that it's not general: one will have to
modify many top-level commands capable of displaying a buffer to bury
*Completions* beforehand.

Also such modification would most likely be rejected for upstream, as
properly coding when to bury *Completions* is not trivial, and that
nontrivial code would be in many places.

comint.el solves this problem somehow, but so far I'm not able to
fully understand the code. What I see is that comint.el 's
*Completions* intercepts keyboard events while it's active.

Andrey Paramonov