mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-16 10:50:49 -08:00
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)
This commit is contained in:
parent
166ffcb6c7
commit
a65e00b9f9
1 changed files with 10 additions and 21 deletions
31
src/xdisp.c
31
src/xdisp.c
|
|
@ -21291,6 +21291,14 @@ Value is the new character position of point. */)
|
||||||
/* Setup the arena. */
|
/* Setup the arena. */
|
||||||
SET_TEXT_POS (pt, PT, PT_BYTE);
|
SET_TEXT_POS (pt, PT, PT_BYTE);
|
||||||
start_display (&it, w, pt);
|
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
|
if (it.cmp_it.id < 0
|
||||||
&& it.method == GET_FROM_STRING
|
&& it.method == GET_FROM_STRING
|
||||||
|
|
@ -21382,6 +21390,8 @@ Value is the new character position of point. */)
|
||||||
if (pt_x > 0)
|
if (pt_x > 0)
|
||||||
{
|
{
|
||||||
start_display (&it, w, pt);
|
start_display (&it, w, pt);
|
||||||
|
if (it.line_wrap == TRUNCATE)
|
||||||
|
it.last_visible_x = INFINITY;
|
||||||
reseat_at_previous_visible_line_start (&it);
|
reseat_at_previous_visible_line_start (&it);
|
||||||
it.current_x = it.current_y = it.hpos = 0;
|
it.current_x = it.current_y = it.hpos = 0;
|
||||||
if (pt_vpos != 0)
|
if (pt_vpos != 0)
|
||||||
|
|
@ -21494,27 +21504,6 @@ Value is the new character position of point. */)
|
||||||
if (it.current_x != target_x)
|
if (it.current_x != target_x)
|
||||||
move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_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
|
/* If we ended up in a display string that covers point, move to
|
||||||
buffer position to the right in the visual order. */
|
buffer position to the right in the visual order. */
|
||||||
if (dir > 0)
|
if (dir > 0)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue