aboutsummaryrefslogtreecommitdiffstats
path: root/src/xdisp.c
diff options
context:
space:
mode:
authorGlenn Morris <[email protected]>2014-04-12 12:24:17 -0700
committerGlenn Morris <[email protected]>2014-04-12 12:24:17 -0700
commite0af409500d5f44b34a6e8d971f0c7abe1d747fe (patch)
treeda8c3218399660418391a9bc35d955aa4ff07c73 /src/xdisp.c
parent3197074e49162f96a6eb33ca45fbbfddcf1ae01a (diff)
parent5121b6923beb2fb62b179b4a95b07f9feb969f3d (diff)
Merge from emacs-24; up to 2014-04-07T20:54:[email protected]
Diffstat (limited to 'src/xdisp.c')
-rw-r--r--src/xdisp.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index 3431a7bad2..067d9f6ac0 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -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);
}