aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2011-07-19 21:04:56 +0300
committerEli Zaretskii2011-07-19 21:04:56 +0300
commite8c17b886b93f34bcc89e2dff0510cbf63c1f179 (patch)
treec93527f2e73a089796f2caae0755cec80795a593 /src
parent551918c187a781636fb437e71fcf7477afda8230 (diff)
downloademacs-e8c17b886b93f34bcc89e2dff0510cbf63c1f179.tar.gz
emacs-e8c17b886b93f34bcc89e2dff0510cbf63c1f179.zip
Speed up cursor motion in large fontified buffers.
src/xdisp.c (reseat): Don't look for prev_stop, as that could mean a very long run. (next_element_from_buffer): When iterator oversteps prev_pos backwards, don't search for a new prev_stop more than 1000 characters back. (handle_stop_backwards): Don't assume that CHARPOS is necessarily a stop_pos. (compute_display_string_pos): Check also BUF_OVERLAY_MODIFF for a match, when testing the cached display string position for applicability.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog15
-rw-r--r--src/xdisp.c73
2 files changed, 61 insertions, 27 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 0114495838f..15f37f486e2 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,18 @@
12011-07-19 Eli Zaretskii <eliz@gnu.org>
2
3 Fix a significant slow-down of vertical-motion when leaning on C-n
4 or C-p in a fontified buffer.
5 * xdisp.c (reseat): Don't look for prev_stop, as that could mean a
6 very long run.
7 (next_element_from_buffer): When iterator oversteps prev_pos
8 backwards, don't search for a new prev_stop more than 1000
9 characters back.
10 (handle_stop_backwards): Don't assume that CHARPOS is necessarily
11 a stop_pos.
12 (compute_display_string_pos): Check also BUF_OVERLAY_MODIFF for a
13 match, when testing the cached display string position for
14 applicability.
15
12011-07-16 Eli Zaretskii <eliz@gnu.org> 162011-07-16 Eli Zaretskii <eliz@gnu.org>
2 17
3 * xdisp.c <cached_disp_pos, cached_disp_buffer, cached_disp_modiff>: 18 * xdisp.c <cached_disp_pos, cached_disp_buffer, cached_disp_modiff>:
diff --git a/src/xdisp.c b/src/xdisp.c
index 1ddd78caa5d..9968fabf2a4 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -3140,8 +3140,12 @@ next_overlay_change (EMACS_INT pos)
3140/* Record one cached display string position found recently by 3140/* Record one cached display string position found recently by
3141 compute_display_string_pos. */ 3141 compute_display_string_pos. */
3142static EMACS_INT cached_disp_pos; 3142static EMACS_INT cached_disp_pos;
3143static EMACS_INT cached_prev_pos;
3143static struct buffer *cached_disp_buffer; 3144static struct buffer *cached_disp_buffer;
3144static int cached_disp_modiff; 3145static int cached_disp_modiff;
3146static int cached_disp_overlay_modiff;
3147
3148static int ignore_display_strings;
3145 3149
3146/* Return the character position of a display string at or after 3150/* Return the character position of a display string at or after
3147 position specified by POSITION. If no display string exists at or 3151 position specified by POSITION. If no display string exists at or
@@ -3171,7 +3175,8 @@ compute_display_string_pos (struct text_pos *position,
3171 that have display string properties. */ 3175 that have display string properties. */
3172 || string->from_disp_str 3176 || string->from_disp_str
3173 /* C strings cannot have display properties. */ 3177 /* C strings cannot have display properties. */
3174 || (string->s && !STRINGP (object))) 3178 || (string->s && !STRINGP (object))
3179 || ignore_display_strings)
3175 return eob; 3180 return eob;
3176 3181
3177 /* Check the cached values. */ 3182 /* Check the cached values. */
@@ -3183,12 +3188,22 @@ compute_display_string_pos (struct text_pos *position,
3183 b = XBUFFER (object); 3188 b = XBUFFER (object);
3184 if (b == cached_disp_buffer 3189 if (b == cached_disp_buffer
3185 && BUF_MODIFF (b) == cached_disp_modiff 3190 && BUF_MODIFF (b) == cached_disp_modiff
3186 && charpos <= cached_disp_pos) 3191 && BUF_OVERLAY_MODIFF (b) == cached_disp_overlay_modiff)
3187 return cached_disp_pos; 3192 {
3193 if (cached_prev_pos
3194 && cached_prev_pos < charpos && charpos <= cached_disp_pos)
3195 return cached_disp_pos;
3196 /* Handle overstepping eather end of the known interval. */
3197 if (charpos > cached_disp_pos)
3198 cached_prev_pos = cached_disp_pos;
3199 else /* charpos <= cached_prev_pos */
3200 cached_prev_pos = max (charpos - 1, BEGV);
3201 }
3188 3202
3189 /* Record new values in the cache. */ 3203 /* Record new values in the cache. */
3190 cached_disp_buffer = b; 3204 cached_disp_buffer = b;
3191 cached_disp_modiff = BUF_MODIFF (b); 3205 cached_disp_modiff = BUF_MODIFF (b);
3206 cached_disp_overlay_modiff = BUF_OVERLAY_MODIFF (b);
3192 } 3207 }
3193 3208
3194 /* If the character at CHARPOS is where the display string begins, 3209 /* If the character at CHARPOS is where the display string begins,
@@ -5758,17 +5773,11 @@ reseat (struct it *it, struct text_pos pos, int force_p)
5758 { 5773 {
5759 /* For bidi iteration, we need to prime prev_stop and 5774 /* For bidi iteration, we need to prime prev_stop and
5760 base_level_stop with our best estimations. */ 5775 base_level_stop with our best estimations. */
5761 if (CHARPOS (pos) < it->prev_stop) 5776 if (CHARPOS (pos) != it->prev_stop)
5762 { 5777 it->prev_stop = CHARPOS (pos);
5763 handle_stop_backwards (it, BEGV); 5778 if (CHARPOS (pos) < it->base_level_stop)
5764 if (CHARPOS (pos) < it->base_level_stop) 5779 it->base_level_stop = 0;
5765 it->base_level_stop = 0; 5780 handle_stop (it);
5766 }
5767 else if (CHARPOS (pos) > it->stop_charpos
5768 && it->stop_charpos >= BEGV)
5769 handle_stop_backwards (it, it->stop_charpos);
5770 else /* force_p */
5771 handle_stop (it);
5772 } 5781 }
5773 else 5782 else
5774 { 5783 {
@@ -7022,10 +7031,10 @@ next_element_from_string (struct it *it)
7022 embedding level, so test for that explicitly. */ 7031 embedding level, so test for that explicitly. */
7023 && !BIDI_AT_BASE_LEVEL (it->bidi_it)) 7032 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7024 { 7033 {
7025 /* If we lost track of base_level_stop, we have no better place 7034 /* If we lost track of base_level_stop, we have no better
7026 for handle_stop_backwards to start from than BEGV. This 7035 place for handle_stop_backwards to start from than string
7027 happens, e.g., when we were reseated to the previous 7036 beginning. This happens, e.g., when we were reseated to
7028 screenful of text by vertical-motion. */ 7037 the previous screenful of text by vertical-motion. */
7029 if (it->base_level_stop <= 0 7038 if (it->base_level_stop <= 0
7030 || IT_STRING_CHARPOS (*it) < it->base_level_stop) 7039 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7031 it->base_level_stop = 0; 7040 it->base_level_stop = 0;
@@ -7230,6 +7239,7 @@ handle_stop_backwards (struct it *it, EMACS_INT charpos)
7230 struct text_pos save_position = it->position; 7239 struct text_pos save_position = it->position;
7231 struct text_pos pos1; 7240 struct text_pos pos1;
7232 EMACS_INT next_stop; 7241 EMACS_INT next_stop;
7242 int found_stop = 0;
7233 7243
7234 /* Scan in strict logical order. */ 7244 /* Scan in strict logical order. */
7235 it->bidi_p = 0; 7245 it->bidi_p = 0;
@@ -7247,17 +7257,24 @@ handle_stop_backwards (struct it *it, EMACS_INT charpos)
7247 /* We must advance forward, right? */ 7257 /* We must advance forward, right? */
7248 if (it->stop_charpos <= it->prev_stop) 7258 if (it->stop_charpos <= it->prev_stop)
7249 abort (); 7259 abort ();
7260 /* Did we find at least one stop_pos between CHARPOS and IT's
7261 current position? */
7262 if (it->stop_charpos <= where_we_are)
7263 found_stop = 1;
7250 charpos = it->stop_charpos; 7264 charpos = it->stop_charpos;
7251 } 7265 }
7252 while (charpos <= where_we_are); 7266 while (charpos <= where_we_are);
7253 7267
7254 next_stop = it->stop_charpos;
7255 it->stop_charpos = it->prev_stop;
7256 it->bidi_p = 1; 7268 it->bidi_p = 1;
7257 it->current = save_current; 7269 it->current = save_current;
7258 it->position = save_position; 7270 it->position = save_position;
7259 handle_stop (it); 7271 if (found_stop)
7260 it->stop_charpos = next_stop; 7272 {
7273 next_stop = it->stop_charpos;
7274 it->stop_charpos = it->prev_stop;
7275 handle_stop (it);
7276 it->stop_charpos = next_stop;
7277 }
7261} 7278}
7262 7279
7263/* Load IT with the next display element from current_buffer. Value 7280/* Load IT with the next display element from current_buffer. Value
@@ -7352,14 +7369,16 @@ next_element_from_buffer (struct it *it)
7352 embedding level, so test for that explicitly. */ 7369 embedding level, so test for that explicitly. */
7353 && !BIDI_AT_BASE_LEVEL (it->bidi_it)) 7370 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7354 { 7371 {
7355 /* If we lost track of base_level_stop, we have no better place 7372 EMACS_INT start_from;
7356 for handle_stop_backwards to start from than BEGV. This 7373 /* If we lost track of base_level_stop, we try looking backwards
7357 happens, e.g., when we were reseated to the previous 7374 for at most 1000 characters. This happens, e.g., when we
7358 screenful of text by vertical-motion. */ 7375 were reseated to the previous screenful of text by
7376 vertical-motion. */
7359 if (it->base_level_stop <= 0 7377 if (it->base_level_stop <= 0
7360 || IT_CHARPOS (*it) < it->base_level_stop) 7378 || IT_CHARPOS (*it) < it->base_level_stop)
7361 it->base_level_stop = BEGV; 7379 it->base_level_stop = BEGV;
7362 handle_stop_backwards (it, it->base_level_stop); 7380 start_from = max (it->base_level_stop, IT_CHARPOS (*it) - 1000);
7381 handle_stop_backwards (it, start_from);
7363 return GET_NEXT_DISPLAY_ELEMENT (it); 7382 return GET_NEXT_DISPLAY_ELEMENT (it);
7364 } 7383 }
7365 else 7384 else