To: vim_dev@googlegroups.com Subject: Patch 8.0.0643 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0643 Problem: When 'hlsearch' is set and matching with the last search pattern is very slow, Vim becomes unusable. Cannot quit search by pressing CTRL-C. Solution: When the search times out set a flag and don't try again. Check for timeout and CTRL-C in NFA loop that adds states. Files: src/screen.c, src/ex_cmds.c, src/quickfix.c, src/regexp.c, src/proto/regexp.pro, src/regexp.h, src/search.c, src/proto/search.pro, src/syntax.c, src/regexp_nfa.c, src/spell.c, src/tag.c, src/gui.c, src/edit.c, src/evalfunc.c, src/ex_docmd.c, src/ex_getln.c, src/normal.c *** ../vim-8.0.0642/src/screen.c 2017-06-13 17:20:35.687782351 +0200 --- src/screen.c 2017-06-17 17:40:54.061966780 +0200 *************** *** 7800,7819 **** int regprog_is_copy = (shl != &search_hl && cur != NULL && shl == &cur->hl && cur->match.regprog == cur->hl.rm.regprog); nmatched = vim_regexec_multi(&shl->rm, win, shl->buf, lnum, matchcol, #ifdef FEAT_RELTIME ! &(shl->tm) #else ! NULL #endif ); /* Copy the regprog, in case it got freed and recompiled. */ if (regprog_is_copy) cur->match.regprog = cur->hl.rm.regprog; ! if (called_emsg || got_int) { /* Error while handling regexp: stop using this regexp. */ if (shl == &search_hl) --- 7800,7820 ---- int regprog_is_copy = (shl != &search_hl && cur != NULL && shl == &cur->hl && cur->match.regprog == cur->hl.rm.regprog); + int timed_out = FALSE; nmatched = vim_regexec_multi(&shl->rm, win, shl->buf, lnum, matchcol, #ifdef FEAT_RELTIME ! &(shl->tm), &timed_out #else ! NULL, NULL #endif ); /* Copy the regprog, in case it got freed and recompiled. */ if (regprog_is_copy) cur->match.regprog = cur->hl.rm.regprog; ! if (called_emsg || got_int || timed_out) { /* Error while handling regexp: stop using this regexp. */ if (shl == &search_hl) *** ../vim-8.0.0642/src/ex_cmds.c 2017-06-10 14:29:26.766871128 +0200 --- src/ex_cmds.c 2017-06-17 17:41:44.501599148 +0200 *************** *** 5096,5102 **** ); ++lnum) { nmatch = vim_regexec_multi(®match, curwin, curbuf, lnum, ! (colnr_T)0, NULL); if (nmatch) { colnr_T copycol; --- 5096,5102 ---- ); ++lnum) { nmatch = vim_regexec_multi(®match, curwin, curbuf, lnum, ! (colnr_T)0, NULL, NULL); if (nmatch) { colnr_T copycol; *************** *** 5695,5701 **** || nmatch_tl > 0 || (nmatch = vim_regexec_multi(®match, curwin, curbuf, sub_firstlnum, ! matchcol, NULL)) == 0 || regmatch.startpos[0].lnum > 0) { if (new_start != NULL) --- 5695,5701 ---- || nmatch_tl > 0 || (nmatch = vim_regexec_multi(®match, curwin, curbuf, sub_firstlnum, ! matchcol, NULL, NULL)) == 0 || regmatch.startpos[0].lnum > 0) { if (new_start != NULL) *************** *** 5760,5766 **** } if (nmatch == -1 && !lastone) nmatch = vim_regexec_multi(®match, curwin, curbuf, ! sub_firstlnum, matchcol, NULL); /* * 5. break if there isn't another match in this line --- 5760,5766 ---- } if (nmatch == -1 && !lastone) nmatch = vim_regexec_multi(®match, curwin, curbuf, ! sub_firstlnum, matchcol, NULL, NULL); /* * 5. break if there isn't another match in this line *************** *** 6012,6018 **** { lnum = curwin->w_cursor.lnum; match = vim_regexec_multi(®match, curwin, curbuf, lnum, ! (colnr_T)0, NULL); if ((type == 'g' && match) || (type == 'v' && !match)) global_exe_one(cmd, lnum); } --- 6012,6018 ---- { lnum = curwin->w_cursor.lnum; match = vim_regexec_multi(®match, curwin, curbuf, lnum, ! (colnr_T)0, NULL, NULL); if ((type == 'g' && match) || (type == 'v' && !match)) global_exe_one(cmd, lnum); } *************** *** 6025,6031 **** { /* a match on this line? */ match = vim_regexec_multi(®match, curwin, curbuf, lnum, ! (colnr_T)0, NULL); if ((type == 'g' && match) || (type == 'v' && !match)) { ml_setmarked(lnum); --- 6025,6031 ---- { /* a match on this line? */ match = vim_regexec_multi(®match, curwin, curbuf, lnum, ! (colnr_T)0, NULL, NULL); if ((type == 'g' && match) || (type == 'v' && !match)) { ml_setmarked(lnum); *** ../vim-8.0.0642/src/quickfix.c 2017-06-13 17:20:35.683782375 +0200 --- src/quickfix.c 2017-06-17 18:17:49.657686222 +0200 *************** *** 2415,2421 **** save_cursor = curwin->w_cursor; curwin->w_cursor.lnum = 0; if (!do_search(NULL, '/', qf_ptr->qf_pattern, (long)1, ! SEARCH_KEEP, NULL)) curwin->w_cursor = save_cursor; } --- 2415,2421 ---- save_cursor = curwin->w_cursor; curwin->w_cursor.lnum = 0; if (!do_search(NULL, '/', qf_ptr->qf_pattern, (long)1, ! SEARCH_KEEP, NULL, NULL)) curwin->w_cursor = save_cursor; } *************** *** 4237,4243 **** { col = 0; while (vim_regexec_multi(®match, curwin, buf, lnum, ! col, NULL) > 0) { /* Pass the buffer number so that it gets used even for a * dummy buffer, unless duplicate_name is set, then the --- 4237,4243 ---- { col = 0; while (vim_regexec_multi(®match, curwin, buf, lnum, ! col, NULL, NULL) > 0) { /* Pass the buffer number so that it gets used even for a * dummy buffer, unless duplicate_name is set, then the *** ../vim-8.0.0642/src/regexp.c 2017-06-05 17:53:33.475700562 +0200 --- src/regexp.c 2017-06-17 18:05:45.706987502 +0200 *************** *** 3479,3485 **** } regbehind_T; static char_u *reg_getline(linenr_T lnum); ! static long bt_regexec_both(char_u *line, colnr_T col, proftime_T *tm); static long regtry(bt_regprog_T *prog, colnr_T col); static void cleanup_subexpr(void); #ifdef FEAT_SYN_HL --- 3479,3485 ---- } regbehind_T; static char_u *reg_getline(linenr_T lnum); ! static long bt_regexec_both(char_u *line, colnr_T col, proftime_T *tm, int *timed_out); static long regtry(bt_regprog_T *prog, colnr_T col); static void cleanup_subexpr(void); #ifdef FEAT_SYN_HL *************** *** 3722,3728 **** #endif rex.reg_maxcol = 0; ! return bt_regexec_both(line, col, NULL); } /* --- 3722,3728 ---- #endif rex.reg_maxcol = 0; ! return bt_regexec_both(line, col, NULL, NULL); } /* *************** *** 3740,3746 **** buf_T *buf, /* buffer in which to search */ linenr_T lnum, /* nr of line to start looking for match */ colnr_T col, /* column to start looking for match */ ! proftime_T *tm) /* timeout limit or NULL */ { rex.reg_match = NULL; rex.reg_mmatch = rmp; --- 3740,3747 ---- buf_T *buf, /* buffer in which to search */ linenr_T lnum, /* nr of line to start looking for match */ colnr_T col, /* column to start looking for match */ ! proftime_T *tm, /* timeout limit or NULL */ ! int *timed_out) /* flag set on timeout or NULL */ { rex.reg_match = NULL; rex.reg_mmatch = rmp; *************** *** 3755,3761 **** #endif rex.reg_maxcol = rmp->rmm_maxcol; ! return bt_regexec_both(NULL, col, tm); } /* --- 3756,3762 ---- #endif rex.reg_maxcol = rmp->rmm_maxcol; ! return bt_regexec_both(NULL, col, tm, timed_out); } /* *************** *** 3767,3773 **** bt_regexec_both( char_u *line, colnr_T col, /* column to start looking for match */ ! proftime_T *tm UNUSED) /* timeout limit or NULL */ { bt_regprog_T *prog; char_u *s; --- 3768,3775 ---- bt_regexec_both( char_u *line, colnr_T col, /* column to start looking for match */ ! proftime_T *tm UNUSED, /* timeout limit or NULL */ ! int *timed_out UNUSED) /* flag set on timeout or NULL */ { bt_regprog_T *prog; char_u *s; *************** *** 3968,3974 **** --- 3970,3980 ---- { tm_count = 0; if (profile_passed_limit(tm)) + { + if (timed_out != NULL) + *timed_out = TRUE; break; + } } #endif } *************** *** 8308,8314 **** buf_T *buf, /* buffer in which to search */ linenr_T lnum, /* nr of line to start looking for match */ colnr_T col, /* column to start looking for match */ ! proftime_T *tm) /* timeout limit or NULL */ { int result; regexec_T rex_save; --- 8314,8321 ---- buf_T *buf, /* buffer in which to search */ linenr_T lnum, /* nr of line to start looking for match */ colnr_T col, /* column to start looking for match */ ! proftime_T *tm, /* timeout limit or NULL */ ! int *timed_out) /* flag is set when timeout limit reached */ { int result; regexec_T rex_save; *************** *** 8319,8325 **** rex_save = rex; rex_in_use = TRUE; ! result = rmp->regprog->engine->regexec_multi(rmp, win, buf, lnum, col, tm); /* NFA engine aborted because it's very slow. */ if (rmp->regprog->re_engine == AUTOMATIC_ENGINE --- 8326,8333 ---- rex_save = rex; rex_in_use = TRUE; ! result = rmp->regprog->engine->regexec_multi( ! rmp, win, buf, lnum, col, tm, timed_out); /* NFA engine aborted because it's very slow. */ if (rmp->regprog->re_engine == AUTOMATIC_ENGINE *************** *** 8339,8345 **** rmp->regprog = vim_regcomp(pat, re_flags); if (rmp->regprog != NULL) result = rmp->regprog->engine->regexec_multi( ! rmp, win, buf, lnum, col, tm); vim_free(pat); } p_re = save_p_re; --- 8347,8353 ---- rmp->regprog = vim_regcomp(pat, re_flags); if (rmp->regprog != NULL) result = rmp->regprog->engine->regexec_multi( ! rmp, win, buf, lnum, col, tm, timed_out); vim_free(pat); } p_re = save_p_re; *** ../vim-8.0.0642/src/proto/regexp.pro 2016-09-12 13:04:17.000000000 +0200 --- src/proto/regexp.pro 2017-06-17 17:51:04.105477928 +0200 *************** *** 16,20 **** int vim_regexec_prog(regprog_T **prog, int ignore_case, char_u *line, colnr_T col); int vim_regexec(regmatch_T *rmp, char_u *line, colnr_T col); int vim_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col); ! long vim_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf, linenr_T lnum, colnr_T col, proftime_T *tm); /* vim: set ft=c : */ --- 16,20 ---- int vim_regexec_prog(regprog_T **prog, int ignore_case, char_u *line, colnr_T col); int vim_regexec(regmatch_T *rmp, char_u *line, colnr_T col); int vim_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col); ! long vim_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf, linenr_T lnum, colnr_T col, proftime_T *tm, int *timed_out); /* vim: set ft=c : */ *** ../vim-8.0.0642/src/regexp.h 2016-08-29 22:42:20.000000000 +0200 --- src/regexp.h 2017-06-17 17:52:18.816926472 +0200 *************** *** 165,172 **** { regprog_T *(*regcomp)(char_u*, int); void (*regfree)(regprog_T *); ! int (*regexec_nl)(regmatch_T*, char_u*, colnr_T, int); ! long (*regexec_multi)(regmmatch_T*, win_T*, buf_T*, linenr_T, colnr_T, proftime_T*); char_u *expr; }; --- 165,172 ---- { regprog_T *(*regcomp)(char_u*, int); void (*regfree)(regprog_T *); ! int (*regexec_nl)(regmatch_T *, char_u *, colnr_T, int); ! long (*regexec_multi)(regmmatch_T *, win_T *, buf_T *, linenr_T, colnr_T, proftime_T *, int *); char_u *expr; }; *** ../vim-8.0.0642/src/search.c 2017-06-05 19:56:01.124964522 +0200 --- src/search.c 2017-06-17 18:08:22.637835726 +0200 *************** *** 593,599 **** int options, int pat_use, /* which pattern to use when "pat" is empty */ linenr_T stop_lnum, /* stop after this line number when != 0 */ ! proftime_T *tm UNUSED) /* timeout limit or NULL */ { int found; linenr_T lnum; /* no init to shut up Apollo cc */ --- 593,600 ---- int options, int pat_use, /* which pattern to use when "pat" is empty */ linenr_T stop_lnum, /* stop after this line number when != 0 */ ! proftime_T *tm UNUSED, /* timeout limit or NULL */ ! int *timed_out UNUSED) /* set when timed out or NULL */ { int found; linenr_T lnum; /* no init to shut up Apollo cc */ *************** *** 715,727 **** nmatched = vim_regexec_multi(®match, win, buf, lnum, col, #ifdef FEAT_RELTIME ! tm #else ! NULL #endif ); /* Abort searching on an error (e.g., out of stack). */ ! if (called_emsg) break; if (nmatched > 0) { --- 716,732 ---- nmatched = vim_regexec_multi(®match, win, buf, lnum, col, #ifdef FEAT_RELTIME ! tm, timed_out #else ! NULL, NULL #endif ); /* Abort searching on an error (e.g., out of stack). */ ! if (called_emsg ! #ifdef FEAT_RELTIME ! || (timed_out != NULL && *timed_out) ! #endif ! ) break; if (nmatched > 0) { *************** *** 810,818 **** win, buf, lnum + matchpos.lnum, matchcol, #ifdef FEAT_RELTIME ! tm #else ! NULL #endif )) == 0) { --- 815,823 ---- win, buf, lnum + matchpos.lnum, matchcol, #ifdef FEAT_RELTIME ! tm, timed_out #else ! NULL, NULL #endif )) == 0) { *************** *** 922,930 **** win, buf, lnum + matchpos.lnum, matchcol, #ifdef FEAT_RELTIME ! tm #else ! NULL #endif )) == 0) break; --- 927,935 ---- win, buf, lnum + matchpos.lnum, matchcol, #ifdef FEAT_RELTIME ! tm, timed_out #else ! NULL, NULL #endif )) == 0) break; *************** *** 1019,1028 **** * twice. */ if (!p_ws || stop_lnum != 0 || got_int || called_emsg #ifdef FEAT_SEARCH_EXTRA ! || break_loop #endif ! || found || loop) break; /* --- 1024,1036 ---- * twice. */ if (!p_ws || stop_lnum != 0 || got_int || called_emsg + #ifdef FEAT_RELTIME + || (timed_out != NULL && *timed_out) + #endif #ifdef FEAT_SEARCH_EXTRA ! || break_loop #endif ! || found || loop) break; /* *************** *** 1041,1046 **** --- 1049,1057 ---- ? top_bot_msg : bot_top_msg), TRUE); } if (got_int || called_emsg + #ifdef FEAT_RELTIME + || (timed_out != NULL && *timed_out) + #endif #ifdef FEAT_SEARCH_EXTRA || break_loop #endif *************** *** 1147,1153 **** char_u *pat, long count, int options, ! proftime_T *tm) /* timeout limit or NULL */ { pos_T pos; /* position of the last match */ char_u *searchstr; --- 1158,1165 ---- char_u *pat, long count, int options, ! proftime_T *tm, /* timeout limit or NULL */ ! int *timed_out) /* flag set on timeout or NULL */ { pos_T pos; /* position of the last match */ char_u *searchstr; *************** *** 1433,1439 **** (SEARCH_KEEP + SEARCH_PEEK + SEARCH_HIS + SEARCH_MSG + SEARCH_START + ((pat != NULL && *pat == ';') ? 0 : SEARCH_NOOF))), ! RE_LAST, (linenr_T)0, tm); if (dircp != NULL) *dircp = dirc; /* restore second '/' or '?' for normal_cmd() */ --- 1445,1451 ---- (SEARCH_KEEP + SEARCH_PEEK + SEARCH_HIS + SEARCH_MSG + SEARCH_START + ((pat != NULL && *pat == ';') ? 0 : SEARCH_NOOF))), ! RE_LAST, (linenr_T)0, tm, timed_out); if (dircp != NULL) *dircp = dirc; /* restore second '/' or '?' for normal_cmd() */ *************** *** 4672,4678 **** result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD), spats[last_idx].pat, (long) (i ? count : 1), ! SEARCH_KEEP | flags, RE_SEARCH, 0, NULL); /* First search may fail, but then start searching from the * beginning of the file (cursor might be on the search match) --- 4684,4690 ---- result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD), spats[last_idx].pat, (long) (i ? count : 1), ! SEARCH_KEEP | flags, RE_SEARCH, 0, NULL, NULL); /* First search may fail, but then start searching from the * beginning of the file (cursor might be on the search match) *************** *** 4719,4725 **** * already on the next match */ if (!one_char) result = searchit(curwin, curbuf, &pos, (forward ? FORWARD : BACKWARD), ! spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0, NULL); if (!VIsual_active) VIsual = start_pos; --- 4731,4738 ---- * already on the next match */ if (!one_char) result = searchit(curwin, curbuf, &pos, (forward ? FORWARD : BACKWARD), ! spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0, ! NULL, NULL); if (!VIsual_active) VIsual = start_pos; *************** *** 4800,4806 **** } if (searchit(curwin, curbuf, &pos, FORWARD, pattern, 1, ! SEARCH_KEEP + flag, RE_SEARCH, 0, NULL) != FAIL) { /* Zero-width pattern should match somewhere, then we can check if * start and end are in the same position. */ --- 4813,4819 ---- } if (searchit(curwin, curbuf, &pos, FORWARD, pattern, 1, ! SEARCH_KEEP + flag, RE_SEARCH, 0, NULL, NULL) != FAIL) { /* Zero-width pattern should match somewhere, then we can check if * start and end are in the same position. */ *************** *** 4809,4815 **** { regmatch.startpos[0].col++; nmatched = vim_regexec_multi(®match, curwin, curbuf, ! pos.lnum, regmatch.startpos[0].col, NULL); if (!nmatched) break; } while (regmatch.startpos[0].col < pos.col); --- 4822,4828 ---- { regmatch.startpos[0].col++; nmatched = vim_regexec_multi(®match, curwin, curbuf, ! pos.lnum, regmatch.startpos[0].col, NULL, NULL); if (!nmatched) break; } while (regmatch.startpos[0].col < pos.col); *** ../vim-8.0.0642/src/proto/search.pro 2016-09-12 13:04:18.000000000 +0200 --- src/proto/search.pro 2017-06-17 18:07:47.278095159 +0200 *************** *** 19,27 **** void reset_search_dir(void); void set_last_search_pat(char_u *s, int idx, int magic, int setlast); void last_pat_prog(regmmatch_T *regmatch); ! int searchit(win_T *win, buf_T *buf, pos_T *pos, int dir, char_u *pat, long count, int options, int pat_use, linenr_T stop_lnum, proftime_T *tm); void set_search_direction(int cdir); ! int do_search(oparg_T *oap, int dirc, char_u *pat, long count, int options, proftime_T *tm); int search_for_exact_line(buf_T *buf, pos_T *pos, int dir, char_u *pat); int searchc(cmdarg_T *cap, int t_cmd); pos_T *findmatch(oparg_T *oap, int initc); --- 19,27 ---- void reset_search_dir(void); void set_last_search_pat(char_u *s, int idx, int magic, int setlast); void last_pat_prog(regmmatch_T *regmatch); ! int searchit(win_T *win, buf_T *buf, pos_T *pos, int dir, char_u *pat, long count, int options, int pat_use, linenr_T stop_lnum, proftime_T *tm, int *timed_out); void set_search_direction(int cdir); ! int do_search(oparg_T *oap, int dirc, char_u *pat, long count, int options, proftime_T *tm, int *timed_out); int search_for_exact_line(buf_T *buf, pos_T *pos, int dir, char_u *pat); int searchc(cmdarg_T *cap, int t_cmd); pos_T *findmatch(oparg_T *oap, int initc); *** ../vim-8.0.0642/src/syntax.c 2017-06-13 17:20:35.687782351 +0200 --- src/syntax.c 2017-06-17 17:48:45.270503447 +0200 *************** *** 3303,3309 **** #endif rmp->rmm_maxcol = syn_buf->b_p_smc; ! r = vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col, NULL); #ifdef FEAT_PROFILE if (syn_time_on) --- 3303,3309 ---- #endif rmp->rmm_maxcol = syn_buf->b_p_smc; ! r = vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col, NULL, NULL); #ifdef FEAT_PROFILE if (syn_time_on) *** ../vim-8.0.0642/src/regexp_nfa.c 2017-06-05 16:54:04.424407859 +0200 --- src/regexp_nfa.c 2017-06-17 18:30:30.804088832 +0200 *************** *** 311,322 **** static void nfa_save_listids(nfa_regprog_T *prog, int *list); static void nfa_restore_listids(nfa_regprog_T *prog, int *list); static int nfa_re_num_cmp(long_u val, int op, long_u pos); ! static long nfa_regtry(nfa_regprog_T *prog, colnr_T col, proftime_T *tm); ! static long nfa_regexec_both(char_u *line, colnr_T col, proftime_T *tm); static regprog_T *nfa_regcomp(char_u *expr, int re_flags); static void nfa_regfree(regprog_T *prog); static int nfa_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col, int line_lbr); ! static long nfa_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf, linenr_T lnum, colnr_T col, proftime_T *tm); static int match_follows(nfa_state_T *startstate, int depth); static int failure_chance(nfa_state_T *state, int depth); --- 311,322 ---- static void nfa_save_listids(nfa_regprog_T *prog, int *list); static void nfa_restore_listids(nfa_regprog_T *prog, int *list); static int nfa_re_num_cmp(long_u val, int op, long_u pos); ! static long nfa_regtry(nfa_regprog_T *prog, colnr_T col, proftime_T *tm, int *timed_out); ! static long nfa_regexec_both(char_u *line, colnr_T col, proftime_T *tm, int *timed_out); static regprog_T *nfa_regcomp(char_u *expr, int re_flags); static void nfa_regfree(regprog_T *prog); static int nfa_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col, int line_lbr); ! static long nfa_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf, linenr_T lnum, colnr_T col, proftime_T *tm, int *timed_out); static int match_follows(nfa_state_T *startstate, int depth); static int failure_chance(nfa_state_T *state, int depth); *************** *** 3959,3964 **** --- 3959,3965 ---- static int nfa_match; #ifdef FEAT_RELTIME static proftime_T *nfa_time_limit; + static int *nfa_timed_out; static int nfa_time_count; #endif *************** *** 5508,5513 **** --- 5509,5528 ---- return 0L; } + #ifdef FEAT_RELTIME + static int + nfa_did_time_out() + { + if (nfa_time_limit != NULL && profile_passed_limit(nfa_time_limit)) + { + if (nfa_timed_out != NULL) + *nfa_timed_out = TRUE; + return TRUE; + } + return FALSE; + } + #endif + /* * Main matching routine. * *************** *** 5551,5557 **** if (got_int) return FALSE; #ifdef FEAT_RELTIME ! if (nfa_time_limit != NULL && profile_passed_limit(nfa_time_limit)) return FALSE; #endif --- 5566,5572 ---- if (got_int) return FALSE; #ifdef FEAT_RELTIME ! if (nfa_did_time_out()) return FALSE; #endif *************** *** 5694,5699 **** --- 5709,5727 ---- /* compute nextlist */ for (listidx = 0; listidx < thislist->n; ++listidx) { + /* If the list gets very long there probably is something wrong. + * At least allow interrupting with CTRL-C. */ + fast_breakcheck(); + if (got_int) + break; + #ifdef FEAT_RELTIME + if (nfa_time_limit != NULL && ++nfa_time_count == 20) + { + nfa_time_count = 0; + if (nfa_did_time_out()) + break; + } + #endif t = &thislist->t[listidx]; #ifdef NFA_REGEXP_DEBUG_LOG *************** *** 6915,6921 **** if (nfa_time_limit != NULL && ++nfa_time_count == 20) { nfa_time_count = 0; ! if (profile_passed_limit(nfa_time_limit)) break; } #endif --- 6943,6949 ---- if (nfa_time_limit != NULL && ++nfa_time_count == 20) { nfa_time_count = 0; ! if (nfa_did_time_out()) break; } #endif *************** *** 6948,6954 **** nfa_regtry( nfa_regprog_T *prog, colnr_T col, ! proftime_T *tm UNUSED) /* timeout limit or NULL */ { int i; regsubs_T subs, m; --- 6976,6983 ---- nfa_regtry( nfa_regprog_T *prog, colnr_T col, ! proftime_T *tm UNUSED, /* timeout limit or NULL */ ! int *timed_out UNUSED) /* flag set on timeout or NULL */ { int i; regsubs_T subs, m; *************** *** 6961,6966 **** --- 6990,6996 ---- reginput = regline + col; #ifdef FEAT_RELTIME nfa_time_limit = tm; + nfa_timed_out = timed_out; nfa_time_count = 0; #endif *************** *** 7087,7093 **** nfa_regexec_both( char_u *line, colnr_T startcol, /* column to start looking for match */ ! proftime_T *tm) /* timeout limit or NULL */ { nfa_regprog_T *prog; long retval = 0L; --- 7117,7124 ---- nfa_regexec_both( char_u *line, colnr_T startcol, /* column to start looking for match */ ! proftime_T *tm, /* timeout limit or NULL */ ! int *timed_out) /* flag set on timeout or NULL */ { nfa_regprog_T *prog; long retval = 0L; *************** *** 7181,7187 **** prog->state[i].lastlist[1] = 0; } ! retval = nfa_regtry(prog, col, tm); nfa_regengine.expr = NULL; --- 7212,7218 ---- prog->state[i].lastlist[1] = 0; } ! retval = nfa_regtry(prog, col, tm, timed_out); nfa_regengine.expr = NULL; *************** *** 7340,7346 **** rex.reg_icombine = FALSE; #endif rex.reg_maxcol = 0; ! return nfa_regexec_both(line, col, NULL); } --- 7371,7377 ---- rex.reg_icombine = FALSE; #endif rex.reg_maxcol = 0; ! return nfa_regexec_both(line, col, NULL, NULL); } *************** *** 7376,7382 **** buf_T *buf, /* buffer in which to search */ linenr_T lnum, /* nr of line to start looking for match */ colnr_T col, /* column to start looking for match */ ! proftime_T *tm) /* timeout limit or NULL */ { rex.reg_match = NULL; rex.reg_mmatch = rmp; --- 7407,7414 ---- buf_T *buf, /* buffer in which to search */ linenr_T lnum, /* nr of line to start looking for match */ colnr_T col, /* column to start looking for match */ ! proftime_T *tm, /* timeout limit or NULL */ ! int *timed_out) /* flag set on timeout or NULL */ { rex.reg_match = NULL; rex.reg_mmatch = rmp; *************** *** 7391,7397 **** #endif rex.reg_maxcol = rmp->rmm_maxcol; ! return nfa_regexec_both(NULL, col, tm); } #ifdef DEBUG --- 7423,7429 ---- #endif rex.reg_maxcol = rmp->rmm_maxcol; ! return nfa_regexec_both(NULL, col, tm, timed_out); } #ifdef DEBUG *** ../vim-8.0.0642/src/spell.c 2017-04-22 23:49:48.442047574 +0200 --- src/spell.c 2017-06-17 18:08:42.177692383 +0200 *************** *** 3675,3681 **** curwin->w_cursor.lnum = 0; while (!got_int) { ! if (do_search(NULL, '/', frompat, 1L, SEARCH_KEEP, NULL) == 0 || u_save_cursor() == FAIL) break; --- 3675,3681 ---- curwin->w_cursor.lnum = 0; while (!got_int) { ! if (do_search(NULL, '/', frompat, 1L, SEARCH_KEEP, NULL, NULL) == 0 || u_save_cursor() == FAIL) break; *** ../vim-8.0.0642/src/tag.c 2017-06-05 16:01:53.913848249 +0200 --- src/tag.c 2017-06-17 18:09:28.593351946 +0200 *************** *** 3308,3314 **** save_lnum = curwin->w_cursor.lnum; curwin->w_cursor.lnum = 0; /* start search before first line */ if (do_search(NULL, pbuf[0], pbuf + 1, (long)1, ! search_options, NULL)) retval = OK; else { --- 3308,3314 ---- save_lnum = curwin->w_cursor.lnum; curwin->w_cursor.lnum = 0; /* start search before first line */ if (do_search(NULL, pbuf[0], pbuf + 1, (long)1, ! search_options, NULL, NULL)) retval = OK; else { *************** *** 3320,3326 **** */ p_ic = TRUE; if (!do_search(NULL, pbuf[0], pbuf + 1, (long)1, ! search_options, NULL)) { /* * Failed to find pattern, take a guess: "^func (" --- 3320,3326 ---- */ p_ic = TRUE; if (!do_search(NULL, pbuf[0], pbuf + 1, (long)1, ! search_options, NULL, NULL)) { /* * Failed to find pattern, take a guess: "^func (" *************** *** 3331,3343 **** *tagp.tagname_end = NUL; sprintf((char *)pbuf, "^%s\\s\\*(", tagp.tagname); if (!do_search(NULL, '/', pbuf, (long)1, ! search_options, NULL)) { /* Guess again: "^char * \w_cursor; subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L, ! options, RE_SEARCH, (linenr_T)lnum_stop, &tm); if (subpatnum != FAIL) { if (flags & SP_SUBPAT) --- 9281,9287 ---- pos = save_cursor = curwin->w_cursor; subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L, ! options, RE_SEARCH, (linenr_T)lnum_stop, &tm, NULL); if (subpatnum != FAIL) { if (flags & SP_SUBPAT) *************** *** 9619,9625 **** for (;;) { n = searchit(curwin, curbuf, &pos, dir, pat, 1L, ! options, RE_SEARCH, lnum_stop, &tm); if (n == FAIL || (firstpos.lnum != 0 && EQUAL_POS(pos, firstpos))) /* didn't find it or found the first match again: FAIL */ break; --- 9619,9625 ---- for (;;) { n = searchit(curwin, curbuf, &pos, dir, pat, 1L, ! options, RE_SEARCH, lnum_stop, &tm, NULL); if (n == FAIL || (firstpos.lnum != 0 && EQUAL_POS(pos, firstpos))) /* didn't find it or found the first match again: FAIL */ break; *** ../vim-8.0.0642/src/ex_docmd.c 2017-06-04 20:43:43.956009665 +0200 --- src/ex_docmd.c 2017-06-17 18:14:53.714969622 +0200 *************** *** 4556,4562 **** curwin->w_cursor.col = 0; searchcmdlen = 0; if (!do_search(NULL, c, cmd, 1L, ! SEARCH_HIS | SEARCH_MSG, NULL)) { curwin->w_cursor = pos; cmd = NULL; --- 4556,4562 ---- curwin->w_cursor.col = 0; searchcmdlen = 0; if (!do_search(NULL, c, cmd, 1L, ! SEARCH_HIS | SEARCH_MSG, NULL, NULL)) { curwin->w_cursor = pos; cmd = NULL; *************** *** 4613,4619 **** if (searchit(curwin, curbuf, &pos, *cmd == '?' ? BACKWARD : FORWARD, (char_u *)"", 1L, SEARCH_MSG, ! i, (linenr_T)0, NULL) != FAIL) lnum = pos.lnum; else { --- 4613,4619 ---- if (searchit(curwin, curbuf, &pos, *cmd == '?' ? BACKWARD : FORWARD, (char_u *)"", 1L, SEARCH_MSG, ! i, (linenr_T)0, NULL, NULL) != FAIL) lnum = pos.lnum; else { *** ../vim-8.0.0642/src/ex_getln.c 2017-04-30 19:39:32.650857838 +0200 --- src/ex_getln.c 2017-06-17 18:16:07.674428637 +0200 *************** *** 1693,1699 **** i = searchit(curwin, curbuf, &t, c == Ctrl_G ? FORWARD : BACKWARD, ccline.cmdbuff, count, search_flags, ! RE_SEARCH, 0, NULL); --emsg_off; if (i) { --- 1693,1699 ---- i = searchit(curwin, curbuf, &t, c == Ctrl_G ? FORWARD : BACKWARD, ccline.cmdbuff, count, search_flags, ! RE_SEARCH, 0, NULL, NULL); --emsg_off; if (i) { *************** *** 1903,1911 **** i = do_search(NULL, firstc, ccline.cmdbuff, count, SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK, #ifdef FEAT_RELTIME ! &tm #else ! NULL #endif ); --emsg_off; --- 1903,1911 ---- i = do_search(NULL, firstc, ccline.cmdbuff, count, SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK, #ifdef FEAT_RELTIME ! &tm, NULL #else ! NULL, NULL #endif ); --emsg_off; *** ../vim-8.0.0642/src/normal.c 2017-06-04 15:33:44.541488336 +0200 --- src/normal.c 2017-06-17 18:17:31.701816911 +0200 *************** *** 4358,4364 **** { valid = FALSE; t = searchit(curwin, curbuf, &curwin->w_cursor, FORWARD, ! pat, 1L, searchflags, RE_LAST, (linenr_T)0, NULL); if (curwin->w_cursor.lnum >= old_pos.lnum) t = FAIL; /* match after start is failure too */ --- 4358,4364 ---- { valid = FALSE; t = searchit(curwin, curbuf, &curwin->w_cursor, FORWARD, ! pat, 1L, searchflags, RE_LAST, (linenr_T)0, NULL, NULL); if (curwin->w_cursor.lnum >= old_pos.lnum) t = FAIL; /* match after start is failure too */ *************** *** 6380,6386 **** curwin->w_set_curswant = TRUE; i = do_search(cap->oap, dir, pat, cap->count1, ! opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, NULL); if (i == 0) clearop(cap->oap); else --- 6380,6386 ---- curwin->w_set_curswant = TRUE; i = do_search(cap->oap, dir, pat, cap->count1, ! opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, NULL, NULL); if (i == 0) clearop(cap->oap); else *** ../vim-8.0.0642/src/version.c 2017-06-13 19:38:33.301791799 +0200 --- src/version.c 2017-06-17 18:26:02.866059733 +0200 *************** *** 766,767 **** --- 766,769 ---- { /* Add new patch number below this line */ + /**/ + 643, /**/ -- A fine is a tax for doing wrong. A tax is a fine for doing well. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///