aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval
diff options
context:
space:
mode:
authorSean Dewar <seandewar@users.noreply.github.com>2022-02-01 12:44:14 +0000
committerSean Dewar <seandewar@users.noreply.github.com>2022-02-12 12:00:36 +0000
commitcdb2c100118ab788772a6a0a1d60f555370fd201 (patch)
tree744caa88947432672753f274876ce726d866c1f3 /src/nvim/eval
parenta7321e37a75fff5c0048b0779cf91d504455d6f3 (diff)
downloadrneovim-cdb2c100118ab788772a6a0a1d60f555370fd201.tar.gz
rneovim-cdb2c100118ab788772a6a0a1d60f555370fd201.tar.bz2
rneovim-cdb2c100118ab788772a6a0a1d60f555370fd201.zip
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) https://github.com/vim/vim/commit/adc17a5f9d207fd1623fd923457a46efc9214777 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) https://github.com/vim/vim/commit/0f7ff851cb721bb3c07261adbf82b591229f530d
Diffstat (limited to 'src/nvim/eval')
-rw-r--r--src/nvim/eval/funcs.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index db4fb06a73..8004c1d32e 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -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;
}