Mercurial > vim
comparison src/screen.c @ 11529:998d2cf59caa v8.0.0647
patch 8.0.0647: syntax highlighting can make cause a freeze
commit https://github.com/vim/vim/commit/06f1ed2f78c5c03af95054fc3a8665df39dec362
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jun 18 22:41:03 2017 +0200
patch 8.0.0647: syntax highlighting can make cause a freeze
Problem: Syntax highlighting can make cause a freeze.
Solution: Apply 'redrawtime' to syntax highlighting, per window.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sun, 18 Jun 2017 22:45:04 +0200 |
parents | 578df034735d |
children | 18373179040e |
comparison
equal
deleted
inserted
replaced
11528:5d3f98e7f715 | 11529:998d2cf59caa |
---|---|
122 #ifdef FEAT_FOLDING | 122 #ifdef FEAT_FOLDING |
123 static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T lnum, int row); | 123 static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T lnum, int row); |
124 static void fill_foldcolumn(char_u *p, win_T *wp, int closed, linenr_T lnum); | 124 static void fill_foldcolumn(char_u *p, win_T *wp, int closed, linenr_T lnum); |
125 static void copy_text_attr(int off, char_u *buf, int len, int attr); | 125 static void copy_text_attr(int off, char_u *buf, int len, int attr); |
126 #endif | 126 #endif |
127 static int win_line(win_T *, linenr_T, int, int, int nochange); | 127 static int win_line(win_T *, linenr_T, int, int, int nochange, proftime_T *syntax_tm); |
128 static int char_needs_redraw(int off_from, int off_to, int cols); | 128 static int char_needs_redraw(int off_from, int off_to, int cols); |
129 #ifdef FEAT_RIGHTLEFT | 129 #ifdef FEAT_RIGHTLEFT |
130 static void screen_line(int row, int coloff, int endcol, int clear_width, int rlflag); | 130 static void screen_line(int row, int coloff, int endcol, int clear_width, int rlflag); |
131 # define SCREEN_LINE(r, o, e, c, rl) screen_line((r), (o), (e), (c), (rl)) | 131 # define SCREEN_LINE(r, o, e, c, rl) screen_line((r), (o), (e), (c), (rl)) |
132 #else | 132 #else |
181 #endif | 181 #endif |
182 | 182 |
183 #if defined(FEAT_CLIPBOARD) || defined(FEAT_WINDOWS) | 183 #if defined(FEAT_CLIPBOARD) || defined(FEAT_WINDOWS) |
184 /* Ugly global: overrule attribute used by screen_char() */ | 184 /* Ugly global: overrule attribute used by screen_char() */ |
185 static int screen_char_attr = 0; | 185 static int screen_char_attr = 0; |
186 #endif | |
187 | |
188 #if defined(FEAT_SYN_HL) && defined(FEAT_RELTIME) | |
189 /* Can limit syntax highlight time to 'redrawtime'. */ | |
190 # define SYN_TIME_LIMIT 1 | |
186 #endif | 191 #endif |
187 | 192 |
188 /* | 193 /* |
189 * Redraw the current window later, with update_screen(type). | 194 * Redraw the current window later, with update_screen(type). |
190 * Set must_redraw only if not already set to a higher value. | 195 * Set must_redraw only if not already set to a higher value. |
921 void | 926 void |
922 update_single_line(win_T *wp, linenr_T lnum) | 927 update_single_line(win_T *wp, linenr_T lnum) |
923 { | 928 { |
924 int row; | 929 int row; |
925 int j; | 930 int j; |
931 #ifdef SYN_TIME_LIMIT | |
932 proftime_T syntax_tm; | |
933 #endif | |
926 | 934 |
927 /* Don't do anything if the screen structures are (not yet) valid. */ | 935 /* Don't do anything if the screen structures are (not yet) valid. */ |
928 if (!screen_valid(TRUE) || updating_screen) | 936 if (!screen_valid(TRUE) || updating_screen) |
929 return; | 937 return; |
930 | 938 |
931 if (lnum >= wp->w_topline && lnum < wp->w_botline | 939 if (lnum >= wp->w_topline && lnum < wp->w_botline |
932 && foldedCount(wp, lnum, &win_foldinfo) == 0) | 940 && foldedCount(wp, lnum, &win_foldinfo) == 0) |
933 { | 941 { |
942 #ifdef SYN_TIME_LIMIT | |
943 /* Set the time limit to 'redrawtime'. */ | |
944 profile_setlimit(p_rdt, &syntax_tm); | |
945 #endif | |
934 update_prepare(); | 946 update_prepare(); |
935 | 947 |
936 row = 0; | 948 row = 0; |
937 for (j = 0; j < wp->w_lines_valid; ++j) | 949 for (j = 0; j < wp->w_lines_valid; ++j) |
938 { | 950 { |
942 # ifdef FEAT_SEARCH_EXTRA | 954 # ifdef FEAT_SEARCH_EXTRA |
943 init_search_hl(wp); | 955 init_search_hl(wp); |
944 start_search_hl(); | 956 start_search_hl(); |
945 prepare_search_hl(wp, lnum); | 957 prepare_search_hl(wp, lnum); |
946 # endif | 958 # endif |
947 win_line(wp, lnum, row, row + wp->w_lines[j].wl_size, FALSE); | 959 win_line(wp, lnum, row, row + wp->w_lines[j].wl_size, FALSE, |
960 #ifdef SYN_TIME_LIMIT | |
961 &syntax_tm | |
962 #else | |
963 NULL | |
964 #endif | |
965 ); | |
948 # if defined(FEAT_SEARCH_EXTRA) | 966 # if defined(FEAT_SEARCH_EXTRA) |
949 end_search_hl(); | 967 end_search_hl(); |
950 # endif | 968 # endif |
951 break; | 969 break; |
952 } | 970 } |
1138 linenr_T mod_top = 0; | 1156 linenr_T mod_top = 0; |
1139 linenr_T mod_bot = 0; | 1157 linenr_T mod_bot = 0; |
1140 #if defined(FEAT_SYN_HL) || defined(FEAT_SEARCH_EXTRA) | 1158 #if defined(FEAT_SYN_HL) || defined(FEAT_SEARCH_EXTRA) |
1141 int save_got_int; | 1159 int save_got_int; |
1142 #endif | 1160 #endif |
1161 #ifdef SYN_TIME_LIMIT | |
1162 proftime_T syntax_tm; | |
1163 #endif | |
1143 | 1164 |
1144 type = wp->w_redr_type; | 1165 type = wp->w_redr_type; |
1145 | 1166 |
1146 if (type == NOT_VALID) | 1167 if (type == NOT_VALID) |
1147 { | 1168 { |
1789 | 1810 |
1790 #if defined(FEAT_SYN_HL) || defined(FEAT_SEARCH_EXTRA) | 1811 #if defined(FEAT_SYN_HL) || defined(FEAT_SEARCH_EXTRA) |
1791 /* reset got_int, otherwise regexp won't work */ | 1812 /* reset got_int, otherwise regexp won't work */ |
1792 save_got_int = got_int; | 1813 save_got_int = got_int; |
1793 got_int = 0; | 1814 got_int = 0; |
1815 #endif | |
1816 #ifdef SYN_TIME_LIMIT | |
1817 /* Set the time limit to 'redrawtime'. */ | |
1818 profile_setlimit(p_rdt, &syntax_tm); | |
1794 #endif | 1819 #endif |
1795 #ifdef FEAT_FOLDING | 1820 #ifdef FEAT_FOLDING |
1796 win_foldinfo.fi_level = 0; | 1821 win_foldinfo.fi_level = 0; |
1797 #endif | 1822 #endif |
1798 | 1823 |
2084 #endif | 2109 #endif |
2085 | 2110 |
2086 /* | 2111 /* |
2087 * Display one line. | 2112 * Display one line. |
2088 */ | 2113 */ |
2089 row = win_line(wp, lnum, srow, wp->w_height, mod_top == 0); | 2114 row = win_line(wp, lnum, srow, wp->w_height, mod_top == 0, |
2115 #ifdef SYN_TIME_LIMIT | |
2116 &syntax_tm | |
2117 #else | |
2118 NULL | |
2119 #endif | |
2120 ); | |
2090 | 2121 |
2091 #ifdef FEAT_FOLDING | 2122 #ifdef FEAT_FOLDING |
2092 wp->w_lines[idx].wl_folded = FALSE; | 2123 wp->w_lines[idx].wl_folded = FALSE; |
2093 wp->w_lines[idx].wl_lastlnum = lnum; | 2124 wp->w_lines[idx].wl_lastlnum = lnum; |
2094 #endif | 2125 #endif |
2955 win_line( | 2986 win_line( |
2956 win_T *wp, | 2987 win_T *wp, |
2957 linenr_T lnum, | 2988 linenr_T lnum, |
2958 int startrow, | 2989 int startrow, |
2959 int endrow, | 2990 int endrow, |
2960 int nochange UNUSED) /* not updating for changed text */ | 2991 int nochange UNUSED, /* not updating for changed text */ |
2992 proftime_T *syntax_tm) | |
2961 { | 2993 { |
2962 int col = 0; /* visual column on screen */ | 2994 int col = 0; /* visual column on screen */ |
2963 unsigned off; /* offset in ScreenLines/ScreenAttrs */ | 2995 unsigned off; /* offset in ScreenLines/ScreenAttrs */ |
2964 int c = 0; /* init for GCC */ | 2996 int c = 0; /* init for GCC */ |
2965 long vcol = 0; /* virtual column (for tabs) */ | 2997 long vcol = 0; /* virtual column (for tabs) */ |
3156 extra_check = wp->w_p_lbr; | 3188 extra_check = wp->w_p_lbr; |
3157 #else | 3189 #else |
3158 extra_check = 0; | 3190 extra_check = 0; |
3159 #endif | 3191 #endif |
3160 #ifdef FEAT_SYN_HL | 3192 #ifdef FEAT_SYN_HL |
3161 if (syntax_present(wp) && !wp->w_s->b_syn_error) | 3193 if (syntax_present(wp) && !wp->w_s->b_syn_error |
3194 # ifdef SYN_TIME_LIMIT | |
3195 && !wp->w_s->b_syn_slow | |
3196 # endif | |
3197 ) | |
3162 { | 3198 { |
3163 /* Prepare for syntax highlighting in this line. When there is an | 3199 /* Prepare for syntax highlighting in this line. When there is an |
3164 * error, stop syntax highlighting. */ | 3200 * error, stop syntax highlighting. */ |
3165 save_did_emsg = did_emsg; | 3201 save_did_emsg = did_emsg; |
3166 did_emsg = FALSE; | 3202 did_emsg = FALSE; |
3167 syntax_start(wp, lnum); | 3203 syntax_start(wp, lnum, syntax_tm); |
3168 if (did_emsg) | 3204 if (did_emsg) |
3169 wp->w_s->b_syn_error = TRUE; | 3205 wp->w_s->b_syn_error = TRUE; |
3170 else | 3206 else |
3171 { | 3207 { |
3172 did_emsg = save_did_emsg; | 3208 did_emsg = save_did_emsg; |
3173 has_syntax = TRUE; | 3209 #ifdef SYN_TIME_LIMIT |
3174 extra_check = TRUE; | 3210 if (!wp->w_s->b_syn_slow) |
3211 #endif | |
3212 { | |
3213 has_syntax = TRUE; | |
3214 extra_check = TRUE; | |
3215 } | |
3175 } | 3216 } |
3176 } | 3217 } |
3177 | 3218 |
3178 /* Check for columns to display for 'colorcolumn'. */ | 3219 /* Check for columns to display for 'colorcolumn'. */ |
3179 color_cols = wp->w_p_cc_cols; | 3220 color_cols = wp->w_p_cc_cols; |
3546 wp->w_cursor = pos; | 3587 wp->w_cursor = pos; |
3547 | 3588 |
3548 # ifdef FEAT_SYN_HL | 3589 # ifdef FEAT_SYN_HL |
3549 /* Need to restart syntax highlighting for this line. */ | 3590 /* Need to restart syntax highlighting for this line. */ |
3550 if (has_syntax) | 3591 if (has_syntax) |
3551 syntax_start(wp, lnum); | 3592 syntax_start(wp, lnum, syntax_tm); |
3552 # endif | 3593 # endif |
3553 } | 3594 } |
3554 #endif | 3595 #endif |
3555 } | 3596 } |
3556 | 3597 |
4489 wp->w_s->b_syn_error = TRUE; | 4530 wp->w_s->b_syn_error = TRUE; |
4490 has_syntax = FALSE; | 4531 has_syntax = FALSE; |
4491 } | 4532 } |
4492 else | 4533 else |
4493 did_emsg = save_did_emsg; | 4534 did_emsg = save_did_emsg; |
4535 #ifdef SYN_TIME_LIMIT | |
4536 if (wp->w_s->b_syn_slow) | |
4537 has_syntax = FALSE; | |
4538 #endif | |
4494 | 4539 |
4495 /* Need to get the line again, a multi-line regexp may | 4540 /* Need to get the line again, a multi-line regexp may |
4496 * have made it invalid. */ | 4541 * have made it invalid. */ |
4497 line = ml_get_buf(wp->w_buffer, lnum, FALSE); | 4542 line = ml_get_buf(wp->w_buffer, lnum, FALSE); |
4498 ptr = line + v; | 4543 ptr = line + v; |