diff --git a/src/nvim/path.c b/src/nvim/path.c index cf7cd98829..21a3a67e24 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -620,7 +620,7 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in static int stardepth = 0; // depth for "**" expansion // Expanding "**" may take a long time, check for CTRL-C. - if (stardepth > 0) { + if (stardepth > 0 && !(flags & EW_NOBREAK)) { os_breakcheck(); if (got_int) { return 0; @@ -701,7 +701,8 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in if (flags & (EW_NOERROR | EW_NOTWILD)) { emsg_silent++; } - regmatch.regprog = vim_regcomp(pat, RE_MAGIC); + bool nobreak = (flags & EW_NOBREAK); + regmatch.regprog = vim_regcomp(pat, RE_MAGIC | (nobreak ? RE_NOBREAK : 0)); if (flags & (EW_NOERROR | EW_NOTWILD)) { emsg_silent--; } diff --git a/src/nvim/path.h b/src/nvim/path.h index c8d192dffe..eaadc7f37d 100644 --- a/src/nvim/path.h +++ b/src/nvim/path.h @@ -26,6 +26,7 @@ #define EW_DODOT 0x4000 // also files starting with a dot #define EW_EMPTYOK 0x8000 // no matches is not an error #define EW_NOTENV 0x10000 // do not expand environment variables +#define EW_NOBREAK 0x20000 // do not invoke breakcheck /// Return value for the comparison of two files. Also @see path_full_compare. typedef enum file_comparison { diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 3ed32bf8af..b5cffb17d0 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -989,6 +989,8 @@ typedef struct { // flag in the regexp. Defaults to false, always. bool reg_icombine; + bool reg_nobreak; + // Copy of "rmm_maxcol": maximum column to search for a match. Zero when // there is no maximum. colnr_T reg_maxcol; @@ -1011,6 +1013,13 @@ typedef struct { static regexec_T rex; static bool rex_in_use = false; +static void reg_breakcheck(void) +{ + if (!rex.reg_nobreak) { + fast_breakcheck(); + } +} + // Return true if character 'c' is included in 'iskeyword' option for // "reg_buf" buffer. static bool reg_iswordc(int c) @@ -1221,7 +1230,7 @@ static void reg_nextline(void) { rex.line = (uint8_t *)reg_getline(++rex.lnum); rex.input = rex.line; - fast_breakcheck(); + reg_breakcheck(); } // Check whether a backreference matches. @@ -2265,6 +2274,7 @@ static void init_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf, linenr_ rex.reg_line_lbr = false; rex.reg_ic = rmp->rmm_ic; rex.reg_icombine = false; + rex.reg_nobreak = rmp->regprog->re_flags & RE_NOBREAK; rex.reg_maxcol = rmp->rmm_maxcol; } diff --git a/src/nvim/regexp.h b/src/nvim/regexp.h index dcc58fa34c..95296a5f90 100644 --- a/src/nvim/regexp.h +++ b/src/nvim/regexp.h @@ -10,6 +10,7 @@ #define RE_STRING 2 ///< match in string instead of buffer text #define RE_STRICT 4 ///< don't allow [abc] without ] #define RE_AUTO 8 ///< automatic engine selection +#define RE_NOBREAK 16 ///< don't use breakcheck functions // values for reg_do_extmatch #define REX_SET 1 ///< to allow \z\(...\), diff --git a/src/nvim/regexp_bt.c b/src/nvim/regexp_bt.c index af3d93f7c4..a6f554d4ae 100644 --- a/src/nvim/regexp_bt.c +++ b/src/nvim/regexp_bt.c @@ -3539,7 +3539,7 @@ static bool regmatch(uint8_t *scan, proftime_T *tm, int *timed_out) for (;;) { // Some patterns may take a long time to match, e.g., "\([a-z]\+\)\+Q". // Allow interrupting them with CTRL-C. - fast_breakcheck(); + reg_breakcheck(); #ifdef REGEXP_DEBUG if (scan != NULL && regnarrate) { @@ -4792,7 +4792,7 @@ static bool regmatch(uint8_t *scan, proftime_T *tm, int *timed_out) break; } rex.input = rex.line + strlen((char *)rex.line); - fast_breakcheck(); + reg_breakcheck(); } else { MB_PTR_BACK(rex.line, rex.input); } @@ -5155,6 +5155,7 @@ static int bt_regexec_nl(regmatch_T *rmp, uint8_t *line, colnr_T col, bool line_ rex.reg_win = NULL; rex.reg_ic = rmp->rm_ic; rex.reg_icombine = false; + rex.reg_nobreak = rmp->regprog->re_flags & RE_NOBREAK; rex.reg_maxcol = 0; long r = bt_regexec_both(line, col, NULL, NULL); diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 260d40a202..69d4f00ee5 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -5890,7 +5890,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm regsubs_T *r; // Some patterns may take a long time to match, especially when using // recursive_regmatch(). Allow interrupting them with CTRL-C. - fast_breakcheck(); + reg_breakcheck(); if (got_int) { return false; } @@ -6020,7 +6020,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm 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(); + reg_breakcheck(); if (got_int) { break; } @@ -7168,7 +7168,7 @@ nextchar: } // Allow interrupting with CTRL-C. - line_breakcheck(); + reg_breakcheck(); if (got_int) { break; } @@ -7591,6 +7591,7 @@ static int nfa_regexec_nl(regmatch_T *rmp, uint8_t *line, colnr_T col, bool line rex.reg_win = NULL; rex.reg_ic = rmp->rm_ic; rex.reg_icombine = false; + rex.reg_nobreak = rmp->regprog->re_flags & RE_NOBREAK; rex.reg_maxcol = 0; return (int)nfa_regexec_both(line, col, NULL, NULL); } diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 401139a89a..a6ed5c7410 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -470,7 +470,8 @@ int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, void *c } int ew_flags = ((flags & DIP_DIR) ? EW_DIR : EW_FILE) - | (flags & DIP_DIRFILE) ? (EW_DIR|EW_FILE) : 0; + | ((flags & DIP_DIRFILE) ? (EW_DIR|EW_FILE) : 0) + | EW_NOBREAK; // Expand wildcards, invoke the callback for each match. char *(pat[]) = { buf }; @@ -670,7 +671,7 @@ static void expand_rtp_entry(RuntimeSearchPath *search_path, Map(String, handle_ int num_files; char **files; char *(pat[]) = { entry }; - if (gen_expand_wildcards(1, pat, &num_files, &files, EW_DIR) == OK) { + if (gen_expand_wildcards(1, pat, &num_files, &files, EW_DIR | EW_NOBREAK) == OK) { for (int i = 0; i < num_files; i++) { push_path(search_path, rtp_used, files[i], after); }