To: vim_dev@googlegroups.com Subject: Patch 8.2.3110 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3110 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 #8497, closes #8179) Files: runtime/doc/pattern.txt, src/errors.h, src/regexp_bt.c, src/regexp_nfa.c, src/testdir/test_regexp_latin.vim *** ../vim-8.2.3109/runtime/doc/pattern.txt 2021-01-31 17:02:06.258490157 +0100 --- runtime/doc/pattern.txt 2021-07-05 20:07:47.985037677 +0200 *************** *** 229,235 **** *last-pattern* The last used pattern and offset are remembered. They can be used to repeat the search, possibly in another direction or with another count. Note that ! two patterns are remembered: One for 'normal' search commands and one for the substitute command ":s". Each time an empty pattern is given, the previously used pattern is used. However, if there is no previous search command, a previous substitute pattern is used, if possible. --- 230,236 ---- *last-pattern* The last used pattern and offset are remembered. They can be used to repeat the search, possibly in another direction or with another count. Note that ! two patterns are remembered: One for "normal" search commands and one for the substitute command ":s". Each time an empty pattern is given, the previously used pattern is used. However, if there is no previous search command, a previous substitute pattern is used, if possible. *************** *** 928,940 **** \%23l Matches in a specific line. \%<23l Matches above a specific line (lower line number). \%>23l Matches below a specific line (higher line number). 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. Example, to highlight the line where the cursor currently is: > ! :exe '/\%' . line(".") . '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. --- 929,948 ---- \%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. 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' ! < 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. *************** *** 942,956 **** \%23c Matches in a specific column. \%<23c Matches before a specific column. \%>23c Matches after a specific 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. Example, to highlight the column where the cursor currently is: > :exe '/\%' . col(".") . '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: > --- 950,972 ---- \%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. 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: > *************** *** 961,966 **** --- 977,985 ---- \%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'). *************** *** 970,982 **** one screen character. WARNING: When inserting or deleting text Vim does not automatically update highlighted matches. This means Syntax highlighting quickly ! becomes wrong. 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 < Column 17 is not included, because this is a |/zero-width| match. To include the column use: > /^.*\%17v. --- 989,1006 ---- 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 ! 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. *************** *** 1216,1222 **** \%d123 Matches the character specified with a decimal number. Must be followed by a non-digit. ! \%o40 Matches the character specified with an octal number up to 0377. Numbers below 0o40 must be followed by a non-octal digit or a non-digit. \%x2a Matches the character specified with up to two hexadecimal characters. --- 1240,1246 ---- \%d123 Matches the character specified with a decimal number. Must be followed by a non-digit. ! \%o40 Matches the character specified with an octal number up to 0o377. Numbers below 0o40 must be followed by a non-octal digit or a non-digit. \%x2a Matches the character specified with up to two hexadecimal characters. *** ../vim-8.2.3109/src/errors.h 2021-06-27 22:03:28.637707737 +0200 --- src/errors.h 2021-07-05 20:07:47.985037677 +0200 *************** *** 488,490 **** --- 488,492 ---- INIT(= N_("E1202: No white space allowed after '%s': %s")); EXTERN char e_dot_can_only_be_used_on_dictionary_str[] INIT(= N_("E1203: Dot can only be used on a dictionary: %s")); + EXTERN char e_regexp_number_after_dot_pos_search[] + INIT(= N_("E1204: No Number allowed after .: '\\%%%c'")); *** ../vim-8.2.3109/src/regexp_bt.c 2021-05-24 22:56:10.110989235 +0200 --- src/regexp_bt.c 2021-07-05 20:12:51.144460668 +0200 *************** *** 1628,1641 **** default: if (VIM_ISDIGIT(c) || c == '<' || c == '>' ! || c == '\'') { long_u n = 0; int cmp; cmp = c; if (cmp == '<' || cmp == '>') c = getchr(); while (VIM_ISDIGIT(c)) { n = n * 10 + (c - '0'); --- 1628,1647 ---- default: if (VIM_ISDIGIT(c) || c == '<' || c == '>' ! || c == '\'' || c == '.') { long_u n = 0; int cmp; + int cur = FALSE; cmp = c; if (cmp == '<' || cmp == '>') c = getchr(); + if (no_Magic(c) == '.') + { + cur = TRUE; + c = getchr(); + } while (VIM_ISDIGIT(c)) { n = n * 10 + (c - '0'); *************** *** 1657,1672 **** --- 1663,1704 ---- } 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); + ++vcol; + n = vcol; + } ret = regnode(RE_VCOL); + } if (ret == JUST_CALC_SIZE) regsize += 5; else *** ../vim-8.2.3109/src/regexp_nfa.c 2021-05-24 22:56:10.110989235 +0200 --- src/regexp_nfa.c 2021-07-05 20:13:23.484398135 +0200 *************** *** 1707,1718 **** { long_u n = 0; int cmp = c; if (c == '<' || c == '>') c = getchr(); while (VIM_ISDIGIT(c)) { ! long_u tmp = n * 10 + (c - '0'); if (tmp < n) { --- 1707,1729 ---- { long_u n = 0; int cmp = c; + int cur = FALSE; if (c == '<' || c == '>') c = getchr(); + if (no_Magic(c) == '.') + { + cur = TRUE; + c = getchr(); + } while (VIM_ISDIGIT(c)) { ! long_u tmp; ! ! if (cur) ! semsg(_(e_regexp_number_after_dot_pos_search), ! no_Magic(c)); ! tmp = n * 10 + (c - '0'); if (tmp < n) { *************** *** 1729,1734 **** --- 1740,1747 ---- 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); *************** *** 1736,1746 **** --- 1749,1774 ---- 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); *** ../vim-8.2.3109/src/testdir/test_regexp_latin.vim 2021-03-26 17:24:30.931546613 +0100 --- src/testdir/test_regexp_latin.vim 2021-07-05 20:07:47.985037677 +0200 *************** *** 947,950 **** --- 947,1040 ---- close! 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 + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.3109/src/version.c 2021-07-05 17:48:59.501911723 +0200 --- src/version.c 2021-07-05 20:14:09.160309560 +0200 *************** *** 757,758 **** --- 757,760 ---- { /* Add new patch number below this line */ + /**/ + 3110, /**/ -- Do not trust atoms, they make up everything. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///