blob: 446d5ecd3ac9afe814e2ecdb1c2c5cc94be716ce [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
Bram Moolenaar73171ba2022-06-20 12:39:39 +0100336 let g:test_is_flaky = 1
Bram Moolenaar5ea38d12022-06-16 21:20:48 +0100337
338 func Waitabit()
339 sleep 20m
340 return 1 " skip match
341 endfunc
342
343 new
344 call setline(1, range(100))
345 call setline(1, "(start here")
346 call setline(100, "end here)")
347 let starttime = reltime()
348
349 " A timeout of 100 msec should happen after about five times of 20 msec wait
350 " in Waitabit(). When the timeout applies to each search the elapsed time
351 " will be much longer.
352 call assert_equal(0, searchpair('(', '\d', ')', '', "Waitabit()", 0, 100))
353 let elapsed = reltime(starttime)->reltimefloat()
354 call assert_inrange(0.09, 0.300, elapsed)
355
Bram Moolenaar12a49402022-06-21 22:35:40 +0100356 delfunc Waitabit
Bram Moolenaar5ea38d12022-06-16 21:20:48 +0100357 bwipe!
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100358endfunc
359
Bram Moolenaare5303952022-06-19 17:05:47 +0100360func SearchpairSkip()
361 let id = synID(line('.'), col('.'), 0)
362 let attr = synIDattr(id, 'name')
363 return attr !~ 'comment'
364endfunc
365
366func Test_searchpair_timeout_with_skip()
367 let g:test_is_flaky = 1
368
369 edit ../evalfunc.c
370 if has('win32')
371 " Windows timeouts are rather coarse grained, about 16ms.
372 let ms = 20
373 let min_time = 0.016
374 let max_time = min_time * 10.0
375 else
376 let ms = 1
377 let min_time = 0.001
James McCoydbe6ef12022-12-31 11:44:57 +0000378 let max_time = min_time * 15.0
Bram Moolenaare366ed42022-06-19 20:13:56 +0100379 if RunningWithValgrind()
Bram Moolenaare5303952022-06-19 17:05:47 +0100380 let max_time += 0.04 " this can be slow with valgrind
381 endif
Bram Moolenaare9b74c02022-06-24 20:11:59 +0100382 if has('bsd')
383 " test often fails with FreeBSD
384 let max_time = max_time * 2.0
385 endif
Bram Moolenaare5303952022-06-19 17:05:47 +0100386 endif
387 let start = reltime()
388 let found = searchpair('(', '', ')', 'crnm', 'SearchpairSkip()', 0, ms)
389 let elapsed = reltimefloat(reltime(start))
390 call assert_inrange(min_time, max_time, elapsed)
391
392 bwipe!
393endfunc
394
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100395func Test_searchpairpos()
396 new
397 call setline(1, ['other code', 'here [', ' [', ' " cursor here', ' ]]'])
398
399 4
400 call assert_equal([3, 2], searchpairpos('\[', '', ']', 'bW'))
401 call assert_equal([0, 3, 2, 0], getpos('.'))
402 4
403 call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bWr'))
404 call assert_equal([0, 2, 6, 0], getpos('.'))
405 4|norm ^
406 call assert_equal([5, 2], searchpairpos('\[', '', ']', 'Wn'))
407 call assert_equal([0, 4, 2, 0], getpos('.'))
408 4
409 call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bW',
410 \ 'getline(".") =~ "^\\s*\["'))
411 call assert_equal([0, 2, 6, 0], getpos('.'))
412 4
413 call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bWr'))
414 call assert_equal([0, 2, 6, 0], getpos('.'))
415 set nomagic
416 4
417 call assert_equal([3, 2], searchpairpos('\[', '', ']', 'bW'))
418 call assert_equal([0, 3, 2, 0], getpos('.'))
419 set magic
420 4|norm ^
421 call assert_equal([0, 0], searchpairpos('{', '', '}', 'bW'))
422 call assert_equal([0, 4, 2, 0], getpos('.'))
423
424 %d
425 call setline(1, ['if 1', ' if 2', ' else', ' endif 2', 'endif 1'])
426 /\<if 1
427 call assert_equal([5, 1], searchpairpos('\<if\>', '\<else\>', '\<endif\>', 'W'))
428 call assert_equal([0, 5, 1, 0], getpos('.'))
429 /\<if 2
430 call assert_equal([3, 3], searchpairpos('\<if\>', '\<else\>', '\<endif\>', 'W'))
431 call assert_equal([0, 3, 3, 0], getpos('.'))
432
Bram Moolenaar6e450a52017-01-06 20:03:58 +0100433 q!
434endfunc
435
Bram Moolenaar3dddb092018-06-24 19:01:59 +0200436func Test_searchpair_errors()
Yegappan Lakshmanan5b739922021-07-10 13:15:41 +0200437 call assert_fails("call searchpair([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: Using a List as a String')
438 call assert_fails("call searchpair('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: Using a Funcref as a String')
439 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 +0200440 call assert_fails("call searchpair('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
Bram Moolenaar3dddb092018-06-24 19:01:59 +0200441 call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
442 call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100443 call assert_fails("call searchpair('start', 'middle', 'end', 'e')", 'E475: Invalid argument: e')
444 call assert_fails("call searchpair('start', 'middle', 'end', 'sn')", 'E475: Invalid argument: sn')
445endfunc
446
447func Test_searchpairpos_errors()
Yegappan Lakshmanan5b739922021-07-10 13:15:41 +0200448 call assert_fails("call searchpairpos([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: Using a List as a String')
449 call assert_fails("call searchpairpos('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: Using a Funcref as a String')
450 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 +0100451 call assert_fails("call searchpairpos('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100452 call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
453 call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')
454 call assert_fails("call searchpairpos('start', 'middle', 'end', 'e')", 'E475: Invalid argument: e')
455 call assert_fails("call searchpairpos('start', 'middle', 'end', 'sn')", 'E475: Invalid argument: sn')
Bram Moolenaar3dddb092018-06-24 19:01:59 +0200456endfunc
457
Bram Moolenaar48570482017-10-30 21:48:41 +0100458func Test_searchpair_skip()
459 func Zero()
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100460 return 0
Bram Moolenaar48570482017-10-30 21:48:41 +0100461 endfunc
462 func Partial(x)
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100463 return a:x
Bram Moolenaar48570482017-10-30 21:48:41 +0100464 endfunc
465 new
466 call setline(1, ['{', 'foo', 'foo', 'foo', '}'])
467 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', ''))
468 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', '0'))
469 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', {-> 0}))
470 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Zero')))
471 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Partial', [0])))
Bram Moolenaar48570482017-10-30 21:48:41 +0100472 bw!
473endfunc
474
Bram Moolenaara43ebe92018-07-14 17:25:01 +0200475func Test_searchpair_leak()
476 new
477 call setline(1, 'if one else another endif')
478
479 " The error in the skip expression caused memory to leak.
480 call assert_fails("call searchpair('\\<if\\>', '\\<else\\>', '\\<endif\\>', '', '\"foo\" 2')", 'E15:')
481
482 bwipe!
483endfunc
484
Bram Moolenaar66727e12017-03-01 22:17:05 +0100485func Test_searchc()
486 " These commands used to cause memory overflow in searchc().
487 new
488 norm ixx
489 exe "norm 0t\u93cf"
490 bw!
491endfunc
Bram Moolenaara693d052017-06-29 22:23:06 +0200492
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200493func Cmdline3_prep()
494 " need to disable char_avail,
495 " so that expansion of commandline works
496 call test_override("char_avail", 1)
497 new
498 call setline(1, [' 1', ' 2 the~e', ' 3 the theother'])
499 set incsearch
500endfunc
501
Bram Moolenaar976b8472018-08-12 15:49:47 +0200502func Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200503 set noincsearch
504 call test_override("char_avail", 0)
505 bw!
506endfunc
507
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200508func Test_search_cmdline3()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100509 CheckOption incsearch
510
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200511 call Cmdline3_prep()
512 1
513 " first match
514 call feedkeys("/the\<c-l>\<cr>", 'tx')
515 call assert_equal(' 2 the~e', getline('.'))
516
Bram Moolenaar976b8472018-08-12 15:49:47 +0200517 call Incsearch_cleanup()
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200518endfunc
519
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200520func Test_search_cmdline3s()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100521 CheckOption incsearch
522
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200523 call Cmdline3_prep()
524 1
525 call feedkeys(":%s/the\<c-l>/xxx\<cr>", 'tx')
526 call assert_equal(' 2 xxxe', getline('.'))
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200527 undo
528 call feedkeys(":%subs/the\<c-l>/xxx\<cr>", 'tx')
529 call assert_equal(' 2 xxxe', getline('.'))
530 undo
531 call feedkeys(":%substitute/the\<c-l>/xxx\<cr>", 'tx')
532 call assert_equal(' 2 xxxe', getline('.'))
Bram Moolenaar167ae422018-08-14 21:32:21 +0200533 undo
534 call feedkeys(":%smagic/the.e/xxx\<cr>", 'tx')
535 call assert_equal(' 2 xxx', getline('.'))
536 undo
Bram Moolenaare2e40752020-09-04 21:18:46 +0200537 call assert_fails(":%snomagic/the.e/xxx\<cr>", 'E486:')
Bram Moolenaar167ae422018-08-14 21:32:21 +0200538 "
539 call feedkeys(":%snomagic/the\\.e/xxx\<cr>", 'tx')
540 call assert_equal(' 2 xxx', getline('.'))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200541
Bram Moolenaar976b8472018-08-12 15:49:47 +0200542 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200543endfunc
544
545func Test_search_cmdline3g()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100546 CheckOption incsearch
547
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200548 call Cmdline3_prep()
549 1
550 call feedkeys(":g/the\<c-l>/d\<cr>", 'tx')
551 call assert_equal(' 3 the theother', getline(2))
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200552 undo
553 call feedkeys(":global/the\<c-l>/d\<cr>", 'tx')
554 call assert_equal(' 3 the theother', getline(2))
Bram Moolenaardef7b1d2018-08-13 22:54:35 +0200555 undo
556 call feedkeys(":g!/the\<c-l>/d\<cr>", 'tx')
557 call assert_equal(1, line('$'))
558 call assert_equal(' 2 the~e', getline(1))
559 undo
560 call feedkeys(":global!/the\<c-l>/d\<cr>", 'tx')
561 call assert_equal(1, line('$'))
562 call assert_equal(' 2 the~e', getline(1))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200563
Bram Moolenaar976b8472018-08-12 15:49:47 +0200564 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200565endfunc
566
567func Test_search_cmdline3v()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100568 CheckOption incsearch
569
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200570 call Cmdline3_prep()
571 1
572 call feedkeys(":v/the\<c-l>/d\<cr>", 'tx')
573 call assert_equal(1, line('$'))
574 call assert_equal(' 2 the~e', getline(1))
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200575 undo
576 call feedkeys(":vglobal/the\<c-l>/d\<cr>", 'tx')
577 call assert_equal(1, line('$'))
578 call assert_equal(' 2 the~e', getline(1))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200579
Bram Moolenaar976b8472018-08-12 15:49:47 +0200580 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200581endfunc
582
Bram Moolenaarda5116d2017-07-01 23:11:17 +0200583func Test_search_cmdline4()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100584 CheckOption incsearch
585
Bram Moolenaarda5116d2017-07-01 23:11:17 +0200586 " need to disable char_avail,
587 " so that expansion of commandline works
588 call test_override("char_avail", 1)
589 new
590 call setline(1, [' 1 the first', ' 2 the second', ' 3 the third'])
591 set incsearch
592 $
593 call feedkeys("?the\<c-g>\<cr>", 'tx')
594 call assert_equal(' 3 the third', getline('.'))
595 $
596 call feedkeys("?the\<c-g>\<c-g>\<cr>", 'tx')
597 call assert_equal(' 1 the first', getline('.'))
598 $
599 call feedkeys("?the\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
600 call assert_equal(' 2 the second', getline('.'))
601 $
602 call feedkeys("?the\<c-t>\<cr>", 'tx')
603 call assert_equal(' 1 the first', getline('.'))
604 $
605 call feedkeys("?the\<c-t>\<c-t>\<cr>", 'tx')
606 call assert_equal(' 3 the third', getline('.'))
607 $
608 call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
609 call assert_equal(' 2 the second', getline('.'))
610 " clean up
611 set noincsearch
612 call test_override("char_avail", 0)
613 bw!
614endfunc
Bram Moolenaardb510072017-09-28 21:52:17 +0200615
Bram Moolenaarf8e8c062017-10-22 14:44:17 +0200616func Test_search_cmdline5()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100617 CheckOption incsearch
618
Bram Moolenaarf8e8c062017-10-22 14:44:17 +0200619 " Do not call test_override("char_avail", 1) so that <C-g> and <C-t> work
620 " regardless char_avail.
621 new
Bram Moolenaar69a5b862019-07-16 21:38:51 +0200622 call setline(1, [' 1 the first', ' 2 the second', ' 3 the third', ''])
Bram Moolenaarf8e8c062017-10-22 14:44:17 +0200623 set incsearch
624 1
625 call feedkeys("/the\<c-g>\<c-g>\<cr>", 'tx')
626 call assert_equal(' 3 the third', getline('.'))
627 $
628 call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
Bram Moolenaar69a5b862019-07-16 21:38:51 +0200629 call assert_equal(' 1 the first', getline('.'))
Bram Moolenaarf8e8c062017-10-22 14:44:17 +0200630 " clean up
631 set noincsearch
632 bw!
633endfunc
634
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100635func Test_search_cmdline6()
636 " Test that consecutive matches
637 " are caught by <c-g>/<c-t>
Bram Moolenaarb68df222020-03-19 15:05:28 +0100638 CheckOption incsearch
639
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100640 " need to disable char_avail,
641 " so that expansion of commandline works
642 call test_override("char_avail", 1)
643 new
644 call setline(1, [' bbvimb', ''])
645 set incsearch
646 " first match
647 norm! gg0
648 call feedkeys("/b\<cr>", 'tx')
649 call assert_equal([0,1,2,0], getpos('.'))
650 " second match
651 norm! gg0
652 call feedkeys("/b\<c-g>\<cr>", 'tx')
653 call assert_equal([0,1,3,0], getpos('.'))
654 " third match
655 norm! gg0
656 call feedkeys("/b\<c-g>\<c-g>\<cr>", 'tx')
657 call assert_equal([0,1,7,0], getpos('.'))
658 " first match again
659 norm! gg0
660 call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
661 call assert_equal([0,1,2,0], getpos('.'))
662 set nowrapscan
663 " last match
664 norm! gg0
665 call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
666 call assert_equal([0,1,7,0], getpos('.'))
667 " clean up
668 set wrapscan&vim
669 set noincsearch
670 call test_override("char_avail", 0)
671 bw!
672endfunc
673
674func Test_search_cmdline7()
Bram Moolenaard66cdcd2020-07-26 13:27:16 +0200675 " Test that pressing <c-g> in an empty command line
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100676 " does not move the cursor
Bram Moolenaarb68df222020-03-19 15:05:28 +0100677 CheckOption incsearch
678
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100679 " need to disable char_avail,
680 " so that expansion of commandline works
681 call test_override("char_avail", 1)
682 new
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200683 let @/ = 'b'
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100684 call setline(1, [' bbvimb', ''])
685 set incsearch
686 " first match
687 norm! gg0
688 " moves to next match of previous search pattern, just like /<cr>
689 call feedkeys("/\<c-g>\<cr>", 'tx')
690 call assert_equal([0,1,2,0], getpos('.'))
691 " moves to next match of previous search pattern, just like /<cr>
692 call feedkeys("/\<cr>", 'tx')
693 call assert_equal([0,1,3,0], getpos('.'))
694 " moves to next match of previous search pattern, just like /<cr>
695 call feedkeys("/\<c-t>\<cr>", 'tx')
696 call assert_equal([0,1,7,0], getpos('.'))
Bram Moolenaard0480092017-11-16 22:20:39 +0100697
698 " using an offset uses the last search pattern
699 call cursor(1, 1)
700 call setline(1, ['1 bbvimb', ' 2 bbvimb'])
701 let @/ = 'b'
702 call feedkeys("//e\<c-g>\<cr>", 'tx')
703 call assert_equal('1 bbvimb', getline('.'))
704 call assert_equal(4, col('.'))
705
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100706 set noincsearch
707 call test_override("char_avail", 0)
708 bw!
709endfunc
710
711func Test_search_cmdline8()
712 " Highlighting is cleared in all windows
713 " since hls applies to all windows
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200714 CheckOption incsearch
715 CheckFeature terminal
716 CheckNotGui
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100717 if has("win32")
718 throw "Skipped: Bug with sending <ESC> to terminal window not fixed yet"
719 endif
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200720
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100721 let h = winheight(0)
722 if h < 3
723 return
724 endif
725 " Prepare buffer text
726 let lines = ['abb vim vim vi', 'vimvivim']
Bram Moolenaar56564962022-10-10 22:39:42 +0100727 call writefile(lines, 'Xsearch.txt', 'D')
Bram Moolenaar13deab82017-11-04 18:48:43 +0100728 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100729
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200730 call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100731
Bram Moolenaar13deab82017-11-04 18:48:43 +0100732 call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
733 call term_sendkeys(buf, ":14vsp\<cr>")
734 call term_sendkeys(buf, "/vim\<cr>")
735 call term_sendkeys(buf, "/b\<esc>")
736 call term_sendkeys(buf, "gg0")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200737 call TermWait(buf, 250)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100738 let screen_line = term_scrape(buf, 1)
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100739 let [a0,a1,a2,a3] = [screen_line[3].attr, screen_line[4].attr,
740 \ screen_line[18].attr, screen_line[19].attr]
741 call assert_notequal(a0, a1)
742 call assert_notequal(a0, a3)
743 call assert_notequal(a1, a2)
744 call assert_equal(a0, a2)
745 call assert_equal(a1, a3)
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100746
Bram Moolenaar56564962022-10-10 22:39:42 +0100747 " clean up
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100748 bwipe!
749endfunc
750
Bram Moolenaardb510072017-09-28 21:52:17 +0200751" Tests for regexp with various magic settings
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200752func Run_search_regexp_magic_opt()
Bram Moolenaardb510072017-09-28 21:52:17 +0200753 put ='1 a aa abb abbccc'
754 exe 'normal! /a*b\{2}c\+/e' . "\<CR>"
755 call assert_equal([0, 2, 17, 0], getpos('.'))
756
757 put ='2 d dd dee deefff'
758 exe 'normal! /\Md\*e\{2}f\+/e' . "\<CR>"
759 call assert_equal([0, 3, 17, 0], getpos('.'))
760
761 set nomagic
762 put ='3 g gg ghh ghhiii'
763 exe 'normal! /g\*h\{2}i\+/e' . "\<CR>"
764 call assert_equal([0, 4, 17, 0], getpos('.'))
765
766 put ='4 j jj jkk jkklll'
767 exe 'normal! /\mj*k\{2}l\+/e' . "\<CR>"
768 call assert_equal([0, 5, 17, 0], getpos('.'))
769
770 put ='5 m mm mnn mnnooo'
771 exe 'normal! /\vm*n{2}o+/e' . "\<CR>"
772 call assert_equal([0, 6, 17, 0], getpos('.'))
773
774 put ='6 x ^aa$ x'
775 exe 'normal! /\V^aa$' . "\<CR>"
776 call assert_equal([0, 7, 5, 0], getpos('.'))
777
778 set magic
779 put ='7 (a)(b) abbaa'
780 exe 'normal! /\v(a)(b)\2\1\1/e' . "\<CR>"
781 call assert_equal([0, 8, 14, 0], getpos('.'))
782
783 put ='8 axx [ab]xx'
784 exe 'normal! /\V[ab]\(\[xy]\)\1' . "\<CR>"
785 call assert_equal([0, 9, 7, 0], getpos('.'))
786
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200787 %d
788endfunc
789
790func Test_search_regexp()
791 enew!
792
793 set regexpengine=1
794 call Run_search_regexp_magic_opt()
795 set regexpengine=2
796 call Run_search_regexp_magic_opt()
797 set regexpengine&
798
Bram Moolenaardb510072017-09-28 21:52:17 +0200799 set undolevels=100
800 put ='9 foobar'
801 put =''
802 exe "normal! a\<C-G>u\<Esc>"
803 normal G
804 exe 'normal! dv?bar?' . "\<CR>"
805 call assert_equal('9 foo', getline('.'))
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200806 call assert_equal([0, 2, 5, 0], getpos('.'))
807 call assert_equal(2, line('$'))
Bram Moolenaardb510072017-09-28 21:52:17 +0200808 normal u
809 call assert_equal('9 foobar', getline('.'))
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200810 call assert_equal([0, 2, 6, 0], getpos('.'))
811 call assert_equal(3, line('$'))
Bram Moolenaardb510072017-09-28 21:52:17 +0200812
813 set undolevels&
814 enew!
815endfunc
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100816
817func Test_search_cmdline_incsearch_highlight()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100818 CheckOption incsearch
819
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100820 set incsearch hlsearch
821 " need to disable char_avail,
822 " so that expansion of commandline works
823 call test_override("char_avail", 1)
824 new
825 call setline(1, ['aaa 1 the first', ' 2 the second', ' 3 the third'])
826
827 1
828 call feedkeys("/second\<cr>", 'tx')
829 call assert_equal('second', @/)
830 call assert_equal(' 2 the second', getline('.'))
831
832 " Canceling search won't change @/
833 1
834 let @/ = 'last pattern'
835 call feedkeys("/third\<C-c>", 'tx')
836 call assert_equal('last pattern', @/)
837 call feedkeys("/third\<Esc>", 'tx')
838 call assert_equal('last pattern', @/)
839 call feedkeys("/3\<bs>\<bs>", 'tx')
840 call assert_equal('last pattern', @/)
841 call feedkeys("/third\<c-g>\<c-t>\<Esc>", 'tx')
842 call assert_equal('last pattern', @/)
843
844 " clean up
845 set noincsearch nohlsearch
zeertzjq29b29c62025-07-03 20:02:02 +0200846 call test_override("char_avail", 0)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100847 bw!
848endfunc
849
850func Test_search_cmdline_incsearch_highlight_attr()
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200851 CheckOption incsearch
852 CheckFeature terminal
853 CheckNotGui
854
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100855 let h = winheight(0)
856 if h < 3
857 return
858 endif
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100859
860 " Prepare buffer text
Bram Moolenaar13deab82017-11-04 18:48:43 +0100861 let lines = ['abb vim vim vi', 'vimvivim']
Bram Moolenaar56564962022-10-10 22:39:42 +0100862 call writefile(lines, 'Xsearch.txt', 'D')
Bram Moolenaar13deab82017-11-04 18:48:43 +0100863 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
864
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200865 call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
Bram Moolenaarb50773c2018-01-30 22:31:19 +0100866 " wait for vim to complete initialization
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200867 call TermWait(buf)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100868
869 " Get attr of normal(a0), incsearch(a1), hlsearch(a2) highlight
Bram Moolenaar13deab82017-11-04 18:48:43 +0100870 call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
871 call term_sendkeys(buf, '/b')
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200872 call TermWait(buf, 100)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100873 let screen_line1 = term_scrape(buf, 1)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100874 call assert_true(len(screen_line1) > 2)
875 " a0: attr_normal
876 let a0 = screen_line1[0].attr
877 " a1: attr_incsearch
878 let a1 = screen_line1[1].attr
879 " a2: attr_hlsearch
880 let a2 = screen_line1[2].attr
881 call assert_notequal(a0, a1)
882 call assert_notequal(a0, a2)
883 call assert_notequal(a1, a2)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100884 call term_sendkeys(buf, "\<cr>gg0")
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100885
886 " Test incremental highlight search
Bram Moolenaar13deab82017-11-04 18:48:43 +0100887 call term_sendkeys(buf, "/vim")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200888 call TermWait(buf, 100)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100889 " Buffer:
890 " abb vim vim vi
891 " vimvivim
892 " Search: /vim
893 let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a2,a2,a2,a0,a0,a0]
894 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100895 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
896 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100897
898 " Test <C-g>
Bram Moolenaar13deab82017-11-04 18:48:43 +0100899 call term_sendkeys(buf, "\<C-g>\<C-g>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200900 call TermWait(buf, 100)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100901 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
902 let attr_line2 = [a1,a1,a1,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100903 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
904 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100905
906 " Test <C-t>
Bram Moolenaar13deab82017-11-04 18:48:43 +0100907 call term_sendkeys(buf, "\<C-t>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200908 call TermWait(buf, 100)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100909 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a1,a1,a1,a0,a0,a0]
910 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100911 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
912 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100913
914 " Type Enter and a1(incsearch highlight) should become a2(hlsearch highlight)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100915 call term_sendkeys(buf, "\<cr>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200916 call TermWait(buf, 100)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100917 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
918 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100919 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
920 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100921
922 " Test nohlsearch. a2(hlsearch highlight) should become a0(normal highlight)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100923 call term_sendkeys(buf, ":1\<cr>")
924 call term_sendkeys(buf, ":set nohlsearch\<cr>")
925 call term_sendkeys(buf, "/vim")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200926 call TermWait(buf, 100)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100927 let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a0,a0,a0,a0,a0,a0]
928 let attr_line2 = [a0,a0,a0,a0,a0,a0,a0,a0]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100929 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
930 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100931
932 bwipe!
933endfunc
Bram Moolenaarf45938c2017-11-02 15:59:57 +0100934
Bram Moolenaar548e5982018-12-26 21:45:00 +0100935func Test_incsearch_cmdline_modifier()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100936 CheckOption incsearch
937
Bram Moolenaar548e5982018-12-26 21:45:00 +0100938 call test_override("char_avail", 1)
939 new
940 call setline(1, ['foo'])
941 set incsearch
942 " Test that error E14 does not occur in parsing command modifier.
943 call feedkeys("V:tab", 'tx')
944
945 call Incsearch_cleanup()
946endfunc
947
Bram Moolenaar9d34d902018-04-27 22:18:12 +0200948func Test_incsearch_scrolling()
Drew Vogelea67ba72025-05-07 22:05:17 +0200949 CheckScreendump
Bram Moolenaar494e9062020-05-31 21:28:02 +0200950 CheckRunVimInTerminal
Bram Moolenaar9d34d902018-04-27 22:18:12 +0200951 call assert_equal(0, &scrolloff)
952 call writefile([
953 \ 'let dots = repeat(".", 120)',
954 \ 'set incsearch cmdheight=2 scrolloff=0',
955 \ 'call setline(1, [dots, dots, dots, "", "target", dots, dots])',
956 \ 'normal gg',
957 \ 'redraw',
Bram Moolenaar56564962022-10-10 22:39:42 +0100958 \ ], 'Xscript', 'D')
Bram Moolenaar9d34d902018-04-27 22:18:12 +0200959 let buf = RunVimInTerminal('-S Xscript', {'rows': 9, 'cols': 70})
960 " Need to send one key at a time to force a redraw
961 call term_sendkeys(buf, '/')
962 sleep 100m
963 call term_sendkeys(buf, 't')
964 sleep 100m
965 call term_sendkeys(buf, 'a')
966 sleep 100m
967 call term_sendkeys(buf, 'r')
968 sleep 100m
969 call term_sendkeys(buf, 'g')
970 call VerifyScreenDump(buf, 'Test_incsearch_scrolling_01', {})
971
972 call term_sendkeys(buf, "\<Esc>")
973 call StopVimInTerminal(buf)
Bram Moolenaar9d34d902018-04-27 22:18:12 +0200974endfunc
975
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200976func Test_incsearch_search_dump()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100977 CheckOption incsearch
978 CheckScreendump
979
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200980 call writefile([
981 \ 'set incsearch hlsearch scrolloff=0',
982 \ 'for n in range(1, 8)',
983 \ ' call setline(n, "foo " . n)',
984 \ 'endfor',
985 \ '3',
Bram Moolenaar56564962022-10-10 22:39:42 +0100986 \ ], 'Xis_search_script', 'D')
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200987 let buf = RunVimInTerminal('-S Xis_search_script', {'rows': 9, 'cols': 70})
988 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
989 " the 'ambiwidth' check.
990 sleep 100m
991
992 " Need to send one key at a time to force a redraw.
993 call term_sendkeys(buf, '/fo')
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200994 call VerifyScreenDump(buf, 'Test_incsearch_search_01', {})
995 call term_sendkeys(buf, "\<Esc>")
996 sleep 100m
997
998 call term_sendkeys(buf, '/\v')
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200999 call VerifyScreenDump(buf, 'Test_incsearch_search_02', {})
1000 call term_sendkeys(buf, "\<Esc>")
1001
1002 call StopVimInTerminal(buf)
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +02001003endfunc
1004
Bram Moolenaar41f08952021-02-22 22:13:49 +01001005func Test_hlsearch_dump()
1006 CheckOption hlsearch
1007 CheckScreendump
1008
1009 call writefile([
1010 \ 'set hlsearch cursorline',
1011 \ 'call setline(1, ["xxx", "xxx", "xxx"])',
1012 \ '/.*',
1013 \ '2',
Bram Moolenaar56564962022-10-10 22:39:42 +01001014 \ ], 'Xhlsearch_script', 'D')
Bram Moolenaar41f08952021-02-22 22:13:49 +01001015 let buf = RunVimInTerminal('-S Xhlsearch_script', {'rows': 6, 'cols': 50})
1016 call VerifyScreenDump(buf, 'Test_hlsearch_1', {})
1017
1018 call term_sendkeys(buf, "/\\_.*\<CR>")
1019 call VerifyScreenDump(buf, 'Test_hlsearch_2', {})
1020
1021 call StopVimInTerminal(buf)
Bram Moolenaar41f08952021-02-22 22:13:49 +01001022endfunc
1023
Bram Moolenaar2d5f3852021-04-21 15:11:42 +02001024func Test_hlsearch_and_visual()
1025 CheckOption hlsearch
1026 CheckScreendump
1027
1028 call writefile([
1029 \ 'set hlsearch',
1030 \ 'call setline(1, repeat(["xxx yyy zzz"], 3))',
1031 \ 'hi Search cterm=bold',
1032 \ '/yyy',
1033 \ 'call cursor(1, 6)',
Bram Moolenaar56564962022-10-10 22:39:42 +01001034 \ ], 'Xhlvisual_script', 'D')
Bram Moolenaar2d5f3852021-04-21 15:11:42 +02001035 let buf = RunVimInTerminal('-S Xhlvisual_script', {'rows': 6, 'cols': 40})
1036 call term_sendkeys(buf, "vjj")
1037 call VerifyScreenDump(buf, 'Test_hlsearch_visual_1', {})
1038 call term_sendkeys(buf, "\<Esc>")
1039
1040 call StopVimInTerminal(buf)
Bram Moolenaar2d5f3852021-04-21 15:11:42 +02001041endfunc
1042
Bram Moolenaare71c0eb2021-05-30 16:43:11 +02001043func Test_hlsearch_block_visual_match()
1044 CheckScreendump
1045
1046 let lines =<< trim END
1047 set hlsearch
1048 call setline(1, ['aa', 'bbbb', 'cccccc'])
1049 END
Bram Moolenaar56564962022-10-10 22:39:42 +01001050 call writefile(lines, 'Xhlsearch_block', 'D')
Bram Moolenaare71c0eb2021-05-30 16:43:11 +02001051 let buf = RunVimInTerminal('-S Xhlsearch_block', {'rows': 9, 'cols': 60})
1052
1053 call term_sendkeys(buf, "G\<C-V>$kk\<Esc>")
1054 sleep 100m
1055 call term_sendkeys(buf, "/\\%V\<CR>")
1056 sleep 100m
1057 call VerifyScreenDump(buf, 'Test_hlsearch_block_visual_match', {})
1058
1059 call StopVimInTerminal(buf)
Bram Moolenaare71c0eb2021-05-30 16:43:11 +02001060endfunc
1061
Bram Moolenaar976b8472018-08-12 15:49:47 +02001062func Test_incsearch_substitute()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001063 CheckOption incsearch
1064
Bram Moolenaar976b8472018-08-12 15:49:47 +02001065 call test_override("char_avail", 1)
1066 new
1067 set incsearch
1068 for n in range(1, 10)
1069 call setline(n, 'foo ' . n)
1070 endfor
1071 4
1072 call feedkeys(":.,.+2s/foo\<BS>o\<BS>o/xxx\<cr>", 'tx')
1073 call assert_equal('foo 3', getline(3))
1074 call assert_equal('xxx 4', getline(4))
1075 call assert_equal('xxx 5', getline(5))
1076 call assert_equal('xxx 6', getline(6))
1077 call assert_equal('foo 7', getline(7))
1078
1079 call Incsearch_cleanup()
1080endfunc
1081
Bram Moolenaar795aaa12020-10-02 20:36:01 +02001082func Test_incsearch_substitute_long_line()
1083 new
1084 call test_override("char_avail", 1)
1085 set incsearch
1086
1087 call repeat('x', 100000)->setline(1)
1088 call feedkeys(':s/\%c', 'xt')
1089 redraw
1090 call feedkeys("\<Esc>", 'xt')
1091
1092 call Incsearch_cleanup()
1093 bwipe!
1094endfunc
1095
LemonBoya4399382022-04-09 21:04:08 +01001096func Test_hlsearch_cursearch()
1097 CheckScreendump
1098
1099 let lines =<< trim END
1100 set hlsearch scrolloff=0
Bram Moolenaar9b367502022-04-22 20:07:21 +01001101 call setline(1, ['one', 'foo', 'bar', 'baz', 'foo the foo and foo', 'bar'])
LemonBoya4399382022-04-09 21:04:08 +01001102 hi Search ctermbg=yellow
1103 hi CurSearch ctermbg=blue
1104 END
Bram Moolenaar56564962022-10-10 22:39:42 +01001105 call writefile(lines, 'Xhlsearch_cursearch', 'D')
LemonBoya4399382022-04-09 21:04:08 +01001106 let buf = RunVimInTerminal('-S Xhlsearch_cursearch', {'rows': 9, 'cols': 60})
1107
1108 call term_sendkeys(buf, "gg/foo\<CR>")
1109 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_1', {})
1110
1111 call term_sendkeys(buf, "n")
1112 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2', {})
1113
Bram Moolenaar9b367502022-04-22 20:07:21 +01001114 call term_sendkeys(buf, "n")
1115 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2a', {})
1116
1117 call term_sendkeys(buf, "n")
1118 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2b', {})
1119
1120 call term_sendkeys(buf, ":call setline(5, 'foo')\<CR>")
1121 call term_sendkeys(buf, "0?\<CR>")
LemonBoya4399382022-04-09 21:04:08 +01001122 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_3', {})
1123
1124 call term_sendkeys(buf, "gg/foo\\nbar\<CR>")
Bram Moolenaar693ccd12022-04-16 12:04:37 +01001125 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_1', {})
1126
1127 call term_sendkeys(buf, ":call setline(1, ['---', 'abcdefg', 'hijkl', '---', 'abcdefg', 'hijkl'])\<CR>")
1128 call term_sendkeys(buf, "gg/efg\\nhij\<CR>")
1129 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_2', {})
1130 call term_sendkeys(buf, "h\<C-L>")
1131 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_3', {})
1132 call term_sendkeys(buf, "j\<C-L>")
1133 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_4', {})
1134 call term_sendkeys(buf, "h\<C-L>")
1135 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_5', {})
LemonBoya4399382022-04-09 21:04:08 +01001136
Bram Moolenaar368137a2022-05-31 13:43:12 +01001137 " check clearing CurSearch when using it for another match
1138 call term_sendkeys(buf, "G?^abcd\<CR>Y")
1139 call term_sendkeys(buf, "kkP")
1140 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_changed_1', {})
1141
LemonBoya4399382022-04-09 21:04:08 +01001142 call StopVimInTerminal(buf)
LemonBoya4399382022-04-09 21:04:08 +01001143endfunc
1144
Bram Moolenaar164251f2018-08-12 16:26:58 +02001145" Similar to Test_incsearch_substitute() but with a screendump halfway.
1146func Test_incsearch_substitute_dump()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001147 CheckOption incsearch
1148 CheckScreendump
1149
Bram Moolenaar164251f2018-08-12 16:26:58 +02001150 call writefile([
1151 \ 'set incsearch hlsearch scrolloff=0',
1152 \ 'for n in range(1, 10)',
1153 \ ' call setline(n, "foo " . n)',
1154 \ 'endfor',
Bram Moolenaar2f6a3462018-08-14 18:16:52 +02001155 \ 'call setline(11, "bar 11")',
Bram Moolenaar164251f2018-08-12 16:26:58 +02001156 \ '3',
Bram Moolenaar56564962022-10-10 22:39:42 +01001157 \ ], 'Xis_subst_script', 'D')
Bram Moolenaar164251f2018-08-12 16:26:58 +02001158 let buf = RunVimInTerminal('-S Xis_subst_script', {'rows': 9, 'cols': 70})
1159 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1160 " the 'ambiwidth' check.
1161 sleep 100m
1162
1163 " Need to send one key at a time to force a redraw.
Bram Moolenaarc7f08b72018-08-12 17:39:14 +02001164 " Select three lines at the cursor with typed pattern.
Bram Moolenaar164251f2018-08-12 16:26:58 +02001165 call term_sendkeys(buf, ':.,.+2s/')
1166 sleep 100m
1167 call term_sendkeys(buf, 'f')
1168 sleep 100m
1169 call term_sendkeys(buf, 'o')
1170 sleep 100m
1171 call term_sendkeys(buf, 'o')
1172 call VerifyScreenDump(buf, 'Test_incsearch_substitute_01', {})
Bram Moolenaarc7f08b72018-08-12 17:39:14 +02001173 call term_sendkeys(buf, "\<Esc>")
1174
1175 " Select three lines at the cursor using previous pattern.
1176 call term_sendkeys(buf, "/foo\<CR>")
1177 sleep 100m
1178 call term_sendkeys(buf, ':.,.+2s//')
Bram Moolenaarc7f08b72018-08-12 17:39:14 +02001179 call VerifyScreenDump(buf, 'Test_incsearch_substitute_02', {})
1180
1181 " Deleting last slash should remove the match.
1182 call term_sendkeys(buf, "\<BS>")
Bram Moolenaarc7f08b72018-08-12 17:39:14 +02001183 call VerifyScreenDump(buf, 'Test_incsearch_substitute_03', {})
Bram Moolenaar60d08712018-08-12 21:53:15 +02001184 call term_sendkeys(buf, "\<Esc>")
1185
1186 " Reverse range is accepted
1187 call term_sendkeys(buf, ':5,2s/foo')
Bram Moolenaar60d08712018-08-12 21:53:15 +02001188 call VerifyScreenDump(buf, 'Test_incsearch_substitute_04', {})
Bram Moolenaar164251f2018-08-12 16:26:58 +02001189 call term_sendkeys(buf, "\<Esc>")
Bram Moolenaar2b926fc2018-08-13 11:07:57 +02001190
1191 " White space after the command is skipped
1192 call term_sendkeys(buf, ':2,3sub /fo')
Bram Moolenaar2b926fc2018-08-13 11:07:57 +02001193 call VerifyScreenDump(buf, 'Test_incsearch_substitute_05', {})
1194 call term_sendkeys(buf, "\<Esc>")
1195
Bram Moolenaar33c4dbb2018-08-14 16:06:16 +02001196 " Command modifiers are skipped
1197 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 +02001198 call VerifyScreenDump(buf, 'Test_incsearch_substitute_06', {})
1199 call term_sendkeys(buf, "\<Esc>")
1200
Bram Moolenaar2f6a3462018-08-14 18:16:52 +02001201 " Cursorline highlighting at match
1202 call term_sendkeys(buf, ":set cursorline\<CR>")
1203 call term_sendkeys(buf, 'G9G')
1204 call term_sendkeys(buf, ':9,11s/bar')
Bram Moolenaar2f6a3462018-08-14 18:16:52 +02001205 call VerifyScreenDump(buf, 'Test_incsearch_substitute_07', {})
1206 call term_sendkeys(buf, "\<Esc>")
1207
1208 " Cursorline highlighting at cursor when no match
1209 call term_sendkeys(buf, ':9,10s/bar')
Bram Moolenaar2f6a3462018-08-14 18:16:52 +02001210 call VerifyScreenDump(buf, 'Test_incsearch_substitute_08', {})
1211 call term_sendkeys(buf, "\<Esc>")
1212
Bram Moolenaar8b0d5ce2018-08-22 23:05:44 +02001213 " Only \v handled as empty pattern, does not move cursor
1214 call term_sendkeys(buf, '3G4G')
1215 call term_sendkeys(buf, ":nohlsearch\<CR>")
1216 call term_sendkeys(buf, ':6,7s/\v')
Bram Moolenaar8b0d5ce2018-08-22 23:05:44 +02001217 call VerifyScreenDump(buf, 'Test_incsearch_substitute_09', {})
1218 call term_sendkeys(buf, "\<Esc>")
1219
Bram Moolenaarf13daa42018-08-31 22:09:54 +02001220 call term_sendkeys(buf, ":set nocursorline\<CR>")
1221
1222 " All matches are highlighted for 'hlsearch' after the incsearch canceled
1223 call term_sendkeys(buf, "1G*")
1224 call term_sendkeys(buf, ":2,5s/foo")
1225 sleep 100m
1226 call term_sendkeys(buf, "\<Esc>")
1227 call VerifyScreenDump(buf, 'Test_incsearch_substitute_10', {})
1228
Bram Moolenaar65985ac2018-09-16 17:08:04 +02001229 call term_sendkeys(buf, ":split\<CR>")
1230 call term_sendkeys(buf, ":let @/ = 'xyz'\<CR>")
1231 call term_sendkeys(buf, ":%s/.")
1232 call VerifyScreenDump(buf, 'Test_incsearch_substitute_11', {})
1233 call term_sendkeys(buf, "\<BS>")
1234 call VerifyScreenDump(buf, 'Test_incsearch_substitute_12', {})
1235 call term_sendkeys(buf, "\<Esc>")
1236 call VerifyScreenDump(buf, 'Test_incsearch_substitute_13', {})
Bram Moolenaarc6725252019-11-23 21:56:46 +01001237 call term_sendkeys(buf, ":%bwipe!\<CR>")
1238 call term_sendkeys(buf, ":only!\<CR>")
1239
1240 " get :'<,'>s command in history
1241 call term_sendkeys(buf, ":set cmdheight=2\<CR>")
1242 call term_sendkeys(buf, "aasdfasdf\<Esc>")
1243 call term_sendkeys(buf, "V:s/a/b/g\<CR>")
1244 " Using '<,'> does not give E20
1245 call term_sendkeys(buf, ":new\<CR>")
1246 call term_sendkeys(buf, "aasdfasdf\<Esc>")
1247 call term_sendkeys(buf, ":\<Up>\<Up>")
1248 call VerifyScreenDump(buf, 'Test_incsearch_substitute_14', {})
1249 call term_sendkeys(buf, "<Esc>")
Bram Moolenaar65985ac2018-09-16 17:08:04 +02001250
Bram Moolenaar164251f2018-08-12 16:26:58 +02001251 call StopVimInTerminal(buf)
Bram Moolenaar164251f2018-08-12 16:26:58 +02001252endfunc
1253
Bram Moolenaarc036e872020-02-21 21:30:52 +01001254func Test_incsearch_highlighting()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001255 CheckOption incsearch
1256 CheckScreendump
Bram Moolenaarc036e872020-02-21 21:30:52 +01001257
1258 call writefile([
1259 \ 'set incsearch hlsearch',
1260 \ 'call setline(1, "hello/there")',
Bram Moolenaar56564962022-10-10 22:39:42 +01001261 \ ], 'Xis_subst_hl_script', 'D')
Bram Moolenaarc036e872020-02-21 21:30:52 +01001262 let buf = RunVimInTerminal('-S Xis_subst_hl_script', {'rows': 4, 'cols': 20})
1263 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1264 " the 'ambiwidth' check.
1265 sleep 300m
1266
1267 " Using a different search delimiter should still highlight matches
1268 " that contain a '/'.
1269 call term_sendkeys(buf, ":%s;ello/the")
1270 call VerifyScreenDump(buf, 'Test_incsearch_substitute_15', {})
1271 call term_sendkeys(buf, "<Esc>")
Bram Moolenaarb68df222020-03-19 15:05:28 +01001272
1273 call StopVimInTerminal(buf)
Bram Moolenaarc036e872020-02-21 21:30:52 +01001274endfunc
1275
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +01001276func Test_incsearch_with_change()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001277 CheckFeature timers
1278 CheckOption incsearch
1279 CheckScreendump
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +01001280
1281 call writefile([
1282 \ 'set incsearch hlsearch scrolloff=0',
1283 \ 'call setline(1, ["one", "two ------ X", "three"])',
1284 \ 'call timer_start(200, { _ -> setline(2, "x")})',
Bram Moolenaar56564962022-10-10 22:39:42 +01001285 \ ], 'Xis_change_script', 'D')
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +01001286 let buf = RunVimInTerminal('-S Xis_change_script', {'rows': 9, 'cols': 70})
1287 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1288 " the 'ambiwidth' check.
Bram Moolenaare86ecbd2019-02-21 17:48:59 +01001289 sleep 300m
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +01001290
1291 " Highlight X, it will be deleted by the timer callback.
1292 call term_sendkeys(buf, ':%s/X')
1293 call VerifyScreenDump(buf, 'Test_incsearch_change_01', {})
1294 call term_sendkeys(buf, "\<Esc>")
1295
1296 call StopVimInTerminal(buf)
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +01001297endfunc
1298
Bram Moolenaar81f56532018-08-18 16:19:42 +02001299" Similar to Test_incsearch_substitute_dump() for :sort
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +02001300func Test_incsearch_sort_dump()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001301 CheckOption incsearch
1302 CheckScreendump
1303
Bram Moolenaar81f56532018-08-18 16:19:42 +02001304 call writefile([
1305 \ 'set incsearch hlsearch scrolloff=0',
1306 \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
Bram Moolenaar56564962022-10-10 22:39:42 +01001307 \ ], 'Xis_sort_script', 'D')
Bram Moolenaar81f56532018-08-18 16:19:42 +02001308 let buf = RunVimInTerminal('-S Xis_sort_script', {'rows': 9, 'cols': 70})
1309 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1310 " the 'ambiwidth' check.
1311 sleep 100m
1312
Bram Moolenaar81f56532018-08-18 16:19:42 +02001313 call term_sendkeys(buf, ':sort ni u /on')
Bram Moolenaar81f56532018-08-18 16:19:42 +02001314 call VerifyScreenDump(buf, 'Test_incsearch_sort_01', {})
1315 call term_sendkeys(buf, "\<Esc>")
1316
Bram Moolenaar333015a2020-04-25 15:54:16 +02001317 call term_sendkeys(buf, ':sort! /on')
1318 call VerifyScreenDump(buf, 'Test_incsearch_sort_02', {})
1319 call term_sendkeys(buf, "\<Esc>")
1320
Bram Moolenaar81f56532018-08-18 16:19:42 +02001321 call StopVimInTerminal(buf)
Bram Moolenaar81f56532018-08-18 16:19:42 +02001322endfunc
1323
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001324" Similar to Test_incsearch_substitute_dump() for :vimgrep famiry
1325func Test_incsearch_vimgrep_dump()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001326 CheckOption incsearch
1327 CheckScreendump
1328
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001329 call writefile([
1330 \ 'set incsearch hlsearch scrolloff=0',
1331 \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
Bram Moolenaar56564962022-10-10 22:39:42 +01001332 \ ], 'Xis_vimgrep_script', 'D')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001333 let buf = RunVimInTerminal('-S Xis_vimgrep_script', {'rows': 9, 'cols': 70})
1334 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1335 " the 'ambiwidth' check.
1336 sleep 100m
1337
1338 " Need to send one key at a time to force a redraw.
1339 call term_sendkeys(buf, ':vimgrep on')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001340 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_01', {})
1341 call term_sendkeys(buf, "\<Esc>")
1342
1343 call term_sendkeys(buf, ':vimg /on/ *.txt')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001344 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_02', {})
1345 call term_sendkeys(buf, "\<Esc>")
1346
1347 call term_sendkeys(buf, ':vimgrepadd "\<on')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001348 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_03', {})
1349 call term_sendkeys(buf, "\<Esc>")
1350
1351 call term_sendkeys(buf, ':lv "tha')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001352 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_04', {})
1353 call term_sendkeys(buf, "\<Esc>")
1354
1355 call term_sendkeys(buf, ':lvimgrepa "the" **/*.txt')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001356 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_05', {})
1357 call term_sendkeys(buf, "\<Esc>")
1358
1359 call StopVimInTerminal(buf)
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001360endfunc
1361
Bram Moolenaar198cb662018-09-06 21:44:17 +02001362func Test_keep_last_search_pattern()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001363 CheckOption incsearch
1364
Bram Moolenaar198cb662018-09-06 21:44:17 +02001365 new
1366 call setline(1, ['foo', 'foo', 'foo'])
1367 set incsearch
1368 call test_override("char_avail", 1)
1369 let @/ = 'bar'
1370 call feedkeys(":/foo/s//\<Esc>", 'ntx')
1371 call assert_equal('bar', @/)
1372
Bram Moolenaar50eb16c2018-09-15 15:42:40 +02001373 " no error message if pattern not found
1374 call feedkeys(":/xyz/s//\<Esc>", 'ntx')
1375 call assert_equal('bar', @/)
1376
Bram Moolenaar198cb662018-09-06 21:44:17 +02001377 bwipe!
1378 call test_override("ALL", 0)
1379 set noincsearch
1380endfunc
1381
Bram Moolenaar99f043a2018-09-09 15:54:14 +02001382func Test_word_under_cursor_after_match()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001383 CheckOption incsearch
1384
Bram Moolenaar99f043a2018-09-09 15:54:14 +02001385 new
1386 call setline(1, 'foo bar')
1387 set incsearch
1388 call test_override("char_avail", 1)
1389 try
1390 call feedkeys("/foo\<C-R>\<C-W>\<CR>", 'ntx')
1391 catch /E486:/
1392 endtry
1393 call assert_equal('foobar', @/)
1394
1395 bwipe!
1396 call test_override("ALL", 0)
1397 set noincsearch
1398endfunc
1399
1400func Test_subst_word_under_cursor()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001401 CheckOption incsearch
1402
Bram Moolenaar99f043a2018-09-09 15:54:14 +02001403 new
1404 call setline(1, ['int SomeLongName;', 'for (xxx = 1; xxx < len; ++xxx)'])
1405 set incsearch
1406 call test_override("char_avail", 1)
1407 call feedkeys("/LongName\<CR>", 'ntx')
1408 call feedkeys(":%s/xxx/\<C-R>\<C-W>/g\<CR>", 'ntx')
1409 call assert_equal('for (SomeLongName = 1; SomeLongName < len; ++SomeLongName)', getline(2))
1410
1411 bwipe!
1412 call test_override("ALL", 0)
1413 set noincsearch
1414endfunc
1415
Bram Moolenaar3d79f0a2023-01-22 20:14:26 +00001416func Test_search_skip_all_matches()
1417 enew
1418 call setline(1, ['no match here',
1419 \ 'match this line',
1420 \ 'nope',
1421 \ 'match in this line',
1422 \ 'last line',
1423 \ ])
1424 call cursor(1, 1)
1425 let lnum = search('this', '', 0, 0, 'getline(".") =~ "this line"')
1426 " Only check that no match is found. Previously it searched forever.
1427 call assert_equal(0, lnum)
1428
1429 bwipe!
1430endfunc
1431
Bram Moolenaarf45938c2017-11-02 15:59:57 +01001432func Test_search_undefined_behaviour()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001433 CheckFeature terminal
1434
Bram Moolenaarf45938c2017-11-02 15:59:57 +01001435 let h = winheight(0)
1436 if h < 3
1437 return
1438 endif
1439 " did cause an undefined left shift
1440 let g:buf = term_start([GetVimProg(), '--clean', '-e', '-s', '-c', 'call search(getline("."))', 'samples/test000'], {'term_rows': 3})
1441 call assert_equal([''], getline(1, '$'))
1442 call term_sendkeys(g:buf, ":qa!\<cr>")
1443 bwipe!
1444endfunc
Bram Moolenaar2973daa2017-11-02 23:15:40 +01001445
1446func Test_search_undefined_behaviour2()
1447 call search("\%UC0000000")
1448endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01001449
1450" Test for search('multi-byte char', 'bce')
1451func Test_search_multibyte()
Bram Moolenaarfb094e12017-11-05 20:59:28 +01001452 let save_enc = &encoding
1453 set encoding=utf8
1454 enew!
1455 call append('$', 'A')
1456 call cursor(2, 1)
1457 call assert_equal(2, search('A', 'bce', line('.')))
1458 enew!
1459 let &encoding = save_enc
1460endfunc
Bram Moolenaar890dd052017-12-16 19:59:37 +01001461
1462" This was causing E874. Also causes an invalid read?
1463func Test_look_behind()
1464 new
Bram Moolenaar3ba35402019-12-21 22:00:50 +01001465 call setline(1, '0\|\&\n\@<=')
Bram Moolenaar890dd052017-12-16 19:59:37 +01001466 call search(getline("."))
1467 bwipe!
1468endfunc
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +01001469
Bram Moolenaar872bee52021-05-24 22:56:15 +02001470func Test_search_visual_area_linewise()
1471 new
1472 call setline(1, ['aa', 'bb', 'cc'])
1473 exe "normal 2GV\<Esc>"
1474 for engine in [1, 2]
1475 exe 'set regexpengine=' .. engine
1476 exe "normal gg/\\%'<\<CR>>"
1477 call assert_equal([0, 2, 1, 0, 1], getcurpos(), 'engine ' .. engine)
1478 exe "normal gg/\\%'>\<CR>"
1479 call assert_equal([0, 2, 2, 0, 2], getcurpos(), 'engine ' .. engine)
1480 endfor
1481
1482 bwipe!
1483 set regexpengine&
1484endfunc
1485
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +01001486func Test_search_sentence()
1487 new
1488 " this used to cause a crash
Bram Moolenaar1bd999f2017-12-19 22:25:40 +01001489 /\%'(
1490 /
Bram Moolenaar872bee52021-05-24 22:56:15 +02001491 bwipe
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +01001492endfunc
Bram Moolenaar2fb8f682018-12-01 13:14:45 +01001493
1494" Test that there is no crash when there is a last search pattern but no last
1495" substitute pattern.
1496func Test_no_last_substitute_pat()
1497 " Use viminfo to set the last search pattern to a string and make the last
1498 " substitute pattern the most recent used and make it empty (NULL).
Bram Moolenaar56564962022-10-10 22:39:42 +01001499 call writefile(['~MSle0/bar', '~MSle0~&'], 'Xviminfo', 'D')
Bram Moolenaar2fb8f682018-12-01 13:14:45 +01001500 rviminfo! Xviminfo
1501 call assert_fails('normal n', 'E35:')
Bram Moolenaar2fb8f682018-12-01 13:14:45 +01001502endfunc
Bram Moolenaar5f5e2032018-12-14 15:47:03 +01001503
1504func Test_search_Ctrl_L_combining()
1505 " Make sure, that Ctrl-L works correctly with combining characters.
1506 " It uses an artificial example of an 'a' with 4 combining chars:
Bram Moolenaar3ba35402019-12-21 22:00:50 +01001507 " 'a' U+0061 Dec:97 LATIN SMALL LETTER A &#x61; /\%u61\Z "\u0061"
Bram Moolenaar5f5e2032018-12-14 15:47:03 +01001508 " ' ̀' U+0300 Dec:768 COMBINING GRAVE ACCENT &#x300; /\%u300\Z "\u0300"
1509 " ' ́' U+0301 Dec:769 COMBINING ACUTE ACCENT &#x301; /\%u301\Z "\u0301"
1510 " ' ̇' U+0307 Dec:775 COMBINING DOT ABOVE &#x307; /\%u307\Z "\u0307"
Bram Moolenaar3ba35402019-12-21 22:00:50 +01001511 " ' ̣' U+0323 Dec:803 COMBINING DOT BELOW &#x323; /\%u323 "\u0323"
Bram Moolenaar5f5e2032018-12-14 15:47:03 +01001512 " Those should also appear on the commandline
Bram Moolenaarb68df222020-03-19 15:05:28 +01001513 CheckOption incsearch
1514
Bram Moolenaar5f5e2032018-12-14 15:47:03 +01001515 call Cmdline3_prep()
1516 1
1517 let bufcontent = ['', 'Miạ̀́̇m']
1518 call append('$', bufcontent)
1519 call feedkeys("/Mi\<c-l>\<c-l>\<cr>", 'tx')
1520 call assert_equal(5, line('.'))
1521 call assert_equal(bufcontent[1], @/)
1522 call Incsearch_cleanup()
1523endfunc
Bram Moolenaar527a2d82019-02-21 22:28:51 +01001524
Bram Moolenaarab350f82019-02-28 06:25:00 +01001525func Test_large_hex_chars1()
Bram Moolenaar527a2d82019-02-21 22:28:51 +01001526 " This used to cause a crash, the character becomes an NFA state.
1527 try
1528 /\%Ufffffc23
1529 catch
1530 call assert_match('E678:', v:exception)
1531 endtry
Bram Moolenaarab350f82019-02-28 06:25:00 +01001532 try
1533 set re=1
1534 /\%Ufffffc23
1535 catch
1536 call assert_match('E678:', v:exception)
1537 endtry
1538 set re&
1539endfunc
1540
1541func Test_large_hex_chars2()
1542 " This used to cause a crash, the character becomes an NFA state.
1543 try
1544 /[\Ufffffc1f]
1545 catch
Christian Brabandtf2b16982025-03-29 09:08:58 +01001546 call assert_match('E1541:', v:exception)
Bram Moolenaarab350f82019-02-28 06:25:00 +01001547 endtry
1548 try
1549 set re=1
1550 /[\Ufffffc1f]
1551 catch
Christian Brabandtf2b16982025-03-29 09:08:58 +01001552 call assert_match('E1541:', v:exception)
Bram Moolenaarab350f82019-02-28 06:25:00 +01001553 endtry
1554 set re&
Bram Moolenaar527a2d82019-02-21 22:28:51 +01001555endfunc
Bram Moolenaarcd625122019-02-22 17:29:43 +01001556
Christian Brabandtf2b16982025-03-29 09:08:58 +01001557func Test_large_hex_chars3()
1558 " Validate max number of Unicode char
1559 try
1560 /[\UFFFFFFFF]
1561 catch
1562 call assert_match('E1541:', v:exception)
1563 endtry
1564 try
1565 /[\UFFFFFFF]
1566 catch
1567 call assert_match('E486:', v:exception)
1568 endtry
1569 try
1570 /\%#=2[\d32-\UFFFFFFFF]
1571 catch
1572 call assert_match('E1541:', v:exception)
1573 endtry
1574 try
1575 /\%#=1[\UFFFFFFFF]
1576 catch
1577 call assert_match('E1541:', v:exception)
1578 endtry
1579 try
1580 /\%#=1[\d32-\UFFFFFFFF]
1581 catch
1582 call assert_match('E945:', v:exception)
1583 endtry
1584endfunc
1585
Bram Moolenaarcd625122019-02-22 17:29:43 +01001586func Test_one_error_msg()
Bram Moolenaar8832a342020-04-11 18:36:38 +02001587 " This was also giving an internal error
Bram Moolenaarcd625122019-02-22 17:29:43 +01001588 call assert_fails('call search(" \\((\\v[[=P=]]){185}+ ")', 'E871:')
1589endfunc
Bram Moolenaar730f48f2019-04-11 13:45:57 +02001590
1591func Test_incsearch_add_char_under_cursor()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001592 CheckOption incsearch
1593
Bram Moolenaar730f48f2019-04-11 13:45:57 +02001594 set incsearch
1595 new
1596 call setline(1, ['find match', 'anything'])
1597 1
1598 call test_override('char_avail', 1)
1599 call feedkeys("fc/m\<C-L>\<C-L>\<C-L>\<C-L>\<C-L>\<CR>", 'tx')
1600 call assert_equal('match', @/)
1601 call test_override('char_avail', 0)
1602
1603 set incsearch&
1604 bwipe!
1605endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001606
1607" Test for the search() function with match at the cursor position
1608func Test_search_match_at_curpos()
1609 new
1610 call append(0, ['foobar', '', 'one two', ''])
1611
1612 normal gg
1613
Bram Moolenaar196b4662019-09-06 21:34:30 +02001614 eval 'foobar'->search('c')
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001615 call assert_equal([1, 1], [line('.'), col('.')])
1616
1617 normal j
1618 call search('^$', 'c')
1619 call assert_equal([2, 1], [line('.'), col('.')])
1620
1621 call search('^$', 'bc')
1622 call assert_equal([2, 1], [line('.'), col('.')])
1623
1624 exe "normal /two\<CR>"
1625 call search('.', 'c')
1626 call assert_equal([3, 5], [line('.'), col('.')])
1627
1628 close!
1629endfunc
Bram Moolenaardb294ad2019-06-06 12:49:29 +02001630
Bram Moolenaar0e05de42020-03-25 22:23:46 +01001631" Test for error cases with the search() function
1632func Test_search_errors()
1633 call assert_fails("call search('pat', [])", 'E730:')
1634 call assert_fails("call search('pat', 'b', {})", 'E728:')
1635 call assert_fails("call search('pat', 'b', 1, [])", 'E745:')
1636 call assert_fails("call search('pat', 'ns')", 'E475:')
1637 call assert_fails("call search('pat', 'mr')", 'E475:')
Bram Moolenaar8832a342020-04-11 18:36:38 +02001638
1639 new
1640 call setline(1, ['foo', 'bar'])
1641 call assert_fails('call feedkeys("/foo/;/bar/;\<CR>", "tx")', 'E386:')
1642 bwipe!
Bram Moolenaar0e05de42020-03-25 22:23:46 +01001643endfunc
1644
Paul Ollis65745772022-06-05 16:55:54 +01001645func Test_search_timeout()
Bram Moolenaar73171ba2022-06-20 12:39:39 +01001646 let g:test_is_flaky = 1
Paul Ollis65745772022-06-05 16:55:54 +01001647 new
Bram Moolenaar616592e2022-06-17 15:17:10 +01001648 " use a complicated pattern that should be slow with the BT engine
Paul Ollis65745772022-06-05 16:55:54 +01001649 let pattern = '\%#=1a*.*X\@<=b*'
Bram Moolenaar616592e2022-06-17 15:17:10 +01001650
1651 " use a timeout of 50 msec
1652 let search_timeout = 0.05
1653
1654 " fill the buffer so that it takes 15 times the timeout to search
Paul Ollis65745772022-06-05 16:55:54 +01001655 let slow_target_timeout = search_timeout * 15.0
1656
Bram Moolenaar616592e2022-06-17 15:17:10 +01001657 " Fill the buffer with more and more text until searching takes more time
1658 " than slow_target_timeout.
Paul Ollis65745772022-06-05 16:55:54 +01001659 for n in range(40, 400, 30)
1660 call setline(1, ['aaa', repeat('abc ', n), 'ccc'])
1661 let start = reltime()
1662 call search(pattern, '', 0)
1663 let elapsed = reltimefloat(reltime(start))
1664 if elapsed > slow_target_timeout
1665 break
1666 endif
1667 endfor
1668 call assert_true(elapsed > slow_target_timeout)
1669
Bram Moolenaar616592e2022-06-17 15:17:10 +01001670 " Check that the timeout kicks in, the time should be less than half of what
1671 " we measured without the timeout. This is permissive, because the timer is
1672 " known to overrun, especially when using valgrind.
Paul Ollis65745772022-06-05 16:55:54 +01001673 let max_time = elapsed / 2.0
1674 let start = reltime()
1675 call search(pattern, '', 0, float2nr(search_timeout * 1000))
1676 let elapsed = reltimefloat(reltime(start))
Bram Moolenaar616592e2022-06-17 15:17:10 +01001677 call assert_inrange(search_timeout * 0.9, max_time, elapsed)
Paul Ollis65745772022-06-05 16:55:54 +01001678
1679 bwipe!
1680endfunc
1681
Bram Moolenaardb294ad2019-06-06 12:49:29 +02001682func Test_search_display_pattern()
1683 new
1684 call setline(1, ['foo', 'bar', 'foobar'])
1685
1686 call cursor(1, 1)
1687 let @/ = 'foo'
Bram Moolenaara4208962019-08-24 20:50:19 +02001688 let pat = @/->escape('()*?'. '\s\+')
Bram Moolenaardb294ad2019-06-06 12:49:29 +02001689 let g:a = execute(':unsilent :norm! n')
1690 call assert_match(pat, g:a)
1691
1692 " right-left
1693 if exists("+rightleft")
1694 set rl
1695 call cursor(1, 1)
1696 let @/ = 'foo'
1697 let pat = 'oof/\s\+'
1698 let g:a = execute(':unsilent :norm! n')
1699 call assert_match(pat, g:a)
1700 set norl
1701 endif
1702endfunc
Bram Moolenaar196b4662019-09-06 21:34:30 +02001703
1704func Test_searchdecl()
1705 let lines =<< trim END
1706 int global;
1707
1708 func()
1709 {
1710 int global;
1711 if (cond) {
1712 int local;
1713 }
1714 int local;
1715 // comment
1716 }
1717 END
1718 new
1719 call setline(1, lines)
1720 10
1721 call assert_equal(0, searchdecl('local', 0, 0))
1722 call assert_equal(7, getcurpos()[1])
1723
1724 10
1725 call assert_equal(0, 'local'->searchdecl(0, 1))
1726 call assert_equal(9, getcurpos()[1])
1727
1728 10
1729 call assert_equal(0, searchdecl('global'))
1730 call assert_equal(5, getcurpos()[1])
1731
1732 10
1733 call assert_equal(0, searchdecl('global', 1))
1734 call assert_equal(1, getcurpos()[1])
1735
1736 bwipe!
1737endfunc
Bram Moolenaar98a336d2020-01-20 20:22:30 +01001738
1739func Test_search_special()
Bram Moolenaarfe4bbac2020-01-20 21:12:20 +01001740 " this was causing illegal memory access and an endless loop
1741 set t_PE=
Bram Moolenaar98a336d2020-01-20 20:22:30 +01001742 exe "norm /\x80PS"
1743endfunc
Bram Moolenaar07ada5f2020-02-05 20:38:22 +01001744
1745" Test for command failures when the last search pattern is not set.
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001746" Need to run this in a new vim instance where last search pattern is not set.
Bram Moolenaar07ada5f2020-02-05 20:38:22 +01001747func Test_search_with_no_last_pat()
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001748 let lines =<< trim [SCRIPT]
1749 call assert_fails("normal i\<C-R>/\e", 'E35:')
1750 call assert_fails("exe '/'", 'E35:')
1751 call assert_fails("exe '?'", 'E35:')
1752 call assert_fails("/", 'E35:')
1753 call assert_fails("?", 'E35:')
1754 call assert_fails("normal n", 'E35:')
1755 call assert_fails("normal N", 'E35:')
1756 call assert_fails("normal gn", 'E35:')
1757 call assert_fails("normal gN", 'E35:')
1758 call assert_fails("normal cgn", 'E35:')
1759 call assert_fails("normal cgN", 'E35:')
1760 let p = []
1761 let p = @/
1762 call assert_equal('', p)
1763 call assert_fails("normal :\<C-R>/", 'E35:')
1764 call assert_fails("//p", 'E35:')
1765 call assert_fails(";//p", 'E35:')
1766 call assert_fails("??p", 'E35:')
1767 call assert_fails(";??p", 'E35:')
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001768 call assert_fails('g//p', ['E35:', 'E476:'])
1769 call assert_fails('v//p', ['E35:', 'E476:'])
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001770 call writefile(v:errors, 'Xresult')
1771 qall!
1772 [SCRIPT]
Bram Moolenaar56564962022-10-10 22:39:42 +01001773 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001774
1775 if RunVim([], [], '--clean -S Xscript')
1776 call assert_equal([], readfile('Xresult'))
1777 endif
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001778 call delete('Xresult')
Bram Moolenaar07ada5f2020-02-05 20:38:22 +01001779endfunc
1780
zeertzjqd1c8d2d2024-08-24 11:33:39 +02001781" Test for using the last substitute pattern without last search pattern.
1782func Test_search_with_last_substitute_pat()
1783 let lines =<< trim [SCRIPT]
1784 new
1785 set shortmess+=S
1786 call setline(1, repeat(['foofoo'], 3))
1787 %s/foo/bar/
1788 call assert_equal(repeat(['barfoo'], 3), getline(1, '$'))
1789
1790 call cursor(1, 1)
1791 call assert_equal("/foo", execute('call feedkeys("/\r", "tx")', '')->trim())
1792 call assert_equal([0, 1, 4, 0], getpos('.'))
1793
1794 if has('rightleft')
1795 set rightleft rightleftcmd=search
1796 call cursor(1, 1)
1797 call assert_equal("oof/", execute('call feedkeys("/\r", "tx")', '')->trim())
1798 call assert_equal([0, 1, 4, 0], getpos('.'))
1799 endif
1800
1801 call writefile(v:errors, 'Xresult')
1802 qall!
1803 [SCRIPT]
1804 call writefile(lines, 'Xscript', 'D')
1805
1806 if RunVim([], [], '--clean -S Xscript')
1807 call assert_equal([], readfile('Xresult'))
1808 endif
1809 call delete('Xresult')
1810endfunc
1811
Bram Moolenaar07ada5f2020-02-05 20:38:22 +01001812" Test for using tilde (~) atom in search. This should use the last used
1813" substitute pattern
1814func Test_search_tilde_pat()
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001815 let lines =<< trim [SCRIPT]
1816 set regexpengine=1
1817 call assert_fails('exe "normal /~\<CR>"', 'E33:')
1818 call assert_fails('exe "normal ?~\<CR>"', 'E33:')
1819 set regexpengine=2
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001820 call assert_fails('exe "normal /~\<CR>"', ['E33:', 'E383:'])
1821 call assert_fails('exe "normal ?~\<CR>"', ['E33:', 'E383:'])
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001822 set regexpengine&
1823 call writefile(v:errors, 'Xresult')
1824 qall!
1825 [SCRIPT]
Bram Moolenaar56564962022-10-10 22:39:42 +01001826 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001827 if RunVim([], [], '--clean -S Xscript')
1828 call assert_equal([], readfile('Xresult'))
1829 endif
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001830 call delete('Xresult')
Bram Moolenaar07ada5f2020-02-05 20:38:22 +01001831endfunc
1832
Bram Moolenaar406cd902020-02-18 21:54:41 +01001833" Test for searching a pattern that is not present with 'nowrapscan'
1834func Test_search_pat_not_found()
1835 new
1836 set nowrapscan
1837 let @/ = '1abcxyz2'
1838 call assert_fails('normal n', 'E385:')
1839 call assert_fails('normal N', 'E384:')
1840 set wrapscan&
1841 close
1842endfunc
1843
1844" Test for v:searchforward variable
1845func Test_searchforward_var()
1846 new
1847 call setline(1, ['foo', '', 'foo'])
1848 call cursor(2, 1)
1849 let @/ = 'foo'
1850 let v:searchforward = 0
1851 normal N
1852 call assert_equal(3, line('.'))
1853 call cursor(2, 1)
1854 let v:searchforward = 1
1855 normal N
1856 call assert_equal(1, line('.'))
1857 close!
1858endfunc
1859
Bram Moolenaar476a6132020-04-08 19:48:56 +02001860" Test for invalid regular expressions
1861func Test_invalid_regexp()
1862 set regexpengine=1
1863 call assert_fails("call search(repeat('\\(.\\)', 10))", 'E51:')
Bram Moolenaar4d23c522020-04-09 18:42:11 +02001864 call assert_fails("call search('\\%(')", 'E53:')
1865 call assert_fails("call search('\\(')", 'E54:')
1866 call assert_fails("call search('\\)')", 'E55:')
Bram Moolenaar476a6132020-04-08 19:48:56 +02001867 call assert_fails("call search('x\\@#')", 'E59:')
Bram Moolenaar4d23c522020-04-09 18:42:11 +02001868 call assert_fails('call search(''\v%(%(%(%(%(%(%(%(%(%(%(a){1}){1}){1}){1}){1}){1}){1}){1}){1}){1}){1}'')', 'E60:')
1869 call assert_fails("call search('a\\+*')", 'E61:')
Bram Moolenaar476a6132020-04-08 19:48:56 +02001870 call assert_fails("call search('\\_m')", 'E63:')
1871 call assert_fails("call search('\\+')", 'E64:')
1872 call assert_fails("call search('\\1')", 'E65:')
1873 call assert_fails("call search('\\z\\(\\)')", 'E66:')
1874 call assert_fails("call search('\\z2')", 'E67:')
1875 call assert_fails("call search('\\zx')", 'E68:')
1876 call assert_fails("call search('\\%[ab')", 'E69:')
1877 call assert_fails("call search('\\%[]')", 'E70:')
1878 call assert_fails("call search('\\%a')", 'E71:')
1879 call assert_fails("call search('ab\\%[\\(cd\\)]')", 'E369:')
1880 call assert_fails("call search('ab\\%[\\%(cd\\)]')", 'E369:')
1881 set regexpengine=2
1882 call assert_fails("call search('\\_')", 'E865:')
1883 call assert_fails("call search('\\+')", 'E866:')
1884 call assert_fails("call search('\\zx')", 'E867:')
1885 call assert_fails("call search('\\%a')", 'E867:')
1886 call assert_fails("call search('x\\@#')", 'E869:')
1887 call assert_fails("call search(repeat('\\(.\\)', 10))", 'E872:')
1888 call assert_fails("call search('\\_m')", 'E877:')
1889 call assert_fails("call search('\\%(')", 'E53:')
1890 call assert_fails("call search('\\(')", 'E54:')
1891 call assert_fails("call search('\\)')", 'E55:')
1892 call assert_fails("call search('\\z\\(\\)')", 'E66:')
Dominique Pelle8bfa0eb2022-01-02 16:16:33 +00001893 call assert_fails("call search('\\z2')", 'E67:')
1894 call assert_fails("call search('\\zx')", 'E867:')
Bram Moolenaar476a6132020-04-08 19:48:56 +02001895 call assert_fails("call search('\\%[ab')", 'E69:')
Bram Moolenaar4d23c522020-04-09 18:42:11 +02001896 call assert_fails("call search('\\%[]')", 'E70:')
Bram Moolenaar476a6132020-04-08 19:48:56 +02001897 call assert_fails("call search('\\%9999999999999999999999999999v')", 'E951:')
1898 set regexpengine&
1899 call assert_fails("call search('\\%#=3ab')", 'E864:')
1900endfunc
1901
Bram Moolenaar004a6782020-04-11 17:09:31 +02001902" Test for searching a very complex pattern in a string. Should switch the
1903" regexp engine from NFA to the old engine.
1904func Test_regexp_switch_engine()
1905 let l = readfile('samples/re.freeze.txt')
1906 let v = substitute(l[4], '..\@<!', '', '')
1907 call assert_equal(l[4], v)
1908endfunc
1909
1910" Test for the \%V atom to search within visually selected text
1911func Test_search_in_visual_area()
1912 new
1913 call setline(1, ['foo bar1', 'foo bar2', 'foo bar3', 'foo bar4'])
1914 exe "normal 2GVjo/\\%Vbar\<CR>\<Esc>"
1915 call assert_equal([2, 5], [line('.'), col('.')])
1916 exe "normal 2GVj$?\\%Vbar\<CR>\<Esc>"
1917 call assert_equal([3, 5], [line('.'), col('.')])
1918 close!
1919endfunc
1920
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02001921" Test for searching with 'smartcase' and 'ignorecase'
1922func Test_search_smartcase()
1923 new
1924 call setline(1, ['', 'Hello'])
1925 set noignorecase nosmartcase
1926 call assert_fails('exe "normal /\\a\\_.\\(.*\\)O\<CR>"', 'E486:')
1927
1928 set ignorecase nosmartcase
1929 exe "normal /\\a\\_.\\(.*\\)O\<CR>"
1930 call assert_equal([2, 1], [line('.'), col('.')])
1931
1932 call cursor(1, 1)
1933 set ignorecase smartcase
1934 call assert_fails('exe "normal /\\a\\_.\\(.*\\)O\<CR>"', 'E486:')
1935
1936 exe "normal /\\a\\_.\\(.*\\)o\<CR>"
1937 call assert_equal([2, 1], [line('.'), col('.')])
1938
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001939 " Test for using special atoms with 'smartcase'
1940 call setline(1, ['', ' Hello\ '])
1941 call cursor(1, 1)
1942 call feedkeys('/\_.\%(\uello\)\' .. "\<CR>", 'xt')
1943 call assert_equal([2, 4], [line('.'), col('.')])
1944
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02001945 set ignorecase& smartcase&
1946 close!
Bram Moolenaard66cdcd2020-07-26 13:27:16 +02001947endfun
1948
1949" Test 'smartcase' with utf-8.
1950func Test_search_smartcase_utf8()
1951 new
1952 let save_enc = &encoding
1953 set encoding=utf8 ignorecase smartcase
1954
1955 call setline(1, 'Café cafÉ')
1956 1s/café/x/g
1957 call assert_equal('x x', getline(1))
1958
1959 call setline(1, 'Café cafÉ')
1960 1s/cafÉ/x/g
1961 call assert_equal('Café x', getline(1))
1962
1963 set ignorecase& smartcase&
1964 let &encoding = save_enc
Bram Moolenaarc96311b2022-11-25 21:13:47 +00001965 bwipe!
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02001966endfunc
1967
1968" Test searching past the end of a file
1969func Test_search_past_eof()
1970 new
1971 call setline(1, ['Line'])
1972 exe "normal /\\n\\zs\<CR>"
1973 call assert_equal([1, 4], [line('.'), col('.')])
Bram Moolenaarc96311b2022-11-25 21:13:47 +00001974 bwipe!
1975endfunc
1976
1977" Test setting the start of the match and still finding a next match in the
1978" same line.
1979func Test_search_set_start_same_line()
1980 new
1981 set cpo-=c
1982
1983 call setline(1, ['1', '2', '3 .', '4', '5'])
1984 exe "normal /\\_s\\zs\\S\<CR>"
1985 call assert_equal([2, 1], [line('.'), col('.')])
1986 exe 'normal n'
1987 call assert_equal([3, 1], [line('.'), col('.')])
1988 exe 'normal n'
1989 call assert_equal([3, 3], [line('.'), col('.')])
1990 exe 'normal n'
1991 call assert_equal([4, 1], [line('.'), col('.')])
1992 exe 'normal n'
1993 call assert_equal([5, 1], [line('.'), col('.')])
1994
1995 set cpo+=c
1996 bwipe!
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02001997endfunc
1998
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001999" Test for various search offsets
2000func Test_search_offset()
2001 " With /e, for a match in the first column of a line, the cursor should be
2002 " placed at the end of the previous line.
2003 new
2004 call setline(1, ['one two', 'three four'])
2005 call search('two\_.', 'e')
2006 call assert_equal([1, 7], [line('.'), col('.')])
2007
2008 " with cursor at the beginning of the file, use /s+1
2009 call cursor(1, 1)
2010 exe "normal /two/s+1\<CR>"
2011 call assert_equal([1, 6], [line('.'), col('.')])
2012
2013 " with cursor at the end of the file, use /e-1
2014 call cursor(2, 10)
2015 exe "normal ?three?e-1\<CR>"
2016 call assert_equal([2, 4], [line('.'), col('.')])
2017
2018 " line offset - after the last line
2019 call cursor(1, 1)
2020 exe "normal /three/+1\<CR>"
2021 call assert_equal([2, 1], [line('.'), col('.')])
2022
2023 " line offset - before the first line
2024 call cursor(2, 1)
2025 exe "normal ?one?-1\<CR>"
2026 call assert_equal([1, 1], [line('.'), col('.')])
2027
2028 " character offset - before the first character in the file
2029 call cursor(2, 1)
2030 exe "normal ?one?s-1\<CR>"
2031 call assert_equal([1, 1], [line('.'), col('.')])
2032 call cursor(2, 1)
2033 exe "normal ?one?e-3\<CR>"
2034 call assert_equal([1, 1], [line('.'), col('.')])
2035
2036 " character offset - after the last character in the file
2037 call cursor(1, 1)
2038 exe "normal /four/s+4\<CR>"
2039 call assert_equal([2, 10], [line('.'), col('.')])
2040 call cursor(1, 1)
2041 exe "normal /four/e+1\<CR>"
2042 call assert_equal([2, 10], [line('.'), col('.')])
2043
2044 close!
2045endfunc
2046
2047" Test for searching for matching parenthesis using %
2048func Test_search_match_paren()
2049 new
2050 call setline(1, "abc(def')'ghi'('jk'\\t'lm)no")
2051 " searching for a matching parenthesis should skip single quoted characters
2052 call cursor(1, 4)
2053 normal %
2054 call assert_equal([1, 25], [line('.'), col('.')])
2055 normal %
2056 call assert_equal([1, 4], [line('.'), col('.')])
2057 call cursor(1, 5)
2058 normal ])
2059 call assert_equal([1, 25], [line('.'), col('.')])
2060 call cursor(1, 24)
2061 normal [(
2062 call assert_equal([1, 4], [line('.'), col('.')])
2063
2064 " matching parenthesis in 'virtualedit' mode with cursor after the eol
2065 call setline(1, 'abc(defgh)')
2066 set virtualedit=all
2067 normal 20|%
2068 call assert_equal(4, col('.'))
2069 set virtualedit&
2070 close!
2071endfunc
2072
2073" Test for searching a pattern and stopping before a specified line
2074func Test_search_stopline()
2075 new
2076 call setline(1, ['', '', '', 'vim'])
2077 call assert_equal(0, search('vim', 'n', 3))
2078 call assert_equal(4, search('vim', 'n', 4))
2079 call setline(1, ['vim', '', '', ''])
2080 call cursor(4, 1)
2081 call assert_equal(0, search('vim', 'bn', 2))
2082 call assert_equal(1, search('vim', 'bn', 1))
2083 close!
2084endfunc
2085
Bram Moolenaar6bed0db2020-11-25 17:41:20 +01002086func Test_incsearch_highlighting_newline()
Bram Moolenaar448465e2020-11-25 13:49:27 +01002087 CheckRunVimInTerminal
2088 CheckOption incsearch
2089 CheckScreendump
2090 new
2091 call test_override("char_avail", 1)
2092
2093 let commands =<< trim [CODE]
2094 set incsearch nohls
2095 call setline(1, ['test', 'xxx'])
2096 [CODE]
Bram Moolenaar56564962022-10-10 22:39:42 +01002097 call writefile(commands, 'Xincsearch_nl', 'D')
Bram Moolenaar448465e2020-11-25 13:49:27 +01002098 let buf = RunVimInTerminal('-S Xincsearch_nl', {'rows': 5, 'cols': 10})
Bram Moolenaar448465e2020-11-25 13:49:27 +01002099 call term_sendkeys(buf, '/test')
Bram Moolenaar448465e2020-11-25 13:49:27 +01002100 call VerifyScreenDump(buf, 'Test_incsearch_newline1', {})
Bram Moolenaar6bed0db2020-11-25 17:41:20 +01002101 " Need to send one key at a time to force a redraw
Bram Moolenaar448465e2020-11-25 13:49:27 +01002102 call term_sendkeys(buf, '\n')
Bram Moolenaar448465e2020-11-25 13:49:27 +01002103 call VerifyScreenDump(buf, 'Test_incsearch_newline2', {})
2104 call term_sendkeys(buf, 'x')
Bram Moolenaar448465e2020-11-25 13:49:27 +01002105 call VerifyScreenDump(buf, 'Test_incsearch_newline3', {})
2106 call term_sendkeys(buf, 'x')
2107 call VerifyScreenDump(buf, 'Test_incsearch_newline4', {})
2108 call term_sendkeys(buf, "\<CR>")
Bram Moolenaar448465e2020-11-25 13:49:27 +01002109 call VerifyScreenDump(buf, 'Test_incsearch_newline5', {})
2110 call StopVimInTerminal(buf)
2111
2112 " clean up
Bram Moolenaar448465e2020-11-25 13:49:27 +01002113 call test_override("char_avail", 0)
2114 bw
2115endfunc
2116
Bram Moolenaard93a7fc2021-01-04 12:42:13 +01002117func Test_incsearch_substitute_dump2()
2118 CheckOption incsearch
2119 CheckScreendump
2120
2121 call writefile([
2122 \ 'set incsearch hlsearch scrolloff=0',
2123 \ 'for n in range(1, 4)',
2124 \ ' call setline(n, "foo " . n)',
2125 \ 'endfor',
2126 \ 'call setline(5, "abc|def")',
2127 \ '3',
Bram Moolenaar56564962022-10-10 22:39:42 +01002128 \ ], 'Xis_subst_script2', 'D')
Bram Moolenaard93a7fc2021-01-04 12:42:13 +01002129 let buf = RunVimInTerminal('-S Xis_subst_script2', {'rows': 9, 'cols': 70})
2130
2131 call term_sendkeys(buf, ':%s/\vabc|')
2132 sleep 100m
2133 call VerifyScreenDump(buf, 'Test_incsearch_sub_01', {})
2134 call term_sendkeys(buf, "\<Esc>")
2135
2136 " The following should not be highlighted
2137 call term_sendkeys(buf, ':1,5s/\v|')
2138 sleep 100m
2139 call VerifyScreenDump(buf, 'Test_incsearch_sub_02', {})
2140
2141
2142 call StopVimInTerminal(buf)
Bram Moolenaard93a7fc2021-01-04 12:42:13 +01002143endfunc
2144
zeertzjq7b7b4cb2023-08-11 23:48:27 +02002145func Test_incsearch_restore_view()
2146 CheckOption incsearch
2147 CheckScreendump
2148
2149 let lines =<< trim [CODE]
2150 set incsearch nohlsearch
2151 setlocal scrolloff=0 smoothscroll
2152 call setline(1, [join(range(25), ' '), '', '', '', '', 'xxx'])
2153 call feedkeys("2\<C-E>", 't')
2154 [CODE]
2155 call writefile(lines, 'Xincsearch_restore_view', 'D')
2156 let buf = RunVimInTerminal('-S Xincsearch_restore_view', {'rows': 6, 'cols': 20})
2157
2158 call VerifyScreenDump(buf, 'Test_incsearch_restore_view_01', {})
Christ van Willegen73b82092023-08-12 20:17:26 +02002159 call term_sendkeys(buf, '/xx')
zeertzjq7b7b4cb2023-08-11 23:48:27 +02002160 call VerifyScreenDump(buf, 'Test_incsearch_restore_view_02', {})
Christ van Willegen73b82092023-08-12 20:17:26 +02002161 call term_sendkeys(buf, 'x')
2162 call VerifyScreenDump(buf, 'Test_incsearch_restore_view_03', {})
zeertzjq7b7b4cb2023-08-11 23:48:27 +02002163 call term_sendkeys(buf, "\<Esc>")
2164 call VerifyScreenDump(buf, 'Test_incsearch_restore_view_01', {})
2165
2166 call StopVimInTerminal(buf)
2167endfunc
2168
Christian Brabandt78ba9332021-08-01 12:44:37 +02002169func Test_pattern_is_uppercase_smartcase()
2170 new
2171 let input=['abc', 'ABC', 'Abc', 'abC']
2172 call setline(1, input)
2173 call cursor(1,1)
2174 " default, matches firstline
2175 %s/abc//g
2176 call assert_equal(['', 'ABC', 'Abc', 'abC'],
2177 \ getline(1, '$'))
2178
2179 set smartcase ignorecase
2180 sil %d
2181 call setline(1, input)
2182 call cursor(1,1)
2183 " with smartcase and incsearch set, matches everything
2184 %s/abc//g
2185 call assert_equal(['', '', '', ''], getline(1, '$'))
2186
2187 sil %d
2188 call setline(1, input)
2189 call cursor(1,1)
2190 " with smartcase and incsearch set and found an uppercase letter,
2191 " match only that.
2192 %s/abC//g
2193 call assert_equal(['abc', 'ABC', 'Abc', ''],
2194 \ getline(1, '$'))
2195
2196 sil %d
2197 call setline(1, input)
2198 call cursor(1,1)
2199 exe "norm! vG$\<esc>"
2200 " \%V should not be detected as uppercase letter
2201 %s/\%Vabc//g
2202 call assert_equal(['', '', '', ''], getline(1, '$'))
2203
2204 call setline(1, input)
2205 call cursor(1,1)
2206 exe "norm! vG$\<esc>"
2207 " \v%V should not be detected as uppercase letter
2208 %s/\v%Vabc//g
2209 call assert_equal(['', '', '', ''], getline(1, '$'))
2210
2211 call setline(1, input)
2212 call cursor(1,1)
2213 exe "norm! vG$\<esc>"
2214 " \v%VabC should be detected as uppercase letter
2215 %s/\v%VabC//g
2216 call assert_equal(['abc', 'ABC', 'Abc', ''],
2217 \ getline(1, '$'))
2218
Christian Brabandtbc67e5a2021-08-05 15:24:59 +02002219 call setline(1, input)
2220 call cursor(1,1)
2221 " \Vabc should match everything
2222 %s/\Vabc//g
2223 call assert_equal(['', '', '', ''], getline(1, '$'))
2224
2225 call setline(1, input + ['_abc'])
2226 " _ matches normally
2227 %s/\v_.*//g
2228 call assert_equal(['abc', 'ABC', 'Abc', 'abC', ''], getline(1, '$'))
2229
Christian Brabandt78ba9332021-08-01 12:44:37 +02002230 set smartcase& ignorecase&
2231 bw!
2232endfunc
2233
Bram Moolenaard8d957d2021-10-04 19:47:35 +01002234func Test_no_last_search_pattern()
2235 CheckOption incsearch
2236
2237 let @/ = ""
2238 set incsearch
Bram Moolenaar9af9fd62021-10-04 20:09:19 +01002239 " these were causing a crash
2240 call feedkeys("//\<C-G>", 'xt')
2241 call feedkeys("//\<C-T>", 'xt')
2242 call feedkeys("??\<C-G>", 'xt')
2243 call feedkeys("??\<C-T>", 'xt')
Bram Moolenaard8d957d2021-10-04 19:47:35 +01002244endfunc
2245
Bram Moolenaar35a319b2021-10-09 13:58:55 +01002246func Test_search_with_invalid_range()
2247 new
2248 let lines =<< trim END
2249 /\%.v
2250 5/
2251 c
2252 END
Bram Moolenaar56564962022-10-10 22:39:42 +01002253 call writefile(lines, 'Xrangesearch', 'D')
Bram Moolenaar35a319b2021-10-09 13:58:55 +01002254 source Xrangesearch
2255
2256 bwipe!
Bram Moolenaar35a319b2021-10-09 13:58:55 +01002257endfunc
2258
Bram Moolenaard8d957d2021-10-04 19:47:35 +01002259
Bram Moolenaar07ada5f2020-02-05 20:38:22 +01002260" vim: shiftwidth=2 sts=2 expandtab