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(&regmatch, curwin, curbuf, lnum,
!                                                           (colnr_T)0, NULL);
        if (nmatch)
        {
            colnr_T     copycol;
--- 5096,5102 ----
                ); ++lnum)
      {
        nmatch = vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
!                                                      (colnr_T)0, NULL, NULL);
        if (nmatch)
        {
            colnr_T     copycol;
***************
*** 5695,5701 ****
                        || nmatch_tl > 0
                        || (nmatch = vim_regexec_multi(&regmatch, 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(&regmatch, 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(&regmatch, 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(&regmatch, 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(&regmatch, 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(&regmatch, 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(&regmatch, 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(&regmatch, 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(&regmatch, 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(&regmatch, 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(&regmatch, 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(&regmatch, 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(&regmatch, 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(&regmatch, 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 * \<func  (" */
                        sprintf((char *)pbuf, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
                                                                tagp.tagname);
                        if (!do_search(NULL, '/', pbuf, (long)1,
!                                                       search_options, NULL))
                            found = 0;
                    }
                    *tagp.tagname_end = cc;
--- 3331,3343 ----
                    *tagp.tagname_end = NUL;
                    sprintf((char *)pbuf, "^%s\\s\\*(", tagp.tagname);
                    if (!do_search(NULL, '/', pbuf, (long)1,
!                                                  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, NULL))
                            found = 0;
                    }
                    *tagp.tagname_end = cc;
*** ../vim-8.0.0642/src/gui.c   2017-06-05 13:31:52.503500012 +0200
--- src/gui.c   2017-06-17 18:09:41.253259106 +0200
***************
*** 5361,5367 ****
            searchflags += SEARCH_START;
        i = msg_scroll;
        (void)do_search(NULL, down ? '/' : '?', ga.ga_data, 1L,
!                                                          searchflags, NULL);
        msg_scroll = i;     /* don't let an error message set msg_scroll */
      }
  
--- 5361,5367 ----
            searchflags += SEARCH_START;
        i = msg_scroll;
        (void)do_search(NULL, down ? '/' : '?', ga.ga_data, 1L,
!                                                     searchflags, NULL, NULL);
        msg_scroll = i;     /* don't let an error message set msg_scroll */
      }
  
*** ../vim-8.0.0642/src/edit.c  2017-05-01 20:46:47.747526808 +0200
--- src/edit.c  2017-06-17 18:12:06.504194363 +0200
***************
*** 4512,4518 ****
                    found_new_match = searchit(NULL, ins_buf, pos,
                                                              compl_direction,
                                 compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG,
!                                                 RE_LAST, (linenr_T)0, NULL);
                --msg_silent;
                if (!compl_started || set_match_pos)
                {
--- 4512,4518 ----
                    found_new_match = searchit(NULL, ins_buf, pos,
                                                              compl_direction,
                                 compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG,
!                                            RE_LAST, (linenr_T)0, NULL, NULL);
                --msg_silent;
                if (!compl_started || set_match_pos)
                {
*** ../vim-8.0.0642/src/evalfunc.c      2017-06-13 19:38:33.301791799 +0200
--- src/evalfunc.c      2017-06-17 18:14:04.295331490 +0200
***************
*** 9281,9287 ****
  
      pos = save_cursor = curwin->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 -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui