Subject: Re: bug#79241: [PATCH] WIP: Fix incorrect handling of overlays in `vertical-motion'

From: Sergio Pastor Pérez <[email-masked]>
Date: Tue, 19 Aug 2025 21:44:55 +0200

Hello!

I've debugged the `vertical-motion' procedure and found the troublesome
code. This patch solves the issue with the goal column, but it has 1
corner case to that I don't know how to solve.

Sergio Pastor Pérez <[email-masked]> writes:

> FIXME: if multiple lines with multi-line overlays are present, going
> upwards jumps to the first one of them, instead of the previous line at
> the right column.
>
> * src/indent.c (vertical-motion): Ensure multi-line overlay handling
> logic captures upward motions.
> ---
>  src/indent.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/src/indent.c b/src/indent.c
> index b4f3c349dc5..c1c32824dad 100644
> --- a/src/indent.c
> +++ b/src/indent.c
> @@ -2513,15 +2513,16 @@ line (if such column exists on that line, that is).  If the line is
>  	     and then reposition point at the requested X coordinate;
>  	     if we don't, the cursor will be placed just after the
>  	     string, which might not be the requested column.  */
> -	  if (nlines >= 0 && it.area == TEXT_AREA)
> +	  if (nlines != 0 && it.area == TEXT_AREA)
>  	    {
>  	      while (it.method == GET_FROM_STRING
> -		     && !it.string_from_display_prop_p
>  		     && memchr (SSDATA (it.string) + IT_STRING_BYTEPOS (it),
>  				'\n',
>  				SBYTES (it.string) - IT_STRING_BYTEPOS (it)))
>  		{
> -		  move_it_by_lines (&it, 1);
> +		  int direction = (nlines > 0) ? 1 : -1;
> +
> +		  move_it_by_lines (&it, direction);
>  		  move_it_in_display_line (&it, ZV, first_x + to_x, MOVE_TO_X);
>  		}

I don't know what primitives are available to break this loop once the
target line has been reached, so what seems to happen is that if there
are consecutive lines with multi-line overlays, one after the other,
this while loop keeps going until it reaches the first one of them. This
is only a problem for the upward motion. Since I did not find a
solution, I'm writing this mail in case there is someone more familiar
with the code, that knows how we could detect that the while loop should
finish in this particular case of consecutive lines with multi-line
overlays. In all other cases I've encountered, the patch seems to work
well.

>  	    }

Best regards,
Sergio