[Top][All Lists]

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

bug#4748: 23.1; least recently used window - is it?

From: Drew Adams
Subject: bug#4748: 23.1; least recently used window - is it?
Date: Sun, 18 Oct 2009 11:48:17 -0700

> (let ((owin (selected-window)))
>    (dolist (window (window-list))
>      (unless (eq window owin)
>        (select-window window)))
>    (get-lru-window))

That doesn't work either. For the same reason: `get-lru-window' will never
return certain windows.

>  > Which means you cannot use `pop-up-buffer' in any 
>  > reasonable way to get the window-selection behavior of
>  > `switch-to-buffer'. Or else please show me how.
> Maybe.  My `switch-to-buffer' is in Elisp for quite some 
> time.  It goes like
>     ((or (window-minibuffer-p) (eq (window-dedicated-p) t))
>      (pop-to-buffer buffer-or-name nil norecord))

(I'm curious: Why not call `pop-to-buffer' if the window is dedicated or a
minibuffer? What's the reason for that conditional?)

If you feel that your version of `switch-to-buffer' makes it respect the
use-other-frame variables but otherwise have the same behavior as the current
`switch-to-buffer', then why don't you install it?

But do you in fact claim that? If not, I don't see it as a solution to the

>  > `switch-to-buffer', which Stefan says repeatedly (and it 
>  > sounds right to me) should not be used in Lisp code (i.e.
>  > should be used pretty much only interactively), does not
>  > respect `special-display-regexps',
>  > `special-display-buffer-names', or `pop-up-frames'.
> Because it wouldn't make much sense to respect these ;-)

Huh? Why not? Why shouldn't it use the current window (as now) except when those
variables say not to (a la `switch-to-buffer-other-window' and `pop-to-buffer')?

IOW, have it do just what you claim it already does for dedicated windows. Just
as a dedicated window says "don't use me", so the use-other-frame variables also
say "don't use me". You say that we listen to the former - but we unfortunately
still do not listen to the latter.

>  > And yet `switch-to-buffer' _is_ used in Lisp code, 
>  > including in the Emacs sources. It is called from commonly
>  > used commands, such as `bookmark-bmenu-list'
>  > and `view-buffer'/`view-file' (which means, e.g., 
>  > `view-emacs-news').
> We'd have to look at each of these cases to tell whether they can use
> `pop-to-buffer' directly.

They cannot, by definition, if we intend to keep the current behavior of using
the same window (except when the use-other-frame vars say not to) and having the
same `quit-window' behavior.

The problem is not just looking at each occurrence individually. The problem is
how to get the intended behavior (current window unless frame vars say
otherwise; same `quit-window' behavior).

>  > Presumably, there is a common use case there that should 
>  > be respected: someone wants to substitute for the current
>  > buffer preferably in the same window,
>  > instead of opening a new window and moving focus there. 
>  > Dunno if that's a reasonable use case - I never need that
>  > behavior myself, but it seems to be fairly common.
> I can't tell.  Obviously `same-window-buffer-names' and friends
> implicitly provide the same service.

How so? If you have a solution to the question I raised, please post it, by all

>  > Assuming we should be able to meet that use case, what's 
>  > the right replacement for `switch-to-buffer' for that case?
> If and when we enhance `display-buffer' with a same-window argument
> `switch-to-buffer' could become obsolete (for Elisp calls).  OTOH this
> might lead programmers to call `display-buffer' with the same-window
> argument in these and other cases.

Is that a discussion topic for emacs-devel? If you're proposing such a change to
`display-buffer', then it should be discussed there. Such a change shouldn't
"just happen".
>  > What code will do the same thing wrt which
>  > window gets used and which buffer will be put in place 
>  > after using, say, `quit-window' in the newly displayed buffer?
> Does `quit-window' behave differently wrt whether 
> `switch-to-buffer' was called or `pop-to-buffer'?

Try it. I gave the recipe. Use the code I sent that uses `pop-to-buffer' and
compare, using the C-x 2 C-x 3 situation, with different buffers and with the
same buffer in all 3 windows.

>  > The above code loops forever in some cases (e.g. C-x 2 C-x 
>  > 3; put 3 diff buffers in the windows; then the small,
>  > right-hand window will never be used by
>  > `pop-to-buffer'. That is, this will not work:
>  >
>  > (cond ((one-window-p) ; This part works.
>  >        (pop-to-buffer (get-buffer-create "*foo*"))
>  >        (delete-other-windows))
>  >       (t ; This part works except for some windows.
>  >        (let ((owin  (selected-window)))
>  >          (while (not (eq (get-lru-window) owin))
>  >            (other-window 1)))
>  >        (pop-to-buffer (get-buffer-create "*foo*"))))
>  >
>  > (You'll recommend comparing with the root window, instead 
>  > of calling `one-window-p', but that doesn't change the
>  > point in question.)
> You shouldn't use `other-window' because it doesn't bury the window as
> you expect.  Loop over `window-list' instead.

Please show me what you mean. You can see what I'm trying to do. How to do it?

And please explain why `other-window' should not be used - in what way doesn't
it "bury the window as you expect"? Is it also a dwim function? What about
`next-window' - would that work better?

>  > Here's another attempt, which at least doesn't loop 
>  > forever: Replace the `let' sexp above by this:
>  >
>  > (dotimes (i (1- (count-windows))) (other-window 1))
>  >
>  > That suffers from more or less the same problem: the newly 
>  > displayed buffer is never shown in the right-hand window -
>  > the full-width window is always used whenever the right-hand
>  > window is selected. (But of course this preference for
>  > full-width is inconsistent - the just-as-small left-hand 
>  > window _is_ used to display the buffer. IOW, this dwim does
>  > not dwim.)
>  >
>  > [You cannot just use (other-window (1- (count-window)) 
>  > instead of a loop, because that doesn't cycle the
>  > window-selection (lru) order.]
> I still don't understand why and how you want to control the 
> setting of the LRU window in practice.

I don't really care about the lru window. I was trying to get `pop-to-buffer' to
use the selected window (whatever that window is, no exceptions). And also to
keep the same `quit-window' behavior that you get when you use

>  > And if you have the same buffer in more than one window, 
>  > then such "solutions" also behave differently from
>  > `switch-to-buffer' when you use `quit-window'. E.g.
>  > C-x 2 C-x 3, without using 3 different buffers, etc.
> In what sense do they behave differently?

When you quit the window, you get a different buffer from what you get when you
use `switch-to-buffer'. At least that's what I saw. Try the examples I mentioned
- C-x 2 C-x 3.

>  > 1. The reason for avoiding `switch-to-buffer' here, and 
>  >    using `pop-to-buffer' instead, is so that variables
>  >    such as `special-display-*' and `pop-up-frames'
>  >    will be respected. E.g., if `special-display-regexps'
>  >    is ("[ ]?[*][^*]+[*]"), then *foo* will be opened in
>  >    its own, special frame.
> Good.
>  > 2. The reason for trying to simulate `switch-to-buffer's 
>  >    which-window-gets-used behavior and its `quit-window' behavior
> I still don't understand - what is `switch-to-buffer's `quit-window'
> behavior?

God only knows. I don't try to characterize any of the behavior in a meaningful
way. It does what it does - why and how I do not know.

The point is that if you use `switch-to-buffer' and then quit the window, the
buffer that is displayed is different than what you see if you use
`pop-to-buffer' (successfully forcing it to use the same window, at least for
most windows) and then you quit the window. Try the examples I gave, and see for

Again, personally I don't care about preserving the same behavior that
`switch-to-buffer' gives (wrt using the same window and quitting). But I imagine
that someone does, or we wouldn't still be using it.

>  > is that such behavior is apparently a common use case.
>  > If replacing `switch-to-buffer' in, say, `view-buffer',
>  > we would presumably want to keep the same behavior as now
>  > for users who do not use `special-display-*' and `pop-up-frames'.
> So try to experiment with the following: Have `display-buffer'
> interpret a 'same-window value for the NOT-THIS-WINDOW argument
> and replace calls like (switch-to-buffer buffer) with
> (pop-to-buffer buffer 'same-window).

I don't have any time for that, sorry.

But if that makes `pop-to-buffer' use the same window, and users are happy with
it, then that's the way to go.

However, that won't help with older Emacs versions, which is a concern I also
have. IOW, even if the main concern (for me too) is to fix Emacs in this regard
going forward, I would also like to know what code I can use in older versions
to get a solution (act like `switch-to-buffer' except when the use-other-frame
vars say to use another frame). Maybe the answer is that there is no such
solution. But I'd like to know.

>  > Again, dunno about #2. Maybe we should just forget about 
>  > that use case and replace `switch-to-buffer' willy nilly by 
>  > `pop-to-buffer'/`display-buffer'?
>  >
>  > Or maybe we should redefine `switch-to-buffer' so that it 
>  > respects the variables in question (and possibly other
>  > relevant variables, if any). IOW, make it use
>  > `display-buffer'. (Why doesn't it?)
> It does (if the selected window is dedicated).

That's not a solution. `special-display-*' and `pop-up-frames' do not affect
only dedicated windows.

Have it respect _all_ such don't-use-this-window stuff, not just dedicated
>  > Or (more likely) maybe I'm missing something, and there is 
>  > already a reasonable way to get both (a) the
>  > `switch-to-buffer' behavior wrt window selection and
>  > `quit-window' and (b) the `display-buffer' behavior wrt 
>  > the use-another-frame variables?
>  >
>  > In which case, please enlighten me. How should we replace 
>  > `switch-to-buffer' in, say, `view-buffer' or
>  > `bookmark-bmenu-list' (or...)?
> First you have to enlighten me wrt the quit-window behavior.

Just try it. I saw a difference, when you: (a) use `quit-window' after using
`switch-to-buffer' versus (b) use `quit-window' after using `pop-to-buffer' in
such a way that it reuses the same window (not possible for some windows, but
possible for most - see the code I sent). The buffer that is displayed in the
window after `quit-window' is not the same.

If I'm wrong about that, fine - one less thing to worry about when trying to
keep the current `switch-to-buffer' behavior (except when proscribed by
use-other-frame vars).

>  >>  > Currently, it doesn't seem easy to predict or control
>  >>  > which window is used by things such as `pop-to-buffer'
>  >>  > that try to use another window. Being able to set the
>  >>  > so-called lruw that such functions use would
>  >>  > make things a lot more straightforward.
>  >>
>  >> We can easily remove the FULL-WIDTH feature.  But _who_ would be
>  >> responsible for "touching" windows in order to make them LRU?
>  >
>  > I would do it in my code - if it worked.
> But it's the _user_ who should touch the windows, not the application
> programmer.

Agreed. So show me how to do it without fiddling with lru. I tried that fiddling
only to try to get `pop-to-buffer' to reuse the same window. The aim was to keep
the `switch-to-buffer' behavior for people who do not use `special-display-*' or
`pop-to-frames', but otherwise have the behavior that `pop-to-buffer' has when
those vars are used.

>  > But the main question is posed above. Given the aim of, in 
>  > effect, making `pop-to-buffer' use a particular window, I tried to 
>  > somehow set a window to be the lru. But that doesn't work because
>  > of the full-width criterion.
>  > I was hoping that simply making a window be the least 
>  > recently used one would cause `pop-to-buffer' to use that window.
>  > But things are apparently far from so simple. I'm hoping you or
>  > someone else (e.g. Stefan) has a simple solution that I've been blind to.
> Stefan has proposed to enhance the NOT-THIS-WINDOW argument of
> `display-buffer' for this purpose and I'm all for it.

I haven't seen such a proposal discussed in emacs-devel. What is the thread?

And what is a solution for older Emacs versions (is there one)?

reply via email to

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