[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local
From: |
martin rudalics |
Subject: |
bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local |
Date: |
Sat, 08 Oct 2011 15:23:29 +0200 |
User-agent: |
Thunderbird 2.0.0.21 (Windows/20090302) |
> Assume you have buffer B open on frame F in windows T, U and V,
> respectively displaying B at positions P1, P2 and P3. Now in window
> W, also on F, you C-x b to switch to B. Today it takes you to P1,
> assuming T is next in the window-list.
Hardly. It takes you to P1 because presumably window T is selected and
the window point of the selected window usually coincides with that
window's buffer's point.
> If no window were currently
> showing B, then W would display point-min.
Hopefully not. W should display the buffer's `point' (which, if the
buffer was never shown before, would coincide with `point-min').
> Let's call this the "existing-window" behavior, as for a new window W it
> will choose a position from an existing window.
Not necessarily. If another window were selected and, in B you go to
some other position, the next `switch-to-buffer' will display B around
`point' which might not coincide with any of the other windows'
positions.
> If you were to make my
> proposed multi-frame change, I think you could reasonably choose to
> retain the existing-window behavior within a frame, as it preserves the
> current intra-frame buffer-switching semantics.
>
> However, over the decades I have noticed that when I have two or
> more windows open to the same buffer on the same frame, it is almost
> always because I want to establish N > 1 persistent working locations
> within that buffer. In fact it is rarely useful to have two windows open
> to the same buffer location, as they merely echo each other. So
> I would posit that my "multiple persistent working locations" use case
> is likely to be the most common reason for users to have N > 1
> windows displaying the same buffer in a given frame.
Having "two or more windows open to the same buffer" sounds like a
reasonable condition. The problem is that you might have no window
showing the buffer and still want to restore the previous window
position. That's why `switch-to-prev-buffer' is superior to any
`switch-to-buffer' changing solution. Notwithstanding Lars' argument
that people are used to C-x b, tell me why `switch-to-prev-buffer'
(combined with `switch-to-next-buffer') doesn't do what you want.
> The problem with today's "existing-window" behavior is that if you
> have window T displaying buffer B on frame F at buffer position P,
> then you can not sustain a *persistent* working location P' in any
> other window U on F. By "persistent", I specifically mean that in
> window U, if I switch temporarily away to another buffer and then
> back, I want to go back to P'. Today it takes me to P: I have lost
> my working location in U.
Not with `switch-to-prev-buffer' ;-)
> I have long found this behavior most unfortunate. Ironically, the
> best workaround is to visit B in window X on a second frame G.
> Then no matter what happens to the window configuration in F,
> X will retain its window point at your second working location P'.
>
> Trying to work around it within F requires that you disturb your
> window configuration, or attempt to track your working locations
> with the mark ring, or some other relatively unnatural workflow.
> At least, I find it unnatural compared to my desired workflow:
>
> - open a window T and display buffer B at position Pt
> - in window U switch to buffer B (it defaults to Pt, which is fine)
> - then in U:
> * move to a different position Pu in B
> * switch to any other buffer C (e.g. Info, shell, ...)
> * switch back to buffer B
This should be `switch-to-prev-buffer'.
> * continue working at Pu
>
> This workflow, which I think of as "persistent window positions",
> would actually be closest to how Emacs works in the most
> common use case of all: single-frame, single-window. If you are
> visiting B at position P, and you switch away, then back, you will
> return to P. It is easy to think of this as the window remembering
> where you last were in B. If you think of it this way, as I do, then
> you are constantly surprised that windows suffer from amnesia
> whenever more than one of them is displaying the same buffer.
> It feels to me that they should behave as if they are independent.
>
> Thus I would be happiest if there were an option such that every
> window tracks the buffer positions of every buffer that it visits,
You can get these positions via `window-prev-buffers'.
> and when switching back to a buffer B that it has already visited,
> each window displays B at the same position it last displayed B.
>
> If you kill a window, its position list goes away. New windows
> would start with a nil position list, and the first time they visit a
> buffer they would use the "existing-window" semantics: use
> the position of the next window currently displaying the buffer,
> or else point-min. (It might be confusing to have them choose
> from the position-list of a window that has previously visited
> the buffer but is not currently displaying it, so I'd not do that.)
>
> Similarly if you kill a buffer, then it is removed from the position
> lists for all existing windows. If it is recreated, e.g. by opening
> the file again for file buffers, all windows would initially begin
> viewing it at point-min.
>
> I think "per-window visited-buffer last-position lists" would solve
> the multi-frame problem (4041). I believe they would also
> clean up the IMO rather unfortunate existing semantics for
> same-buffer, same-frame, multiple windows, since the current
> behavior (a) doesn't parallel the current single-frame, single
> window behavior, and (b) doesn't allow for multiple temporary
> "persistent" working locations in multiple windows in a single
> buffer on a single frame.
>
> At the very least it'd be a nice global configuration option.
> I'm sure you could probably do all this with a package, but
> it's fairly fundamental -- it would be nice, for example, to be
> able to enable it by setting a single variable on someone
> else's Emacs instance while debugging something for them.
>
> I have done an exhaustive survey of everyone sitting near
> me right now, and they both agreed that buffer positions
> should be "window-local", and that they've been annoyed
> by it forever as well. Just wanted to cover my bases! ;)
All this has been implemented - see section 28.14 Window History in the
Elisp manual. If you still insist on having C-x b return to the
previous position, try the definition below.
martin
(defun switch-to-buffer (buffer-or-name &optional norecord force-same-window)
"Switch to buffer BUFFER-OR-NAME in the selected window.
If called interactively, prompt for the buffer name using the
minibuffer. The variable `confirm-nonexistent-file-or-buffer'
determines whether to request confirmation before creating a new
buffer.
BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
nil. If BUFFER-OR-NAME is a string that does not identify an
existing buffer, create a buffer with that name. If
BUFFER-OR-NAME is nil, switch to the buffer returned by
`other-buffer'.
Optional argument NORECORD non-nil means do not put the buffer
specified by BUFFER-OR-NAME at the front of the buffer list and
do not make the window displaying it the most recently selected
one.
If FORCE-SAME-WINDOW is non-nil, BUFFER-OR-NAME must be displayed
in the selected window; signal an error if that is
impossible (e.g. if the selected window is minibuffer-only). If
nil, BUFFER-OR-NAME may be displayed in another window.
Return the buffer switched to."
(interactive
(list (read-buffer-to-switch "Switch to buffer: ") nil t))
(let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
(if (null force-same-window)
(pop-to-buffer buffer display-buffer--same-window-action norecord)
(cond
;; Don't call set-window-buffer if it's not needed since it
;; might signal an error (e.g. if the window is dedicated).
((eq buffer (window-buffer)))
((window-minibuffer-p)
(error "Cannot switch buffers in minibuffer window"))
((eq (window-dedicated-p) t)
(error "Cannot switch buffers in a dedicated window"))
(t
(let* ((entry (and (get-buffer-window buffer 0)
(assq buffer (window-prev-buffers))))
(start (and entry (nth 1 entry)))
(pos (and entry (nth 2 entry))))
(set-window-buffer nil buffer)
(when entry
;; If BUFFER-OR-NAME (1) was shown in the selected window
;; before and (2) is currently displayed in some other
;; visible window, try to restore start and point of buffer
;; in the selected window.
(set-window-start (selected-window) start t)
(set-window-point-1 nil pos)))))
(unless norecord
(select-window (selected-window)))
(set-buffer buffer))))
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, Lars Magne Ingebrigtsen, 2011/10/06
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, martin rudalics, 2011/10/07
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, Lars Magne Ingebrigtsen, 2011/10/07
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, martin rudalics, 2011/10/07
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, Steve Yegge, 2011/10/07
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, Leo, 2011/10/08
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, Eli Zaretskii, 2011/10/08
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, Drew Adams, 2011/10/08
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local,
martin rudalics <=
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, Eli Zaretskii, 2011/10/08
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, martin rudalics, 2011/10/08
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, Eli Zaretskii, 2011/10/08
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, martin rudalics, 2011/10/08
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, Eli Zaretskii, 2011/10/08
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, martin rudalics, 2011/10/08
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, Eli Zaretskii, 2011/10/08
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, martin rudalics, 2011/10/09
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, Eli Zaretskii, 2011/10/09
- bug#4041: 23.0.92; Emacs 23: buffer point is no longer frame-local, martin rudalics, 2011/10/10