From c96311b5be307f5a1d1b20a0ec930d63964e7335 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 25 Nov 2022 21:13:47 +0000 Subject: [PATCH] patch 9.0.0950: the pattern "\_s\zs" matches at EOL Problem: The pattern "\_s\zs" matches at EOL. Solution: Make the pattern "\_s\zs" match at the start of the next line. (closes #11617) --- src/regexp.c | 1 - src/regexp_nfa.c | 14 ++++++++------ src/search.c | 6 +++++- src/testdir/test_search.vim | 26 ++++++++++++++++++++++++-- src/version.c | 2 ++ 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/regexp.c b/src/regexp.c index e29e6eaef..74ed13f3f 100644 --- a/src/regexp.c +++ b/src/regexp.c @@ -1093,7 +1093,6 @@ static void cleanup_subexpr(void); #ifdef FEAT_SYN_HL static void cleanup_zsubexpr(void); #endif -static void reg_nextline(void); static int match_with_backref(linenr_T start_lnum, colnr_T start_col, linenr_T end_lnum, colnr_T end_col, int *bytelen); /* diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c index b829a3a81..0228cfc42 100644 --- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -1742,7 +1742,8 @@ nfa_regatom(void) break; } } - semsg(_(e_nfa_regexp_unknown_operator_percent_chr), no_Magic(c)); + semsg(_(e_nfa_regexp_unknown_operator_percent_chr), + no_Magic(c)); return FAIL; } break; @@ -4013,7 +4014,8 @@ log_subexpr(regsub_T *sub) for (j = 0; j < sub->in_use; j++) if (REG_MULTI) - fprintf(log_fd, "*** group %d, start: c=%d, l=%d, end: c=%d, l=%d\n", + fprintf(log_fd, + "*** group %d, start: c=%d, l=%d, end: c=%d, l=%d\n", j, sub->list.multi[j].start_col, (int)sub->list.multi[j].start_lnum, @@ -4790,7 +4792,7 @@ skip_add: { sub->list.multi[subidx].start_lnum = rex.lnum; sub->list.multi[subidx].start_col = - (colnr_T)(rex.input - rex.line + off); + (colnr_T)(rex.input - rex.line + off); } sub->list.multi[subidx].end_lnum = -1; } @@ -6243,7 +6245,7 @@ nfa_regmatch( } else if (!vim_iswordc_buf(curc, rex.reg_buf) || (rex.input > rex.line - && vim_iswordc_buf(rex.input[-1], rex.reg_buf))) + && vim_iswordc_buf(rex.input[-1], rex.reg_buf))) result = FALSE; if (result) { @@ -6373,7 +6375,7 @@ nfa_regmatch( case NFA_NEWL: if (curc == NUL && !rex.reg_line_lbr && REG_MULTI - && rex.lnum <= rex.reg_maxline) + && rex.lnum <= rex.reg_maxline) { go_to_nextline = TRUE; // Pass -1 for the offset, which means taking the position @@ -7025,7 +7027,7 @@ nfa_regmatch( && rex.lnum == 0 && clen != 0 && (rex.reg_maxcol == 0 - || (colnr_T)(rex.input - rex.line) < rex.reg_maxcol)) + || (colnr_T)(rex.input - rex.line) < rex.reg_maxcol)) || (nfa_endp != NULL && (REG_MULTI ? (rex.lnum < nfa_endp->se_u.pos.lnum diff --git a/src/search.c b/src/search.c index 8045bd735..a4ec4448a 100644 --- a/src/search.c +++ b/src/search.c @@ -793,6 +793,8 @@ searchit( if (dir == FORWARD && at_first_line) { match_ok = TRUE; + matchcol = col; + /* * When the match starts in a next line it's certainly * past the start position. @@ -837,7 +839,9 @@ searchit( } else { - matchcol = matchpos.col; + // Advance "matchcol" to the next character. + // This does not use matchpos.col, because + // "\zs" may have have set it. if (ptr[matchcol] != NUL) { if (has_mbyte) diff --git a/src/testdir/test_search.vim b/src/testdir/test_search.vim index 357667359..e51803d0e 100644 --- a/src/testdir/test_search.vim +++ b/src/testdir/test_search.vim @@ -1884,7 +1884,7 @@ func Test_search_smartcase_utf8() set ignorecase& smartcase& let &encoding = save_enc - close! + bwipe! endfunc " Test searching past the end of a file @@ -1893,7 +1893,29 @@ func Test_search_past_eof() call setline(1, ['Line']) exe "normal /\\n\\zs\" call assert_equal([1, 4], [line('.'), col('.')]) - close! + bwipe! +endfunc + +" Test setting the start of the match and still finding a next match in the +" same line. +func Test_search_set_start_same_line() + new + set cpo-=c + + call setline(1, ['1', '2', '3 .', '4', '5']) + exe "normal /\\_s\\zs\\S\" + call assert_equal([2, 1], [line('.'), col('.')]) + exe 'normal n' + call assert_equal([3, 1], [line('.'), col('.')]) + exe 'normal n' + call assert_equal([3, 3], [line('.'), col('.')]) + exe 'normal n' + call assert_equal([4, 1], [line('.'), col('.')]) + exe 'normal n' + call assert_equal([5, 1], [line('.'), col('.')]) + + set cpo+=c + bwipe! endfunc " Test for various search offsets diff --git a/src/version.c b/src/version.c index e6fc986fd..9566edd99 100644 --- a/src/version.c +++ b/src/version.c @@ -695,6 +695,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 950, /**/ 949, /**/ -- 2.40.0