aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/regexp.c
diff options
context:
space:
mode:
authorBilly Su <g4691821@gmail.com>2019-03-07 13:08:15 +0800
committerBilly Su <g4691821@gmail.com>2019-03-07 23:27:19 +0800
commit241b905b1378c5c45d8d284bb191b16807ff2a44 (patch)
treece1726447334ae05c894b1b7bd59718058a12a32 /src/nvim/regexp.c
parent5f84b1dc4154ea8def87b6113fa9b9ed058d83d2 (diff)
downloadrneovim-241b905b1378c5c45d8d284bb191b16807ff2a44.tar.gz
rneovim-241b905b1378c5c45d8d284bb191b16807ff2a44.tar.bz2
rneovim-241b905b1378c5c45d8d284bb191b16807ff2a44.zip
vim-patch:8.0.0643: when a pattern search is slow Vim becomes unusable
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. https://github.com/vim/vim/commit/fbd0b0af6800f6ff89857863d6a07ea03f09ff6c
Diffstat (limited to 'src/nvim/regexp.c')
-rw-r--r--src/nvim/regexp.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index c043d4a173..25fa67c112 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -3297,7 +3297,7 @@ bt_regexec_nl (
rex.reg_icombine = false;
rex.reg_maxcol = 0;
- long r = bt_regexec_both(line, col, NULL);
+ long r = bt_regexec_both(line, col, NULL, NULL);
assert(r <= INT_MAX);
return (int)r;
}
@@ -3357,7 +3357,8 @@ static inline char_u *cstrchr(const char_u *const s, const int c)
/// @return zero if there is no match and number of lines contained in the match
/// otherwise.
static long bt_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf,
- linenr_T lnum, colnr_T col, proftime_T *tm)
+ linenr_T lnum, colnr_T col,
+ proftime_T *tm, int *timed_out)
{
rex.reg_match = NULL;
rex.reg_mmatch = rmp;
@@ -3370,7 +3371,7 @@ static long bt_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf,
rex.reg_icombine = false;
rex.reg_maxcol = rmp->rmm_maxcol;
- return bt_regexec_both(NULL, col, tm);
+ return bt_regexec_both(NULL, col, tm, timed_out);
}
/*
@@ -3379,8 +3380,10 @@ static long bt_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf,
* Returns 0 for failure, number of lines contained in the match otherwise.
*/
static long bt_regexec_both(char_u *line,
- colnr_T col, /* column to start looking for match */
- proftime_T *tm /* timeout limit or NULL */
+ // column to start looking for match
+ colnr_T col,
+ proftime_T *tm, // timeout limit or NULL
+ int *timed_out // flag set on timeout or NULL
)
{
bt_regprog_T *prog;
@@ -3525,8 +3528,12 @@ static long bt_regexec_both(char_u *line,
/* Check for timeout once in a twenty times to avoid overhead. */
if (tm != NULL && ++tm_count == 20) {
tm_count = 0;
- if (profile_passed_limit(*tm))
+ if (profile_passed_limit(*tm)) {
+ if (timed_out != NULL) {
+ *timed_out = true;
+ }
break;
+ }
}
}
}
@@ -7275,12 +7282,13 @@ int vim_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col)
/// Return zero if there is no match. Return number of lines contained in the
/// match otherwise.
long vim_regexec_multi(
- regmmatch_T *rmp,
- win_T *win, /* window in which to search or NULL */
- 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 */
+ regmmatch_T *rmp,
+ win_T *win, // window in which to search or NULL
+ 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
)
{
regexec_T rex_save;
@@ -7293,7 +7301,7 @@ long vim_regexec_multi(
rex_in_use = true;
int result = rmp->regprog->engine->regexec_multi(rmp, win, buf, lnum, col,
- tm);
+ tm, timed_out);
// NFA engine aborted because it's very slow, use backtracking engine instead.
if (rmp->regprog->re_engine == AUTOMATIC_ENGINE
@@ -7313,7 +7321,7 @@ long vim_regexec_multi(
if (rmp->regprog != NULL) {
result = rmp->regprog->engine->regexec_multi(rmp, win, buf, lnum, col,
- tm);
+ tm, timed_out);
}
xfree(pat);