Skip to content

Commit 6835dc6

Browse files
committed
patch 7.4.2100
Problem: "cgn" and "dgn" do not work correctly with a single character match and the replacement includes the searched pattern. (John Beckett) Solution: If the match is found in the wrong column try in the next column. Turn the test into new style. (Christian Brabandt)
1 parent 73ac0c4 commit 6835dc6

7 files changed

Lines changed: 117 additions & 92 deletions

File tree

src/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2076,6 +2076,7 @@ test_arglist \
20762076
test_filter_map \
20772077
test_fnamemodify \
20782078
test_glob2regpat \
2079+
test_gn \
20792080
test_goto \
20802081
test_hardcopy \
20812082
test_help_tagjump \

src/search.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4719,7 +4719,7 @@ current_search(
47194719
}
47204720

47214721
/*
4722-
* Check if the pattern is one character or zero-width.
4722+
* Check if the pattern is one character long or zero-width.
47234723
* If move is TRUE, check from the beginning of the buffer, else from the
47244724
* current cursor position.
47254725
* Returns TRUE, FALSE or -1 for failure.
@@ -4734,10 +4734,15 @@ is_one_char(char_u *pattern, int move)
47344734
int save_called_emsg = called_emsg;
47354735
int flag = 0;
47364736

4737+
if (pattern == NULL)
4738+
pattern = spats[last_idx].pat;
4739+
47374740
if (search_regcomp(pattern, RE_SEARCH, RE_SEARCH,
47384741
SEARCH_KEEP, &regmatch) == FAIL)
47394742
return -1;
47404743

4744+
/* init startcol correctly */
4745+
regmatch.startpos[0].col = -1;
47414746
/* move to match */
47424747
if (move)
47434748
clearpos(&pos)
@@ -4748,22 +4753,30 @@ is_one_char(char_u *pattern, int move)
47484753
flag = SEARCH_START;
47494754
}
47504755

4751-
if (searchit(curwin, curbuf, &pos, FORWARD, spats[last_idx].pat, 1,
4756+
if (searchit(curwin, curbuf, &pos, FORWARD, pattern, 1,
47524757
SEARCH_KEEP + flag, RE_SEARCH, 0, NULL) != FAIL)
47534758
{
47544759
/* Zero-width pattern should match somewhere, then we can check if
47554760
* start and end are in the same position. */
47564761
called_emsg = FALSE;
4757-
nmatched = vim_regexec_multi(&regmatch, curwin, curbuf,
4758-
pos.lnum, (colnr_T)0, NULL);
4762+
do
4763+
{
4764+
regmatch.startpos[0].col++;
4765+
nmatched = vim_regexec_multi(&regmatch, curwin, curbuf,
4766+
pos.lnum, regmatch.startpos[0].col, NULL);
4767+
if (!nmatched)
4768+
break;
4769+
} while (regmatch.startpos[0].col < pos.col);
47594770

47604771
if (!called_emsg)
4772+
{
47614773
result = (nmatched != 0
47624774
&& regmatch.startpos[0].lnum == regmatch.endpos[0].lnum
47634775
&& regmatch.startpos[0].col == regmatch.endpos[0].col);
4764-
4765-
if (!result && inc(&pos) >= 0 && pos.col == regmatch.endpos[0].col)
4766-
result = TRUE;
4776+
/* one char width */
4777+
if (!result && inc(&pos) >= 0 && pos.col == regmatch.endpos[0].col)
4778+
result = TRUE;
4779+
}
47674780
}
47684781

47694782
called_emsg |= save_called_emsg;

src/testdir/Make_all.mak

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ NEW_TESTS = test_arglist.res \
171171
test_cscope.res \
172172
test_digraph.res \
173173
test_farsi.res \
174+
test_gn.res \
174175
test_hardcopy.res \
175176
test_history.res \
176177
test_increment.res \

src/testdir/test53.in

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ Note that the end-of-line moves the cursor to the next test line.
44

55
Also test match() and matchstr()
66

7-
Also test the gn command and repeating it.
8-
97
STARTTEST
108
:so small.vim
119
/^start:/
@@ -53,35 +51,6 @@ dit
5351
:put =match('abc', '\zs', 2, 1) " 2
5452
:put =match('abc', '\zs', 3, 1) " 3
5553
:put =match('abc', '\zs', 4, 1) " -1
56-
/^foobar
57-
gncsearchmatch/one\_s*two\_s
58-
:1
59-
gnd
60-
/[a]bcdx
61-
:1
62-
2gnd/join
63-
/$
64-
0gnd
65-
/\>\zs
66-
0gnd/^
67-
gnd$h/\zs
68-
gnd/[u]niquepattern/s
69-
vlgnd
70-
/mother
71-
:set selection=exclusive
72-
$cgNmongoose/i
73-
cgnj
74-
:" Make sure there is no other match y uppercase.
75-
/x59
76-
gggnd
77-
:" test repeating dgn
78-
/^Johnny
79-
ggdgn.
80-
:" test repeating gUgn
81-
/^Depp
82-
gggUgn.
83-
gg/a:0\@!\zs\d\+
84-
nygnop
8554
:/^start:/,/^end:/wq! test.out
8655
ENDTEST
8756

@@ -103,32 +72,4 @@ innertext object
10372
</b>
10473
</begin>
10574
SEARCH:
106-
foobar
107-
one
108-
two
109-
abcdx | abcdx | abcdx
110-
join
111-
lines
112-
zero width pattern
113-
delete first and last chars
114-
uniquepattern uniquepattern
115-
my very excellent mother just served us nachos
116-
for (i=0; i<=10; i++)
117-
a:10
118-
119-
a:1
120-
121-
a:20
122-
Y
123-
text
124-
Y
125-
--1
126-
Johnny
127-
--2
128-
Johnny
129-
--3
130-
Depp
131-
--4
132-
Depp
133-
--5
13475
end:

src/testdir/test53.ok

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -42,30 +42,4 @@ a
4242
3
4343
-1
4444
SEARCH:
45-
searchmatch
46-
abcdx | | abcdx
47-
join lines
48-
zerowidth pattern
49-
elete first and last char
50-
uniquepattern
51-
my very excellent mongoose just served us nachos
52-
for (j=0; i<=10; i++)
53-
a:10
54-
55-
a:1
56-
1
57-
58-
a:20
59-
60-
text
61-
Y
62-
--1
63-
64-
--2
65-
66-
--3
67-
DEPP
68-
--4
69-
DEPP
70-
--5
7145
end:

src/testdir/test_gn.vim

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
" Test for gn command
2+
3+
func Test_gn_command()
4+
noa new
5+
" replace a single char by itsself quoted:
6+
call setline('.', 'abc x def x ghi x jkl')
7+
let @/='x'
8+
exe "norm! cgn'x'\<esc>.."
9+
call assert_equal("abc 'x' def 'x' ghi 'x' jkl", getline('.'))
10+
sil! %d_
11+
" simple search match
12+
call setline('.', 'foobar')
13+
let @/='foobar'
14+
exe "norm! gncsearchmatch"
15+
call assert_equal('searchmatch', getline('.'))
16+
sil! %d _
17+
" replace a multi-line match
18+
call setline('.', ['', 'one', 'two'])
19+
let @/='one\_s*two\_s'
20+
exe "norm! gnceins\<CR>zwei"
21+
call assert_equal(['','eins','zwei'], getline(1,'$'))
22+
sil! %d _
23+
" test count argument
24+
call setline('.', ['', 'abcdx | abcdx | abcdx'])
25+
let @/='[a]bcdx'
26+
exe "norm! 2gnd"
27+
call assert_equal(['','abcdx | | abcdx'], getline(1,'$'))
28+
sil! %d _
29+
" join lines
30+
call setline('.', ['join ', 'lines'])
31+
let @/='$'
32+
exe "norm! 0gnd"
33+
call assert_equal(['join lines'], getline(1,'$'))
34+
sil! %d _
35+
" zero-width match
36+
call setline('.', ['', 'zero width pattern'])
37+
let @/='\>\zs'
38+
exe "norm! 0gnd"
39+
call assert_equal(['', 'zerowidth pattern'], getline(1,'$'))
40+
sil! %d _
41+
" delete first and last chars
42+
call setline('.', ['delete first and last chars'])
43+
let @/='^'
44+
exe "norm! 0gnd$"
45+
let @/='\zs'
46+
exe "norm! gnd"
47+
call assert_equal(['elete first and last char'], getline(1,'$'))
48+
sil! %d _
49+
" using visual mode
50+
call setline('.', ['', 'uniquepattern uniquepattern'])
51+
exe "norm! /[u]niquepattern/s\<cr>vlgnd"
52+
call assert_equal(['', ' uniquepattern'], getline(1,'$'))
53+
sil! %d _
54+
" backwards search
55+
call setline('.', ['my very excellent mother just served us nachos'])
56+
let @/='mother'
57+
exe "norm! $cgNmongoose"
58+
call assert_equal(['my very excellent mongoose just served us nachos'], getline(1,'$'))
59+
sil! %d _
60+
" search for single char
61+
call setline('.', ['','for (i=0; i<=10; i++)'])
62+
let @/='i'
63+
exe "norm! cgnj"
64+
call assert_equal(['','for (j=0; i<=10; i++)'], getline(1,'$'))
65+
sil! %d _
66+
" search hex char
67+
call setline('.', ['','Y'])
68+
set noignorecase
69+
let @/='\%x59'
70+
exe "norm! gnd"
71+
call assert_equal(['',''], getline(1,'$'))
72+
sil! %d _
73+
" test repeating gdn
74+
call setline('.', ['', '1', 'Johnny', '2', 'Johnny', '3'])
75+
let @/='Johnny'
76+
exe "norm! dgn."
77+
call assert_equal(['','1', '', '2', '', '3'], getline(1,'$'))
78+
sil! %d _
79+
" test repeating gUgn
80+
call setline('.', ['', '1', 'Depp', '2', 'Depp', '3'])
81+
let @/='Depp'
82+
exe "norm! gUgn."
83+
call assert_equal(['', '1', 'DEPP', '2', 'DEPP', '3'], getline(1,'$'))
84+
sil! %d _
85+
" test using look-ahead assertions
86+
call setline('.', ['a:10', '', 'a:1', '', 'a:20'])
87+
let @/='a:0\@!\zs\d\+'
88+
exe "norm! 2nygno\<esc>p"
89+
call assert_equal(['a:10', '', 'a:1', '1', '', 'a:20'], getline(1,'$'))
90+
sil! %d _
91+
endfu
92+
93+
" vim: tabstop=2 shiftwidth=0 expandtab

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,8 @@ static char *(features[]) =
758758

759759
static int included_patches[] =
760760
{ /* Add new patch number below this line */
761+
/**/
762+
2100,
761763
/**/
762764
2099,
763765
/**/

0 commit comments

Comments
 (0)