forked from aniani/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 #8497, closes #8179)
This commit is contained in:
@@ -929,13 +929,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.
|
||||
|
||||
@@ -943,15 +950,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: >
|
||||
@@ -962,6 +977,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').
|
||||
@@ -971,13 +989,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.
|
||||
|
@@ -488,3 +488,5 @@ EXTERN char e_no_white_space_allowed_after_str_str[]
|
||||
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'"));
|
||||
|
@@ -1628,14 +1628,20 @@ regatom(int *flagp)
|
||||
|
||||
default:
|
||||
if (VIM_ISDIGIT(c) || 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,16 +1663,42 @@ regatom(int *flagp)
|
||||
}
|
||||
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
|
||||
|
@@ -1707,12 +1707,23 @@ nfa_regatom(void)
|
||||
{
|
||||
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 = n * 10 + (c - '0');
|
||||
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,6 +1740,8 @@ nfa_regatom(void)
|
||||
|
||||
if (c == 'l')
|
||||
{
|
||||
if (cur)
|
||||
n = curwin->w_cursor.lnum;
|
||||
// \%{n}l \%{n}<l \%{n}>l
|
||||
EMIT(cmp == '<' ? NFA_LNUM_LT :
|
||||
cmp == '>' ? NFA_LNUM_GT : NFA_LNUM);
|
||||
@@ -1736,11 +1749,26 @@ nfa_regatom(void)
|
||||
at_start = TRUE;
|
||||
}
|
||||
else if (c == 'c')
|
||||
{
|
||||
if (cur)
|
||||
{
|
||||
n = curwin->w_cursor.col;
|
||||
n++;
|
||||
}
|
||||
// \%{n}c \%{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 \%{n}>v
|
||||
EMIT(cmp == '<' ? NFA_VCOL_LT :
|
||||
cmp == '>' ? NFA_VCOL_GT : NFA_VCOL);
|
||||
|
@@ -947,4 +947,94 @@ func Test_regexp_last_subst_string()
|
||||
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
|
||||
|
@@ -755,6 +755,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
3110,
|
||||
/**/
|
||||
3109,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user