summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2015-09-13 13:15:55 +0300
committerEli Zaretskii <eliz@gnu.org>2015-09-13 13:15:55 +0300
commit6514b30e6eb14e9d2364c08526dc8440a7412fef (patch)
treef6a1f9970c8cfdf786f25e682da4ccabfa956e60
parentfc9dc032906d840f63d29fbdcfd25e36ca3451b8 (diff)
downloademacs-6514b30e6eb14e9d2364c08526dc8440a7412fef.tar.gz
Fix vertical cursor motion across overlay strings with newlines
* 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)
-rw-r--r--src/indent.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/indent.c b/src/indent.c
index 7e8f0a573a3..777cd36cc52 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -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);