Subject: 29.0.50; narrow-to-region induces buffer recentering

From: Jose A Ortega Ruiz <[email-masked]>
Date: Thu, 20 Jan 2022 20:59:25 +0000

Hi,

I've observed this behaviour in both emacs 28 and 29 when using
message-mode's message-kill-to-signature:

  - start composing a message, e.g. a reply, so that the current window
    shows only a portion of the buffer, and not the signature

  - with point somewhere on the lower half of the window, C-c C-z
    (message-kill-to-signature)

  - the text from point to signature is deleted alright, but the buffer
    contents is recentered, as if one had invoked recenter /twice/, so
    the window gets scrolled up.  previous behaviour was that the window
    wouldn't scroll at all, one would just see the contents of the
    buffer below point change (and show the signature).

The body of message-kill-to-signature is simple, and i've observed that
if one comments out the narrow-to-region invocation marked below, the
effect disappears:

       (defun message-kill-to-signature (&optional arg)
          "Kill all text up to the signature.
        If a numeric argument or prefix arg is given, leave that number
        of lines before the signature intact."
          (interactive "P" message-mode)
          (save-excursion
            (save-restriction
              (let ((point (point)))
        	(narrow-to-region point (point-max))  ;;;;;; <------------------------
        	(message-goto-signature)
        	(unless (eobp)
        	  (if (and arg (numberp arg))
        	      (forward-line (- -1 arg))
        	    (end-of-line -1)))
        	(unless (= point (point))
        	  (kill-region point (point))
        	  (unless (bolp)
        	    (insert "\n")))))))

so i am (wild) guessing that the spurious recenter might be related with
save-restriction workings in combination with narrow, but i don't really
know what i'm talking about :)

The only variable related to scroll i can see changed from its default
value in my config is scroll-preserve-screen-position, which i set to
'always, but changing its value doesn't affect the behaviour above in
any way.
            
Thanks,
jao

In GNU Emacs 29.0.50 (build 10, x86_64-pc-linux-gnu, cairo version 1.16.0)
 of 2022-01-20 built on rivendell
Repository revision: 172c055745b1eb32def7be8ddcaae975996a789f
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12014000
System Description: Debian GNU/Linux bookworm/sid

Configured using:
 'configure --prefix=/usr/local/stow/emacs --with-x-toolkit=no
 --with-imagemagick'

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ
IMAGEMAGICK JPEG JSON LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2
M17N_FLT MODULES NOTIFY INOTIFY OLDXMENU PDUMPER PNG RSVG SECCOMP SOUND
THREADS TIFF X11 XDBE XIM XPM ZLIB

Important settings:
  value of $LANG: en_GB.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Lisp Interaction

Minor modes in effect:
  global-git-commit-mode: t
  magit-auto-revert-mode: t
  semantic-minor-modes-format: ((:eval (if (or semantic-highlight-edits-mode semantic-show-unmatched-syntax-mode)  S)))
  circe-lagmon-mode: t
  telega-root-auto-fill-mode: t
  telega-active-locations-mode: t
  telega-patrons-mode: t
  telega-mode-line-mode: t
  global-diff-hl-mode: t
  eshell-syntax-highlighting-global-mode: t
  pdf-occur-global-minor-mode: t
  shell-dirtrack-mode: t
  winner-mode: t
  global-auto-revert-mode: t
  corfu-global-mode: t
  corfu-mode: t
  marginalia-mode: t
  vertico-mode: t
  persistent-scratch-autosave-mode: t
  global-so-long-mode: t
  display-battery-mode: t
  minibuffer-electric-default-mode: t
  minibuffer-depth-indicate-mode: t
  repeat-mode: t
  savehist-mode: t
  recentf-mode: t
  save-place-mode: t
  override-global-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  column-number-mode: t

Load-path shadows:
/home/jao/lib/elisp/org-static-blog/org-static-blog hides /home/jao/.emacs.d/elpa.29/org-static-blog-20220110.739/org-static-blog
/home/jao/etc/emacs/site/custom hides /usr/local/stow/emacs/share/emacs/29.0.50/lisp/custom
/home/jao/.emacs.d/elpa.29/transient-20220117.1122/transient hides /usr/local/stow/emacs/share/emacs/29.0.50/lisp/transient

Features:
(shadow sort mailalias bbdb-message mail-extr quail vc-mtn vc-hg vc-bzr
vc-src vc-sccs vc-svn vc-cvs vc-rcs forge-list forge-commands forge-semi
forge-bitbucket buck forge-gogs gogs forge-gitea gtea forge-gitlab glab
forge-github ghub-graphql treepy gsexp ghub forge-notify forge-revnote
forge-pullreq forge-issue forge-topic yaml bug-reference forge-post
forge-repo forge forge-core forge-db closql emacsql-sqlite emacsql
emacsql-compiler magit-bookmark magit-submodule magit-obsolete
magit-blame magit-stash magit-reflog magit-bisect magit-push magit-pull
magit-fetch magit-clone magit-remote magit-commit magit-sequence
magit-notes magit-worktree magit-tag magit-merge magit-branch
magit-reset magit-files magit-refs magit-status magit magit-repos
magit-apply magit-wip magit-log which-func magit-diff smerge-mode diff
git-commit log-edit add-log magit-core magit-autorevert magit-margin
magit-transient magit-process with-editor magit-mode magit-git
magit-section magit-utils pulse cl-print misearch multi-isearch
bash-completion em-unix em-script em-prompt em-ls em-hist em-pred
em-glob em-cmpl em-basic em-banner goto-chg multisession sqlite
tramp-cmds executable copyright shortdoc shr-color url-file url-dired
url-http url-gw url-cache url-auth vertico-directory textsec uni-scripts
idna-mapping ucs-normalize uni-confusable textsec-check org-duration
org-agenda cal-iso cal-move mule-util emojify apropos tar-mode arc-mode
archive-mode ht network-stream circe-display-images circe-lagmon
lui-track circe lui-irc-colors irc lcs lui-logging lui-format
circe-compat slack slack-company slack-unread slack-websocket
slack-thread-event slack-room-event slack-star-event
slack-reaction-event slack-reply-event slack-typing slack-slash-commands
slack-message-event slack-event slack-dialog-edit-element-buffer
slack-dialog-buffer slack-dialog slack-stars-buffer
slack-search-result-buffer slack-thread-message-compose-buffer
slack-file-list-buffer slack-file-info-buffer slack-all-threads-buffer
slack-message-buffer slack-user-profile-buffer slack-pinned-items-buffer
slack-pinned-item slack-thread-message-buffer slack-room-info-buffer
slack-room-buffer slack-message-share-buffer slack-message-edit-buffer
slack-room-message-compose-buffer slack-message-compose-buffer
slack-message-attachment-preview-buffer slack-action slack-star
slack-reminder slack-search slack-message-reaction slack-message-editor
slack-message-sender slack-message-notification slack-buffer
slack-message-formatter slack-thread slack-im slack-channel slack-group
slack-conversations slack-create-message slack-attachment
slack-selectable slack-bot-message slack-user-message slack-file
slack-message slack-message-faces slack-unescape slack-block
slack-mrkdwn slack-usergroup slack-reaction slack-modeline slack-room
slack-counts slack-user slack-bot slack-dnd-status slack-emoji
slack-image slack-request slack-log request lui flyspell ispell
slack-team slack-team-ws slack-util websocket exwm-systemtray
xcb-systemtray xcb-xembed exwm-edit exwm exwm-input xcb-keysyms xcb-xkb
exwm-manage exwm-floating xcb-cursor xcb-render exwm-layout
exwm-workspace exwm-core xcb-ewmh xcb-icccm xcb xcb-xproto xcb-types
xcb-debug paredit display-fill-column-indicator smartscan org-appear
cdlatex texmathp image-file image-converter bigml bml-logs bml bml-misc
bml-whizzml bml-clojure bml-clj-tests bml-python bml-skels bml-utils
whizzml-skeletons skeleton whizzml-mode lice sieve sieve-mode
sieve-manage sasl sasl-anonymous sasl-login sasl-plain jao-mpc
jao-random-album jao-lyrics jao-spt jao-mpris consult-spotify espotify
telega-obsolete telega telega-tdlib-events telega-webpage
visual-fill-column telega-root telega-info telega-chat telega-modes
telega-company telega-user telega-notifications telega-voip telega-msg
telega-tme telega-sticker telega-i18n telega-vvnote bindat telega-ffplay
telega-media telega-sort telega-filter telega-ins telega-folders
telega-inline telega-tdlib telega-util rainbow-identifiers dired-aux
telega-server telega-core cursor-sensor telega-customize emacsbug
sendmail jao-mullvad bluetooth json-mode json-snatcher js cc-mode
cc-fonts cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars
cc-defs virtualenvwrapper gud ediprolog haskell-doc inf-haskell
haskell-decl-scan haskell haskell-completions haskell-load
haskell-commands highlight-uses-mode haskell-modules haskell-sandbox
haskell-navigate-imports haskell-repl haskell-svg haskell-collapse
hideshow haskell-debug haskell-interactive-mode
haskell-presentation-mode haskell-compile haskell-hoogle haskell-process
haskell-session haskell-mode haskell-cabal haskell-utils
haskell-font-lock haskell-indentation haskell-string
haskell-sort-imports haskell-lexeme haskell-align-imports
haskell-complete-module haskell-ghc-support flymake-proc flymake
warnings dabbrev haskell-customize pie geiser-guile info-look
geiser-repl geiser-compile geiser-debug geiser-image geiser-company
geiser-doc geiser-menu geiser-edit etags fileloop xref project
geiser-completion geiser-autodoc geiser-eval geiser-connection
geiser-syntax scheme geiser-impl help-fns radix-tree geiser-log
geiser-popup view geiser-custom geiser-base geiser package-lint finder
lisp-mnt edit-list git-modes gitignore-mode gitconfig-mode conf-mode
gitattributes-mode git-link git-timemachine diff-hl log-view pcvs-util
vc-dir ewoc vc jao-eshell-here eshell-autojump em-dirs esh-var eshell-up
git-ps1-mode em-term eshell-syntax-highlighting em-alias vterm
face-remap term disp-table ehelp vterm-module term/xterm xterm
saveplace-pdf-view pdf-occur ibuf-ext ibuffer ibuffer-loaddefs tablist
tablist-filter semantic/wisent/comp semantic/wisent
semantic/wisent/wisent semantic/util-modes semantic/util semantic
semantic/tag semantic/lex semantic/fw mode-local cedet pdf-isearch
pdf-misc consult-notmuch org-capture org-refile jao-notmuch notmuch
notmuch-tree notmuch-jump notmuch-hello notmuch-show notmuch-print
notmuch-crypto notmuch-mua notmuch-message notmuch-draft
notmuch-maildir-fcc notmuch-address notmuch-company notmuch-parser
notmuch-wash coolj notmuch-query goto-addr icalendar notmuch-tag
notmuch-lib notmuch-version notmuch-compat pcase hl-line bbdb-anniv
bbdb-com crm bbdb bbdb-site timezone randomsig socks gnutls nsm elpher
jao-eww-session markdown-toc dash s markdown-mode htmlize jao-org-links
jao-maildir jao-doc-view let-alist pdf-tools pdf-view pdf-cache pdf-info
tq pdf-util pdf-macs ol-eshell esh-mode eshell esh-cmd esh-ext esh-opt
esh-proc esh-io esh-arg esh-module esh-groups esh-util jao-org-notes
ob-shell ob-scheme ob-python python tramp-sh tramp tramp-loaddefs
trampver tramp-integration files-x tramp-compat shell ls-lisp ob-org
ob-ocaml ob-makefile ob-haskell ob-gnuplot ob-clojure ob-calc calc-store
calc-trail calc-ext calc calc-loaddefs rect calc-macs ob-prolog prolog
smie align org-tempo tempo ox-texinfo ox-latex ox-html table ox-ascii
ox-publish ox org-fragtog jao-afio winner autorevert filenotify
autoinsert embark-consult embark ffap consult-recoll jao-compilation
consult-vertico consult bookmark corfu marginalia mct vertico orderless
imenu find-dired dired-x wgrep grep compile persistent-scratch so-long
cal-china lunar solar cal-dst cal-bahai cal-islam cal-hebrew holidays
hol-loaddefs appt diary-lib diary-loaddefs jao-tracking tracking shorten
jao-notify alert log4e notifications gntp battery time jao-minibuffer
minibuf-eldef mb-depth jao-recoll diminish jao-light-theme jao-themes
pinentry epa-file transient cus-edit pp cus-load repeat edmacro kmacro
jao-sleep server savehist recentf tree-widget saveplace
gnu-elpa-keyring-update use-package use-package-ensure
use-package-delight use-package-diminish use-package-bind-key bind-key
use-package-core vc-git diff-mode vc-dispatcher org-element avl-tree
generator ol-eww eww xdg url-queue thingatpt mm-url ol-rmail ol-mhe
ol-irc ol-info ol-gnus nnselect gnus-search eieio-opt speedbar ezimage
dframe gnus-art mm-uu mml2015 mm-view mml-smime smime dig gnus-sum shr
pixel-fill kinsoku svg dom gnus-group gnus-undo gnus-start gnus-dbus
dbus xml gnus-cloud nnimap nnmail mail-source utf7 netrc nnoo parse-time
gnus-spec gnus-int gnus-range message yank-media rmc puny rfc822 mml
mml-sec epa epg rfc6068 epg-config mm-decode mm-bodies mm-encode
mail-parse rfc2231 rfc2047 rfc2045 ietf-drums mailabbrev gmm-utils
mailheader gnus-win gnus nnheader gnus-util text-property-search
mail-utils range mm-util mail-prsvr ol-docview doc-view jka-compr
image-mode exif dired dired-loaddefs ol-bibtex ol-bbdb ol-w3m ol-doi
org-link-doi poly-org polymode derived poly-lock polymode-base
polymode-weave polymode-export polymode-compat polymode-methods
polymode-core polymode-classes eieio-custom wid-edit eieio-base color
cl-extra help-mode org ob ob-tangle ob-ref ob-lob ob-table ob-exp
org-macro org-footnote org-src ob-comint org-pcomplete pcomplete comint
ansi-color ring org-list org-faces org-entities noutline outline
easy-mmode org-version ob-emacs-lisp ob-core ob-eval org-table oc-basic
bibtex iso8601 time-date ol org-keys oc org-compat advice org-macs
org-loaddefs format-spec find-func cal-menu calendar cal-loaddefs
finder-inf tex-site rx info package browse-url url url-proxy url-privacy
url-expand url-methods url-history url-cookie url-domsuf url-util
mailcap url-handlers url-parse auth-source cl-seq eieio eieio-core
cl-macs eieio-loaddefs password-cache json map url-vars seq gv subr-x
byte-opt bytecomp byte-compile cconv cl-loaddefs cl-lib iso-transl
tooltip 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 cl-generic
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 simple abbrev obarray
cl-preloaded nadvice button 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 multi-tty make-network-process emacs)

Memory information:
((conses 16 2087812 408191)
 (symbols 48 96469 59)
 (strings 32 520835 48015)
 (string-bytes 1 15883545)
 (vectors 16 231351)
 (vector-slots 8 6850024 212937)
 (floats 8 11233 1944)
 (intervals 56 114191 23112)
 (buffers 992 88))

-- 
He who joyfully marches to music in rank and file has already earned
my contempt. He has been given a large brain by mistake, since for him
the spinal cord would suffice.
 -Albert Einstein