diff options
author | Eli Zaretskii <[email protected]> | 2011-09-17 18:18:56 +0300 |
---|---|---|
committer | Eli Zaretskii <[email protected]> | 2011-09-17 18:18:56 +0300 |
commit | 1137e8b8eb6fbae76880b814d516377de30eddd3 (patch) | |
tree | 51e82ce03063d5940d0e9e27fff0f10f2587634b /src/bidi.c | |
parent | 8d5ed89901195abc4a5d660371ea26e849292ea6 (diff) |
Fix bug #9470 with slow redisplay in huge single-paragraph buffers.
src/bidi.c (MAX_PARAGRAPH_SEARCH): New macro.
(bidi_find_paragraph_start): Search back for paragraph beginning
at most MAX_PARAGRAPH_SEARCH lines; if not found, return BEGV_BYTE.
(bidi_move_to_visually_next): Only trigger paragraph-related
computations when the last character is a newline or at EOB, not
just any NEUTRAL_B.
src/xdisp.c (reseat_at_next_visible_line_start): Keep information
about the current paragraph and restore it after the call to
reseat.
Diffstat (limited to 'src/bidi.c')
-rw-r--r-- | src/bidi.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/src/bidi.c b/src/bidi.c index bb29647ea8..3efdc1590d 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -1071,15 +1071,25 @@ bidi_at_paragraph_end (EMACS_INT charpos, EMACS_INT bytepos) return val; } +/* On my 2005-vintage machine, searching back for paragraph start + takes ~1 ms per line. And bidi_paragraph_init is called 4 times + when user types C-p. The number below limits each call to + bidi_paragraph_init to about 10 ms. */ +#define MAX_PARAGRAPH_SEARCH 7500 + /* Find the beginning of this paragraph by looking back in the buffer. - Value is the byte position of the paragraph's beginning. */ + Value is the byte position of the paragraph's beginning, or + BEGV_BYTE if paragraph_start_re is still not found after looking + back MAX_PARAGRAPH_SEARCH lines in the buffer. */ static EMACS_INT bidi_find_paragraph_start (EMACS_INT pos, EMACS_INT pos_byte) { Lisp_Object re = paragraph_start_re; EMACS_INT limit = ZV, limit_byte = ZV_BYTE; + EMACS_INT n = 0; while (pos_byte > BEGV_BYTE + && n++ < MAX_PARAGRAPH_SEARCH && fast_looking_at (re, pos, pos_byte, limit, limit_byte, Qnil) < 0) { /* FIXME: What if the paragraph beginning is covered by a @@ -1089,6 +1099,8 @@ bidi_find_paragraph_start (EMACS_INT pos, EMACS_INT pos_byte) pos = find_next_newline_no_quit (pos - 1, -1); pos_byte = CHAR_TO_BYTE (pos); } + if (n >= MAX_PARAGRAPH_SEARCH) + pos_byte = BEGV_BYTE; return pos_byte; } @@ -2239,7 +2251,8 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it) GCPRO1 (bidi_it->string.lstring); /* If we just passed a newline, initialize for the next line. */ - if (!bidi_it->first_elt && bidi_it->orig_type == NEUTRAL_B) + if (!bidi_it->first_elt + && (bidi_it->ch == '\n' || bidi_it->ch == BIDI_EOB)) bidi_line_init (bidi_it); /* Prepare the sentinel iterator state, and cache it. When we bump @@ -2320,7 +2333,8 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it) reordering, whereas we _must_ know the paragraph base direction _before_ we process the paragraph's text, since the base direction affects the reordering. */ - if (bidi_it->scan_dir == 1 && bidi_it->orig_type == NEUTRAL_B) + if (bidi_it->scan_dir == 1 + && (bidi_it->ch == '\n' || bidi_it->ch == BIDI_EOB)) { /* The paragraph direction of the entire string, once determined, is in effect for the entire string. Setting the |