aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2022-06-19 14:56:43 +0300
committerEli Zaretskii2022-06-19 14:56:43 +0300
commit287e714fe0f8819dbfd2dea82e5432665493ff50 (patch)
tree8a2673a2949060c8df767f59d144f742bd976dcf /src
parent4b00bc47c7e07bb2a329fa6d0220f39a45289875 (diff)
downloademacs-287e714fe0f8819dbfd2dea82e5432665493ff50.tar.gz
emacs-287e714fe0f8819dbfd2dea82e5432665493ff50.zip
Update redisplay ticks for more operations, and misc modifications
* src/xdisp.c (update_redisplay_ticks): Don't disable redisplay of mini-windows. * src/regex-emacs.c (re_match_2_internal): * src/bidi.c (bidi_find_bracket_pairs, bidi_fetch_char) (bidi_paragraph_init, bidi_find_other_level_edge): Update the redisplay tick count as appropriate, when moving the iterator by one character position actually requires to examine many more positions. * doc/emacs/trouble.texi (Long Lines): * src/xdisp.c (syms_of_xdisp) <max_redisplay_ticks>: Update recommended non-zero values.
Diffstat (limited to 'src')
-rw-r--r--src/bidi.c42
-rw-r--r--src/dispnew.c17
-rw-r--r--src/regex-emacs.c30
-rw-r--r--src/xdisp.c7
4 files changed, 87 insertions, 9 deletions
diff --git a/src/bidi.c b/src/bidi.c
index 4d2c74b17cd..267b62fb0bc 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -1277,6 +1277,12 @@ bidi_fetch_char (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t *disp_pos,
1277 SET_TEXT_POS (pos, charpos, bytepos); 1277 SET_TEXT_POS (pos, charpos, bytepos);
1278 *disp_pos = compute_display_string_pos (&pos, string, w, frame_window_p, 1278 *disp_pos = compute_display_string_pos (&pos, string, w, frame_window_p,
1279 disp_prop); 1279 disp_prop);
1280 /* The factor of 100 below is a heuristic that needs to be
1281 tuned. It means we consider 100 buffer positions examined by
1282 the above call roughly equivalent to the display engine
1283 iterating over a single buffer position. */
1284 if (*disp_pos > charpos)
1285 update_redisplay_ticks ((*disp_pos - charpos) / 100 + 1, w);
1280 } 1286 }
1281 1287
1282 /* Fetch the character at BYTEPOS. */ 1288 /* Fetch the character at BYTEPOS. */
@@ -1385,6 +1391,8 @@ bidi_fetch_char (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t *disp_pos,
1385 SET_TEXT_POS (pos, charpos + *nchars, bytepos + *ch_len); 1391 SET_TEXT_POS (pos, charpos + *nchars, bytepos + *ch_len);
1386 *disp_pos = compute_display_string_pos (&pos, string, w, frame_window_p, 1392 *disp_pos = compute_display_string_pos (&pos, string, w, frame_window_p,
1387 disp_prop); 1393 disp_prop);
1394 if (*disp_pos > charpos + *nchars)
1395 update_redisplay_ticks ((*disp_pos - charpos - *nchars) / 100 + 1, w);
1388 } 1396 }
1389 1397
1390 return ch; 1398 return ch;
@@ -1583,6 +1591,9 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte)
1583 return pos_byte; 1591 return pos_byte;
1584} 1592}
1585 1593
1594/* This tracks how far we needed to search for first strong character. */
1595static ptrdiff_t nsearch_for_strong;
1596
1586/* On a 3.4 GHz machine, searching forward for a strong directional 1597/* On a 3.4 GHz machine, searching forward for a strong directional
1587 character in a long paragraph full of weaks or neutrals takes about 1598 character in a long paragraph full of weaks or neutrals takes about
1588 1 ms for each 20K characters. The number below limits each call to 1599 1 ms for each 20K characters. The number below limits each call to
@@ -1652,6 +1663,8 @@ find_first_strong_char (ptrdiff_t pos, ptrdiff_t bytepos, ptrdiff_t end,
1652 pos += *nchars; 1663 pos += *nchars;
1653 bytepos += *ch_len; 1664 bytepos += *ch_len;
1654 } 1665 }
1666
1667 nsearch_for_strong += pos - pos1;
1655 return type; 1668 return type;
1656} 1669}
1657 1670
@@ -1681,6 +1694,9 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p)
1681 calls to BYTE_TO_CHAR and its ilk. */ 1694 calls to BYTE_TO_CHAR and its ilk. */
1682 ptrdiff_t begbyte = string_p ? 0 : BEGV_BYTE; 1695 ptrdiff_t begbyte = string_p ? 0 : BEGV_BYTE;
1683 ptrdiff_t end = string_p ? bidi_it->string.schars : ZV; 1696 ptrdiff_t end = string_p ? bidi_it->string.schars : ZV;
1697 ptrdiff_t pos = bidi_it->charpos;
1698
1699 nsearch_for_strong = 0;
1684 1700
1685 /* Special case for an empty buffer. */ 1701 /* Special case for an empty buffer. */
1686 if (bytepos == begbyte && bidi_it->charpos == end) 1702 if (bytepos == begbyte && bidi_it->charpos == end)
@@ -1702,7 +1718,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p)
1702 else if (dir == NEUTRAL_DIR) /* P2 */ 1718 else if (dir == NEUTRAL_DIR) /* P2 */
1703 { 1719 {
1704 ptrdiff_t ch_len, nchars; 1720 ptrdiff_t ch_len, nchars;
1705 ptrdiff_t pos, disp_pos = -1; 1721 ptrdiff_t disp_pos = -1;
1706 int disp_prop = 0; 1722 int disp_prop = 0;
1707 bidi_type_t type; 1723 bidi_type_t type;
1708 const unsigned char *s; 1724 const unsigned char *s;
@@ -1800,6 +1816,14 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p)
1800 bidi_it->level_stack[0].level = 0; 1816 bidi_it->level_stack[0].level = 0;
1801 1817
1802 bidi_line_init (bidi_it); 1818 bidi_line_init (bidi_it);
1819
1820 /* The factor of 50 below is a heuristic that needs to be tuned. It
1821 means we consider 50 buffer positions examined by this function
1822 roughly equivalent to the display engine iterating over a single
1823 buffer position. */
1824 ptrdiff_t nexamined = bidi_it->charpos - pos + nsearch_for_strong;
1825 if (nexamined > 0)
1826 update_redisplay_ticks (nexamined / 50, bidi_it->w);
1803} 1827}
1804 1828
1805 1829
@@ -2566,6 +2590,7 @@ bidi_find_bracket_pairs (struct bidi_it *bidi_it)
2566 bidi_bracket_type_t btype; 2590 bidi_bracket_type_t btype;
2567 bidi_type_t type = bidi_it->type; 2591 bidi_type_t type = bidi_it->type;
2568 bool retval = false; 2592 bool retval = false;
2593 ptrdiff_t n = 0;
2569 2594
2570 /* When scanning backwards, we don't expect any unresolved bidi 2595 /* When scanning backwards, we don't expect any unresolved bidi
2571 bracket characters. */ 2596 bracket characters. */
@@ -2695,6 +2720,7 @@ bidi_find_bracket_pairs (struct bidi_it *bidi_it)
2695 } 2720 }
2696 old_sidx = bidi_it->stack_idx; 2721 old_sidx = bidi_it->stack_idx;
2697 type = bidi_resolve_weak (bidi_it); 2722 type = bidi_resolve_weak (bidi_it);
2723 n++;
2698 /* Skip level runs excluded from this isolating run sequence. */ 2724 /* Skip level runs excluded from this isolating run sequence. */
2699 new_sidx = bidi_it->stack_idx; 2725 new_sidx = bidi_it->stack_idx;
2700 if (bidi_it->level_stack[new_sidx].level > current_level 2726 if (bidi_it->level_stack[new_sidx].level > current_level
@@ -2718,6 +2744,7 @@ bidi_find_bracket_pairs (struct bidi_it *bidi_it)
2718 goto give_up; 2744 goto give_up;
2719 } 2745 }
2720 type = bidi_resolve_weak (bidi_it); 2746 type = bidi_resolve_weak (bidi_it);
2747 n++;
2721 } 2748 }
2722 } 2749 }
2723 if (type == NEUTRAL_B 2750 if (type == NEUTRAL_B
@@ -2794,6 +2821,12 @@ bidi_find_bracket_pairs (struct bidi_it *bidi_it)
2794 } 2821 }
2795 2822
2796 give_up: 2823 give_up:
2824 /* The factor of 20 below is a heuristic that needs to be tuned. It
2825 means we consider 20 buffer positions examined by this function
2826 roughly equivalent to the display engine iterating over a single
2827 buffer position. */
2828 if (n > 0)
2829 update_redisplay_ticks (n / 20 + 1, bidi_it->w);
2797 return retval; 2830 return retval;
2798} 2831}
2799 2832
@@ -3363,6 +3396,7 @@ bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, bool end_flag)
3363 else 3396 else
3364 { 3397 {
3365 int new_level; 3398 int new_level;
3399 ptrdiff_t pos0 = bidi_it->charpos;
3366 3400
3367 /* If we are at end of level, its edges must be cached. */ 3401 /* If we are at end of level, its edges must be cached. */
3368 if (end_flag) 3402 if (end_flag)
@@ -3398,6 +3432,12 @@ bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, bool end_flag)
3398 bidi_cache_iterator_state (bidi_it, 1, 1); 3432 bidi_cache_iterator_state (bidi_it, 1, 1);
3399 } 3433 }
3400 } while (new_level >= level); 3434 } while (new_level >= level);
3435 /* The factor of 50 below is a heuristic that needs to be
3436 tuned. It means we consider 50 buffer positions examined by
3437 the above call roughly equivalent to the display engine
3438 iterating over a single buffer position. */
3439 if (bidi_it->charpos > pos0)
3440 update_redisplay_ticks ((bidi_it->charpos - pos0) / 50 + 1, bidi_it->w);
3401 } 3441 }
3402} 3442}
3403 3443
diff --git a/src/dispnew.c b/src/dispnew.c
index 9d587ea00e3..4509262ea62 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -2732,18 +2732,23 @@ set_frame_matrix_frame (struct frame *f)
2732 operations in window matrices of frame_matrix_frame. */ 2732 operations in window matrices of frame_matrix_frame. */
2733 2733
2734static void 2734static void
2735make_current (struct glyph_matrix *desired_matrix, struct glyph_matrix *current_matrix, int row) 2735make_current (struct glyph_matrix *desired_matrix,
2736 struct glyph_matrix *current_matrix, int row)
2736{ 2737{
2737 struct glyph_row *current_row = MATRIX_ROW (current_matrix, row); 2738 struct glyph_row *current_row = MATRIX_ROW (current_matrix, row);
2738 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, row); 2739 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, row);
2739 bool mouse_face_p = current_row->mouse_face_p; 2740 bool mouse_face_p = current_row->mouse_face_p;
2740 2741
2741 /* If we aborted redisplay of this window, a row in the desired 2742 /* If we aborted redisplay of this window, a row in the desired
2742 matrix might not have its hash computed. */ 2743 matrix might not have its hash computed. But update_window
2743 if (!(!desired_row->used[0] 2744 relies on each row having its correct hash, so do it here if
2744 && !desired_row->used[1] 2745 needed. */
2745 && !desired_row->used[2]) 2746 if (!desired_row->hash
2746 && !desired_row->hash) 2747 /* A glyph row that is not completely empty is unlikely to have
2748 a zero hash value. */
2749 && !(!desired_row->used[0]
2750 && !desired_row->used[1]
2751 && !desired_row->used[2]))
2747 desired_row->hash = row_hash (desired_row); 2752 desired_row->hash = row_hash (desired_row);
2748 2753
2749 /* Do current_row = desired_row. This exchanges glyph pointers 2754 /* Do current_row = desired_row. This exchanges glyph pointers
diff --git a/src/regex-emacs.c b/src/regex-emacs.c
index 8662fe8d6d0..4d87418eeaf 100644
--- a/src/regex-emacs.c
+++ b/src/regex-emacs.c
@@ -33,6 +33,7 @@
33#include "buffer.h" 33#include "buffer.h"
34#include "syntax.h" 34#include "syntax.h"
35#include "category.h" 35#include "category.h"
36#include "dispextern.h"
36 37
37/* Maximum number of duplicates an interval can allow. Some systems 38/* Maximum number of duplicates an interval can allow. Some systems
38 define this in other header files, but we want our value, so remove 39 define this in other header files, but we want our value, so remove
@@ -3953,6 +3954,9 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
3953 and need to test it, it's not garbage. */ 3954 and need to test it, it's not garbage. */
3954 re_char *match_end = NULL; 3955 re_char *match_end = NULL;
3955 3956
3957 /* This keeps track of how many buffer/string positions we examined. */
3958 ptrdiff_t nchars = 0;
3959
3956#ifdef DEBUG_COMPILES_ARGUMENTS 3960#ifdef DEBUG_COMPILES_ARGUMENTS
3957 /* Counts the total number of registers pushed. */ 3961 /* Counts the total number of registers pushed. */
3958 ptrdiff_t num_regs_pushed = 0; 3962 ptrdiff_t num_regs_pushed = 0;
@@ -4209,6 +4213,12 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4209 4213
4210 unbind_to (count, Qnil); 4214 unbind_to (count, Qnil);
4211 SAFE_FREE (); 4215 SAFE_FREE ();
4216 /* The factor of 50 below is a heuristic that needs to be tuned. It
4217 means we consider 50 buffer positions examined by this function
4218 roughly equivalent to the display engine iterating over a single
4219 buffer position. */
4220 if (nchars > 0)
4221 update_redisplay_ticks (nchars / 50 + 1, NULL);
4212 return dcnt; 4222 return dcnt;
4213 } 4223 }
4214 4224
@@ -4261,6 +4271,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4261 p += pat_charlen; 4271 p += pat_charlen;
4262 d += buf_charlen; 4272 d += buf_charlen;
4263 mcnt -= pat_charlen; 4273 mcnt -= pat_charlen;
4274 nchars++;
4264 } 4275 }
4265 while (mcnt > 0); 4276 while (mcnt > 0);
4266 else 4277 else
@@ -4298,6 +4309,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4298 p += pat_charlen; 4309 p += pat_charlen;
4299 d++; 4310 d++;
4300 mcnt -= pat_charlen; 4311 mcnt -= pat_charlen;
4312 nchars++;
4301 } 4313 }
4302 while (mcnt > 0); 4314 while (mcnt > 0);
4303 4315
@@ -4321,6 +4333,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4321 4333
4322 DEBUG_PRINT (" Matched \"%d\".\n", *d); 4334 DEBUG_PRINT (" Matched \"%d\".\n", *d);
4323 d += buf_charlen; 4335 d += buf_charlen;
4336 nchars++;
4324 } 4337 }
4325 break; 4338 break;
4326 4339
@@ -4373,6 +4386,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4373 goto fail; 4386 goto fail;
4374 4387
4375 d += len; 4388 d += len;
4389 nchars++;
4376 } 4390 }
4377 break; 4391 break;
4378 4392
@@ -4492,6 +4506,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4492 goto fail; 4506 goto fail;
4493 } 4507 }
4494 d += dcnt, d2 += dcnt; 4508 d += dcnt, d2 += dcnt;
4509 nchars++;
4495 } 4510 }
4496 } 4511 }
4497 break; 4512 break;
@@ -4773,10 +4788,12 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4773 ptrdiff_t charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset) - 1; 4788 ptrdiff_t charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset) - 1;
4774 UPDATE_SYNTAX_TABLE (charpos); 4789 UPDATE_SYNTAX_TABLE (charpos);
4775 GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2); 4790 GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2);
4791 nchars++;
4776 s1 = SYNTAX (c1); 4792 s1 = SYNTAX (c1);
4777 UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1); 4793 UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1);
4778 PREFETCH_NOLIMIT (); 4794 PREFETCH_NOLIMIT ();
4779 GET_CHAR_AFTER (c2, d, dummy); 4795 GET_CHAR_AFTER (c2, d, dummy);
4796 nchars++;
4780 s2 = SYNTAX (c2); 4797 s2 = SYNTAX (c2);
4781 4798
4782 if (/* Case 2: Only one of S1 and S2 is Sword. */ 4799 if (/* Case 2: Only one of S1 and S2 is Sword. */
@@ -4812,6 +4829,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4812 UPDATE_SYNTAX_TABLE (charpos); 4829 UPDATE_SYNTAX_TABLE (charpos);
4813 PREFETCH (); 4830 PREFETCH ();
4814 GET_CHAR_AFTER (c2, d, dummy); 4831 GET_CHAR_AFTER (c2, d, dummy);
4832 nchars++;
4815 s2 = SYNTAX (c2); 4833 s2 = SYNTAX (c2);
4816 4834
4817 /* Case 2: S2 is not Sword. */ 4835 /* Case 2: S2 is not Sword. */
@@ -4822,6 +4840,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4822 if (!AT_STRINGS_BEG (d)) 4840 if (!AT_STRINGS_BEG (d))
4823 { 4841 {
4824 GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2); 4842 GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2);
4843 nchars++;
4825 UPDATE_SYNTAX_TABLE_BACKWARD (charpos - 1); 4844 UPDATE_SYNTAX_TABLE_BACKWARD (charpos - 1);
4826 s1 = SYNTAX (c1); 4845 s1 = SYNTAX (c1);
4827 4846
@@ -4852,6 +4871,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4852 ptrdiff_t charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset) - 1; 4871 ptrdiff_t charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset) - 1;
4853 UPDATE_SYNTAX_TABLE (charpos); 4872 UPDATE_SYNTAX_TABLE (charpos);
4854 GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2); 4873 GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2);
4874 nchars++;
4855 s1 = SYNTAX (c1); 4875 s1 = SYNTAX (c1);
4856 4876
4857 /* Case 2: S1 is not Sword. */ 4877 /* Case 2: S1 is not Sword. */
@@ -4863,6 +4883,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4863 { 4883 {
4864 PREFETCH_NOLIMIT (); 4884 PREFETCH_NOLIMIT ();
4865 GET_CHAR_AFTER (c2, d, dummy); 4885 GET_CHAR_AFTER (c2, d, dummy);
4886 nchars++;
4866 UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1); 4887 UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1);
4867 s2 = SYNTAX (c2); 4888 s2 = SYNTAX (c2);
4868 4889
@@ -4893,6 +4914,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4893 UPDATE_SYNTAX_TABLE (charpos); 4914 UPDATE_SYNTAX_TABLE (charpos);
4894 PREFETCH (); 4915 PREFETCH ();
4895 c2 = RE_STRING_CHAR (d, target_multibyte); 4916 c2 = RE_STRING_CHAR (d, target_multibyte);
4917 nchars++;
4896 s2 = SYNTAX (c2); 4918 s2 = SYNTAX (c2);
4897 4919
4898 /* Case 2: S2 is neither Sword nor Ssymbol. */ 4920 /* Case 2: S2 is neither Sword nor Ssymbol. */
@@ -4903,6 +4925,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4903 if (!AT_STRINGS_BEG (d)) 4925 if (!AT_STRINGS_BEG (d))
4904 { 4926 {
4905 GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2); 4927 GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2);
4928 nchars++;
4906 UPDATE_SYNTAX_TABLE_BACKWARD (charpos - 1); 4929 UPDATE_SYNTAX_TABLE_BACKWARD (charpos - 1);
4907 s1 = SYNTAX (c1); 4930 s1 = SYNTAX (c1);
4908 4931
@@ -4931,6 +4954,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4931 ptrdiff_t charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset) - 1; 4954 ptrdiff_t charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset) - 1;
4932 UPDATE_SYNTAX_TABLE (charpos); 4955 UPDATE_SYNTAX_TABLE (charpos);
4933 GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2); 4956 GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2);
4957 nchars++;
4934 s1 = SYNTAX (c1); 4958 s1 = SYNTAX (c1);
4935 4959
4936 /* Case 2: S1 is neither Ssymbol nor Sword. */ 4960 /* Case 2: S1 is neither Ssymbol nor Sword. */
@@ -4942,6 +4966,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4942 { 4966 {
4943 PREFETCH_NOLIMIT (); 4967 PREFETCH_NOLIMIT ();
4944 c2 = RE_STRING_CHAR (d, target_multibyte); 4968 c2 = RE_STRING_CHAR (d, target_multibyte);
4969 nchars++;
4945 UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1); 4970 UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1);
4946 s2 = SYNTAX (c2); 4971 s2 = SYNTAX (c2);
4947 4972
@@ -4973,6 +4998,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4973 if ((SYNTAX (c) != (enum syntaxcode) mcnt) ^ not) 4998 if ((SYNTAX (c) != (enum syntaxcode) mcnt) ^ not)
4974 goto fail; 4999 goto fail;
4975 d += len; 5000 d += len;
5001 nchars++;
4976 } 5002 }
4977 } 5003 }
4978 break; 5004 break;
@@ -4999,6 +5025,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4999 if ((!CHAR_HAS_CATEGORY (c, mcnt)) ^ not) 5025 if ((!CHAR_HAS_CATEGORY (c, mcnt)) ^ not)
5000 goto fail; 5026 goto fail;
5001 d += len; 5027 d += len;
5028 nchars++;
5002 } 5029 }
5003 } 5030 }
5004 break; 5031 break;
@@ -5060,6 +5087,9 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
5060 unbind_to (count, Qnil); 5087 unbind_to (count, Qnil);
5061 SAFE_FREE (); 5088 SAFE_FREE ();
5062 5089
5090 if (nchars > 0)
5091 update_redisplay_ticks (nchars / 50 + 1, NULL);
5092
5063 return -1; /* Failure to match. */ 5093 return -1; /* Failure to match. */
5064} 5094}
5065 5095
diff --git a/src/xdisp.c b/src/xdisp.c
index 1d52bbc6c93..f95aeb6149a 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -17218,7 +17218,10 @@ update_redisplay_ticks (int ticks, struct window *w)
17218 } 17218 }
17219 /* Some callers can be run in contexts unrelated to display code, so 17219 /* Some callers can be run in contexts unrelated to display code, so
17220 don't abort them and don't update the tick count in those cases. */ 17220 don't abort them and don't update the tick count in those cases. */
17221 if (!w && !redisplaying_p && !display_working_on_window_p) 17221 if ((!w && !redisplaying_p && !display_working_on_window_p)
17222 /* We never disable redisplay of a mini-window, since that is
17223 absolutely essential for communicating with Emacs. */
17224 || (w && MINI_WINDOW_P (w)))
17222 return; 17225 return;
17223 17226
17224 if (ticks > 0) 17227 if (ticks > 0)
@@ -36765,7 +36768,7 @@ You can also decide to kill the buffer and visit it in some
36765other way, like under `so-long-mode' or literally. 36768other way, like under `so-long-mode' or literally.
36766 36769
36767The default value is zero, which disables this feature. 36770The default value is zero, which disables this feature.
36768The recommended non-zero value is between 50000 and 200000, 36771The recommended non-zero value is between 100000 and 1000000,
36769depending on your patience and the speed of your system. */); 36772depending on your patience and the speed of your system. */);
36770 max_redisplay_ticks = 0; 36773 max_redisplay_ticks = 0;
36771} 36774}