Subject: Re: bug#19200: Point adjustemnt moves *into* invisible text

From: Eli Zaretskii <[email-masked]>
Date: Mon, 21 Mar 2016 20:28:05 +0200

> From: Stefan Monnier <[email-masked]>
> Date: Mon, 21 Mar 2016 11:36:23 -0400
> Cc: [email-masked], Jonas Bernoulli <[email-masked]>
> 
> >> The way point-adjustment is defined is too conservative for that.
> >> So I suggest you try and make you code more robust w.r.t the position of
> >> point within an invisible region in any case.
> > Well, we just want that cursor movement starting from a visible position
> > not end up at an invisible position - the docs seem to suggest that this
> > should not happen, right?
> 
> It doesn't guarantee it in all cases, no.  E.g. it won't work if the
> command that moves point started/ended in another buffer, or if the
> command set disable-point-adjustment, plus a few other cases.
> 
> > We have the following, very simple situation:
> 
> > Line N
> > { M invisible lines here }
> > Line N+M+1
> 
> > Line N and Line N+M+1 are completely visible, and displayed after each
> > other.  Point is at the start of Line N, no invisible text near that
> > position.  Now I hit [down] one time and end up somewhere inside the
> > invisible text in between.
> 
> I agree it's a bug.  I'm just pointing out that even if we fix this bug,
> there will be other cases which ae not considered bugs where point will
> end up in the middle of the invisible text, and where it would be odd
> for your code to then operate on the selection at the "current line"
> since that's not the line that the user is actually seeing.
> 
> So, yes, point-adjustment needs to be fixed (this is bug#19200), but
> Magit also needs to be fixed anyway (and after that fix, it won't care
> about bug#19200 nearly as much, I think).

Can someone tell me why you think point adjustment has anything to do
with the original report for this bug?  Because I fail to see any
connection; maybe I'm missing something.

What I see is that vertical-motion, called by next-line's subroutines,
ends up at position 5, because when it tries to get to column zero, it
skips the invisible text between positions 3 and 5.  It stops at 5
because the function called to move to the goal column can only move
within a single display line.  IOW, this is a simple artifact of the
implementation of vertical-motion.

Michael, does the patch below fix the Magit problem?  (It does fix the
simple test case presented by Stefan at the beginning of this bug
report.)

diff --git a/src/indent.c b/src/indent.c
index d5162e3..e10b084 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -2222,7 +2222,8 @@ whether or not it is currently displayed in some window.  */)
 	 an addition to the hscroll amount.  */
       if (lcols_given)
 	{
-	  move_it_in_display_line (&it, ZV, first_x + to_x, MOVE_TO_X);
+	  if (it.current_x < first_x + to_x)
+	    move_it_in_display_line (&it, ZV, first_x + to_x, MOVE_TO_X);
 	  /* If we find ourselves in the middle of an overlay string
 	     which includes a newline after current string position,
 	     we need to move by lines until we get out of the string,