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

From: Eli Zaretskii <[email-masked]>
Date: Sat, 16 Aug 2025 09:50:57 +0300

severity 79241 minor
thanks

> 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.

Thanks.

The "beginning of the line" where the Flymake diagnostic is displayed
doesn't really exist in the buffer.  If you place point at the end of
the code line for which Flymake shows a diagnostic and then press C-f,
the cursor will jump over all the diagnostic string and land at the
beginning of the _following_ line.  This is expected, because Emacs
cannot place the cursor inside an overlay, not really.  Flymake
attempts to "fix" that by having the 'cursor' property on the
overlay's string, but that only works up to a point.

Overlay strings like this with embedded newlines cause a lot of
complexity and grief in vertical-motion's implementation, so I'm not
surprised that it behaves a bit strangely in this case.  The basic
requirement from vertical-motion in these cases is not to get stuck
around such lines, so that C-n and C-p work reasonably well and allow
movement through the buffer, and that does work in this case.

So from where I stand, this is a very minor annoyance, nothing more.
If someone wants to work on improving the behavior of vertical-motion
in these cases, and they do a clean job, such changes will be very
welcome, but failing that, I think the current behavior is far from a
catastrophe that needs immediate attention.