blob: a356393b063cb88740f04af16d96dbebd4b7e283 [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('.'))
Bram Moolenaar69a5b862019-07-16 21:38:51 +0200243 1
244 " go to previous match (on line 2)
245 call feedkeys("/the\<C-G>\<C-R>\<C-W>\<cr>", 'tx')
246 call assert_equal('theother', @/)
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200247
Bram Moolenaardda933d2016-09-03 21:04:58 +0200248 " Test 2: keep the view,
249 " after deleting a character from the search cmd
250 call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar'])
251 resize 5
252 1
253 call feedkeys("/foo\<bs>\<cr>", 'tx')
254 redraw
255 call assert_equal({'lnum': 10, 'leftcol': 0, 'col': 4, 'topfill': 0, 'topline': 6, 'coladd': 0, 'skipcol': 0, 'curswant': 4}, winsaveview())
256
257 " remove all history entries
Bram Moolenaar69a5b862019-07-16 21:38:51 +0200258 for i in range(11)
Bram Moolenaardda933d2016-09-03 21:04:58 +0200259 call histdel('/')
260 endfor
261
262 " Test 3: reset the view,
263 " after deleting all characters from the search cmd
264 norm! 1gg0
265 " unfortunately, neither "/foo\<c-w>\<cr>", nor "/foo\<bs>\<bs>\<bs>\<cr>",
266 " nor "/foo\<c-u>\<cr>" works to delete the commandline.
267 " In that case Vim should return "E35 no previous regular expression",
268 " but it looks like Vim still sees /foo and therefore the test fails.
269 " Therefore, disableing this test
270 "call assert_fails(feedkeys("/foo\<c-w>\<cr>", 'tx'), 'E35')
271 "call assert_equal({'lnum': 1, 'leftcol': 0, 'col': 0, 'topfill': 0, 'topline': 1, 'coladd': 0, 'skipcol': 0, 'curswant': 0}, winsaveview())
272
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200273 " clean up
Bram Moolenaardda933d2016-09-03 21:04:58 +0200274 set noincsearch
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100275 call test_override("char_avail", 0)
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200276 bw!
277endfunc
Bram Moolenaarea683da2016-09-09 21:41:34 +0200278
279func Test_use_sub_pat()
280 split
281 let @/ = ''
282 func X()
283 s/^/a/
284 /
285 endfunc
286 call X()
287 bwipe!
288endfunc
Bram Moolenaar6e450a52017-01-06 20:03:58 +0100289
290func Test_searchpair()
291 new
292 call setline(1, ['other code here', '', '[', '" cursor here', ']'])
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 nomagic
297 4
Bram Moolenaar3dddb092018-06-24 19:01:59 +0200298 let a = searchpair('\[','',']','bW')
Bram Moolenaar6e450a52017-01-06 20:03:58 +0100299 call assert_equal(3, a)
300 set magic
301 q!
302endfunc
303
Bram Moolenaar3dddb092018-06-24 19:01:59 +0200304func Test_searchpair_errors()
305 call assert_fails("call searchpair([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: using List as a String')
306 call assert_fails("call searchpair('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: using Funcref as a String')
307 call assert_fails("call searchpair('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: using Dictionary as a String')
308 call assert_fails("call searchpair('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
309 call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 0, 99, 100)", 'E475: Invalid argument: 0')
310 call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
311 call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')
312endfunc
313
Bram Moolenaar48570482017-10-30 21:48:41 +0100314func Test_searchpair_skip()
315 func Zero()
316 return 0
317 endfunc
318 func Partial(x)
319 return a:x
320 endfunc
321 new
322 call setline(1, ['{', 'foo', 'foo', 'foo', '}'])
323 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', ''))
324 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', '0'))
325 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', {-> 0}))
326 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Zero')))
327 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Partial', [0])))
Bram Moolenaar48570482017-10-30 21:48:41 +0100328 bw!
329endfunc
330
Bram Moolenaara43ebe92018-07-14 17:25:01 +0200331func Test_searchpair_leak()
332 new
333 call setline(1, 'if one else another endif')
334
335 " The error in the skip expression caused memory to leak.
336 call assert_fails("call searchpair('\\<if\\>', '\\<else\\>', '\\<endif\\>', '', '\"foo\" 2')", 'E15:')
337
338 bwipe!
339endfunc
340
Bram Moolenaar66727e12017-03-01 22:17:05 +0100341func Test_searchc()
342 " These commands used to cause memory overflow in searchc().
343 new
344 norm ixx
345 exe "norm 0t\u93cf"
346 bw!
347endfunc
Bram Moolenaara693d052017-06-29 22:23:06 +0200348
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200349func Cmdline3_prep()
350 " need to disable char_avail,
351 " so that expansion of commandline works
352 call test_override("char_avail", 1)
353 new
354 call setline(1, [' 1', ' 2 the~e', ' 3 the theother'])
355 set incsearch
356endfunc
357
Bram Moolenaar976b8472018-08-12 15:49:47 +0200358func Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200359 set noincsearch
360 call test_override("char_avail", 0)
361 bw!
362endfunc
363
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200364func Test_search_cmdline3()
365 if !exists('+incsearch')
366 return
367 endif
368 call Cmdline3_prep()
369 1
370 " first match
371 call feedkeys("/the\<c-l>\<cr>", 'tx')
372 call assert_equal(' 2 the~e', getline('.'))
373
Bram Moolenaar976b8472018-08-12 15:49:47 +0200374 call Incsearch_cleanup()
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200375endfunc
376
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200377func Test_search_cmdline3s()
378 if !exists('+incsearch')
379 return
380 endif
381 call Cmdline3_prep()
382 1
383 call feedkeys(":%s/the\<c-l>/xxx\<cr>", 'tx')
384 call assert_equal(' 2 xxxe', getline('.'))
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200385 undo
386 call feedkeys(":%subs/the\<c-l>/xxx\<cr>", 'tx')
387 call assert_equal(' 2 xxxe', getline('.'))
388 undo
389 call feedkeys(":%substitute/the\<c-l>/xxx\<cr>", 'tx')
390 call assert_equal(' 2 xxxe', getline('.'))
Bram Moolenaar167ae422018-08-14 21:32:21 +0200391 undo
392 call feedkeys(":%smagic/the.e/xxx\<cr>", 'tx')
393 call assert_equal(' 2 xxx', getline('.'))
394 undo
395 call assert_fails(":%snomagic/the.e/xxx\<cr>", 'E486')
396 "
397 call feedkeys(":%snomagic/the\\.e/xxx\<cr>", 'tx')
398 call assert_equal(' 2 xxx', getline('.'))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200399
Bram Moolenaar976b8472018-08-12 15:49:47 +0200400 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200401endfunc
402
403func Test_search_cmdline3g()
404 if !exists('+incsearch')
405 return
406 endif
407 call Cmdline3_prep()
408 1
409 call feedkeys(":g/the\<c-l>/d\<cr>", 'tx')
410 call assert_equal(' 3 the theother', getline(2))
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200411 undo
412 call feedkeys(":global/the\<c-l>/d\<cr>", 'tx')
413 call assert_equal(' 3 the theother', getline(2))
Bram Moolenaardef7b1d2018-08-13 22:54:35 +0200414 undo
415 call feedkeys(":g!/the\<c-l>/d\<cr>", 'tx')
416 call assert_equal(1, line('$'))
417 call assert_equal(' 2 the~e', getline(1))
418 undo
419 call feedkeys(":global!/the\<c-l>/d\<cr>", 'tx')
420 call assert_equal(1, line('$'))
421 call assert_equal(' 2 the~e', getline(1))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200422
Bram Moolenaar976b8472018-08-12 15:49:47 +0200423 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200424endfunc
425
426func Test_search_cmdline3v()
427 if !exists('+incsearch')
428 return
429 endif
430 call Cmdline3_prep()
431 1
432 call feedkeys(":v/the\<c-l>/d\<cr>", 'tx')
433 call assert_equal(1, line('$'))
434 call assert_equal(' 2 the~e', getline(1))
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200435 undo
436 call feedkeys(":vglobal/the\<c-l>/d\<cr>", 'tx')
437 call assert_equal(1, line('$'))
438 call assert_equal(' 2 the~e', getline(1))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200439
Bram Moolenaar976b8472018-08-12 15:49:47 +0200440 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200441endfunc
442
Bram Moolenaarda5116d2017-07-01 23:11:17 +0200443func Test_search_cmdline4()
444 if !exists('+incsearch')
445 return
446 endif
447 " need to disable char_avail,
448 " so that expansion of commandline works
449 call test_override("char_avail", 1)
450 new
451 call setline(1, [' 1 the first', ' 2 the second', ' 3 the third'])
452 set incsearch
453 $
454 call feedkeys("?the\<c-g>\<cr>", 'tx')
455 call assert_equal(' 3 the third', getline('.'))
456 $
457 call feedkeys("?the\<c-g>\<c-g>\<cr>", 'tx')
458 call assert_equal(' 1 the first', getline('.'))
459 $
460 call feedkeys("?the\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
461 call assert_equal(' 2 the second', getline('.'))
462 $
463 call feedkeys("?the\<c-t>\<cr>", 'tx')
464 call assert_equal(' 1 the first', getline('.'))
465 $
466 call feedkeys("?the\<c-t>\<c-t>\<cr>", 'tx')
467 call assert_equal(' 3 the third', getline('.'))
468 $
469 call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
470 call assert_equal(' 2 the second', getline('.'))
471 " clean up
472 set noincsearch
473 call test_override("char_avail", 0)
474 bw!
475endfunc
Bram Moolenaardb510072017-09-28 21:52:17 +0200476
Bram Moolenaarf8e8c062017-10-22 14:44:17 +0200477func Test_search_cmdline5()
478 if !exists('+incsearch')
479 return
480 endif
481 " Do not call test_override("char_avail", 1) so that <C-g> and <C-t> work
482 " regardless char_avail.
483 new
Bram Moolenaar69a5b862019-07-16 21:38:51 +0200484 call setline(1, [' 1 the first', ' 2 the second', ' 3 the third', ''])
Bram Moolenaarf8e8c062017-10-22 14:44:17 +0200485 set incsearch
486 1
487 call feedkeys("/the\<c-g>\<c-g>\<cr>", 'tx')
488 call assert_equal(' 3 the third', getline('.'))
489 $
490 call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
Bram Moolenaar69a5b862019-07-16 21:38:51 +0200491 call assert_equal(' 1 the first', getline('.'))
Bram Moolenaarf8e8c062017-10-22 14:44:17 +0200492 " clean up
493 set noincsearch
494 bw!
495endfunc
496
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100497func Test_search_cmdline6()
498 " Test that consecutive matches
499 " are caught by <c-g>/<c-t>
500 if !exists('+incsearch')
501 return
502 endif
503 " need to disable char_avail,
504 " so that expansion of commandline works
505 call test_override("char_avail", 1)
506 new
507 call setline(1, [' bbvimb', ''])
508 set incsearch
509 " first match
510 norm! gg0
511 call feedkeys("/b\<cr>", 'tx')
512 call assert_equal([0,1,2,0], getpos('.'))
513 " second match
514 norm! gg0
515 call feedkeys("/b\<c-g>\<cr>", 'tx')
516 call assert_equal([0,1,3,0], getpos('.'))
517 " third match
518 norm! gg0
519 call feedkeys("/b\<c-g>\<c-g>\<cr>", 'tx')
520 call assert_equal([0,1,7,0], getpos('.'))
521 " first match again
522 norm! gg0
523 call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
524 call assert_equal([0,1,2,0], getpos('.'))
525 set nowrapscan
526 " last match
527 norm! gg0
528 call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
529 call assert_equal([0,1,7,0], getpos('.'))
530 " clean up
531 set wrapscan&vim
532 set noincsearch
533 call test_override("char_avail", 0)
534 bw!
535endfunc
536
537func Test_search_cmdline7()
538 " Test that an pressing <c-g> in an empty command line
539 " does not move the cursor
540 if !exists('+incsearch')
541 return
542 endif
543 " need to disable char_avail,
544 " so that expansion of commandline works
545 call test_override("char_avail", 1)
546 new
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200547 let @/ = 'b'
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100548 call setline(1, [' bbvimb', ''])
549 set incsearch
550 " first match
551 norm! gg0
552 " moves to next match of previous search pattern, just like /<cr>
553 call feedkeys("/\<c-g>\<cr>", 'tx')
554 call assert_equal([0,1,2,0], getpos('.'))
555 " moves to next match of previous search pattern, just like /<cr>
556 call feedkeys("/\<cr>", 'tx')
557 call assert_equal([0,1,3,0], getpos('.'))
558 " moves to next match of previous search pattern, just like /<cr>
559 call feedkeys("/\<c-t>\<cr>", 'tx')
560 call assert_equal([0,1,7,0], getpos('.'))
Bram Moolenaard0480092017-11-16 22:20:39 +0100561
562 " using an offset uses the last search pattern
563 call cursor(1, 1)
564 call setline(1, ['1 bbvimb', ' 2 bbvimb'])
565 let @/ = 'b'
566 call feedkeys("//e\<c-g>\<cr>", 'tx')
567 call assert_equal('1 bbvimb', getline('.'))
568 call assert_equal(4, col('.'))
569
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100570 set noincsearch
571 call test_override("char_avail", 0)
572 bw!
573endfunc
574
575func Test_search_cmdline8()
576 " Highlighting is cleared in all windows
577 " since hls applies to all windows
578 if !exists('+incsearch') || !has('terminal') || has('gui_running') || winwidth(0) < 30
579 return
580 endif
581 if has("win32")
582 throw "Skipped: Bug with sending <ESC> to terminal window not fixed yet"
583 endif
584 let h = winheight(0)
585 if h < 3
586 return
587 endif
588 " Prepare buffer text
589 let lines = ['abb vim vim vi', 'vimvivim']
590 call writefile(lines, 'Xsearch.txt')
Bram Moolenaar13deab82017-11-04 18:48:43 +0100591 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100592
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200593 call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100594
Bram Moolenaar13deab82017-11-04 18:48:43 +0100595 call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
596 call term_sendkeys(buf, ":14vsp\<cr>")
597 call term_sendkeys(buf, "/vim\<cr>")
598 call term_sendkeys(buf, "/b\<esc>")
599 call term_sendkeys(buf, "gg0")
600 call term_wait(buf, 500)
601 let screen_line = term_scrape(buf, 1)
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100602 let [a0,a1,a2,a3] = [screen_line[3].attr, screen_line[4].attr,
603 \ screen_line[18].attr, screen_line[19].attr]
604 call assert_notequal(a0, a1)
605 call assert_notequal(a0, a3)
606 call assert_notequal(a1, a2)
607 call assert_equal(a0, a2)
608 call assert_equal(a1, a3)
609 " clean up
610 call delete('Xsearch.txt')
611
612 bwipe!
613endfunc
614
Bram Moolenaardb510072017-09-28 21:52:17 +0200615" Tests for regexp with various magic settings
616func Test_search_regexp()
617 enew!
618
619 put ='1 a aa abb abbccc'
620 exe 'normal! /a*b\{2}c\+/e' . "\<CR>"
621 call assert_equal([0, 2, 17, 0], getpos('.'))
622
623 put ='2 d dd dee deefff'
624 exe 'normal! /\Md\*e\{2}f\+/e' . "\<CR>"
625 call assert_equal([0, 3, 17, 0], getpos('.'))
626
627 set nomagic
628 put ='3 g gg ghh ghhiii'
629 exe 'normal! /g\*h\{2}i\+/e' . "\<CR>"
630 call assert_equal([0, 4, 17, 0], getpos('.'))
631
632 put ='4 j jj jkk jkklll'
633 exe 'normal! /\mj*k\{2}l\+/e' . "\<CR>"
634 call assert_equal([0, 5, 17, 0], getpos('.'))
635
636 put ='5 m mm mnn mnnooo'
637 exe 'normal! /\vm*n{2}o+/e' . "\<CR>"
638 call assert_equal([0, 6, 17, 0], getpos('.'))
639
640 put ='6 x ^aa$ x'
641 exe 'normal! /\V^aa$' . "\<CR>"
642 call assert_equal([0, 7, 5, 0], getpos('.'))
643
644 set magic
645 put ='7 (a)(b) abbaa'
646 exe 'normal! /\v(a)(b)\2\1\1/e' . "\<CR>"
647 call assert_equal([0, 8, 14, 0], getpos('.'))
648
649 put ='8 axx [ab]xx'
650 exe 'normal! /\V[ab]\(\[xy]\)\1' . "\<CR>"
651 call assert_equal([0, 9, 7, 0], getpos('.'))
652
653 set undolevels=100
654 put ='9 foobar'
655 put =''
656 exe "normal! a\<C-G>u\<Esc>"
657 normal G
658 exe 'normal! dv?bar?' . "\<CR>"
659 call assert_equal('9 foo', getline('.'))
660 call assert_equal([0, 10, 5, 0], getpos('.'))
661 call assert_equal(10, line('$'))
662 normal u
663 call assert_equal('9 foobar', getline('.'))
664 call assert_equal([0, 10, 6, 0], getpos('.'))
665 call assert_equal(11, line('$'))
666
667 set undolevels&
668 enew!
669endfunc
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100670
671func Test_search_cmdline_incsearch_highlight()
672 if !exists('+incsearch')
673 return
674 endif
675 set incsearch hlsearch
676 " need to disable char_avail,
677 " so that expansion of commandline works
678 call test_override("char_avail", 1)
679 new
680 call setline(1, ['aaa 1 the first', ' 2 the second', ' 3 the third'])
681
682 1
683 call feedkeys("/second\<cr>", 'tx')
684 call assert_equal('second', @/)
685 call assert_equal(' 2 the second', getline('.'))
686
687 " Canceling search won't change @/
688 1
689 let @/ = 'last pattern'
690 call feedkeys("/third\<C-c>", 'tx')
691 call assert_equal('last pattern', @/)
692 call feedkeys("/third\<Esc>", 'tx')
693 call assert_equal('last pattern', @/)
694 call feedkeys("/3\<bs>\<bs>", 'tx')
695 call assert_equal('last pattern', @/)
696 call feedkeys("/third\<c-g>\<c-t>\<Esc>", 'tx')
697 call assert_equal('last pattern', @/)
698
699 " clean up
700 set noincsearch nohlsearch
701 bw!
702endfunc
703
704func Test_search_cmdline_incsearch_highlight_attr()
705 if !exists('+incsearch') || !has('terminal') || has('gui_running')
706 return
707 endif
708 let h = winheight(0)
709 if h < 3
710 return
711 endif
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100712
713 " Prepare buffer text
Bram Moolenaar13deab82017-11-04 18:48:43 +0100714 let lines = ['abb vim vim vi', 'vimvivim']
715 call writefile(lines, 'Xsearch.txt')
716 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
717
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200718 call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
Bram Moolenaarb50773c2018-01-30 22:31:19 +0100719 " wait for vim to complete initialization
720 call term_wait(buf)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100721
722 " Get attr of normal(a0), incsearch(a1), hlsearch(a2) highlight
Bram Moolenaar13deab82017-11-04 18:48:43 +0100723 call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
724 call term_sendkeys(buf, '/b')
725 call term_wait(buf, 200)
726 let screen_line1 = term_scrape(buf, 1)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100727 call assert_true(len(screen_line1) > 2)
728 " a0: attr_normal
729 let a0 = screen_line1[0].attr
730 " a1: attr_incsearch
731 let a1 = screen_line1[1].attr
732 " a2: attr_hlsearch
733 let a2 = screen_line1[2].attr
734 call assert_notequal(a0, a1)
735 call assert_notequal(a0, a2)
736 call assert_notequal(a1, a2)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100737 call term_sendkeys(buf, "\<cr>gg0")
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100738
739 " Test incremental highlight search
Bram Moolenaar13deab82017-11-04 18:48:43 +0100740 call term_sendkeys(buf, "/vim")
741 call term_wait(buf, 200)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100742 " Buffer:
743 " abb vim vim vi
744 " vimvivim
745 " Search: /vim
746 let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a2,a2,a2,a0,a0,a0]
747 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100748 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
749 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100750
751 " Test <C-g>
Bram Moolenaar13deab82017-11-04 18:48:43 +0100752 call term_sendkeys(buf, "\<C-g>\<C-g>")
753 call term_wait(buf, 200)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100754 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
755 let attr_line2 = [a1,a1,a1,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100756 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
757 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100758
759 " Test <C-t>
Bram Moolenaar13deab82017-11-04 18:48:43 +0100760 call term_sendkeys(buf, "\<C-t>")
761 call term_wait(buf, 200)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100762 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a1,a1,a1,a0,a0,a0]
763 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100764 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
765 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100766
767 " Type Enter and a1(incsearch highlight) should become a2(hlsearch highlight)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100768 call term_sendkeys(buf, "\<cr>")
769 call term_wait(buf, 200)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100770 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
771 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100772 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
773 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100774
775 " Test nohlsearch. a2(hlsearch highlight) should become a0(normal highlight)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100776 call term_sendkeys(buf, ":1\<cr>")
777 call term_sendkeys(buf, ":set nohlsearch\<cr>")
778 call term_sendkeys(buf, "/vim")
779 call term_wait(buf, 200)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100780 let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a0,a0,a0,a0,a0,a0]
781 let attr_line2 = [a0,a0,a0,a0,a0,a0,a0,a0]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100782 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
783 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100784 call delete('Xsearch.txt')
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100785
Bram Moolenaarb94340c2017-11-02 16:16:31 +0100786 call delete('Xsearch.txt')
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100787 bwipe!
788endfunc
Bram Moolenaarf45938c2017-11-02 15:59:57 +0100789
Bram Moolenaar548e5982018-12-26 21:45:00 +0100790func Test_incsearch_cmdline_modifier()
791 if !exists('+incsearch')
792 return
793 endif
794 call test_override("char_avail", 1)
795 new
796 call setline(1, ['foo'])
797 set incsearch
798 " Test that error E14 does not occur in parsing command modifier.
799 call feedkeys("V:tab", 'tx')
800
801 call Incsearch_cleanup()
802endfunc
803
Bram Moolenaar9d34d902018-04-27 22:18:12 +0200804func Test_incsearch_scrolling()
805 if !CanRunVimInTerminal()
Bram Moolenaar5d30ff12019-06-06 16:12:12 +0200806 throw 'Skipped: cannot make screendumps'
Bram Moolenaar9d34d902018-04-27 22:18:12 +0200807 endif
808 call assert_equal(0, &scrolloff)
809 call writefile([
810 \ 'let dots = repeat(".", 120)',
811 \ 'set incsearch cmdheight=2 scrolloff=0',
812 \ 'call setline(1, [dots, dots, dots, "", "target", dots, dots])',
813 \ 'normal gg',
814 \ 'redraw',
815 \ ], 'Xscript')
816 let buf = RunVimInTerminal('-S Xscript', {'rows': 9, 'cols': 70})
817 " Need to send one key at a time to force a redraw
818 call term_sendkeys(buf, '/')
819 sleep 100m
820 call term_sendkeys(buf, 't')
821 sleep 100m
822 call term_sendkeys(buf, 'a')
823 sleep 100m
824 call term_sendkeys(buf, 'r')
825 sleep 100m
826 call term_sendkeys(buf, 'g')
827 call VerifyScreenDump(buf, 'Test_incsearch_scrolling_01', {})
828
829 call term_sendkeys(buf, "\<Esc>")
830 call StopVimInTerminal(buf)
831 call delete('Xscript')
832endfunc
833
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200834func Test_incsearch_search_dump()
835 if !exists('+incsearch')
836 return
837 endif
838 if !CanRunVimInTerminal()
Bram Moolenaar5d30ff12019-06-06 16:12:12 +0200839 throw 'Skipped: cannot make screendumps'
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200840 endif
841 call writefile([
842 \ 'set incsearch hlsearch scrolloff=0',
843 \ 'for n in range(1, 8)',
844 \ ' call setline(n, "foo " . n)',
845 \ 'endfor',
846 \ '3',
847 \ ], 'Xis_search_script')
848 let buf = RunVimInTerminal('-S Xis_search_script', {'rows': 9, 'cols': 70})
849 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
850 " the 'ambiwidth' check.
851 sleep 100m
852
853 " Need to send one key at a time to force a redraw.
854 call term_sendkeys(buf, '/fo')
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200855 call VerifyScreenDump(buf, 'Test_incsearch_search_01', {})
856 call term_sendkeys(buf, "\<Esc>")
857 sleep 100m
858
859 call term_sendkeys(buf, '/\v')
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200860 call VerifyScreenDump(buf, 'Test_incsearch_search_02', {})
861 call term_sendkeys(buf, "\<Esc>")
862
863 call StopVimInTerminal(buf)
864 call delete('Xis_search_script')
865endfunc
866
Bram Moolenaar976b8472018-08-12 15:49:47 +0200867func Test_incsearch_substitute()
868 if !exists('+incsearch')
869 return
870 endif
871 call test_override("char_avail", 1)
872 new
873 set incsearch
874 for n in range(1, 10)
875 call setline(n, 'foo ' . n)
876 endfor
877 4
878 call feedkeys(":.,.+2s/foo\<BS>o\<BS>o/xxx\<cr>", 'tx')
879 call assert_equal('foo 3', getline(3))
880 call assert_equal('xxx 4', getline(4))
881 call assert_equal('xxx 5', getline(5))
882 call assert_equal('xxx 6', getline(6))
883 call assert_equal('foo 7', getline(7))
884
885 call Incsearch_cleanup()
886endfunc
887
Bram Moolenaar164251f2018-08-12 16:26:58 +0200888" Similar to Test_incsearch_substitute() but with a screendump halfway.
889func Test_incsearch_substitute_dump()
890 if !exists('+incsearch')
891 return
892 endif
893 if !CanRunVimInTerminal()
Bram Moolenaar5d30ff12019-06-06 16:12:12 +0200894 throw 'Skipped: cannot make screendumps'
Bram Moolenaar164251f2018-08-12 16:26:58 +0200895 endif
896 call writefile([
897 \ 'set incsearch hlsearch scrolloff=0',
898 \ 'for n in range(1, 10)',
899 \ ' call setline(n, "foo " . n)',
900 \ 'endfor',
Bram Moolenaar2f6a3462018-08-14 18:16:52 +0200901 \ 'call setline(11, "bar 11")',
Bram Moolenaar164251f2018-08-12 16:26:58 +0200902 \ '3',
903 \ ], 'Xis_subst_script')
904 let buf = RunVimInTerminal('-S Xis_subst_script', {'rows': 9, 'cols': 70})
905 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
906 " the 'ambiwidth' check.
907 sleep 100m
908
909 " Need to send one key at a time to force a redraw.
Bram Moolenaarc7f08b72018-08-12 17:39:14 +0200910 " Select three lines at the cursor with typed pattern.
Bram Moolenaar164251f2018-08-12 16:26:58 +0200911 call term_sendkeys(buf, ':.,.+2s/')
912 sleep 100m
913 call term_sendkeys(buf, 'f')
914 sleep 100m
915 call term_sendkeys(buf, 'o')
916 sleep 100m
917 call term_sendkeys(buf, 'o')
918 call VerifyScreenDump(buf, 'Test_incsearch_substitute_01', {})
Bram Moolenaarc7f08b72018-08-12 17:39:14 +0200919 call term_sendkeys(buf, "\<Esc>")
920
921 " Select three lines at the cursor using previous pattern.
922 call term_sendkeys(buf, "/foo\<CR>")
923 sleep 100m
924 call term_sendkeys(buf, ':.,.+2s//')
Bram Moolenaarc7f08b72018-08-12 17:39:14 +0200925 call VerifyScreenDump(buf, 'Test_incsearch_substitute_02', {})
926
927 " Deleting last slash should remove the match.
928 call term_sendkeys(buf, "\<BS>")
Bram Moolenaarc7f08b72018-08-12 17:39:14 +0200929 call VerifyScreenDump(buf, 'Test_incsearch_substitute_03', {})
Bram Moolenaar60d08712018-08-12 21:53:15 +0200930 call term_sendkeys(buf, "\<Esc>")
931
932 " Reverse range is accepted
933 call term_sendkeys(buf, ':5,2s/foo')
Bram Moolenaar60d08712018-08-12 21:53:15 +0200934 call VerifyScreenDump(buf, 'Test_incsearch_substitute_04', {})
Bram Moolenaar164251f2018-08-12 16:26:58 +0200935 call term_sendkeys(buf, "\<Esc>")
Bram Moolenaar2b926fc2018-08-13 11:07:57 +0200936
937 " White space after the command is skipped
938 call term_sendkeys(buf, ':2,3sub /fo')
Bram Moolenaar2b926fc2018-08-13 11:07:57 +0200939 call VerifyScreenDump(buf, 'Test_incsearch_substitute_05', {})
940 call term_sendkeys(buf, "\<Esc>")
941
Bram Moolenaar33c4dbb2018-08-14 16:06:16 +0200942 " Command modifiers are skipped
943 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 +0200944 call VerifyScreenDump(buf, 'Test_incsearch_substitute_06', {})
945 call term_sendkeys(buf, "\<Esc>")
946
Bram Moolenaar2f6a3462018-08-14 18:16:52 +0200947 " Cursorline highlighting at match
948 call term_sendkeys(buf, ":set cursorline\<CR>")
949 call term_sendkeys(buf, 'G9G')
950 call term_sendkeys(buf, ':9,11s/bar')
Bram Moolenaar2f6a3462018-08-14 18:16:52 +0200951 call VerifyScreenDump(buf, 'Test_incsearch_substitute_07', {})
952 call term_sendkeys(buf, "\<Esc>")
953
954 " Cursorline highlighting at cursor when no match
955 call term_sendkeys(buf, ':9,10s/bar')
Bram Moolenaar2f6a3462018-08-14 18:16:52 +0200956 call VerifyScreenDump(buf, 'Test_incsearch_substitute_08', {})
957 call term_sendkeys(buf, "\<Esc>")
958
Bram Moolenaar8b0d5ce2018-08-22 23:05:44 +0200959 " Only \v handled as empty pattern, does not move cursor
960 call term_sendkeys(buf, '3G4G')
961 call term_sendkeys(buf, ":nohlsearch\<CR>")
962 call term_sendkeys(buf, ':6,7s/\v')
Bram Moolenaar8b0d5ce2018-08-22 23:05:44 +0200963 call VerifyScreenDump(buf, 'Test_incsearch_substitute_09', {})
964 call term_sendkeys(buf, "\<Esc>")
965
Bram Moolenaarf13daa42018-08-31 22:09:54 +0200966 call term_sendkeys(buf, ":set nocursorline\<CR>")
967
968 " All matches are highlighted for 'hlsearch' after the incsearch canceled
969 call term_sendkeys(buf, "1G*")
970 call term_sendkeys(buf, ":2,5s/foo")
971 sleep 100m
972 call term_sendkeys(buf, "\<Esc>")
973 call VerifyScreenDump(buf, 'Test_incsearch_substitute_10', {})
974
Bram Moolenaar65985ac2018-09-16 17:08:04 +0200975 call term_sendkeys(buf, ":split\<CR>")
976 call term_sendkeys(buf, ":let @/ = 'xyz'\<CR>")
977 call term_sendkeys(buf, ":%s/.")
978 call VerifyScreenDump(buf, 'Test_incsearch_substitute_11', {})
979 call term_sendkeys(buf, "\<BS>")
980 call VerifyScreenDump(buf, 'Test_incsearch_substitute_12', {})
981 call term_sendkeys(buf, "\<Esc>")
982 call VerifyScreenDump(buf, 'Test_incsearch_substitute_13', {})
983
Bram Moolenaar164251f2018-08-12 16:26:58 +0200984 call StopVimInTerminal(buf)
985 call delete('Xis_subst_script')
986endfunc
987
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +0100988func Test_incsearch_with_change()
989 if !has('timers') || !exists('+incsearch') || !CanRunVimInTerminal()
Bram Moolenaar5d30ff12019-06-06 16:12:12 +0200990 throw 'Skipped: cannot make screendumps and/or timers feature and/or incsearch option missing'
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +0100991 endif
992
993 call writefile([
994 \ 'set incsearch hlsearch scrolloff=0',
995 \ 'call setline(1, ["one", "two ------ X", "three"])',
996 \ 'call timer_start(200, { _ -> setline(2, "x")})',
997 \ ], 'Xis_change_script')
998 let buf = RunVimInTerminal('-S Xis_change_script', {'rows': 9, 'cols': 70})
999 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1000 " the 'ambiwidth' check.
Bram Moolenaare86ecbd2019-02-21 17:48:59 +01001001 sleep 300m
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +01001002
1003 " Highlight X, it will be deleted by the timer callback.
1004 call term_sendkeys(buf, ':%s/X')
1005 call VerifyScreenDump(buf, 'Test_incsearch_change_01', {})
1006 call term_sendkeys(buf, "\<Esc>")
1007
1008 call StopVimInTerminal(buf)
1009 call delete('Xis_change_script')
1010endfunc
1011
Bram Moolenaar81f56532018-08-18 16:19:42 +02001012" Similar to Test_incsearch_substitute_dump() for :sort
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +02001013func Test_incsearch_sort_dump()
Bram Moolenaar81f56532018-08-18 16:19:42 +02001014 if !exists('+incsearch')
1015 return
1016 endif
1017 if !CanRunVimInTerminal()
Bram Moolenaar5d30ff12019-06-06 16:12:12 +02001018 throw 'Skipped: cannot make screendumps'
Bram Moolenaar81f56532018-08-18 16:19:42 +02001019 endif
1020 call writefile([
1021 \ 'set incsearch hlsearch scrolloff=0',
1022 \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
1023 \ ], 'Xis_sort_script')
1024 let buf = RunVimInTerminal('-S Xis_sort_script', {'rows': 9, 'cols': 70})
1025 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1026 " the 'ambiwidth' check.
1027 sleep 100m
1028
1029 " Need to send one key at a time to force a redraw.
1030 call term_sendkeys(buf, ':sort ni u /on')
Bram Moolenaar81f56532018-08-18 16:19:42 +02001031 call VerifyScreenDump(buf, 'Test_incsearch_sort_01', {})
1032 call term_sendkeys(buf, "\<Esc>")
1033
1034 call StopVimInTerminal(buf)
1035 call delete('Xis_sort_script')
1036endfunc
1037
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001038" Similar to Test_incsearch_substitute_dump() for :vimgrep famiry
1039func Test_incsearch_vimgrep_dump()
1040 if !exists('+incsearch')
1041 return
1042 endif
1043 if !CanRunVimInTerminal()
Bram Moolenaar5d30ff12019-06-06 16:12:12 +02001044 throw 'Skipped: cannot make screendumps'
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001045 endif
1046 call writefile([
1047 \ 'set incsearch hlsearch scrolloff=0',
1048 \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
1049 \ ], 'Xis_vimgrep_script')
1050 let buf = RunVimInTerminal('-S Xis_vimgrep_script', {'rows': 9, 'cols': 70})
1051 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1052 " the 'ambiwidth' check.
1053 sleep 100m
1054
1055 " Need to send one key at a time to force a redraw.
1056 call term_sendkeys(buf, ':vimgrep on')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001057 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_01', {})
1058 call term_sendkeys(buf, "\<Esc>")
1059
1060 call term_sendkeys(buf, ':vimg /on/ *.txt')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001061 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_02', {})
1062 call term_sendkeys(buf, "\<Esc>")
1063
1064 call term_sendkeys(buf, ':vimgrepadd "\<on')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001065 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_03', {})
1066 call term_sendkeys(buf, "\<Esc>")
1067
1068 call term_sendkeys(buf, ':lv "tha')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001069 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_04', {})
1070 call term_sendkeys(buf, "\<Esc>")
1071
1072 call term_sendkeys(buf, ':lvimgrepa "the" **/*.txt')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001073 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_05', {})
1074 call term_sendkeys(buf, "\<Esc>")
1075
1076 call StopVimInTerminal(buf)
1077 call delete('Xis_vimgrep_script')
1078endfunc
1079
Bram Moolenaar198cb662018-09-06 21:44:17 +02001080func Test_keep_last_search_pattern()
1081 if !exists('+incsearch')
1082 return
1083 endif
1084 new
1085 call setline(1, ['foo', 'foo', 'foo'])
1086 set incsearch
1087 call test_override("char_avail", 1)
1088 let @/ = 'bar'
1089 call feedkeys(":/foo/s//\<Esc>", 'ntx')
1090 call assert_equal('bar', @/)
1091
Bram Moolenaar50eb16c2018-09-15 15:42:40 +02001092 " no error message if pattern not found
1093 call feedkeys(":/xyz/s//\<Esc>", 'ntx')
1094 call assert_equal('bar', @/)
1095
Bram Moolenaar198cb662018-09-06 21:44:17 +02001096 bwipe!
1097 call test_override("ALL", 0)
1098 set noincsearch
1099endfunc
1100
Bram Moolenaar99f043a2018-09-09 15:54:14 +02001101func Test_word_under_cursor_after_match()
1102 if !exists('+incsearch')
1103 return
1104 endif
1105 new
1106 call setline(1, 'foo bar')
1107 set incsearch
1108 call test_override("char_avail", 1)
1109 try
1110 call feedkeys("/foo\<C-R>\<C-W>\<CR>", 'ntx')
1111 catch /E486:/
1112 endtry
1113 call assert_equal('foobar', @/)
1114
1115 bwipe!
1116 call test_override("ALL", 0)
1117 set noincsearch
1118endfunc
1119
1120func Test_subst_word_under_cursor()
1121 if !exists('+incsearch')
1122 return
1123 endif
1124 new
1125 call setline(1, ['int SomeLongName;', 'for (xxx = 1; xxx < len; ++xxx)'])
1126 set incsearch
1127 call test_override("char_avail", 1)
1128 call feedkeys("/LongName\<CR>", 'ntx')
1129 call feedkeys(":%s/xxx/\<C-R>\<C-W>/g\<CR>", 'ntx')
1130 call assert_equal('for (SomeLongName = 1; SomeLongName < len; ++SomeLongName)', getline(2))
1131
1132 bwipe!
1133 call test_override("ALL", 0)
1134 set noincsearch
1135endfunc
1136
Bram Moolenaarf45938c2017-11-02 15:59:57 +01001137func Test_search_undefined_behaviour()
1138 if !has("terminal")
1139 return
1140 endif
1141 let h = winheight(0)
1142 if h < 3
1143 return
1144 endif
1145 " did cause an undefined left shift
1146 let g:buf = term_start([GetVimProg(), '--clean', '-e', '-s', '-c', 'call search(getline("."))', 'samples/test000'], {'term_rows': 3})
1147 call assert_equal([''], getline(1, '$'))
1148 call term_sendkeys(g:buf, ":qa!\<cr>")
1149 bwipe!
1150endfunc
Bram Moolenaar2973daa2017-11-02 23:15:40 +01001151
1152func Test_search_undefined_behaviour2()
1153 call search("\%UC0000000")
1154endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01001155
1156" Test for search('multi-byte char', 'bce')
1157func Test_search_multibyte()
Bram Moolenaarfb094e12017-11-05 20:59:28 +01001158 let save_enc = &encoding
1159 set encoding=utf8
1160 enew!
1161 call append('$', 'A')
1162 call cursor(2, 1)
1163 call assert_equal(2, search('A', 'bce', line('.')))
1164 enew!
1165 let &encoding = save_enc
1166endfunc
Bram Moolenaar890dd052017-12-16 19:59:37 +01001167
1168" This was causing E874. Also causes an invalid read?
1169func Test_look_behind()
1170 new
1171 call setline(1, '0\|\&\n\@<=')
1172 call search(getline("."))
1173 bwipe!
1174endfunc
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +01001175
1176func Test_search_sentence()
1177 new
1178 " this used to cause a crash
Bram Moolenaar1bd999f2017-12-19 22:25:40 +01001179 call assert_fails("/\\%')", 'E486')
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +01001180 call assert_fails("/", 'E486')
Bram Moolenaar1bd999f2017-12-19 22:25:40 +01001181 /\%'(
1182 /
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +01001183endfunc
Bram Moolenaar2fb8f682018-12-01 13:14:45 +01001184
1185" Test that there is no crash when there is a last search pattern but no last
1186" substitute pattern.
1187func Test_no_last_substitute_pat()
1188 " Use viminfo to set the last search pattern to a string and make the last
1189 " substitute pattern the most recent used and make it empty (NULL).
1190 call writefile(['~MSle0/bar', '~MSle0~&'], 'Xviminfo')
1191 rviminfo! Xviminfo
1192 call assert_fails('normal n', 'E35:')
1193
1194 call delete('Xviminfo')
1195endfunc
Bram Moolenaar5f5e2032018-12-14 15:47:03 +01001196
1197func Test_search_Ctrl_L_combining()
1198 " Make sure, that Ctrl-L works correctly with combining characters.
1199 " It uses an artificial example of an 'a' with 4 combining chars:
1200 " 'a' U+0061 Dec:97 LATIN SMALL LETTER A &#x61; /\%u61\Z "\u0061"
1201 " ' ̀' U+0300 Dec:768 COMBINING GRAVE ACCENT &#x300; /\%u300\Z "\u0300"
1202 " ' ́' U+0301 Dec:769 COMBINING ACUTE ACCENT &#x301; /\%u301\Z "\u0301"
1203 " ' ̇' U+0307 Dec:775 COMBINING DOT ABOVE &#x307; /\%u307\Z "\u0307"
1204 " ' ̣' U+0323 Dec:803 COMBINING DOT BELOW &#x323; /\%u323 "\u0323"
1205 " Those should also appear on the commandline
Bram Moolenaar30276f22019-01-24 17:59:39 +01001206 if !exists('+incsearch')
Bram Moolenaar5f5e2032018-12-14 15:47:03 +01001207 return
1208 endif
1209 call Cmdline3_prep()
1210 1
1211 let bufcontent = ['', 'Miạ̀́̇m']
1212 call append('$', bufcontent)
1213 call feedkeys("/Mi\<c-l>\<c-l>\<cr>", 'tx')
1214 call assert_equal(5, line('.'))
1215 call assert_equal(bufcontent[1], @/)
1216 call Incsearch_cleanup()
1217endfunc
Bram Moolenaar527a2d82019-02-21 22:28:51 +01001218
Bram Moolenaarab350f82019-02-28 06:25:00 +01001219func Test_large_hex_chars1()
Bram Moolenaar527a2d82019-02-21 22:28:51 +01001220 " This used to cause a crash, the character becomes an NFA state.
1221 try
1222 /\%Ufffffc23
1223 catch
1224 call assert_match('E678:', v:exception)
1225 endtry
Bram Moolenaarab350f82019-02-28 06:25:00 +01001226 try
1227 set re=1
1228 /\%Ufffffc23
1229 catch
1230 call assert_match('E678:', v:exception)
1231 endtry
1232 set re&
1233endfunc
1234
1235func Test_large_hex_chars2()
1236 " This used to cause a crash, the character becomes an NFA state.
1237 try
1238 /[\Ufffffc1f]
1239 catch
1240 call assert_match('E486:', v:exception)
1241 endtry
1242 try
1243 set re=1
1244 /[\Ufffffc1f]
1245 catch
1246 call assert_match('E486:', v:exception)
1247 endtry
1248 set re&
Bram Moolenaar527a2d82019-02-21 22:28:51 +01001249endfunc
Bram Moolenaarcd625122019-02-22 17:29:43 +01001250
1251func Test_one_error_msg()
1252 " This was also giving an internal error
1253 call assert_fails('call search(" \\((\\v[[=P=]]){185}+ ")', 'E871:')
1254endfunc
Bram Moolenaar730f48f2019-04-11 13:45:57 +02001255
1256func Test_incsearch_add_char_under_cursor()
1257 if !exists('+incsearch')
1258 return
1259 endif
1260 set incsearch
1261 new
1262 call setline(1, ['find match', 'anything'])
1263 1
1264 call test_override('char_avail', 1)
1265 call feedkeys("fc/m\<C-L>\<C-L>\<C-L>\<C-L>\<C-L>\<CR>", 'tx')
1266 call assert_equal('match', @/)
1267 call test_override('char_avail', 0)
1268
1269 set incsearch&
1270 bwipe!
1271endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001272
1273" Test for the search() function with match at the cursor position
1274func Test_search_match_at_curpos()
1275 new
1276 call append(0, ['foobar', '', 'one two', ''])
1277
1278 normal gg
1279
1280 call search('foobar', 'c')
1281 call assert_equal([1, 1], [line('.'), col('.')])
1282
1283 normal j
1284 call search('^$', 'c')
1285 call assert_equal([2, 1], [line('.'), col('.')])
1286
1287 call search('^$', 'bc')
1288 call assert_equal([2, 1], [line('.'), col('.')])
1289
1290 exe "normal /two\<CR>"
1291 call search('.', 'c')
1292 call assert_equal([3, 5], [line('.'), col('.')])
1293
1294 close!
1295endfunc
Bram Moolenaardb294ad2019-06-06 12:49:29 +02001296
1297func Test_search_display_pattern()
1298 new
1299 call setline(1, ['foo', 'bar', 'foobar'])
1300
1301 call cursor(1, 1)
1302 let @/ = 'foo'
1303 let pat = escape(@/, '()*?'. '\s\+')
1304 let g:a = execute(':unsilent :norm! n')
1305 call assert_match(pat, g:a)
1306
1307 " right-left
1308 if exists("+rightleft")
1309 set rl
1310 call cursor(1, 1)
1311 let @/ = 'foo'
1312 let pat = 'oof/\s\+'
1313 let g:a = execute(':unsilent :norm! n')
1314 call assert_match(pat, g:a)
1315 set norl
1316 endif
1317endfunc