Subject: 30.1.50; ibuffer - preserve window position when updating

From: Daniel Mendler <[email-masked]>
Date: Sun, 23 Mar 2025 17:38:53 +0100

Ibuffer updates its buffer content after actions on the buffers, when
the buffer list changes if `ibuffer-auto-mode' is enabled, or when
pressing "g", which invokes `ibuffer-update'.

The buffer update leads to movement of the window point and window start
position. In particular if the buffer list has many buffers, such that
the list does not fit into the window, the Ibuffer content jumps after
an update.

Right now I use the following advice which tries to preserve the window
position and tries to prevent the jumping during an update:

  (advice-add #'ibuffer-redisplay-engine :around #'ibuffer-preserve-position)
  (defun ibuffer-preserve-position (&rest app)
    (if-let ((buf (get-buffer "*Ibuffer*")))
        (let (restore)
          (dolist (win (get-buffer-window-list buf))
            (let ((pt (window-point win))
                  (start (window-start win)))
              (push (lambda ()
                      (when (eq buf (window-buffer win))
                        (set-window-buffer-start-and-point win buf start pt)))
                    restore)))
          (let ((pt (with-current-buffer buf (point))))
            (push (lambda () (with-current-buffer buf (goto-char pt)))
                  restore))
          (prog1 (apply app)
            (mapc #'funcall restore)))
      (apply app)))

The advice works in most cases, for example when killing buffers from
inside Ibuffer or from somewhere else. When selecting a buffer the
Ibuffer window content still moves. Is there a better way to preserve
the content position of Ibuffer than the given advice?

I would like to provide a patch to `ibuffer-redisplay-engine' (or to
`ibuffer-update' or `ibuffer-redisplay') which improves the update such
that the window content does not move. Any suggestions welcome. Thank
you!

In GNU Emacs 30.1.50 (build 1, x86_64-pc-linux-gnu, X toolkit, cairo
 version 1.18.4) of 2025-03-20
Windowing system distributor 'The X.Org Foundation', version 11.0.12101016
System Description: Debian GNU/Linux trixie/sid

Configured using:
 'configure --with-tree-sitter
 --with-native-compilation --with-x-toolkit=athena --with-dbus
 --without-toolkit-scroll-bars --without-selinux --without-threads
 --without-gsettings --without-gpm --with-cairo --with-cairo-xcb
 --disable-gc-mark-trace --with-xinput2'

Configured features:
CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS HARFBUZZ JPEG LIBOTF LIBSYSTEMD
LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP
SOUND SQLITE3 TIFF TREE_SITTER WEBP X11 XDBE XIM XINPUT2 XPM LUCID ZLIB