blob: 7b4b9fd32fba671566caf8758af4d0f0c57e700e [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 Moolenaar8c5a2782019-08-07 23:07:07 +02005source check.vim
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +01006
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +02007func Test_search_cmdline()
Bram Moolenaarb68df222020-03-19 15:05:28 +01008 CheckOption incsearch
9
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020010 " 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')
Bram Moolenaar8832a342020-04-11 18:36:38 +020020 call feedkeys("/the\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020021 call assert_equal('the', @/)
Bram Moolenaar8832a342020-04-11 18:36:38 +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
Bram Moolenaar3ba35402019-12-21 22:00:50 +010059 " eighth 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
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100101 " eighth 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()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100204 CheckOption incsearch
205
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200206 " need to disable char_avail,
207 " so that expansion of commandline works
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100208 call test_override("char_avail", 1)
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200209 new
210 call setline(1, [' 1', ' 2 these', ' 3 the theother'])
211 " Test 1
Bram Moolenaar11956692016-08-27 16:26:56 +0200212 " Ctrl-T goes correctly back and forth
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200213 set incsearch
214 1
215 " first match
216 call feedkeys("/the\<cr>", 'tx')
217 call assert_equal(' 2 these', getline('.'))
218 1
219 " go to next match (on next line)
Bram Moolenaar11956692016-08-27 16:26:56 +0200220 call feedkeys("/the\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200221 call assert_equal(' 3 the theother', getline('.'))
222 1
223 " go to next match (still on line 3)
Bram Moolenaar11956692016-08-27 16:26:56 +0200224 call feedkeys("/the\<C-G>\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200225 call assert_equal(' 3 the theother', getline('.'))
226 1
227 " go to next match (still on line 3)
Bram Moolenaar11956692016-08-27 16:26:56 +0200228 call feedkeys("/the\<C-G>\<C-G>\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200229 call assert_equal(' 3 the theother', getline('.'))
230 1
231 " go to previous match (on line 3)
Bram Moolenaar11956692016-08-27 16:26:56 +0200232 call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200233 call assert_equal(' 3 the theother', getline('.'))
234 1
235 " go to previous match (on line 3)
Bram Moolenaar11956692016-08-27 16:26:56 +0200236 call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200237 call assert_equal(' 3 the theother', getline('.'))
238 1
239 " go to previous match (on line 2)
Bram Moolenaar11956692016-08-27 16:26:56 +0200240 call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<C-T>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200241 call assert_equal(' 2 these', getline('.'))
Bram Moolenaar69a5b862019-07-16 21:38:51 +0200242 1
243 " go to previous match (on line 2)
244 call feedkeys("/the\<C-G>\<C-R>\<C-W>\<cr>", 'tx')
245 call assert_equal('theother', @/)
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200246
Bram Moolenaardda933d2016-09-03 21:04:58 +0200247 " Test 2: keep the view,
248 " after deleting a character from the search cmd
249 call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar'])
250 resize 5
251 1
252 call feedkeys("/foo\<bs>\<cr>", 'tx')
253 redraw
254 call assert_equal({'lnum': 10, 'leftcol': 0, 'col': 4, 'topfill': 0, 'topline': 6, 'coladd': 0, 'skipcol': 0, 'curswant': 4}, winsaveview())
255
256 " remove all history entries
Bram Moolenaar69a5b862019-07-16 21:38:51 +0200257 for i in range(11)
Bram Moolenaardda933d2016-09-03 21:04:58 +0200258 call histdel('/')
259 endfor
260
261 " Test 3: reset the view,
262 " after deleting all characters from the search cmd
263 norm! 1gg0
264 " unfortunately, neither "/foo\<c-w>\<cr>", nor "/foo\<bs>\<bs>\<bs>\<cr>",
265 " nor "/foo\<c-u>\<cr>" works to delete the commandline.
266 " In that case Vim should return "E35 no previous regular expression",
267 " but it looks like Vim still sees /foo and therefore the test fails.
Bram Moolenaar1bc353b2019-09-01 14:45:28 +0200268 " Therefore, disabling this test
Bram Moolenaare2e40752020-09-04 21:18:46 +0200269 "call assert_fails(feedkeys("/foo\<c-w>\<cr>", 'tx'), 'E35:')
Bram Moolenaardda933d2016-09-03 21:04:58 +0200270 "call assert_equal({'lnum': 1, 'leftcol': 0, 'col': 0, 'topfill': 0, 'topline': 1, 'coladd': 0, 'skipcol': 0, 'curswant': 0}, winsaveview())
271
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200272 " clean up
Bram Moolenaardda933d2016-09-03 21:04:58 +0200273 set noincsearch
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100274 call test_override("char_avail", 0)
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200275 bw!
276endfunc
Bram Moolenaarea683da2016-09-09 21:41:34 +0200277
278func Test_use_sub_pat()
279 split
280 let @/ = ''
281 func X()
282 s/^/a/
283 /
284 endfunc
285 call X()
286 bwipe!
287endfunc
Bram Moolenaar6e450a52017-01-06 20:03:58 +0100288
289func Test_searchpair()
290 new
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100291 call setline(1, ['other code', 'here [', ' [', ' " cursor here', ' ]]'])
292
Bram Moolenaarbade44e2020-09-26 22:39:24 +0200293 " should not give an error for using "42"
294 call assert_equal(0, searchpair('a', 'b', 'c', '', 42))
295
Bram Moolenaar6e450a52017-01-06 20:03:58 +0100296 4
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100297 call assert_equal(3, searchpair('\[', '', ']', 'bW'))
298 call assert_equal([0, 3, 2, 0], getpos('.'))
299 4
300 call assert_equal(2, searchpair('\[', '', ']', 'bWr'))
301 call assert_equal([0, 2, 6, 0], getpos('.'))
302 4
303 call assert_equal(1, searchpair('\[', '', ']', 'bWm'))
304 call assert_equal([0, 3, 2, 0], getpos('.'))
305 4|norm ^
306 call assert_equal(5, searchpair('\[', '', ']', 'Wn'))
307 call assert_equal([0, 4, 2, 0], getpos('.'))
308 4
309 call assert_equal(2, searchpair('\[', '', ']', 'bW',
310 \ 'getline(".") =~ "^\\s*\["'))
311 call assert_equal([0, 2, 6, 0], getpos('.'))
Bram Moolenaar6e450a52017-01-06 20:03:58 +0100312 set nomagic
313 4
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100314 call assert_equal(3, searchpair('\[', '', ']', 'bW'))
315 call assert_equal([0, 3, 2, 0], getpos('.'))
Bram Moolenaar6e450a52017-01-06 20:03:58 +0100316 set magic
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100317 4|norm ^
318 call assert_equal(0, searchpair('{', '', '}', 'bW'))
319 call assert_equal([0, 4, 2, 0], getpos('.'))
320
321 %d
322 call setline(1, ['if 1', ' if 2', ' else', ' endif 2', 'endif 1'])
323
324 /\<if 1
325 call assert_equal(5, searchpair('\<if\>', '\<else\>', '\<endif\>', 'W'))
326 call assert_equal([0, 5, 1, 0], getpos('.'))
327 /\<if 2
328 call assert_equal(3, searchpair('\<if\>', '\<else\>', '\<endif\>', 'W'))
329 call assert_equal([0, 3, 3, 0], getpos('.'))
330
Bram Moolenaar5ea38d12022-06-16 21:20:48 +0100331 bwipe!
332endfunc
333
334func Test_searchpair_timeout()
335 CheckFeature reltime
336
337 func Waitabit()
338 sleep 20m
339 return 1 " skip match
340 endfunc
341
342 new
343 call setline(1, range(100))
344 call setline(1, "(start here")
345 call setline(100, "end here)")
346 let starttime = reltime()
347
348 " A timeout of 100 msec should happen after about five times of 20 msec wait
349 " in Waitabit(). When the timeout applies to each search the elapsed time
350 " will be much longer.
351 call assert_equal(0, searchpair('(', '\d', ')', '', "Waitabit()", 0, 100))
352 let elapsed = reltime(starttime)->reltimefloat()
353 call assert_inrange(0.09, 0.300, elapsed)
354
355 bwipe!
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100356endfunc
357
358func Test_searchpairpos()
359 new
360 call setline(1, ['other code', 'here [', ' [', ' " cursor here', ' ]]'])
361
362 4
363 call assert_equal([3, 2], searchpairpos('\[', '', ']', 'bW'))
364 call assert_equal([0, 3, 2, 0], getpos('.'))
365 4
366 call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bWr'))
367 call assert_equal([0, 2, 6, 0], getpos('.'))
368 4|norm ^
369 call assert_equal([5, 2], searchpairpos('\[', '', ']', 'Wn'))
370 call assert_equal([0, 4, 2, 0], getpos('.'))
371 4
372 call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bW',
373 \ 'getline(".") =~ "^\\s*\["'))
374 call assert_equal([0, 2, 6, 0], getpos('.'))
375 4
376 call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bWr'))
377 call assert_equal([0, 2, 6, 0], getpos('.'))
378 set nomagic
379 4
380 call assert_equal([3, 2], searchpairpos('\[', '', ']', 'bW'))
381 call assert_equal([0, 3, 2, 0], getpos('.'))
382 set magic
383 4|norm ^
384 call assert_equal([0, 0], searchpairpos('{', '', '}', 'bW'))
385 call assert_equal([0, 4, 2, 0], getpos('.'))
386
387 %d
388 call setline(1, ['if 1', ' if 2', ' else', ' endif 2', 'endif 1'])
389 /\<if 1
390 call assert_equal([5, 1], searchpairpos('\<if\>', '\<else\>', '\<endif\>', 'W'))
391 call assert_equal([0, 5, 1, 0], getpos('.'))
392 /\<if 2
393 call assert_equal([3, 3], searchpairpos('\<if\>', '\<else\>', '\<endif\>', 'W'))
394 call assert_equal([0, 3, 3, 0], getpos('.'))
395
Bram Moolenaar6e450a52017-01-06 20:03:58 +0100396 q!
397endfunc
398
Bram Moolenaar3dddb092018-06-24 19:01:59 +0200399func Test_searchpair_errors()
Yegappan Lakshmanan5b739922021-07-10 13:15:41 +0200400 call assert_fails("call searchpair([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: Using a List as a String')
401 call assert_fails("call searchpair('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: Using a Funcref as a String')
402 call assert_fails("call searchpair('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: Using a Dictionary as a String')
Bram Moolenaar3dddb092018-06-24 19:01:59 +0200403 call assert_fails("call searchpair('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
Bram Moolenaar3dddb092018-06-24 19:01:59 +0200404 call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
405 call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100406 call assert_fails("call searchpair('start', 'middle', 'end', 'e')", 'E475: Invalid argument: e')
407 call assert_fails("call searchpair('start', 'middle', 'end', 'sn')", 'E475: Invalid argument: sn')
408endfunc
409
410func Test_searchpairpos_errors()
Yegappan Lakshmanan5b739922021-07-10 13:15:41 +0200411 call assert_fails("call searchpairpos([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: Using a List as a String')
412 call assert_fails("call searchpairpos('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: Using a Funcref as a String')
413 call assert_fails("call searchpairpos('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: Using a Dictionary as a String')
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100414 call assert_fails("call searchpairpos('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100415 call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
416 call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')
417 call assert_fails("call searchpairpos('start', 'middle', 'end', 'e')", 'E475: Invalid argument: e')
418 call assert_fails("call searchpairpos('start', 'middle', 'end', 'sn')", 'E475: Invalid argument: sn')
Bram Moolenaar3dddb092018-06-24 19:01:59 +0200419endfunc
420
Bram Moolenaar48570482017-10-30 21:48:41 +0100421func Test_searchpair_skip()
422 func Zero()
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100423 return 0
Bram Moolenaar48570482017-10-30 21:48:41 +0100424 endfunc
425 func Partial(x)
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100426 return a:x
Bram Moolenaar48570482017-10-30 21:48:41 +0100427 endfunc
428 new
429 call setline(1, ['{', 'foo', 'foo', 'foo', '}'])
430 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', ''))
431 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', '0'))
432 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', {-> 0}))
433 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Zero')))
434 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Partial', [0])))
Bram Moolenaar48570482017-10-30 21:48:41 +0100435 bw!
436endfunc
437
Bram Moolenaara43ebe92018-07-14 17:25:01 +0200438func Test_searchpair_leak()
439 new
440 call setline(1, 'if one else another endif')
441
442 " The error in the skip expression caused memory to leak.
443 call assert_fails("call searchpair('\\<if\\>', '\\<else\\>', '\\<endif\\>', '', '\"foo\" 2')", 'E15:')
444
445 bwipe!
446endfunc
447
Bram Moolenaar66727e12017-03-01 22:17:05 +0100448func Test_searchc()
449 " These commands used to cause memory overflow in searchc().
450 new
451 norm ixx
452 exe "norm 0t\u93cf"
453 bw!
454endfunc
Bram Moolenaara693d052017-06-29 22:23:06 +0200455
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200456func Cmdline3_prep()
457 " need to disable char_avail,
458 " so that expansion of commandline works
459 call test_override("char_avail", 1)
460 new
461 call setline(1, [' 1', ' 2 the~e', ' 3 the theother'])
462 set incsearch
463endfunc
464
Bram Moolenaar976b8472018-08-12 15:49:47 +0200465func Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200466 set noincsearch
467 call test_override("char_avail", 0)
468 bw!
469endfunc
470
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200471func Test_search_cmdline3()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100472 CheckOption incsearch
473
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200474 call Cmdline3_prep()
475 1
476 " first match
477 call feedkeys("/the\<c-l>\<cr>", 'tx')
478 call assert_equal(' 2 the~e', getline('.'))
479
Bram Moolenaar976b8472018-08-12 15:49:47 +0200480 call Incsearch_cleanup()
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200481endfunc
482
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200483func Test_search_cmdline3s()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100484 CheckOption incsearch
485
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200486 call Cmdline3_prep()
487 1
488 call feedkeys(":%s/the\<c-l>/xxx\<cr>", 'tx')
489 call assert_equal(' 2 xxxe', getline('.'))
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200490 undo
491 call feedkeys(":%subs/the\<c-l>/xxx\<cr>", 'tx')
492 call assert_equal(' 2 xxxe', getline('.'))
493 undo
494 call feedkeys(":%substitute/the\<c-l>/xxx\<cr>", 'tx')
495 call assert_equal(' 2 xxxe', getline('.'))
Bram Moolenaar167ae422018-08-14 21:32:21 +0200496 undo
497 call feedkeys(":%smagic/the.e/xxx\<cr>", 'tx')
498 call assert_equal(' 2 xxx', getline('.'))
499 undo
Bram Moolenaare2e40752020-09-04 21:18:46 +0200500 call assert_fails(":%snomagic/the.e/xxx\<cr>", 'E486:')
Bram Moolenaar167ae422018-08-14 21:32:21 +0200501 "
502 call feedkeys(":%snomagic/the\\.e/xxx\<cr>", 'tx')
503 call assert_equal(' 2 xxx', getline('.'))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200504
Bram Moolenaar976b8472018-08-12 15:49:47 +0200505 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200506endfunc
507
508func Test_search_cmdline3g()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100509 CheckOption incsearch
510
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200511 call Cmdline3_prep()
512 1
513 call feedkeys(":g/the\<c-l>/d\<cr>", 'tx')
514 call assert_equal(' 3 the theother', getline(2))
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200515 undo
516 call feedkeys(":global/the\<c-l>/d\<cr>", 'tx')
517 call assert_equal(' 3 the theother', getline(2))
Bram Moolenaardef7b1d2018-08-13 22:54:35 +0200518 undo
519 call feedkeys(":g!/the\<c-l>/d\<cr>", 'tx')
520 call assert_equal(1, line('$'))
521 call assert_equal(' 2 the~e', getline(1))
522 undo
523 call feedkeys(":global!/the\<c-l>/d\<cr>", 'tx')
524 call assert_equal(1, line('$'))
525 call assert_equal(' 2 the~e', getline(1))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200526
Bram Moolenaar976b8472018-08-12 15:49:47 +0200527 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200528endfunc
529
530func Test_search_cmdline3v()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100531 CheckOption incsearch
532
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200533 call Cmdline3_prep()
534 1
535 call feedkeys(":v/the\<c-l>/d\<cr>", 'tx')
536 call assert_equal(1, line('$'))
537 call assert_equal(' 2 the~e', getline(1))
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200538 undo
539 call feedkeys(":vglobal/the\<c-l>/d\<cr>", 'tx')
540 call assert_equal(1, line('$'))
541 call assert_equal(' 2 the~e', getline(1))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200542
Bram Moolenaar976b8472018-08-12 15:49:47 +0200543 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200544endfunc
545
Bram Moolenaarda5116d2017-07-01 23:11:17 +0200546func Test_search_cmdline4()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100547 CheckOption incsearch
548
Bram Moolenaarda5116d2017-07-01 23:11:17 +0200549 " need to disable char_avail,
550 " so that expansion of commandline works
551 call test_override("char_avail", 1)
552 new
553 call setline(1, [' 1 the first', ' 2 the second', ' 3 the third'])
554 set incsearch
555 $
556 call feedkeys("?the\<c-g>\<cr>", 'tx')
557 call assert_equal(' 3 the third', getline('.'))
558 $
559 call feedkeys("?the\<c-g>\<c-g>\<cr>", 'tx')
560 call assert_equal(' 1 the first', getline('.'))
561 $
562 call feedkeys("?the\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
563 call assert_equal(' 2 the second', getline('.'))
564 $
565 call feedkeys("?the\<c-t>\<cr>", 'tx')
566 call assert_equal(' 1 the first', getline('.'))
567 $
568 call feedkeys("?the\<c-t>\<c-t>\<cr>", 'tx')
569 call assert_equal(' 3 the third', getline('.'))
570 $
571 call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
572 call assert_equal(' 2 the second', getline('.'))
573 " clean up
574 set noincsearch
575 call test_override("char_avail", 0)
576 bw!
577endfunc
Bram Moolenaardb510072017-09-28 21:52:17 +0200578
Bram Moolenaarf8e8c062017-10-22 14:44:17 +0200579func Test_search_cmdline5()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100580 CheckOption incsearch
581
Bram Moolenaarf8e8c062017-10-22 14:44:17 +0200582 " Do not call test_override("char_avail", 1) so that <C-g> and <C-t> work
583 " regardless char_avail.
584 new
Bram Moolenaar69a5b862019-07-16 21:38:51 +0200585 call setline(1, [' 1 the first', ' 2 the second', ' 3 the third', ''])
Bram Moolenaarf8e8c062017-10-22 14:44:17 +0200586 set incsearch
587 1
588 call feedkeys("/the\<c-g>\<c-g>\<cr>", 'tx')
589 call assert_equal(' 3 the third', getline('.'))
590 $
591 call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
Bram Moolenaar69a5b862019-07-16 21:38:51 +0200592 call assert_equal(' 1 the first', getline('.'))
Bram Moolenaarf8e8c062017-10-22 14:44:17 +0200593 " clean up
594 set noincsearch
595 bw!
596endfunc
597
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100598func Test_search_cmdline6()
599 " Test that consecutive matches
600 " are caught by <c-g>/<c-t>
Bram Moolenaarb68df222020-03-19 15:05:28 +0100601 CheckOption incsearch
602
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100603 " need to disable char_avail,
604 " so that expansion of commandline works
605 call test_override("char_avail", 1)
606 new
607 call setline(1, [' bbvimb', ''])
608 set incsearch
609 " first match
610 norm! gg0
611 call feedkeys("/b\<cr>", 'tx')
612 call assert_equal([0,1,2,0], getpos('.'))
613 " second match
614 norm! gg0
615 call feedkeys("/b\<c-g>\<cr>", 'tx')
616 call assert_equal([0,1,3,0], getpos('.'))
617 " third match
618 norm! gg0
619 call feedkeys("/b\<c-g>\<c-g>\<cr>", 'tx')
620 call assert_equal([0,1,7,0], getpos('.'))
621 " first match again
622 norm! gg0
623 call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
624 call assert_equal([0,1,2,0], getpos('.'))
625 set nowrapscan
626 " last match
627 norm! gg0
628 call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
629 call assert_equal([0,1,7,0], getpos('.'))
630 " clean up
631 set wrapscan&vim
632 set noincsearch
633 call test_override("char_avail", 0)
634 bw!
635endfunc
636
637func Test_search_cmdline7()
Bram Moolenaard66cdcd2020-07-26 13:27:16 +0200638 " Test that pressing <c-g> in an empty command line
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100639 " does not move the cursor
Bram Moolenaarb68df222020-03-19 15:05:28 +0100640 CheckOption incsearch
641
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100642 " need to disable char_avail,
643 " so that expansion of commandline works
644 call test_override("char_avail", 1)
645 new
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200646 let @/ = 'b'
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100647 call setline(1, [' bbvimb', ''])
648 set incsearch
649 " first match
650 norm! gg0
651 " moves to next match of previous search pattern, just like /<cr>
652 call feedkeys("/\<c-g>\<cr>", 'tx')
653 call assert_equal([0,1,2,0], getpos('.'))
654 " moves to next match of previous search pattern, just like /<cr>
655 call feedkeys("/\<cr>", 'tx')
656 call assert_equal([0,1,3,0], getpos('.'))
657 " moves to next match of previous search pattern, just like /<cr>
658 call feedkeys("/\<c-t>\<cr>", 'tx')
659 call assert_equal([0,1,7,0], getpos('.'))
Bram Moolenaard0480092017-11-16 22:20:39 +0100660
661 " using an offset uses the last search pattern
662 call cursor(1, 1)
663 call setline(1, ['1 bbvimb', ' 2 bbvimb'])
664 let @/ = 'b'
665 call feedkeys("//e\<c-g>\<cr>", 'tx')
666 call assert_equal('1 bbvimb', getline('.'))
667 call assert_equal(4, col('.'))
668
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100669 set noincsearch
670 call test_override("char_avail", 0)
671 bw!
672endfunc
673
674func Test_search_cmdline8()
675 " Highlighting is cleared in all windows
676 " since hls applies to all windows
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200677 CheckOption incsearch
678 CheckFeature terminal
679 CheckNotGui
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100680 if has("win32")
681 throw "Skipped: Bug with sending <ESC> to terminal window not fixed yet"
682 endif
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200683
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100684 let h = winheight(0)
685 if h < 3
686 return
687 endif
688 " Prepare buffer text
689 let lines = ['abb vim vim vi', 'vimvivim']
690 call writefile(lines, 'Xsearch.txt')
Bram Moolenaar13deab82017-11-04 18:48:43 +0100691 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100692
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200693 call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100694
Bram Moolenaar13deab82017-11-04 18:48:43 +0100695 call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
696 call term_sendkeys(buf, ":14vsp\<cr>")
697 call term_sendkeys(buf, "/vim\<cr>")
698 call term_sendkeys(buf, "/b\<esc>")
699 call term_sendkeys(buf, "gg0")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200700 call TermWait(buf, 250)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100701 let screen_line = term_scrape(buf, 1)
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100702 let [a0,a1,a2,a3] = [screen_line[3].attr, screen_line[4].attr,
703 \ screen_line[18].attr, screen_line[19].attr]
704 call assert_notequal(a0, a1)
705 call assert_notequal(a0, a3)
706 call assert_notequal(a1, a2)
707 call assert_equal(a0, a2)
708 call assert_equal(a1, a3)
709 " clean up
710 call delete('Xsearch.txt')
711
712 bwipe!
713endfunc
714
Bram Moolenaardb510072017-09-28 21:52:17 +0200715" Tests for regexp with various magic settings
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200716func Run_search_regexp_magic_opt()
Bram Moolenaardb510072017-09-28 21:52:17 +0200717 put ='1 a aa abb abbccc'
718 exe 'normal! /a*b\{2}c\+/e' . "\<CR>"
719 call assert_equal([0, 2, 17, 0], getpos('.'))
720
721 put ='2 d dd dee deefff'
722 exe 'normal! /\Md\*e\{2}f\+/e' . "\<CR>"
723 call assert_equal([0, 3, 17, 0], getpos('.'))
724
725 set nomagic
726 put ='3 g gg ghh ghhiii'
727 exe 'normal! /g\*h\{2}i\+/e' . "\<CR>"
728 call assert_equal([0, 4, 17, 0], getpos('.'))
729
730 put ='4 j jj jkk jkklll'
731 exe 'normal! /\mj*k\{2}l\+/e' . "\<CR>"
732 call assert_equal([0, 5, 17, 0], getpos('.'))
733
734 put ='5 m mm mnn mnnooo'
735 exe 'normal! /\vm*n{2}o+/e' . "\<CR>"
736 call assert_equal([0, 6, 17, 0], getpos('.'))
737
738 put ='6 x ^aa$ x'
739 exe 'normal! /\V^aa$' . "\<CR>"
740 call assert_equal([0, 7, 5, 0], getpos('.'))
741
742 set magic
743 put ='7 (a)(b) abbaa'
744 exe 'normal! /\v(a)(b)\2\1\1/e' . "\<CR>"
745 call assert_equal([0, 8, 14, 0], getpos('.'))
746
747 put ='8 axx [ab]xx'
748 exe 'normal! /\V[ab]\(\[xy]\)\1' . "\<CR>"
749 call assert_equal([0, 9, 7, 0], getpos('.'))
750
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200751 %d
752endfunc
753
754func Test_search_regexp()
755 enew!
756
757 set regexpengine=1
758 call Run_search_regexp_magic_opt()
759 set regexpengine=2
760 call Run_search_regexp_magic_opt()
761 set regexpengine&
762
Bram Moolenaardb510072017-09-28 21:52:17 +0200763 set undolevels=100
764 put ='9 foobar'
765 put =''
766 exe "normal! a\<C-G>u\<Esc>"
767 normal G
768 exe 'normal! dv?bar?' . "\<CR>"
769 call assert_equal('9 foo', getline('.'))
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200770 call assert_equal([0, 2, 5, 0], getpos('.'))
771 call assert_equal(2, line('$'))
Bram Moolenaardb510072017-09-28 21:52:17 +0200772 normal u
773 call assert_equal('9 foobar', getline('.'))
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200774 call assert_equal([0, 2, 6, 0], getpos('.'))
775 call assert_equal(3, line('$'))
Bram Moolenaardb510072017-09-28 21:52:17 +0200776
777 set undolevels&
778 enew!
779endfunc
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100780
781func Test_search_cmdline_incsearch_highlight()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100782 CheckOption incsearch
783
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100784 set incsearch hlsearch
785 " need to disable char_avail,
786 " so that expansion of commandline works
787 call test_override("char_avail", 1)
788 new
789 call setline(1, ['aaa 1 the first', ' 2 the second', ' 3 the third'])
790
791 1
792 call feedkeys("/second\<cr>", 'tx')
793 call assert_equal('second', @/)
794 call assert_equal(' 2 the second', getline('.'))
795
796 " Canceling search won't change @/
797 1
798 let @/ = 'last pattern'
799 call feedkeys("/third\<C-c>", 'tx')
800 call assert_equal('last pattern', @/)
801 call feedkeys("/third\<Esc>", 'tx')
802 call assert_equal('last pattern', @/)
803 call feedkeys("/3\<bs>\<bs>", 'tx')
804 call assert_equal('last pattern', @/)
805 call feedkeys("/third\<c-g>\<c-t>\<Esc>", 'tx')
806 call assert_equal('last pattern', @/)
807
808 " clean up
809 set noincsearch nohlsearch
810 bw!
811endfunc
812
813func Test_search_cmdline_incsearch_highlight_attr()
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200814 CheckOption incsearch
815 CheckFeature terminal
816 CheckNotGui
817
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100818 let h = winheight(0)
819 if h < 3
820 return
821 endif
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100822
823 " Prepare buffer text
Bram Moolenaar13deab82017-11-04 18:48:43 +0100824 let lines = ['abb vim vim vi', 'vimvivim']
825 call writefile(lines, 'Xsearch.txt')
826 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
827
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200828 call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
Bram Moolenaarb50773c2018-01-30 22:31:19 +0100829 " wait for vim to complete initialization
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200830 call TermWait(buf)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100831
832 " Get attr of normal(a0), incsearch(a1), hlsearch(a2) highlight
Bram Moolenaar13deab82017-11-04 18:48:43 +0100833 call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
834 call term_sendkeys(buf, '/b')
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200835 call TermWait(buf, 100)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100836 let screen_line1 = term_scrape(buf, 1)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100837 call assert_true(len(screen_line1) > 2)
838 " a0: attr_normal
839 let a0 = screen_line1[0].attr
840 " a1: attr_incsearch
841 let a1 = screen_line1[1].attr
842 " a2: attr_hlsearch
843 let a2 = screen_line1[2].attr
844 call assert_notequal(a0, a1)
845 call assert_notequal(a0, a2)
846 call assert_notequal(a1, a2)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100847 call term_sendkeys(buf, "\<cr>gg0")
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100848
849 " Test incremental highlight search
Bram Moolenaar13deab82017-11-04 18:48:43 +0100850 call term_sendkeys(buf, "/vim")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200851 call TermWait(buf, 100)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100852 " Buffer:
853 " abb vim vim vi
854 " vimvivim
855 " Search: /vim
856 let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a2,a2,a2,a0,a0,a0]
857 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100858 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
859 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100860
861 " Test <C-g>
Bram Moolenaar13deab82017-11-04 18:48:43 +0100862 call term_sendkeys(buf, "\<C-g>\<C-g>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200863 call TermWait(buf, 100)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100864 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
865 let attr_line2 = [a1,a1,a1,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100866 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
867 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100868
869 " Test <C-t>
Bram Moolenaar13deab82017-11-04 18:48:43 +0100870 call term_sendkeys(buf, "\<C-t>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200871 call TermWait(buf, 100)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100872 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a1,a1,a1,a0,a0,a0]
873 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100874 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
875 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100876
877 " Type Enter and a1(incsearch highlight) should become a2(hlsearch highlight)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100878 call term_sendkeys(buf, "\<cr>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200879 call TermWait(buf, 100)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100880 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
881 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100882 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
883 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100884
885 " Test nohlsearch. a2(hlsearch highlight) should become a0(normal highlight)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100886 call term_sendkeys(buf, ":1\<cr>")
887 call term_sendkeys(buf, ":set nohlsearch\<cr>")
888 call term_sendkeys(buf, "/vim")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200889 call TermWait(buf, 100)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100890 let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a0,a0,a0,a0,a0,a0]
891 let attr_line2 = [a0,a0,a0,a0,a0,a0,a0,a0]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100892 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
893 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100894 call delete('Xsearch.txt')
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100895
Bram Moolenaarb94340c2017-11-02 16:16:31 +0100896 call delete('Xsearch.txt')
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100897 bwipe!
898endfunc
Bram Moolenaarf45938c2017-11-02 15:59:57 +0100899
Bram Moolenaar548e5982018-12-26 21:45:00 +0100900func Test_incsearch_cmdline_modifier()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100901 CheckOption incsearch
902
Bram Moolenaar548e5982018-12-26 21:45:00 +0100903 call test_override("char_avail", 1)
904 new
905 call setline(1, ['foo'])
906 set incsearch
907 " Test that error E14 does not occur in parsing command modifier.
908 call feedkeys("V:tab", 'tx')
909
910 call Incsearch_cleanup()
911endfunc
912
Bram Moolenaar9d34d902018-04-27 22:18:12 +0200913func Test_incsearch_scrolling()
Bram Moolenaar494e9062020-05-31 21:28:02 +0200914 CheckRunVimInTerminal
Bram Moolenaar9d34d902018-04-27 22:18:12 +0200915 call assert_equal(0, &scrolloff)
916 call writefile([
917 \ 'let dots = repeat(".", 120)',
918 \ 'set incsearch cmdheight=2 scrolloff=0',
919 \ 'call setline(1, [dots, dots, dots, "", "target", dots, dots])',
920 \ 'normal gg',
921 \ 'redraw',
922 \ ], 'Xscript')
923 let buf = RunVimInTerminal('-S Xscript', {'rows': 9, 'cols': 70})
924 " Need to send one key at a time to force a redraw
925 call term_sendkeys(buf, '/')
926 sleep 100m
927 call term_sendkeys(buf, 't')
928 sleep 100m
929 call term_sendkeys(buf, 'a')
930 sleep 100m
931 call term_sendkeys(buf, 'r')
932 sleep 100m
933 call term_sendkeys(buf, 'g')
934 call VerifyScreenDump(buf, 'Test_incsearch_scrolling_01', {})
935
936 call term_sendkeys(buf, "\<Esc>")
937 call StopVimInTerminal(buf)
938 call delete('Xscript')
939endfunc
940
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200941func Test_incsearch_search_dump()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100942 CheckOption incsearch
943 CheckScreendump
944
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200945 call writefile([
946 \ 'set incsearch hlsearch scrolloff=0',
947 \ 'for n in range(1, 8)',
948 \ ' call setline(n, "foo " . n)',
949 \ 'endfor',
950 \ '3',
951 \ ], 'Xis_search_script')
952 let buf = RunVimInTerminal('-S Xis_search_script', {'rows': 9, 'cols': 70})
953 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
954 " the 'ambiwidth' check.
955 sleep 100m
956
957 " Need to send one key at a time to force a redraw.
958 call term_sendkeys(buf, '/fo')
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200959 call VerifyScreenDump(buf, 'Test_incsearch_search_01', {})
960 call term_sendkeys(buf, "\<Esc>")
961 sleep 100m
962
963 call term_sendkeys(buf, '/\v')
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200964 call VerifyScreenDump(buf, 'Test_incsearch_search_02', {})
965 call term_sendkeys(buf, "\<Esc>")
966
967 call StopVimInTerminal(buf)
968 call delete('Xis_search_script')
969endfunc
970
Bram Moolenaar41f08952021-02-22 22:13:49 +0100971func Test_hlsearch_dump()
972 CheckOption hlsearch
973 CheckScreendump
974
975 call writefile([
976 \ 'set hlsearch cursorline',
977 \ 'call setline(1, ["xxx", "xxx", "xxx"])',
978 \ '/.*',
979 \ '2',
980 \ ], 'Xhlsearch_script')
981 let buf = RunVimInTerminal('-S Xhlsearch_script', {'rows': 6, 'cols': 50})
982 call VerifyScreenDump(buf, 'Test_hlsearch_1', {})
983
984 call term_sendkeys(buf, "/\\_.*\<CR>")
985 call VerifyScreenDump(buf, 'Test_hlsearch_2', {})
986
987 call StopVimInTerminal(buf)
988 call delete('Xhlsearch_script')
989endfunc
990
Bram Moolenaar2d5f3852021-04-21 15:11:42 +0200991func Test_hlsearch_and_visual()
992 CheckOption hlsearch
993 CheckScreendump
994
995 call writefile([
996 \ 'set hlsearch',
997 \ 'call setline(1, repeat(["xxx yyy zzz"], 3))',
998 \ 'hi Search cterm=bold',
999 \ '/yyy',
1000 \ 'call cursor(1, 6)',
1001 \ ], 'Xhlvisual_script')
1002 let buf = RunVimInTerminal('-S Xhlvisual_script', {'rows': 6, 'cols': 40})
1003 call term_sendkeys(buf, "vjj")
1004 call VerifyScreenDump(buf, 'Test_hlsearch_visual_1', {})
1005 call term_sendkeys(buf, "\<Esc>")
1006
1007 call StopVimInTerminal(buf)
1008 call delete('Xhlvisual_script')
1009endfunc
1010
Bram Moolenaare71c0eb2021-05-30 16:43:11 +02001011func Test_hlsearch_block_visual_match()
1012 CheckScreendump
1013
1014 let lines =<< trim END
1015 set hlsearch
1016 call setline(1, ['aa', 'bbbb', 'cccccc'])
1017 END
1018 call writefile(lines, 'Xhlsearch_block')
1019 let buf = RunVimInTerminal('-S Xhlsearch_block', {'rows': 9, 'cols': 60})
1020
1021 call term_sendkeys(buf, "G\<C-V>$kk\<Esc>")
1022 sleep 100m
1023 call term_sendkeys(buf, "/\\%V\<CR>")
1024 sleep 100m
1025 call VerifyScreenDump(buf, 'Test_hlsearch_block_visual_match', {})
1026
1027 call StopVimInTerminal(buf)
1028 call delete('Xhlsearch_block')
1029endfunc
1030
Bram Moolenaar976b8472018-08-12 15:49:47 +02001031func Test_incsearch_substitute()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001032 CheckOption incsearch
1033
Bram Moolenaar976b8472018-08-12 15:49:47 +02001034 call test_override("char_avail", 1)
1035 new
1036 set incsearch
1037 for n in range(1, 10)
1038 call setline(n, 'foo ' . n)
1039 endfor
1040 4
1041 call feedkeys(":.,.+2s/foo\<BS>o\<BS>o/xxx\<cr>", 'tx')
1042 call assert_equal('foo 3', getline(3))
1043 call assert_equal('xxx 4', getline(4))
1044 call assert_equal('xxx 5', getline(5))
1045 call assert_equal('xxx 6', getline(6))
1046 call assert_equal('foo 7', getline(7))
1047
1048 call Incsearch_cleanup()
1049endfunc
1050
Bram Moolenaar795aaa12020-10-02 20:36:01 +02001051func Test_incsearch_substitute_long_line()
1052 new
1053 call test_override("char_avail", 1)
1054 set incsearch
1055
1056 call repeat('x', 100000)->setline(1)
1057 call feedkeys(':s/\%c', 'xt')
1058 redraw
1059 call feedkeys("\<Esc>", 'xt')
1060
1061 call Incsearch_cleanup()
1062 bwipe!
1063endfunc
1064
LemonBoya4399382022-04-09 21:04:08 +01001065func Test_hlsearch_cursearch()
1066 CheckScreendump
1067
1068 let lines =<< trim END
1069 set hlsearch scrolloff=0
Bram Moolenaar9b367502022-04-22 20:07:21 +01001070 call setline(1, ['one', 'foo', 'bar', 'baz', 'foo the foo and foo', 'bar'])
LemonBoya4399382022-04-09 21:04:08 +01001071 hi Search ctermbg=yellow
1072 hi CurSearch ctermbg=blue
1073 END
1074 call writefile(lines, 'Xhlsearch_cursearch')
1075 let buf = RunVimInTerminal('-S Xhlsearch_cursearch', {'rows': 9, 'cols': 60})
1076
1077 call term_sendkeys(buf, "gg/foo\<CR>")
1078 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_1', {})
1079
1080 call term_sendkeys(buf, "n")
1081 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2', {})
1082
Bram Moolenaar9b367502022-04-22 20:07:21 +01001083 call term_sendkeys(buf, "n")
1084 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2a', {})
1085
1086 call term_sendkeys(buf, "n")
1087 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2b', {})
1088
1089 call term_sendkeys(buf, ":call setline(5, 'foo')\<CR>")
1090 call term_sendkeys(buf, "0?\<CR>")
LemonBoya4399382022-04-09 21:04:08 +01001091 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_3', {})
1092
1093 call term_sendkeys(buf, "gg/foo\\nbar\<CR>")
Bram Moolenaar693ccd12022-04-16 12:04:37 +01001094 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_1', {})
1095
1096 call term_sendkeys(buf, ":call setline(1, ['---', 'abcdefg', 'hijkl', '---', 'abcdefg', 'hijkl'])\<CR>")
1097 call term_sendkeys(buf, "gg/efg\\nhij\<CR>")
1098 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_2', {})
1099 call term_sendkeys(buf, "h\<C-L>")
1100 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_3', {})
1101 call term_sendkeys(buf, "j\<C-L>")
1102 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_4', {})
1103 call term_sendkeys(buf, "h\<C-L>")
1104 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_5', {})
LemonBoya4399382022-04-09 21:04:08 +01001105
Bram Moolenaar368137a2022-05-31 13:43:12 +01001106 " check clearing CurSearch when using it for another match
1107 call term_sendkeys(buf, "G?^abcd\<CR>Y")
1108 call term_sendkeys(buf, "kkP")
1109 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_changed_1', {})
1110
LemonBoya4399382022-04-09 21:04:08 +01001111 call StopVimInTerminal(buf)
1112 call delete('Xhlsearch_cursearch')
1113endfunc
1114
Bram Moolenaar164251f2018-08-12 16:26:58 +02001115" Similar to Test_incsearch_substitute() but with a screendump halfway.
1116func Test_incsearch_substitute_dump()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001117 CheckOption incsearch
1118 CheckScreendump
1119
Bram Moolenaar164251f2018-08-12 16:26:58 +02001120 call writefile([
1121 \ 'set incsearch hlsearch scrolloff=0',
1122 \ 'for n in range(1, 10)',
1123 \ ' call setline(n, "foo " . n)',
1124 \ 'endfor',
Bram Moolenaar2f6a3462018-08-14 18:16:52 +02001125 \ 'call setline(11, "bar 11")',
Bram Moolenaar164251f2018-08-12 16:26:58 +02001126 \ '3',
1127 \ ], 'Xis_subst_script')
1128 let buf = RunVimInTerminal('-S Xis_subst_script', {'rows': 9, 'cols': 70})
1129 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1130 " the 'ambiwidth' check.
1131 sleep 100m
1132
1133 " Need to send one key at a time to force a redraw.
Bram Moolenaarc7f08b72018-08-12 17:39:14 +02001134 " Select three lines at the cursor with typed pattern.
Bram Moolenaar164251f2018-08-12 16:26:58 +02001135 call term_sendkeys(buf, ':.,.+2s/')
1136 sleep 100m
1137 call term_sendkeys(buf, 'f')
1138 sleep 100m
1139 call term_sendkeys(buf, 'o')
1140 sleep 100m
1141 call term_sendkeys(buf, 'o')
1142 call VerifyScreenDump(buf, 'Test_incsearch_substitute_01', {})
Bram Moolenaarc7f08b72018-08-12 17:39:14 +02001143 call term_sendkeys(buf, "\<Esc>")
1144
1145 " Select three lines at the cursor using previous pattern.
1146 call term_sendkeys(buf, "/foo\<CR>")
1147 sleep 100m
1148 call term_sendkeys(buf, ':.,.+2s//')
Bram Moolenaarc7f08b72018-08-12 17:39:14 +02001149 call VerifyScreenDump(buf, 'Test_incsearch_substitute_02', {})
1150
1151 " Deleting last slash should remove the match.
1152 call term_sendkeys(buf, "\<BS>")
Bram Moolenaarc7f08b72018-08-12 17:39:14 +02001153 call VerifyScreenDump(buf, 'Test_incsearch_substitute_03', {})
Bram Moolenaar60d08712018-08-12 21:53:15 +02001154 call term_sendkeys(buf, "\<Esc>")
1155
1156 " Reverse range is accepted
1157 call term_sendkeys(buf, ':5,2s/foo')
Bram Moolenaar60d08712018-08-12 21:53:15 +02001158 call VerifyScreenDump(buf, 'Test_incsearch_substitute_04', {})
Bram Moolenaar164251f2018-08-12 16:26:58 +02001159 call term_sendkeys(buf, "\<Esc>")
Bram Moolenaar2b926fc2018-08-13 11:07:57 +02001160
1161 " White space after the command is skipped
1162 call term_sendkeys(buf, ':2,3sub /fo')
Bram Moolenaar2b926fc2018-08-13 11:07:57 +02001163 call VerifyScreenDump(buf, 'Test_incsearch_substitute_05', {})
1164 call term_sendkeys(buf, "\<Esc>")
1165
Bram Moolenaar33c4dbb2018-08-14 16:06:16 +02001166 " Command modifiers are skipped
1167 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 +02001168 call VerifyScreenDump(buf, 'Test_incsearch_substitute_06', {})
1169 call term_sendkeys(buf, "\<Esc>")
1170
Bram Moolenaar2f6a3462018-08-14 18:16:52 +02001171 " Cursorline highlighting at match
1172 call term_sendkeys(buf, ":set cursorline\<CR>")
1173 call term_sendkeys(buf, 'G9G')
1174 call term_sendkeys(buf, ':9,11s/bar')
Bram Moolenaar2f6a3462018-08-14 18:16:52 +02001175 call VerifyScreenDump(buf, 'Test_incsearch_substitute_07', {})
1176 call term_sendkeys(buf, "\<Esc>")
1177
1178 " Cursorline highlighting at cursor when no match
1179 call term_sendkeys(buf, ':9,10s/bar')
Bram Moolenaar2f6a3462018-08-14 18:16:52 +02001180 call VerifyScreenDump(buf, 'Test_incsearch_substitute_08', {})
1181 call term_sendkeys(buf, "\<Esc>")
1182
Bram Moolenaar8b0d5ce2018-08-22 23:05:44 +02001183 " Only \v handled as empty pattern, does not move cursor
1184 call term_sendkeys(buf, '3G4G')
1185 call term_sendkeys(buf, ":nohlsearch\<CR>")
1186 call term_sendkeys(buf, ':6,7s/\v')
Bram Moolenaar8b0d5ce2018-08-22 23:05:44 +02001187 call VerifyScreenDump(buf, 'Test_incsearch_substitute_09', {})
1188 call term_sendkeys(buf, "\<Esc>")
1189
Bram Moolenaarf13daa42018-08-31 22:09:54 +02001190 call term_sendkeys(buf, ":set nocursorline\<CR>")
1191
1192 " All matches are highlighted for 'hlsearch' after the incsearch canceled
1193 call term_sendkeys(buf, "1G*")
1194 call term_sendkeys(buf, ":2,5s/foo")
1195 sleep 100m
1196 call term_sendkeys(buf, "\<Esc>")
1197 call VerifyScreenDump(buf, 'Test_incsearch_substitute_10', {})
1198
Bram Moolenaar65985ac2018-09-16 17:08:04 +02001199 call term_sendkeys(buf, ":split\<CR>")
1200 call term_sendkeys(buf, ":let @/ = 'xyz'\<CR>")
1201 call term_sendkeys(buf, ":%s/.")
1202 call VerifyScreenDump(buf, 'Test_incsearch_substitute_11', {})
1203 call term_sendkeys(buf, "\<BS>")
1204 call VerifyScreenDump(buf, 'Test_incsearch_substitute_12', {})
1205 call term_sendkeys(buf, "\<Esc>")
1206 call VerifyScreenDump(buf, 'Test_incsearch_substitute_13', {})
Bram Moolenaarc6725252019-11-23 21:56:46 +01001207 call term_sendkeys(buf, ":%bwipe!\<CR>")
1208 call term_sendkeys(buf, ":only!\<CR>")
1209
1210 " get :'<,'>s command in history
1211 call term_sendkeys(buf, ":set cmdheight=2\<CR>")
1212 call term_sendkeys(buf, "aasdfasdf\<Esc>")
1213 call term_sendkeys(buf, "V:s/a/b/g\<CR>")
1214 " Using '<,'> does not give E20
1215 call term_sendkeys(buf, ":new\<CR>")
1216 call term_sendkeys(buf, "aasdfasdf\<Esc>")
1217 call term_sendkeys(buf, ":\<Up>\<Up>")
1218 call VerifyScreenDump(buf, 'Test_incsearch_substitute_14', {})
1219 call term_sendkeys(buf, "<Esc>")
Bram Moolenaar65985ac2018-09-16 17:08:04 +02001220
Bram Moolenaar164251f2018-08-12 16:26:58 +02001221 call StopVimInTerminal(buf)
1222 call delete('Xis_subst_script')
1223endfunc
1224
Bram Moolenaarc036e872020-02-21 21:30:52 +01001225func Test_incsearch_highlighting()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001226 CheckOption incsearch
1227 CheckScreendump
Bram Moolenaarc036e872020-02-21 21:30:52 +01001228
1229 call writefile([
1230 \ 'set incsearch hlsearch',
1231 \ 'call setline(1, "hello/there")',
1232 \ ], 'Xis_subst_hl_script')
1233 let buf = RunVimInTerminal('-S Xis_subst_hl_script', {'rows': 4, 'cols': 20})
1234 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1235 " the 'ambiwidth' check.
1236 sleep 300m
1237
1238 " Using a different search delimiter should still highlight matches
1239 " that contain a '/'.
1240 call term_sendkeys(buf, ":%s;ello/the")
1241 call VerifyScreenDump(buf, 'Test_incsearch_substitute_15', {})
1242 call term_sendkeys(buf, "<Esc>")
Bram Moolenaarb68df222020-03-19 15:05:28 +01001243
1244 call StopVimInTerminal(buf)
1245 call delete('Xis_subst_hl_script')
Bram Moolenaarc036e872020-02-21 21:30:52 +01001246endfunc
1247
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +01001248func Test_incsearch_with_change()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001249 CheckFeature timers
1250 CheckOption incsearch
1251 CheckScreendump
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +01001252
1253 call writefile([
1254 \ 'set incsearch hlsearch scrolloff=0',
1255 \ 'call setline(1, ["one", "two ------ X", "three"])',
1256 \ 'call timer_start(200, { _ -> setline(2, "x")})',
1257 \ ], 'Xis_change_script')
1258 let buf = RunVimInTerminal('-S Xis_change_script', {'rows': 9, 'cols': 70})
1259 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1260 " the 'ambiwidth' check.
Bram Moolenaare86ecbd2019-02-21 17:48:59 +01001261 sleep 300m
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +01001262
1263 " Highlight X, it will be deleted by the timer callback.
1264 call term_sendkeys(buf, ':%s/X')
1265 call VerifyScreenDump(buf, 'Test_incsearch_change_01', {})
1266 call term_sendkeys(buf, "\<Esc>")
1267
1268 call StopVimInTerminal(buf)
1269 call delete('Xis_change_script')
1270endfunc
1271
Bram Moolenaar81f56532018-08-18 16:19:42 +02001272" Similar to Test_incsearch_substitute_dump() for :sort
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +02001273func Test_incsearch_sort_dump()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001274 CheckOption incsearch
1275 CheckScreendump
1276
Bram Moolenaar81f56532018-08-18 16:19:42 +02001277 call writefile([
1278 \ 'set incsearch hlsearch scrolloff=0',
1279 \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
1280 \ ], 'Xis_sort_script')
1281 let buf = RunVimInTerminal('-S Xis_sort_script', {'rows': 9, 'cols': 70})
1282 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1283 " the 'ambiwidth' check.
1284 sleep 100m
1285
Bram Moolenaar81f56532018-08-18 16:19:42 +02001286 call term_sendkeys(buf, ':sort ni u /on')
Bram Moolenaar81f56532018-08-18 16:19:42 +02001287 call VerifyScreenDump(buf, 'Test_incsearch_sort_01', {})
1288 call term_sendkeys(buf, "\<Esc>")
1289
Bram Moolenaar333015a2020-04-25 15:54:16 +02001290 call term_sendkeys(buf, ':sort! /on')
1291 call VerifyScreenDump(buf, 'Test_incsearch_sort_02', {})
1292 call term_sendkeys(buf, "\<Esc>")
1293
Bram Moolenaar81f56532018-08-18 16:19:42 +02001294 call StopVimInTerminal(buf)
1295 call delete('Xis_sort_script')
1296endfunc
1297
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001298" Similar to Test_incsearch_substitute_dump() for :vimgrep famiry
1299func Test_incsearch_vimgrep_dump()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001300 CheckOption incsearch
1301 CheckScreendump
1302
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001303 call writefile([
1304 \ 'set incsearch hlsearch scrolloff=0',
1305 \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
1306 \ ], 'Xis_vimgrep_script')
1307 let buf = RunVimInTerminal('-S Xis_vimgrep_script', {'rows': 9, 'cols': 70})
1308 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1309 " the 'ambiwidth' check.
1310 sleep 100m
1311
1312 " Need to send one key at a time to force a redraw.
1313 call term_sendkeys(buf, ':vimgrep on')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001314 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_01', {})
1315 call term_sendkeys(buf, "\<Esc>")
1316
1317 call term_sendkeys(buf, ':vimg /on/ *.txt')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001318 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_02', {})
1319 call term_sendkeys(buf, "\<Esc>")
1320
1321 call term_sendkeys(buf, ':vimgrepadd "\<on')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001322 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_03', {})
1323 call term_sendkeys(buf, "\<Esc>")
1324
1325 call term_sendkeys(buf, ':lv "tha')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001326 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_04', {})
1327 call term_sendkeys(buf, "\<Esc>")
1328
1329 call term_sendkeys(buf, ':lvimgrepa "the" **/*.txt')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001330 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_05', {})
1331 call term_sendkeys(buf, "\<Esc>")
1332
1333 call StopVimInTerminal(buf)
1334 call delete('Xis_vimgrep_script')
1335endfunc
1336
Bram Moolenaar198cb662018-09-06 21:44:17 +02001337func Test_keep_last_search_pattern()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001338 CheckOption incsearch
1339
Bram Moolenaar198cb662018-09-06 21:44:17 +02001340 new
1341 call setline(1, ['foo', 'foo', 'foo'])
1342 set incsearch
1343 call test_override("char_avail", 1)
1344 let @/ = 'bar'
1345 call feedkeys(":/foo/s//\<Esc>", 'ntx')
1346 call assert_equal('bar', @/)
1347
Bram Moolenaar50eb16c2018-09-15 15:42:40 +02001348 " no error message if pattern not found
1349 call feedkeys(":/xyz/s//\<Esc>", 'ntx')
1350 call assert_equal('bar', @/)
1351
Bram Moolenaar198cb662018-09-06 21:44:17 +02001352 bwipe!
1353 call test_override("ALL", 0)
1354 set noincsearch
1355endfunc
1356
Bram Moolenaar99f043a2018-09-09 15:54:14 +02001357func Test_word_under_cursor_after_match()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001358 CheckOption incsearch
1359
Bram Moolenaar99f043a2018-09-09 15:54:14 +02001360 new
1361 call setline(1, 'foo bar')
1362 set incsearch
1363 call test_override("char_avail", 1)
1364 try
1365 call feedkeys("/foo\<C-R>\<C-W>\<CR>", 'ntx')
1366 catch /E486:/
1367 endtry
1368 call assert_equal('foobar', @/)
1369
1370 bwipe!
1371 call test_override("ALL", 0)
1372 set noincsearch
1373endfunc
1374
1375func Test_subst_word_under_cursor()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001376 CheckOption incsearch
1377
Bram Moolenaar99f043a2018-09-09 15:54:14 +02001378 new
1379 call setline(1, ['int SomeLongName;', 'for (xxx = 1; xxx < len; ++xxx)'])
1380 set incsearch
1381 call test_override("char_avail", 1)
1382 call feedkeys("/LongName\<CR>", 'ntx')
1383 call feedkeys(":%s/xxx/\<C-R>\<C-W>/g\<CR>", 'ntx')
1384 call assert_equal('for (SomeLongName = 1; SomeLongName < len; ++SomeLongName)', getline(2))
1385
1386 bwipe!
1387 call test_override("ALL", 0)
1388 set noincsearch
1389endfunc
1390
Bram Moolenaarf45938c2017-11-02 15:59:57 +01001391func Test_search_undefined_behaviour()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001392 CheckFeature terminal
1393
Bram Moolenaarf45938c2017-11-02 15:59:57 +01001394 let h = winheight(0)
1395 if h < 3
1396 return
1397 endif
1398 " did cause an undefined left shift
1399 let g:buf = term_start([GetVimProg(), '--clean', '-e', '-s', '-c', 'call search(getline("."))', 'samples/test000'], {'term_rows': 3})
1400 call assert_equal([''], getline(1, '$'))
1401 call term_sendkeys(g:buf, ":qa!\<cr>")
1402 bwipe!
1403endfunc
Bram Moolenaar2973daa2017-11-02 23:15:40 +01001404
1405func Test_search_undefined_behaviour2()
1406 call search("\%UC0000000")
1407endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01001408
1409" Test for search('multi-byte char', 'bce')
1410func Test_search_multibyte()
Bram Moolenaarfb094e12017-11-05 20:59:28 +01001411 let save_enc = &encoding
1412 set encoding=utf8
1413 enew!
1414 call append('$', 'A')
1415 call cursor(2, 1)
1416 call assert_equal(2, search('A', 'bce', line('.')))
1417 enew!
1418 let &encoding = save_enc
1419endfunc
Bram Moolenaar890dd052017-12-16 19:59:37 +01001420
1421" This was causing E874. Also causes an invalid read?
1422func Test_look_behind()
1423 new
Bram Moolenaar3ba35402019-12-21 22:00:50 +01001424 call setline(1, '0\|\&\n\@<=')
Bram Moolenaar890dd052017-12-16 19:59:37 +01001425 call search(getline("."))
1426 bwipe!
1427endfunc
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +01001428
Bram Moolenaar872bee52021-05-24 22:56:15 +02001429func Test_search_visual_area_linewise()
1430 new
1431 call setline(1, ['aa', 'bb', 'cc'])
1432 exe "normal 2GV\<Esc>"
1433 for engine in [1, 2]
1434 exe 'set regexpengine=' .. engine
1435 exe "normal gg/\\%'<\<CR>>"
1436 call assert_equal([0, 2, 1, 0, 1], getcurpos(), 'engine ' .. engine)
1437 exe "normal gg/\\%'>\<CR>"
1438 call assert_equal([0, 2, 2, 0, 2], getcurpos(), 'engine ' .. engine)
1439 endfor
1440
1441 bwipe!
1442 set regexpengine&
1443endfunc
1444
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +01001445func Test_search_sentence()
1446 new
1447 " this used to cause a crash
Bram Moolenaar1bd999f2017-12-19 22:25:40 +01001448 /\%'(
1449 /
Bram Moolenaar872bee52021-05-24 22:56:15 +02001450 bwipe
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +01001451endfunc
Bram Moolenaar2fb8f682018-12-01 13:14:45 +01001452
1453" Test that there is no crash when there is a last search pattern but no last
1454" substitute pattern.
1455func Test_no_last_substitute_pat()
1456 " Use viminfo to set the last search pattern to a string and make the last
1457 " substitute pattern the most recent used and make it empty (NULL).
1458 call writefile(['~MSle0/bar', '~MSle0~&'], 'Xviminfo')
1459 rviminfo! Xviminfo
1460 call assert_fails('normal n', 'E35:')
1461
1462 call delete('Xviminfo')
1463endfunc
Bram Moolenaar5f5e2032018-12-14 15:47:03 +01001464
1465func Test_search_Ctrl_L_combining()
1466 " Make sure, that Ctrl-L works correctly with combining characters.
1467 " It uses an artificial example of an 'a' with 4 combining chars:
Bram Moolenaar3ba35402019-12-21 22:00:50 +01001468 " 'a' U+0061 Dec:97 LATIN SMALL LETTER A &#x61; /\%u61\Z "\u0061"
Bram Moolenaar5f5e2032018-12-14 15:47:03 +01001469 " ' ̀' U+0300 Dec:768 COMBINING GRAVE ACCENT &#x300; /\%u300\Z "\u0300"
1470 " ' ́' U+0301 Dec:769 COMBINING ACUTE ACCENT &#x301; /\%u301\Z "\u0301"
1471 " ' ̇' U+0307 Dec:775 COMBINING DOT ABOVE &#x307; /\%u307\Z "\u0307"
Bram Moolenaar3ba35402019-12-21 22:00:50 +01001472 " ' ̣' U+0323 Dec:803 COMBINING DOT BELOW &#x323; /\%u323 "\u0323"
Bram Moolenaar5f5e2032018-12-14 15:47:03 +01001473 " Those should also appear on the commandline
Bram Moolenaarb68df222020-03-19 15:05:28 +01001474 CheckOption incsearch
1475
Bram Moolenaar5f5e2032018-12-14 15:47:03 +01001476 call Cmdline3_prep()
1477 1
1478 let bufcontent = ['', 'Miạ̀́̇m']
1479 call append('$', bufcontent)
1480 call feedkeys("/Mi\<c-l>\<c-l>\<cr>", 'tx')
1481 call assert_equal(5, line('.'))
1482 call assert_equal(bufcontent[1], @/)
1483 call Incsearch_cleanup()
1484endfunc
Bram Moolenaar527a2d82019-02-21 22:28:51 +01001485
Bram Moolenaarab350f82019-02-28 06:25:00 +01001486func Test_large_hex_chars1()
Bram Moolenaar527a2d82019-02-21 22:28:51 +01001487 " This used to cause a crash, the character becomes an NFA state.
1488 try
1489 /\%Ufffffc23
1490 catch
1491 call assert_match('E678:', v:exception)
1492 endtry
Bram Moolenaarab350f82019-02-28 06:25:00 +01001493 try
1494 set re=1
1495 /\%Ufffffc23
1496 catch
1497 call assert_match('E678:', v:exception)
1498 endtry
1499 set re&
1500endfunc
1501
1502func Test_large_hex_chars2()
1503 " This used to cause a crash, the character becomes an NFA state.
1504 try
1505 /[\Ufffffc1f]
1506 catch
1507 call assert_match('E486:', v:exception)
1508 endtry
1509 try
1510 set re=1
1511 /[\Ufffffc1f]
1512 catch
1513 call assert_match('E486:', v:exception)
1514 endtry
1515 set re&
Bram Moolenaar527a2d82019-02-21 22:28:51 +01001516endfunc
Bram Moolenaarcd625122019-02-22 17:29:43 +01001517
1518func Test_one_error_msg()
Bram Moolenaar8832a342020-04-11 18:36:38 +02001519 " This was also giving an internal error
Bram Moolenaarcd625122019-02-22 17:29:43 +01001520 call assert_fails('call search(" \\((\\v[[=P=]]){185}+ ")', 'E871:')
1521endfunc
Bram Moolenaar730f48f2019-04-11 13:45:57 +02001522
1523func Test_incsearch_add_char_under_cursor()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001524 CheckOption incsearch
1525
Bram Moolenaar730f48f2019-04-11 13:45:57 +02001526 set incsearch
1527 new
1528 call setline(1, ['find match', 'anything'])
1529 1
1530 call test_override('char_avail', 1)
1531 call feedkeys("fc/m\<C-L>\<C-L>\<C-L>\<C-L>\<C-L>\<CR>", 'tx')
1532 call assert_equal('match', @/)
1533 call test_override('char_avail', 0)
1534
1535 set incsearch&
1536 bwipe!
1537endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001538
1539" Test for the search() function with match at the cursor position
1540func Test_search_match_at_curpos()
1541 new
1542 call append(0, ['foobar', '', 'one two', ''])
1543
1544 normal gg
1545
Bram Moolenaar196b4662019-09-06 21:34:30 +02001546 eval 'foobar'->search('c')
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001547 call assert_equal([1, 1], [line('.'), col('.')])
1548
1549 normal j
1550 call search('^$', 'c')
1551 call assert_equal([2, 1], [line('.'), col('.')])
1552
1553 call search('^$', 'bc')
1554 call assert_equal([2, 1], [line('.'), col('.')])
1555
1556 exe "normal /two\<CR>"
1557 call search('.', 'c')
1558 call assert_equal([3, 5], [line('.'), col('.')])
1559
1560 close!
1561endfunc
Bram Moolenaardb294ad2019-06-06 12:49:29 +02001562
Bram Moolenaar0e05de42020-03-25 22:23:46 +01001563" Test for error cases with the search() function
1564func Test_search_errors()
1565 call assert_fails("call search('pat', [])", 'E730:')
1566 call assert_fails("call search('pat', 'b', {})", 'E728:')
1567 call assert_fails("call search('pat', 'b', 1, [])", 'E745:')
1568 call assert_fails("call search('pat', 'ns')", 'E475:')
1569 call assert_fails("call search('pat', 'mr')", 'E475:')
Bram Moolenaar8832a342020-04-11 18:36:38 +02001570
1571 new
1572 call setline(1, ['foo', 'bar'])
1573 call assert_fails('call feedkeys("/foo/;/bar/;\<CR>", "tx")', 'E386:')
1574 bwipe!
Bram Moolenaar0e05de42020-03-25 22:23:46 +01001575endfunc
1576
Paul Ollis65745772022-06-05 16:55:54 +01001577func Test_search_timeout()
1578 new
Bram Moolenaar616592e2022-06-17 15:17:10 +01001579 " use a complicated pattern that should be slow with the BT engine
Paul Ollis65745772022-06-05 16:55:54 +01001580 let pattern = '\%#=1a*.*X\@<=b*'
Bram Moolenaar616592e2022-06-17 15:17:10 +01001581
1582 " use a timeout of 50 msec
1583 let search_timeout = 0.05
1584
1585 " fill the buffer so that it takes 15 times the timeout to search
Paul Ollis65745772022-06-05 16:55:54 +01001586 let slow_target_timeout = search_timeout * 15.0
1587
Bram Moolenaar616592e2022-06-17 15:17:10 +01001588 " Fill the buffer with more and more text until searching takes more time
1589 " than slow_target_timeout.
Paul Ollis65745772022-06-05 16:55:54 +01001590 for n in range(40, 400, 30)
1591 call setline(1, ['aaa', repeat('abc ', n), 'ccc'])
1592 let start = reltime()
1593 call search(pattern, '', 0)
1594 let elapsed = reltimefloat(reltime(start))
1595 if elapsed > slow_target_timeout
1596 break
1597 endif
1598 endfor
1599 call assert_true(elapsed > slow_target_timeout)
1600
Bram Moolenaar616592e2022-06-17 15:17:10 +01001601 " Check that the timeout kicks in, the time should be less than half of what
1602 " we measured without the timeout. This is permissive, because the timer is
1603 " known to overrun, especially when using valgrind.
Paul Ollis65745772022-06-05 16:55:54 +01001604 let max_time = elapsed / 2.0
1605 let start = reltime()
1606 call search(pattern, '', 0, float2nr(search_timeout * 1000))
1607 let elapsed = reltimefloat(reltime(start))
Bram Moolenaar616592e2022-06-17 15:17:10 +01001608 call assert_inrange(search_timeout * 0.9, max_time, elapsed)
Paul Ollis65745772022-06-05 16:55:54 +01001609
1610 bwipe!
1611endfunc
1612
Bram Moolenaardb294ad2019-06-06 12:49:29 +02001613func Test_search_display_pattern()
1614 new
1615 call setline(1, ['foo', 'bar', 'foobar'])
1616
1617 call cursor(1, 1)
1618 let @/ = 'foo'
Bram Moolenaara4208962019-08-24 20:50:19 +02001619 let pat = @/->escape('()*?'. '\s\+')
Bram Moolenaardb294ad2019-06-06 12:49:29 +02001620 let g:a = execute(':unsilent :norm! n')
1621 call assert_match(pat, g:a)
1622
1623 " right-left
1624 if exists("+rightleft")
1625 set rl
1626 call cursor(1, 1)
1627 let @/ = 'foo'
1628 let pat = 'oof/\s\+'
1629 let g:a = execute(':unsilent :norm! n')
1630 call assert_match(pat, g:a)
1631 set norl
1632 endif
1633endfunc
Bram Moolenaar196b4662019-09-06 21:34:30 +02001634
1635func Test_searchdecl()
1636 let lines =<< trim END
1637 int global;
1638
1639 func()
1640 {
1641 int global;
1642 if (cond) {
1643 int local;
1644 }
1645 int local;
1646 // comment
1647 }
1648 END
1649 new
1650 call setline(1, lines)
1651 10
1652 call assert_equal(0, searchdecl('local', 0, 0))
1653 call assert_equal(7, getcurpos()[1])
1654
1655 10
1656 call assert_equal(0, 'local'->searchdecl(0, 1))
1657 call assert_equal(9, getcurpos()[1])
1658
1659 10
1660 call assert_equal(0, searchdecl('global'))
1661 call assert_equal(5, getcurpos()[1])
1662
1663 10
1664 call assert_equal(0, searchdecl('global', 1))
1665 call assert_equal(1, getcurpos()[1])
1666
1667 bwipe!
1668endfunc
Bram Moolenaar98a336d2020-01-20 20:22:30 +01001669
1670func Test_search_special()
Bram Moolenaarfe4bbac2020-01-20 21:12:20 +01001671 " this was causing illegal memory access and an endless loop
1672 set t_PE=
Bram Moolenaar98a336d2020-01-20 20:22:30 +01001673 exe "norm /\x80PS"
1674endfunc
Bram Moolenaar07ada5f2020-02-05 20:38:22 +01001675
1676" Test for command failures when the last search pattern is not set.
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001677" Need to run this in a new vim instance where last search pattern is not set.
Bram Moolenaar07ada5f2020-02-05 20:38:22 +01001678func Test_search_with_no_last_pat()
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001679 let lines =<< trim [SCRIPT]
1680 call assert_fails("normal i\<C-R>/\e", 'E35:')
1681 call assert_fails("exe '/'", 'E35:')
1682 call assert_fails("exe '?'", 'E35:')
1683 call assert_fails("/", 'E35:')
1684 call assert_fails("?", 'E35:')
1685 call assert_fails("normal n", 'E35:')
1686 call assert_fails("normal N", 'E35:')
1687 call assert_fails("normal gn", 'E35:')
1688 call assert_fails("normal gN", 'E35:')
1689 call assert_fails("normal cgn", 'E35:')
1690 call assert_fails("normal cgN", 'E35:')
1691 let p = []
1692 let p = @/
1693 call assert_equal('', p)
1694 call assert_fails("normal :\<C-R>/", 'E35:')
1695 call assert_fails("//p", 'E35:')
1696 call assert_fails(";//p", 'E35:')
1697 call assert_fails("??p", 'E35:')
1698 call assert_fails(";??p", 'E35:')
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001699 call assert_fails('g//p', ['E35:', 'E476:'])
1700 call assert_fails('v//p', ['E35:', 'E476:'])
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001701 call writefile(v:errors, 'Xresult')
1702 qall!
1703 [SCRIPT]
1704 call writefile(lines, 'Xscript')
1705
1706 if RunVim([], [], '--clean -S Xscript')
1707 call assert_equal([], readfile('Xresult'))
1708 endif
1709 call delete('Xscript')
1710 call delete('Xresult')
Bram Moolenaar07ada5f2020-02-05 20:38:22 +01001711endfunc
1712
1713" Test for using tilde (~) atom in search. This should use the last used
1714" substitute pattern
1715func Test_search_tilde_pat()
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001716 let lines =<< trim [SCRIPT]
1717 set regexpengine=1
1718 call assert_fails('exe "normal /~\<CR>"', 'E33:')
1719 call assert_fails('exe "normal ?~\<CR>"', 'E33:')
1720 set regexpengine=2
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001721 call assert_fails('exe "normal /~\<CR>"', ['E33:', 'E383:'])
1722 call assert_fails('exe "normal ?~\<CR>"', ['E33:', 'E383:'])
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001723 set regexpengine&
1724 call writefile(v:errors, 'Xresult')
1725 qall!
1726 [SCRIPT]
1727 call writefile(lines, 'Xscript')
1728 if RunVim([], [], '--clean -S Xscript')
1729 call assert_equal([], readfile('Xresult'))
1730 endif
1731 call delete('Xscript')
1732 call delete('Xresult')
Bram Moolenaar07ada5f2020-02-05 20:38:22 +01001733endfunc
1734
Bram Moolenaar406cd902020-02-18 21:54:41 +01001735" Test for searching a pattern that is not present with 'nowrapscan'
1736func Test_search_pat_not_found()
1737 new
1738 set nowrapscan
1739 let @/ = '1abcxyz2'
1740 call assert_fails('normal n', 'E385:')
1741 call assert_fails('normal N', 'E384:')
1742 set wrapscan&
1743 close
1744endfunc
1745
1746" Test for v:searchforward variable
1747func Test_searchforward_var()
1748 new
1749 call setline(1, ['foo', '', 'foo'])
1750 call cursor(2, 1)
1751 let @/ = 'foo'
1752 let v:searchforward = 0
1753 normal N
1754 call assert_equal(3, line('.'))
1755 call cursor(2, 1)
1756 let v:searchforward = 1
1757 normal N
1758 call assert_equal(1, line('.'))
1759 close!
1760endfunc
1761
Bram Moolenaar476a6132020-04-08 19:48:56 +02001762" Test for invalid regular expressions
1763func Test_invalid_regexp()
1764 set regexpengine=1
1765 call assert_fails("call search(repeat('\\(.\\)', 10))", 'E51:')
Bram Moolenaar4d23c522020-04-09 18:42:11 +02001766 call assert_fails("call search('\\%(')", 'E53:')
1767 call assert_fails("call search('\\(')", 'E54:')
1768 call assert_fails("call search('\\)')", 'E55:')
Bram Moolenaar476a6132020-04-08 19:48:56 +02001769 call assert_fails("call search('x\\@#')", 'E59:')
Bram Moolenaar4d23c522020-04-09 18:42:11 +02001770 call assert_fails('call search(''\v%(%(%(%(%(%(%(%(%(%(%(a){1}){1}){1}){1}){1}){1}){1}){1}){1}){1}){1}'')', 'E60:')
1771 call assert_fails("call search('a\\+*')", 'E61:')
Bram Moolenaar476a6132020-04-08 19:48:56 +02001772 call assert_fails("call search('\\_m')", 'E63:')
1773 call assert_fails("call search('\\+')", 'E64:')
1774 call assert_fails("call search('\\1')", 'E65:')
1775 call assert_fails("call search('\\z\\(\\)')", 'E66:')
1776 call assert_fails("call search('\\z2')", 'E67:')
1777 call assert_fails("call search('\\zx')", 'E68:')
1778 call assert_fails("call search('\\%[ab')", 'E69:')
1779 call assert_fails("call search('\\%[]')", 'E70:')
1780 call assert_fails("call search('\\%a')", 'E71:')
1781 call assert_fails("call search('ab\\%[\\(cd\\)]')", 'E369:')
1782 call assert_fails("call search('ab\\%[\\%(cd\\)]')", 'E369:')
1783 set regexpengine=2
1784 call assert_fails("call search('\\_')", 'E865:')
1785 call assert_fails("call search('\\+')", 'E866:')
1786 call assert_fails("call search('\\zx')", 'E867:')
1787 call assert_fails("call search('\\%a')", 'E867:')
1788 call assert_fails("call search('x\\@#')", 'E869:')
1789 call assert_fails("call search(repeat('\\(.\\)', 10))", 'E872:')
1790 call assert_fails("call search('\\_m')", 'E877:')
1791 call assert_fails("call search('\\%(')", 'E53:')
1792 call assert_fails("call search('\\(')", 'E54:')
1793 call assert_fails("call search('\\)')", 'E55:')
1794 call assert_fails("call search('\\z\\(\\)')", 'E66:')
Dominique Pelle8bfa0eb2022-01-02 16:16:33 +00001795 call assert_fails("call search('\\z2')", 'E67:')
1796 call assert_fails("call search('\\zx')", 'E867:')
Bram Moolenaar476a6132020-04-08 19:48:56 +02001797 call assert_fails("call search('\\%[ab')", 'E69:')
Bram Moolenaar4d23c522020-04-09 18:42:11 +02001798 call assert_fails("call search('\\%[]')", 'E70:')
Bram Moolenaar476a6132020-04-08 19:48:56 +02001799 call assert_fails("call search('\\%9999999999999999999999999999v')", 'E951:')
1800 set regexpengine&
1801 call assert_fails("call search('\\%#=3ab')", 'E864:')
1802endfunc
1803
Bram Moolenaar004a6782020-04-11 17:09:31 +02001804" Test for searching a very complex pattern in a string. Should switch the
1805" regexp engine from NFA to the old engine.
1806func Test_regexp_switch_engine()
1807 let l = readfile('samples/re.freeze.txt')
1808 let v = substitute(l[4], '..\@<!', '', '')
1809 call assert_equal(l[4], v)
1810endfunc
1811
1812" Test for the \%V atom to search within visually selected text
1813func Test_search_in_visual_area()
1814 new
1815 call setline(1, ['foo bar1', 'foo bar2', 'foo bar3', 'foo bar4'])
1816 exe "normal 2GVjo/\\%Vbar\<CR>\<Esc>"
1817 call assert_equal([2, 5], [line('.'), col('.')])
1818 exe "normal 2GVj$?\\%Vbar\<CR>\<Esc>"
1819 call assert_equal([3, 5], [line('.'), col('.')])
1820 close!
1821endfunc
1822
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02001823" Test for searching with 'smartcase' and 'ignorecase'
1824func Test_search_smartcase()
1825 new
1826 call setline(1, ['', 'Hello'])
1827 set noignorecase nosmartcase
1828 call assert_fails('exe "normal /\\a\\_.\\(.*\\)O\<CR>"', 'E486:')
1829
1830 set ignorecase nosmartcase
1831 exe "normal /\\a\\_.\\(.*\\)O\<CR>"
1832 call assert_equal([2, 1], [line('.'), col('.')])
1833
1834 call cursor(1, 1)
1835 set ignorecase smartcase
1836 call assert_fails('exe "normal /\\a\\_.\\(.*\\)O\<CR>"', 'E486:')
1837
1838 exe "normal /\\a\\_.\\(.*\\)o\<CR>"
1839 call assert_equal([2, 1], [line('.'), col('.')])
1840
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001841 " Test for using special atoms with 'smartcase'
1842 call setline(1, ['', ' Hello\ '])
1843 call cursor(1, 1)
1844 call feedkeys('/\_.\%(\uello\)\' .. "\<CR>", 'xt')
1845 call assert_equal([2, 4], [line('.'), col('.')])
1846
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02001847 set ignorecase& smartcase&
1848 close!
Bram Moolenaard66cdcd2020-07-26 13:27:16 +02001849endfun
1850
1851" Test 'smartcase' with utf-8.
1852func Test_search_smartcase_utf8()
1853 new
1854 let save_enc = &encoding
1855 set encoding=utf8 ignorecase smartcase
1856
1857 call setline(1, 'Café cafÉ')
1858 1s/café/x/g
1859 call assert_equal('x x', getline(1))
1860
1861 call setline(1, 'Café cafÉ')
1862 1s/cafÉ/x/g
1863 call assert_equal('Café x', getline(1))
1864
1865 set ignorecase& smartcase&
1866 let &encoding = save_enc
1867 close!
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02001868endfunc
1869
1870" Test searching past the end of a file
1871func Test_search_past_eof()
1872 new
1873 call setline(1, ['Line'])
1874 exe "normal /\\n\\zs\<CR>"
1875 call assert_equal([1, 4], [line('.'), col('.')])
1876 close!
1877endfunc
1878
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001879" Test for various search offsets
1880func Test_search_offset()
1881 " With /e, for a match in the first column of a line, the cursor should be
1882 " placed at the end of the previous line.
1883 new
1884 call setline(1, ['one two', 'three four'])
1885 call search('two\_.', 'e')
1886 call assert_equal([1, 7], [line('.'), col('.')])
1887
1888 " with cursor at the beginning of the file, use /s+1
1889 call cursor(1, 1)
1890 exe "normal /two/s+1\<CR>"
1891 call assert_equal([1, 6], [line('.'), col('.')])
1892
1893 " with cursor at the end of the file, use /e-1
1894 call cursor(2, 10)
1895 exe "normal ?three?e-1\<CR>"
1896 call assert_equal([2, 4], [line('.'), col('.')])
1897
1898 " line offset - after the last line
1899 call cursor(1, 1)
1900 exe "normal /three/+1\<CR>"
1901 call assert_equal([2, 1], [line('.'), col('.')])
1902
1903 " line offset - before the first line
1904 call cursor(2, 1)
1905 exe "normal ?one?-1\<CR>"
1906 call assert_equal([1, 1], [line('.'), col('.')])
1907
1908 " character offset - before the first character in the file
1909 call cursor(2, 1)
1910 exe "normal ?one?s-1\<CR>"
1911 call assert_equal([1, 1], [line('.'), col('.')])
1912 call cursor(2, 1)
1913 exe "normal ?one?e-3\<CR>"
1914 call assert_equal([1, 1], [line('.'), col('.')])
1915
1916 " character offset - after the last character in the file
1917 call cursor(1, 1)
1918 exe "normal /four/s+4\<CR>"
1919 call assert_equal([2, 10], [line('.'), col('.')])
1920 call cursor(1, 1)
1921 exe "normal /four/e+1\<CR>"
1922 call assert_equal([2, 10], [line('.'), col('.')])
1923
1924 close!
1925endfunc
1926
1927" Test for searching for matching parenthesis using %
1928func Test_search_match_paren()
1929 new
1930 call setline(1, "abc(def')'ghi'('jk'\\t'lm)no")
1931 " searching for a matching parenthesis should skip single quoted characters
1932 call cursor(1, 4)
1933 normal %
1934 call assert_equal([1, 25], [line('.'), col('.')])
1935 normal %
1936 call assert_equal([1, 4], [line('.'), col('.')])
1937 call cursor(1, 5)
1938 normal ])
1939 call assert_equal([1, 25], [line('.'), col('.')])
1940 call cursor(1, 24)
1941 normal [(
1942 call assert_equal([1, 4], [line('.'), col('.')])
1943
1944 " matching parenthesis in 'virtualedit' mode with cursor after the eol
1945 call setline(1, 'abc(defgh)')
1946 set virtualedit=all
1947 normal 20|%
1948 call assert_equal(4, col('.'))
1949 set virtualedit&
1950 close!
1951endfunc
1952
1953" Test for searching a pattern and stopping before a specified line
1954func Test_search_stopline()
1955 new
1956 call setline(1, ['', '', '', 'vim'])
1957 call assert_equal(0, search('vim', 'n', 3))
1958 call assert_equal(4, search('vim', 'n', 4))
1959 call setline(1, ['vim', '', '', ''])
1960 call cursor(4, 1)
1961 call assert_equal(0, search('vim', 'bn', 2))
1962 call assert_equal(1, search('vim', 'bn', 1))
1963 close!
1964endfunc
1965
Bram Moolenaar6bed0db2020-11-25 17:41:20 +01001966func Test_incsearch_highlighting_newline()
Bram Moolenaar448465e2020-11-25 13:49:27 +01001967 CheckRunVimInTerminal
1968 CheckOption incsearch
1969 CheckScreendump
1970 new
1971 call test_override("char_avail", 1)
1972
1973 let commands =<< trim [CODE]
1974 set incsearch nohls
1975 call setline(1, ['test', 'xxx'])
1976 [CODE]
1977 call writefile(commands, 'Xincsearch_nl')
1978 let buf = RunVimInTerminal('-S Xincsearch_nl', {'rows': 5, 'cols': 10})
Bram Moolenaar448465e2020-11-25 13:49:27 +01001979 call term_sendkeys(buf, '/test')
Bram Moolenaar448465e2020-11-25 13:49:27 +01001980 call VerifyScreenDump(buf, 'Test_incsearch_newline1', {})
Bram Moolenaar6bed0db2020-11-25 17:41:20 +01001981 " Need to send one key at a time to force a redraw
Bram Moolenaar448465e2020-11-25 13:49:27 +01001982 call term_sendkeys(buf, '\n')
Bram Moolenaar448465e2020-11-25 13:49:27 +01001983 call VerifyScreenDump(buf, 'Test_incsearch_newline2', {})
1984 call term_sendkeys(buf, 'x')
Bram Moolenaar448465e2020-11-25 13:49:27 +01001985 call VerifyScreenDump(buf, 'Test_incsearch_newline3', {})
1986 call term_sendkeys(buf, 'x')
1987 call VerifyScreenDump(buf, 'Test_incsearch_newline4', {})
1988 call term_sendkeys(buf, "\<CR>")
Bram Moolenaar448465e2020-11-25 13:49:27 +01001989 call VerifyScreenDump(buf, 'Test_incsearch_newline5', {})
1990 call StopVimInTerminal(buf)
1991
1992 " clean up
1993 call delete('Xincsearch_nl')
1994 call test_override("char_avail", 0)
1995 bw
1996endfunc
1997
Bram Moolenaard93a7fc2021-01-04 12:42:13 +01001998func Test_incsearch_substitute_dump2()
1999 CheckOption incsearch
2000 CheckScreendump
2001
2002 call writefile([
2003 \ 'set incsearch hlsearch scrolloff=0',
2004 \ 'for n in range(1, 4)',
2005 \ ' call setline(n, "foo " . n)',
2006 \ 'endfor',
2007 \ 'call setline(5, "abc|def")',
2008 \ '3',
2009 \ ], 'Xis_subst_script2')
2010 let buf = RunVimInTerminal('-S Xis_subst_script2', {'rows': 9, 'cols': 70})
2011
2012 call term_sendkeys(buf, ':%s/\vabc|')
2013 sleep 100m
2014 call VerifyScreenDump(buf, 'Test_incsearch_sub_01', {})
2015 call term_sendkeys(buf, "\<Esc>")
2016
2017 " The following should not be highlighted
2018 call term_sendkeys(buf, ':1,5s/\v|')
2019 sleep 100m
2020 call VerifyScreenDump(buf, 'Test_incsearch_sub_02', {})
2021
2022
2023 call StopVimInTerminal(buf)
2024 call delete('Xis_subst_script2')
2025endfunc
2026
Christian Brabandt78ba9332021-08-01 12:44:37 +02002027func Test_pattern_is_uppercase_smartcase()
2028 new
2029 let input=['abc', 'ABC', 'Abc', 'abC']
2030 call setline(1, input)
2031 call cursor(1,1)
2032 " default, matches firstline
2033 %s/abc//g
2034 call assert_equal(['', 'ABC', 'Abc', 'abC'],
2035 \ getline(1, '$'))
2036
2037 set smartcase ignorecase
2038 sil %d
2039 call setline(1, input)
2040 call cursor(1,1)
2041 " with smartcase and incsearch set, matches everything
2042 %s/abc//g
2043 call assert_equal(['', '', '', ''], getline(1, '$'))
2044
2045 sil %d
2046 call setline(1, input)
2047 call cursor(1,1)
2048 " with smartcase and incsearch set and found an uppercase letter,
2049 " match only that.
2050 %s/abC//g
2051 call assert_equal(['abc', 'ABC', 'Abc', ''],
2052 \ getline(1, '$'))
2053
2054 sil %d
2055 call setline(1, input)
2056 call cursor(1,1)
2057 exe "norm! vG$\<esc>"
2058 " \%V should not be detected as uppercase letter
2059 %s/\%Vabc//g
2060 call assert_equal(['', '', '', ''], getline(1, '$'))
2061
2062 call setline(1, input)
2063 call cursor(1,1)
2064 exe "norm! vG$\<esc>"
2065 " \v%V should not be detected as uppercase letter
2066 %s/\v%Vabc//g
2067 call assert_equal(['', '', '', ''], getline(1, '$'))
2068
2069 call setline(1, input)
2070 call cursor(1,1)
2071 exe "norm! vG$\<esc>"
2072 " \v%VabC should be detected as uppercase letter
2073 %s/\v%VabC//g
2074 call assert_equal(['abc', 'ABC', 'Abc', ''],
2075 \ getline(1, '$'))
2076
Christian Brabandtbc67e5a2021-08-05 15:24:59 +02002077 call setline(1, input)
2078 call cursor(1,1)
2079 " \Vabc should match everything
2080 %s/\Vabc//g
2081 call assert_equal(['', '', '', ''], getline(1, '$'))
2082
2083 call setline(1, input + ['_abc'])
2084 " _ matches normally
2085 %s/\v_.*//g
2086 call assert_equal(['abc', 'ABC', 'Abc', 'abC', ''], getline(1, '$'))
2087
Christian Brabandt78ba9332021-08-01 12:44:37 +02002088 set smartcase& ignorecase&
2089 bw!
2090endfunc
2091
Bram Moolenaard8d957d2021-10-04 19:47:35 +01002092func Test_no_last_search_pattern()
2093 CheckOption incsearch
2094
2095 let @/ = ""
2096 set incsearch
Bram Moolenaar9af9fd62021-10-04 20:09:19 +01002097 " these were causing a crash
2098 call feedkeys("//\<C-G>", 'xt')
2099 call feedkeys("//\<C-T>", 'xt')
2100 call feedkeys("??\<C-G>", 'xt')
2101 call feedkeys("??\<C-T>", 'xt')
Bram Moolenaard8d957d2021-10-04 19:47:35 +01002102endfunc
2103
Bram Moolenaar35a319b2021-10-09 13:58:55 +01002104func Test_search_with_invalid_range()
2105 new
2106 let lines =<< trim END
2107 /\%.v
2108 5/
2109 c
2110 END
2111 call writefile(lines, 'Xrangesearch')
2112 source Xrangesearch
2113
2114 bwipe!
2115 call delete('Xrangesearch')
2116endfunc
2117
Bram Moolenaard8d957d2021-10-04 19:47:35 +01002118
Bram Moolenaar07ada5f2020-02-05 20:38:22 +01002119" vim: shiftwidth=2 sts=2 expandtab