# HG changeset patch # User Bram Moolenaar # Date 1655411403 -7200 # Node ID d1e263ecf6348796648318d456ed0457089c2ff0 # Parent f96e0bc4494b92d93048dd4549a9089da3de4157 patch 8.2.5114: time limit on searchpair() does not work properly Commit: https://github.com/vim/vim/commit/5ea38d1e7fd597ffde13b292d43e12747f20e97f Author: Bram Moolenaar Date: Thu Jun 16 21:20:48 2022 +0100 patch 8.2.5114: time limit on searchpair() does not work properly Problem: Time limit on searchpair() does not work properly. Solution: Set the time limit once instead of for each regexp. (closes https://github.com/vim/vim/issues/10562) diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -8975,6 +8975,10 @@ do_searchpair( if (skip != NULL) use_skip = eval_expr_valid_arg(skip); +#ifdef FEAT_RELTIME + if (time_limit > 0) + init_regexp_timeout(time_limit); +#endif save_cursor = curwin->w_cursor; pos = curwin->w_cursor; CLEAR_POS(&firstpos); @@ -8986,9 +8990,6 @@ do_searchpair( CLEAR_FIELD(sia); sia.sa_stop_lnum = lnum_stop; -#ifdef FEAT_RELTIME - sia.sa_tm = time_limit; -#endif n = searchit(curwin, curbuf, &pos, NULL, dir, pat, 1L, options, RE_SEARCH, &sia); if (n == FAIL || (firstpos.lnum != 0 && EQUAL_POS(pos, firstpos))) @@ -9074,6 +9075,9 @@ do_searchpair( curwin->w_cursor = save_cursor; theend: +#ifdef FEAT_RELTIME + disable_regexp_timeout(); +#endif vim_free(pat2); vim_free(pat3); if (p_cpo == empty_option) diff --git a/src/search.c b/src/search.c --- a/src/search.c +++ b/src/search.c @@ -674,10 +674,10 @@ searchit( stop_lnum = extra_arg->sa_stop_lnum; #ifdef FEAT_RELTIME if (extra_arg->sa_tm > 0) - { init_regexp_timeout(extra_arg->sa_tm); - timed_out = &extra_arg->sa_timed_out; - } + // Also set the pointer when sa_tm is zero, the caller may have set the + // timeout. + timed_out = &extra_arg->sa_timed_out; #endif } @@ -1105,9 +1105,10 @@ searchit( } while (--count > 0 && found); // stop after count matches or no match -# ifdef FEAT_RELTIME - disable_regexp_timeout(); -# endif +#ifdef FEAT_RELTIME + if (extra_arg != NULL && extra_arg->sa_tm > 0) + disable_regexp_timeout(); +#endif vim_regfree(regmatch.regprog); if (!found) // did not find it @@ -4859,7 +4860,7 @@ do_fuzzymatch(typval_T *argvars, typval_ // get the fuzzy matches ret = rettv_list_alloc(rettv); - if (ret != OK) + if (ret == FAIL) goto done; if (retmatchpos) { diff --git a/src/testdir/test_search.vim b/src/testdir/test_search.vim --- a/src/testdir/test_search.vim +++ b/src/testdir/test_search.vim @@ -328,7 +328,31 @@ func Test_searchpair() call assert_equal(3, searchpair('\', '\', '\', 'W')) call assert_equal([0, 3, 3, 0], getpos('.')) - q! + bwipe! +endfunc + +func Test_searchpair_timeout() + CheckFeature reltime + + func Waitabit() + sleep 20m + return 1 " skip match + endfunc + + new + call setline(1, range(100)) + call setline(1, "(start here") + call setline(100, "end here)") + let starttime = reltime() + + " A timeout of 100 msec should happen after about five times of 20 msec wait + " in Waitabit(). When the timeout applies to each search the elapsed time + " will be much longer. + call assert_equal(0, searchpair('(', '\d', ')', '', "Waitabit()", 0, 100)) + let elapsed = reltime(starttime)->reltimefloat() + call assert_inrange(0.09, 0.300, elapsed) + + bwipe! endfunc func Test_searchpairpos() diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -735,6 +735,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 5114, +/**/ 5113, /**/ 5112,