blob: 20ffa0fbffc05ab1d22a096151f54343fddcd9d3 [file] [log] [blame]
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +02001" Test for the search command
2
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +01003source shared.vim
Bram Moolenaar9d34d902018-04-27 22:18:12 +02004source screendump.vim
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +01005
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +02006func Test_search_cmdline()
7 if !exists('+incsearch')
8 return
9 endif
10 " need to disable char_avail,
11 " so that expansion of commandline works
Bram Moolenaareb992cb2017-03-09 18:20:16 +010012 call test_override("char_avail", 1)
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020013 new
14 call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar'])
15 " Test 1
16 " CTRL-N / CTRL-P skips through the previous search history
17 set noincsearch
18 :1
19 call feedkeys("/foobar\<cr>", 'tx')
20 call feedkeys("/the\<cr>",'tx')
21 call assert_equal('the', @/)
Bram Moolenaar11956692016-08-27 16:26:56 +020022 call feedkeys("/thes\<C-P>\<C-P>\<cr>",'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020023 call assert_equal('foobar', @/)
24
25 " Test 2
Bram Moolenaar11956692016-08-27 16:26:56 +020026 " Ctrl-G goes from one match to the next
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020027 " until the end of the buffer
28 set incsearch nowrapscan
29 :1
30 " first match
31 call feedkeys("/the\<cr>", 'tx')
32 call assert_equal(' 2 these', getline('.'))
33 :1
34 " second match
Bram Moolenaar11956692016-08-27 16:26:56 +020035 call feedkeys("/the\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020036 call assert_equal(' 3 the', getline('.'))
Bram Moolenaardda933d2016-09-03 21:04:58 +020037 call assert_equal([0, 0, 0, 0], getpos('"'))
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020038 :1
39 " third match
Bram Moolenaar11956692016-08-27 16:26:56 +020040 call feedkeys("/the".repeat("\<C-G>", 2)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020041 call assert_equal(' 4 their', getline('.'))
42 :1
43 " fourth match
Bram Moolenaar11956692016-08-27 16:26:56 +020044 call feedkeys("/the".repeat("\<C-G>", 3)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020045 call assert_equal(' 5 there', getline('.'))
46 :1
47 " fifth match
Bram Moolenaar11956692016-08-27 16:26:56 +020048 call feedkeys("/the".repeat("\<C-G>", 4)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020049 call assert_equal(' 6 their', getline('.'))
50 :1
51 " sixth match
Bram Moolenaar11956692016-08-27 16:26:56 +020052 call feedkeys("/the".repeat("\<C-G>", 5)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020053 call assert_equal(' 7 the', getline('.'))
54 :1
55 " seventh match
Bram Moolenaar11956692016-08-27 16:26:56 +020056 call feedkeys("/the".repeat("\<C-G>", 6)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020057 call assert_equal(' 8 them', getline('.'))
58 :1
59 " eigth match
Bram Moolenaar11956692016-08-27 16:26:56 +020060 call feedkeys("/the".repeat("\<C-G>", 7)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020061 call assert_equal(' 9 these', getline('.'))
62 :1
63 " no further match
Bram Moolenaar11956692016-08-27 16:26:56 +020064 call feedkeys("/the".repeat("\<C-G>", 8)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020065 call assert_equal(' 9 these', getline('.'))
Bram Moolenaardda933d2016-09-03 21:04:58 +020066 call assert_equal([0, 0, 0, 0], getpos('"'))
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020067
68 " Test 3
Bram Moolenaar11956692016-08-27 16:26:56 +020069 " Ctrl-G goes from one match to the next
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020070 " and continues back at the top
71 set incsearch wrapscan
72 :1
73 " first match
74 call feedkeys("/the\<cr>", 'tx')
75 call assert_equal(' 2 these', getline('.'))
76 :1
77 " second match
Bram Moolenaar11956692016-08-27 16:26:56 +020078 call feedkeys("/the\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020079 call assert_equal(' 3 the', getline('.'))
80 :1
81 " third match
Bram Moolenaar11956692016-08-27 16:26:56 +020082 call feedkeys("/the".repeat("\<C-G>", 2)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020083 call assert_equal(' 4 their', getline('.'))
84 :1
85 " fourth match
Bram Moolenaar11956692016-08-27 16:26:56 +020086 call feedkeys("/the".repeat("\<C-G>", 3)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020087 call assert_equal(' 5 there', getline('.'))
88 :1
89 " fifth match
Bram Moolenaar11956692016-08-27 16:26:56 +020090 call feedkeys("/the".repeat("\<C-G>", 4)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020091 call assert_equal(' 6 their', getline('.'))
92 :1
93 " sixth match
Bram Moolenaar11956692016-08-27 16:26:56 +020094 call feedkeys("/the".repeat("\<C-G>", 5)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020095 call assert_equal(' 7 the', getline('.'))
96 :1
97 " seventh match
Bram Moolenaar11956692016-08-27 16:26:56 +020098 call feedkeys("/the".repeat("\<C-G>", 6)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020099 call assert_equal(' 8 them', getline('.'))
100 :1
101 " eigth match
Bram Moolenaar11956692016-08-27 16:26:56 +0200102 call feedkeys("/the".repeat("\<C-G>", 7)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200103 call assert_equal(' 9 these', getline('.'))
104 :1
105 " back at first match
Bram Moolenaar11956692016-08-27 16:26:56 +0200106 call feedkeys("/the".repeat("\<C-G>", 8)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200107 call assert_equal(' 2 these', getline('.'))
108
109 " Test 4
Bram Moolenaar11956692016-08-27 16:26:56 +0200110 " CTRL-T goes to the previous match
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200111 set incsearch nowrapscan
112 $
113 " first match
114 call feedkeys("?the\<cr>", 'tx')
115 call assert_equal(' 9 these', getline('.'))
116 $
117 " first match
Bram Moolenaar11956692016-08-27 16:26:56 +0200118 call feedkeys("?the\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200119 call assert_equal(' 9 these', getline('.'))
120 $
121 " second match
Bram Moolenaar11956692016-08-27 16:26:56 +0200122 call feedkeys("?the".repeat("\<C-T>", 1)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200123 call assert_equal(' 8 them', getline('.'))
124 $
125 " last match
Bram Moolenaar11956692016-08-27 16:26:56 +0200126 call feedkeys("?the".repeat("\<C-T>", 7)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200127 call assert_equal(' 2 these', getline('.'))
128 $
129 " last match
Bram Moolenaar11956692016-08-27 16:26:56 +0200130 call feedkeys("?the".repeat("\<C-T>", 8)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200131 call assert_equal(' 2 these', getline('.'))
132
133 " Test 5
Bram Moolenaar11956692016-08-27 16:26:56 +0200134 " CTRL-T goes to the previous match
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200135 set incsearch wrapscan
136 $
137 " first match
138 call feedkeys("?the\<cr>", 'tx')
139 call assert_equal(' 9 these', getline('.'))
140 $
141 " first match at the top
Bram Moolenaar11956692016-08-27 16:26:56 +0200142 call feedkeys("?the\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200143 call assert_equal(' 2 these', getline('.'))
144 $
145 " second match
Bram Moolenaar11956692016-08-27 16:26:56 +0200146 call feedkeys("?the".repeat("\<C-T>", 1)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200147 call assert_equal(' 8 them', getline('.'))
148 $
149 " last match
Bram Moolenaar11956692016-08-27 16:26:56 +0200150 call feedkeys("?the".repeat("\<C-T>", 7)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200151 call assert_equal(' 2 these', getline('.'))
152 $
153 " back at the bottom of the buffer
Bram Moolenaar11956692016-08-27 16:26:56 +0200154 call feedkeys("?the".repeat("\<C-T>", 8)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200155 call assert_equal(' 9 these', getline('.'))
156
157 " Test 6
158 " CTRL-L adds to the search pattern
159 set incsearch wrapscan
160 1
161 " first match
162 call feedkeys("/the\<c-l>\<cr>", 'tx')
163 call assert_equal(' 2 these', getline('.'))
164 1
165 " go to next match of 'thes'
Bram Moolenaar11956692016-08-27 16:26:56 +0200166 call feedkeys("/the\<c-l>\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200167 call assert_equal(' 9 these', getline('.'))
168 1
169 " wrap around
Bram Moolenaar11956692016-08-27 16:26:56 +0200170 call feedkeys("/the\<c-l>\<C-G>\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200171 call assert_equal(' 2 these', getline('.'))
172 1
173 " wrap around
174 set nowrapscan
Bram Moolenaar11956692016-08-27 16:26:56 +0200175 call feedkeys("/the\<c-l>\<C-G>\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200176 call assert_equal(' 9 these', getline('.'))
177
178 " Test 7
179 " <bs> remove from match, but stay at current match
180 set incsearch wrapscan
181 1
182 " first match
183 call feedkeys("/thei\<cr>", 'tx')
184 call assert_equal(' 4 their', getline('.'))
185 1
186 " delete one char, add another
187 call feedkeys("/thei\<bs>s\<cr>", 'tx')
Bram Moolenaardda933d2016-09-03 21:04:58 +0200188 call assert_equal(' 2 these', getline('.'))
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200189 1
190 " delete one char, add another, go to previous match, add one char
Bram Moolenaar11956692016-08-27 16:26:56 +0200191 call feedkeys("/thei\<bs>s\<bs>\<C-T>\<c-l>\<cr>", 'tx')
Bram Moolenaardda933d2016-09-03 21:04:58 +0200192 call assert_equal(' 9 these', getline('.'))
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200193 1
194 " delete all chars, start from the beginning again
195 call feedkeys("/them". repeat("\<bs>",4).'the\>'."\<cr>", 'tx')
196 call assert_equal(' 3 the', getline('.'))
197
198 " clean up
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100199 call test_override("char_avail", 0)
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200200 bw!
201endfunc
202
203func Test_search_cmdline2()
204 if !exists('+incsearch')
205 return
206 endif
207 " need to disable char_avail,
208 " so that expansion of commandline works
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100209 call test_override("char_avail", 1)
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200210 new
211 call setline(1, [' 1', ' 2 these', ' 3 the theother'])
212 " Test 1
Bram Moolenaar11956692016-08-27 16:26:56 +0200213 " Ctrl-T goes correctly back and forth
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200214 set incsearch
215 1
216 " first match
217 call feedkeys("/the\<cr>", 'tx')
218 call assert_equal(' 2 these', getline('.'))
219 1
220 " go to next match (on next line)
Bram Moolenaar11956692016-08-27 16:26:56 +0200221 call feedkeys("/the\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200222 call assert_equal(' 3 the theother', getline('.'))
223 1
224 " go to next match (still on line 3)
Bram Moolenaar11956692016-08-27 16:26:56 +0200225 call feedkeys("/the\<C-G>\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200226 call assert_equal(' 3 the theother', getline('.'))
227 1
228 " go to next match (still on line 3)
Bram Moolenaar11956692016-08-27 16:26:56 +0200229 call feedkeys("/the\<C-G>\<C-G>\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200230 call assert_equal(' 3 the theother', getline('.'))
231 1
232 " go to previous match (on line 3)
Bram Moolenaar11956692016-08-27 16:26:56 +0200233 call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200234 call assert_equal(' 3 the theother', getline('.'))
235 1
236 " go to previous match (on line 3)
Bram Moolenaar11956692016-08-27 16:26:56 +0200237 call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200238 call assert_equal(' 3 the theother', getline('.'))
239 1
240 " go to previous match (on line 2)
Bram Moolenaar11956692016-08-27 16:26:56 +0200241 call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<C-T>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200242 call assert_equal(' 2 these', getline('.'))
243
Bram Moolenaardda933d2016-09-03 21:04:58 +0200244 " Test 2: keep the view,
245 " after deleting a character from the search cmd
246 call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar'])
247 resize 5
248 1
249 call feedkeys("/foo\<bs>\<cr>", 'tx')
250 redraw
251 call assert_equal({'lnum': 10, 'leftcol': 0, 'col': 4, 'topfill': 0, 'topline': 6, 'coladd': 0, 'skipcol': 0, 'curswant': 4}, winsaveview())
252
253 " remove all history entries
254 for i in range(10)
255 call histdel('/')
256 endfor
257
258 " Test 3: reset the view,
259 " after deleting all characters from the search cmd
260 norm! 1gg0
261 " unfortunately, neither "/foo\<c-w>\<cr>", nor "/foo\<bs>\<bs>\<bs>\<cr>",
262 " nor "/foo\<c-u>\<cr>" works to delete the commandline.
263 " In that case Vim should return "E35 no previous regular expression",
264 " but it looks like Vim still sees /foo and therefore the test fails.
265 " Therefore, disableing this test
266 "call assert_fails(feedkeys("/foo\<c-w>\<cr>", 'tx'), 'E35')
267 "call assert_equal({'lnum': 1, 'leftcol': 0, 'col': 0, 'topfill': 0, 'topline': 1, 'coladd': 0, 'skipcol': 0, 'curswant': 0}, winsaveview())
268
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200269 " clean up
Bram Moolenaardda933d2016-09-03 21:04:58 +0200270 set noincsearch
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100271 call test_override("char_avail", 0)
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200272 bw!
273endfunc
Bram Moolenaarea683da2016-09-09 21:41:34 +0200274
275func Test_use_sub_pat()
276 split
277 let @/ = ''
278 func X()
279 s/^/a/
280 /
281 endfunc
282 call X()
283 bwipe!
284endfunc
Bram Moolenaar6e450a52017-01-06 20:03:58 +0100285
286func Test_searchpair()
287 new
288 call setline(1, ['other code here', '', '[', '" cursor here', ']'])
289 4
Bram Moolenaar3dddb092018-06-24 19:01:59 +0200290 let a = searchpair('\[','',']','bW')
Bram Moolenaar6e450a52017-01-06 20:03:58 +0100291 call assert_equal(3, a)
292 set nomagic
293 4
Bram Moolenaar3dddb092018-06-24 19:01:59 +0200294 let a = searchpair('\[','',']','bW')
Bram Moolenaar6e450a52017-01-06 20:03:58 +0100295 call assert_equal(3, a)
296 set magic
297 q!
298endfunc
299
Bram Moolenaar3dddb092018-06-24 19:01:59 +0200300func Test_searchpair_errors()
301 call assert_fails("call searchpair([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: using List as a String')
302 call assert_fails("call searchpair('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: using Funcref as a String')
303 call assert_fails("call searchpair('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: using Dictionary as a String')
304 call assert_fails("call searchpair('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
305 call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 0, 99, 100)", 'E475: Invalid argument: 0')
306 call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
307 call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')
308endfunc
309
Bram Moolenaar48570482017-10-30 21:48:41 +0100310func Test_searchpair_skip()
311 func Zero()
312 return 0
313 endfunc
314 func Partial(x)
315 return a:x
316 endfunc
317 new
318 call setline(1, ['{', 'foo', 'foo', 'foo', '}'])
319 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', ''))
320 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', '0'))
321 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', {-> 0}))
322 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Zero')))
323 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Partial', [0])))
Bram Moolenaar48570482017-10-30 21:48:41 +0100324 bw!
325endfunc
326
Bram Moolenaara43ebe92018-07-14 17:25:01 +0200327func Test_searchpair_leak()
328 new
329 call setline(1, 'if one else another endif')
330
331 " The error in the skip expression caused memory to leak.
332 call assert_fails("call searchpair('\\<if\\>', '\\<else\\>', '\\<endif\\>', '', '\"foo\" 2')", 'E15:')
333
334 bwipe!
335endfunc
336
Bram Moolenaar66727e12017-03-01 22:17:05 +0100337func Test_searchc()
338 " These commands used to cause memory overflow in searchc().
339 new
340 norm ixx
341 exe "norm 0t\u93cf"
342 bw!
343endfunc
Bram Moolenaara693d052017-06-29 22:23:06 +0200344
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200345func Cmdline3_prep()
346 " need to disable char_avail,
347 " so that expansion of commandline works
348 call test_override("char_avail", 1)
349 new
350 call setline(1, [' 1', ' 2 the~e', ' 3 the theother'])
351 set incsearch
352endfunc
353
Bram Moolenaar976b8472018-08-12 15:49:47 +0200354func Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200355 set noincsearch
356 call test_override("char_avail", 0)
357 bw!
358endfunc
359
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200360func Test_search_cmdline3()
361 if !exists('+incsearch')
362 return
363 endif
364 call Cmdline3_prep()
365 1
366 " first match
367 call feedkeys("/the\<c-l>\<cr>", 'tx')
368 call assert_equal(' 2 the~e', getline('.'))
369
Bram Moolenaar976b8472018-08-12 15:49:47 +0200370 call Incsearch_cleanup()
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200371endfunc
372
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200373func Test_search_cmdline3s()
374 if !exists('+incsearch')
375 return
376 endif
377 call Cmdline3_prep()
378 1
379 call feedkeys(":%s/the\<c-l>/xxx\<cr>", 'tx')
380 call assert_equal(' 2 xxxe', getline('.'))
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200381 undo
382 call feedkeys(":%subs/the\<c-l>/xxx\<cr>", 'tx')
383 call assert_equal(' 2 xxxe', getline('.'))
384 undo
385 call feedkeys(":%substitute/the\<c-l>/xxx\<cr>", 'tx')
386 call assert_equal(' 2 xxxe', getline('.'))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200387
Bram Moolenaar976b8472018-08-12 15:49:47 +0200388 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200389endfunc
390
391func Test_search_cmdline3g()
392 if !exists('+incsearch')
393 return
394 endif
395 call Cmdline3_prep()
396 1
397 call feedkeys(":g/the\<c-l>/d\<cr>", 'tx')
398 call assert_equal(' 3 the theother', getline(2))
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200399 undo
400 call feedkeys(":global/the\<c-l>/d\<cr>", 'tx')
401 call assert_equal(' 3 the theother', getline(2))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200402
Bram Moolenaar976b8472018-08-12 15:49:47 +0200403 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200404endfunc
405
406func Test_search_cmdline3v()
407 if !exists('+incsearch')
408 return
409 endif
410 call Cmdline3_prep()
411 1
412 call feedkeys(":v/the\<c-l>/d\<cr>", 'tx')
413 call assert_equal(1, line('$'))
414 call assert_equal(' 2 the~e', getline(1))
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200415 undo
416 call feedkeys(":vglobal/the\<c-l>/d\<cr>", 'tx')
417 call assert_equal(1, line('$'))
418 call assert_equal(' 2 the~e', getline(1))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200419
Bram Moolenaar976b8472018-08-12 15:49:47 +0200420 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200421endfunc
422
Bram Moolenaarda5116d2017-07-01 23:11:17 +0200423func Test_search_cmdline4()
424 if !exists('+incsearch')
425 return
426 endif
427 " need to disable char_avail,
428 " so that expansion of commandline works
429 call test_override("char_avail", 1)
430 new
431 call setline(1, [' 1 the first', ' 2 the second', ' 3 the third'])
432 set incsearch
433 $
434 call feedkeys("?the\<c-g>\<cr>", 'tx')
435 call assert_equal(' 3 the third', getline('.'))
436 $
437 call feedkeys("?the\<c-g>\<c-g>\<cr>", 'tx')
438 call assert_equal(' 1 the first', getline('.'))
439 $
440 call feedkeys("?the\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
441 call assert_equal(' 2 the second', getline('.'))
442 $
443 call feedkeys("?the\<c-t>\<cr>", 'tx')
444 call assert_equal(' 1 the first', getline('.'))
445 $
446 call feedkeys("?the\<c-t>\<c-t>\<cr>", 'tx')
447 call assert_equal(' 3 the third', getline('.'))
448 $
449 call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
450 call assert_equal(' 2 the second', getline('.'))
451 " clean up
452 set noincsearch
453 call test_override("char_avail", 0)
454 bw!
455endfunc
Bram Moolenaardb510072017-09-28 21:52:17 +0200456
Bram Moolenaarf8e8c062017-10-22 14:44:17 +0200457func Test_search_cmdline5()
458 if !exists('+incsearch')
459 return
460 endif
461 " Do not call test_override("char_avail", 1) so that <C-g> and <C-t> work
462 " regardless char_avail.
463 new
464 call setline(1, [' 1 the first', ' 2 the second', ' 3 the third'])
465 set incsearch
466 1
467 call feedkeys("/the\<c-g>\<c-g>\<cr>", 'tx')
468 call assert_equal(' 3 the third', getline('.'))
469 $
470 call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
471 call assert_equal(' 2 the second', getline('.'))
472 " clean up
473 set noincsearch
474 bw!
475endfunc
476
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100477func Test_search_cmdline6()
478 " Test that consecutive matches
479 " are caught by <c-g>/<c-t>
480 if !exists('+incsearch')
481 return
482 endif
483 " need to disable char_avail,
484 " so that expansion of commandline works
485 call test_override("char_avail", 1)
486 new
487 call setline(1, [' bbvimb', ''])
488 set incsearch
489 " first match
490 norm! gg0
491 call feedkeys("/b\<cr>", 'tx')
492 call assert_equal([0,1,2,0], getpos('.'))
493 " second match
494 norm! gg0
495 call feedkeys("/b\<c-g>\<cr>", 'tx')
496 call assert_equal([0,1,3,0], getpos('.'))
497 " third match
498 norm! gg0
499 call feedkeys("/b\<c-g>\<c-g>\<cr>", 'tx')
500 call assert_equal([0,1,7,0], getpos('.'))
501 " first match again
502 norm! gg0
503 call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
504 call assert_equal([0,1,2,0], getpos('.'))
505 set nowrapscan
506 " last match
507 norm! gg0
508 call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
509 call assert_equal([0,1,7,0], getpos('.'))
510 " clean up
511 set wrapscan&vim
512 set noincsearch
513 call test_override("char_avail", 0)
514 bw!
515endfunc
516
517func Test_search_cmdline7()
518 " Test that an pressing <c-g> in an empty command line
519 " does not move the cursor
520 if !exists('+incsearch')
521 return
522 endif
523 " need to disable char_avail,
524 " so that expansion of commandline works
525 call test_override("char_avail", 1)
526 new
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200527 let @/ = 'b'
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100528 call setline(1, [' bbvimb', ''])
529 set incsearch
530 " first match
531 norm! gg0
532 " moves to next match of previous search pattern, just like /<cr>
533 call feedkeys("/\<c-g>\<cr>", 'tx')
534 call assert_equal([0,1,2,0], getpos('.'))
535 " moves to next match of previous search pattern, just like /<cr>
536 call feedkeys("/\<cr>", 'tx')
537 call assert_equal([0,1,3,0], getpos('.'))
538 " moves to next match of previous search pattern, just like /<cr>
539 call feedkeys("/\<c-t>\<cr>", 'tx')
540 call assert_equal([0,1,7,0], getpos('.'))
Bram Moolenaard0480092017-11-16 22:20:39 +0100541
542 " using an offset uses the last search pattern
543 call cursor(1, 1)
544 call setline(1, ['1 bbvimb', ' 2 bbvimb'])
545 let @/ = 'b'
546 call feedkeys("//e\<c-g>\<cr>", 'tx')
547 call assert_equal('1 bbvimb', getline('.'))
548 call assert_equal(4, col('.'))
549
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100550 set noincsearch
551 call test_override("char_avail", 0)
552 bw!
553endfunc
554
555func Test_search_cmdline8()
556 " Highlighting is cleared in all windows
557 " since hls applies to all windows
558 if !exists('+incsearch') || !has('terminal') || has('gui_running') || winwidth(0) < 30
559 return
560 endif
561 if has("win32")
562 throw "Skipped: Bug with sending <ESC> to terminal window not fixed yet"
563 endif
564 let h = winheight(0)
565 if h < 3
566 return
567 endif
568 " Prepare buffer text
569 let lines = ['abb vim vim vi', 'vimvivim']
570 call writefile(lines, 'Xsearch.txt')
Bram Moolenaar13deab82017-11-04 18:48:43 +0100571 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100572
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200573 call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100574
Bram Moolenaar13deab82017-11-04 18:48:43 +0100575 call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
576 call term_sendkeys(buf, ":14vsp\<cr>")
577 call term_sendkeys(buf, "/vim\<cr>")
578 call term_sendkeys(buf, "/b\<esc>")
579 call term_sendkeys(buf, "gg0")
580 call term_wait(buf, 500)
581 let screen_line = term_scrape(buf, 1)
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100582 let [a0,a1,a2,a3] = [screen_line[3].attr, screen_line[4].attr,
583 \ screen_line[18].attr, screen_line[19].attr]
584 call assert_notequal(a0, a1)
585 call assert_notequal(a0, a3)
586 call assert_notequal(a1, a2)
587 call assert_equal(a0, a2)
588 call assert_equal(a1, a3)
589 " clean up
590 call delete('Xsearch.txt')
591
592 bwipe!
593endfunc
594
Bram Moolenaardb510072017-09-28 21:52:17 +0200595" Tests for regexp with various magic settings
596func Test_search_regexp()
597 enew!
598
599 put ='1 a aa abb abbccc'
600 exe 'normal! /a*b\{2}c\+/e' . "\<CR>"
601 call assert_equal([0, 2, 17, 0], getpos('.'))
602
603 put ='2 d dd dee deefff'
604 exe 'normal! /\Md\*e\{2}f\+/e' . "\<CR>"
605 call assert_equal([0, 3, 17, 0], getpos('.'))
606
607 set nomagic
608 put ='3 g gg ghh ghhiii'
609 exe 'normal! /g\*h\{2}i\+/e' . "\<CR>"
610 call assert_equal([0, 4, 17, 0], getpos('.'))
611
612 put ='4 j jj jkk jkklll'
613 exe 'normal! /\mj*k\{2}l\+/e' . "\<CR>"
614 call assert_equal([0, 5, 17, 0], getpos('.'))
615
616 put ='5 m mm mnn mnnooo'
617 exe 'normal! /\vm*n{2}o+/e' . "\<CR>"
618 call assert_equal([0, 6, 17, 0], getpos('.'))
619
620 put ='6 x ^aa$ x'
621 exe 'normal! /\V^aa$' . "\<CR>"
622 call assert_equal([0, 7, 5, 0], getpos('.'))
623
624 set magic
625 put ='7 (a)(b) abbaa'
626 exe 'normal! /\v(a)(b)\2\1\1/e' . "\<CR>"
627 call assert_equal([0, 8, 14, 0], getpos('.'))
628
629 put ='8 axx [ab]xx'
630 exe 'normal! /\V[ab]\(\[xy]\)\1' . "\<CR>"
631 call assert_equal([0, 9, 7, 0], getpos('.'))
632
633 set undolevels=100
634 put ='9 foobar'
635 put =''
636 exe "normal! a\<C-G>u\<Esc>"
637 normal G
638 exe 'normal! dv?bar?' . "\<CR>"
639 call assert_equal('9 foo', getline('.'))
640 call assert_equal([0, 10, 5, 0], getpos('.'))
641 call assert_equal(10, line('$'))
642 normal u
643 call assert_equal('9 foobar', getline('.'))
644 call assert_equal([0, 10, 6, 0], getpos('.'))
645 call assert_equal(11, line('$'))
646
647 set undolevels&
648 enew!
649endfunc
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100650
651func Test_search_cmdline_incsearch_highlight()
652 if !exists('+incsearch')
653 return
654 endif
655 set incsearch hlsearch
656 " need to disable char_avail,
657 " so that expansion of commandline works
658 call test_override("char_avail", 1)
659 new
660 call setline(1, ['aaa 1 the first', ' 2 the second', ' 3 the third'])
661
662 1
663 call feedkeys("/second\<cr>", 'tx')
664 call assert_equal('second', @/)
665 call assert_equal(' 2 the second', getline('.'))
666
667 " Canceling search won't change @/
668 1
669 let @/ = 'last pattern'
670 call feedkeys("/third\<C-c>", 'tx')
671 call assert_equal('last pattern', @/)
672 call feedkeys("/third\<Esc>", 'tx')
673 call assert_equal('last pattern', @/)
674 call feedkeys("/3\<bs>\<bs>", 'tx')
675 call assert_equal('last pattern', @/)
676 call feedkeys("/third\<c-g>\<c-t>\<Esc>", 'tx')
677 call assert_equal('last pattern', @/)
678
679 " clean up
680 set noincsearch nohlsearch
681 bw!
682endfunc
683
684func Test_search_cmdline_incsearch_highlight_attr()
685 if !exists('+incsearch') || !has('terminal') || has('gui_running')
686 return
687 endif
688 let h = winheight(0)
689 if h < 3
690 return
691 endif
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100692
693 " Prepare buffer text
Bram Moolenaar13deab82017-11-04 18:48:43 +0100694 let lines = ['abb vim vim vi', 'vimvivim']
695 call writefile(lines, 'Xsearch.txt')
696 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
697
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200698 call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
Bram Moolenaarb50773c2018-01-30 22:31:19 +0100699 " wait for vim to complete initialization
700 call term_wait(buf)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100701
702 " Get attr of normal(a0), incsearch(a1), hlsearch(a2) highlight
Bram Moolenaar13deab82017-11-04 18:48:43 +0100703 call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
704 call term_sendkeys(buf, '/b')
705 call term_wait(buf, 200)
706 let screen_line1 = term_scrape(buf, 1)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100707 call assert_true(len(screen_line1) > 2)
708 " a0: attr_normal
709 let a0 = screen_line1[0].attr
710 " a1: attr_incsearch
711 let a1 = screen_line1[1].attr
712 " a2: attr_hlsearch
713 let a2 = screen_line1[2].attr
714 call assert_notequal(a0, a1)
715 call assert_notequal(a0, a2)
716 call assert_notequal(a1, a2)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100717 call term_sendkeys(buf, "\<cr>gg0")
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100718
719 " Test incremental highlight search
Bram Moolenaar13deab82017-11-04 18:48:43 +0100720 call term_sendkeys(buf, "/vim")
721 call term_wait(buf, 200)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100722 " Buffer:
723 " abb vim vim vi
724 " vimvivim
725 " Search: /vim
726 let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a2,a2,a2,a0,a0,a0]
727 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100728 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
729 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100730
731 " Test <C-g>
Bram Moolenaar13deab82017-11-04 18:48:43 +0100732 call term_sendkeys(buf, "\<C-g>\<C-g>")
733 call term_wait(buf, 200)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100734 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
735 let attr_line2 = [a1,a1,a1,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100736 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
737 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100738
739 " Test <C-t>
Bram Moolenaar13deab82017-11-04 18:48:43 +0100740 call term_sendkeys(buf, "\<C-t>")
741 call term_wait(buf, 200)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100742 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a1,a1,a1,a0,a0,a0]
743 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100744 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
745 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100746
747 " Type Enter and a1(incsearch highlight) should become a2(hlsearch highlight)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100748 call term_sendkeys(buf, "\<cr>")
749 call term_wait(buf, 200)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100750 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
751 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100752 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
753 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100754
755 " Test nohlsearch. a2(hlsearch highlight) should become a0(normal highlight)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100756 call term_sendkeys(buf, ":1\<cr>")
757 call term_sendkeys(buf, ":set nohlsearch\<cr>")
758 call term_sendkeys(buf, "/vim")
759 call term_wait(buf, 200)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100760 let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a0,a0,a0,a0,a0,a0]
761 let attr_line2 = [a0,a0,a0,a0,a0,a0,a0,a0]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100762 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
763 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100764 call delete('Xsearch.txt')
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100765
Bram Moolenaarb94340c2017-11-02 16:16:31 +0100766 call delete('Xsearch.txt')
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100767 bwipe!
768endfunc
Bram Moolenaarf45938c2017-11-02 15:59:57 +0100769
Bram Moolenaar9d34d902018-04-27 22:18:12 +0200770func Test_incsearch_scrolling()
771 if !CanRunVimInTerminal()
772 return
773 endif
774 call assert_equal(0, &scrolloff)
775 call writefile([
776 \ 'let dots = repeat(".", 120)',
777 \ 'set incsearch cmdheight=2 scrolloff=0',
778 \ 'call setline(1, [dots, dots, dots, "", "target", dots, dots])',
779 \ 'normal gg',
780 \ 'redraw',
781 \ ], 'Xscript')
782 let buf = RunVimInTerminal('-S Xscript', {'rows': 9, 'cols': 70})
783 " Need to send one key at a time to force a redraw
784 call term_sendkeys(buf, '/')
785 sleep 100m
786 call term_sendkeys(buf, 't')
787 sleep 100m
788 call term_sendkeys(buf, 'a')
789 sleep 100m
790 call term_sendkeys(buf, 'r')
791 sleep 100m
792 call term_sendkeys(buf, 'g')
793 call VerifyScreenDump(buf, 'Test_incsearch_scrolling_01', {})
794
795 call term_sendkeys(buf, "\<Esc>")
796 call StopVimInTerminal(buf)
797 call delete('Xscript')
798endfunc
799
Bram Moolenaar976b8472018-08-12 15:49:47 +0200800func Test_incsearch_substitute()
801 if !exists('+incsearch')
802 return
803 endif
804 call test_override("char_avail", 1)
805 new
806 set incsearch
807 for n in range(1, 10)
808 call setline(n, 'foo ' . n)
809 endfor
810 4
811 call feedkeys(":.,.+2s/foo\<BS>o\<BS>o/xxx\<cr>", 'tx')
812 call assert_equal('foo 3', getline(3))
813 call assert_equal('xxx 4', getline(4))
814 call assert_equal('xxx 5', getline(5))
815 call assert_equal('xxx 6', getline(6))
816 call assert_equal('foo 7', getline(7))
817
818 call Incsearch_cleanup()
819endfunc
820
Bram Moolenaar164251f2018-08-12 16:26:58 +0200821" Similar to Test_incsearch_substitute() but with a screendump halfway.
822func Test_incsearch_substitute_dump()
823 if !exists('+incsearch')
824 return
825 endif
826 if !CanRunVimInTerminal()
827 return
828 endif
829 call writefile([
830 \ 'set incsearch hlsearch scrolloff=0',
831 \ 'for n in range(1, 10)',
832 \ ' call setline(n, "foo " . n)',
833 \ 'endfor',
834 \ '3',
835 \ ], 'Xis_subst_script')
836 let buf = RunVimInTerminal('-S Xis_subst_script', {'rows': 9, 'cols': 70})
837 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
838 " the 'ambiwidth' check.
839 sleep 100m
840
841 " Need to send one key at a time to force a redraw.
842 call term_sendkeys(buf, ':.,.+2s/')
843 sleep 100m
844 call term_sendkeys(buf, 'f')
845 sleep 100m
846 call term_sendkeys(buf, 'o')
847 sleep 100m
848 call term_sendkeys(buf, 'o')
849 call VerifyScreenDump(buf, 'Test_incsearch_substitute_01', {})
850
851 call term_sendkeys(buf, "\<Esc>")
852 call StopVimInTerminal(buf)
853 call delete('Xis_subst_script')
854endfunc
855
Bram Moolenaarf45938c2017-11-02 15:59:57 +0100856func Test_search_undefined_behaviour()
857 if !has("terminal")
858 return
859 endif
860 let h = winheight(0)
861 if h < 3
862 return
863 endif
864 " did cause an undefined left shift
865 let g:buf = term_start([GetVimProg(), '--clean', '-e', '-s', '-c', 'call search(getline("."))', 'samples/test000'], {'term_rows': 3})
866 call assert_equal([''], getline(1, '$'))
867 call term_sendkeys(g:buf, ":qa!\<cr>")
868 bwipe!
869endfunc
Bram Moolenaar2973daa2017-11-02 23:15:40 +0100870
871func Test_search_undefined_behaviour2()
872 call search("\%UC0000000")
873endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +0100874
875" Test for search('multi-byte char', 'bce')
876func Test_search_multibyte()
877 if !has('multi_byte')
878 return
879 endif
880 let save_enc = &encoding
881 set encoding=utf8
882 enew!
883 call append('$', '')
884 call cursor(2, 1)
885 call assert_equal(2, search('', 'bce', line('.')))
886 enew!
887 let &encoding = save_enc
888endfunc
Bram Moolenaar890dd052017-12-16 19:59:37 +0100889
890" This was causing E874. Also causes an invalid read?
891func Test_look_behind()
892 new
893 call setline(1, '0\|\&\n\@<=')
894 call search(getline("."))
895 bwipe!
896endfunc
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +0100897
898func Test_search_sentence()
899 new
900 " this used to cause a crash
Bram Moolenaar1bd999f2017-12-19 22:25:40 +0100901 call assert_fails("/\\%')", 'E486')
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +0100902 call assert_fails("/", 'E486')
Bram Moolenaar1bd999f2017-12-19 22:25:40 +0100903 /\%'(
904 /
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +0100905endfunc