blob: dfb367b5f1d8fad5f797220e0c203dfc5c7112fd [file] [log] [blame]
Bram Moolenaar22e42152016-04-03 14:02:02 +02001" Tests for regexp in latin1 encoding
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002
Bram Moolenaar22e42152016-04-03 14:02:02 +02003set encoding=latin1
4scriptencoding latin1
5
Bram Moolenaar5feabe02020-01-30 18:24:53 +01006source check.vim
7
Bram Moolenaar22e42152016-04-03 14:02:02 +02008func s:equivalence_test()
Dominique Pelle8bfa0eb2022-01-02 16:16:33 +00009 let str = 'AÀÁÂÃÄÅ B C D EÈÉÊË F G H IÌÍÎÏ J K L M NÑ OÒÓÔÕÖØ P Q R S T UÙÚÛÜ V W X YÝ Z '
10 \ .. 'aàáâãäå b c d eèéêë f g h iìíîï j k l m nñ oòóôõöø p q r s t uùúûü v w x yýÿ z '
11 \ .. "0 1 2 3 4 5 6 7 8 9 "
12 \ .. "` ~ ! ? ; : . , / \\ ' \" | < > [ ] { } ( ) @ # $ % ^ & * _ - + \b \e \f \n \r \t"
Bram Moolenaar22e42152016-04-03 14:02:02 +020013 let groups = split(str)
14 for group1 in groups
15 for c in split(group1, '\zs')
16 " next statement confirms that equivalence class matches every
17 " character in group
18 call assert_match('^[[=' . c . '=]]*$', group1)
19 for group2 in groups
20 if group2 != group1
21 " next statement converts that equivalence class doesn't match
22 " a character in any other group
23 call assert_equal(-1, match(group2, '[[=' . c . '=]]'))
24 endif
25 endfor
26 endfor
27 endfor
28endfunc
29
30func Test_equivalence_re1()
31 set re=1
32 call s:equivalence_test()
33endfunc
34
35func Test_equivalence_re2()
36 set re=2
37 call s:equivalence_test()
38endfunc
Bram Moolenaarf5a39442016-08-16 21:04:41 +020039
40func Test_recursive_substitute()
41 new
42 s/^/\=execute("s#^##gn")
43 " check we are now not in the sandbox
44 call setwinvar(1, 'myvar', 1)
45 bwipe!
46endfunc
Bram Moolenaard5638832016-09-09 17:59:50 +020047
48func Test_nested_backrefs()
49 " Check example in change.txt.
50 new
51 for re in range(0, 2)
52 exe 'set re=' . re
53 call setline(1, 'aa ab x')
54 1s/\(\(a[a-d] \)*\)\(x\)/-\1- -\2- -\3-/
55 call assert_equal('-aa ab - -ab - -x-', getline(1))
56
57 call assert_equal('-aa ab - -ab - -x-', substitute('aa ab x', '\(\(a[a-d] \)*\)\(x\)', '-\1- -\2- -\3-', ''))
58 endfor
59 bwipe!
60 set re=0
61endfunc
Bram Moolenaar16b35782016-09-09 20:29:50 +020062
63func Test_eow_with_optional()
64 let expected = ['abc def', 'abc', 'def', '', '', '', '', '', '', '']
65 for re in range(0, 2)
66 exe 'set re=' . re
67 let actual = matchlist('abc def', '\(abc\>\)\?\s*\(def\)')
68 call assert_equal(expected, actual)
69 endfor
70endfunc
Bram Moolenaar1ef9bbe2017-06-17 20:08:20 +020071
72func Test_backref()
73 new
74 call setline(1, ['one', 'two', 'three', 'four', 'five'])
75 call assert_equal(3, search('\%#=1\(e\)\1'))
76 call assert_equal(3, search('\%#=2\(e\)\1'))
77 call assert_fails('call search("\\%#=1\\(e\\1\\)")', 'E65:')
78 call assert_fails('call search("\\%#=2\\(e\\1\\)")', 'E65:')
79 bwipe!
80endfunc
Bram Moolenaar6057ed42019-01-14 23:19:29 +010081
82func Test_multi_failure()
83 set re=1
84 call assert_fails('/a**', 'E61:')
85 call assert_fails('/a*\+', 'E62:')
86 call assert_fails('/a\{a}', 'E554:')
87 set re=2
88 call assert_fails('/a**', 'E871:')
89 call assert_fails('/a*\+', 'E871:')
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +020090 call assert_fails('/a\{a}', 'E554:')
Bram Moolenaar6057ed42019-01-14 23:19:29 +010091 set re=0
92endfunc
Bram Moolenaar5567ad42019-02-12 23:05:46 +010093
Bram Moolenaar91ff3d42022-04-04 18:32:32 +010094func Test_column_failure()
95 set re=1
96 call assert_fails('/\%v', 'E71:')
97 call assert_fails('/\%c', 'E71:')
98 call assert_fails('/\%l', 'E71:')
99 set re=2
100 call assert_fails('/\%v', 'E1273:')
101 call assert_fails('/\%c', 'E1273:')
102 call assert_fails('/\%l', 'E1273:')
103 set re=0
104endfunc
105
Bram Moolenaar5567ad42019-02-12 23:05:46 +0100106func Test_recursive_addstate()
107 " This will call addstate() recursively until it runs into the limit.
108 let lnum = search('\v((){328}){389}')
109 call assert_equal(0, lnum)
110endfunc
Bram Moolenaar15bbd6e2019-02-13 20:31:50 +0100111
112func Test_out_of_memory()
113 new
114 s/^/,n
115 " This will be slow...
116 call assert_fails('call search("\\v((n||<)+);")', 'E363:')
117endfunc
Bram Moolenaar985079c2019-02-16 17:07:47 +0100118
119func Test_get_equi_class()
120 new
121 " Incomplete equivalence class caused invalid memory access
122 s/^/[[=
123 call assert_equal(1, search(getline(1)))
Bram Moolenaarf1b57ab2019-02-17 13:53:34 +0100124 s/.*/[[.
125 call assert_equal(1, search(getline(1)))
Bram Moolenaar985079c2019-02-16 17:07:47 +0100126endfunc
Bram Moolenaar8bfd9462019-02-16 18:07:57 +0100127
128func Test_rex_init()
129 set noincsearch
130 set re=1
131 new
132 setlocal iskeyword=a-z
133 call setline(1, ['abc', 'ABC'])
134 call assert_equal(1, search('[[:keyword:]]'))
135 new
136 setlocal iskeyword=A-Z
137 call setline(1, ['abc', 'ABC'])
138 call assert_equal(2, search('[[:keyword:]]'))
139 bwipe!
140 bwipe!
141 set re=0
142endfunc
Bram Moolenaara5483442019-02-17 20:17:02 +0100143
144func Test_range_with_newline()
145 new
146 call setline(1, "a")
147 call assert_equal(0, search("[ -*\\n- ]"))
148 call assert_equal(0, search("[ -*\\t-\\n]"))
149 bwipe!
150endfunc
Bram Moolenaar38f08e72019-02-20 22:04:32 +0100151
152func Test_pattern_compile_speed()
Bram Moolenaar5feabe02020-01-30 18:24:53 +0100153 CheckOption spellcapcheck
154 CheckFunction reltimefloat
155
Bram Moolenaar38f08e72019-02-20 22:04:32 +0100156 let start = reltime()
157 " this used to be very slow, not it should be about a second
158 set spc=\\v(((((Nxxxxxxx&&xxxx){179})+)+)+){179}
159 call assert_inrange(0.01, 10.0, reltimefloat(reltime(start)))
160 set spc=
161endfunc
Bram Moolenaarf9cb05c2019-12-15 13:39:22 +0100162
163" Tests for regexp patterns without multi-byte support.
164func Test_regexp_single_line_pat()
165 " tl is a List of Lists with:
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200166 " regexp engines to test
167 " 0 - test with 'regexpengine' values 0 and 1
168 " 1 - test with 'regexpengine' values 0 and 2
169 " 2 - test with 'regexpengine' values 0, 1 and 2
Bram Moolenaarf9cb05c2019-12-15 13:39:22 +0100170 " regexp pattern
171 " text to test the pattern on
172 " expected match (optional)
173 " expected submatch 1 (optional)
174 " expected submatch 2 (optional)
175 " etc.
176 " When there is no match use only the first two items.
177 let tl = []
178
179 call add(tl, [2, 'ab', 'aab', 'ab'])
180 call add(tl, [2, 'b', 'abcdef', 'b'])
181 call add(tl, [2, 'bc*', 'abccccdef', 'bcccc'])
182 call add(tl, [2, 'bc\{-}', 'abccccdef', 'b'])
183 call add(tl, [2, 'bc\{-}\(d\)', 'abccccdef', 'bccccd', 'd'])
184 call add(tl, [2, 'bc*', 'abbdef', 'b'])
185 call add(tl, [2, 'c*', 'ccc', 'ccc'])
186 call add(tl, [2, 'bc*', 'abdef', 'b'])
187 call add(tl, [2, 'c*', 'abdef', ''])
188 call add(tl, [2, 'bc\+', 'abccccdef', 'bcccc'])
189 call add(tl, [2, 'bc\+', 'abdef']) " no match
Bram Moolenaar004a6782020-04-11 17:09:31 +0200190 " match escape character in a string
191 call add(tl, [2, '.\e.', "one\<Esc>two", "e\<Esc>t"])
192 " match backspace character in a string
193 call add(tl, [2, '.\b.', "one\<C-H>two", "e\<C-H>t"])
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200194 " match newline character in a string
195 call add(tl, [2, 'o\nb', "foo\nbar", "o\nb"])
Bram Moolenaarf9cb05c2019-12-15 13:39:22 +0100196
197 " operator \|
198 call add(tl, [2, 'a\|ab', 'cabd', 'a']) " alternation is ordered
199
200 call add(tl, [2, 'c\?', 'ccb', 'c'])
201 call add(tl, [2, 'bc\?', 'abd', 'b'])
202 call add(tl, [2, 'bc\?', 'abccd', 'bc'])
203
204 call add(tl, [2, '\va{1}', 'ab', 'a'])
205
206 call add(tl, [2, '\va{2}', 'aa', 'aa'])
207 call add(tl, [2, '\va{2}', 'caad', 'aa'])
208 call add(tl, [2, '\va{2}', 'aba'])
209 call add(tl, [2, '\va{2}', 'ab'])
210 call add(tl, [2, '\va{2}', 'abaa', 'aa'])
211 call add(tl, [2, '\va{2}', 'aaa', 'aa'])
212
213 call add(tl, [2, '\vb{1}', 'abca', 'b'])
214 call add(tl, [2, '\vba{2}', 'abaa', 'baa'])
215 call add(tl, [2, '\vba{3}', 'aabaac'])
216
217 call add(tl, [2, '\v(ab){1}', 'ab', 'ab', 'ab'])
218 call add(tl, [2, '\v(ab){1}', 'dabc', 'ab', 'ab'])
219 call add(tl, [2, '\v(ab){1}', 'acb'])
220
221 call add(tl, [2, '\v(ab){0,2}', 'acb', "", ""])
222 call add(tl, [2, '\v(ab){0,2}', 'ab', 'ab', 'ab'])
223 call add(tl, [2, '\v(ab){1,2}', 'ab', 'ab', 'ab'])
224 call add(tl, [2, '\v(ab){1,2}', 'ababc', 'abab', 'ab'])
225 call add(tl, [2, '\v(ab){2,4}', 'ababcab', 'abab', 'ab'])
226 call add(tl, [2, '\v(ab){2,4}', 'abcababa', 'abab', 'ab'])
227
228 call add(tl, [2, '\v(ab){2}', 'abab', 'abab', 'ab'])
229 call add(tl, [2, '\v(ab){2}', 'cdababe', 'abab', 'ab'])
230 call add(tl, [2, '\v(ab){2}', 'abac'])
231 call add(tl, [2, '\v(ab){2}', 'abacabab', 'abab', 'ab'])
232 call add(tl, [2, '\v((ab){2}){2}', 'abababab', 'abababab', 'abab', 'ab'])
233 call add(tl, [2, '\v((ab){2}){2}', 'abacabababab', 'abababab', 'abab', 'ab'])
234
235 call add(tl, [2, '\v(a{1}){1}', 'a', 'a', 'a'])
236 call add(tl, [2, '\v(a{2}){1}', 'aa', 'aa', 'aa'])
237 call add(tl, [2, '\v(a{2}){1}', 'aaac', 'aa', 'aa'])
238 call add(tl, [2, '\v(a{2}){1}', 'daaac', 'aa', 'aa'])
239 call add(tl, [2, '\v(a{1}){2}', 'daaac', 'aa', 'a'])
240 call add(tl, [2, '\v(a{1}){2}', 'aaa', 'aa', 'a'])
241 call add(tl, [2, '\v(a{2})+', 'adaac', 'aa', 'aa'])
242 call add(tl, [2, '\v(a{2})+', 'aa', 'aa', 'aa'])
243 call add(tl, [2, '\v(a{2}){1}', 'aa', 'aa', 'aa'])
244 call add(tl, [2, '\v(a{1}){2}', 'aa', 'aa', 'a'])
245 call add(tl, [2, '\v(a{1}){1}', 'a', 'a', 'a'])
246 call add(tl, [2, '\v(a{2}){2}', 'aaaa', 'aaaa', 'aa'])
247 call add(tl, [2, '\v(a{2}){2}', 'aaabaaaa', 'aaaa', 'aa'])
248
249 call add(tl, [2, '\v(a+){2}', 'dadaac', 'aa', 'a'])
250 call add(tl, [2, '\v(a{3}){2}', 'aaaaaaa', 'aaaaaa', 'aaa'])
251
252 call add(tl, [2, '\v(a{1,2}){2}', 'daaac', 'aaa', 'a'])
253 call add(tl, [2, '\v(a{1,3}){2}', 'daaaac', 'aaaa', 'a'])
254 call add(tl, [2, '\v(a{1,3}){2}', 'daaaaac', 'aaaaa', 'aa'])
255 call add(tl, [2, '\v(a{1,3}){3}', 'daac'])
256 call add(tl, [2, '\v(a{1,2}){2}', 'dac'])
257 call add(tl, [2, '\v(a+)+', 'daac', 'aa', 'aa'])
258 call add(tl, [2, '\v(a+)+', 'aaa', 'aaa', 'aaa'])
259 call add(tl, [2, '\v(a+){1,2}', 'aaa', 'aaa', 'aaa'])
260 call add(tl, [2, '\v(a+)(a+)', 'aaa', 'aaa', 'aa', 'a'])
261 call add(tl, [2, '\v(a{3})+', 'daaaac', 'aaa', 'aaa'])
262 call add(tl, [2, '\v(a|b|c)+', 'aacb', 'aacb', 'b'])
263 call add(tl, [2, '\v(a|b|c){2}', 'abcb', 'ab', 'b'])
264 call add(tl, [2, '\v(abc){2}', 'abcabd', ])
265 call add(tl, [2, '\v(abc){2}', 'abdabcabc','abcabc', 'abc'])
266
267 call add(tl, [2, 'a*', 'cc', ''])
268 call add(tl, [2, '\v(a*)+', 'cc', ''])
269 call add(tl, [2, '\v((ab)+)+', 'ab', 'ab', 'ab', 'ab'])
270 call add(tl, [2, '\v(((ab)+)+)+', 'ab', 'ab', 'ab', 'ab', 'ab'])
271 call add(tl, [2, '\v(((ab)+)+)+', 'dababc', 'abab', 'abab', 'abab', 'ab'])
272 call add(tl, [2, '\v(a{0,2})+', 'cc', ''])
273 call add(tl, [2, '\v(a*)+', '', ''])
274 call add(tl, [2, '\v((a*)+)+', '', ''])
275 call add(tl, [2, '\v((ab)*)+', '', ''])
276 call add(tl, [2, '\va{1,3}', 'aab', 'aa'])
277 call add(tl, [2, '\va{2,3}', 'abaa', 'aa'])
278
279 call add(tl, [2, '\v((ab)+|c*)+', 'abcccaba', 'abcccab', '', 'ab'])
280 call add(tl, [2, '\v(a{2})|(b{3})', 'bbabbbb', 'bbb', '', 'bbb'])
281 call add(tl, [2, '\va{2}|b{2}', 'abab'])
282 call add(tl, [2, '\v(a)+|(c)+', 'bbacbaacbbb', 'a', 'a'])
283 call add(tl, [2, '\vab{2,3}c', 'aabbccccccccccccc', 'abbc'])
284 call add(tl, [2, '\vab{2,3}c', 'aabbbccccccccccccc', 'abbbc'])
285 call add(tl, [2, '\vab{2,3}cd{2,3}e', 'aabbbcddee', 'abbbcdde'])
286 call add(tl, [2, '\va(bc){2}d', 'aabcbfbc' ])
287 call add(tl, [2, '\va*a{2}', 'a', ])
288 call add(tl, [2, '\va*a{2}', 'aa', 'aa' ])
289 call add(tl, [2, '\va*a{2}', 'aaa', 'aaa' ])
290 call add(tl, [2, '\va*a{2}', 'bbbabcc', ])
291 call add(tl, [2, '\va*b*|a*c*', 'a', 'a'])
292 call add(tl, [2, '\va{1}b{1}|a{1}b{1}', ''])
293
294 " submatches
295 call add(tl, [2, '\v(a)', 'ab', 'a', 'a'])
296 call add(tl, [2, '\v(a)(b)', 'ab', 'ab', 'a', 'b'])
297 call add(tl, [2, '\v(ab)(b)(c)', 'abbc', 'abbc', 'ab', 'b', 'c'])
298 call add(tl, [2, '\v((a)(b))', 'ab', 'ab', 'ab', 'a', 'b'])
299 call add(tl, [2, '\v(a)|(b)', 'ab', 'a', 'a'])
300
301 call add(tl, [2, '\v(a*)+', 'aaaa', 'aaaa', ''])
302 call add(tl, [2, 'x', 'abcdef'])
303
304 "
305 " Simple tests
306 "
307
308 " Search single groups
309 call add(tl, [2, 'ab', 'aab', 'ab'])
310 call add(tl, [2, 'ab', 'baced'])
311 call add(tl, [2, 'ab', ' ab ', 'ab'])
312
313 " Search multi-modifiers
314 call add(tl, [2, 'x*', 'xcd', 'x'])
315 call add(tl, [2, 'x*', 'xxxxxxxxxxxxxxxxsofijiojgf', 'xxxxxxxxxxxxxxxx'])
316 " empty match is good
317 call add(tl, [2, 'x*', 'abcdoij', ''])
318 " no match here
319 call add(tl, [2, 'x\+', 'abcdoin'])
320 call add(tl, [2, 'x\+', 'abcdeoijdfxxiuhfij', 'xx'])
321 call add(tl, [2, 'x\+', 'xxxxx', 'xxxxx'])
322 call add(tl, [2, 'x\+', 'abc x siufhiush xxxxxxxxx', 'x'])
323 call add(tl, [2, 'x\=', 'x sdfoij', 'x'])
324 call add(tl, [2, 'x\=', 'abc sfoij', '']) " empty match is good
325 call add(tl, [2, 'x\=', 'xxxxxxxxx c', 'x'])
326 call add(tl, [2, 'x\?', 'x sdfoij', 'x'])
327 " empty match is good
328 call add(tl, [2, 'x\?', 'abc sfoij', ''])
329 call add(tl, [2, 'x\?', 'xxxxxxxxxx c', 'x'])
330
331 call add(tl, [2, 'a\{0,0}', 'abcdfdoij', ''])
332 " same thing as 'a?'
333 call add(tl, [2, 'a\{0,1}', 'asiubid axxxaaa', 'a'])
334 " same thing as 'a\{0,1}'
335 call add(tl, [2, 'a\{1,0}', 'asiubid axxxaaa', 'a'])
336 call add(tl, [2, 'a\{3,6}', 'aa siofuh'])
337 call add(tl, [2, 'a\{3,6}', 'aaaaa asfoij afaa', 'aaaaa'])
338 call add(tl, [2, 'a\{3,6}', 'aaaaaaaa', 'aaaaaa'])
339 call add(tl, [2, 'a\{0}', 'asoiuj', ''])
340 call add(tl, [2, 'a\{2}', 'aaaa', 'aa'])
341 call add(tl, [2, 'a\{2}', 'iuash fiusahfliusah fiushfilushfi uhsaifuh askfj nasfvius afg aaaa sfiuhuhiushf', 'aa'])
342 call add(tl, [2, 'a\{2}', 'abcdefghijklmnopqrestuvwxyz1234567890'])
343 " same thing as 'a*'
344 call add(tl, [2, 'a\{0,}', 'oij sdigfusnf', ''])
345 call add(tl, [2, 'a\{0,}', 'aaaaa aa', 'aaaaa'])
346 call add(tl, [2, 'a\{2,}', 'sdfiougjdsafg'])
347 call add(tl, [2, 'a\{2,}', 'aaaaasfoij ', 'aaaaa'])
348 call add(tl, [2, 'a\{5,}', 'xxaaaaxxx '])
349 call add(tl, [2, 'a\{5,}', 'xxaaaaaxxx ', 'aaaaa'])
350 call add(tl, [2, 'a\{,0}', 'oidfguih iuhi hiu aaaa', ''])
351 call add(tl, [2, 'a\{,5}', 'abcd', 'a'])
352 call add(tl, [2, 'a\{,5}', 'aaaaaaaaaa', 'aaaaa'])
353 " leading star as normal char when \{} follows
354 call add(tl, [2, '^*\{4,}$', '***'])
355 call add(tl, [2, '^*\{4,}$', '****', '****'])
356 call add(tl, [2, '^*\{4,}$', '*****', '*****'])
357 " same thing as 'a*'
358 call add(tl, [2, 'a\{}', 'bbbcddiuhfcd', ''])
359 call add(tl, [2, 'a\{}', 'aaaaioudfh coisf jda', 'aaaa'])
360
361 call add(tl, [2, 'a\{-0,0}', 'abcdfdoij', ''])
362 " anti-greedy version of 'a?'
363 call add(tl, [2, 'a\{-0,1}', 'asiubid axxxaaa', ''])
364 call add(tl, [2, 'a\{-3,6}', 'aa siofuh'])
365 call add(tl, [2, 'a\{-3,6}', 'aaaaa asfoij afaa', 'aaa'])
366 call add(tl, [2, 'a\{-3,6}', 'aaaaaaaa', 'aaa'])
367 call add(tl, [2, 'a\{-0}', 'asoiuj', ''])
368 call add(tl, [2, 'a\{-2}', 'aaaa', 'aa'])
369 call add(tl, [2, 'a\{-2}', 'abcdefghijklmnopqrestuvwxyz1234567890'])
370 call add(tl, [2, 'a\{-0,}', 'oij sdigfusnf', ''])
371 call add(tl, [2, 'a\{-0,}', 'aaaaa aa', ''])
372 call add(tl, [2, 'a\{-2,}', 'sdfiougjdsafg'])
373 call add(tl, [2, 'a\{-2,}', 'aaaaasfoij ', 'aa'])
374 call add(tl, [2, 'a\{-,0}', 'oidfguih iuhi hiu aaaa', ''])
375 call add(tl, [2, 'a\{-,5}', 'abcd', ''])
376 call add(tl, [2, 'a\{-,5}', 'aaaaaaaaaa', ''])
377 " anti-greedy version of 'a*'
378 call add(tl, [2, 'a\{-}', 'bbbcddiuhfcd', ''])
379 call add(tl, [2, 'a\{-}', 'aaaaioudfh coisf jda', ''])
380
381 " Test groups of characters and submatches
382 call add(tl, [2, '\(abc\)*', 'abcabcabc', 'abcabcabc', 'abc'])
383 call add(tl, [2, '\(ab\)\+', 'abababaaaaa', 'ababab', 'ab'])
384 call add(tl, [2, '\(abaaaaa\)*cd', 'cd', 'cd', ''])
385 call add(tl, [2, '\(test1\)\? \(test2\)\?', 'test1 test3', 'test1 ', 'test1', ''])
386 call add(tl, [2, '\(test1\)\= \(test2\) \(test4443\)\=', ' test2 test4443 yupiiiiiiiiiii', ' test2 test4443', '', 'test2', 'test4443'])
387 call add(tl, [2, '\(\(sub1\) hello \(sub 2\)\)', 'asterix sub1 hello sub 2 obelix', 'sub1 hello sub 2', 'sub1 hello sub 2', 'sub1', 'sub 2'])
388 call add(tl, [2, '\(\(\(yyxxzz\)\)\)', 'abcdddsfiusfyyzzxxyyxxzz', 'yyxxzz', 'yyxxzz', 'yyxxzz', 'yyxxzz'])
389 call add(tl, [2, '\v((ab)+|c+)+', 'abcccaba', 'abcccab', 'ab', 'ab'])
390 call add(tl, [2, '\v((ab)|c*)+', 'abcccaba', 'abcccab', '', 'ab'])
391 call add(tl, [2, '\v(a(c*)+b)+', 'acbababaaa', 'acbabab', 'ab', ''])
392 call add(tl, [2, '\v(a|b*)+', 'aaaa', 'aaaa', ''])
393 call add(tl, [2, '\p*', 'aá ', 'aá '])
394
395 " Test greedy-ness and lazy-ness
396 call add(tl, [2, 'a\{-2,7}','aaaaaaaaaaaaa', 'aa'])
397 call add(tl, [2, 'a\{-2,7}x','aaaaaaaaax', 'aaaaaaax'])
398 call add(tl, [2, 'a\{2,7}','aaaaaaaaaaaaaaaaaaaa', 'aaaaaaa'])
399 call add(tl, [2, 'a\{2,7}x','aaaaaaaaax', 'aaaaaaax'])
400 call add(tl, [2, '\vx(.{-,8})yz(.*)','xayxayzxayzxayz','xayxayzxayzxayz','ayxa','xayzxayz'])
401 call add(tl, [2, '\vx(.*)yz(.*)','xayxayzxayzxayz','xayxayzxayzxayz', 'ayxayzxayzxa',''])
402 call add(tl, [2, '\v(a{1,2}){-2,3}','aaaaaaa','aaaa','aa'])
403 call add(tl, [2, '\v(a{-1,3})+', 'aa', 'aa', 'a'])
404 call add(tl, [2, '^\s\{-}\zs\( x\|x$\)', ' x', ' x', ' x'])
405 call add(tl, [2, '^\s\{-}\zs\(x\| x$\)', ' x', ' x', ' x'])
406 call add(tl, [2, '^\s\{-}\ze\(x\| x$\)', ' x', '', ' x'])
407 call add(tl, [2, '^\(\s\{-}\)\(x\| x$\)', ' x', ' x', '', ' x'])
408
409 " Test Character classes
410 call add(tl, [2, '\d\+e\d\d','test 10e23 fd','10e23'])
411
412 " Test collections and character range []
413 call add(tl, [2, '\v[a]', 'abcd', 'a'])
414 call add(tl, [2, 'a[bcd]', 'abcd', 'ab'])
415 call add(tl, [2, 'a[b-d]', 'acbd', 'ac'])
416 call add(tl, [2, '[a-d][e-f][x-x]d', 'cexdxx', 'cexd'])
417 call add(tl, [2, '\v[[:alpha:]]+', 'abcdefghijklmnopqrstuvwxyz6','abcdefghijklmnopqrstuvwxyz'])
418 call add(tl, [2, '[[:alpha:]\+]', '6x8','x'])
419 call add(tl, [2, '[^abc]\+','abcabcabc'])
420 call add(tl, [2, '[^abc]','defghiasijvoinasoiunbvb','d'])
421 call add(tl, [2, '[^abc]\+','ddddddda','ddddddd'])
422 call add(tl, [2, '[^a-d]\+','aaaAAAZIHFNCddd','AAAZIHFNC'])
423 call add(tl, [2, '[a-f]*','iiiiiiii',''])
424 call add(tl, [2, '[a-f]*','abcdefgh','abcdef'])
425 call add(tl, [2, '[^a-f]\+','abcdefgh','gh'])
426 call add(tl, [2, '[a-c]\{-3,6}','abcabc','abc'])
427 call add(tl, [2, '[^[:alpha:]]\+','abcccadfoij7787ysf287yrnccdu','7787'])
428 call add(tl, [2, '[-a]', '-', '-'])
429 call add(tl, [2, '[a-]', '-', '-'])
430 call add(tl, [2, '[a-f]*\c','ABCDEFGH','ABCDEF'])
431 call add(tl, [2, '[abc][xyz]\c','-af-AF-BY--','BY'])
432 " filename regexp
433 call add(tl, [2, '[-./[:alnum:]_~]\+', 'log13.file', 'log13.file'])
434 " special chars
435 call add(tl, [2, '[\]\^\-\\]\+', '\^\\\-\---^', '\^\\\-\---^'])
436 " collation elem
437 call add(tl, [2, '[[.a.]]\+', 'aa', 'aa'])
438 " middle of regexp
439 call add(tl, [2, 'abc[0-9]*ddd', 'siuhabc ii'])
440 call add(tl, [2, 'abc[0-9]*ddd', 'adf abc44482ddd oijs', 'abc44482ddd'])
441 call add(tl, [2, '\_[0-9]\+', 'asfi9888u', '9888'])
442 call add(tl, [2, '[0-9\n]\+', 'asfi9888u', '9888'])
443 call add(tl, [2, '\_[0-9]\+', "asfi\n9888u", "\n9888"])
444 call add(tl, [2, '\_f', " \na ", "\n"])
445 call add(tl, [2, '\_f\+', " \na ", "\na"])
446 call add(tl, [2, '[0-9A-Za-z-_.]\+', " @0_a.A-{ ", "0_a.A-"])
447
448 " Test start/end of line, start/end of file
449 call add(tl, [2, '^a.', "a_\nb ", "a_"])
450 call add(tl, [2, '^a.', "b a \na_"])
451 call add(tl, [2, '.a$', " a\n "])
452 call add(tl, [2, '.a$', " a b\n_a", "_a"])
453 call add(tl, [2, '\%^a.', "a a\na", "a "])
454 call add(tl, [2, '\%^a', " a \na "])
455 call add(tl, [2, '.a\%$', " a\n "])
456 call add(tl, [2, '.a\%$', " a\n_a", "_a"])
457
458 " Test recognition of character classes
459 call add(tl, [2, '[0-7]\+', 'x0123456789x', '01234567'])
460 call add(tl, [2, '[^0-7]\+', '0a;X+% 897', 'a;X+% 89'])
461 call add(tl, [2, '[0-9]\+', 'x0123456789x', '0123456789'])
462 call add(tl, [2, '[^0-9]\+', '0a;X+% 9', 'a;X+% '])
463 call add(tl, [2, '[0-9a-fA-F]\+', 'x0189abcdefg', '0189abcdef'])
464 call add(tl, [2, '[^0-9A-Fa-f]\+', '0189g;X+% ab', 'g;X+% '])
465 call add(tl, [2, '[a-z_A-Z0-9]\+', ';+aso_SfOij ', 'aso_SfOij'])
466 call add(tl, [2, '[^a-z_A-Z0-9]\+', 'aSo_;+% sfOij', ';+% '])
467 call add(tl, [2, '[a-z_A-Z]\+', '0abyz_ABYZ;', 'abyz_ABYZ'])
468 call add(tl, [2, '[^a-z_A-Z]\+', 'abAB_09;+% yzYZ', '09;+% '])
469 call add(tl, [2, '[a-z]\+', '0abcxyz1', 'abcxyz'])
470 call add(tl, [2, '[a-z]\+', 'AabxyzZ', 'abxyz'])
471 call add(tl, [2, '[^a-z]\+', 'a;X09+% x', ';X09+% '])
472 call add(tl, [2, '[^a-z]\+', 'abX0;%yz', 'X0;%'])
473 call add(tl, [2, '[a-zA-Z]\+', '0abABxzXZ9', 'abABxzXZ'])
474 call add(tl, [2, '[^a-zA-Z]\+', 'ab09_;+ XZ', '09_;+ '])
475 call add(tl, [2, '[A-Z]\+', 'aABXYZz', 'ABXYZ'])
476 call add(tl, [2, '[^A-Z]\+', 'ABx0;%YZ', 'x0;%'])
477 call add(tl, [2, '[a-z]\+\c', '0abxyzABXYZ;', 'abxyzABXYZ'])
478 call add(tl, [2, '[A-Z]\+\c', '0abABxzXZ9', 'abABxzXZ'])
479 call add(tl, [2, '\c[^a-z]\+', 'ab09_;+ XZ', '09_;+ '])
480 call add(tl, [2, '\c[^A-Z]\+', 'ab09_;+ XZ', '09_;+ '])
481 call add(tl, [2, '\C[^A-Z]\+', 'ABCOIJDEOIFNSD jsfoij sa', ' jsfoij sa'])
482
483 " Tests for \z features
484 " match ends at \ze
485 call add(tl, [2, 'xx \ze test', 'xx '])
486 call add(tl, [2, 'abc\zeend', 'oij abcend', 'abc'])
487 call add(tl, [2, 'aa\zebb\|aaxx', ' aabb ', 'aa'])
488 call add(tl, [2, 'aa\zebb\|aaxx', ' aaxx ', 'aaxx'])
489 call add(tl, [2, 'aabb\|aa\zebb', ' aabb ', 'aabb'])
490 call add(tl, [2, 'aa\zebb\|aaebb', ' aabb ', 'aa'])
491 " match starts at \zs
492 call add(tl, [2, 'abc\zsdd', 'ddabcddxyzt', 'dd'])
493 call add(tl, [2, 'aa \zsax', ' ax'])
494 call add(tl, [2, 'abc \zsmatch\ze abc', 'abc abc abc match abc abc', 'match'])
495 call add(tl, [2, '\v(a \zsif .*){2}', 'a if then a if last', 'if last', 'a if last'])
496 call add(tl, [2, '\>\zs.', 'aword. ', '.'])
497 call add(tl, [2, '\s\+\ze\[/\|\s\zs\s\+', 'is [a t', ' '])
498
499 " Tests for \@= and \& features
500 call add(tl, [2, 'abc\@=', 'abc', 'ab'])
501 call add(tl, [2, 'abc\@=cd', 'abcd', 'abcd'])
502 call add(tl, [2, 'abc\@=', 'ababc', 'ab'])
503 " will never match, no matter the input text
504 call add(tl, [2, 'abcd\@=e', 'abcd'])
505 " will never match
506 call add(tl, [2, 'abcd\@=e', 'any text in here ... '])
507 call add(tl, [2, '\v(abc)@=..', 'xabcd', 'ab', 'abc'])
508 call add(tl, [2, '\(.*John\)\@=.*Bob', 'here is John, and here is B'])
509 call add(tl, [2, '\(John.*\)\@=.*Bob', 'John is Bobs friend', 'John is Bob', 'John is Bobs friend'])
510 call add(tl, [2, '\<\S\+\())\)\@=', '$((i=i+1))', 'i=i+1', '))'])
511 call add(tl, [2, '.*John\&.*Bob', 'here is John, and here is B'])
512 call add(tl, [2, '.*John\&.*Bob', 'John is Bobs friend', 'John is Bob'])
513 call add(tl, [2, '\v(test1)@=.*yep', 'this is a test1, yep it is', 'test1, yep', 'test1'])
514 call add(tl, [2, 'foo\(bar\)\@!', 'foobar'])
515 call add(tl, [2, 'foo\(bar\)\@!', 'foo bar', 'foo'])
516 call add(tl, [2, 'if \(\(then\)\@!.\)*$', ' if then else'])
517 call add(tl, [2, 'if \(\(then\)\@!.\)*$', ' if else ', 'if else ', ' '])
518 call add(tl, [2, '\(foo\)\@!bar', 'foobar', 'bar'])
519 call add(tl, [2, '\(foo\)\@!...bar', 'foobar'])
520 call add(tl, [2, '^\%(.*bar\)\@!.*\zsfoo', ' bar foo '])
521 call add(tl, [2, '^\%(.*bar\)\@!.*\zsfoo', ' foo bar '])
522 call add(tl, [2, '^\%(.*bar\)\@!.*\zsfoo', ' foo xxx ', 'foo'])
523 call add(tl, [2, '[ ]\@!\p\%([ ]\@!\p\)*:', 'implicit mappings:', 'mappings:'])
524 call add(tl, [2, '[ ]\@!\p\([ ]\@!\p\)*:', 'implicit mappings:', 'mappings:', 's'])
525 call add(tl, [2, 'm\k\+_\@=\%(_\@!\k\)\@<=\k\+e', 'mx__xe', 'mx__xe'])
526 call add(tl, [2, '\%(\U\@<=S\k*\|S\l\)R', 'SuR', 'SuR'])
527
528 " Combining different tests and features
529 call add(tl, [2, '[[:alpha:]]\{-2,6}', '787abcdiuhsasiuhb4', 'ab'])
530 call add(tl, [2, '', 'abcd', ''])
531 call add(tl, [2, '\v(())', 'any possible text', ''])
532 call add(tl, [2, '\v%(ab(xyz)c)', ' abxyzc ', 'abxyzc', 'xyz'])
533 call add(tl, [2, '\v(test|)empty', 'tesempty', 'empty', ''])
534 call add(tl, [2, '\v(a|aa)(a|aa)', 'aaa', 'aa', 'a', 'a'])
535
536 " \%u and friends
537 call add(tl, [2, '\%d32', 'yes no', ' '])
538 call add(tl, [2, '\%o40', 'yes no', ' '])
539 call add(tl, [2, '\%x20', 'yes no', ' '])
540 call add(tl, [2, '\%u0020', 'yes no', ' '])
541 call add(tl, [2, '\%U00000020', 'yes no', ' '])
542 call add(tl, [2, '\%d0', "yes\x0ano", "\x0a"])
543
544 "" \%[abc]
545 call add(tl, [2, 'foo\%[bar]', 'fobar'])
546 call add(tl, [2, 'foo\%[bar]', 'foobar', 'foobar'])
547 call add(tl, [2, 'foo\%[bar]', 'fooxx', 'foo'])
548 call add(tl, [2, 'foo\%[bar]', 'foobxx', 'foob'])
549 call add(tl, [2, 'foo\%[bar]', 'foobaxx', 'fooba'])
550 call add(tl, [2, 'foo\%[bar]', 'foobarxx', 'foobar'])
551 call add(tl, [2, 'foo\%[bar]x', 'foobxx', 'foobx'])
552 call add(tl, [2, 'foo\%[bar]x', 'foobarxx', 'foobarx'])
553 call add(tl, [2, '\%[bar]x', 'barxx', 'barx'])
554 call add(tl, [2, '\%[bar]x', 'bxx', 'bx'])
555 call add(tl, [2, '\%[bar]x', 'xxx', 'x'])
556 call add(tl, [2, 'b\%[[ao]r]', 'bar bor', 'bar'])
557 call add(tl, [2, 'b\%[[]]r]', 'b]r bor', 'b]r'])
558 call add(tl, [2, '@\%[\w\-]*', '<http://john.net/pandoc/>[@pandoc]', '@pandoc'])
559
560 " Alternatives, must use first longest match
561 call add(tl, [2, 'goo\|go', 'google', 'goo'])
562 call add(tl, [2, '\<goo\|\<go', 'google', 'goo'])
563 call add(tl, [2, '\<goo\|go', 'google', 'goo'])
564
565 " Back references
566 call add(tl, [2, '\(\i\+\) \1', ' abc abc', 'abc abc', 'abc'])
567 call add(tl, [2, '\(\i\+\) \1', 'xgoo goox', 'goo goo', 'goo'])
568 call add(tl, [2, '\(a\)\(b\)\(c\)\(dd\)\(e\)\(f\)\(g\)\(h\)\(i\)\1\2\3\4\5\6\7\8\9', 'xabcddefghiabcddefghix', 'abcddefghiabcddefghi', 'a', 'b', 'c', 'dd', 'e', 'f', 'g', 'h', 'i'])
569 call add(tl, [2, '\(\d*\)a \1b', ' a b ', 'a b', ''])
570 call add(tl, [2, '^.\(.\).\_..\1.', "aaa\naaa\nb", "aaa\naaa", 'a'])
571 call add(tl, [2, '^.*\.\(.*\)/.\+\(\1\)\@<!$', 'foo.bat/foo.com', 'foo.bat/foo.com', 'bat'])
572 call add(tl, [2, '^.*\.\(.*\)/.\+\(\1\)\@<!$', 'foo.bat/foo.bat'])
573 call add(tl, [2, '^.*\.\(.*\)/.\+\(\1\)\@<=$', 'foo.bat/foo.bat', 'foo.bat/foo.bat', 'bat', 'bat'])
574 call add(tl, [2, '\\\@<!\${\(\d\+\%(:.\{-}\)\?\\\@<!\)}', '2013-06-27${0}', '${0}', '0'])
575 call add(tl, [2, '^\(a*\)\1$', 'aaaaaaaa', 'aaaaaaaa', 'aaaa'])
576 call add(tl, [2, '^\(a\{-2,}\)\1\+$', 'aaaaaaaaa', 'aaaaaaaaa', 'aaa'])
577
578 " Look-behind with limit
579 call add(tl, [2, '<\@<=span.', 'xxspanxx<spanyyy', 'spany'])
580 call add(tl, [2, '<\@1<=span.', 'xxspanxx<spanyyy', 'spany'])
581 call add(tl, [2, '<\@2<=span.', 'xxspanxx<spanyyy', 'spany'])
582 call add(tl, [2, '\(<<\)\@<=span.', 'xxspanxxxx<spanxx<<spanyyy', 'spany', '<<'])
583 call add(tl, [2, '\(<<\)\@1<=span.', 'xxspanxxxx<spanxx<<spanyyy'])
584 call add(tl, [2, '\(<<\)\@2<=span.', 'xxspanxxxx<spanxx<<spanyyy', 'spany', '<<'])
585 call add(tl, [2, '\(foo\)\@<!bar.', 'xx foobar1 xbar2 xx', 'bar2'])
586
587 " look-behind match in front of a zero-width item
588 call add(tl, [2, '\v\C%(<Last Changed:\s+)@<=.*$', '" test header'])
589 call add(tl, [2, '\v\C%(<Last Changed:\s+)@<=.*$', '" Last Changed: 1970', '1970'])
590 call add(tl, [2, '\(foo\)\@<=\>', 'foobar'])
591 call add(tl, [2, '\(foo\)\@<=\>', 'barfoo', '', 'foo'])
592 call add(tl, [2, '\(foo\)\@<=.*', 'foobar', 'bar', 'foo'])
593
594 " complicated look-behind match
595 call add(tl, [2, '\(r\@<=\|\w\@<!\)\/', 'x = /word/;', '/'])
596 call add(tl, [2, '^[a-z]\+\ze \&\(asdf\)\@<!', 'foo bar', 'foo'])
597
598 "" \@>
599 call add(tl, [2, '\(a*\)\@>a', 'aaaa'])
600 call add(tl, [2, '\(a*\)\@>b', 'aaab', 'aaab', 'aaa'])
601 call add(tl, [2, '^\(.\{-}b\)\@>.', ' abcbd', ' abc', ' ab'])
602 call add(tl, [2, '\(.\{-}\)\(\)\@>$', 'abc', 'abc', 'abc', ''])
603 " TODO: BT engine does not restore submatch after failure
604 call add(tl, [1, '\(a*\)\@>a\|a\+', 'aaaa', 'aaaa'])
605
606 " "\_" prepended negated collection matches EOL
607 call add(tl, [2, '\_[^8-9]\+', "asfi\n9888", "asfi\n"])
608 call add(tl, [2, '\_[^a]\+', "asfi\n9888", "sfi\n9888"])
609
610 " Requiring lots of states.
611 call add(tl, [2, '[0-9a-zA-Z]\{8}-\([0-9a-zA-Z]\{4}-\)\{3}[0-9a-zA-Z]\{12}', " 12345678-1234-1234-1234-123456789012 ", "12345678-1234-1234-1234-123456789012", "1234-"])
612
613 " Skip adding state twice
614 call add(tl, [2, '^\%(\%(^\s*#\s*if\>\|#\s*if\)\)\(\%>1c.*$\)\@=', "#if FOO", "#if", ' FOO'])
615
616 " Test \%V atom
617 call add(tl, [2, '\%>70vGesamt', 'Jean-Michel Charlier & Victor Hubinon\Gesamtausgabe [Salleck] Buck Danny {Jean-Michel Charlier & Victor Hubinon}\Gesamtausgabe', 'Gesamt'])
618
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200619 " Test for ignoring case and matching repeated characters
620 call add(tl, [2, '\cb\+', 'aAbBbBcC', 'bBbB'])
621
Bram Moolenaarf9cb05c2019-12-15 13:39:22 +0100622 " Run the tests
623 for t in tl
624 let re = t[0]
625 let pat = t[1]
626 let text = t[2]
627 let matchidx = 3
628 for engine in [0, 1, 2]
629 if engine == 2 && re == 0 || engine == 1 && re == 1
630 continue
631 endif
632 let &regexpengine = engine
633 try
634 let l = matchlist(text, pat)
635 catch
636 call assert_report('Error ' . engine . ': pat: \"' . pat
637 \ . '\", text: \"' . text . '\", caused an exception: \"'
638 \ . v:exception . '\"')
639 endtry
640 " check the match itself
641 if len(l) == 0 && len(t) > matchidx
642 call assert_report('Error ' . engine . ': pat: \"' . pat
643 \ . '\", text: \"' . text . '\", did not match, expected: \"'
644 \ . t[matchidx] . '\"')
645 elseif len(l) > 0 && len(t) == matchidx
646 call assert_report('Error ' . engine . ': pat: \"' . pat
647 \ . '\", text: \"' . text . '\", match: \"' . l[0]
648 \ . '\", expected no match')
649 elseif len(t) > matchidx && l[0] != t[matchidx]
650 call assert_report('Error ' . engine . ': pat: \"' . pat
651 \ . '\", text: \"' . text . '\", match: \"' . l[0]
652 \ . '\", expected: \"' . t[matchidx] . '\"')
653 else
654 " Test passed
655 endif
656
657 " check all the nine submatches
658 if len(l) > 0
659 for i in range(1, 9)
660 if len(t) <= matchidx + i
661 let e = ''
662 else
663 let e = t[matchidx + i]
664 endif
665 if l[i] != e
666 call assert_report('Error ' . engine . ': pat: \"' . pat
667 \ . '\", text: \"' . text . '\", submatch ' . i . ': \"'
668 \ . l[i] . '\", expected: \"' . e . '\"')
669 endif
670 endfor
671 unlet i
672 endif
673 endfor
674 endfor
675
676 unlet t tl e l
677endfunc
678
679" Tests for multi-line regexp patterns without multi-byte support.
680func Test_regexp_multiline_pat()
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200681 " tl is a List of Lists with:
682 " regexp engines to test
683 " 0 - test with 'regexpengine' values 0 and 1
684 " 1 - test with 'regexpengine' values 0 and 2
685 " 2 - test with 'regexpengine' values 0, 1 and 2
686 " regexp pattern
687 " List with text to test the pattern on
688 " List with the expected match
Bram Moolenaarf9cb05c2019-12-15 13:39:22 +0100689 let tl = []
690
691 " back references
692 call add(tl, [2, '^.\(.\).\_..\1.', ['aaa', 'aaa', 'b'], ['XX', 'b']])
693 call add(tl, [2, '\v.*\/(.*)\n.*\/\1$', ['./Dir1/Dir2/zyxwvuts.txt', './Dir1/Dir2/abcdefgh.bat', '', './Dir1/Dir2/file1.txt', './OtherDir1/OtherDir2/file1.txt'], ['./Dir1/Dir2/zyxwvuts.txt', './Dir1/Dir2/abcdefgh.bat', '', 'XX']])
694
695 " line breaks
696 call add(tl, [2, '\S.*\nx', ['abc', 'def', 'ghi', 'xjk', 'lmn'], ['abc', 'def', 'XXjk', 'lmn']])
697
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200698 " Any single character or end-of-line
699 call add(tl, [2, '\_.\+', ['a', 'b', 'c'], ['XX']])
700 " Any identifier or end-of-line
701 call add(tl, [2, '\_i\+', ['a', 'b', ';', '2'], ['XX;XX']])
702 " Any identifier but excluding digits or end-of-line
703 call add(tl, [2, '\_I\+', ['a', 'b', ';', '2'], ['XX;XX2XX']])
704 " Any keyword or end-of-line
705 call add(tl, [2, '\_k\+', ['a', 'b', '=', '2'], ['XX=XX']])
706 " Any keyword but excluding digits or end-of-line
707 call add(tl, [2, '\_K\+', ['a', 'b', '=', '2'], ['XX=XX2XX']])
708 " Any filename character or end-of-line
709 call add(tl, [2, '\_f\+', ['a', 'b', '.', '5'], ['XX']])
710 " Any filename character but excluding digits or end-of-line
711 call add(tl, [2, '\_F\+', ['a', 'b', '.', '5'], ['XX5XX']])
712 " Any printable character or end-of-line
713 call add(tl, [2, '\_p\+', ['a', 'b', '=', '4'], ['XX']])
714 " Any printable character excluding digits or end-of-line
715 call add(tl, [2, '\_P\+', ['a', 'b', '=', '4'], ['XX4XX']])
716 " Any whitespace character or end-of-line
717 call add(tl, [2, '\_s\+', [' ', ' ', 'a', 'b'], ['XXaXXbXX']])
718 " Any non-whitespace character or end-of-line
719 call add(tl, [2, '\_S\+', [' ', ' ', 'a', 'b'], [' XX XX']])
720 " Any decimal digit or end-of-line
721 call add(tl, [2, '\_d\+', ['1', 'a', '2', 'b', '3'], ['XXaXXbXX']])
722 " Any non-decimal digit or end-of-line
723 call add(tl, [2, '\_D\+', ['1', 'a', '2', 'b', '3'], ['1XX2XX3XX']])
724 " Any hexadecimal digit or end-of-line
725 call add(tl, [2, '\_x\+', ['1', 'a', 'g', '9', '8'], ['XXgXX']])
726 " Any non-hexadecimal digit or end-of-line
727 call add(tl, [2, '\_X\+', ['1', 'a', 'g', '9', '8'], ['1XXaXX9XX8XX']])
728 " Any octal digit or end-of-line
729 call add(tl, [2, '\_o\+', ['0', '7', '8', '9', '0'], ['XX8XX9XX']])
730 " Any non-octal digit or end-of-line
731 call add(tl, [2, '\_O\+', ['0', '7', '8', '9', '0'], ['0XX7XX0XX']])
732 " Any word character or end-of-line
733 call add(tl, [2, '\_w\+', ['A', 'B', '=', 'C', 'D'], ['XX=XX']])
734 " Any non-word character or end-of-line
735 call add(tl, [2, '\_W\+', ['A', 'B', '=', 'C', 'D'], ['AXXBXXCXXDXX']])
736 " Any head-of-word character or end-of-line
737 call add(tl, [2, '\_h\+', ['a', '1', 'b', '2', 'c'], ['XX1XX2XX']])
738 " Any non-head-of-word character or end-of-line
739 call add(tl, [2, '\_H\+', ['a', '1', 'b', '2', 'c'], ['aXXbXXcXX']])
740 " Any alphabetic character or end-of-line
741 call add(tl, [2, '\_a\+', ['a', '1', 'b', '2', 'c'], ['XX1XX2XX']])
742 " Any non-alphabetic character or end-of-line
743 call add(tl, [2, '\_A\+', ['a', '1', 'b', '2', 'c'], ['aXXbXXcXX']])
744 " Any lowercase character or end-of-line
745 call add(tl, [2, '\_l\+', ['a', 'A', 'b', 'B'], ['XXAXXBXX']])
746 " Any non-lowercase character or end-of-line
747 call add(tl, [2, '\_L\+', ['a', 'A', 'b', 'B'], ['aXXbXX']])
748 " Any uppercase character or end-of-line
749 call add(tl, [2, '\_u\+', ['a', 'A', 'b', 'B'], ['aXXbXX']])
750 " Any non-uppercase character or end-of-line
751 call add(tl, [2, '\_U\+', ['a', 'A', 'b', 'B'], ['XXAXXBXX']])
752 " Collection or end-of-line
753 call add(tl, [2, '\_[a-z]\+', ['a', 'A', 'b', 'B'], ['XXAXXBXX']])
754 " start of line anywhere in the text
755 call add(tl, [2, 'one\zs\_s*\_^\zetwo',
756 \ ['', 'one', ' two', 'one', '', 'two'],
757 \ ['', 'one', ' two', 'oneXXtwo']])
758 " end of line anywhere in the text
759 call add(tl, [2, 'one\zs\_$\_s*two',
760 \ ['', 'one', ' two', 'one', '', 'two'], ['', 'oneXX', 'oneXX']])
761
Bram Moolenaarf9cb05c2019-12-15 13:39:22 +0100762 " Check that \_[0-9] matching EOL does not break a following \>
763 call add(tl, [2, '\<\(\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\.\)\{3\}\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\>', ['', 'localnet/192.168.0.1', ''], ['', 'localnet/XX', '']])
764
765 " Check a pattern with a line break and ^ and $
766 call add(tl, [2, 'a\n^b$\n^c', ['a', 'b', 'c'], ['XX']])
767
768 call add(tl, [2, '\(^.\+\n\)\1', [' dog', ' dog', 'asdf'], ['XXasdf']])
769
770 " Run the multi-line tests
771 for t in tl
772 let re = t[0]
773 let pat = t[1]
774 let before = t[2]
775 let after = t[3]
776 for engine in [0, 1, 2]
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200777 if engine == 2 && re == 0 || engine == 1 && re == 1
Bram Moolenaarf9cb05c2019-12-15 13:39:22 +0100778 continue
779 endif
780 let &regexpengine = engine
781 new
782 call setline(1, before)
783 exe '%s/' . pat . '/XX/'
784 let result = getline(1, '$')
785 q!
786 if result != after
787 call assert_report('Error: pat: \"' . pat . '\", text: \"'
788 \ . string(before) . '\", expected: \"' . string(after)
789 \ . '\", got: \"' . string(result) . '\"')
790 else
791 " Test passed
792 endif
793 endfor
794 endfor
795 unlet t tl
796endfunc
797
798" Check that using a pattern on two lines doesn't get messed up by using
799" matchstr() with \ze in between.
800func Test_matchstr_with_ze()
801 new
802 call append(0, ['Substitute here:', '<T="">Ta 5</Title>',
803 \ '<T="">Ac 7</Title>'])
804 call cursor(1, 1)
805 set re=0
806
807 .+1,.+2s/""/\='"' . matchstr(getline("."), '\d\+\ze<') . '"'
808 call assert_equal(['Substitute here:', '<T="5">Ta 5</Title>',
809 \ '<T="7">Ac 7</Title>', ''], getline(1, '$'))
810
811 bwipe!
812endfunc
813
Dominique Pelle81b573d2022-03-22 21:14:55 +0000814" Check a pattern with a look behind crossing a line boundary
Bram Moolenaarf9cb05c2019-12-15 13:39:22 +0100815func Test_lookbehind_across_line()
816 new
817 call append(0, ['Behind:', 'asdfasd<yyy', 'xxstart1', 'asdfasd<yy',
818 \ 'xxxstart2', 'asdfasd<yy', 'xxstart3'])
819 call cursor(1, 1)
820 call search('\(<\_[xy]\+\)\@3<=start')
821 call assert_equal([0, 7, 3, 0], getpos('.'))
822 bwipe!
823endfunc
824
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200825" Test for the \%V atom (match inside the visual area)
826func Regex_Match_Visual_Area()
Bram Moolenaarf9cb05c2019-12-15 13:39:22 +0100827 call append(0, ['Visual:', 'thexe the thexethe', 'andaxand andaxand',
828 \ 'oooxofor foroxooo', 'oooxofor foroxooo'])
829 call cursor(1, 1)
830 exe "normal jfxvfx:s/\\%Ve/E/g\<CR>"
831 exe "normal jV:s/\\%Va/A/g\<CR>"
832 exe "normal jfx\<C-V>fxj:s/\\%Vo/O/g\<CR>"
833 call assert_equal(['Visual:', 'thexE thE thExethe', 'AndAxAnd AndAxAnd',
834 \ 'oooxOfOr fOrOxooo', 'oooxOfOr fOrOxooo', ''], getline(1, '$'))
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200835 %d
836endfunc
837
838" Check matching Visual area
839func Test_matching_visual_area()
840 new
841 set regexpengine=1
842 call Regex_Match_Visual_Area()
843 set regexpengine=2
844 call Regex_Match_Visual_Area()
845 set regexpengine&
Bram Moolenaarf9cb05c2019-12-15 13:39:22 +0100846 bwipe!
847endfunc
848
849" Check matching marks
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200850func Regex_Mark()
Bram Moolenaarf9cb05c2019-12-15 13:39:22 +0100851 call append(0, ['', '', '', 'Marks:', 'asdfSasdfsadfEasdf', 'asdfSas',
852 \ 'dfsadfEasdf', '', '', '', '', ''])
853 call cursor(4, 1)
854 exe "normal jfSmsfEme:.-4,.+6s/.\\%>'s.*\\%<'e../here/\<CR>"
855 exe "normal jfSmsj0fEme:.-4,.+6s/.\\%>'s\\_.*\\%<'e../again/\<CR>"
856 call assert_equal(['', '', '', 'Marks:', 'asdfhereasdf', 'asdfagainasdf',
857 \ '', '', '', '', '', ''], getline(1, '$'))
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200858 %d
859endfunc
860
861func Test_matching_marks()
862 new
863 set regexpengine=1
864 call Regex_Mark()
865 set regexpengine=2
866 call Regex_Mark()
Bram Moolenaarf9cb05c2019-12-15 13:39:22 +0100867 bwipe!
868endfunc
869
870" Check patterns matching cursor position.
871func s:curpos_test()
872 new
873 call setline(1, ['ffooooo', 'boboooo', 'zoooooo', 'koooooo', 'moooooo',
874 \ "\t\t\tfoo", 'abababababababfoo', 'bababababababafoo', '********_',
875 \ ' xxxxxxxxxxxx xxxx xxxxxx xxxxxxx x xxxxxxxxx xx xxxxxx xxxxxx xxxxx xxxxxxx xx xxxx xxxxxxxx xxxx xxxxxxxxxxx xxx xxxxxxx xxxxxxxxx xx xxxxxx xx xxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxx xxx xxxxxxxx xxxxxxxxx xxxx xxx xxxx xxx xxx xxxxx xxxxxxxxxxxx xxxx xxxxxxxxx xxxxxxxxxxx xx xxxxx xxx xxxxxxxx xxxxxx xxx xxx xxxxxxxxx xxxxxxx x xxxxxxxxx xx xxxxxx xxxxxxx xxxxxxxxxxxxxxxxxx xxxxxxx xxxxxxx xxx xxx xxxxxxxx xxxxxxx xxxx xxx xxxxxx xxxxx xxxxx xx xxxxxx xxxxxxx xxx xxxxxxxxxxxx xxxx xxxxxxxxx xxxxxx xxxxxx xxxxx xxx xxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxx xxxxxxxxxx xxxx xx xxxxxxxx xxx xxxxxxxxxxx xxxxx'])
876 call setpos('.', [0, 1, 0, 0])
877 s/\%>3c.//g
878 call setpos('.', [0, 2, 4, 0])
879 s/\%#.*$//g
880 call setpos('.', [0, 3, 0, 0])
881 s/\%<3c./_/g
882 %s/\%4l\%>5c./_/g
883 %s/\%6l\%>25v./_/g
884 %s/\%>6l\%3c./!/g
885 %s/\%>7l\%12c./?/g
886 %s/\%>7l\%<9l\%>5v\%<8v./#/g
887 $s/\%(|\u.*\)\@<=[^|\t]\+$//ge
888 call assert_equal(['ffo', 'bob', '__ooooo', 'koooo__', 'moooooo',
889 \ ' f__', 'ab!babababababfoo',
890 \ 'ba!ab##abab?bafoo', '**!*****_',
891 \ ' ! xxx?xxxxxxxx xxxx xxxxxx xxxxxxx x xxxxxxxxx xx xxxxxx xxxxxx xxxxx xxxxxxx xx xxxx xxxxxxxx xxxx xxxxxxxxxxx xxx xxxxxxx xxxxxxxxx xx xxxxxx xx xxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxx xxx xxxxxxxx xxxxxxxxx xxxx xxx xxxx xxx xxx xxxxx xxxxxxxxxxxx xxxx xxxxxxxxx xxxxxxxxxxx xx xxxxx xxx xxxxxxxx xxxxxx xxx xxx xxxxxxxxx xxxxxxx x xxxxxxxxx xx xxxxxx xxxxxxx xxxxxxxxxxxxxxxxxx xxxxxxx xxxxxxx xxx xxx xxxxxxxx xxxxxxx xxxx xxx xxxxxx xxxxx xxxxx xx xxxxxx xxxxxxx xxx xxxxxxxxxxxx xxxx xxxxxxxxx xxxxxx xxxxxx xxxxx xxx xxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxx xxxxxxxxxx xxxx xx xxxxxxxx xxx xxxxxxxxxxx xxxxx'],
892 \ getline(1, '$'))
893 bwipe!
894endfunc
895
896func Test_matching_curpos()
897 set re=0
898 call s:curpos_test()
899 set re=1
900 call s:curpos_test()
901 set re=2
902 call s:curpos_test()
903 set re&
904endfunc
905
906" Test for matching the start and end of a buffer
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200907func Regex_start_end_buffer()
Bram Moolenaarf9cb05c2019-12-15 13:39:22 +0100908 call setline(1, repeat(['vim edit'], 20))
909 /\%^
910 call assert_equal([0, 1, 1, 0], getpos('.'))
911 exe "normal 50%/\\%^..\<CR>"
912 call assert_equal([0, 1, 1, 0], getpos('.'))
913 exe "normal 50%/\\%$\<CR>"
914 call assert_equal([0, 20, 8, 0], getpos('.'))
915 exe "normal 6gg/..\\%$\<CR>"
916 call assert_equal([0, 20, 7, 0], getpos('.'))
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200917 %d
918endfunc
919
920func Test_start_end_of_buffer_match()
921 new
922 set regexpengine=1
923 call Regex_start_end_buffer()
924 set regexpengine=2
925 call Regex_start_end_buffer()
Bram Moolenaarf9cb05c2019-12-15 13:39:22 +0100926 bwipe!
927endfunc
928
Bram Moolenaara7a691c2020-12-09 16:36:04 +0100929func Test_ze_before_zs()
930 call assert_equal('', matchstr(' ', '\%#=1\ze \zs'))
931 call assert_equal('', matchstr(' ', '\%#=2\ze \zs'))
932 call assert_equal(repeat([''], 10), matchlist(' ', '\%#=1\ze \zs'))
933 call assert_equal(repeat([''], 10), matchlist(' ', '\%#=2\ze \zs'))
934endfunc
935
Bram Moolenaarf9cb05c2019-12-15 13:39:22 +0100936" Check for detecting error
937func Test_regexp_error()
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200938 call assert_fails("call matchlist('x x', '\\%#=1 \\zs*')", 'E888:')
939 call assert_fails("call matchlist('x x', '\\%#=1 \\ze*')", 'E888:')
940 call assert_fails("call matchlist('x x', '\\%#=2 \\zs*')", 'E888:')
941 call assert_fails("call matchlist('x x', '\\%#=2 \\ze*')", 'E888:')
Bram Moolenaar004a6782020-04-11 17:09:31 +0200942 call assert_fails("call matchstr('abcd', '\\%o841\\%o142')", 'E678:')
Bram Moolenaara2b3e7d2021-03-26 17:24:34 +0100943 call assert_fails("call matchstr('abcd', '\\%#=2\\%2147483647c')", 'E951:')
944 call assert_fails("call matchstr('abcd', '\\%#=2\\%2147483647l')", 'E951:')
945 call assert_fails("call matchstr('abcd', '\\%#=2\\%2147483647v')", 'E951:')
946 call assert_fails('exe "normal /\\%#=1\\%[x\\%[x]]\<CR>"', 'E369:')
947 call assert_fails('exe "normal /\\%#=2\\%2147483647l\<CR>"', 'E951:')
948 call assert_fails('exe "normal /\\%#=2\\%2147483647c\<CR>"', 'E951:')
949 call assert_fails('exe "normal /\\%#=2\\%102261126v\<CR>"', 'E951:')
950 call assert_fails('exe "normal /\\%#=2\\%2147483646l\<CR>"', 'E486:')
951 call assert_fails('exe "normal /\\%#=2\\%2147483646c\<CR>"', 'E486:')
952 call assert_fails('exe "normal /\\%#=2\\%102261125v\<CR>"', 'E486:')
Bram Moolenaar004a6782020-04-11 17:09:31 +0200953 call assert_equal('', matchstr('abcd', '\%o181\%o142'))
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200954endfunc
955
956" Test for using the last substitute string pattern (~)
957func Test_regexp_last_subst_string()
958 new
959 s/bar/baz/e
960 call assert_equal(matchstr("foo\nbaz\nbar", "\\%#=1\~"), "baz")
961 call assert_equal(matchstr("foo\nbaz\nbar", "\\%#=2\~"), "baz")
962 close!
Bram Moolenaarf9cb05c2019-12-15 13:39:22 +0100963endfunc
964
Bram Moolenaar04db26b2021-07-05 20:15:23 +0200965" Check patterns matching cursor position.
966func s:curpos_test2()
967 new
968 call setline(1, ['1', '2 foobar eins zwei drei vier fünf sechse',
969 \ '3 foobar eins zwei drei vier fünf sechse',
970 \ '4 foobar eins zwei drei vier fünf sechse',
971 \ '5 foobar eins zwei drei vier fünf sechse',
972 \ '6 foobar eins zwei drei vier fünf sechse',
973 \ '7 foobar eins zwei drei vier fünf sechse'])
974 call setpos('.', [0, 2, 10, 0])
975 s/\%.c.*//g
976 call setpos('.', [0, 3, 15, 0])
977 s/\%.l.*//g
978 call setpos('.', [0, 5, 3, 0])
979 s/\%.v.*/_/g
980 call assert_equal(['1',
981 \ '2 foobar ',
982 \ '',
983 \ '4 foobar eins zwei drei vier fünf sechse',
984 \ '5 _',
985 \ '6 foobar eins zwei drei vier fünf sechse',
986 \ '7 foobar eins zwei drei vier fünf sechse'],
987 \ getline(1, '$'))
988 call assert_fails('call search("\\%.1l")', 'E1204:')
989 call assert_fails('call search("\\%.1c")', 'E1204:')
990 call assert_fails('call search("\\%.1v")', 'E1204:')
991 bwipe!
992endfunc
993
994" Check patterns matching before or after cursor position.
995func s:curpos_test3()
996 new
997 call setline(1, ['1', '2 foobar eins zwei drei vier fünf sechse',
998 \ '3 foobar eins zwei drei vier fünf sechse',
999 \ '4 foobar eins zwei drei vier fünf sechse',
1000 \ '5 foobar eins zwei drei vier fünf sechse',
1001 \ '6 foobar eins zwei drei vier fünf sechse',
1002 \ '7 foobar eins zwei drei vier fünf sechse'])
1003 call setpos('.', [0, 2, 10, 0])
1004 " Note: This removes all columns, except for the column directly in front of
1005 " the cursor. Bug????
1006 :s/^.*\%<.c//
1007 call setpos('.', [0, 3, 10, 0])
1008 :s/\%>.c.*$//
1009 call setpos('.', [0, 5, 4, 0])
1010 " Note: This removes all columns, except for the column directly in front of
1011 " the cursor. Bug????
1012 :s/^.*\%<.v/_/
1013 call setpos('.', [0, 6, 4, 0])
1014 :s/\%>.v.*$/_/
1015 call assert_equal(['1',
1016 \ ' eins zwei drei vier fünf sechse',
1017 \ '3 foobar e',
1018 \ '4 foobar eins zwei drei vier fünf sechse',
1019 \ '_foobar eins zwei drei vier fünf sechse',
1020 \ '6 fo_',
1021 \ '7 foobar eins zwei drei vier fünf sechse'],
1022 \ getline(1, '$'))
1023 sil %d
1024 call setline(1, ['1', '2 foobar eins zwei drei vier fünf sechse',
1025 \ '3 foobar eins zwei drei vier fünf sechse',
1026 \ '4 foobar eins zwei drei vier fünf sechse',
1027 \ '5 foobar eins zwei drei vier fünf sechse',
1028 \ '6 foobar eins zwei drei vier fünf sechse',
1029 \ '7 foobar eins zwei drei vier fünf sechse'])
1030 call setpos('.', [0, 4, 4, 0])
1031 %s/\%<.l.*//
1032 call setpos('.', [0, 5, 4, 0])
1033 %s/\%>.l.*//
1034 call assert_equal(['', '', '',
1035 \ '4 foobar eins zwei drei vier fünf sechse',
1036 \ '5 foobar eins zwei drei vier fünf sechse',
1037 \ '', ''],
1038 \ getline(1, '$'))
1039 bwipe!
1040endfunc
1041
1042" Test that matching below, at or after the
1043" cursor position work
1044func Test_matching_pos()
1045 for val in range(3)
1046 exe "set re=" .. val
1047 " Match at cursor position
1048 call s:curpos_test2()
1049 " Match before or after cursor position
1050 call s:curpos_test3()
1051 endfor
1052 set re&
1053endfunc
1054
Bram Moolenaar64066b92021-11-17 18:22:56 +00001055func Test_using_mark_position()
1056 " this was using freed memory
Bram Moolenaarb55986c2022-03-29 13:24:58 +01001057 " new engine
Bram Moolenaar64066b92021-11-17 18:22:56 +00001058 new
1059 norm O0
1060 call assert_fails("s/\\%')", 'E486:')
1061 bwipe!
Bram Moolenaarb55986c2022-03-29 13:24:58 +01001062
1063 " old engine
1064 new
1065 norm O0
1066 call assert_fails("s/\\%#=1\\%')", 'E486:')
1067 bwipe!
Bram Moolenaar64066b92021-11-17 18:22:56 +00001068endfunc
1069
Bram Moolenaar4c13e5e2021-12-30 14:49:43 +00001070func Test_using_visual_position()
1071 " this was using freed memory
1072 new
1073 exe "norm 0o\<Esc>\<C-V>k\<C-X>o0"
1074 /\%V
1075 bwipe!
1076endfunc
1077
Bram Moolenaar94f31922021-12-30 15:29:18 +00001078func Test_using_invalid_visual_position()
1079 " this was going beyond the end of the line
1080 new
1081 exe "norm 0o000\<Esc>0\<C-V>$s0"
1082 /\%V
1083 bwipe!
1084endfunc
1085
Bram Moolenaarf9cb05c2019-12-15 13:39:22 +01001086" vim: shiftwidth=2 sts=2 expandtab