vim-patch:8.2.0915: search() cannot skip over matches like searchpair() can

Problem:    Search() cannot skip over matches like searchpair() can.
Solution:   Add an optional "skip" argument. (Christian Brabandt, closes vim/vim#861)
adc17a5f9d

Enable skip arg usage in autoload/freebasic.vim

evalarg_T doesn't really matter because it's deleted in v8.2.0918 (and
reincarnated for Vim9 script in v8.2.1047), but I found out too late :P Anyway:

- Port evalarg_T into eval.h and use const char * and Callback fields
- Use EVALARG_INIT to initialize
- Return bool over OK/FAIL from evalarg functions
- Remove check from evalarg_clean as callback_free ignores None callbacks anyway
- Move eva_buf field into evalarg_get as a local (not sure what reason it has
  being in the struct)

N/A patches for version.c:

vim-patch:8.2.4355: unnecessary call to check_colorcolumn()

Problem:    Unnecessary call to check_colorcolumn().
Solution:   Remove the call. (Sean Dewar, closes vim/vim#9748)
0f7ff851cb
This commit is contained in:
Sean Dewar
2022-02-01 12:44:14 +00:00
parent a7321e37a7
commit cdb2c10011
7 changed files with 189 additions and 12 deletions

View File

@@ -8237,6 +8237,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
int options = SEARCH_KEEP;
int subpatnum;
searchit_arg_T sia;
evalarg_T skip = EVALARG_INIT;
const char *const pat = tv_get_string(&argvars[0]);
dir = get_search_arg(&argvars[1], flagsp); // May set p_ws.
@@ -8254,7 +8255,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
options |= SEARCH_COL;
}
// Optional arguments: line number to stop searching and timeout.
// Optional arguments: line number to stop searching, timeout and skip.
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) {
lnum_stop = tv_get_number_chk(&argvars[2], NULL);
if (lnum_stop < 0) {
@@ -8265,6 +8266,9 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
if (time_limit < 0) {
goto theend;
}
if (argvars[4].v_type != VAR_UNKNOWN && !evalarg_get(&argvars[4], &skip)) {
goto theend;
}
}
}
@@ -8284,11 +8288,46 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
}
pos = save_cursor = curwin->w_cursor;
pos_T firstpos = { 0 };
memset(&sia, 0, sizeof(sia));
sia.sa_stop_lnum = (linenr_T)lnum_stop;
sia.sa_tm = &tm;
subpatnum = searchit(curwin, curbuf, &pos, NULL, dir, (char_u *)pat, 1,
options, RE_SEARCH, &sia);
// Repeat until {skip} returns false.
for (;;) {
subpatnum
= searchit(curwin, curbuf, &pos, NULL, dir, (char_u *)pat, 1, options, RE_SEARCH, &sia);
// finding the first match again means there is no match where {skip}
// evaluates to zero.
if (firstpos.lnum != 0 && equalpos(pos, firstpos)) {
subpatnum = FAIL;
}
if (subpatnum == FAIL || !evalarg_valid(&skip)) {
// didn't find it or no skip argument
break;
}
firstpos = pos;
// If the skip pattern matches, ignore this match.
{
bool err;
const pos_T save_pos = curwin->w_cursor;
curwin->w_cursor = pos;
const bool do_skip = evalarg_call_bool(&skip, &err);
curwin->w_cursor = save_pos;
if (err) {
// Evaluating {skip} caused an error, break here.
subpatnum = FAIL;
break;
}
if (!do_skip) {
break;
}
}
}
if (subpatnum != FAIL) {
if (flags & SP_SUBPAT) {
retval = subpatnum;
@@ -8317,6 +8356,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
}
theend:
p_ws = save_p_ws;
evalarg_clean(&skip);
return retval;
}