From 3811fdf3e8b65f39d6388768a3c9643fe293f7f1 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 7 Apr 2012 10:54:56 +0300 Subject: [PATCH] Fix bug #11133 with vertical-motion across a long display string. src/indent.c (Fvertical_motion): If there is a display string at point, use it.vpos to compute how many lines to backtrack after move_it_to point. --- src/ChangeLog | 6 ++++++ src/indent.c | 14 +++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index af65d38a33b..6bd946c0900 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2012-04-07 Eli Zaretskii + + * indent.c (Fvertical_motion): If there is a display string at + point, use it.vpos to compute how many lines to backtrack after + move_it_to point. (Bug#11133) + 2012-04-06 Eli Zaretskii * buffer.h (FETCH_CHAR, FETCH_MULTIBYTE_CHAR): diff --git a/src/indent.c b/src/indent.c index a1fcd2b1018..9b4279f0c4e 100644 --- a/src/indent.c +++ b/src/indent.c @@ -2021,6 +2021,7 @@ whether or not it is currently displayed in some window. */) EMACS_INT it_start; int first_x, it_overshoot_count = 0; int overshoot_handled = 0; + int disp_string_at_start_p = 0; itdata = bidi_shelve_cache (); SET_TEXT_POS (pt, PT, PT_BYTE); @@ -2035,6 +2036,8 @@ whether or not it is currently displayed in some window. */) { const char *s = SSDATA (it.string); const char *e = s + SBYTES (it.string); + + disp_string_at_start_p = it.string_from_display_prop_p; while (s < e) { if (*s++ == '\n') @@ -2062,7 +2065,8 @@ whether or not it is currently displayed in some window. */) /* IT may move too far if truncate-lines is on and PT lies beyond the right margin. IT may also move too far if the starting point is on a Lisp string that has embedded - newlines. In these cases, backtrack. */ + newlines, or spans several screen lines. In these cases, + backtrack. */ if (IT_CHARPOS (it) > it_start) { /* We need to backtrack also if the Lisp string contains no @@ -2073,6 +2077,14 @@ whether or not it is currently displayed in some window. */) && it.method == GET_FROM_BUFFER && it.c == '\n') it_overshoot_count = 1; + else if (disp_string_at_start_p && it.vpos > 0) + { + /* This is the case of a display string that spans + several screen lines. In that case, we end up at the + end of the string, and it.vpos tells us how many + screen lines we need to backtrack. */ + it_overshoot_count = it.vpos; + } if (it_overshoot_count > 0) move_it_by_lines (&it, -it_overshoot_count); -- 2.39.2