]> granicus.if.org Git - vim/commitdiff
patch 8.0.0643: when a pattern search is slow Vim becomes unusable v8.0.0643
authorBram Moolenaar <Bram@vim.org>
Sat, 17 Jun 2017 16:44:21 +0000 (18:44 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 17 Jun 2017 16:44:21 +0000 (18:44 +0200)
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.

19 files changed:
src/edit.c
src/evalfunc.c
src/ex_cmds.c
src/ex_docmd.c
src/ex_getln.c
src/gui.c
src/normal.c
src/proto/regexp.pro
src/proto/search.pro
src/quickfix.c
src/regexp.c
src/regexp.h
src/regexp_nfa.c
src/screen.c
src/search.c
src/spell.c
src/syntax.c
src/tag.c
src/version.c

index 89a5fae072f1355230a0110a39d8e23c63e67aef..da1b238d878aba684a733ec837acef25cc3d2838 100644 (file)
@@ -4512,7 +4512,7 @@ ins_compl_get_exp(pos_T *ini)
                    found_new_match = searchit(NULL, ins_buf, pos,
                                                              compl_direction,
                                 compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG,
-                                                 RE_LAST, (linenr_T)0, NULL);
+                                            RE_LAST, (linenr_T)0, NULL, NULL);
                --msg_silent;
                if (!compl_started || set_match_pos)
                {
index 8167abd60f9b855108ca813b61f2bd6fac6a6ed7..2bbdefc6ef2d254d3f0df992e888e3bb73716865 100644 (file)
@@ -9281,7 +9281,7 @@ search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
 
     pos = save_cursor = curwin->w_cursor;
     subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L,
-                               options, RE_SEARCH, (linenr_T)lnum_stop, &tm);
+                          options, RE_SEARCH, (linenr_T)lnum_stop, &tm, NULL);
     if (subpatnum != FAIL)
     {
        if (flags & SP_SUBPAT)
@@ -9619,7 +9619,7 @@ do_searchpair(
     for (;;)
     {
        n = searchit(curwin, curbuf, &pos, dir, pat, 1L,
-                                          options, RE_SEARCH, lnum_stop, &tm);
+                                    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;
index 859b8c65bfe25db0f65ad5a0f4082fc590ecd65f..59531bea0cca881ee6d53d55e9579aa2a0077097 100644 (file)
@@ -5096,7 +5096,7 @@ do_sub(exarg_T *eap)
                ); ++lnum)
     {
        nmatch = vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
-                                                           (colnr_T)0, NULL);
+                                                      (colnr_T)0, NULL, NULL);
        if (nmatch)
        {
            colnr_T     copycol;
@@ -5695,7 +5695,7 @@ skip:
                        || nmatch_tl > 0
                        || (nmatch = vim_regexec_multi(&regmatch, curwin,
                                                        curbuf, sub_firstlnum,
-                                                        matchcol, NULL)) == 0
+                                                   matchcol, NULL, NULL)) == 0
                        || regmatch.startpos[0].lnum > 0)
                {
                    if (new_start != NULL)
@@ -5760,7 +5760,7 @@ skip:
                    }
                    if (nmatch == -1 && !lastone)
                        nmatch = vim_regexec_multi(&regmatch, curwin, curbuf,
-                                              sub_firstlnum, matchcol, NULL);
+                                         sub_firstlnum, matchcol, NULL, NULL);
 
                    /*
                     * 5. break if there isn't another match in this line
@@ -6012,7 +6012,7 @@ ex_global(exarg_T *eap)
     {
        lnum = curwin->w_cursor.lnum;
        match = vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
-                                                            (colnr_T)0, NULL);
+                                                      (colnr_T)0, NULL, NULL);
        if ((type == 'g' && match) || (type == 'v' && !match))
            global_exe_one(cmd, lnum);
     }
@@ -6025,7 +6025,7 @@ ex_global(exarg_T *eap)
        {
            /* a match on this line? */
            match = vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
-                                                            (colnr_T)0, NULL);
+                                                      (colnr_T)0, NULL, NULL);
            if ((type == 'g' && match) || (type == 'v' && !match))
            {
                ml_setmarked(lnum);
index bf340de4057b445ec2a42bd1e6af07255c582867..9dac9bf3a7243c39b04c663062bf2c47130744e0 100644 (file)
@@ -4556,7 +4556,7 @@ get_address(
                        curwin->w_cursor.col = 0;
                    searchcmdlen = 0;
                    if (!do_search(NULL, c, cmd, 1L,
-                                      SEARCH_HIS | SEARCH_MSG, NULL))
+                                         SEARCH_HIS | SEARCH_MSG, NULL, NULL))
                    {
                        curwin->w_cursor = pos;
                        cmd = NULL;
@@ -4613,7 +4613,7 @@ get_address(
                    if (searchit(curwin, curbuf, &pos,
                                *cmd == '?' ? BACKWARD : FORWARD,
                                (char_u *)"", 1L, SEARCH_MSG,
-                                       i, (linenr_T)0, NULL) != FAIL)
+                                       i, (linenr_T)0, NULL, NULL) != FAIL)
                        lnum = pos.lnum;
                    else
                    {
index c7a6d852dfa971d5c98e91e0283c5c80ad410049..194b3bf3d8b75aacfced4d9c41699d68f32a0e50 100644 (file)
@@ -1693,7 +1693,7 @@ getcmdline(
                    i = searchit(curwin, curbuf, &t,
                                 c == Ctrl_G ? FORWARD : BACKWARD,
                                 ccline.cmdbuff, count, search_flags,
-                                RE_SEARCH, 0, NULL);
+                                RE_SEARCH, 0, NULL, NULL);
                    --emsg_off;
                    if (i)
                    {
@@ -1903,9 +1903,9 @@ cmdline_changed:
                i = do_search(NULL, firstc, ccline.cmdbuff, count,
                        SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK,
 #ifdef FEAT_RELTIME
-                       &tm
+                       &tm, NULL
 #else
-                       NULL
+                       NULL, NULL
 #endif
                        );
                --emsg_off;
index 25310aafd48f282fab909591f0feef5e363297b5..ff81d0b749dc48f0df940a6b9cc226ce0bd2fbc1 100644 (file)
--- a/src/gui.c
+++ b/src/gui.c
@@ -5361,7 +5361,7 @@ gui_do_findrepl(
            searchflags += SEARCH_START;
        i = msg_scroll;
        (void)do_search(NULL, down ? '/' : '?', ga.ga_data, 1L,
-                                                          searchflags, NULL);
+                                                     searchflags, NULL, NULL);
        msg_scroll = i;     /* don't let an error message set msg_scroll */
     }
 
index 7b3f94af529d264a03cf5130daaa2ef119c27124..74a5efec99399f6f10a7787e3911b5663156f364 100644 (file)
@@ -4358,7 +4358,7 @@ find_decl(
     {
        valid = FALSE;
        t = searchit(curwin, curbuf, &curwin->w_cursor, FORWARD,
-                           pat, 1L, searchflags, RE_LAST, (linenr_T)0, NULL);
+                      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,7 +6380,7 @@ normal_search(
     curwin->w_set_curswant = TRUE;
 
     i = do_search(cap->oap, dir, pat, cap->count1,
-                          opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, NULL);
+                     opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, NULL, NULL);
     if (i == 0)
        clearop(cap->oap);
     else
index dfe5c91d52c7387fca90b0ac51305c6fdd784412..d22a83b0eef71812b904add707f5f32fb64b9dcc 100644 (file)
@@ -16,5 +16,5 @@ void vim_regfree(regprog_T *prog);
 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);
+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 : */
index 3b9ca5c74aedc53e8900b7a5667481516b6724b1..63955adee0d3857f9e088eb14e0db031bdeac62d 100644 (file)
@@ -19,9 +19,9 @@ char_u *last_search_pat(void);
 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 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 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);
index 61e96ddc42b379bf8bc9576aae6847962292a63b..f4bc5974ea7f306eaa98cbcd526afdfd59dd7809 100644 (file)
@@ -2415,7 +2415,7 @@ win_found:
            save_cursor = curwin->w_cursor;
            curwin->w_cursor.lnum = 0;
            if (!do_search(NULL, '/', qf_ptr->qf_pattern, (long)1,
-                                                          SEARCH_KEEP, NULL))
+                                                     SEARCH_KEEP, NULL, NULL))
                curwin->w_cursor = save_cursor;
        }
 
@@ -4237,7 +4237,7 @@ ex_vimgrep(exarg_T *eap)
            {
                col = 0;
                while (vim_regexec_multi(&regmatch, curwin, buf, lnum,
-                                                              col, NULL) > 0)
+                                                         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
index a27c594c2a7a7152571f6716908d85bcc3d1944b..74a73c44083ed6482ceaa0f3b1437877b24aa76f 100644 (file)
@@ -3479,7 +3479,7 @@ typedef struct regbehind_S
 } 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    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,7 +3722,7 @@ bt_regexec_nl(
 #endif
     rex.reg_maxcol = 0;
 
-    return bt_regexec_both(line, col, NULL);
+    return bt_regexec_both(line, col, NULL, NULL);
 }
 
 /*
@@ -3740,7 +3740,8 @@ bt_regexec_multi(
     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 */
+    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,7 +3756,7 @@ bt_regexec_multi(
 #endif
     rex.reg_maxcol = rmp->rmm_maxcol;
 
-    return bt_regexec_both(NULL, col, tm);
+    return bt_regexec_both(NULL, col, tm, timed_out);
 }
 
 /*
@@ -3767,7 +3768,8 @@ bt_regexec_multi(
 bt_regexec_both(
     char_u     *line,
     colnr_T    col,            /* column to start looking for match */
-    proftime_T *tm UNUSED)     /* timeout limit or NULL */
+    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,7 +3970,11 @@ bt_regexec_both(
            {
                tm_count = 0;
                if (profile_passed_limit(tm))
+               {
+                   if (timed_out != NULL)
+                       *timed_out = TRUE;
                    break;
+               }
            }
 #endif
        }
@@ -8308,7 +8314,8 @@ vim_regexec_multi(
     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 */
+    proftime_T *tm,            /* timeout limit or NULL */
+    int                *timed_out)     /* flag is set when timeout limit reached */
 {
     int                result;
     regexec_T  rex_save;
@@ -8319,7 +8326,8 @@ vim_regexec_multi(
        rex_save = rex;
     rex_in_use = TRUE;
 
-    result = rmp->regprog->engine->regexec_multi(rmp, win, buf, lnum, col, tm);
+    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,7 +8347,7 @@ vim_regexec_multi(
            rmp->regprog = vim_regcomp(pat, re_flags);
            if (rmp->regprog != NULL)
                result = rmp->regprog->engine->regexec_multi(
-                                               rmp, win, buf, lnum, col, tm);
+                                     rmp, win, buf, lnum, col, tm, timed_out);
            vim_free(pat);
        }
        p_re = save_p_re;
index 79c1e7d82176adebfa09bdcbf69d2e7b4d5761f3..a3526e69755911c66068a349255f5500bb953c12 100644 (file)
@@ -165,8 +165,8 @@ struct regengine
 {
     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                (*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;
 };
 
index 4e111f169fffa6c541154079d9e4a7958d57d741..5ba80f2fedbe58f84c2a803130b8bd3999427a9f 100644 (file)
@@ -311,12 +311,12 @@ static int check_char_class(int class, int c);
 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 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);
+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,6 +3959,7 @@ pim_info(nfa_pim_T *pim)
 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,6 +5509,20 @@ find_match_text(colnr_T startcol, int regstart, char_u *match_text)
     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,7 +5566,7 @@ nfa_regmatch(
     if (got_int)
        return FALSE;
 #ifdef FEAT_RELTIME
-    if (nfa_time_limit != NULL && profile_passed_limit(nfa_time_limit))
+    if (nfa_did_time_out())
        return FALSE;
 #endif
 
@@ -5694,6 +5709,19 @@ nfa_regmatch(
        /* 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,7 +6943,7 @@ nextchar:
        if (nfa_time_limit != NULL && ++nfa_time_count == 20)
        {
            nfa_time_count = 0;
-           if (profile_passed_limit(nfa_time_limit))
+           if (nfa_did_time_out())
                break;
        }
 #endif
@@ -6948,7 +6976,8 @@ theend:
 nfa_regtry(
     nfa_regprog_T   *prog,
     colnr_T        col,
-    proftime_T     *tm UNUSED) /* timeout limit or NULL */
+    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,6 +6990,7 @@ nfa_regtry(
     reginput = regline + col;
 #ifdef FEAT_RELTIME
     nfa_time_limit = tm;
+    nfa_timed_out = timed_out;
     nfa_time_count = 0;
 #endif
 
@@ -7087,7 +7117,8 @@ nfa_regtry(
 nfa_regexec_both(
     char_u     *line,
     colnr_T    startcol,       /* column to start looking for match */
-    proftime_T *tm)            /* timeout limit or NULL */
+    proftime_T *tm,            /* timeout limit or NULL */
+    int                *timed_out)     /* flag set on timeout or NULL */
 {
     nfa_regprog_T   *prog;
     long           retval = 0L;
@@ -7181,7 +7212,7 @@ nfa_regexec_both(
        prog->state[i].lastlist[1] = 0;
     }
 
-    retval = nfa_regtry(prog, col, tm);
+    retval = nfa_regtry(prog, col, tm, timed_out);
 
     nfa_regengine.expr = NULL;
 
@@ -7340,7 +7371,7 @@ nfa_regexec_nl(
     rex.reg_icombine = FALSE;
 #endif
     rex.reg_maxcol = 0;
-    return nfa_regexec_both(line, col, NULL);
+    return nfa_regexec_both(line, col, NULL, NULL);
 }
 
 
@@ -7376,7 +7407,8 @@ nfa_regexec_multi(
     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 */
+    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,7 +7423,7 @@ nfa_regexec_multi(
 #endif
     rex.reg_maxcol = rmp->rmm_maxcol;
 
-    return nfa_regexec_both(NULL, col, tm);
+    return nfa_regexec_both(NULL, col, tm, timed_out);
 }
 
 #ifdef DEBUG
index f10f70dc5e73ff2651941c2ee27b7474777bdb51..c6d8f0ee4adbe0d53f2d45ba736a562c533eb8bc 100644 (file)
@@ -7800,20 +7800,21 @@ next_search_hl(
            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)
+                   &(shl->tm), &timed_out
 #else
-                   NULL
+                   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)
+           if (called_emsg || got_int || timed_out)
            {
                /* Error while handling regexp: stop using this regexp. */
                if (shl == &search_hl)
index 9470073417697b310cccde29290e7fc48b3fda21..ac1192725adf1f77491c1f2b60a471cda228d0ef 100644 (file)
@@ -593,7 +593,8 @@ searchit(
     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 */
+    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,13 +716,17 @@ searchit(
                nmatched = vim_regexec_multi(&regmatch, win, buf,
                                             lnum, col,
 #ifdef FEAT_RELTIME
-                                            tm
+                                            tm, timed_out
 #else
-                                            NULL
+                                            NULL, NULL
 #endif
                                                      );
                /* Abort searching on an error (e.g., out of stack). */
-               if (called_emsg)
+               if (called_emsg
+#ifdef FEAT_RELTIME
+                       || (timed_out != NULL && *timed_out)
+#endif
+                       )
                    break;
                if (nmatched > 0)
                {
@@ -810,9 +815,9 @@ searchit(
                                              win, buf, lnum + matchpos.lnum,
                                              matchcol,
 #ifdef FEAT_RELTIME
-                                             tm
+                                             tm, timed_out
 #else
-                                             NULL
+                                             NULL, NULL
 #endif
                                              )) == 0)
                            {
@@ -922,9 +927,9 @@ searchit(
                                              win, buf, lnum + matchpos.lnum,
                                              matchcol,
 #ifdef FEAT_RELTIME
-                                             tm
+                                             tm, timed_out
 #else
-                                             NULL
+                                             NULL, NULL
 #endif
                                            )) == 0)
                                break;
@@ -1019,10 +1024,13 @@ searchit(
             * 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
+                               || break_loop
 #endif
-                                              || found || loop)
+                               || found || loop)
                break;
 
            /*
@@ -1041,6 +1049,9 @@ searchit(
                                          ? 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,7 +1158,8 @@ do_search(
     char_u         *pat,
     long           count,
     int                    options,
-    proftime_T     *tm)        /* timeout limit or NULL */
+    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,7 +1445,7 @@ do_search(
                       (SEARCH_KEEP + SEARCH_PEEK + SEARCH_HIS
                        + SEARCH_MSG + SEARCH_START
                        + ((pat != NULL && *pat == ';') ? 0 : SEARCH_NOOF))),
-               RE_LAST, (linenr_T)0, tm);
+               RE_LAST, (linenr_T)0, tm, timed_out);
 
        if (dircp != NULL)
            *dircp = dirc;      /* restore second '/' or '?' for normal_cmd() */
@@ -4672,7 +4684,7 @@ current_search(
 
        result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD),
                spats[last_idx].pat, (long) (i ? count : 1),
-               SEARCH_KEEP | flags, RE_SEARCH, 0, NULL);
+               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,7 +4731,8 @@ current_search(
      * 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);
+                   spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0,
+                                                                  NULL, NULL);
 
     if (!VIsual_active)
        VIsual = start_pos;
@@ -4800,7 +4813,7 @@ is_one_char(char_u *pattern, int move, pos_T *cur)
     }
 
     if (searchit(curwin, curbuf, &pos, FORWARD, pattern, 1,
-                             SEARCH_KEEP + flag, RE_SEARCH, 0, NULL) != FAIL)
+                        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,7 +4822,7 @@ is_one_char(char_u *pattern, int move, pos_T *cur)
        {
            regmatch.startpos[0].col++;
            nmatched = vim_regexec_multi(&regmatch, curwin, curbuf,
-                                           pos.lnum, regmatch.startpos[0].col, NULL);
+                              pos.lnum, regmatch.startpos[0].col, NULL, NULL);
            if (!nmatched)
                break;
        } while (regmatch.startpos[0].col < pos.col);
index 118e78bc0e0d12380239ab0d785d5504ff3c97ac..0eb87638eb8f6113b7d8bc1f06ddb571d0571db6 100644 (file)
@@ -3675,7 +3675,7 @@ ex_spellrepall(exarg_T *eap UNUSED)
     curwin->w_cursor.lnum = 0;
     while (!got_int)
     {
-       if (do_search(NULL, '/', frompat, 1L, SEARCH_KEEP, NULL) == 0
+       if (do_search(NULL, '/', frompat, 1L, SEARCH_KEEP, NULL, NULL) == 0
                                                   || u_save_cursor() == FAIL)
            break;
 
index 56d69c6df548b72e726feb400ebcdc98c63460b8..a7b308487f506a5109cb0ced6a045ddb388418ed 100644 (file)
@@ -3303,7 +3303,7 @@ syn_regexec(
 #endif
 
     rmp->rmm_maxcol = syn_buf->b_p_smc;
-    r = vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col, NULL);
+    r = vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col, NULL, NULL);
 
 #ifdef FEAT_PROFILE
     if (syn_time_on)
index ff404748e52a04fe00793385d1ddb8c935caad85..76fbd513e2feed3330822a5bfe84e6658cbc6a84 100644 (file)
--- a/src/tag.c
+++ b/src/tag.c
@@ -3308,7 +3308,7 @@ jumpto_tag(
            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))
+                                                  search_options, NULL, NULL))
                retval = OK;
            else
            {
@@ -3320,7 +3320,7 @@ jumpto_tag(
                 */
                p_ic = TRUE;
                if (!do_search(NULL, pbuf[0], pbuf + 1, (long)1,
-                                                       search_options, NULL))
+                                                  search_options, NULL, NULL))
                {
                    /*
                     * Failed to find pattern, take a guess: "^func  ("
@@ -3331,13 +3331,13 @@ jumpto_tag(
                    *tagp.tagname_end = NUL;
                    sprintf((char *)pbuf, "^%s\\s\\*(", tagp.tagname);
                    if (!do_search(NULL, '/', pbuf, (long)1,
-                                                       search_options, NULL))
+                                                  search_options, NULL, NULL))
                    {
                        /* Guess again: "^char * \<func  (" */
                        sprintf((char *)pbuf, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
                                                                tagp.tagname);
                        if (!do_search(NULL, '/', pbuf, (long)1,
-                                                       search_options, NULL))
+                                                  search_options, NULL, NULL))
                            found = 0;
                    }
                    *tagp.tagname_end = cc;
index 6f5c8938e3fa4f377f763516c769232785f9d9c4..268d4d7d20f29072158d5bc59c8bb2d361d57b74 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    643,
 /**/
     642,
 /**/