From: Bram Moolenaar Date: Mon, 24 May 2021 20:56:15 +0000 (+0200) Subject: patch 8.2.2885: searching for \%'> does not match linewise end of line X-Git-Tag: v8.2.2885 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=872bee557e5f8ab0e4a523a6a845868a2801b17e;p=vim patch 8.2.2885: searching for \%'> does not match linewise end of line Problem: searching for \%'> does not match linewise end of line. (Tim Chase) Solution: Match end of line if column is MAXCOL. (closes #8238) --- diff --git a/src/regexp_bt.c b/src/regexp_bt.c index afea5e4cb..70ddfe986 100644 --- a/src/regexp_bt.c +++ b/src/regexp_bt.c @@ -3357,17 +3357,29 @@ regmatch( pos = getmark_buf(rex.reg_buf, mark, FALSE); if (pos == NULL // mark doesn't exist - || pos->lnum <= 0 // mark isn't set in reg_buf - || (pos->lnum == rex.lnum + rex.reg_firstlnum - ? (pos->col == (colnr_T)(rex.input - rex.line) + || pos->lnum <= 0) // mark isn't set in reg_buf + { + status = RA_NOMATCH; + } + else + { + colnr_T pos_col = pos->lnum == rex.lnum + rex.reg_firstlnum + && pos->col == MAXCOL + ? (colnr_T)STRLEN(reg_getline( + pos->lnum - rex.reg_firstlnum)) + : pos->col; + + if ((pos->lnum == rex.lnum + rex.reg_firstlnum + ? (pos_col == (colnr_T)(rex.input - rex.line) ? (cmp == '<' || cmp == '>') - : (pos->col < (colnr_T)(rex.input - rex.line) + : (pos_col < (colnr_T)(rex.input - rex.line) ? cmp != '>' : cmp != '<')) : (pos->lnum < rex.lnum + rex.reg_firstlnum ? cmp != '>' : cmp != '<'))) status = RA_NOMATCH; + } } break; diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c index a519b8537..2ed18685d 100644 --- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -6806,22 +6806,30 @@ nfa_regmatch( { pos_T *pos = getmark_buf(rex.reg_buf, t->state->val, FALSE); - // Compare the mark position to the match position. - result = (pos != NULL // mark doesn't exist - && pos->lnum > 0 // mark isn't set in reg_buf - && (pos->lnum == rex.lnum + rex.reg_firstlnum - ? (pos->col == (colnr_T)(rex.input - rex.line) + // Compare the mark position to the match position, if the mark + // exists and mark is set in reg_buf. + if (pos != NULL && pos->lnum > 0) + { + colnr_T pos_col = pos->lnum == rex.lnum + rex.reg_firstlnum + && pos->col == MAXCOL + ? (colnr_T)STRLEN(reg_getline( + pos->lnum - rex.reg_firstlnum)) + : pos->col; + + result = (pos->lnum == rex.lnum + rex.reg_firstlnum + ? (pos_col == (colnr_T)(rex.input - rex.line) ? t->state->c == NFA_MARK - : (pos->col < (colnr_T)(rex.input - rex.line) + : (pos_col < (colnr_T)(rex.input - rex.line) ? t->state->c == NFA_MARK_GT : t->state->c == NFA_MARK_LT)) : (pos->lnum < rex.lnum + rex.reg_firstlnum ? t->state->c == NFA_MARK_GT - : t->state->c == NFA_MARK_LT))); - if (result) - { - add_here = TRUE; - add_state = t->state->out; + : t->state->c == NFA_MARK_LT)); + if (result) + { + add_here = TRUE; + add_state = t->state->out; + } } break; } diff --git a/src/testdir/test_search.vim b/src/testdir/test_search.vim index e7c9ac474..b265e97de 100644 --- a/src/testdir/test_search.vim +++ b/src/testdir/test_search.vim @@ -1332,13 +1332,28 @@ func Test_look_behind() bwipe! endfunc +func Test_search_visual_area_linewise() + new + call setline(1, ['aa', 'bb', 'cc']) + exe "normal 2GV\" + for engine in [1, 2] + exe 'set regexpengine=' .. engine + exe "normal gg/\\%'<\>" + call assert_equal([0, 2, 1, 0, 1], getcurpos(), 'engine ' .. engine) + exe "normal gg/\\%'>\" + call assert_equal([0, 2, 2, 0, 2], getcurpos(), 'engine ' .. engine) + endfor + + bwipe! + set regexpengine& +endfunc + func Test_search_sentence() new " this used to cause a crash - call assert_fails("/\\%')", 'E486:') - call assert_fails("/", 'E486:') /\%'( / + bwipe endfunc " Test that there is no crash when there is a last search pattern but no last diff --git a/src/version.c b/src/version.c index c0729b2cb..c841e6b50 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2885, /**/ 2884, /**/