From 1bbe8ec2820497b8a61adcd138da350445b0ad92 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 19 Mar 2022 16:42:24 +0800 Subject: vim-patch:8.2.3110: a pattern that matches the cursor position is complicated Problem: A pattern that matches the cursor position is bit complicated. Solution: Use a dot to indicate the cursor line and column. (Christian Brabandt, closes vim/vim#8497, closes vim/vim#8179) https://github.com/vim/vim/commit/04db26b36000a4677b95403ec94bd11f6cc73975 Also use `n = ++vcol` in regexp_bt.c as `++vcol` alone fails lint. --- runtime/doc/pattern.txt | 31 ++++++++++-- src/nvim/regexp.c | 6 ++- src/nvim/regexp_bt.c | 28 +++++++++-- src/nvim/regexp_nfa.c | 23 ++++++++- src/nvim/testdir/test_regexp_latin.vim | 90 ++++++++++++++++++++++++++++++++++ 5 files changed, 168 insertions(+), 10 deletions(-) diff --git a/runtime/doc/pattern.txt b/runtime/doc/pattern.txt index 680b853dab..c12a099469 100644 --- a/runtime/doc/pattern.txt +++ b/runtime/doc/pattern.txt @@ -918,13 +918,20 @@ $ At end of pattern or in front of "\|", "\)" or "\n" ('magic' on): \%23l Matches in a specific line. \%<23l Matches above a specific line (lower line number). \%>23l Matches below a specific line (higher line number). +\%.l Matches at the cursor line. +\%<.l Matches above the cursor line. +\%>.l Matches below the cursor line. These three can be used to match specific lines in a buffer. The "23" can be any line number. The first line is 1. WARNING: When inserting or deleting lines Vim does not automatically update the matches. This means Syntax highlighting quickly becomes - wrong. + wrong. Also when refering to the cursor position (".") and + the cursor moves the display isn't updated for this change. An update + is done when using the |CTRL-L| command (the whole screen is updated). Example, to highlight the line where the cursor currently is: > - :exe '/\%' .. line(".") .. 'l.*' + :exe '/\%' .. line(".") .. 'l' +< Alternatively use: > + /\%.l < When 'hlsearch' is set and you move the cursor around and make changes this will clearly show when the match is updated or not. @@ -932,15 +939,23 @@ $ At end of pattern or in front of "\|", "\)" or "\n" ('magic' on): \%23c Matches in a specific column. \%<23c Matches before a specific column. \%>23c Matches after a specific column. +\%.c Matches at the cursor column. +\%<.c Matches before the cursor column. +\%>.c Matches after the cursor column. These three can be used to match specific columns in a buffer or string. The "23" can be any column number. The first column is 1. Actually, the column is the byte number (thus it's not exactly right for multibyte characters). WARNING: When inserting or deleting text Vim does not automatically update the matches. This means Syntax highlighting quickly becomes - wrong. + wrong. Also when refering to the cursor position (".") and + the cursor moves the display isn't updated for this change. An update + is done when using the |CTRL-L| command (the whole screen is updated). + Example, to highlight the column where the cursor currently is: > :exe '/\%' .. col(".") .. 'c' +< Alternatively use: > + /\%.c < When 'hlsearch' is set and you move the cursor around and make changes this will clearly show when the match is updated or not. Example for matching a single byte in column 44: > @@ -951,6 +966,9 @@ $ At end of pattern or in front of "\|", "\)" or "\n" ('magic' on): \%23v Matches in a specific virtual column. \%<23v Matches before a specific virtual column. \%>23v Matches after a specific virtual column. +\%.v Matches at the current virtual column. +\%<.v Matches before the current virtual column. +\%>.v Matches after the current virtual column. These three can be used to match specific virtual columns in a buffer or string. When not matching with a buffer in a window, the option values of the current window are used (e.g., 'tabstop'). @@ -960,13 +978,18 @@ $ At end of pattern or in front of "\|", "\)" or "\n" ('magic' on): one screen character. WARNING: When inserting or deleting text Vim does not automatically update highlighted matches. This means Syntax highlighting quickly - becomes wrong. + becomes wrong. Also when refering to the cursor position (".") and + the cursor moves the display isn't updated for this change. An update + is done when using the |CTRL-L| command (the whole screen is updated). Example, to highlight all the characters after virtual column 72: > /\%>72v.* < When 'hlsearch' is set and you move the cursor around and make changes this will clearly show when the match is updated or not. To match the text up to column 17: > /^.*\%17v +< To match all characters after the current virtual column (where the + cursor is): > + /\%>.v.* < Column 17 is not included, because this is a |/zero-width| match. To include the column use: > /^.*\%17v. diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 009a26d4e0..d3c43e530a 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -107,8 +107,10 @@ static char_u e_unmatchedpar[] = N_("E55: Unmatched %s)"); static char_u e_z_not_allowed[] = N_("E66: \\z( not allowed here"); static char_u e_z1_not_allowed[] = N_("E67: \\z1 - \\z9 not allowed here"); static char_u e_missing_sb[] = N_("E69: Missing ] after %s%%["); -static char_u e_empty_sb[] = N_("E70: Empty %s%%[]"); -static char_u e_recursive[] = N_("E956: Cannot use pattern recursively"); +static char_u e_empty_sb[] = N_("E70: Empty %s%%[]"); +static char_u e_recursive[] = N_("E956: Cannot use pattern recursively"); +static char_u e_regexp_number_after_dot_pos_search[] + = N_("E1204: No Number allowed after .: '\\%%%c'"); #define NOT_MULTI 0 #define MULTI_ONE 1 diff --git a/src/nvim/regexp_bt.c b/src/nvim/regexp_bt.c index 3835a2bbae..7d0b9a7a77 100644 --- a/src/nvim/regexp_bt.c +++ b/src/nvim/regexp_bt.c @@ -1578,14 +1578,19 @@ static char_u *regatom(int *flagp) } default: - if (ascii_isdigit(c) || c == '<' || c == '>' - || c == '\'') { + if (ascii_isdigit(c) || c == '<' || c == '>' || c == '\'' || c == '.') { uint32_t n = 0; int cmp; + bool cur = false; cmp = c; - if (cmp == '<' || cmp == '>') + if (cmp == '<' || cmp == '>') { c = getchr(); + } + if (no_Magic(c) == '.') { + cur = true; + c = getchr(); + } while (ascii_isdigit(c)) { n = n * 10 + (uint32_t)(c - '0'); c = getchr(); @@ -1602,14 +1607,31 @@ static char_u *regatom(int *flagp) } break; } else if (c == 'l' || c == 'c' || c == 'v') { + if (cur && n) { + semsg(_(e_regexp_number_after_dot_pos_search), no_Magic(c)); + rc_did_emsg = true; + return NULL; + } if (c == 'l') { + if (cur) { + n = curwin->w_cursor.lnum; + } ret = regnode(RE_LNUM); if (save_prev_at_start) { at_start = true; } } else if (c == 'c') { + if (cur) { + n = curwin->w_cursor.col; + n++; + } ret = regnode(RE_COL); } else { + if (cur) { + colnr_T vcol = 0; + getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &vcol); + n = ++vcol; + } ret = regnode(RE_VCOL); } if (ret == JUST_CALC_SIZE) { diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 7e316624f8..67c11451f6 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -1639,10 +1639,19 @@ static int nfa_regatom(void) { int64_t n = 0; const int cmp = c; + bool cur = false; - if (c == '<' || c == '>') + if (c == '<' || c == '>') { c = getchr(); + } + if (no_Magic(c) == '.') { + cur = true; + c = getchr(); + } while (ascii_isdigit(c)) { + if (cur) { + semsg(_(e_regexp_number_after_dot_pos_search), no_Magic(c)); + } if (n > (INT32_MAX - (c - '0')) / 10) { // overflow. emsg(_(e_value_too_large)); @@ -1655,6 +1664,9 @@ static int nfa_regatom(void) int32_t limit = INT32_MAX; if (c == 'l') { + if (cur) { + n = curwin->w_cursor.lnum; + } // \%{n}l \%{n}l EMIT(cmp == '<' ? NFA_LNUM_LT : cmp == '>' ? NFA_LNUM_GT : NFA_LNUM); @@ -1662,10 +1674,19 @@ static int nfa_regatom(void) at_start = true; } } else if (c == 'c') { + if (cur) { + n = curwin->w_cursor.col; + n++; + } // \%{n}c \%{n}c EMIT(cmp == '<' ? NFA_COL_LT : cmp == '>' ? NFA_COL_GT : NFA_COL); } else { + if (cur) { + colnr_T vcol = 0; + getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &vcol); + n = ++vcol; + } // \%{n}v \%{n}v EMIT(cmp == '<' ? NFA_VCOL_LT : cmp == '>' ? NFA_VCOL_GT : NFA_VCOL); diff --git a/src/nvim/testdir/test_regexp_latin.vim b/src/nvim/testdir/test_regexp_latin.vim index cbd45696a9..b733e334de 100644 --- a/src/nvim/testdir/test_regexp_latin.vim +++ b/src/nvim/testdir/test_regexp_latin.vim @@ -787,6 +787,96 @@ func Test_regexp_error() set re& endfunc +" Check patterns matching cursor position. +func s:curpos_test2() + new + call setline(1, ['1', '2 foobar eins zwei drei vier fünf sechse', + \ '3 foobar eins zwei drei vier fünf sechse', + \ '4 foobar eins zwei drei vier fünf sechse', + \ '5 foobar eins zwei drei vier fünf sechse', + \ '6 foobar eins zwei drei vier fünf sechse', + \ '7 foobar eins zwei drei vier fünf sechse']) + call setpos('.', [0, 2, 10, 0]) + s/\%.c.*//g + call setpos('.', [0, 3, 15, 0]) + s/\%.l.*//g + call setpos('.', [0, 5, 3, 0]) + s/\%.v.*/_/g + call assert_equal(['1', + \ '2 foobar ', + \ '', + \ '4 foobar eins zwei drei vier fünf sechse', + \ '5 _', + \ '6 foobar eins zwei drei vier fünf sechse', + \ '7 foobar eins zwei drei vier fünf sechse'], + \ getline(1, '$')) + call assert_fails('call search("\\%.1l")', 'E1204:') + call assert_fails('call search("\\%.1c")', 'E1204:') + call assert_fails('call search("\\%.1v")', 'E1204:') + bwipe! +endfunc + +" Check patterns matching before or after cursor position. +func s:curpos_test3() + new + call setline(1, ['1', '2 foobar eins zwei drei vier fünf sechse', + \ '3 foobar eins zwei drei vier fünf sechse', + \ '4 foobar eins zwei drei vier fünf sechse', + \ '5 foobar eins zwei drei vier fünf sechse', + \ '6 foobar eins zwei drei vier fünf sechse', + \ '7 foobar eins zwei drei vier fünf sechse']) + call setpos('.', [0, 2, 10, 0]) + " Note: This removes all columns, except for the column directly in front of + " the cursor. Bug???? + :s/^.*\%<.c// + call setpos('.', [0, 3, 10, 0]) + :s/\%>.c.*$// + call setpos('.', [0, 5, 4, 0]) + " Note: This removes all columns, except for the column directly in front of + " the cursor. Bug???? + :s/^.*\%<.v/_/ + call setpos('.', [0, 6, 4, 0]) + :s/\%>.v.*$/_/ + call assert_equal(['1', + \ ' eins zwei drei vier fünf sechse', + \ '3 foobar e', + \ '4 foobar eins zwei drei vier fünf sechse', + \ '_foobar eins zwei drei vier fünf sechse', + \ '6 fo_', + \ '7 foobar eins zwei drei vier fünf sechse'], + \ getline(1, '$')) + sil %d + call setline(1, ['1', '2 foobar eins zwei drei vier fünf sechse', + \ '3 foobar eins zwei drei vier fünf sechse', + \ '4 foobar eins zwei drei vier fünf sechse', + \ '5 foobar eins zwei drei vier fünf sechse', + \ '6 foobar eins zwei drei vier fünf sechse', + \ '7 foobar eins zwei drei vier fünf sechse']) + call setpos('.', [0, 4, 4, 0]) + %s/\%<.l.*// + call setpos('.', [0, 5, 4, 0]) + %s/\%>.l.*// + call assert_equal(['', '', '', + \ '4 foobar eins zwei drei vier fünf sechse', + \ '5 foobar eins zwei drei vier fünf sechse', + \ '', ''], + \ getline(1, '$')) + bwipe! +endfunc + +" Test that matching below, at or after the +" cursor position work +func Test_matching_pos() + for val in range(3) + exe "set re=" .. val + " Match at cursor position + call s:curpos_test2() + " Match before or after cursor position + call s:curpos_test3() + endfor + set re& +endfunc + func Test_using_mark_position() " this was using freed memory " new engine -- cgit From b2819eec26c6e18fe41b103efad641fc2f227450 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 19 Mar 2022 17:48:20 +0800 Subject: docs(pattern.txt): cherry-pick latests changes from Vim runtime updates Update runtime files https://github.com/vim/vim/commit/53f7fccc9413c9f770694b56f40f242d383b2d5f Update runtime files https://github.com/vim/vim/commit/2286304cdbba53ceb52b3ba2ba4a521b0a2f8d0f Update runtime files https://github.com/vim/vim/commit/2f0936cb9a2eb026acac03e6a8fd0b2a5d97508b Update runtime files. https://github.com/vim/vim/commit/a2baa73d1d33014adea0fd9567949089ca21a782 --- runtime/doc/pattern.txt | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/runtime/doc/pattern.txt b/runtime/doc/pattern.txt index c12a099469..35f5b311ff 100644 --- a/runtime/doc/pattern.txt +++ b/runtime/doc/pattern.txt @@ -914,18 +914,18 @@ $ At end of pattern or in front of "\|", "\)" or "\n" ('magic' on): becomes invalid. Vim doesn't automatically update the matches. Similar to moving the cursor for "\%#" |/\%#|. - */\%l* */\%>l* */\%l* */\%23l Matches below a specific line (higher line number). -\%.l Matches at the cursor line. -\%<.l Matches above the cursor line. -\%>.l Matches below the cursor line. - These three can be used to match specific lines in a buffer. The "23" +\%.l Matches at the cursor line. +\%<.l Matches above the cursor line. +\%>.l Matches below the cursor line. + These six can be used to match specific lines in a buffer. The "23" can be any line number. The first line is 1. WARNING: When inserting or deleting lines Vim does not automatically update the matches. This means Syntax highlighting quickly becomes - wrong. Also when refering to the cursor position (".") and + wrong. Also when referring to the cursor position (".") and the cursor moves the display isn't updated for this change. An update is done when using the |CTRL-L| command (the whole screen is updated). Example, to highlight the line where the cursor currently is: > @@ -939,19 +939,18 @@ $ At end of pattern or in front of "\|", "\)" or "\n" ('magic' on): \%23c Matches in a specific column. \%<23c Matches before a specific column. \%>23c Matches after a specific column. -\%.c Matches at the cursor column. -\%<.c Matches before the cursor column. -\%>.c Matches after the cursor column. - These three can be used to match specific columns in a buffer or - string. The "23" can be any column number. The first column is 1. - Actually, the column is the byte number (thus it's not exactly right - for multibyte characters). +\%.c Matches at the cursor column. +\%<.c Matches before the cursor column. +\%>.c Matches after the cursor column. + These six can be used to match specific columns in a buffer or string. + The "23" can be any column number. The first column is 1. Actually, + the column is the byte number (thus it's not exactly right for + multibyte characters). WARNING: When inserting or deleting text Vim does not automatically update the matches. This means Syntax highlighting quickly becomes - wrong. Also when refering to the cursor position (".") and + wrong. Also when referring to the cursor position (".") and the cursor moves the display isn't updated for this change. An update is done when using the |CTRL-L| command (the whole screen is updated). - Example, to highlight the column where the cursor currently is: > :exe '/\%' .. col(".") .. 'c' < Alternatively use: > @@ -966,11 +965,11 @@ $ At end of pattern or in front of "\|", "\)" or "\n" ('magic' on): \%23v Matches in a specific virtual column. \%<23v Matches before a specific virtual column. \%>23v Matches after a specific virtual column. -\%.v Matches at the current virtual column. -\%<.v Matches before the current virtual column. -\%>.v Matches after the current virtual column. - These three can be used to match specific virtual columns in a buffer - or string. When not matching with a buffer in a window, the option +\%.v Matches at the current virtual column. +\%<.v Matches before the current virtual column. +\%>.v Matches after the current virtual column. + These six can be used to match specific virtual columns in a buffer or + string. When not matching with a buffer in a window, the option values of the current window are used (e.g., 'tabstop'). The "23" can be any column number. The first column is 1. Note that some virtual column positions will never match, because they @@ -978,7 +977,7 @@ $ At end of pattern or in front of "\|", "\)" or "\n" ('magic' on): one screen character. WARNING: When inserting or deleting text Vim does not automatically update highlighted matches. This means Syntax highlighting quickly - becomes wrong. Also when refering to the cursor position (".") and + becomes wrong. Also when referring to the cursor position (".") and the cursor moves the display isn't updated for this change. An update is done when using the |CTRL-L| command (the whole screen is updated). Example, to highlight all the characters after virtual column 72: > -- cgit From 465f8ff8cbd3f9b73c1de8823505ee6a804b2bf1 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 19 Mar 2022 19:37:08 +0800 Subject: vim-patch:8.2.4592: search continues after giving E1204 Problem: Search continues after giving E1204. Solution: Return failure after giving E1204. (closes vim/vim#9972) https://github.com/vim/vim/commit/b10ff5c1b3581ed4990d196bed51b4a8f961e8a2 --- src/nvim/regexp_nfa.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 67c11451f6..8a14a2864c 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -1651,6 +1651,7 @@ static int nfa_regatom(void) while (ascii_isdigit(c)) { if (cur) { semsg(_(e_regexp_number_after_dot_pos_search), no_Magic(c)); + return FAIL; } if (n > (INT32_MAX - (c - '0')) / 10) { // overflow. -- cgit