[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#4748: 23.1; least recently used window - is it?
bug#4748: 23.1; least recently used window - is it?
Sun, 18 Oct 2009 11:48:17 -0700
> (let ((owin (selected-window)))
> (dolist (window (window-list))
> (unless (eq window owin)
> (select-window 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
> > 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.
> > 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'
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
> >> > 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
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)?