GNU bug report logs - #64911
30.0.50; switch-to-buffer-preserve-window-point not respected by switch-to-(next|prev)-buffer

Previous Next

Package: emacs;

Reported by: Phil Sainty <psainty <at> orcon.net.nz>

Date: Fri, 28 Jul 2023 05:26:01 UTC

Severity: normal

Found in version 30.0.50

To reply to this bug, email your comments to 64911 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#64911; Package emacs. (Fri, 28 Jul 2023 05:26:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Phil Sainty <psainty <at> orcon.net.nz>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Fri, 28 Jul 2023 05:26:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Phil Sainty <psainty <at> orcon.net.nz>
To: bug-gnu-emacs <at> gnu.org
Cc: Adam Porter <adam <at> alphapapa.net>
Subject: 30.0.50; switch-to-buffer-preserve-window-point not respected by
 switch-to-(next|prev)-buffer
Date: Fri, 28 Jul 2023 17:24:36 +1200
The `switch-to-buffer-preserve-window-point' variable determines
whether the (BUFFER WINDOW-START POS) data returned by
`window-prev-buffers' will be used by `switch-to-buffer' to set
the window's start and point positions.

I think this variable should additionally be respected by both:

- `switch-to-prev-buffer'
- `switch-to-next-buffer'

(If not others?  These are the cases I'm presently aware of.)

Each of the latter functions has two calls like this:

 (set-window-buffer-start-and-point
  window new-buffer (nth 1 entry) (nth 2 entry))

where `entry' comes from a call to `window-prev-buffers', and the
`switch-to-buffer-preserve-window-point' value is not checked in
any of those cases.

In practice this is a problem because the position stored in the
`window-prev-buffers' data is a marker (or at least that is the case
in the scenario I am dealing with), and the buffer in question is
periodically erased and regenerated.  Erasing the buffer causes all
its markers to be moved to position 1, so the end result is that the
user loses their place.  (The buffer contents are rebuilt, but the
new content is typically similar if not identical to the old content,
and so maintaining the original position is desirable).

Tangentially there is a similar case with `quit-window' where an
internal marker is set in (window-parameter WIN 'quit-restore) and
subject to the above issue whenever the buffer is erased.

In that instance, `display-buffer-record-window' does this:

 (set-window-parameter
  window 'quit-restore
  (list 'other
        ;; A quadruple of WINDOW's buffer, start, point and height.
        (list (current-buffer) (window-start window)
              ;; Preserve window-point-insertion-type (Bug#12855).
              (copy-marker
               (window-point window) window-point-insertion-type)
              (if (window-combined-p window)
                  (window-total-height window)
                (window-total-width window)))
        (selected-window) buffer)))

And `quit-restore-window' does this:

 ;; Restore WINDOW's previous buffer, start and point position.
 (set-window-buffer-start-and-point
  window (nth 0 quad) (nth 1 quad) (nth 2 quad))

This also doesn't test `switch-to-buffer-preserve-window-point' (or
anything similar), so the only way of circumventing this behaviour
that I can see is to clobber the marker with its own marker position
after it's been set.

I note that the cases above comprise the *only* standard calls
to `set-window-buffer-start-and-point'.

Maybe `set-window-buffer-start-and-point' itself should be
testing `switch-to-buffer-preserve-window-point' ?


-Phil




In GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, X toolkit, cairo
 version 1.16.0, Xaw scroll bars) of 2023-04-30 built on phil-lp
Repository revision: e03cfec0a455dd8c496d33c422c8edb9ac5a4005
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 
11.0.12101004
System Description: Ubuntu 22.04.2 LTS

Configured using:
 'configure --prefix=/home/phil/emacs/trunk/usr/local
 --with-x-toolkit=lucid --without-sound
 '--program-transform-name=s/^ctags$/ctags_emacs/''

Configured features:
CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG JSON
LCMS2 LIBSELINUX LIBXML2 MODULES NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP
THREADS TIFF TOOLKIT_SCROLL_BARS WEBP X11 XDBE XIM XINPUT2 XPM LUCID
ZLIB

Important settings:
  value of $LC_MONETARY: en_NZ.UTF-8
  value of $LC_NUMERIC: en_NZ.UTF-8
  value of $LC_TIME: en_NZ.UTF-8
  value of $LANG: en_GB.UTF-8
  value of $XMODIFIERS: @im=ibus
  locale-coding-system: utf-8-unix

Major mode: Help

Minor modes in effect:
  tooltip-mode: t
  global-eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  isearch-fold-quotes-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  buffer-read-only: t
  line-number-mode: t
  indent-tabs-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
None found.

Features:
(shadow sort mail-extr emacsbug message mailcap yank-media puny dired
dired-loaddefs rfc822 mml mml-sec password-cache epa derived epg rfc6068
epg-config gnus-util text-property-search time-date subr-x mm-decode
mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader
sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils
cl-extra cl-print byte-opt gv bytecomp byte-compile help-fns radix-tree
help-mode misearch multi-isearch vc-git diff-mode easy-mmode
vc-dispatcher jka-compr thingatpt cl-loaddefs cl-lib find-func rmc
iso-transl tooltip cconv eldoc paren electric uniquify ediff-hook
vc-hooks lisp-float-type elisp-mode mwheel term/x-win x-win
term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe
tabulated-list replace newcomment text-mode lisp-mode prog-mode register
page tab-bar menu-bar rfn-eshadow isearch easymenu timer select
scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors
frame minibuffer nadvice seq simple cl-generic indonesian philippine
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite emoji-zwj charscript
charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure
cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp
files window text-properties overlay sha1 md5 base64 format env
code-pages mule custom widget keymap hashtable-print-readable backquote
threads dbusbind inotify lcms2 dynamic-setting system-font-setting
font-render-setting cairo x-toolkit xinput2 x multi-tty
make-network-process emacs)

Memory information:
((conses 16 61926 21737)
 (symbols 48 6728 0)
 (strings 32 21712 1476)
 (string-bytes 1 576559)
 (vectors 16 12858)
 (vector-slots 8 183318 15975)
 (floats 8 32 45)
 (intervals 56 1270 0)
 (buffers 976 14))





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#64911; Package emacs. (Fri, 28 Jul 2023 07:12:03 GMT) Full text and rfc822 format available.

Message #8 received at 64911 <at> debbugs.gnu.org (full text, mbox):

From: Phil Sainty <psainty <at> orcon.net.nz>
To: 64911 <at> debbugs.gnu.org
Cc: Adam Porter <adam <at> alphapapa.net>
Subject: Re: bug#64911: 30.0.50; switch-to-buffer-preserve-window-point not
 respected by switch-to-(next|prev)-buffer
Date: Fri, 28 Jul 2023 19:11:07 +1200
Tangentially, I can't see any function for obtaining all the
markers for a given buffer.  I see that this has been raised
before as https://debbugs.gnu.org/cgi/bugreport.cgi?bug=35536

There's clearly resistance to implementing that, but... it
would be very useful for cases like the one I'm looking at.

Specifically, the code which is erasing the buffer and then
rebuilding it could firstly loop over the buffer markers, store
some kind of relevant context for each one and then, after
rebuilding the buffer, it could locate the equivalent context
in the new buffer text and update each of those markers
accordingly.

Without a way of querying the buffer's markers it's necessary
to just *know* about them and how to access them; and there's
no guarantee that new markers won't come into play behind the
scenes in future, so it would be useful to be able to access
the list without having to have advance information about how
and where they were being created.


-Phil





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#64911; Package emacs. (Fri, 28 Jul 2023 07:21:02 GMT) Full text and rfc822 format available.

Message #11 received at 64911 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Phil Sainty <psainty <at> orcon.net.nz>, martin rudalics <rudalics <at> gmx.at>
Cc: adam <at> alphapapa.net, 64911 <at> debbugs.gnu.org
Subject: Re: bug#64911: 30.0.50;
 switch-to-buffer-preserve-window-point not respected by
 switch-to-(next|prev)-buffer
Date: Fri, 28 Jul 2023 10:21:12 +0300
> Cc: Adam Porter <adam <at> alphapapa.net>
> Date: Fri, 28 Jul 2023 17:24:36 +1200
> From: Phil Sainty <psainty <at> orcon.net.nz>
> 
> The `switch-to-buffer-preserve-window-point' variable determines
> whether the (BUFFER WINDOW-START POS) data returned by
> `window-prev-buffers' will be used by `switch-to-buffer' to set
> the window's start and point positions.
> 
> I think this variable should additionally be respected by both:
> 
> - `switch-to-prev-buffer'
> - `switch-to-next-buffer'
> 
> (If not others?  These are the cases I'm presently aware of.)

Please provide a significant rationale for this change in behavior.

This option has proved problematic in quite a few cases since it was
introduced: see its uses in the Emacs tree as the evidence of the
subtle issues it introduces.  So I'm not excited with making it affect
even more use cases.  We need a sound rationale for such a change (and
no, "consistency" is not a sound rationale in my book), and we need to
try to audit all the calls to these functions in the tree to
understand and anticipate the impacts.

> In practice this is a problem because the position stored in the
> `window-prev-buffers' data is a marker (or at least that is the case
> in the scenario I am dealing with), and the buffer in question is
> periodically erased and regenerated.  Erasing the buffer causes all
> its markers to be moved to position 1, so the end result is that the
> user loses their place.  (The buffer contents are rebuilt, but the
> new content is typically similar if not identical to the old content,
> and so maintaining the original position is desirable).

This sounds like quite a unique use case to justify a global behavior
change of 2 commands.  Can't you achieve what you need by other means?
Stashing the value of point or window-point somewhere and then
restoring it doesn't sound too complicated to me.

Adding martin, in case he has comments and suggestions.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#64911; Package emacs. (Fri, 28 Jul 2023 11:04:01 GMT) Full text and rfc822 format available.

Message #14 received at 64911 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Phil Sainty <psainty <at> orcon.net.nz>
Cc: adam <at> alphapapa.net, 64911 <at> debbugs.gnu.org
Subject: Re: bug#64911: 30.0.50;
 switch-to-buffer-preserve-window-point not respected by
 switch-to-(next|prev)-buffer
Date: Fri, 28 Jul 2023 14:04:09 +0300
> Cc: Adam Porter <adam <at> alphapapa.net>
> Date: Fri, 28 Jul 2023 19:11:07 +1200
> From: Phil Sainty <psainty <at> orcon.net.nz>
> 
> Tangentially, I can't see any function for obtaining all the
> markers for a given buffer.  I see that this has been raised
> before as https://debbugs.gnu.org/cgi/bugreport.cgi?bug=35536
> 
> There's clearly resistance to implementing that, but... it
> would be very useful for cases like the one I'm looking at.
> 
> Specifically, the code which is erasing the buffer and then
> rebuilding it could firstly loop over the buffer markers, store
> some kind of relevant context for each one and then, after
> rebuilding the buffer, it could locate the equivalent context
> in the new buffer text and update each of those markers
> accordingly.

Why cannot you use replace-buffer-contents instead of erasing the
buffer and rebuilding it?  That function attempts to preserve the
markers.

> Without a way of querying the buffer's markers it's necessary
> to just *know* about them and how to access them; and there's
> no guarantee that new markers won't come into play behind the
> scenes in future, so it would be useful to be able to access
> the list without having to have advance information about how
> and where they were being created.

In general, when you rebuild the buffer's contents, there's no
guarantee the old buffers will be even useful.  What markers are we
talking about, besides window-point?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#64911; Package emacs. (Sat, 29 Jul 2023 08:09:01 GMT) Full text and rfc822 format available.

Message #17 received at 64911 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Eli Zaretskii <eliz <at> gnu.org>, Phil Sainty <psainty <at> orcon.net.nz>
Cc: adam <at> alphapapa.net, 64911 <at> debbugs.gnu.org
Subject: Re: bug#64911: 30.0.50; switch-to-buffer-preserve-window-point not
 respected by switch-to-(next|prev)-buffer
Date: Sat, 29 Jul 2023 10:08:17 +0200
>> In practice this is a problem because the position stored in the
>> `window-prev-buffers' data is a marker (or at least that is the case
>> in the scenario I am dealing with), and the buffer in question is
>> periodically erased and regenerated.  Erasing the buffer causes all
>> its markers to be moved to position 1, so the end result is that the
>> user loses their place.  (The buffer contents are rebuilt, but the
>> new content is typically similar if not identical to the old content,
>> and so maintaining the original position is desirable).
>
> This sounds like quite a unique use case to justify a global behavior
> change of 2 commands.  Can't you achieve what you need by other means?
> Stashing the value of point or window-point somewhere and then
> restoring it doesn't sound too complicated to me.
>
> Adding martin, in case he has comments and suggestions.

The only idea I have is to handle the "erased and regenerated" case by
invalidating the point markers.  IIUC this means that we have to first
identify the "erased and regenerated" case in 'after-change-functions'
and then use 'window-prev-buffers' to update the POS field of all
entries for that buffer in every window it has shown it.  We will miss
occurrences in saved window configurations if the associated window is
not live.

martin




This bug report was last modified 279 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.