Commit 180c8ce0 authored by Eli Zaretskii's avatar Eli Zaretskii
Browse files

Fix bug #17244 with line-move-visual when display string covers a lot of text.

 src/xdisp.c (move_it_by_lines): If a large portion of buffer text is
 covered by a display string that ends in a newline, and that cases
 going back by DVPOS lines to hit the search limit, lift the limit
 and go back until DVPOS is reached.
 src/indent.c (Fvertical_motion): Handle correctly the case when the
 display string is preceded by an empty line.
parent 204db02a
2014-04-12 Eli Zaretskii <eliz@gnu.org>
* xdisp.c (move_it_by_lines): If a large portion of buffer text is
covered by a display string that ends in a newline, and that cases
going back by DVPOS lines to hit the search limit, lift the limit
and go back until DVPOS is reached. (Bug#17244)
* indent.c (Fvertical_motion): Handle correctly the case when the
display string is preceded by an empty line.
2014-04-11 Eli Zaretskii <eliz@gnu.org>
* w32.c (sys_umask) <WRITE_USER>: Remove redundant constant, and
......
......@@ -2051,8 +2051,15 @@ whether or not it is currently displayed in some window. */)
string, move_it_to will overshoot it, while vertical-motion
wants to put the cursor _before_ the display string. So in
that case, we move to buffer position before the display
string, and avoid overshooting. */
move_it_to (&it, disp_string_at_start_p ? PT - 1 : PT,
string, and avoid overshooting. But if the position before
the display string is a newline, we don't do this, because
otherwise we will end up in a screen line that is one too
far back. */
move_it_to (&it,
(!disp_string_at_start_p
|| FETCH_BYTE (IT_BYTEPOS (it)) == '\n')
? PT
: PT - 1,
-1, -1, -1, MOVE_TO_POS);
/* IT may move too far if truncate-lines is on and PT lies
......
......@@ -9511,6 +9511,7 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
ptrdiff_t start_charpos, i;
int nchars_per_row
= (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
bool hit_pos_limit = false;
ptrdiff_t pos_limit;
 
/* Start at the beginning of the screen line containing IT's
......@@ -9527,8 +9528,11 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
pos_limit = BEGV;
else
pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
back_to_previous_visible_line_start (it);
if (i > 0 && IT_CHARPOS (*it) <= pos_limit)
hit_pos_limit = true;
reseat (it, it->current.pos, 1);
 
/* Move further back if we end up in a string or an image. */
......@@ -9572,6 +9576,25 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
else
bidi_unshelve_cache (it2data, 1);
}
else if (hit_pos_limit && pos_limit > BEGV
&& dvpos < 0 && it2.vpos < -dvpos)
{
/* If we hit the limit, but still didn't make it far enough
back, that means there's a display string with a newline
covering a large chunk of text, and that caused
back_to_previous_visible_line_start try to go too far.
Punish those who commit such atrocities by going back
until we've reached DVPOS, after lifting the limit, which
could make it slow for very long lines. "If it hurts,
don't do that!" */
dvpos += it2.vpos;
RESTORE_IT (it, it, it2data);
for (i = -dvpos; i > 0; --i)
{
back_to_previous_visible_line_start (it);
it->vpos--;
}
}
else
RESTORE_IT (it, it, it2data);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment