1cd055da3SBram Moolenaar" Tests for multi-line regexps with ":s".
2cd055da3SBram Moolenaar
39f6277bdSBram Moolenaarsource shared.vim
47a2217beSBram Moolenaarsource check.vim
59f6277bdSBram Moolenaar
61e115360SBram Moolenaarfunc Test_multiline_subst()
7cd055da3SBram Moolenaar  enew!
8cd055da3SBram Moolenaar  call append(0, ["1 aa",
9cd055da3SBram Moolenaar	      \ "bb",
10cd055da3SBram Moolenaar	      \ "cc",
11cd055da3SBram Moolenaar	      \ "2 dd",
12cd055da3SBram Moolenaar	      \ "ee",
13cd055da3SBram Moolenaar	      \ "3 ef",
14cd055da3SBram Moolenaar	      \ "gh",
15cd055da3SBram Moolenaar	      \ "4 ij",
16cd055da3SBram Moolenaar	      \ "5 a8",
17cd055da3SBram Moolenaar	      \ "8b c9",
18cd055da3SBram Moolenaar	      \ "9d",
19cd055da3SBram Moolenaar	      \ "6 e7",
20cd055da3SBram Moolenaar	      \ "77f",
21cd055da3SBram Moolenaar	      \ "xxxxx"])
22cd055da3SBram Moolenaar
23cd055da3SBram Moolenaar  1
24cd055da3SBram Moolenaar  " test if replacing a line break works with a back reference
25cd055da3SBram Moolenaar  /^1/,/^2/s/\n\(.\)/ \1/
26cd055da3SBram Moolenaar  " test if inserting a line break works with a back reference
27cd055da3SBram Moolenaar  /^3/,/^4/s/\(.\)$/\r\1/
28cd055da3SBram Moolenaar  " test if replacing a line break with another line break works
29cd055da3SBram Moolenaar  /^5/,/^6/s/\(\_d\{3}\)/x\1x/
30cd055da3SBram Moolenaar  call assert_equal('1 aa bb cc 2 dd ee', getline(1))
31cd055da3SBram Moolenaar  call assert_equal('3 e', getline(2))
32cd055da3SBram Moolenaar  call assert_equal('f', getline(3))
33cd055da3SBram Moolenaar  call assert_equal('g', getline(4))
34cd055da3SBram Moolenaar  call assert_equal('h', getline(5))
35cd055da3SBram Moolenaar  call assert_equal('4 i', getline(6))
36cd055da3SBram Moolenaar  call assert_equal('j', getline(7))
37cd055da3SBram Moolenaar  call assert_equal('5 ax8', getline(8))
38cd055da3SBram Moolenaar  call assert_equal('8xb cx9', getline(9))
39cd055da3SBram Moolenaar  call assert_equal('9xd', getline(10))
40cd055da3SBram Moolenaar  call assert_equal('6 ex7', getline(11))
41cd055da3SBram Moolenaar  call assert_equal('7x7f', getline(12))
42cd055da3SBram Moolenaar  call assert_equal('xxxxx', getline(13))
43cd055da3SBram Moolenaar  enew!
441e115360SBram Moolenaarendfunc
458c50d50bSBram Moolenaar
461e115360SBram Moolenaarfunc Test_substitute_variants()
478c50d50bSBram Moolenaar  " Validate that all the 2-/3-letter variants which embed the flags into the
488c50d50bSBram Moolenaar  " command name actually work.
498c50d50bSBram Moolenaar  enew!
508c50d50bSBram Moolenaar  let ln = 'Testing string'
518c50d50bSBram Moolenaar  let variants = [
528c50d50bSBram Moolenaar	\ { 'cmd': ':s/Test/test/c', 'exp': 'testing string', 'prompt': 'y' },
538c50d50bSBram Moolenaar	\ { 'cmd': ':s/foo/bar/ce', 'exp': ln },
548c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/cg', 'exp': 'Tesring srring', 'prompt': 'a' },
558c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/ci', 'exp': 'resting string', 'prompt': 'y' },
568c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/cI', 'exp': 'Tesring string', 'prompt': 'y' },
57ea3db914SBram Moolenaar	\ { 'cmd': ':s/t/r/c', 'exp': 'Testing string', 'prompt': 'n' },
588c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/cn', 'exp': ln },
598c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/cp', 'exp': 'Tesring string', 'prompt': 'y' },
608c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/cl', 'exp': 'Tesring string', 'prompt': 'y' },
618c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/gc', 'exp': 'Tesring srring', 'prompt': 'a' },
62ea3db914SBram Moolenaar	\ { 'cmd': ':s/i/I/gc', 'exp': 'TestIng string', 'prompt': 'l' },
638c50d50bSBram Moolenaar	\ { 'cmd': ':s/foo/bar/ge', 'exp': ln },
648c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/g', 'exp': 'Tesring srring' },
658c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/gi', 'exp': 'resring srring' },
668c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/gI', 'exp': 'Tesring srring' },
678c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/gn', 'exp': ln },
688c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/gp', 'exp': 'Tesring srring' },
698c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/gl', 'exp': 'Tesring srring' },
708c50d50bSBram Moolenaar	\ { 'cmd': ':s//r/gr', 'exp': 'Testr strr' },
718c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/ic', 'exp': 'resting string', 'prompt': 'y' },
728c50d50bSBram Moolenaar	\ { 'cmd': ':s/foo/bar/ie', 'exp': ln },
738c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/i', 'exp': 'resting string' },
748c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/iI', 'exp': 'Tesring string' },
758c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/in', 'exp': ln },
768c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/ip', 'exp': 'resting string' },
778c50d50bSBram Moolenaar	\ { 'cmd': ':s//r/ir', 'exp': 'Testr string' },
788c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/Ic', 'exp': 'Tesring string', 'prompt': 'y' },
798c50d50bSBram Moolenaar	\ { 'cmd': ':s/foo/bar/Ie', 'exp': ln },
808c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/Ig', 'exp': 'Tesring srring' },
818c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/Ii', 'exp': 'resting string' },
828c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/I', 'exp': 'Tesring string' },
838c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/Ip', 'exp': 'Tesring string' },
848c50d50bSBram Moolenaar	\ { 'cmd': ':s/t/r/Il', 'exp': 'Tesring string' },
858c50d50bSBram Moolenaar	\ { 'cmd': ':s//r/Ir', 'exp': 'Testr string' },
868c50d50bSBram Moolenaar	\ { 'cmd': ':s//r/rc', 'exp': 'Testr string', 'prompt': 'y' },
878c50d50bSBram Moolenaar	\ { 'cmd': ':s//r/rg', 'exp': 'Testr strr' },
888c50d50bSBram Moolenaar	\ { 'cmd': ':s//r/ri', 'exp': 'Testr string' },
898c50d50bSBram Moolenaar	\ { 'cmd': ':s//r/rI', 'exp': 'Testr string' },
908c50d50bSBram Moolenaar	\ { 'cmd': ':s//r/rn', 'exp': 'Testing string' },
918c50d50bSBram Moolenaar	\ { 'cmd': ':s//r/rp', 'exp': 'Testr string' },
928c50d50bSBram Moolenaar	\ { 'cmd': ':s//r/rl', 'exp': 'Testr string' },
938c50d50bSBram Moolenaar	\ { 'cmd': ':s//r/r', 'exp': 'Testr string' },
94ea3db914SBram Moolenaar	\ { 'cmd': ':s/i/I/gc', 'exp': 'Testing string', 'prompt': 'q' },
958c50d50bSBram Moolenaar	\]
968c50d50bSBram Moolenaar
978c50d50bSBram Moolenaar  for var in variants
988c50d50bSBram Moolenaar    for run in [1, 2]
998c50d50bSBram Moolenaar      let cmd = var.cmd
1008c50d50bSBram Moolenaar      if run == 2 && cmd =~ "/.*/.*/."
1018c50d50bSBram Moolenaar	" Change  :s/from/to/{flags}  to  :s{flags}
1028c50d50bSBram Moolenaar	let cmd = substitute(cmd, '/.*/', '', '')
1038c50d50bSBram Moolenaar      endif
1048c50d50bSBram Moolenaar      call setline(1, [ln])
1058c50d50bSBram Moolenaar      let msg = printf('using "%s"', cmd)
1068c50d50bSBram Moolenaar      let @/='ing'
1078c50d50bSBram Moolenaar      let v:errmsg = ''
1088c50d50bSBram Moolenaar      call feedkeys(cmd . "\<CR>" . get(var, 'prompt', ''), 'ntx')
1098c50d50bSBram Moolenaar      " No error should exist (matters for testing e flag)
1108c50d50bSBram Moolenaar      call assert_equal('', v:errmsg, msg)
1118c50d50bSBram Moolenaar      call assert_equal(var.exp, getline('.'), msg)
1128c50d50bSBram Moolenaar    endfor
1138c50d50bSBram Moolenaar  endfor
1141e115360SBram Moolenaarendfunc
115ba748c8aSBram Moolenaar
1169474716dSBram Moolenaar" Test the l, p, # flags.
1179474716dSBram Moolenaarfunc Test_substitute_flags_lp()
1189474716dSBram Moolenaar  new
1199474716dSBram Moolenaar  call setline(1, "abc\tdef\<C-h>ghi")
1209474716dSBram Moolenaar
1219474716dSBram Moolenaar  let a = execute('s/a/a/p')
1229474716dSBram Moolenaar  call assert_equal("\nabc     def^Hghi", a)
1239474716dSBram Moolenaar
1249474716dSBram Moolenaar  let a = execute('s/a/a/l')
1259474716dSBram Moolenaar  call assert_equal("\nabc^Idef^Hghi$", a)
1269474716dSBram Moolenaar
1279474716dSBram Moolenaar  let a = execute('s/a/a/#')
1289474716dSBram Moolenaar  call assert_equal("\n  1 abc     def^Hghi", a)
1299474716dSBram Moolenaar
1309474716dSBram Moolenaar  let a = execute('s/a/a/p#')
1319474716dSBram Moolenaar  call assert_equal("\n  1 abc     def^Hghi", a)
1329474716dSBram Moolenaar
1339474716dSBram Moolenaar  let a = execute('s/a/a/l#')
1349474716dSBram Moolenaar  call assert_equal("\n  1 abc^Idef^Hghi$", a)
1359474716dSBram Moolenaar
1369474716dSBram Moolenaar  let a = execute('s/a/a/')
1379474716dSBram Moolenaar  call assert_equal("", a)
1389474716dSBram Moolenaar
1399474716dSBram Moolenaar  bwipe!
1409474716dSBram Moolenaarendfunc
1419474716dSBram Moolenaar
142ba748c8aSBram Moolenaarfunc Test_substitute_repeat()
143ba748c8aSBram Moolenaar  " This caused an invalid memory access.
144ba748c8aSBram Moolenaar  split Xfile
145ba748c8aSBram Moolenaar  s/^/x
146ba748c8aSBram Moolenaar  call feedkeys("Qsc\<CR>y", 'tx')
147ba748c8aSBram Moolenaar  bwipe!
148ba748c8aSBram Moolenaarendfunc
1491a333bc4SBram Moolenaar
150d77aa4d2SBram Moolenaar" Test %s/\n// which is implemented as a special case to use a
151d77aa4d2SBram Moolenaar" more efficient join rather than doing a regular substitution.
152d77aa4d2SBram Moolenaarfunc Test_substitute_join()
153d77aa4d2SBram Moolenaar  new
154d77aa4d2SBram Moolenaar
155d77aa4d2SBram Moolenaar  call setline(1, ["foo\tbar", "bar\<C-H>foo"])
156d77aa4d2SBram Moolenaar  let a = execute('%s/\n//')
157d77aa4d2SBram Moolenaar  call assert_equal("", a)
158d77aa4d2SBram Moolenaar  call assert_equal(["foo\tbarbar\<C-H>foo"], getline(1, '$'))
159d77aa4d2SBram Moolenaar  call assert_equal('\n', histget("search", -1))
160d77aa4d2SBram Moolenaar
161d77aa4d2SBram Moolenaar  call setline(1, ["foo\tbar", "bar\<C-H>foo"])
162d77aa4d2SBram Moolenaar  let a = execute('%s/\n//g')
163d77aa4d2SBram Moolenaar  call assert_equal("", a)
164d77aa4d2SBram Moolenaar  call assert_equal(["foo\tbarbar\<C-H>foo"], getline(1, '$'))
165d77aa4d2SBram Moolenaar  call assert_equal('\n', histget("search", -1))
166d77aa4d2SBram Moolenaar
167d77aa4d2SBram Moolenaar  call setline(1, ["foo\tbar", "bar\<C-H>foo"])
168d77aa4d2SBram Moolenaar  let a = execute('%s/\n//p')
169d77aa4d2SBram Moolenaar  call assert_equal("\nfoo     barbar^Hfoo", a)
170d77aa4d2SBram Moolenaar  call assert_equal(["foo\tbarbar\<C-H>foo"], getline(1, '$'))
171d77aa4d2SBram Moolenaar  call assert_equal('\n', histget("search", -1))
172d77aa4d2SBram Moolenaar
173d77aa4d2SBram Moolenaar  call setline(1, ["foo\tbar", "bar\<C-H>foo"])
174d77aa4d2SBram Moolenaar  let a = execute('%s/\n//l')
175d77aa4d2SBram Moolenaar  call assert_equal("\nfoo^Ibarbar^Hfoo$", a)
176d77aa4d2SBram Moolenaar  call assert_equal(["foo\tbarbar\<C-H>foo"], getline(1, '$'))
177d77aa4d2SBram Moolenaar  call assert_equal('\n', histget("search", -1))
178d77aa4d2SBram Moolenaar
179d77aa4d2SBram Moolenaar  call setline(1, ["foo\tbar", "bar\<C-H>foo"])
180d77aa4d2SBram Moolenaar  let a = execute('%s/\n//#')
181d77aa4d2SBram Moolenaar  call assert_equal("\n  1 foo     barbar^Hfoo", a)
182d77aa4d2SBram Moolenaar  call assert_equal(["foo\tbarbar\<C-H>foo"], getline(1, '$'))
183d77aa4d2SBram Moolenaar  call assert_equal('\n', histget("search", -1))
184d77aa4d2SBram Moolenaar
185ea3db914SBram Moolenaar  call setline(1, ['foo', 'bar', 'baz', 'qux'])
186ea3db914SBram Moolenaar  call execute('1,2s/\n//')
187ea3db914SBram Moolenaar  call assert_equal(['foobarbaz', 'qux'], getline(1, '$'))
188ea3db914SBram Moolenaar
189d77aa4d2SBram Moolenaar  bwipe!
190d77aa4d2SBram Moolenaarendfunc
191d77aa4d2SBram Moolenaar
192d77aa4d2SBram Moolenaarfunc Test_substitute_count()
193d77aa4d2SBram Moolenaar  new
194d77aa4d2SBram Moolenaar  call setline(1, ['foo foo', 'foo foo', 'foo foo', 'foo foo', 'foo foo'])
195d77aa4d2SBram Moolenaar  2
196d77aa4d2SBram Moolenaar
197d77aa4d2SBram Moolenaar  s/foo/bar/3
198d77aa4d2SBram Moolenaar  call assert_equal(['foo foo', 'bar foo', 'bar foo', 'bar foo', 'foo foo'],
199d77aa4d2SBram Moolenaar  \                 getline(1, '$'))
200d77aa4d2SBram Moolenaar
201d77aa4d2SBram Moolenaar  call assert_fails('s/foo/bar/0', 'E939:')
202d77aa4d2SBram Moolenaar
203ea3db914SBram Moolenaar  call setline(1, ['foo foo', 'foo foo', 'foo foo', 'foo foo', 'foo foo'])
204ea3db914SBram Moolenaar  2,4s/foo/bar/ 10
205ea3db914SBram Moolenaar  call assert_equal(['foo foo', 'foo foo', 'foo foo', 'bar foo', 'bar foo'],
206ea3db914SBram Moolenaar        \           getline(1, '$'))
207ea3db914SBram Moolenaar
208d77aa4d2SBram Moolenaar  bwipe!
209d77aa4d2SBram Moolenaarendfunc
210d77aa4d2SBram Moolenaar
211d77aa4d2SBram Moolenaar" Test substitute 'n' flag (report number of matches, do not substitute).
212d77aa4d2SBram Moolenaarfunc Test_substitute_flag_n()
213d77aa4d2SBram Moolenaar  new
214d77aa4d2SBram Moolenaar  let lines = ['foo foo', 'foo foo', 'foo foo', 'foo foo', 'foo foo']
215d77aa4d2SBram Moolenaar  call setline(1, lines)
216d77aa4d2SBram Moolenaar
217d77aa4d2SBram Moolenaar  call assert_equal("\n3 matches on 3 lines", execute('2,4s/foo/bar/n'))
218d77aa4d2SBram Moolenaar  call assert_equal("\n6 matches on 3 lines", execute('2,4s/foo/bar/gn'))
219d77aa4d2SBram Moolenaar
220d77aa4d2SBram Moolenaar  " c flag (confirm) should be ignored when using n flag.
221d77aa4d2SBram Moolenaar  call assert_equal("\n3 matches on 3 lines", execute('2,4s/foo/bar/nc'))
222d77aa4d2SBram Moolenaar
223d77aa4d2SBram Moolenaar  " No substitution should have been done.
224d77aa4d2SBram Moolenaar  call assert_equal(lines, getline(1, '$'))
225d77aa4d2SBram Moolenaar
226ea3db914SBram Moolenaar  %delete _
227ea3db914SBram Moolenaar  call setline(1, ['A', 'Bar', 'Baz'])
228ea3db914SBram Moolenaar  call assert_equal("\n1 match on 1 line", execute('s/\nB\@=//gn'))
229ea3db914SBram Moolenaar
230d77aa4d2SBram Moolenaar  bwipe!
231d77aa4d2SBram Moolenaarendfunc
232d77aa4d2SBram Moolenaar
233d77aa4d2SBram Moolenaarfunc Test_substitute_errors()
234d77aa4d2SBram Moolenaar  new
235d77aa4d2SBram Moolenaar  call setline(1, 'foobar')
236d77aa4d2SBram Moolenaar
237d77aa4d2SBram Moolenaar  call assert_fails('s/FOO/bar/', 'E486:')
238d77aa4d2SBram Moolenaar  call assert_fails('s/foo/bar/@', 'E488:')
2399b7bf9e9SBram Moolenaar  call assert_fails('s/\(/bar/', 'E54:')
2405d98dc2aSBram Moolenaar  call assert_fails('s afooabara', 'E146:')
2415d98dc2aSBram Moolenaar  call assert_fails('s\\a', 'E10:')
242d77aa4d2SBram Moolenaar
243d77aa4d2SBram Moolenaar  setl nomodifiable
244d77aa4d2SBram Moolenaar  call assert_fails('s/foo/bar/', 'E21:')
245d77aa4d2SBram Moolenaar
2460e05de46SBram Moolenaar  call assert_fails("let s=substitute([], 'a', 'A', 'g')", 'E730:')
2470e05de46SBram Moolenaar  call assert_fails("let s=substitute('abcda', [], 'A', 'g')", 'E730:')
2480e05de46SBram Moolenaar  call assert_fails("let s=substitute('abcda', 'a', [], 'g')", 'E730:')
2490e05de46SBram Moolenaar  call assert_fails("let s=substitute('abcda', 'a', 'A', [])", 'E730:')
250531be47aSBram Moolenaar  call assert_fails("let s=substitute('abc', '\\%(', 'A', 'g')", 'E53:')
2510e05de46SBram Moolenaar
252d77aa4d2SBram Moolenaar  bwipe!
253d77aa4d2SBram Moolenaarendfunc
254d77aa4d2SBram Moolenaar
2551a333bc4SBram Moolenaar" Test for *sub-replace-special* and *sub-replace-expression* on substitute().
2561a333bc4SBram Moolenaarfunc Test_sub_replace_1()
2571a333bc4SBram Moolenaar  " Run the tests with 'magic' on
2581a333bc4SBram Moolenaar  set magic
2591a333bc4SBram Moolenaar  set cpo&
2601a333bc4SBram Moolenaar  call assert_equal('AA', substitute('A', 'A', '&&', ''))
2611a333bc4SBram Moolenaar  call assert_equal('&', substitute('B', 'B', '\&', ''))
2621a333bc4SBram Moolenaar  call assert_equal('C123456789987654321', substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', ''))
2631a333bc4SBram Moolenaar  call assert_equal('d', substitute('D', 'D', 'd', ''))
2641a333bc4SBram Moolenaar  call assert_equal('~', substitute('E', 'E', '~', ''))
2651a333bc4SBram Moolenaar  call assert_equal('~', substitute('F', 'F', '\~', ''))
2661a333bc4SBram Moolenaar  call assert_equal('Gg', substitute('G', 'G', '\ugg', ''))
2671a333bc4SBram Moolenaar  call assert_equal('Hh', substitute('H', 'H', '\Uh\Eh', ''))
2681a333bc4SBram Moolenaar  call assert_equal('iI', substitute('I', 'I', '\lII', ''))
2691a333bc4SBram Moolenaar  call assert_equal('jJ', substitute('J', 'J', '\LJ\EJ', ''))
2701a333bc4SBram Moolenaar  call assert_equal('Kk', substitute('K', 'K', '\Uk\ek', ''))
2711a333bc4SBram Moolenaar  call assert_equal("l\<C-V>\<C-M>l",
2721a333bc4SBram Moolenaar			\ substitute('lLl', 'L', "\<C-V>\<C-M>", ''))
2731a333bc4SBram Moolenaar  call assert_equal("m\<C-M>m", substitute('mMm', 'M', '\r', ''))
2741a333bc4SBram Moolenaar  call assert_equal("n\<C-V>\<C-M>n",
2751a333bc4SBram Moolenaar			\ substitute('nNn', 'N', "\\\<C-V>\<C-M>", ''))
2761a333bc4SBram Moolenaar  call assert_equal("o\no", substitute('oOo', 'O', '\n', ''))
2771a333bc4SBram Moolenaar  call assert_equal("p\<C-H>p", substitute('pPp', 'P', '\b', ''))
2781a333bc4SBram Moolenaar  call assert_equal("q\tq", substitute('qQq', 'Q', '\t', ''))
2791a333bc4SBram Moolenaar  call assert_equal('r\r', substitute('rRr', 'R', '\\', ''))
2801a333bc4SBram Moolenaar  call assert_equal('scs', substitute('sSs', 'S', '\c', ''))
2811a333bc4SBram Moolenaar  call assert_equal("u\nu", substitute('uUu', 'U', "\n", ''))
2821a333bc4SBram Moolenaar  call assert_equal("v\<C-H>v", substitute('vVv', 'V', "\b", ''))
2831a333bc4SBram Moolenaar  call assert_equal("w\\w", substitute('wWw', 'W', "\\", ''))
2841a333bc4SBram Moolenaar  call assert_equal("x\<C-M>x", substitute('xXx', 'X', "\r", ''))
2851a333bc4SBram Moolenaar  call assert_equal("YyyY", substitute('Y', 'Y', '\L\uyYy\l\EY', ''))
2861a333bc4SBram Moolenaar  call assert_equal("zZZz", substitute('Z', 'Z', '\U\lZzZ\u\Ez', ''))
287004a6781SBram Moolenaar  " \v or \V after $
288004a6781SBram Moolenaar  call assert_equal('abxx', substitute('abcd', 'xy$\v|cd$', 'xx', ''))
289004a6781SBram Moolenaar  call assert_equal('abxx', substitute('abcd', 'xy$\V\|cd\$', 'xx', ''))
2901a333bc4SBram Moolenaarendfunc
2911a333bc4SBram Moolenaar
2921a333bc4SBram Moolenaarfunc Test_sub_replace_2()
2931a333bc4SBram Moolenaar  " Run the tests with 'magic' off
2941a333bc4SBram Moolenaar  set nomagic
2951a333bc4SBram Moolenaar  set cpo&
2961a333bc4SBram Moolenaar  call assert_equal('AA', substitute('A', 'A', '&&', ''))
2971a333bc4SBram Moolenaar  call assert_equal('&', substitute('B', 'B', '\&', ''))
2981a333bc4SBram Moolenaar  call assert_equal('C123456789987654321', substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', ''))
2991a333bc4SBram Moolenaar  call assert_equal('d', substitute('D', 'D', 'd', ''))
3001a333bc4SBram Moolenaar  call assert_equal('~', substitute('E', 'E', '~', ''))
3011a333bc4SBram Moolenaar  call assert_equal('~', substitute('F', 'F', '\~', ''))
3021a333bc4SBram Moolenaar  call assert_equal('Gg', substitute('G', 'G', '\ugg', ''))
3031a333bc4SBram Moolenaar  call assert_equal('Hh', substitute('H', 'H', '\Uh\Eh', ''))
3041a333bc4SBram Moolenaar  call assert_equal('iI', substitute('I', 'I', '\lII', ''))
3051a333bc4SBram Moolenaar  call assert_equal('jJ', substitute('J', 'J', '\LJ\EJ', ''))
3061a333bc4SBram Moolenaar  call assert_equal('Kk', substitute('K', 'K', '\Uk\ek', ''))
3071a333bc4SBram Moolenaar  call assert_equal("l\<C-V>\<C-M>l",
3081a333bc4SBram Moolenaar			\ substitute('lLl', 'L', "\<C-V>\<C-M>", ''))
3091a333bc4SBram Moolenaar  call assert_equal("m\<C-M>m", substitute('mMm', 'M', '\r', ''))
3101a333bc4SBram Moolenaar  call assert_equal("n\<C-V>\<C-M>n",
3111a333bc4SBram Moolenaar			\ substitute('nNn', 'N', "\\\<C-V>\<C-M>", ''))
3121a333bc4SBram Moolenaar  call assert_equal("o\no", substitute('oOo', 'O', '\n', ''))
3131a333bc4SBram Moolenaar  call assert_equal("p\<C-H>p", substitute('pPp', 'P', '\b', ''))
3141a333bc4SBram Moolenaar  call assert_equal("q\tq", substitute('qQq', 'Q', '\t', ''))
3151a333bc4SBram Moolenaar  call assert_equal('r\r', substitute('rRr', 'R', '\\', ''))
3161a333bc4SBram Moolenaar  call assert_equal('scs', substitute('sSs', 'S', '\c', ''))
3171a333bc4SBram Moolenaar  call assert_equal("t\<C-M>t", substitute('tTt', 'T', "\r", ''))
3181a333bc4SBram Moolenaar  call assert_equal("u\nu", substitute('uUu', 'U', "\n", ''))
3191a333bc4SBram Moolenaar  call assert_equal("v\<C-H>v", substitute('vVv', 'V', "\b", ''))
3201a333bc4SBram Moolenaar  call assert_equal('w\w', substitute('wWw', 'W', "\\", ''))
3211a333bc4SBram Moolenaar  call assert_equal('XxxX', substitute('X', 'X', '\L\uxXx\l\EX', ''))
3221a333bc4SBram Moolenaar  call assert_equal('yYYy', substitute('Y', 'Y', '\U\lYyY\u\Ey', ''))
3231a333bc4SBram Moolenaarendfunc
3241a333bc4SBram Moolenaar
3251a333bc4SBram Moolenaarfunc Test_sub_replace_3()
3261a333bc4SBram Moolenaar  set magic&
3271a333bc4SBram Moolenaar  set cpo&
3281a333bc4SBram Moolenaar  call assert_equal('a\a', substitute('aAa', 'A', '\="\\"', ''))
3291a333bc4SBram Moolenaar  call assert_equal('b\\b', substitute('bBb', 'B', '\="\\\\"', ''))
3301a333bc4SBram Moolenaar  call assert_equal("c\rc", substitute('cCc', 'C', "\\=\"\r\"", ''))
3311a333bc4SBram Moolenaar  call assert_equal("d\\\rd", substitute('dDd', 'D', "\\=\"\\\\\r\"", ''))
3321a333bc4SBram Moolenaar  call assert_equal("e\\\\\re", substitute('eEe', 'E', "\\=\"\\\\\\\\\r\"", ''))
3331a333bc4SBram Moolenaar  call assert_equal('f\rf', substitute('fFf', 'F', '\="\\r"', ''))
3341a333bc4SBram Moolenaar  call assert_equal('j\nj', substitute('jJj', 'J', '\="\\n"', ''))
3351a333bc4SBram Moolenaar  call assert_equal("k\<C-M>k", substitute('kKk', 'K', '\="\r"', ''))
3361a333bc4SBram Moolenaar  call assert_equal("l\nl", substitute('lLl', 'L', '\="\n"', ''))
3371a333bc4SBram Moolenaarendfunc
3381a333bc4SBram Moolenaar
3391a333bc4SBram Moolenaar" Test for submatch() on substitute().
3401a333bc4SBram Moolenaarfunc Test_sub_replace_4()
3411a333bc4SBram Moolenaar  set magic&
3421a333bc4SBram Moolenaar  set cpo&
3431a333bc4SBram Moolenaar  call assert_equal('a\a', substitute('aAa', 'A',
3441a333bc4SBram Moolenaar		\ '\=substitute(submatch(0), ".", "\\", "")', ''))
3451a333bc4SBram Moolenaar  call assert_equal('b\b', substitute('bBb', 'B',
3461a333bc4SBram Moolenaar		\ '\=substitute(submatch(0), ".", "\\\\", "")', ''))
3471a333bc4SBram Moolenaar  call assert_equal("c\<C-V>\<C-M>c", substitute('cCc', 'C', '\=substitute(submatch(0), ".", "\<C-V>\<C-M>", "")', ''))
3481a333bc4SBram Moolenaar  call assert_equal("d\<C-V>\<C-M>d", substitute('dDd', 'D', '\=substitute(submatch(0), ".", "\\\<C-V>\<C-M>", "")', ''))
3491a333bc4SBram Moolenaar  call assert_equal("e\\\<C-V>\<C-M>e", substitute('eEe', 'E', '\=substitute(submatch(0), ".", "\\\\\<C-V>\<C-M>", "")', ''))
3501a333bc4SBram Moolenaar  call assert_equal("f\<C-M>f", substitute('fFf', 'F', '\=substitute(submatch(0), ".", "\\r", "")', ''))
3511a333bc4SBram Moolenaar  call assert_equal("j\nj", substitute('jJj', 'J', '\=substitute(submatch(0), ".", "\\n", "")', ''))
3521a333bc4SBram Moolenaar  call assert_equal("k\rk", substitute('kKk', 'K', '\=substitute(submatch(0), ".", "\r", "")', ''))
3531a333bc4SBram Moolenaar  call assert_equal("l\nl", substitute('lLl', 'L', '\=substitute(submatch(0), ".", "\n", "")', ''))
3541a333bc4SBram Moolenaarendfunc
3551a333bc4SBram Moolenaar
3561a333bc4SBram Moolenaarfunc Test_sub_replace_5()
3571a333bc4SBram Moolenaar  set magic&
3581a333bc4SBram Moolenaar  set cpo&
3591a333bc4SBram Moolenaar  call assert_equal('A123456789987654321', substitute('A123456789',
3601a333bc4SBram Moolenaar		\ 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)',
3611a333bc4SBram Moolenaar		\ '\=submatch(0) . submatch(9) . submatch(8) . ' .
3621a333bc4SBram Moolenaar		\ 'submatch(7) . submatch(6) . submatch(5) . ' .
3631a333bc4SBram Moolenaar		\ 'submatch(4) . submatch(3) . submatch(2) . submatch(1)',
3641a333bc4SBram Moolenaar		\ ''))
3651a333bc4SBram Moolenaar   call assert_equal("[['A123456789'], ['9'], ['8'], ['7'], ['6'], " .
3661a333bc4SBram Moolenaar		\ "['5'], ['4'], ['3'], ['2'], ['1']]",
3671a333bc4SBram Moolenaar		\ substitute('A123456789',
3681a333bc4SBram Moolenaar		\ 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)',
3691a333bc4SBram Moolenaar		\ '\=string([submatch(0, 1), submatch(9, 1), ' .
370f6ed61e1SBram Moolenaar		\ 'submatch(8, 1), 7->submatch(1), submatch(6, 1), ' .
3711a333bc4SBram Moolenaar		\ 'submatch(5, 1), submatch(4, 1), submatch(3, 1), ' .
3721a333bc4SBram Moolenaar		\ 'submatch(2, 1), submatch(1, 1)])',
3731a333bc4SBram Moolenaar		\ ''))
3741a333bc4SBram Moolenaarendfunc
3751a333bc4SBram Moolenaar
3761a333bc4SBram Moolenaarfunc Test_sub_replace_6()
3771a333bc4SBram Moolenaar  set magic&
3781a333bc4SBram Moolenaar  set cpo+=/
3791a333bc4SBram Moolenaar  call assert_equal('a', substitute('A', 'A', 'a', ''))
3801a333bc4SBram Moolenaar  call assert_equal('%', substitute('B', 'B', '%', ''))
3811a333bc4SBram Moolenaar  set cpo-=/
3821a333bc4SBram Moolenaar  call assert_equal('c', substitute('C', 'C', 'c', ''))
3831a333bc4SBram Moolenaar  call assert_equal('%', substitute('D', 'D', '%', ''))
3841a333bc4SBram Moolenaarendfunc
3851a333bc4SBram Moolenaar
3861a333bc4SBram Moolenaarfunc Test_sub_replace_7()
3871a333bc4SBram Moolenaar  set magic&
3881a333bc4SBram Moolenaar  set cpo&
3891a333bc4SBram Moolenaar  call assert_equal('AA', substitute('AA', 'A.', '\=submatch(0)', ''))
3901a333bc4SBram Moolenaar  call assert_equal("B\nB", substitute("B\nB", 'B.', '\=submatch(0)', ''))
3911a333bc4SBram Moolenaar  call assert_equal("['B\n']B", substitute("B\nB", 'B.', '\=string(submatch(0, 1))', ''))
3921a333bc4SBram Moolenaar  call assert_equal('-abab', substitute('-bb', '\zeb', 'a', 'g'))
3931a333bc4SBram Moolenaar  call assert_equal('c-cbcbc', substitute('-bb', '\ze', 'c', 'g'))
3941a333bc4SBram Moolenaarendfunc
3951a333bc4SBram Moolenaar
3961a333bc4SBram Moolenaar" Test for *:s%* on :substitute.
3971a333bc4SBram Moolenaarfunc Test_sub_replace_8()
3981a333bc4SBram Moolenaar  new
3991a333bc4SBram Moolenaar  set magic&
4001a333bc4SBram Moolenaar  set cpo&
4011a333bc4SBram Moolenaar  $put =',,X'
4021a333bc4SBram Moolenaar  s/\(^\|,\)\ze\(,\|X\)/\1N/g
4031a333bc4SBram Moolenaar  call assert_equal('N,,NX', getline("$"))
4041a333bc4SBram Moolenaar  $put =',,Y'
4051a333bc4SBram Moolenaar  let cmd = ':s/\(^\|,\)\ze\(,\|Y\)/\1N/gc'
4061a333bc4SBram Moolenaar  call feedkeys(cmd . "\<CR>a", "xt")
4071a333bc4SBram Moolenaar  call assert_equal('N,,NY', getline("$"))
4081a333bc4SBram Moolenaar  :$put =',,Z'
4091a333bc4SBram Moolenaar  let cmd = ':s/\(^\|,\)\ze\(,\|Z\)/\1N/gc'
4101a333bc4SBram Moolenaar  call feedkeys(cmd . "\<CR>yy", "xt")
4111a333bc4SBram Moolenaar  call assert_equal('N,,NZ', getline("$"))
4121a333bc4SBram Moolenaar  enew! | close
4131a333bc4SBram Moolenaarendfunc
4141a333bc4SBram Moolenaar
4151a333bc4SBram Moolenaarfunc Test_sub_replace_9()
4161a333bc4SBram Moolenaar  new
4171a333bc4SBram Moolenaar  set magic&
4181a333bc4SBram Moolenaar  set cpo&
4191a333bc4SBram Moolenaar  $put ='xxx'
4201a333bc4SBram Moolenaar  call feedkeys(":s/x/X/gc\<CR>yyq", "xt")
4211a333bc4SBram Moolenaar  call assert_equal('XXx', getline("$"))
4221a333bc4SBram Moolenaar  enew! | close
4231a333bc4SBram Moolenaarendfunc
4241a333bc4SBram Moolenaar
4251a333bc4SBram Moolenaarfunc Test_sub_replace_10()
4261a333bc4SBram Moolenaar   set magic&
4271a333bc4SBram Moolenaar   set cpo&
4281a333bc4SBram Moolenaar   call assert_equal('a1a2a3a', substitute('123', '\zs', 'a', 'g'))
4291a333bc4SBram Moolenaar   call assert_equal('aaa', substitute('123', '\zs.', 'a', 'g'))
4301a333bc4SBram Moolenaar   call assert_equal('1a2a3a', substitute('123', '.\zs', 'a', 'g'))
4311a333bc4SBram Moolenaar   call assert_equal('a1a2a3a', substitute('123', '\ze', 'a', 'g'))
4321a333bc4SBram Moolenaar   call assert_equal('a1a2a3', substitute('123', '\ze.', 'a', 'g'))
4331a333bc4SBram Moolenaar   call assert_equal('aaa', substitute('123', '.\ze', 'a', 'g'))
4341a333bc4SBram Moolenaar   call assert_equal('aa2a3a', substitute('123', '1\|\ze', 'a', 'g'))
4351a333bc4SBram Moolenaar   call assert_equal('1aaa', substitute('123', '1\zs\|[23]', 'a', 'g'))
4361a333bc4SBram Moolenaarendfunc
43715993ce9SBram Moolenaar
438b0745b22SBram Moolenaarfunc SubReplacer(text, submatches)
439b0745b22SBram Moolenaar  return a:text .. a:submatches[0] .. a:text
440b0745b22SBram Moolenaarendfunc
4414c054e9fSBram Moolenaarfunc SubReplacer20(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, submatches)
4424c054e9fSBram Moolenaar  return a:t3 .. a:submatches[0] .. a:t11
4434c054e9fSBram Moolenaarendfunc
444b0745b22SBram Moolenaar
445b0745b22SBram Moolenaarfunc Test_substitute_partial()
446b0745b22SBram Moolenaar   call assert_equal('1foo2foo3', substitute('123', '2', function('SubReplacer', ['foo']), 'g'))
4474c054e9fSBram Moolenaar
4484c054e9fSBram Moolenaar   " 19 arguments plus one is just OK
4494c054e9fSBram Moolenaar   let Replacer = function('SubReplacer20', repeat(['foo'], 19))
4504c054e9fSBram Moolenaar   call assert_equal('1foo2foo3', substitute('123', '2', Replacer, 'g'))
4514c054e9fSBram Moolenaar
4524c054e9fSBram Moolenaar   " 20 arguments plus one is too many
4534c054e9fSBram Moolenaar   let Replacer = function('SubReplacer20', repeat(['foo'], 20))
454e2e4075fSBram Moolenaar   call assert_fails("call substitute('123', '2', Replacer, 'g')", 'E118:')
455b0745b22SBram Moolenaarendfunc
456b0745b22SBram Moolenaar
4577a2217beSBram Moolenaarfunc Test_substitute_float()
4587a2217beSBram Moolenaar  CheckFeature float
4597a2217beSBram Moolenaar
4607a2217beSBram Moolenaar  call assert_equal('number 1.23', substitute('number ', '$', { -> 1.23 }, ''))
4617a2217beSBram Moolenaar  vim9 assert_equal('number 1.23', substitute('number ', '$', () => 1.23, ''))
4627a2217beSBram Moolenaarendfunc
4637a2217beSBram Moolenaar
46415993ce9SBram Moolenaar" Tests for *sub-replace-special* and *sub-replace-expression* on :substitute.
46515993ce9SBram Moolenaar
46615993ce9SBram Moolenaar" Execute a list of :substitute command tests
46715993ce9SBram Moolenaarfunc Run_SubCmd_Tests(tests)
46815993ce9SBram Moolenaar  enew!
46915993ce9SBram Moolenaar  for t in a:tests
47015993ce9SBram Moolenaar    let start = line('.') + 1
47115993ce9SBram Moolenaar    let end = start + len(t[2]) - 1
472bb265962SBram Moolenaar    " TODO: why is there a one second delay the first time we get here?
47315993ce9SBram Moolenaar    exe "normal o" . t[0]
47415993ce9SBram Moolenaar    call cursor(start, 1)
47515993ce9SBram Moolenaar    exe t[1]
47615993ce9SBram Moolenaar    call assert_equal(t[2], getline(start, end), t[1])
47715993ce9SBram Moolenaar  endfor
47815993ce9SBram Moolenaar  enew!
47915993ce9SBram Moolenaarendfunc
48015993ce9SBram Moolenaar
48115993ce9SBram Moolenaarfunc Test_sub_cmd_1()
48215993ce9SBram Moolenaar  set magic
48315993ce9SBram Moolenaar  set cpo&
48415993ce9SBram Moolenaar
48515993ce9SBram Moolenaar  " List entry format: [input, cmd, output]
48615993ce9SBram Moolenaar  let tests = [['A', 's/A/&&/', ['AA']],
48715993ce9SBram Moolenaar	      \ ['B', 's/B/\&/', ['&']],
48815993ce9SBram Moolenaar	      \ ['C123456789', 's/C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)/\0\9\8\7\6\5\4\3\2\1/', ['C123456789987654321']],
48915993ce9SBram Moolenaar	      \ ['D', 's/D/d/', ['d']],
49015993ce9SBram Moolenaar	      \ ['E', 's/E/~/', ['d']],
49115993ce9SBram Moolenaar	      \ ['F', 's/F/\~/', ['~']],
49215993ce9SBram Moolenaar	      \ ['G', 's/G/\ugg/', ['Gg']],
49315993ce9SBram Moolenaar	      \ ['H', 's/H/\Uh\Eh/', ['Hh']],
49415993ce9SBram Moolenaar	      \ ['I', 's/I/\lII/', ['iI']],
49515993ce9SBram Moolenaar	      \ ['J', 's/J/\LJ\EJ/', ['jJ']],
49615993ce9SBram Moolenaar	      \ ['K', 's/K/\Uk\ek/', ['Kk']],
49715993ce9SBram Moolenaar	      \ ['lLl', "s/L/\<C-V>\<C-M>/", ["l\<C-V>", 'l']],
49815993ce9SBram Moolenaar	      \ ['mMm', 's/M/\r/', ['m', 'm']],
49915993ce9SBram Moolenaar	      \ ['nNn', "s/N/\\\<C-V>\<C-M>/", ["n\<C-V>", 'n']],
50015993ce9SBram Moolenaar	      \ ['oOo', 's/O/\n/', ["o\no"]],
50115993ce9SBram Moolenaar	      \ ['pPp', 's/P/\b/', ["p\<C-H>p"]],
50215993ce9SBram Moolenaar	      \ ['qQq', 's/Q/\t/', ["q\tq"]],
50315993ce9SBram Moolenaar	      \ ['rRr', 's/R/\\/', ['r\r']],
50415993ce9SBram Moolenaar	      \ ['sSs', 's/S/\c/', ['scs']],
50515993ce9SBram Moolenaar	      \ ['tTt', "s/T/\<C-V>\<C-J>/", ["t\<C-V>\<C-J>t"]],
50615993ce9SBram Moolenaar	      \ ['U', 's/U/\L\uuUu\l\EU/', ['UuuU']],
50715993ce9SBram Moolenaar	      \ ['V', 's/V/\U\lVvV\u\Ev/', ['vVVv']]
50815993ce9SBram Moolenaar	      \ ]
50915993ce9SBram Moolenaar  call Run_SubCmd_Tests(tests)
51015993ce9SBram Moolenaarendfunc
51115993ce9SBram Moolenaar
51215993ce9SBram Moolenaarfunc Test_sub_cmd_2()
51315993ce9SBram Moolenaar  set nomagic
51415993ce9SBram Moolenaar  set cpo&
51515993ce9SBram Moolenaar
51615993ce9SBram Moolenaar  " List entry format: [input, cmd, output]
51715993ce9SBram Moolenaar  let tests = [['A', 's/A/&&/', ['&&']],
51815993ce9SBram Moolenaar	      \ ['B', 's/B/\&/', ['B']],
51915993ce9SBram Moolenaar	      \ ['C123456789', 's/\mC\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)/\0\9\8\7\6\5\4\3\2\1/', ['C123456789987654321']],
52015993ce9SBram Moolenaar	      \ ['D', 's/D/d/', ['d']],
52115993ce9SBram Moolenaar	      \ ['E', 's/E/~/', ['~']],
52215993ce9SBram Moolenaar	      \ ['F', 's/F/\~/', ['~']],
52315993ce9SBram Moolenaar	      \ ['G', 's/G/\ugg/', ['Gg']],
52415993ce9SBram Moolenaar	      \ ['H', 's/H/\Uh\Eh/', ['Hh']],
52515993ce9SBram Moolenaar	      \ ['I', 's/I/\lII/', ['iI']],
52615993ce9SBram Moolenaar	      \ ['J', 's/J/\LJ\EJ/', ['jJ']],
52715993ce9SBram Moolenaar	      \ ['K', 's/K/\Uk\ek/', ['Kk']],
52815993ce9SBram Moolenaar	      \ ['lLl', "s/L/\<C-V>\<C-M>/", ["l\<C-V>", 'l']],
52915993ce9SBram Moolenaar	      \ ['mMm', 's/M/\r/', ['m', 'm']],
53015993ce9SBram Moolenaar	      \ ['nNn', "s/N/\\\<C-V>\<C-M>/", ["n\<C-V>", 'n']],
53115993ce9SBram Moolenaar	      \ ['oOo', 's/O/\n/', ["o\no"]],
53215993ce9SBram Moolenaar	      \ ['pPp', 's/P/\b/', ["p\<C-H>p"]],
53315993ce9SBram Moolenaar	      \ ['qQq', 's/Q/\t/', ["q\tq"]],
53415993ce9SBram Moolenaar	      \ ['rRr', 's/R/\\/', ['r\r']],
53515993ce9SBram Moolenaar	      \ ['sSs', 's/S/\c/', ['scs']],
53615993ce9SBram Moolenaar	      \ ['tTt', "s/T/\<C-V>\<C-J>/", ["t\<C-V>\<C-J>t"]],
53715993ce9SBram Moolenaar	      \ ['U', 's/U/\L\uuUu\l\EU/', ['UuuU']],
53815993ce9SBram Moolenaar	      \ ['V', 's/V/\U\lVvV\u\Ev/', ['vVVv']]
53915993ce9SBram Moolenaar	      \ ]
54015993ce9SBram Moolenaar  call Run_SubCmd_Tests(tests)
54115993ce9SBram Moolenaarendfunc
54215993ce9SBram Moolenaar
54315993ce9SBram Moolenaarfunc Test_sub_cmd_3()
54415993ce9SBram Moolenaar  set nomagic
54515993ce9SBram Moolenaar  set cpo&
54615993ce9SBram Moolenaar
54715993ce9SBram Moolenaar  " List entry format: [input, cmd, output]
54815993ce9SBram Moolenaar  let tests = [['aAa', "s/A/\\='\\'/", ['a\a']],
54915993ce9SBram Moolenaar	      \ ['bBb', "s/B/\\='\\\\'/", ['b\\b']],
55015993ce9SBram Moolenaar	      \ ['cCc', "s/C/\\='\<C-V>\<C-M>'/", ["c\<C-V>", 'c']],
55115993ce9SBram Moolenaar	      \ ['dDd', "s/D/\\='\\\<C-V>\<C-M>'/", ["d\\\<C-V>", 'd']],
55215993ce9SBram Moolenaar	      \ ['eEe', "s/E/\\='\\\\\<C-V>\<C-M>'/", ["e\\\\\<C-V>", 'e']],
55315993ce9SBram Moolenaar	      \ ['fFf', "s/F/\\='\r'/", ['f', 'f']],
55415993ce9SBram Moolenaar	      \ ['gGg', "s/G/\\='\<C-V>\<C-J>'/", ["g\<C-V>", 'g']],
55515993ce9SBram Moolenaar	      \ ['hHh', "s/H/\\='\\\<C-V>\<C-J>'/", ["h\\\<C-V>", 'h']],
55615993ce9SBram Moolenaar	      \ ['iIi', "s/I/\\='\\\\\<C-V>\<C-J>'/", ["i\\\\\<C-V>", 'i']],
55715993ce9SBram Moolenaar	      \ ['jJj', "s/J/\\='\n'/", ['j', 'j']],
55815993ce9SBram Moolenaar	      \ ['kKk', 's/K/\="\r"/', ['k', 'k']],
55915993ce9SBram Moolenaar	      \ ['lLl', 's/L/\="\n"/', ['l', 'l']]
56015993ce9SBram Moolenaar	      \ ]
56115993ce9SBram Moolenaar  call Run_SubCmd_Tests(tests)
56215993ce9SBram Moolenaarendfunc
56315993ce9SBram Moolenaar
564f1699968SBram Moolenaar" Test for submatch() on :substitute.
56515993ce9SBram Moolenaarfunc Test_sub_cmd_4()
56615993ce9SBram Moolenaar  set magic&
56715993ce9SBram Moolenaar  set cpo&
56815993ce9SBram Moolenaar
56915993ce9SBram Moolenaar  " List entry format: [input, cmd, output]
57015993ce9SBram Moolenaar  let tests = [ ['aAa', "s/A/\\=substitute(submatch(0), '.', '\\', '')/",
57115993ce9SBram Moolenaar	      \				['a\a']],
57215993ce9SBram Moolenaar	      \ ['bBb', "s/B/\\=substitute(submatch(0), '.', '\\', '')/",
57315993ce9SBram Moolenaar	      \				['b\b']],
57415993ce9SBram Moolenaar	      \ ['cCc', "s/C/\\=substitute(submatch(0), '.', '\<C-V>\<C-M>', '')/",
57515993ce9SBram Moolenaar	      \				["c\<C-V>", 'c']],
57615993ce9SBram Moolenaar	      \ ['dDd', "s/D/\\=substitute(submatch(0), '.', '\\\<C-V>\<C-M>', '')/",
57715993ce9SBram Moolenaar	      \				["d\<C-V>", 'd']],
57815993ce9SBram Moolenaar	      \ ['eEe', "s/E/\\=substitute(submatch(0), '.', '\\\\\<C-V>\<C-M>', '')/",
57915993ce9SBram Moolenaar	      \				["e\\\<C-V>", 'e']],
58015993ce9SBram Moolenaar	      \ ['fFf', "s/F/\\=substitute(submatch(0), '.', '\\r', '')/",
58115993ce9SBram Moolenaar	      \				['f', 'f']],
58215993ce9SBram Moolenaar	      \ ['gGg', 's/G/\=substitute(submatch(0), ".", "\<C-V>\<C-J>", "")/',
58315993ce9SBram Moolenaar	      \				["g\<C-V>", 'g']],
58415993ce9SBram Moolenaar	      \ ['hHh', 's/H/\=substitute(submatch(0), ".", "\\\<C-V>\<C-J>", "")/',
58515993ce9SBram Moolenaar	      \				["h\<C-V>", 'h']],
58615993ce9SBram Moolenaar	      \ ['iIi', 's/I/\=substitute(submatch(0), ".", "\\\\\<C-V>\<C-J>", "")/',
58715993ce9SBram Moolenaar	      \				["i\\\<C-V>", 'i']],
58815993ce9SBram Moolenaar	      \ ['jJj', "s/J/\\=substitute(submatch(0), '.', '\\n', '')/",
58915993ce9SBram Moolenaar	      \				['j', 'j']],
59015993ce9SBram Moolenaar	      \ ['kKk', "s/K/\\=substitute(submatch(0), '.', '\\r', '')/",
59115993ce9SBram Moolenaar	      \				['k', 'k']],
59215993ce9SBram Moolenaar	      \ ['lLl', "s/L/\\=substitute(submatch(0), '.', '\\n', '')/",
59315993ce9SBram Moolenaar	      \				['l', 'l']],
59415993ce9SBram Moolenaar	      \ ]
59515993ce9SBram Moolenaar  call Run_SubCmd_Tests(tests)
59615993ce9SBram Moolenaarendfunc
59715993ce9SBram Moolenaar
59815993ce9SBram Moolenaarfunc Test_sub_cmd_5()
59915993ce9SBram Moolenaar  set magic&
60015993ce9SBram Moolenaar  set cpo&
60115993ce9SBram Moolenaar
60215993ce9SBram Moolenaar  " List entry format: [input, cmd, output]
60315993ce9SBram Moolenaar  let tests = [ ['A123456789', 's/A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)/\=submatch(0) . submatch(9) . submatch(8) . submatch(7) . submatch(6) . submatch(5) . submatch(4) . submatch(3) . submatch(2) . submatch(1)/', ['A123456789987654321']],
60415993ce9SBram Moolenaar	      \ ['B123456789', 's/B\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)/\=string([submatch(0, 1), submatch(9, 1), submatch(8, 1), submatch(7, 1), submatch(6, 1), submatch(5, 1), submatch(4, 1), submatch(3, 1), submatch(2, 1), submatch(1, 1)])/', ["[['B123456789'], ['9'], ['8'], ['7'], ['6'], ['5'], ['4'], ['3'], ['2'], ['1']]"]],
60515993ce9SBram Moolenaar	      \ ]
60615993ce9SBram Moolenaar  call Run_SubCmd_Tests(tests)
60715993ce9SBram Moolenaarendfunc
60815993ce9SBram Moolenaar
60915993ce9SBram Moolenaar" Test for *:s%* on :substitute.
61015993ce9SBram Moolenaarfunc Test_sub_cmd_6()
61115993ce9SBram Moolenaar  set magic&
61215993ce9SBram Moolenaar  set cpo+=/
61315993ce9SBram Moolenaar
61415993ce9SBram Moolenaar  " List entry format: [input, cmd, output]
61515993ce9SBram Moolenaar  let tests = [ ['A', 's/A/a/', ['a']],
61615993ce9SBram Moolenaar	      \ ['B', 's/B/%/', ['a']],
61715993ce9SBram Moolenaar	      \ ]
61815993ce9SBram Moolenaar  call Run_SubCmd_Tests(tests)
61915993ce9SBram Moolenaar
62015993ce9SBram Moolenaar  set cpo-=/
62115993ce9SBram Moolenaar  let tests = [ ['C', 's/C/c/', ['c']],
62215993ce9SBram Moolenaar	      \ ['D', 's/D/%/', ['%']],
62315993ce9SBram Moolenaar	      \ ]
62415993ce9SBram Moolenaar  call Run_SubCmd_Tests(tests)
62515993ce9SBram Moolenaar
62615993ce9SBram Moolenaar  set cpo&
62715993ce9SBram Moolenaarendfunc
62815993ce9SBram Moolenaar
62915993ce9SBram Moolenaar" Test for :s replacing \n with  line break.
63015993ce9SBram Moolenaarfunc Test_sub_cmd_7()
63115993ce9SBram Moolenaar  set magic&
63215993ce9SBram Moolenaar  set cpo&
63315993ce9SBram Moolenaar
63415993ce9SBram Moolenaar  " List entry format: [input, cmd, output]
63515993ce9SBram Moolenaar  let tests = [ ["A\<C-V>\<C-M>A", 's/A./\=submatch(0)/', ['A', 'A']],
63615993ce9SBram Moolenaar	      \ ["B\<C-V>\<C-J>B", 's/B./\=submatch(0)/', ['B', 'B']],
63715993ce9SBram Moolenaar	      \ ["C\<C-V>\<C-J>C", 's/C./\=strtrans(string(submatch(0, 1)))/', [strtrans("['C\<C-J>']C")]],
63815993ce9SBram Moolenaar	      \ ["D\<C-V>\<C-J>\nD", 's/D.\nD/\=strtrans(string(submatch(0, 1)))/', [strtrans("['D\<C-J>', 'D']")]],
63915993ce9SBram Moolenaar	      \ ["E\<C-V>\<C-J>\n\<C-V>\<C-J>\n\<C-V>\<C-J>\n\<C-V>\<C-J>\n\<C-V>\<C-J>E", 's/E\_.\{-}E/\=strtrans(string(submatch(0, 1)))/', [strtrans("['E\<C-J>', '\<C-J>', '\<C-J>', '\<C-J>', '\<C-J>E']")]],
64015993ce9SBram Moolenaar	      \ ]
64115993ce9SBram Moolenaar  call Run_SubCmd_Tests(tests)
64215993ce9SBram Moolenaar
64315993ce9SBram Moolenaar  exe "normal oQ\nQ\<Esc>k"
644e2e4075fSBram Moolenaar  call assert_fails('s/Q[^\n]Q/\=submatch(0)."foobar"/', 'E486:')
64515993ce9SBram Moolenaar  enew!
64615993ce9SBram Moolenaarendfunc
64715993ce9SBram Moolenaar
64815993ce9SBram Moolenaarfunc TitleString()
64915993ce9SBram Moolenaar  let check = 'foo' =~ 'bar'
65015993ce9SBram Moolenaar  return ""
65115993ce9SBram Moolenaarendfunc
65215993ce9SBram Moolenaar
65315993ce9SBram Moolenaarfunc Test_sub_cmd_8()
65415993ce9SBram Moolenaar  set titlestring=%{TitleString()}
65515993ce9SBram Moolenaar
65615993ce9SBram Moolenaar  enew!
65715993ce9SBram Moolenaar  call append(0, ['', 'test_one', 'test_two'])
65815993ce9SBram Moolenaar  call cursor(1,1)
65915993ce9SBram Moolenaar  /^test_one/s/.*/\="foo\nbar"/
66015993ce9SBram Moolenaar  call assert_equal('foo', getline(2))
66115993ce9SBram Moolenaar  call assert_equal('bar', getline(3))
66215993ce9SBram Moolenaar  call feedkeys(':/^test_two/s/.*/\="foo\nbar"/c', "t")
66315993ce9SBram Moolenaar  call feedkeys("\<CR>y", "xt")
66415993ce9SBram Moolenaar  call assert_equal('foo', getline(4))
66515993ce9SBram Moolenaar  call assert_equal('bar', getline(5))
66615993ce9SBram Moolenaar
66715993ce9SBram Moolenaar  enew!
66815993ce9SBram Moolenaar  set titlestring&
66915993ce9SBram Moolenaarendfunc
6700e97b948SBram Moolenaar
67180341bcdSBram Moolenaarfunc Test_sub_cmd_9()
67280341bcdSBram Moolenaar  new
67380341bcdSBram Moolenaar  let input = ['1 aaa', '2 aaa', '3 aaa']
67480341bcdSBram Moolenaar  call setline(1, input)
67580341bcdSBram Moolenaar  func Foo()
67680341bcdSBram Moolenaar    return submatch(0)
67780341bcdSBram Moolenaar  endfunc
67880341bcdSBram Moolenaar  %s/aaa/\=Foo()/gn
67980341bcdSBram Moolenaar  call assert_equal(input, getline(1, '$'))
68080341bcdSBram Moolenaar  call assert_equal(1, &modifiable)
68180341bcdSBram Moolenaar
68280341bcdSBram Moolenaar  delfunc Foo
68380341bcdSBram Moolenaar  bw!
68480341bcdSBram Moolenaarendfunc
68580341bcdSBram Moolenaar
6860e97b948SBram Moolenaarfunc Test_nocatch_sub_failure_handling()
6870e97b948SBram Moolenaar  " normal error results in all replacements
68880341bcdSBram Moolenaar  func Foo()
6890e97b948SBram Moolenaar    foobar
6900e97b948SBram Moolenaar  endfunc
6910e97b948SBram Moolenaar  new
6920e97b948SBram Moolenaar  call setline(1, ['1 aaa', '2 aaa', '3 aaa'])
6930e97b948SBram Moolenaar  %s/aaa/\=Foo()/g
6940e97b948SBram Moolenaar  call assert_equal(['1 0', '2 0', '3 0'], getline(1, 3))
6950e97b948SBram Moolenaar
6960e97b948SBram Moolenaar  " Trow without try-catch causes abort after the first line.
6970e97b948SBram Moolenaar  " We cannot test this, since it would stop executing the test script.
6980e97b948SBram Moolenaar
6990e97b948SBram Moolenaar  " try/catch does not result in any changes
7000e97b948SBram Moolenaar  func! Foo()
7010e97b948SBram Moolenaar    throw 'error'
7020e97b948SBram Moolenaar  endfunc
7030e97b948SBram Moolenaar  call setline(1, ['1 aaa', '2 aaa', '3 aaa'])
7040e97b948SBram Moolenaar  let error_caught = 0
7050e97b948SBram Moolenaar  try
7060e97b948SBram Moolenaar    %s/aaa/\=Foo()/g
7070e97b948SBram Moolenaar  catch
7080e97b948SBram Moolenaar    let error_caught = 1
7090e97b948SBram Moolenaar  endtry
7100e97b948SBram Moolenaar  call assert_equal(1, error_caught)
7110e97b948SBram Moolenaar  call assert_equal(['1 aaa', '2 aaa', '3 aaa'], getline(1, 3))
7120e97b948SBram Moolenaar
7136349e941SBram Moolenaar  " Same, but using "n" flag so that "sandbox" gets set
7146349e941SBram Moolenaar  call setline(1, ['1 aaa', '2 aaa', '3 aaa'])
7156349e941SBram Moolenaar  let error_caught = 0
7166349e941SBram Moolenaar  try
7176349e941SBram Moolenaar    %s/aaa/\=Foo()/gn
7186349e941SBram Moolenaar  catch
7196349e941SBram Moolenaar    let error_caught = 1
7206349e941SBram Moolenaar  endtry
7216349e941SBram Moolenaar  call assert_equal(1, error_caught)
7226349e941SBram Moolenaar  call assert_equal(['1 aaa', '2 aaa', '3 aaa'], getline(1, 3))
7236349e941SBram Moolenaar
72480341bcdSBram Moolenaar  delfunc Foo
7250e97b948SBram Moolenaar  bwipe!
7260e97b948SBram Moolenaarendfunc
727c6b37db1SBram Moolenaar
728c6b37db1SBram Moolenaar" Test ":s/pat/sub/" with different ~s in sub.
729c6b37db1SBram Moolenaarfunc Test_replace_with_tilde()
730c6b37db1SBram Moolenaar  new
731c6b37db1SBram Moolenaar  " Set the last replace string to empty
732c6b37db1SBram Moolenaar  s/^$//
733c6b37db1SBram Moolenaar  call append(0, ['- Bug in "vPPPP" on this text:'])
734c6b37db1SBram Moolenaar  normal gg
735c6b37db1SBram Moolenaar  s/u/~u~/
736c6b37db1SBram Moolenaar  call assert_equal('- Bug in "vPPPP" on this text:', getline(1))
737c6b37db1SBram Moolenaar  s/i/~u~/
738c6b37db1SBram Moolenaar  call assert_equal('- Bug uuun "vPPPP" on this text:', getline(1))
739c6b37db1SBram Moolenaar  s/o/~~~/
740c6b37db1SBram Moolenaar  call assert_equal('- Bug uuun "vPPPP" uuuuuuuuun this text:', getline(1))
741c6b37db1SBram Moolenaar  close!
742c6b37db1SBram Moolenaarendfunc
743c6b37db1SBram Moolenaar
744c6b37db1SBram Moolenaarfunc Test_replace_keeppatterns()
745c6b37db1SBram Moolenaar  new
746c6b37db1SBram Moolenaar  a
747c6b37db1SBram Moolenaarfoobar
748c6b37db1SBram Moolenaar
749c6b37db1SBram Moolenaarsubstitute foo asdf
750c6b37db1SBram Moolenaar
751c6b37db1SBram Moolenaarone two
752c6b37db1SBram Moolenaar.
753c6b37db1SBram Moolenaar
754c6b37db1SBram Moolenaar  normal gg
755c6b37db1SBram Moolenaar  /^substitute
756c6b37db1SBram Moolenaar  s/foo/bar/
757c6b37db1SBram Moolenaar  call assert_equal('foo', @/)
758c6b37db1SBram Moolenaar  call assert_equal('substitute bar asdf', getline('.'))
759c6b37db1SBram Moolenaar
760c6b37db1SBram Moolenaar  /^substitute
761c6b37db1SBram Moolenaar  keeppatterns s/asdf/xyz/
762c6b37db1SBram Moolenaar  call assert_equal('^substitute', @/)
763c6b37db1SBram Moolenaar  call assert_equal('substitute bar xyz', getline('.'))
764c6b37db1SBram Moolenaar
765c6b37db1SBram Moolenaar  exe "normal /bar /e\<CR>"
766c6b37db1SBram Moolenaar  call assert_equal(15, col('.'))
767c6b37db1SBram Moolenaar  normal -
768c6b37db1SBram Moolenaar  keeppatterns /xyz
769c6b37db1SBram Moolenaar  call assert_equal('bar ', @/)
770c6b37db1SBram Moolenaar  call assert_equal('substitute bar xyz', getline('.'))
771c6b37db1SBram Moolenaar  exe "normal 0dn"
772c6b37db1SBram Moolenaar  call assert_equal('xyz', getline('.'))
773c6b37db1SBram Moolenaar
774c6b37db1SBram Moolenaar  close!
775c6b37db1SBram Moolenaarendfunc
776bb265962SBram Moolenaar
777bb265962SBram Moolenaarfunc Test_sub_beyond_end()
778bb265962SBram Moolenaar  new
779bb265962SBram Moolenaar  call setline(1, '#')
780bb265962SBram Moolenaar  let @/ = '^#\n\zs'
781bb265962SBram Moolenaar  s///e
782bb265962SBram Moolenaar  call assert_equal('#', getline(1))
783bb265962SBram Moolenaar  bwipe!
784bb265962SBram Moolenaarendfunc
7855d98dc2aSBram Moolenaar
786ea3db914SBram Moolenaar" Test for repeating last substitution using :~ and :&r
787ea3db914SBram Moolenaarfunc Test_repeat_last_sub()
788ea3db914SBram Moolenaar  new
789ea3db914SBram Moolenaar  call setline(1, ['blue green yellow orange white'])
790ea3db914SBram Moolenaar  s/blue/red/
791ea3db914SBram Moolenaar  let @/ = 'yellow'
792ea3db914SBram Moolenaar  ~
793ea3db914SBram Moolenaar  let @/ = 'white'
794ea3db914SBram Moolenaar  :&r
795ea3db914SBram Moolenaar  let @/ = 'green'
796ea3db914SBram Moolenaar  s//gray
797ea3db914SBram Moolenaar  call assert_equal('red gray red orange red', getline(1))
798ea3db914SBram Moolenaar  close!
799ea3db914SBram Moolenaarendfunc
800ea3db914SBram Moolenaar
801ea3db914SBram Moolenaar" Test for Vi compatible substitution:
802ea3db914SBram Moolenaar"     \/{string}/, \?{string}? and \&{string}&
803ea3db914SBram Moolenaarfunc Test_sub_vi_compatibility()
804ea3db914SBram Moolenaar  new
805ea3db914SBram Moolenaar  call setline(1, ['blue green yellow orange blue'])
806ea3db914SBram Moolenaar  let @/ = 'orange'
807ea3db914SBram Moolenaar  s\/white/
808ea3db914SBram Moolenaar  let @/ = 'blue'
809ea3db914SBram Moolenaar  s\?amber?
810ea3db914SBram Moolenaar  let @/ = 'white'
811ea3db914SBram Moolenaar  s\&green&
812ea3db914SBram Moolenaar  call assert_equal('amber green yellow white green', getline(1))
813ea3db914SBram Moolenaar  close!
814ea3db914SBram Moolenaarendfunc
815ea3db914SBram Moolenaar
816ea3db914SBram Moolenaar" Test for substitute with the new text longer than the original text
817ea3db914SBram Moolenaarfunc Test_sub_expand_text()
818ea3db914SBram Moolenaar  new
819ea3db914SBram Moolenaar  call setline(1, 'abcabcabcabcabcabcabcabc')
820ea3db914SBram Moolenaar  s/b/\=repeat('B', 10)/g
821ea3db914SBram Moolenaar  call assert_equal(repeat('aBBBBBBBBBBc', 8), getline(1))
822ea3db914SBram Moolenaar  close!
823ea3db914SBram Moolenaarendfunc
824ea3db914SBram Moolenaar
82507ada5ffSBram Moolenaar" Test for command failures when the last substitute pattern is not set.
82607ada5ffSBram Moolenaarfunc Test_sub_with_no_last_pat()
8279f6277bdSBram Moolenaar  let lines =<< trim [SCRIPT]
82807ada5ffSBram Moolenaar    call assert_fails('~', 'E33:')
8299b7bf9e9SBram Moolenaar    call assert_fails('s//abc/g', 'E35:')
8309b7bf9e9SBram Moolenaar    call assert_fails('s\/bar', 'E35:')
8319b7bf9e9SBram Moolenaar    call assert_fails('s\&bar&', 'E33:')
8329f6277bdSBram Moolenaar    call writefile(v:errors, 'Xresult')
8339f6277bdSBram Moolenaar    qall!
8349f6277bdSBram Moolenaar  [SCRIPT]
8359f6277bdSBram Moolenaar  call writefile(lines, 'Xscript')
8369f6277bdSBram Moolenaar  if RunVim([], [], '--clean -S Xscript')
8379f6277bdSBram Moolenaar    call assert_equal([], readfile('Xresult'))
8389f6277bdSBram Moolenaar  endif
83907ada5ffSBram Moolenaar
8409f6277bdSBram Moolenaar  let lines =<< trim [SCRIPT]
84107ada5ffSBram Moolenaar    set cpo+=/
84207ada5ffSBram Moolenaar    call assert_fails('s/abc/%/', 'E33:')
8439f6277bdSBram Moolenaar    call writefile(v:errors, 'Xresult')
8449f6277bdSBram Moolenaar    qall!
8459f6277bdSBram Moolenaar  [SCRIPT]
8469f6277bdSBram Moolenaar  call writefile(lines, 'Xscript')
8479f6277bdSBram Moolenaar  if RunVim([], [], '--clean -S Xscript')
8489f6277bdSBram Moolenaar    call assert_equal([], readfile('Xresult'))
8499f6277bdSBram Moolenaar  endif
8509f6277bdSBram Moolenaar
8519f6277bdSBram Moolenaar  call delete('Xscript')
8529f6277bdSBram Moolenaar  call delete('Xresult')
85307ada5ffSBram Moolenaarendfunc
85407ada5ffSBram Moolenaar
855ca68ae13SBram Moolenaarfunc Test_substitute()
856ca68ae13SBram Moolenaar  call assert_equal('a1a2a3a', substitute('123', '\zs', 'a', 'g'))
857004a6781SBram Moolenaar  " Substitute with special keys
858004a6781SBram Moolenaar  call assert_equal("a\<End>c", substitute('abc', "a.c", "a\<End>c", ''))
859004a6781SBram Moolenaarendfunc
860004a6781SBram Moolenaar
861004a6781SBram Moolenaarfunc Test_substitute_expr()
862004a6781SBram Moolenaar  let g:val = 'XXX'
863004a6781SBram Moolenaar  call assert_equal('XXX', substitute('yyy', 'y*', '\=g:val', ''))
864004a6781SBram Moolenaar  call assert_equal('XXX', substitute('yyy', 'y*', {-> g:val}, ''))
865004a6781SBram Moolenaar  call assert_equal("-\u1b \uf2-", substitute("-%1b %f2-", '%\(\x\x\)',
866004a6781SBram Moolenaar			   \ '\=nr2char("0x" . submatch(1))', 'g'))
867004a6781SBram Moolenaar  call assert_equal("-\u1b \uf2-", substitute("-%1b %f2-", '%\(\x\x\)',
868004a6781SBram Moolenaar			   \ {-> nr2char("0x" . submatch(1))}, 'g'))
869004a6781SBram Moolenaar
870004a6781SBram Moolenaar  call assert_equal('231', substitute('123', '\(.\)\(.\)\(.\)',
871004a6781SBram Moolenaar	\ {-> submatch(2) . submatch(3) . submatch(1)}, ''))
872004a6781SBram Moolenaar
873004a6781SBram Moolenaar  func Recurse()
874004a6781SBram Moolenaar    return substitute('yyy', 'y\(.\)y', {-> submatch(1)}, '')
875004a6781SBram Moolenaar  endfunc
876004a6781SBram Moolenaar  " recursive call works
877004a6781SBram Moolenaar  call assert_equal('-y-x-', substitute('xxx', 'x\(.\)x', {-> '-' . Recurse() . '-' . submatch(1) . '-'}, ''))
878004a6781SBram Moolenaar
879004a6781SBram Moolenaar  call assert_fails("let s=submatch([])", 'E745:')
880004a6781SBram Moolenaar  call assert_fails("let s=submatch(2, [])", 'E745:')
881004a6781SBram Moolenaarendfunc
882004a6781SBram Moolenaar
883004a6781SBram Moolenaarfunc Test_invalid_submatch()
884004a6781SBram Moolenaar  " This was causing invalid memory access in Vim-7.4.2232 and older
885004a6781SBram Moolenaar  call assert_fails("call substitute('x', '.', {-> submatch(10)}, '')", 'E935:')
886004a6781SBram Moolenaar  call assert_fails('eval submatch(-1)', 'E935:')
887004a6781SBram Moolenaar  call assert_equal('', submatch(0))
888004a6781SBram Moolenaar  call assert_equal('', submatch(1))
889004a6781SBram Moolenaar  call assert_equal([], submatch(0, 1))
890004a6781SBram Moolenaar  call assert_equal([], submatch(1, 1))
891004a6781SBram Moolenaarendfunc
892004a6781SBram Moolenaar
8938a0dcf43SBram Moolenaarfunc Test_submatch_list_concatenate()
8948a0dcf43SBram Moolenaar  let pat = 'A\(.\)'
8958a0dcf43SBram Moolenaar  let Rep = {-> string([submatch(0, 1)] + [[submatch(1)]])}
8968a0dcf43SBram Moolenaar  call substitute('A1', pat, Rep, '')->assert_equal("[['A1'], ['1']]")
8978a0dcf43SBram Moolenaarendfunc
8988a0dcf43SBram Moolenaar
899004a6781SBram Moolenaarfunc Test_substitute_expr_arg()
900004a6781SBram Moolenaar  call assert_equal('123456789-123456789=', substitute('123456789',
901004a6781SBram Moolenaar	\ '\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)',
902004a6781SBram Moolenaar	\ {m -> m[0] . '-' . m[1] . m[2] . m[3] . m[4] . m[5] . m[6] . m[7] . m[8] . m[9] . '='}, ''))
903004a6781SBram Moolenaar
904004a6781SBram Moolenaar  call assert_equal('123456-123456=789', substitute('123456789',
905004a6781SBram Moolenaar	\ '\(.\)\(.\)\(.\)\(a*\)\(n*\)\(.\)\(.\)\(.\)\(x*\)',
906004a6781SBram Moolenaar	\ {m -> m[0] . '-' . m[1] . m[2] . m[3] . m[4] . m[5] . m[6] . m[7] . m[8] . m[9] . '='}, ''))
907004a6781SBram Moolenaar
908004a6781SBram Moolenaar  call assert_equal('123456789-123456789x=', substitute('123456789',
909004a6781SBram Moolenaar	\ '\(.\)\(.\)\(.*\)',
910004a6781SBram Moolenaar	\ {m -> m[0] . '-' . m[1] . m[2] . m[3] . 'x' . m[4] . m[5] . m[6] . m[7] . m[8] . m[9] . '='}, ''))
911004a6781SBram Moolenaar
912004a6781SBram Moolenaar  call assert_fails("call substitute('xxx', '.', {m -> string(add(m, 'x'))}, '')", 'E742:')
913004a6781SBram Moolenaar  call assert_fails("call substitute('xxx', '.', {m -> string(insert(m, 'x'))}, '')", 'E742:')
914004a6781SBram Moolenaar  call assert_fails("call substitute('xxx', '.', {m -> string(extend(m, ['x']))}, '')", 'E742:')
915004a6781SBram Moolenaar  call assert_fails("call substitute('xxx', '.', {m -> string(remove(m, 1))}, '')", 'E742:')
916004a6781SBram Moolenaarendfunc
917004a6781SBram Moolenaar
918004a6781SBram Moolenaar" Test for using a function to supply the substitute string
919004a6781SBram Moolenaarfunc Test_substitute_using_func()
920004a6781SBram Moolenaar  func Xfunc()
921004a6781SBram Moolenaar    return '1234'
922004a6781SBram Moolenaar  endfunc
923004a6781SBram Moolenaar  call assert_equal('a1234f', substitute('abcdef', 'b..e',
924004a6781SBram Moolenaar        \ function("Xfunc"), ''))
925004a6781SBram Moolenaar  delfunc Xfunc
926004a6781SBram Moolenaarendfunc
927004a6781SBram Moolenaar
928004a6781SBram Moolenaar" Test for using submatch() with a multiline match
929004a6781SBram Moolenaarfunc Test_substitute_multiline_submatch()
930004a6781SBram Moolenaar  new
931004a6781SBram Moolenaar  call setline(1, ['line1', 'line2', 'line3', 'line4'])
932004a6781SBram Moolenaar  %s/^line1\(\_.\+\)line4$/\=submatch(1)/
933004a6781SBram Moolenaar  call assert_equal(['', 'line2', 'line3', ''], getline(1, '$'))
934004a6781SBram Moolenaar  close!
935ca68ae13SBram Moolenaarendfunc
936ca68ae13SBram Moolenaar
937df36514aSBram Moolenaarfunc Test_substitute_skipped_range()
938df36514aSBram Moolenaar  new
939df36514aSBram Moolenaar  if 0
940df36514aSBram Moolenaar    /1/5/2/2/\n
941df36514aSBram Moolenaar  endif
942df36514aSBram Moolenaar  call assert_equal([0, 1, 1, 0, 1], getcurpos())
943df36514aSBram Moolenaar  bwipe!
944df36514aSBram Moolenaarendfunc
945df36514aSBram Moolenaar
946*bfb2bb16SDominique Pelle" Test using the 'gdefault' option (when on, flag 'g' is default on).
947*bfb2bb16SDominique Pellefunc Test_substitute_gdefault()
948*bfb2bb16SDominique Pelle  new
949*bfb2bb16SDominique Pelle
950*bfb2bb16SDominique Pelle  " First check without 'gdefault'
951*bfb2bb16SDominique Pelle  call setline(1, 'foo bar foo')
952*bfb2bb16SDominique Pelle  s/foo/FOO/
953*bfb2bb16SDominique Pelle  call assert_equal('FOO bar foo', getline(1))
954*bfb2bb16SDominique Pelle  call setline(1, 'foo bar foo')
955*bfb2bb16SDominique Pelle  s/foo/FOO/g
956*bfb2bb16SDominique Pelle  call assert_equal('FOO bar FOO', getline(1))
957*bfb2bb16SDominique Pelle  call setline(1, 'foo bar foo')
958*bfb2bb16SDominique Pelle  s/foo/FOO/gg
959*bfb2bb16SDominique Pelle  call assert_equal('FOO bar foo', getline(1))
960*bfb2bb16SDominique Pelle
961*bfb2bb16SDominique Pelle  " Then check with 'gdefault'
962*bfb2bb16SDominique Pelle  set gdefault
963*bfb2bb16SDominique Pelle  call setline(1, 'foo bar foo')
964*bfb2bb16SDominique Pelle  s/foo/FOO/
965*bfb2bb16SDominique Pelle  call assert_equal('FOO bar FOO', getline(1))
966*bfb2bb16SDominique Pelle  call setline(1, 'foo bar foo')
967*bfb2bb16SDominique Pelle  s/foo/FOO/g
968*bfb2bb16SDominique Pelle  call assert_equal('FOO bar foo', getline(1))
969*bfb2bb16SDominique Pelle  call setline(1, 'foo bar foo')
970*bfb2bb16SDominique Pelle  s/foo/FOO/gg
971*bfb2bb16SDominique Pelle  call assert_equal('FOO bar FOO', getline(1))
972*bfb2bb16SDominique Pelle
973*bfb2bb16SDominique Pelle  " Setting 'compatible' should reset 'gdefault'
974*bfb2bb16SDominique Pelle  call assert_equal(1, &gdefault)
975*bfb2bb16SDominique Pelle  set compatible
976*bfb2bb16SDominique Pelle  call assert_equal(0, &gdefault)
977*bfb2bb16SDominique Pelle  set nocompatible
978*bfb2bb16SDominique Pelle  call assert_equal(0, &gdefault)
979*bfb2bb16SDominique Pelle
980*bfb2bb16SDominique Pelle  bw!
981*bfb2bb16SDominique Pelleendfunc
982*bfb2bb16SDominique Pelle
9835d98dc2aSBram Moolenaar" vim: shiftwidth=2 sts=2 expandtab
984