blob: 2765c8cbf81efe2985619d774ad8c8d5e3022093 [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 Moolenaar167ae422018-08-14 21:32:21 +0200387 undo
388 call feedkeys(":%smagic/the.e/xxx\<cr>", 'tx')
389 call assert_equal(' 2 xxx', getline('.'))
390 undo
391 call assert_fails(":%snomagic/the.e/xxx\<cr>", 'E486')
392 "
393 call feedkeys(":%snomagic/the\\.e/xxx\<cr>", 'tx')
394 call assert_equal(' 2 xxx', getline('.'))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200395
Bram Moolenaar976b8472018-08-12 15:49:47 +0200396 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200397endfunc
398
399func Test_search_cmdline3g()
400 if !exists('+incsearch')
401 return
402 endif
403 call Cmdline3_prep()
404 1
405 call feedkeys(":g/the\<c-l>/d\<cr>", 'tx')
406 call assert_equal(' 3 the theother', getline(2))
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200407 undo
408 call feedkeys(":global/the\<c-l>/d\<cr>", 'tx')
409 call assert_equal(' 3 the theother', getline(2))
Bram Moolenaardef7b1d2018-08-13 22:54:35 +0200410 undo
411 call feedkeys(":g!/the\<c-l>/d\<cr>", 'tx')
412 call assert_equal(1, line('$'))
413 call assert_equal(' 2 the~e', getline(1))
414 undo
415 call feedkeys(":global!/the\<c-l>/d\<cr>", 'tx')
416 call assert_equal(1, line('$'))
417 call assert_equal(' 2 the~e', getline(1))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200418
Bram Moolenaar976b8472018-08-12 15:49:47 +0200419 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200420endfunc
421
422func Test_search_cmdline3v()
423 if !exists('+incsearch')
424 return
425 endif
426 call Cmdline3_prep()
427 1
428 call feedkeys(":v/the\<c-l>/d\<cr>", 'tx')
429 call assert_equal(1, line('$'))
430 call assert_equal(' 2 the~e', getline(1))
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200431 undo
432 call feedkeys(":vglobal/the\<c-l>/d\<cr>", 'tx')
433 call assert_equal(1, line('$'))
434 call assert_equal(' 2 the~e', getline(1))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200435
Bram Moolenaar976b8472018-08-12 15:49:47 +0200436 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200437endfunc
438
Bram Moolenaarda5116d2017-07-01 23:11:17 +0200439func Test_search_cmdline4()
440 if !exists('+incsearch')
441 return
442 endif
443 " need to disable char_avail,
444 " so that expansion of commandline works
445 call test_override("char_avail", 1)
446 new
447 call setline(1, [' 1 the first', ' 2 the second', ' 3 the third'])
448 set incsearch
449 $
450 call feedkeys("?the\<c-g>\<cr>", 'tx')
451 call assert_equal(' 3 the third', getline('.'))
452 $
453 call feedkeys("?the\<c-g>\<c-g>\<cr>", 'tx')
454 call assert_equal(' 1 the first', getline('.'))
455 $
456 call feedkeys("?the\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
457 call assert_equal(' 2 the second', getline('.'))
458 $
459 call feedkeys("?the\<c-t>\<cr>", 'tx')
460 call assert_equal(' 1 the first', getline('.'))
461 $
462 call feedkeys("?the\<c-t>\<c-t>\<cr>", 'tx')
463 call assert_equal(' 3 the third', getline('.'))
464 $
465 call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
466 call assert_equal(' 2 the second', getline('.'))
467 " clean up
468 set noincsearch
469 call test_override("char_avail", 0)
470 bw!
471endfunc
Bram Moolenaardb510072017-09-28 21:52:17 +0200472
Bram Moolenaarf8e8c062017-10-22 14:44:17 +0200473func Test_search_cmdline5()
474 if !exists('+incsearch')
475 return
476 endif
477 " Do not call test_override("char_avail", 1) so that <C-g> and <C-t> work
478 " regardless char_avail.
479 new
480 call setline(1, [' 1 the first', ' 2 the second', ' 3 the third'])
481 set incsearch
482 1
483 call feedkeys("/the\<c-g>\<c-g>\<cr>", 'tx')
484 call assert_equal(' 3 the third', getline('.'))
485 $
486 call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
487 call assert_equal(' 2 the second', getline('.'))
488 " clean up
489 set noincsearch
490 bw!
491endfunc
492
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100493func Test_search_cmdline6()
494 " Test that consecutive matches
495 " are caught by <c-g>/<c-t>
496 if !exists('+incsearch')
497 return
498 endif
499 " need to disable char_avail,
500 " so that expansion of commandline works
501 call test_override("char_avail", 1)
502 new
503 call setline(1, [' bbvimb', ''])
504 set incsearch
505 " first match
506 norm! gg0
507 call feedkeys("/b\<cr>", 'tx')
508 call assert_equal([0,1,2,0], getpos('.'))
509 " second match
510 norm! gg0
511 call feedkeys("/b\<c-g>\<cr>", 'tx')
512 call assert_equal([0,1,3,0], getpos('.'))
513 " third match
514 norm! gg0
515 call feedkeys("/b\<c-g>\<c-g>\<cr>", 'tx')
516 call assert_equal([0,1,7,0], getpos('.'))
517 " first match again
518 norm! gg0
519 call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
520 call assert_equal([0,1,2,0], getpos('.'))
521 set nowrapscan
522 " last match
523 norm! gg0
524 call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
525 call assert_equal([0,1,7,0], getpos('.'))
526 " clean up
527 set wrapscan&vim
528 set noincsearch
529 call test_override("char_avail", 0)
530 bw!
531endfunc
532
533func Test_search_cmdline7()
534 " Test that an pressing <c-g> in an empty command line
535 " does not move the cursor
536 if !exists('+incsearch')
537 return
538 endif
539 " need to disable char_avail,
540 " so that expansion of commandline works
541 call test_override("char_avail", 1)
542 new
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200543 let @/ = 'b'
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100544 call setline(1, [' bbvimb', ''])
545 set incsearch
546 " first match
547 norm! gg0
548 " moves to next match of previous search pattern, just like /<cr>
549 call feedkeys("/\<c-g>\<cr>", 'tx')
550 call assert_equal([0,1,2,0], getpos('.'))
551 " moves to next match of previous search pattern, just like /<cr>
552 call feedkeys("/\<cr>", 'tx')
553 call assert_equal([0,1,3,0], getpos('.'))
554 " moves to next match of previous search pattern, just like /<cr>
555 call feedkeys("/\<c-t>\<cr>", 'tx')
556 call assert_equal([0,1,7,0], getpos('.'))
Bram Moolenaard0480092017-11-16 22:20:39 +0100557
558 " using an offset uses the last search pattern
559 call cursor(1, 1)
560 call setline(1, ['1 bbvimb', ' 2 bbvimb'])
561 let @/ = 'b'
562 call feedkeys("//e\<c-g>\<cr>", 'tx')
563 call assert_equal('1 bbvimb', getline('.'))
564 call assert_equal(4, col('.'))
565
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100566 set noincsearch
567 call test_override("char_avail", 0)
568 bw!
569endfunc
570
571func Test_search_cmdline8()
572 " Highlighting is cleared in all windows
573 " since hls applies to all windows
574 if !exists('+incsearch') || !has('terminal') || has('gui_running') || winwidth(0) < 30
575 return
576 endif
577 if has("win32")
578 throw "Skipped: Bug with sending <ESC> to terminal window not fixed yet"
579 endif
580 let h = winheight(0)
581 if h < 3
582 return
583 endif
584 " Prepare buffer text
585 let lines = ['abb vim vim vi', 'vimvivim']
586 call writefile(lines, 'Xsearch.txt')
Bram Moolenaar13deab82017-11-04 18:48:43 +0100587 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100588
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200589 call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100590
Bram Moolenaar13deab82017-11-04 18:48:43 +0100591 call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
592 call term_sendkeys(buf, ":14vsp\<cr>")
593 call term_sendkeys(buf, "/vim\<cr>")
594 call term_sendkeys(buf, "/b\<esc>")
595 call term_sendkeys(buf, "gg0")
596 call term_wait(buf, 500)
597 let screen_line = term_scrape(buf, 1)
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100598 let [a0,a1,a2,a3] = [screen_line[3].attr, screen_line[4].attr,
599 \ screen_line[18].attr, screen_line[19].attr]
600 call assert_notequal(a0, a1)
601 call assert_notequal(a0, a3)
602 call assert_notequal(a1, a2)
603 call assert_equal(a0, a2)
604 call assert_equal(a1, a3)
605 " clean up
606 call delete('Xsearch.txt')
607
608 bwipe!
609endfunc
610
Bram Moolenaardb510072017-09-28 21:52:17 +0200611" Tests for regexp with various magic settings
612func Test_search_regexp()
613 enew!
614
615 put ='1 a aa abb abbccc'
616 exe 'normal! /a*b\{2}c\+/e' . "\<CR>"
617 call assert_equal([0, 2, 17, 0], getpos('.'))
618
619 put ='2 d dd dee deefff'
620 exe 'normal! /\Md\*e\{2}f\+/e' . "\<CR>"
621 call assert_equal([0, 3, 17, 0], getpos('.'))
622
623 set nomagic
624 put ='3 g gg ghh ghhiii'
625 exe 'normal! /g\*h\{2}i\+/e' . "\<CR>"
626 call assert_equal([0, 4, 17, 0], getpos('.'))
627
628 put ='4 j jj jkk jkklll'
629 exe 'normal! /\mj*k\{2}l\+/e' . "\<CR>"
630 call assert_equal([0, 5, 17, 0], getpos('.'))
631
632 put ='5 m mm mnn mnnooo'
633 exe 'normal! /\vm*n{2}o+/e' . "\<CR>"
634 call assert_equal([0, 6, 17, 0], getpos('.'))
635
636 put ='6 x ^aa$ x'
637 exe 'normal! /\V^aa$' . "\<CR>"
638 call assert_equal([0, 7, 5, 0], getpos('.'))
639
640 set magic
641 put ='7 (a)(b) abbaa'
642 exe 'normal! /\v(a)(b)\2\1\1/e' . "\<CR>"
643 call assert_equal([0, 8, 14, 0], getpos('.'))
644
645 put ='8 axx [ab]xx'
646 exe 'normal! /\V[ab]\(\[xy]\)\1' . "\<CR>"
647 call assert_equal([0, 9, 7, 0], getpos('.'))
648
649 set undolevels=100
650 put ='9 foobar'
651 put =''
652 exe "normal! a\<C-G>u\<Esc>"
653 normal G
654 exe 'normal! dv?bar?' . "\<CR>"
655 call assert_equal('9 foo', getline('.'))
656 call assert_equal([0, 10, 5, 0], getpos('.'))
657 call assert_equal(10, line('$'))
658 normal u
659 call assert_equal('9 foobar', getline('.'))
660 call assert_equal([0, 10, 6, 0], getpos('.'))
661 call assert_equal(11, line('$'))
662
663 set undolevels&
664 enew!
665endfunc
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100666
667func Test_search_cmdline_incsearch_highlight()
668 if !exists('+incsearch')
669 return
670 endif
671 set incsearch hlsearch
672 " need to disable char_avail,
673 " so that expansion of commandline works
674 call test_override("char_avail", 1)
675 new
676 call setline(1, ['aaa 1 the first', ' 2 the second', ' 3 the third'])
677
678 1
679 call feedkeys("/second\<cr>", 'tx')
680 call assert_equal('second', @/)
681 call assert_equal(' 2 the second', getline('.'))
682
683 " Canceling search won't change @/
684 1
685 let @/ = 'last pattern'
686 call feedkeys("/third\<C-c>", 'tx')
687 call assert_equal('last pattern', @/)
688 call feedkeys("/third\<Esc>", 'tx')
689 call assert_equal('last pattern', @/)
690 call feedkeys("/3\<bs>\<bs>", 'tx')
691 call assert_equal('last pattern', @/)
692 call feedkeys("/third\<c-g>\<c-t>\<Esc>", 'tx')
693 call assert_equal('last pattern', @/)
694
695 " clean up
696 set noincsearch nohlsearch
697 bw!
698endfunc
699
700func Test_search_cmdline_incsearch_highlight_attr()
701 if !exists('+incsearch') || !has('terminal') || has('gui_running')
702 return
703 endif
704 let h = winheight(0)
705 if h < 3
706 return
707 endif
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100708
709 " Prepare buffer text
Bram Moolenaar13deab82017-11-04 18:48:43 +0100710 let lines = ['abb vim vim vi', 'vimvivim']
711 call writefile(lines, 'Xsearch.txt')
712 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
713
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200714 call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
Bram Moolenaarb50773c2018-01-30 22:31:19 +0100715 " wait for vim to complete initialization
716 call term_wait(buf)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100717
718 " Get attr of normal(a0), incsearch(a1), hlsearch(a2) highlight
Bram Moolenaar13deab82017-11-04 18:48:43 +0100719 call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
720 call term_sendkeys(buf, '/b')
721 call term_wait(buf, 200)
722 let screen_line1 = term_scrape(buf, 1)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100723 call assert_true(len(screen_line1) > 2)
724 " a0: attr_normal
725 let a0 = screen_line1[0].attr
726 " a1: attr_incsearch
727 let a1 = screen_line1[1].attr
728 " a2: attr_hlsearch
729 let a2 = screen_line1[2].attr
730 call assert_notequal(a0, a1)
731 call assert_notequal(a0, a2)
732 call assert_notequal(a1, a2)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100733 call term_sendkeys(buf, "\<cr>gg0")
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100734
735 " Test incremental highlight search
Bram Moolenaar13deab82017-11-04 18:48:43 +0100736 call term_sendkeys(buf, "/vim")
737 call term_wait(buf, 200)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100738 " Buffer:
739 " abb vim vim vi
740 " vimvivim
741 " Search: /vim
742 let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a2,a2,a2,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 " Test <C-g>
Bram Moolenaar13deab82017-11-04 18:48:43 +0100748 call term_sendkeys(buf, "\<C-g>\<C-g>")
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 = [a1,a1,a1,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 <C-t>
Bram Moolenaar13deab82017-11-04 18:48:43 +0100756 call term_sendkeys(buf, "\<C-t>")
757 call term_wait(buf, 200)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100758 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a1,a1,a1,a0,a0,a0]
759 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100760 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
761 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100762
763 " Type Enter and a1(incsearch highlight) should become a2(hlsearch highlight)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100764 call term_sendkeys(buf, "\<cr>")
765 call term_wait(buf, 200)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100766 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
767 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100768 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
769 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100770
771 " Test nohlsearch. a2(hlsearch highlight) should become a0(normal highlight)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100772 call term_sendkeys(buf, ":1\<cr>")
773 call term_sendkeys(buf, ":set nohlsearch\<cr>")
774 call term_sendkeys(buf, "/vim")
775 call term_wait(buf, 200)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100776 let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a0,a0,a0,a0,a0,a0]
777 let attr_line2 = [a0,a0,a0,a0,a0,a0,a0,a0]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100778 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
779 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100780 call delete('Xsearch.txt')
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100781
Bram Moolenaarb94340c2017-11-02 16:16:31 +0100782 call delete('Xsearch.txt')
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100783 bwipe!
784endfunc
Bram Moolenaarf45938c2017-11-02 15:59:57 +0100785
Bram Moolenaar548e5982018-12-26 21:45:00 +0100786func Test_incsearch_cmdline_modifier()
787 if !exists('+incsearch')
788 return
789 endif
790 call test_override("char_avail", 1)
791 new
792 call setline(1, ['foo'])
793 set incsearch
794 " Test that error E14 does not occur in parsing command modifier.
795 call feedkeys("V:tab", 'tx')
796
797 call Incsearch_cleanup()
798endfunc
799
Bram Moolenaar9d34d902018-04-27 22:18:12 +0200800func Test_incsearch_scrolling()
801 if !CanRunVimInTerminal()
Bram Moolenaar5d30ff12019-06-06 16:12:12 +0200802 throw 'Skipped: cannot make screendumps'
Bram Moolenaar9d34d902018-04-27 22:18:12 +0200803 endif
804 call assert_equal(0, &scrolloff)
805 call writefile([
806 \ 'let dots = repeat(".", 120)',
807 \ 'set incsearch cmdheight=2 scrolloff=0',
808 \ 'call setline(1, [dots, dots, dots, "", "target", dots, dots])',
809 \ 'normal gg',
810 \ 'redraw',
811 \ ], 'Xscript')
812 let buf = RunVimInTerminal('-S Xscript', {'rows': 9, 'cols': 70})
813 " Need to send one key at a time to force a redraw
814 call term_sendkeys(buf, '/')
815 sleep 100m
816 call term_sendkeys(buf, 't')
817 sleep 100m
818 call term_sendkeys(buf, 'a')
819 sleep 100m
820 call term_sendkeys(buf, 'r')
821 sleep 100m
822 call term_sendkeys(buf, 'g')
823 call VerifyScreenDump(buf, 'Test_incsearch_scrolling_01', {})
824
825 call term_sendkeys(buf, "\<Esc>")
826 call StopVimInTerminal(buf)
827 call delete('Xscript')
828endfunc
829
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200830func Test_incsearch_search_dump()
831 if !exists('+incsearch')
832 return
833 endif
834 if !CanRunVimInTerminal()
Bram Moolenaar5d30ff12019-06-06 16:12:12 +0200835 throw 'Skipped: cannot make screendumps'
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200836 endif
837 call writefile([
838 \ 'set incsearch hlsearch scrolloff=0',
839 \ 'for n in range(1, 8)',
840 \ ' call setline(n, "foo " . n)',
841 \ 'endfor',
842 \ '3',
843 \ ], 'Xis_search_script')
844 let buf = RunVimInTerminal('-S Xis_search_script', {'rows': 9, 'cols': 70})
845 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
846 " the 'ambiwidth' check.
847 sleep 100m
848
849 " Need to send one key at a time to force a redraw.
850 call term_sendkeys(buf, '/fo')
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200851 call VerifyScreenDump(buf, 'Test_incsearch_search_01', {})
852 call term_sendkeys(buf, "\<Esc>")
853 sleep 100m
854
855 call term_sendkeys(buf, '/\v')
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200856 call VerifyScreenDump(buf, 'Test_incsearch_search_02', {})
857 call term_sendkeys(buf, "\<Esc>")
858
859 call StopVimInTerminal(buf)
860 call delete('Xis_search_script')
861endfunc
862
Bram Moolenaar976b8472018-08-12 15:49:47 +0200863func Test_incsearch_substitute()
864 if !exists('+incsearch')
865 return
866 endif
867 call test_override("char_avail", 1)
868 new
869 set incsearch
870 for n in range(1, 10)
871 call setline(n, 'foo ' . n)
872 endfor
873 4
874 call feedkeys(":.,.+2s/foo\<BS>o\<BS>o/xxx\<cr>", 'tx')
875 call assert_equal('foo 3', getline(3))
876 call assert_equal('xxx 4', getline(4))
877 call assert_equal('xxx 5', getline(5))
878 call assert_equal('xxx 6', getline(6))
879 call assert_equal('foo 7', getline(7))
880
881 call Incsearch_cleanup()
882endfunc
883
Bram Moolenaar164251f2018-08-12 16:26:58 +0200884" Similar to Test_incsearch_substitute() but with a screendump halfway.
885func Test_incsearch_substitute_dump()
886 if !exists('+incsearch')
887 return
888 endif
889 if !CanRunVimInTerminal()
Bram Moolenaar5d30ff12019-06-06 16:12:12 +0200890 throw 'Skipped: cannot make screendumps'
Bram Moolenaar164251f2018-08-12 16:26:58 +0200891 endif
892 call writefile([
893 \ 'set incsearch hlsearch scrolloff=0',
894 \ 'for n in range(1, 10)',
895 \ ' call setline(n, "foo " . n)',
896 \ 'endfor',
Bram Moolenaar2f6a3462018-08-14 18:16:52 +0200897 \ 'call setline(11, "bar 11")',
Bram Moolenaar164251f2018-08-12 16:26:58 +0200898 \ '3',
899 \ ], 'Xis_subst_script')
900 let buf = RunVimInTerminal('-S Xis_subst_script', {'rows': 9, 'cols': 70})
901 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
902 " the 'ambiwidth' check.
903 sleep 100m
904
905 " Need to send one key at a time to force a redraw.
Bram Moolenaarc7f08b72018-08-12 17:39:14 +0200906 " Select three lines at the cursor with typed pattern.
Bram Moolenaar164251f2018-08-12 16:26:58 +0200907 call term_sendkeys(buf, ':.,.+2s/')
908 sleep 100m
909 call term_sendkeys(buf, 'f')
910 sleep 100m
911 call term_sendkeys(buf, 'o')
912 sleep 100m
913 call term_sendkeys(buf, 'o')
914 call VerifyScreenDump(buf, 'Test_incsearch_substitute_01', {})
Bram Moolenaarc7f08b72018-08-12 17:39:14 +0200915 call term_sendkeys(buf, "\<Esc>")
916
917 " Select three lines at the cursor using previous pattern.
918 call term_sendkeys(buf, "/foo\<CR>")
919 sleep 100m
920 call term_sendkeys(buf, ':.,.+2s//')
Bram Moolenaarc7f08b72018-08-12 17:39:14 +0200921 call VerifyScreenDump(buf, 'Test_incsearch_substitute_02', {})
922
923 " Deleting last slash should remove the match.
924 call term_sendkeys(buf, "\<BS>")
Bram Moolenaarc7f08b72018-08-12 17:39:14 +0200925 call VerifyScreenDump(buf, 'Test_incsearch_substitute_03', {})
Bram Moolenaar60d08712018-08-12 21:53:15 +0200926 call term_sendkeys(buf, "\<Esc>")
927
928 " Reverse range is accepted
929 call term_sendkeys(buf, ':5,2s/foo')
Bram Moolenaar60d08712018-08-12 21:53:15 +0200930 call VerifyScreenDump(buf, 'Test_incsearch_substitute_04', {})
Bram Moolenaar164251f2018-08-12 16:26:58 +0200931 call term_sendkeys(buf, "\<Esc>")
Bram Moolenaar2b926fc2018-08-13 11:07:57 +0200932
933 " White space after the command is skipped
934 call term_sendkeys(buf, ':2,3sub /fo')
Bram Moolenaar2b926fc2018-08-13 11:07:57 +0200935 call VerifyScreenDump(buf, 'Test_incsearch_substitute_05', {})
936 call term_sendkeys(buf, "\<Esc>")
937
Bram Moolenaar33c4dbb2018-08-14 16:06:16 +0200938 " Command modifiers are skipped
939 call term_sendkeys(buf, ':above below browse botr confirm keepmar keepalt keeppat keepjum filter xxx hide lockm leftabove noau noswap rightbel sandbox silent silent! $tab top unsil vert verbose 4,5s/fo.')
Bram Moolenaar33c4dbb2018-08-14 16:06:16 +0200940 call VerifyScreenDump(buf, 'Test_incsearch_substitute_06', {})
941 call term_sendkeys(buf, "\<Esc>")
942
Bram Moolenaar2f6a3462018-08-14 18:16:52 +0200943 " Cursorline highlighting at match
944 call term_sendkeys(buf, ":set cursorline\<CR>")
945 call term_sendkeys(buf, 'G9G')
946 call term_sendkeys(buf, ':9,11s/bar')
Bram Moolenaar2f6a3462018-08-14 18:16:52 +0200947 call VerifyScreenDump(buf, 'Test_incsearch_substitute_07', {})
948 call term_sendkeys(buf, "\<Esc>")
949
950 " Cursorline highlighting at cursor when no match
951 call term_sendkeys(buf, ':9,10s/bar')
Bram Moolenaar2f6a3462018-08-14 18:16:52 +0200952 call VerifyScreenDump(buf, 'Test_incsearch_substitute_08', {})
953 call term_sendkeys(buf, "\<Esc>")
954
Bram Moolenaar8b0d5ce2018-08-22 23:05:44 +0200955 " Only \v handled as empty pattern, does not move cursor
956 call term_sendkeys(buf, '3G4G')
957 call term_sendkeys(buf, ":nohlsearch\<CR>")
958 call term_sendkeys(buf, ':6,7s/\v')
Bram Moolenaar8b0d5ce2018-08-22 23:05:44 +0200959 call VerifyScreenDump(buf, 'Test_incsearch_substitute_09', {})
960 call term_sendkeys(buf, "\<Esc>")
961
Bram Moolenaarf13daa42018-08-31 22:09:54 +0200962 call term_sendkeys(buf, ":set nocursorline\<CR>")
963
964 " All matches are highlighted for 'hlsearch' after the incsearch canceled
965 call term_sendkeys(buf, "1G*")
966 call term_sendkeys(buf, ":2,5s/foo")
967 sleep 100m
968 call term_sendkeys(buf, "\<Esc>")
969 call VerifyScreenDump(buf, 'Test_incsearch_substitute_10', {})
970
Bram Moolenaar65985ac2018-09-16 17:08:04 +0200971 call term_sendkeys(buf, ":split\<CR>")
972 call term_sendkeys(buf, ":let @/ = 'xyz'\<CR>")
973 call term_sendkeys(buf, ":%s/.")
974 call VerifyScreenDump(buf, 'Test_incsearch_substitute_11', {})
975 call term_sendkeys(buf, "\<BS>")
976 call VerifyScreenDump(buf, 'Test_incsearch_substitute_12', {})
977 call term_sendkeys(buf, "\<Esc>")
978 call VerifyScreenDump(buf, 'Test_incsearch_substitute_13', {})
979
Bram Moolenaar164251f2018-08-12 16:26:58 +0200980 call StopVimInTerminal(buf)
981 call delete('Xis_subst_script')
982endfunc
983
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +0100984func Test_incsearch_with_change()
985 if !has('timers') || !exists('+incsearch') || !CanRunVimInTerminal()
Bram Moolenaar5d30ff12019-06-06 16:12:12 +0200986 throw 'Skipped: cannot make screendumps and/or timers feature and/or incsearch option missing'
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +0100987 endif
988
989 call writefile([
990 \ 'set incsearch hlsearch scrolloff=0',
991 \ 'call setline(1, ["one", "two ------ X", "three"])',
992 \ 'call timer_start(200, { _ -> setline(2, "x")})',
993 \ ], 'Xis_change_script')
994 let buf = RunVimInTerminal('-S Xis_change_script', {'rows': 9, 'cols': 70})
995 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
996 " the 'ambiwidth' check.
Bram Moolenaare86ecbd2019-02-21 17:48:59 +0100997 sleep 300m
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +0100998
999 " Highlight X, it will be deleted by the timer callback.
1000 call term_sendkeys(buf, ':%s/X')
1001 call VerifyScreenDump(buf, 'Test_incsearch_change_01', {})
1002 call term_sendkeys(buf, "\<Esc>")
1003
1004 call StopVimInTerminal(buf)
1005 call delete('Xis_change_script')
1006endfunc
1007
Bram Moolenaar81f56532018-08-18 16:19:42 +02001008" Similar to Test_incsearch_substitute_dump() for :sort
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +02001009func Test_incsearch_sort_dump()
Bram Moolenaar81f56532018-08-18 16:19:42 +02001010 if !exists('+incsearch')
1011 return
1012 endif
1013 if !CanRunVimInTerminal()
Bram Moolenaar5d30ff12019-06-06 16:12:12 +02001014 throw 'Skipped: cannot make screendumps'
Bram Moolenaar81f56532018-08-18 16:19:42 +02001015 endif
1016 call writefile([
1017 \ 'set incsearch hlsearch scrolloff=0',
1018 \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
1019 \ ], 'Xis_sort_script')
1020 let buf = RunVimInTerminal('-S Xis_sort_script', {'rows': 9, 'cols': 70})
1021 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1022 " the 'ambiwidth' check.
1023 sleep 100m
1024
1025 " Need to send one key at a time to force a redraw.
1026 call term_sendkeys(buf, ':sort ni u /on')
Bram Moolenaar81f56532018-08-18 16:19:42 +02001027 call VerifyScreenDump(buf, 'Test_incsearch_sort_01', {})
1028 call term_sendkeys(buf, "\<Esc>")
1029
1030 call StopVimInTerminal(buf)
1031 call delete('Xis_sort_script')
1032endfunc
1033
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001034" Similar to Test_incsearch_substitute_dump() for :vimgrep famiry
1035func Test_incsearch_vimgrep_dump()
1036 if !exists('+incsearch')
1037 return
1038 endif
1039 if !CanRunVimInTerminal()
Bram Moolenaar5d30ff12019-06-06 16:12:12 +02001040 throw 'Skipped: cannot make screendumps'
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001041 endif
1042 call writefile([
1043 \ 'set incsearch hlsearch scrolloff=0',
1044 \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
1045 \ ], 'Xis_vimgrep_script')
1046 let buf = RunVimInTerminal('-S Xis_vimgrep_script', {'rows': 9, 'cols': 70})
1047 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1048 " the 'ambiwidth' check.
1049 sleep 100m
1050
1051 " Need to send one key at a time to force a redraw.
1052 call term_sendkeys(buf, ':vimgrep on')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001053 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_01', {})
1054 call term_sendkeys(buf, "\<Esc>")
1055
1056 call term_sendkeys(buf, ':vimg /on/ *.txt')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001057 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_02', {})
1058 call term_sendkeys(buf, "\<Esc>")
1059
1060 call term_sendkeys(buf, ':vimgrepadd "\<on')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001061 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_03', {})
1062 call term_sendkeys(buf, "\<Esc>")
1063
1064 call term_sendkeys(buf, ':lv "tha')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001065 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_04', {})
1066 call term_sendkeys(buf, "\<Esc>")
1067
1068 call term_sendkeys(buf, ':lvimgrepa "the" **/*.txt')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001069 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_05', {})
1070 call term_sendkeys(buf, "\<Esc>")
1071
1072 call StopVimInTerminal(buf)
1073 call delete('Xis_vimgrep_script')
1074endfunc
1075
Bram Moolenaar198cb662018-09-06 21:44:17 +02001076func Test_keep_last_search_pattern()
1077 if !exists('+incsearch')
1078 return
1079 endif
1080 new
1081 call setline(1, ['foo', 'foo', 'foo'])
1082 set incsearch
1083 call test_override("char_avail", 1)
1084 let @/ = 'bar'
1085 call feedkeys(":/foo/s//\<Esc>", 'ntx')
1086 call assert_equal('bar', @/)
1087
Bram Moolenaar50eb16c2018-09-15 15:42:40 +02001088 " no error message if pattern not found
1089 call feedkeys(":/xyz/s//\<Esc>", 'ntx')
1090 call assert_equal('bar', @/)
1091
Bram Moolenaar198cb662018-09-06 21:44:17 +02001092 bwipe!
1093 call test_override("ALL", 0)
1094 set noincsearch
1095endfunc
1096
Bram Moolenaar99f043a2018-09-09 15:54:14 +02001097func Test_word_under_cursor_after_match()
1098 if !exists('+incsearch')
1099 return
1100 endif
1101 new
1102 call setline(1, 'foo bar')
1103 set incsearch
1104 call test_override("char_avail", 1)
1105 try
1106 call feedkeys("/foo\<C-R>\<C-W>\<CR>", 'ntx')
1107 catch /E486:/
1108 endtry
1109 call assert_equal('foobar', @/)
1110
1111 bwipe!
1112 call test_override("ALL", 0)
1113 set noincsearch
1114endfunc
1115
1116func Test_subst_word_under_cursor()
1117 if !exists('+incsearch')
1118 return
1119 endif
1120 new
1121 call setline(1, ['int SomeLongName;', 'for (xxx = 1; xxx < len; ++xxx)'])
1122 set incsearch
1123 call test_override("char_avail", 1)
1124 call feedkeys("/LongName\<CR>", 'ntx')
1125 call feedkeys(":%s/xxx/\<C-R>\<C-W>/g\<CR>", 'ntx')
1126 call assert_equal('for (SomeLongName = 1; SomeLongName < len; ++SomeLongName)', getline(2))
1127
1128 bwipe!
1129 call test_override("ALL", 0)
1130 set noincsearch
1131endfunc
1132
Bram Moolenaarf45938c2017-11-02 15:59:57 +01001133func Test_search_undefined_behaviour()
1134 if !has("terminal")
1135 return
1136 endif
1137 let h = winheight(0)
1138 if h < 3
1139 return
1140 endif
1141 " did cause an undefined left shift
1142 let g:buf = term_start([GetVimProg(), '--clean', '-e', '-s', '-c', 'call search(getline("."))', 'samples/test000'], {'term_rows': 3})
1143 call assert_equal([''], getline(1, '$'))
1144 call term_sendkeys(g:buf, ":qa!\<cr>")
1145 bwipe!
1146endfunc
Bram Moolenaar2973daa2017-11-02 23:15:40 +01001147
1148func Test_search_undefined_behaviour2()
1149 call search("\%UC0000000")
1150endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01001151
1152" Test for search('multi-byte char', 'bce')
1153func Test_search_multibyte()
Bram Moolenaarfb094e12017-11-05 20:59:28 +01001154 let save_enc = &encoding
1155 set encoding=utf8
1156 enew!
1157 call append('$', 'A')
1158 call cursor(2, 1)
1159 call assert_equal(2, search('A', 'bce', line('.')))
1160 enew!
1161 let &encoding = save_enc
1162endfunc
Bram Moolenaar890dd052017-12-16 19:59:37 +01001163
1164" This was causing E874. Also causes an invalid read?
1165func Test_look_behind()
1166 new
1167 call setline(1, '0\|\&\n\@<=')
1168 call search(getline("."))
1169 bwipe!
1170endfunc
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +01001171
1172func Test_search_sentence()
1173 new
1174 " this used to cause a crash
Bram Moolenaar1bd999f2017-12-19 22:25:40 +01001175 call assert_fails("/\\%')", 'E486')
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +01001176 call assert_fails("/", 'E486')
Bram Moolenaar1bd999f2017-12-19 22:25:40 +01001177 /\%'(
1178 /
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +01001179endfunc
Bram Moolenaar2fb8f682018-12-01 13:14:45 +01001180
1181" Test that there is no crash when there is a last search pattern but no last
1182" substitute pattern.
1183func Test_no_last_substitute_pat()
1184 " Use viminfo to set the last search pattern to a string and make the last
1185 " substitute pattern the most recent used and make it empty (NULL).
1186 call writefile(['~MSle0/bar', '~MSle0~&'], 'Xviminfo')
1187 rviminfo! Xviminfo
1188 call assert_fails('normal n', 'E35:')
1189
1190 call delete('Xviminfo')
1191endfunc
Bram Moolenaar5f5e2032018-12-14 15:47:03 +01001192
1193func Test_search_Ctrl_L_combining()
1194 " Make sure, that Ctrl-L works correctly with combining characters.
1195 " It uses an artificial example of an 'a' with 4 combining chars:
1196 " 'a' U+0061 Dec:97 LATIN SMALL LETTER A &#x61; /\%u61\Z "\u0061"
1197 " ' ̀' U+0300 Dec:768 COMBINING GRAVE ACCENT &#x300; /\%u300\Z "\u0300"
1198 " ' ́' U+0301 Dec:769 COMBINING ACUTE ACCENT &#x301; /\%u301\Z "\u0301"
1199 " ' ̇' U+0307 Dec:775 COMBINING DOT ABOVE &#x307; /\%u307\Z "\u0307"
1200 " ' ̣' U+0323 Dec:803 COMBINING DOT BELOW &#x323; /\%u323 "\u0323"
1201 " Those should also appear on the commandline
Bram Moolenaar30276f22019-01-24 17:59:39 +01001202 if !exists('+incsearch')
Bram Moolenaar5f5e2032018-12-14 15:47:03 +01001203 return
1204 endif
1205 call Cmdline3_prep()
1206 1
1207 let bufcontent = ['', 'Miạ̀́̇m']
1208 call append('$', bufcontent)
1209 call feedkeys("/Mi\<c-l>\<c-l>\<cr>", 'tx')
1210 call assert_equal(5, line('.'))
1211 call assert_equal(bufcontent[1], @/)
1212 call Incsearch_cleanup()
1213endfunc
Bram Moolenaar527a2d82019-02-21 22:28:51 +01001214
Bram Moolenaarab350f82019-02-28 06:25:00 +01001215func Test_large_hex_chars1()
Bram Moolenaar527a2d82019-02-21 22:28:51 +01001216 " This used to cause a crash, the character becomes an NFA state.
1217 try
1218 /\%Ufffffc23
1219 catch
1220 call assert_match('E678:', v:exception)
1221 endtry
Bram Moolenaarab350f82019-02-28 06:25:00 +01001222 try
1223 set re=1
1224 /\%Ufffffc23
1225 catch
1226 call assert_match('E678:', v:exception)
1227 endtry
1228 set re&
1229endfunc
1230
1231func Test_large_hex_chars2()
1232 " This used to cause a crash, the character becomes an NFA state.
1233 try
1234 /[\Ufffffc1f]
1235 catch
1236 call assert_match('E486:', v:exception)
1237 endtry
1238 try
1239 set re=1
1240 /[\Ufffffc1f]
1241 catch
1242 call assert_match('E486:', v:exception)
1243 endtry
1244 set re&
Bram Moolenaar527a2d82019-02-21 22:28:51 +01001245endfunc
Bram Moolenaarcd625122019-02-22 17:29:43 +01001246
1247func Test_one_error_msg()
1248 " This was also giving an internal error
1249 call assert_fails('call search(" \\((\\v[[=P=]]){185}+ ")', 'E871:')
1250endfunc
Bram Moolenaar730f48f2019-04-11 13:45:57 +02001251
1252func Test_incsearch_add_char_under_cursor()
1253 if !exists('+incsearch')
1254 return
1255 endif
1256 set incsearch
1257 new
1258 call setline(1, ['find match', 'anything'])
1259 1
1260 call test_override('char_avail', 1)
1261 call feedkeys("fc/m\<C-L>\<C-L>\<C-L>\<C-L>\<C-L>\<CR>", 'tx')
1262 call assert_equal('match', @/)
1263 call test_override('char_avail', 0)
1264
1265 set incsearch&
1266 bwipe!
1267endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001268
1269" Test for the search() function with match at the cursor position
1270func Test_search_match_at_curpos()
1271 new
1272 call append(0, ['foobar', '', 'one two', ''])
1273
1274 normal gg
1275
1276 call search('foobar', 'c')
1277 call assert_equal([1, 1], [line('.'), col('.')])
1278
1279 normal j
1280 call search('^$', 'c')
1281 call assert_equal([2, 1], [line('.'), col('.')])
1282
1283 call search('^$', 'bc')
1284 call assert_equal([2, 1], [line('.'), col('.')])
1285
1286 exe "normal /two\<CR>"
1287 call search('.', 'c')
1288 call assert_equal([3, 5], [line('.'), col('.')])
1289
1290 close!
1291endfunc
Bram Moolenaardb294ad2019-06-06 12:49:29 +02001292
1293func Test_search_display_pattern()
1294 new
1295 call setline(1, ['foo', 'bar', 'foobar'])
1296
1297 call cursor(1, 1)
1298 let @/ = 'foo'
1299 let pat = escape(@/, '()*?'. '\s\+')
1300 let g:a = execute(':unsilent :norm! n')
1301 call assert_match(pat, g:a)
1302
1303 " right-left
1304 if exists("+rightleft")
1305 set rl
1306 call cursor(1, 1)
1307 let @/ = 'foo'
1308 let pat = 'oof/\s\+'
1309 let g:a = execute(':unsilent :norm! n')
1310 call assert_match(pat, g:a)
1311 set norl
1312 endif
1313endfunc