Subject: bug#79241: 31.0.50; `vertical-motion' not respecting goal column when there is an overlay that spans multiple virtual lines

From: Sergio Pastor Pérez <[email-masked]>
Date: Fri, 15 Aug 2025 10:31:29 +0200

The issue is that `vertical-motion' does not seem to respect goal column
when moving upwards through an overlay that spans multiple visual lines.

I will give a recipe using the latest version of Flymake, since it's an
easy way to generate an overlay that spawns multiple visual lines, but I
suspect that this issue can be reproduced with any overlay of those
characteristics, and is not a particual issue of Flymake. I've tried to
debug the line movement code but at some point I reached
`vertical-motion', which is a C function, so I didn't debug it further.
Invoking: `(vertical-motion '(0.0 . -1))' is enough to see the behavior
described.

1) Install Flymake v1.4.1. (I used Elpaca)
2) `(setq flymake-show-diagnostics-at-end-of-line 'fancy)`
3) Go to a buffer where diagnostic will show, I used Eglot for this.
4) Put the cursor a the beginning of the line prior to the overlay
generated by Flymake. Notice that when using the `'fancy' setting, the
message will span across multiple visual lines.
5) Try to move upwards, towards the diagnostic. We expect the cursor to
remain at the beggining of the line but instead, it goes to the end of
the line. This behavior does not happen when moving downwards through
the diagnostic message.
The issue is that `vertical-motion' does not seem to respect goal column
when moving upwards through an overlay that spans multiple visual lines.

I will give a recipe using the latest version of Flymake, since it's an
easy way to generate an overlay that spawns multiple visual lines, but I
suspect that this issue can be reproduced with any overlay of those
characteristics and is not a particular issue of Flymake. I've tried to
debug the line movement code but at some point I reached
`vertical-motion' which is a C function so I cannot debug it further.
Invoking: `(vertical-motion '(0.0 . -1))' is enough to see the behavior
described.

1) Install Flymake v1.4.1. (I used Elpaca)
2) `(setq flymake-show-diagnostics-at-end-of-line 'fancy)`
3) Go to a buffer where diagnostic will show, I used Eglot for this.
4) Put the cursor a the beginning of the line prior to the overlay
generated by Flymake. Notice that when using the `'fancy' setting, the
message will span across multiple visual lines.
5) Try to move upwords, towards the diagnostic. We expect the cursor to
remain at the beginning of the line but instead, it goes to the end of
the line. This behavior does not happen when moving downwards through
the diagnostic message.

In GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version
3.24.43, cairo version 1.18.4)
System Description: Guix System

Configured using:
 'configure
 CONFIG_SHELL=/gnu/store/nnx8iifrj6jfih4sivivq17cf65aa968-bash-minimal-5.2.37/bin/bash
 SHELL=/gnu/store/nnx8iifrj6jfih4sivivq17cf65aa968-bash-minimal-5.2.37/bin/bash
 --prefix=/gnu/store/g1rsgv58jnqpy6q2rnhy7xzqvpjks2f4-emacs-next-pgtk-31.0.50-1.9663c95
 --enable-fast-install --with-pgtk --with-cairo --with-modules
 --with-native-compilation=aot 'CFLAGS=-g -O2
 -Wno-error=incompatible-pointer-types' --disable-build-details'

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 MODULES NATIVE_COMP NOTIFY
INOTIFY PDUMPER PGTK PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS TREE_SITTER WEBP XIM GTK3 ZLIB

Important settings:
  value of $EMACSLOADPATH: /home/pastor/.guix-home/profile/share/emacs/site-lisp:/home/pastor/.guix-home/profile/share/emacs/site-lisp:/run/current-system/profile/share/emacs/site-lisp:/gnu/store/g1rsgv58jnqpy6q2rnhy7xzqvpjks2f4-emacs-next-pgtk-31.0.50-1.9663c95/share/emacs/31.0.50/lisp
  value of $EMACSNATIVELOADPATH: /home/pastor/.guix-home/profile/lib/emacs/native-site-lisp:/home/pastor/.guix-home/profile/lib/emacs/native-site-lisp
  value of $LANG: en_US.utf8
  locale-coding-system: utf-8-unix

Major mode: C++//l

Minor modes in effect:
  eglot--managed-mode: t
  flymake-mode: t
  elpaca-use-package-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
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  minibuffer-regexp-mode: 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
  abbrev-mode: t

Load-path shadows:
/home/pastor/.guix-home/profile/share/emacs/site-lisp/guix-emacs hides /run/current-system/profile/share/emacs/site-lisp/guix-emacs
/home/pastor/.guix-home/profile/share/emacs/site-lisp/site-start hides /run/current-system/profile/share/emacs/site-lisp/site-start
/home/pastor/.emacs.d/elpaca/builds/flymake/flymake hides /gnu/store/g1rsgv58jnqpy6q2rnhy7xzqvpjks2f4-emacs-next-pgtk-31.0.50-1.9663c95/share/emacs/31.0.50/lisp/progmodes/flymake
/gnu/store/1i3864529l6ckl45kc80b2y72wfigf6m-emacs-compat-30.0.2.0/share/emacs/site-lisp/compat-30.0.2.0/compat hides /gnu/store/g1rsgv58jnqpy6q2rnhy7xzqvpjks2f4-emacs-next-pgtk-31.0.50-1.9663c95/share/emacs/31.0.50/lisp/emacs-lisp/compat

Features:
(shadow sort mail-extr info emacsbug lisp-mnt message yank-media puny
dired dired-loaddefs rfc822 mml mml-sec epa derived epg rfc6068
epg-config gnus-util mm-decode mm-bodies mm-encode mail-parse rfc2231
mailabbrev gmm-utils mailheader sendmail rfc2047 rfc2045 ietf-drums
mm-util mail-prsvr mail-utils rect cl-extra eglot tree-widget wid-edit
external-completion jsonrpc xref flymake thingatpt project diff ert pp
ewoc debug backtrace find-func filenotify compile text-property-search
pcase imenu cc-mode cc-fonts cc-guess cc-menus cc-cmds cc-styles
cc-align cc-engine cc-vars cc-defs misearch multi-isearch
flymake-autoloads tramp-archive tramp-gvfs dbus xml tramp trampver
tramp-integration tramp-message help-mode tramp-compat xdg shell
pcomplete comint ansi-osc ring parse-time iso8601 time-date format-spec
ansi-color tramp-loaddefs elpaca-menu-elpa no-littering compat
no-littering-autoloads elpaca-menu-melpa elpaca-menu-org
elpaca-use-package use-package use-package-ensure use-package-delight
use-package-diminish use-package-bind-key bind-key use-package-core
elpaca-use-package-autoloads hl-line display-line-numbers elpaca-log
elpaca-ui url url-proxy url-privacy url-expand url-methods url-history
url-cookie generate-lisp-file url-domsuf url-util url-parse auth-source
eieio eieio-core cl-macs password-cache json subr-x map byte-opt gv
bytecomp byte-compile url-vars mailcap cl-seq elpaca warnings icons
elpaca-process elpaca-autoloads vc-git diff-mode track-changes
easy-mmode files-x vc-dispatcher cl-loaddefs cl-lib
magit-popup-autoloads geiser-guile-autoloads edit-indirect-autoloads
bui-autoloads guix-autoloads rx stgit-autoloads
page-break-lines-autoloads dashboard-autoloads memoize-autoloads
dash-autoloads s-autoloads f-autoloads all-the-icons-autoloads
log4e-autoloads gntp-autoloads alert-autoloads telega-contrib-autoloads
rainbow-identifiers-autoloads visual-fill-column-autoloads
telega-autoloads consult-autoloads consult-notmuch-autoloads
notmuch-indicator-autoloads notmuch-autoloads compat-autoloads
jinx-autoloads tablist-autoloads pdf-tools-autoloads company-autoloads
geiser-autoloads vterm-git.f76de08-autoloads guix-emacs rmc iso-transl
tooltip cconv eldoc paren electric uniquify ediff-hook vc-hooks
lisp-float-type elisp-mode mwheel term/pgtk-win pgtk-win term/common-win
touch-screen pgtk-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 dynamic-setting system-font-setting
font-render-setting cairo gtk pgtk lcms2 multi-tty move-toolbar
make-network-process tty-child-frames native-compile emacs)

Memory information:
((conses 16 505081 51672) (symbols 48 23934 48)
 (strings 32 216943 3808) (string-bytes 1 4504841) (vectors 16 35040)
 (vector-slots 8 447974 25893) (floats 8 76 879)
 (intervals 56 2253 176) (buffers 992 26))