From a65e00b9f9b486debdbd9ec2fc584ce1967dba44 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 18 Jul 2015 15:17:26 +0300 Subject: [PATCH] Fix visual-order cursor movement when lines are truncated * src/xdisp.c (Fmove_point_visually): When lines are truncated, simulate display in a window of infinite width, to allow move_it_* functions reach positions outside of normal window dimensions. Remove code that tried to handle a subset of these situations by manual iteration of buffer text. (Bug#17777) --- src/xdisp.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/src/xdisp.c b/src/xdisp.c index 16a7a64c89b..2be057fd211 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -21291,6 +21291,14 @@ Value is the new character position of point. */) /* Setup the arena. */ SET_TEXT_POS (pt, PT, PT_BYTE); start_display (&it, w, pt); + /* When lines are truncated, we could be called with point + outside of the windows edges, in which case move_it_* + functions either prematurely stop at window's edge or jump to + the next screen line, whereas we rely below on our ability to + reach point, in order to start from its X coordinate. So we + need to disregard the window's horizontal extent in that case. */ + if (it.line_wrap == TRUNCATE) + it.last_visible_x = INFINITY; if (it.cmp_it.id < 0 && it.method == GET_FROM_STRING @@ -21382,6 +21390,8 @@ Value is the new character position of point. */) if (pt_x > 0) { start_display (&it, w, pt); + if (it.line_wrap == TRUNCATE) + it.last_visible_x = INFINITY; reseat_at_previous_visible_line_start (&it); it.current_x = it.current_y = it.hpos = 0; if (pt_vpos != 0) @@ -21494,27 +21504,6 @@ Value is the new character position of point. */) if (it.current_x != target_x) move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X); - /* When lines are truncated, the above loop will stop at the - window edge. But we want to get to the end of line, even if - it is beyond the window edge; automatic hscroll will then - scroll the window to show point as appropriate. */ - if (target_is_eol_p && it.line_wrap == TRUNCATE - && get_next_display_element (&it)) - { - struct text_pos new_pos = it.current.pos; - - while (!ITERATOR_AT_END_OF_LINE_P (&it)) - { - set_iterator_to_next (&it, false); - if (it.method == GET_FROM_BUFFER) - new_pos = it.current.pos; - if (!get_next_display_element (&it)) - break; - } - - it.current.pos = new_pos; - } - /* If we ended up in a display string that covers point, move to buffer position to the right in the visual order. */ if (dir > 0) -- 2.11.4.GIT