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

Previous Next

Package: emacs;

Reported by: Sergio Pastor Pérez <sergio.pastorperez <at> gmail.com>

Date: Fri, 15 Aug 2025 08:33:02 UTC

Severity: minor

Found in version 31.0.50

Full log


Message #16 received at 79241 <at> debbugs.gnu.org (full text, mbox):

From: Sergio Pastor Pérez <sergio.pastorperez <at> gmail.com>
To: 79241 <at> debbugs.gnu.org
Cc: Eli Zaretskii <eliz <at> gnu.org>
Subject: Re: bug#79241: [PATCH] WIP: Fix incorrect handling of overlays in
 `vertical-motion'
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 <sergio.pastorperez <at> gmail.com> 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




This bug report was last modified 4 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.