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 in a specific line.
|
||||||
\%<23l Matches above a specific line (lower line number).
|
\%<23l Matches above a specific line (lower line number).
|
||||||
\%>23l Matches below a specific line (higher 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"
|
These three can be used to match specific lines in a buffer. The "23"
|
||||||
can be any line number. The first line is 1.
|
can be any line number. The first line is 1.
|
||||||
WARNING: When inserting or deleting lines Vim does not automatically
|
WARNING: When inserting or deleting lines Vim does not automatically
|
||||||
update the matches. This means Syntax highlighting quickly becomes
|
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: >
|
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
|
< When 'hlsearch' is set and you move the cursor around and make changes
|
||||||
this will clearly show when the match is updated or not.
|
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 in a specific column.
|
||||||
\%<23c Matches before a specific column.
|
\%<23c Matches before a specific column.
|
||||||
\%>23c Matches after 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
|
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.
|
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
|
Actually, the column is the byte number (thus it's not exactly right
|
||||||
for multibyte characters).
|
for multibyte characters).
|
||||||
WARNING: When inserting or deleting text Vim does not automatically
|
WARNING: When inserting or deleting text Vim does not automatically
|
||||||
update the matches. This means Syntax highlighting quickly becomes
|
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: >
|
Example, to highlight the column where the cursor currently is: >
|
||||||
:exe '/\%' . col(".") . 'c'
|
:exe '/\%' . col(".") . 'c'
|
||||||
|
< Alternatively use: >
|
||||||
|
/\%.c
|
||||||
< When 'hlsearch' is set and you move the cursor around and make changes
|
< When 'hlsearch' is set and you move the cursor around and make changes
|
||||||
this will clearly show when the match is updated or not.
|
this will clearly show when the match is updated or not.
|
||||||
Example for matching a single byte in column 44: >
|
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 in a specific virtual column.
|
||||||
\%<23v Matches before a specific virtual column.
|
\%<23v Matches before a specific virtual column.
|
||||||
\%>23v Matches after 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
|
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
|
or string. When not matching with a buffer in a window, the option
|
||||||
values of the current window are used (e.g., 'tabstop').
|
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.
|
one screen character.
|
||||||
WARNING: When inserting or deleting text Vim does not automatically
|
WARNING: When inserting or deleting text Vim does not automatically
|
||||||
update highlighted matches. This means Syntax highlighting quickly
|
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: >
|
Example, to highlight all the characters after virtual column 72: >
|
||||||
/\%>72v.*
|
/\%>72v.*
|
||||||
< When 'hlsearch' is set and you move the cursor around and make changes
|
< When 'hlsearch' is set and you move the cursor around and make changes
|
||||||
this will clearly show when the match is updated or not.
|
this will clearly show when the match is updated or not.
|
||||||
To match the text up to column 17: >
|
To match the text up to column 17: >
|
||||||
/^.*\%17v
|
/^.*\%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
|
< Column 17 is not included, because this is a |/zero-width| match. To
|
||||||
include the column use: >
|
include the column use: >
|
||||||
/^.*\%17v.
|
/^.*\%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"));
|
INIT(= N_("E1202: No white space allowed after '%s': %s"));
|
||||||
EXTERN char e_dot_can_only_be_used_on_dictionary_str[]
|
EXTERN char e_dot_can_only_be_used_on_dictionary_str[]
|
||||||
INIT(= N_("E1203: Dot can only be used on a dictionary: %s"));
|
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:
|
default:
|
||||||
if (VIM_ISDIGIT(c) || c == '<' || c == '>'
|
if (VIM_ISDIGIT(c) || c == '<' || c == '>'
|
||||||
|| c == '\'')
|
|| c == '\'' || c == '.')
|
||||||
{
|
{
|
||||||
long_u n = 0;
|
long_u n = 0;
|
||||||
int cmp;
|
int cmp;
|
||||||
|
int cur = FALSE;
|
||||||
|
|
||||||
cmp = c;
|
cmp = c;
|
||||||
if (cmp == '<' || cmp == '>')
|
if (cmp == '<' || cmp == '>')
|
||||||
c = getchr();
|
c = getchr();
|
||||||
|
if (no_Magic(c) == '.')
|
||||||
|
{
|
||||||
|
cur = TRUE;
|
||||||
|
c = getchr();
|
||||||
|
}
|
||||||
while (VIM_ISDIGIT(c))
|
while (VIM_ISDIGIT(c))
|
||||||
{
|
{
|
||||||
n = n * 10 + (c - '0');
|
n = n * 10 + (c - '0');
|
||||||
@@ -1657,16 +1663,42 @@ regatom(int *flagp)
|
|||||||
}
|
}
|
||||||
else if (c == 'l' || c == 'c' || c == 'v')
|
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 (c == 'l')
|
||||||
{
|
{
|
||||||
|
if (cur)
|
||||||
|
n = curwin->w_cursor.lnum;
|
||||||
ret = regnode(RE_LNUM);
|
ret = regnode(RE_LNUM);
|
||||||
if (save_prev_at_start)
|
if (save_prev_at_start)
|
||||||
at_start = TRUE;
|
at_start = TRUE;
|
||||||
}
|
}
|
||||||
else if (c == 'c')
|
else if (c == 'c')
|
||||||
|
{
|
||||||
|
if (cur)
|
||||||
|
{
|
||||||
|
n = curwin->w_cursor.col;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
ret = regnode(RE_COL);
|
ret = regnode(RE_COL);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (cur)
|
||||||
|
{
|
||||||
|
colnr_T vcol = 0;
|
||||||
|
|
||||||
|
getvvcol(curwin, &curwin->w_cursor,
|
||||||
|
NULL, NULL, &vcol);
|
||||||
|
++vcol;
|
||||||
|
n = vcol;
|
||||||
|
}
|
||||||
ret = regnode(RE_VCOL);
|
ret = regnode(RE_VCOL);
|
||||||
|
}
|
||||||
if (ret == JUST_CALC_SIZE)
|
if (ret == JUST_CALC_SIZE)
|
||||||
regsize += 5;
|
regsize += 5;
|
||||||
else
|
else
|
||||||
|
@@ -1707,12 +1707,23 @@ nfa_regatom(void)
|
|||||||
{
|
{
|
||||||
long_u n = 0;
|
long_u n = 0;
|
||||||
int cmp = c;
|
int cmp = c;
|
||||||
|
int cur = FALSE;
|
||||||
|
|
||||||
if (c == '<' || c == '>')
|
if (c == '<' || c == '>')
|
||||||
c = getchr();
|
c = getchr();
|
||||||
|
if (no_Magic(c) == '.')
|
||||||
|
{
|
||||||
|
cur = TRUE;
|
||||||
|
c = getchr();
|
||||||
|
}
|
||||||
while (VIM_ISDIGIT(c))
|
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)
|
if (tmp < n)
|
||||||
{
|
{
|
||||||
@@ -1729,6 +1740,8 @@ nfa_regatom(void)
|
|||||||
|
|
||||||
if (c == 'l')
|
if (c == 'l')
|
||||||
{
|
{
|
||||||
|
if (cur)
|
||||||
|
n = curwin->w_cursor.lnum;
|
||||||
// \%{n}l \%{n}<l \%{n}>l
|
// \%{n}l \%{n}<l \%{n}>l
|
||||||
EMIT(cmp == '<' ? NFA_LNUM_LT :
|
EMIT(cmp == '<' ? NFA_LNUM_LT :
|
||||||
cmp == '>' ? NFA_LNUM_GT : NFA_LNUM);
|
cmp == '>' ? NFA_LNUM_GT : NFA_LNUM);
|
||||||
@@ -1736,11 +1749,26 @@ nfa_regatom(void)
|
|||||||
at_start = TRUE;
|
at_start = TRUE;
|
||||||
}
|
}
|
||||||
else if (c == 'c')
|
else if (c == 'c')
|
||||||
|
{
|
||||||
|
if (cur)
|
||||||
|
{
|
||||||
|
n = curwin->w_cursor.col;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
// \%{n}c \%{n}<c \%{n}>c
|
// \%{n}c \%{n}<c \%{n}>c
|
||||||
EMIT(cmp == '<' ? NFA_COL_LT :
|
EMIT(cmp == '<' ? NFA_COL_LT :
|
||||||
cmp == '>' ? NFA_COL_GT : NFA_COL);
|
cmp == '>' ? NFA_COL_GT : NFA_COL);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (cur)
|
||||||
|
{
|
||||||
|
colnr_T vcol = 0;
|
||||||
|
|
||||||
|
getvvcol(curwin, &curwin->w_cursor,
|
||||||
|
NULL, NULL, &vcol);
|
||||||
|
n = ++vcol;
|
||||||
|
}
|
||||||
// \%{n}v \%{n}<v \%{n}>v
|
// \%{n}v \%{n}<v \%{n}>v
|
||||||
EMIT(cmp == '<' ? NFA_VCOL_LT :
|
EMIT(cmp == '<' ? NFA_VCOL_LT :
|
||||||
cmp == '>' ? NFA_VCOL_GT : NFA_VCOL);
|
cmp == '>' ? NFA_VCOL_GT : NFA_VCOL);
|
||||||
|
@@ -947,4 +947,94 @@ func Test_regexp_last_subst_string()
|
|||||||
close!
|
close!
|
||||||
endfunc
|
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: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -755,6 +755,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
3110,
|
||||||
/**/
|
/**/
|
||||||
3109,
|
3109,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user