]> code.delx.au - gnu-emacs/commitdiff
Fix vertical cursor motion across overlay strings with newlines
authorEli Zaretskii <eliz@gnu.org>
Sun, 13 Sep 2015 10:15:55 +0000 (13:15 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sun, 13 Sep 2015 10:15:55 +0000 (13:15 +0300)
* src/indent.c (Fvertical_motion): Don't leave point in the middle
of an overlay string with newlines, as that will position the
cursor after the string at whatever column is there.  (Bug#21468)

src/indent.c

index 7e8f0a573a30c5c76de54d01ec69cc599aa9079f..777cd36cc52191da3b3b705cff0606c53b123063 100644 (file)
@@ -2195,7 +2195,30 @@ whether or not it is currently displayed in some window.  */)
         was originally hscrolled, the goal column is interpreted as
         an addition to the hscroll amount.  */
       if (lcols_given)
-       move_it_in_display_line (&it, ZV, first_x + to_x, MOVE_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,
+            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.method == GET_FROM_STRING
+             && !it.string_from_display_prop_p
+             && 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);
+                 move_it_in_display_line (&it, ZV, first_x + to_x, MOVE_TO_X);
+               }
+           }
+       }
 
       SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
       bidi_unshelve_cache (itdata, 0);