blob: 4e5fd0620f7017ea7e1bd43ee25b8570cdfdf50d [file] [log] [blame]
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +02001" Test for the search command
2
Christian Brabandteb380b92025-07-07 20:53:55 +02003source util/screendump.vim
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +01004
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +02005func Test_search_cmdline()
Bram Moolenaarb68df222020-03-19 15:05:28 +01006 CheckOption incsearch
7
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +02008 " need to disable char_avail,
9 " so that expansion of commandline works
Bram Moolenaareb992cb2017-03-09 18:20:16 +010010 call test_override("char_avail", 1)
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020011 new
12 call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar'])
13 " Test 1
14 " CTRL-N / CTRL-P skips through the previous search history
15 set noincsearch
16 :1
17 call feedkeys("/foobar\<cr>", 'tx')
Bram Moolenaar8832a342020-04-11 18:36:38 +020018 call feedkeys("/the\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020019 call assert_equal('the', @/)
Bram Moolenaar8832a342020-04-11 18:36:38 +020020 call feedkeys("/thes\<C-P>\<C-P>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020021 call assert_equal('foobar', @/)
22
23 " Test 2
Bram Moolenaar11956692016-08-27 16:26:56 +020024 " Ctrl-G goes from one match to the next
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020025 " until the end of the buffer
26 set incsearch nowrapscan
27 :1
28 " first match
29 call feedkeys("/the\<cr>", 'tx')
30 call assert_equal(' 2 these', getline('.'))
31 :1
32 " second match
Bram Moolenaar11956692016-08-27 16:26:56 +020033 call feedkeys("/the\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020034 call assert_equal(' 3 the', getline('.'))
Bram Moolenaardda933d2016-09-03 21:04:58 +020035 call assert_equal([0, 0, 0, 0], getpos('"'))
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020036 :1
37 " third match
Bram Moolenaar11956692016-08-27 16:26:56 +020038 call feedkeys("/the".repeat("\<C-G>", 2)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020039 call assert_equal(' 4 their', getline('.'))
40 :1
41 " fourth match
Bram Moolenaar11956692016-08-27 16:26:56 +020042 call feedkeys("/the".repeat("\<C-G>", 3)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020043 call assert_equal(' 5 there', getline('.'))
44 :1
45 " fifth match
Bram Moolenaar11956692016-08-27 16:26:56 +020046 call feedkeys("/the".repeat("\<C-G>", 4)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020047 call assert_equal(' 6 their', getline('.'))
48 :1
49 " sixth match
Bram Moolenaar11956692016-08-27 16:26:56 +020050 call feedkeys("/the".repeat("\<C-G>", 5)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020051 call assert_equal(' 7 the', getline('.'))
52 :1
53 " seventh match
Bram Moolenaar11956692016-08-27 16:26:56 +020054 call feedkeys("/the".repeat("\<C-G>", 6)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020055 call assert_equal(' 8 them', getline('.'))
56 :1
Bram Moolenaar3ba35402019-12-21 22:00:50 +010057 " eighth match
Bram Moolenaar11956692016-08-27 16:26:56 +020058 call feedkeys("/the".repeat("\<C-G>", 7)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020059 call assert_equal(' 9 these', getline('.'))
60 :1
61 " no further match
Bram Moolenaar11956692016-08-27 16:26:56 +020062 call feedkeys("/the".repeat("\<C-G>", 8)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020063 call assert_equal(' 9 these', getline('.'))
Bram Moolenaardda933d2016-09-03 21:04:58 +020064 call assert_equal([0, 0, 0, 0], getpos('"'))
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020065
66 " Test 3
Bram Moolenaar11956692016-08-27 16:26:56 +020067 " Ctrl-G goes from one match to the next
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020068 " and continues back at the top
69 set incsearch wrapscan
70 :1
71 " first match
72 call feedkeys("/the\<cr>", 'tx')
73 call assert_equal(' 2 these', getline('.'))
74 :1
75 " second match
Bram Moolenaar11956692016-08-27 16:26:56 +020076 call feedkeys("/the\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020077 call assert_equal(' 3 the', getline('.'))
78 :1
79 " third match
Bram Moolenaar11956692016-08-27 16:26:56 +020080 call feedkeys("/the".repeat("\<C-G>", 2)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020081 call assert_equal(' 4 their', getline('.'))
82 :1
83 " fourth match
Bram Moolenaar11956692016-08-27 16:26:56 +020084 call feedkeys("/the".repeat("\<C-G>", 3)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020085 call assert_equal(' 5 there', getline('.'))
86 :1
87 " fifth match
Bram Moolenaar11956692016-08-27 16:26:56 +020088 call feedkeys("/the".repeat("\<C-G>", 4)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020089 call assert_equal(' 6 their', getline('.'))
90 :1
91 " sixth match
Bram Moolenaar11956692016-08-27 16:26:56 +020092 call feedkeys("/the".repeat("\<C-G>", 5)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020093 call assert_equal(' 7 the', getline('.'))
94 :1
95 " seventh match
Bram Moolenaar11956692016-08-27 16:26:56 +020096 call feedkeys("/the".repeat("\<C-G>", 6)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +020097 call assert_equal(' 8 them', getline('.'))
98 :1
Bram Moolenaar3ba35402019-12-21 22:00:50 +010099 " eighth match
Bram Moolenaar11956692016-08-27 16:26:56 +0200100 call feedkeys("/the".repeat("\<C-G>", 7)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200101 call assert_equal(' 9 these', getline('.'))
102 :1
103 " back at first match
Bram Moolenaar11956692016-08-27 16:26:56 +0200104 call feedkeys("/the".repeat("\<C-G>", 8)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200105 call assert_equal(' 2 these', getline('.'))
106
107 " Test 4
Bram Moolenaar11956692016-08-27 16:26:56 +0200108 " CTRL-T goes to the previous match
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200109 set incsearch nowrapscan
110 $
111 " first match
112 call feedkeys("?the\<cr>", 'tx')
113 call assert_equal(' 9 these', getline('.'))
114 $
115 " first match
Bram Moolenaar11956692016-08-27 16:26:56 +0200116 call feedkeys("?the\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200117 call assert_equal(' 9 these', getline('.'))
118 $
119 " second match
Bram Moolenaar11956692016-08-27 16:26:56 +0200120 call feedkeys("?the".repeat("\<C-T>", 1)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200121 call assert_equal(' 8 them', getline('.'))
122 $
123 " last match
Bram Moolenaar11956692016-08-27 16:26:56 +0200124 call feedkeys("?the".repeat("\<C-T>", 7)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200125 call assert_equal(' 2 these', getline('.'))
126 $
127 " last match
Bram Moolenaar11956692016-08-27 16:26:56 +0200128 call feedkeys("?the".repeat("\<C-T>", 8)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200129 call assert_equal(' 2 these', getline('.'))
130
131 " Test 5
Bram Moolenaar11956692016-08-27 16:26:56 +0200132 " CTRL-T goes to the previous match
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200133 set incsearch wrapscan
134 $
135 " first match
136 call feedkeys("?the\<cr>", 'tx')
137 call assert_equal(' 9 these', getline('.'))
138 $
139 " first match at the top
Bram Moolenaar11956692016-08-27 16:26:56 +0200140 call feedkeys("?the\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200141 call assert_equal(' 2 these', getline('.'))
142 $
143 " second match
Bram Moolenaar11956692016-08-27 16:26:56 +0200144 call feedkeys("?the".repeat("\<C-T>", 1)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200145 call assert_equal(' 8 them', getline('.'))
146 $
147 " last match
Bram Moolenaar11956692016-08-27 16:26:56 +0200148 call feedkeys("?the".repeat("\<C-T>", 7)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200149 call assert_equal(' 2 these', getline('.'))
150 $
151 " back at the bottom of the buffer
Bram Moolenaar11956692016-08-27 16:26:56 +0200152 call feedkeys("?the".repeat("\<C-T>", 8)."\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200153 call assert_equal(' 9 these', getline('.'))
154
155 " Test 6
156 " CTRL-L adds to the search pattern
157 set incsearch wrapscan
158 1
159 " first match
160 call feedkeys("/the\<c-l>\<cr>", 'tx')
161 call assert_equal(' 2 these', getline('.'))
162 1
163 " go to next match of 'thes'
Bram Moolenaar11956692016-08-27 16:26:56 +0200164 call feedkeys("/the\<c-l>\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200165 call assert_equal(' 9 these', getline('.'))
166 1
167 " wrap around
Bram Moolenaar11956692016-08-27 16:26:56 +0200168 call feedkeys("/the\<c-l>\<C-G>\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200169 call assert_equal(' 2 these', getline('.'))
170 1
171 " wrap around
172 set nowrapscan
Bram Moolenaar11956692016-08-27 16:26:56 +0200173 call feedkeys("/the\<c-l>\<C-G>\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200174 call assert_equal(' 9 these', getline('.'))
175
176 " Test 7
177 " <bs> remove from match, but stay at current match
178 set incsearch wrapscan
179 1
180 " first match
181 call feedkeys("/thei\<cr>", 'tx')
182 call assert_equal(' 4 their', getline('.'))
183 1
184 " delete one char, add another
185 call feedkeys("/thei\<bs>s\<cr>", 'tx')
Bram Moolenaardda933d2016-09-03 21:04:58 +0200186 call assert_equal(' 2 these', getline('.'))
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200187 1
188 " delete one char, add another, go to previous match, add one char
Bram Moolenaar11956692016-08-27 16:26:56 +0200189 call feedkeys("/thei\<bs>s\<bs>\<C-T>\<c-l>\<cr>", 'tx')
Bram Moolenaardda933d2016-09-03 21:04:58 +0200190 call assert_equal(' 9 these', getline('.'))
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200191 1
192 " delete all chars, start from the beginning again
193 call feedkeys("/them". repeat("\<bs>",4).'the\>'."\<cr>", 'tx')
194 call assert_equal(' 3 the', getline('.'))
195
196 " clean up
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100197 call test_override("char_avail", 0)
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200198 bw!
199endfunc
200
201func Test_search_cmdline2()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100202 CheckOption incsearch
203
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200204 " need to disable char_avail,
205 " so that expansion of commandline works
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100206 call test_override("char_avail", 1)
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200207 new
208 call setline(1, [' 1', ' 2 these', ' 3 the theother'])
209 " Test 1
Bram Moolenaar11956692016-08-27 16:26:56 +0200210 " Ctrl-T goes correctly back and forth
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200211 set incsearch
212 1
213 " first match
214 call feedkeys("/the\<cr>", 'tx')
215 call assert_equal(' 2 these', getline('.'))
216 1
217 " go to next match (on next line)
Bram Moolenaar11956692016-08-27 16:26:56 +0200218 call feedkeys("/the\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200219 call assert_equal(' 3 the theother', getline('.'))
220 1
221 " go to next match (still on line 3)
Bram Moolenaar11956692016-08-27 16:26:56 +0200222 call feedkeys("/the\<C-G>\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200223 call assert_equal(' 3 the theother', getline('.'))
224 1
225 " go to next match (still on line 3)
Bram Moolenaar11956692016-08-27 16:26:56 +0200226 call feedkeys("/the\<C-G>\<C-G>\<C-G>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200227 call assert_equal(' 3 the theother', getline('.'))
228 1
229 " go to previous match (on line 3)
Bram Moolenaar11956692016-08-27 16:26:56 +0200230 call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200231 call assert_equal(' 3 the theother', getline('.'))
232 1
233 " go to previous match (on line 3)
Bram Moolenaar11956692016-08-27 16:26:56 +0200234 call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200235 call assert_equal(' 3 the theother', getline('.'))
236 1
237 " go to previous match (on line 2)
Bram Moolenaar11956692016-08-27 16:26:56 +0200238 call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<C-T>\<cr>", 'tx')
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200239 call assert_equal(' 2 these', getline('.'))
Bram Moolenaar69a5b862019-07-16 21:38:51 +0200240 1
241 " go to previous match (on line 2)
242 call feedkeys("/the\<C-G>\<C-R>\<C-W>\<cr>", 'tx')
243 call assert_equal('theother', @/)
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200244
Bram Moolenaardda933d2016-09-03 21:04:58 +0200245 " Test 2: keep the view,
246 " after deleting a character from the search cmd
247 call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar'])
248 resize 5
249 1
250 call feedkeys("/foo\<bs>\<cr>", 'tx')
251 redraw
252 call assert_equal({'lnum': 10, 'leftcol': 0, 'col': 4, 'topfill': 0, 'topline': 6, 'coladd': 0, 'skipcol': 0, 'curswant': 4}, winsaveview())
253
254 " remove all history entries
Bram Moolenaar69a5b862019-07-16 21:38:51 +0200255 for i in range(11)
Bram Moolenaardda933d2016-09-03 21:04:58 +0200256 call histdel('/')
257 endfor
258
259 " Test 3: reset the view,
260 " after deleting all characters from the search cmd
261 norm! 1gg0
262 " unfortunately, neither "/foo\<c-w>\<cr>", nor "/foo\<bs>\<bs>\<bs>\<cr>",
263 " nor "/foo\<c-u>\<cr>" works to delete the commandline.
264 " In that case Vim should return "E35 no previous regular expression",
265 " but it looks like Vim still sees /foo and therefore the test fails.
Bram Moolenaar1bc353b2019-09-01 14:45:28 +0200266 " Therefore, disabling this test
Bram Moolenaare2e40752020-09-04 21:18:46 +0200267 "call assert_fails(feedkeys("/foo\<c-w>\<cr>", 'tx'), 'E35:')
Bram Moolenaardda933d2016-09-03 21:04:58 +0200268 "call assert_equal({'lnum': 1, 'leftcol': 0, 'col': 0, 'topfill': 0, 'topline': 1, 'coladd': 0, 'skipcol': 0, 'curswant': 0}, winsaveview())
269
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200270 " clean up
Bram Moolenaardda933d2016-09-03 21:04:58 +0200271 set noincsearch
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100272 call test_override("char_avail", 0)
Bram Moolenaar4d6f32c2016-08-26 19:13:46 +0200273 bw!
274endfunc
Bram Moolenaarea683da2016-09-09 21:41:34 +0200275
276func Test_use_sub_pat()
277 split
278 let @/ = ''
279 func X()
280 s/^/a/
281 /
282 endfunc
283 call X()
284 bwipe!
285endfunc
Bram Moolenaar6e450a52017-01-06 20:03:58 +0100286
287func Test_searchpair()
288 new
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100289 call setline(1, ['other code', 'here [', ' [', ' " cursor here', ' ]]'])
290
Bram Moolenaarbade44e2020-09-26 22:39:24 +0200291 " should not give an error for using "42"
292 call assert_equal(0, searchpair('a', 'b', 'c', '', 42))
293
Bram Moolenaar6e450a52017-01-06 20:03:58 +0100294 4
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100295 call assert_equal(3, searchpair('\[', '', ']', 'bW'))
296 call assert_equal([0, 3, 2, 0], getpos('.'))
297 4
298 call assert_equal(2, searchpair('\[', '', ']', 'bWr'))
299 call assert_equal([0, 2, 6, 0], getpos('.'))
300 4
301 call assert_equal(1, searchpair('\[', '', ']', 'bWm'))
302 call assert_equal([0, 3, 2, 0], getpos('.'))
303 4|norm ^
304 call assert_equal(5, searchpair('\[', '', ']', 'Wn'))
305 call assert_equal([0, 4, 2, 0], getpos('.'))
306 4
307 call assert_equal(2, searchpair('\[', '', ']', 'bW',
308 \ 'getline(".") =~ "^\\s*\["'))
309 call assert_equal([0, 2, 6, 0], getpos('.'))
Bram Moolenaar6e450a52017-01-06 20:03:58 +0100310 set nomagic
311 4
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100312 call assert_equal(3, searchpair('\[', '', ']', 'bW'))
313 call assert_equal([0, 3, 2, 0], getpos('.'))
Bram Moolenaar6e450a52017-01-06 20:03:58 +0100314 set magic
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100315 4|norm ^
316 call assert_equal(0, searchpair('{', '', '}', 'bW'))
317 call assert_equal([0, 4, 2, 0], getpos('.'))
318
319 %d
320 call setline(1, ['if 1', ' if 2', ' else', ' endif 2', 'endif 1'])
321
322 /\<if 1
323 call assert_equal(5, searchpair('\<if\>', '\<else\>', '\<endif\>', 'W'))
324 call assert_equal([0, 5, 1, 0], getpos('.'))
325 /\<if 2
326 call assert_equal(3, searchpair('\<if\>', '\<else\>', '\<endif\>', 'W'))
327 call assert_equal([0, 3, 3, 0], getpos('.'))
328
Bram Moolenaar5ea38d12022-06-16 21:20:48 +0100329 bwipe!
330endfunc
331
332func Test_searchpair_timeout()
333 CheckFeature reltime
Bram Moolenaar73171ba2022-06-20 12:39:39 +0100334 let g:test_is_flaky = 1
Bram Moolenaar5ea38d12022-06-16 21:20:48 +0100335
336 func Waitabit()
337 sleep 20m
338 return 1 " skip match
339 endfunc
340
341 new
342 call setline(1, range(100))
343 call setline(1, "(start here")
344 call setline(100, "end here)")
345 let starttime = reltime()
346
347 " A timeout of 100 msec should happen after about five times of 20 msec wait
348 " in Waitabit(). When the timeout applies to each search the elapsed time
349 " will be much longer.
350 call assert_equal(0, searchpair('(', '\d', ')', '', "Waitabit()", 0, 100))
351 let elapsed = reltime(starttime)->reltimefloat()
352 call assert_inrange(0.09, 0.300, elapsed)
353
Bram Moolenaar12a49402022-06-21 22:35:40 +0100354 delfunc Waitabit
Bram Moolenaar5ea38d12022-06-16 21:20:48 +0100355 bwipe!
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100356endfunc
357
Bram Moolenaare5303952022-06-19 17:05:47 +0100358func SearchpairSkip()
359 let id = synID(line('.'), col('.'), 0)
360 let attr = synIDattr(id, 'name')
361 return attr !~ 'comment'
362endfunc
363
364func Test_searchpair_timeout_with_skip()
365 let g:test_is_flaky = 1
366
367 edit ../evalfunc.c
368 if has('win32')
369 " Windows timeouts are rather coarse grained, about 16ms.
370 let ms = 20
371 let min_time = 0.016
372 let max_time = min_time * 10.0
373 else
374 let ms = 1
375 let min_time = 0.001
James McCoydbe6ef12022-12-31 11:44:57 +0000376 let max_time = min_time * 15.0
Bram Moolenaare366ed42022-06-19 20:13:56 +0100377 if RunningWithValgrind()
Bram Moolenaare5303952022-06-19 17:05:47 +0100378 let max_time += 0.04 " this can be slow with valgrind
379 endif
Bram Moolenaare9b74c02022-06-24 20:11:59 +0100380 if has('bsd')
381 " test often fails with FreeBSD
382 let max_time = max_time * 2.0
383 endif
Bram Moolenaare5303952022-06-19 17:05:47 +0100384 endif
385 let start = reltime()
386 let found = searchpair('(', '', ')', 'crnm', 'SearchpairSkip()', 0, ms)
387 let elapsed = reltimefloat(reltime(start))
388 call assert_inrange(min_time, max_time, elapsed)
389
390 bwipe!
391endfunc
392
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100393func Test_searchpairpos()
394 new
395 call setline(1, ['other code', 'here [', ' [', ' " cursor here', ' ]]'])
396
397 4
398 call assert_equal([3, 2], searchpairpos('\[', '', ']', 'bW'))
399 call assert_equal([0, 3, 2, 0], getpos('.'))
400 4
401 call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bWr'))
402 call assert_equal([0, 2, 6, 0], getpos('.'))
403 4|norm ^
404 call assert_equal([5, 2], searchpairpos('\[', '', ']', 'Wn'))
405 call assert_equal([0, 4, 2, 0], getpos('.'))
406 4
407 call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bW',
408 \ 'getline(".") =~ "^\\s*\["'))
409 call assert_equal([0, 2, 6, 0], getpos('.'))
410 4
411 call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bWr'))
412 call assert_equal([0, 2, 6, 0], getpos('.'))
413 set nomagic
414 4
415 call assert_equal([3, 2], searchpairpos('\[', '', ']', 'bW'))
416 call assert_equal([0, 3, 2, 0], getpos('.'))
417 set magic
418 4|norm ^
419 call assert_equal([0, 0], searchpairpos('{', '', '}', 'bW'))
420 call assert_equal([0, 4, 2, 0], getpos('.'))
421
422 %d
423 call setline(1, ['if 1', ' if 2', ' else', ' endif 2', 'endif 1'])
424 /\<if 1
425 call assert_equal([5, 1], searchpairpos('\<if\>', '\<else\>', '\<endif\>', 'W'))
426 call assert_equal([0, 5, 1, 0], getpos('.'))
427 /\<if 2
428 call assert_equal([3, 3], searchpairpos('\<if\>', '\<else\>', '\<endif\>', 'W'))
429 call assert_equal([0, 3, 3, 0], getpos('.'))
430
Bram Moolenaar6e450a52017-01-06 20:03:58 +0100431 q!
432endfunc
433
Bram Moolenaar3dddb092018-06-24 19:01:59 +0200434func Test_searchpair_errors()
Yegappan Lakshmanan5b739922021-07-10 13:15:41 +0200435 call assert_fails("call searchpair([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: Using a List as a String')
436 call assert_fails("call searchpair('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: Using a Funcref as a String')
437 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 +0200438 call assert_fails("call searchpair('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
Bram Moolenaar3dddb092018-06-24 19:01:59 +0200439 call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
440 call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100441 call assert_fails("call searchpair('start', 'middle', 'end', 'e')", 'E475: Invalid argument: e')
442 call assert_fails("call searchpair('start', 'middle', 'end', 'sn')", 'E475: Invalid argument: sn')
443endfunc
444
445func Test_searchpairpos_errors()
Yegappan Lakshmanan5b739922021-07-10 13:15:41 +0200446 call assert_fails("call searchpairpos([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: Using a List as a String')
447 call assert_fails("call searchpairpos('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: Using a Funcref as a String')
448 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 +0100449 call assert_fails("call searchpairpos('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100450 call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
451 call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')
452 call assert_fails("call searchpairpos('start', 'middle', 'end', 'e')", 'E475: Invalid argument: e')
453 call assert_fails("call searchpairpos('start', 'middle', 'end', 'sn')", 'E475: Invalid argument: sn')
Bram Moolenaar3dddb092018-06-24 19:01:59 +0200454endfunc
455
Bram Moolenaar48570482017-10-30 21:48:41 +0100456func Test_searchpair_skip()
457 func Zero()
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100458 return 0
Bram Moolenaar48570482017-10-30 21:48:41 +0100459 endfunc
460 func Partial(x)
Bram Moolenaar3ba35402019-12-21 22:00:50 +0100461 return a:x
Bram Moolenaar48570482017-10-30 21:48:41 +0100462 endfunc
463 new
464 call setline(1, ['{', 'foo', 'foo', 'foo', '}'])
465 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', ''))
466 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', '0'))
467 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', {-> 0}))
468 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Zero')))
469 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Partial', [0])))
Bram Moolenaar48570482017-10-30 21:48:41 +0100470 bw!
471endfunc
472
Bram Moolenaara43ebe92018-07-14 17:25:01 +0200473func Test_searchpair_leak()
474 new
475 call setline(1, 'if one else another endif')
476
477 " The error in the skip expression caused memory to leak.
478 call assert_fails("call searchpair('\\<if\\>', '\\<else\\>', '\\<endif\\>', '', '\"foo\" 2')", 'E15:')
479
480 bwipe!
481endfunc
482
Bram Moolenaar66727e12017-03-01 22:17:05 +0100483func Test_searchc()
484 " These commands used to cause memory overflow in searchc().
485 new
486 norm ixx
487 exe "norm 0t\u93cf"
488 bw!
489endfunc
Bram Moolenaara693d052017-06-29 22:23:06 +0200490
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200491func Cmdline3_prep()
492 " need to disable char_avail,
493 " so that expansion of commandline works
494 call test_override("char_avail", 1)
495 new
496 call setline(1, [' 1', ' 2 the~e', ' 3 the theother'])
497 set incsearch
498endfunc
499
Bram Moolenaar976b8472018-08-12 15:49:47 +0200500func Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200501 set noincsearch
502 call test_override("char_avail", 0)
503 bw!
504endfunc
505
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200506func Test_search_cmdline3()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100507 CheckOption incsearch
508
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200509 call Cmdline3_prep()
510 1
511 " first match
512 call feedkeys("/the\<c-l>\<cr>", 'tx')
513 call assert_equal(' 2 the~e', getline('.'))
514
Bram Moolenaar976b8472018-08-12 15:49:47 +0200515 call Incsearch_cleanup()
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200516endfunc
517
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200518func Test_search_cmdline3s()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100519 CheckOption incsearch
520
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200521 call Cmdline3_prep()
522 1
523 call feedkeys(":%s/the\<c-l>/xxx\<cr>", 'tx')
524 call assert_equal(' 2 xxxe', getline('.'))
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200525 undo
526 call feedkeys(":%subs/the\<c-l>/xxx\<cr>", 'tx')
527 call assert_equal(' 2 xxxe', getline('.'))
528 undo
529 call feedkeys(":%substitute/the\<c-l>/xxx\<cr>", 'tx')
530 call assert_equal(' 2 xxxe', getline('.'))
Bram Moolenaar167ae422018-08-14 21:32:21 +0200531 undo
532 call feedkeys(":%smagic/the.e/xxx\<cr>", 'tx')
533 call assert_equal(' 2 xxx', getline('.'))
534 undo
Bram Moolenaare2e40752020-09-04 21:18:46 +0200535 call assert_fails(":%snomagic/the.e/xxx\<cr>", 'E486:')
Bram Moolenaar167ae422018-08-14 21:32:21 +0200536 "
537 call feedkeys(":%snomagic/the\\.e/xxx\<cr>", 'tx')
538 call assert_equal(' 2 xxx', getline('.'))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200539
Bram Moolenaar976b8472018-08-12 15:49:47 +0200540 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200541endfunc
542
543func Test_search_cmdline3g()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100544 CheckOption incsearch
545
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200546 call Cmdline3_prep()
547 1
548 call feedkeys(":g/the\<c-l>/d\<cr>", 'tx')
549 call assert_equal(' 3 the theother', getline(2))
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200550 undo
551 call feedkeys(":global/the\<c-l>/d\<cr>", 'tx')
552 call assert_equal(' 3 the theother', getline(2))
Bram Moolenaardef7b1d2018-08-13 22:54:35 +0200553 undo
554 call feedkeys(":g!/the\<c-l>/d\<cr>", 'tx')
555 call assert_equal(1, line('$'))
556 call assert_equal(' 2 the~e', getline(1))
557 undo
558 call feedkeys(":global!/the\<c-l>/d\<cr>", 'tx')
559 call assert_equal(1, line('$'))
560 call assert_equal(' 2 the~e', getline(1))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200561
Bram Moolenaar976b8472018-08-12 15:49:47 +0200562 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200563endfunc
564
565func Test_search_cmdline3v()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100566 CheckOption incsearch
567
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200568 call Cmdline3_prep()
569 1
570 call feedkeys(":v/the\<c-l>/d\<cr>", 'tx')
571 call assert_equal(1, line('$'))
572 call assert_equal(' 2 the~e', getline(1))
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200573 undo
574 call feedkeys(":vglobal/the\<c-l>/d\<cr>", 'tx')
575 call assert_equal(1, line('$'))
576 call assert_equal(' 2 the~e', getline(1))
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200577
Bram Moolenaar976b8472018-08-12 15:49:47 +0200578 call Incsearch_cleanup()
Bram Moolenaarb0acacd2018-08-11 16:40:43 +0200579endfunc
580
Bram Moolenaarda5116d2017-07-01 23:11:17 +0200581func Test_search_cmdline4()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100582 CheckOption incsearch
583
Bram Moolenaarda5116d2017-07-01 23:11:17 +0200584 " need to disable char_avail,
585 " so that expansion of commandline works
586 call test_override("char_avail", 1)
587 new
588 call setline(1, [' 1 the first', ' 2 the second', ' 3 the third'])
589 set incsearch
590 $
591 call feedkeys("?the\<c-g>\<cr>", 'tx')
592 call assert_equal(' 3 the third', getline('.'))
593 $
594 call feedkeys("?the\<c-g>\<c-g>\<cr>", 'tx')
595 call assert_equal(' 1 the first', getline('.'))
596 $
597 call feedkeys("?the\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
598 call assert_equal(' 2 the second', getline('.'))
599 $
600 call feedkeys("?the\<c-t>\<cr>", 'tx')
601 call assert_equal(' 1 the first', getline('.'))
602 $
603 call feedkeys("?the\<c-t>\<c-t>\<cr>", 'tx')
604 call assert_equal(' 3 the third', getline('.'))
605 $
606 call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
607 call assert_equal(' 2 the second', getline('.'))
608 " clean up
609 set noincsearch
610 call test_override("char_avail", 0)
611 bw!
612endfunc
Bram Moolenaardb510072017-09-28 21:52:17 +0200613
Bram Moolenaarf8e8c062017-10-22 14:44:17 +0200614func Test_search_cmdline5()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100615 CheckOption incsearch
616
Bram Moolenaarf8e8c062017-10-22 14:44:17 +0200617 " Do not call test_override("char_avail", 1) so that <C-g> and <C-t> work
618 " regardless char_avail.
619 new
Bram Moolenaar69a5b862019-07-16 21:38:51 +0200620 call setline(1, [' 1 the first', ' 2 the second', ' 3 the third', ''])
Bram Moolenaarf8e8c062017-10-22 14:44:17 +0200621 set incsearch
622 1
623 call feedkeys("/the\<c-g>\<c-g>\<cr>", 'tx')
624 call assert_equal(' 3 the third', getline('.'))
625 $
626 call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
Bram Moolenaar69a5b862019-07-16 21:38:51 +0200627 call assert_equal(' 1 the first', getline('.'))
Bram Moolenaarf8e8c062017-10-22 14:44:17 +0200628 " clean up
629 set noincsearch
630 bw!
631endfunc
632
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100633func Test_search_cmdline6()
634 " Test that consecutive matches
635 " are caught by <c-g>/<c-t>
Bram Moolenaarb68df222020-03-19 15:05:28 +0100636 CheckOption incsearch
637
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100638 " need to disable char_avail,
639 " so that expansion of commandline works
640 call test_override("char_avail", 1)
641 new
642 call setline(1, [' bbvimb', ''])
643 set incsearch
644 " first match
645 norm! gg0
646 call feedkeys("/b\<cr>", 'tx')
647 call assert_equal([0,1,2,0], getpos('.'))
648 " second match
649 norm! gg0
650 call feedkeys("/b\<c-g>\<cr>", 'tx')
651 call assert_equal([0,1,3,0], getpos('.'))
652 " third match
653 norm! gg0
654 call feedkeys("/b\<c-g>\<c-g>\<cr>", 'tx')
655 call assert_equal([0,1,7,0], getpos('.'))
656 " first match again
657 norm! gg0
658 call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
659 call assert_equal([0,1,2,0], getpos('.'))
660 set nowrapscan
661 " last match
662 norm! gg0
663 call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
664 call assert_equal([0,1,7,0], getpos('.'))
665 " clean up
666 set wrapscan&vim
667 set noincsearch
668 call test_override("char_avail", 0)
669 bw!
670endfunc
671
672func Test_search_cmdline7()
Bram Moolenaard66cdcd2020-07-26 13:27:16 +0200673 " Test that pressing <c-g> in an empty command line
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100674 " does not move the cursor
Bram Moolenaarb68df222020-03-19 15:05:28 +0100675 CheckOption incsearch
676
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100677 " need to disable char_avail,
678 " so that expansion of commandline works
679 call test_override("char_avail", 1)
680 new
Bram Moolenaar21f990e2018-08-11 19:20:49 +0200681 let @/ = 'b'
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100682 call setline(1, [' bbvimb', ''])
683 set incsearch
684 " first match
685 norm! gg0
686 " moves to next match of previous search pattern, just like /<cr>
687 call feedkeys("/\<c-g>\<cr>", 'tx')
688 call assert_equal([0,1,2,0], getpos('.'))
689 " moves to next match of previous search pattern, just like /<cr>
690 call feedkeys("/\<cr>", 'tx')
691 call assert_equal([0,1,3,0], getpos('.'))
692 " moves to next match of previous search pattern, just like /<cr>
693 call feedkeys("/\<c-t>\<cr>", 'tx')
694 call assert_equal([0,1,7,0], getpos('.'))
Bram Moolenaard0480092017-11-16 22:20:39 +0100695
696 " using an offset uses the last search pattern
697 call cursor(1, 1)
698 call setline(1, ['1 bbvimb', ' 2 bbvimb'])
699 let @/ = 'b'
700 call feedkeys("//e\<c-g>\<cr>", 'tx')
701 call assert_equal('1 bbvimb', getline('.'))
702 call assert_equal(4, col('.'))
703
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100704 set noincsearch
705 call test_override("char_avail", 0)
706 bw!
707endfunc
708
709func Test_search_cmdline8()
710 " Highlighting is cleared in all windows
711 " since hls applies to all windows
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200712 CheckOption incsearch
713 CheckFeature terminal
714 CheckNotGui
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100715 if has("win32")
716 throw "Skipped: Bug with sending <ESC> to terminal window not fixed yet"
717 endif
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200718
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100719 let h = winheight(0)
720 if h < 3
721 return
722 endif
723 " Prepare buffer text
724 let lines = ['abb vim vim vi', 'vimvivim']
Bram Moolenaar56564962022-10-10 22:39:42 +0100725 call writefile(lines, 'Xsearch.txt', 'D')
Bram Moolenaar13deab82017-11-04 18:48:43 +0100726 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100727
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200728 call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100729
Bram Moolenaar13deab82017-11-04 18:48:43 +0100730 call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
731 call term_sendkeys(buf, ":14vsp\<cr>")
732 call term_sendkeys(buf, "/vim\<cr>")
733 call term_sendkeys(buf, "/b\<esc>")
734 call term_sendkeys(buf, "gg0")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200735 call TermWait(buf, 250)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100736 let screen_line = term_scrape(buf, 1)
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100737 let [a0,a1,a2,a3] = [screen_line[3].attr, screen_line[4].attr,
738 \ screen_line[18].attr, screen_line[19].attr]
739 call assert_notequal(a0, a1)
740 call assert_notequal(a0, a3)
741 call assert_notequal(a1, a2)
742 call assert_equal(a0, a2)
743 call assert_equal(a1, a3)
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100744
Bram Moolenaar56564962022-10-10 22:39:42 +0100745 " clean up
Bram Moolenaarf8f8b2e2017-11-02 19:08:48 +0100746 bwipe!
747endfunc
748
Bram Moolenaardb510072017-09-28 21:52:17 +0200749" Tests for regexp with various magic settings
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200750func Run_search_regexp_magic_opt()
Bram Moolenaardb510072017-09-28 21:52:17 +0200751 put ='1 a aa abb abbccc'
752 exe 'normal! /a*b\{2}c\+/e' . "\<CR>"
753 call assert_equal([0, 2, 17, 0], getpos('.'))
754
755 put ='2 d dd dee deefff'
756 exe 'normal! /\Md\*e\{2}f\+/e' . "\<CR>"
757 call assert_equal([0, 3, 17, 0], getpos('.'))
758
759 set nomagic
760 put ='3 g gg ghh ghhiii'
761 exe 'normal! /g\*h\{2}i\+/e' . "\<CR>"
762 call assert_equal([0, 4, 17, 0], getpos('.'))
763
764 put ='4 j jj jkk jkklll'
765 exe 'normal! /\mj*k\{2}l\+/e' . "\<CR>"
766 call assert_equal([0, 5, 17, 0], getpos('.'))
767
768 put ='5 m mm mnn mnnooo'
769 exe 'normal! /\vm*n{2}o+/e' . "\<CR>"
770 call assert_equal([0, 6, 17, 0], getpos('.'))
771
772 put ='6 x ^aa$ x'
773 exe 'normal! /\V^aa$' . "\<CR>"
774 call assert_equal([0, 7, 5, 0], getpos('.'))
775
776 set magic
777 put ='7 (a)(b) abbaa'
778 exe 'normal! /\v(a)(b)\2\1\1/e' . "\<CR>"
779 call assert_equal([0, 8, 14, 0], getpos('.'))
780
781 put ='8 axx [ab]xx'
782 exe 'normal! /\V[ab]\(\[xy]\)\1' . "\<CR>"
783 call assert_equal([0, 9, 7, 0], getpos('.'))
784
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200785 %d
786endfunc
787
788func Test_search_regexp()
789 enew!
790
791 set regexpengine=1
792 call Run_search_regexp_magic_opt()
793 set regexpengine=2
794 call Run_search_regexp_magic_opt()
795 set regexpengine&
796
Bram Moolenaardb510072017-09-28 21:52:17 +0200797 set undolevels=100
798 put ='9 foobar'
799 put =''
800 exe "normal! a\<C-G>u\<Esc>"
801 normal G
802 exe 'normal! dv?bar?' . "\<CR>"
803 call assert_equal('9 foo', getline('.'))
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200804 call assert_equal([0, 2, 5, 0], getpos('.'))
805 call assert_equal(2, line('$'))
Bram Moolenaardb510072017-09-28 21:52:17 +0200806 normal u
807 call assert_equal('9 foobar', getline('.'))
Bram Moolenaar4d23c522020-04-09 18:42:11 +0200808 call assert_equal([0, 2, 6, 0], getpos('.'))
809 call assert_equal(3, line('$'))
Bram Moolenaardb510072017-09-28 21:52:17 +0200810
811 set undolevels&
812 enew!
813endfunc
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100814
815func Test_search_cmdline_incsearch_highlight()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100816 CheckOption incsearch
817
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100818 set incsearch hlsearch
819 " need to disable char_avail,
820 " so that expansion of commandline works
821 call test_override("char_avail", 1)
822 new
823 call setline(1, ['aaa 1 the first', ' 2 the second', ' 3 the third'])
824
825 1
826 call feedkeys("/second\<cr>", 'tx')
827 call assert_equal('second', @/)
828 call assert_equal(' 2 the second', getline('.'))
829
830 " Canceling search won't change @/
831 1
832 let @/ = 'last pattern'
833 call feedkeys("/third\<C-c>", 'tx')
834 call assert_equal('last pattern', @/)
835 call feedkeys("/third\<Esc>", 'tx')
836 call assert_equal('last pattern', @/)
837 call feedkeys("/3\<bs>\<bs>", 'tx')
838 call assert_equal('last pattern', @/)
839 call feedkeys("/third\<c-g>\<c-t>\<Esc>", 'tx')
840 call assert_equal('last pattern', @/)
841
842 " clean up
843 set noincsearch nohlsearch
zeertzjq29b29c62025-07-03 20:02:02 +0200844 call test_override("char_avail", 0)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100845 bw!
846endfunc
847
848func Test_search_cmdline_incsearch_highlight_attr()
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200849 CheckOption incsearch
850 CheckFeature terminal
851 CheckNotGui
852
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100853 let h = winheight(0)
854 if h < 3
855 return
856 endif
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100857
858 " Prepare buffer text
Bram Moolenaar13deab82017-11-04 18:48:43 +0100859 let lines = ['abb vim vim vi', 'vimvivim']
Bram Moolenaar56564962022-10-10 22:39:42 +0100860 call writefile(lines, 'Xsearch.txt', 'D')
Bram Moolenaar13deab82017-11-04 18:48:43 +0100861 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
862
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200863 call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
Bram Moolenaarb50773c2018-01-30 22:31:19 +0100864 " wait for vim to complete initialization
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200865 call TermWait(buf)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100866
867 " Get attr of normal(a0), incsearch(a1), hlsearch(a2) highlight
Bram Moolenaar13deab82017-11-04 18:48:43 +0100868 call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
869 call term_sendkeys(buf, '/b')
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200870 call TermWait(buf, 100)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100871 let screen_line1 = term_scrape(buf, 1)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100872 call assert_true(len(screen_line1) > 2)
873 " a0: attr_normal
874 let a0 = screen_line1[0].attr
875 " a1: attr_incsearch
876 let a1 = screen_line1[1].attr
877 " a2: attr_hlsearch
878 let a2 = screen_line1[2].attr
879 call assert_notequal(a0, a1)
880 call assert_notequal(a0, a2)
881 call assert_notequal(a1, a2)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100882 call term_sendkeys(buf, "\<cr>gg0")
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100883
884 " Test incremental highlight search
Bram Moolenaar13deab82017-11-04 18:48:43 +0100885 call term_sendkeys(buf, "/vim")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200886 call TermWait(buf, 100)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100887 " Buffer:
888 " abb vim vim vi
889 " vimvivim
890 " Search: /vim
891 let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a2,a2,a2,a0,a0,a0]
892 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100893 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
894 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100895
896 " Test <C-g>
Bram Moolenaar13deab82017-11-04 18:48:43 +0100897 call term_sendkeys(buf, "\<C-g>\<C-g>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200898 call TermWait(buf, 100)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100899 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
900 let attr_line2 = [a1,a1,a1,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100901 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
902 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100903
904 " Test <C-t>
Bram Moolenaar13deab82017-11-04 18:48:43 +0100905 call term_sendkeys(buf, "\<C-t>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200906 call TermWait(buf, 100)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100907 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a1,a1,a1,a0,a0,a0]
908 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100909 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
910 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100911
912 " Type Enter and a1(incsearch highlight) should become a2(hlsearch highlight)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100913 call term_sendkeys(buf, "\<cr>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200914 call TermWait(buf, 100)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100915 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
916 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100917 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
918 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100919
920 " Test nohlsearch. a2(hlsearch highlight) should become a0(normal highlight)
Bram Moolenaar13deab82017-11-04 18:48:43 +0100921 call term_sendkeys(buf, ":1\<cr>")
922 call term_sendkeys(buf, ":set nohlsearch\<cr>")
923 call term_sendkeys(buf, "/vim")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200924 call TermWait(buf, 100)
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100925 let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a0,a0,a0,a0,a0,a0]
926 let attr_line2 = [a0,a0,a0,a0,a0,a0,a0,a0]
Bram Moolenaar13deab82017-11-04 18:48:43 +0100927 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
928 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
Bram Moolenaar2e51d9a2017-10-29 16:40:30 +0100929
930 bwipe!
931endfunc
Bram Moolenaarf45938c2017-11-02 15:59:57 +0100932
Bram Moolenaar548e5982018-12-26 21:45:00 +0100933func Test_incsearch_cmdline_modifier()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100934 CheckOption incsearch
935
Bram Moolenaar548e5982018-12-26 21:45:00 +0100936 call test_override("char_avail", 1)
937 new
938 call setline(1, ['foo'])
939 set incsearch
940 " Test that error E14 does not occur in parsing command modifier.
941 call feedkeys("V:tab", 'tx')
942
943 call Incsearch_cleanup()
944endfunc
945
Bram Moolenaar9d34d902018-04-27 22:18:12 +0200946func Test_incsearch_scrolling()
Drew Vogelea67ba72025-05-07 22:05:17 +0200947 CheckScreendump
Bram Moolenaar494e9062020-05-31 21:28:02 +0200948 CheckRunVimInTerminal
Bram Moolenaar9d34d902018-04-27 22:18:12 +0200949 call assert_equal(0, &scrolloff)
950 call writefile([
951 \ 'let dots = repeat(".", 120)',
952 \ 'set incsearch cmdheight=2 scrolloff=0',
953 \ 'call setline(1, [dots, dots, dots, "", "target", dots, dots])',
954 \ 'normal gg',
955 \ 'redraw',
Bram Moolenaar56564962022-10-10 22:39:42 +0100956 \ ], 'Xscript', 'D')
Bram Moolenaar9d34d902018-04-27 22:18:12 +0200957 let buf = RunVimInTerminal('-S Xscript', {'rows': 9, 'cols': 70})
958 " Need to send one key at a time to force a redraw
959 call term_sendkeys(buf, '/')
960 sleep 100m
961 call term_sendkeys(buf, 't')
962 sleep 100m
963 call term_sendkeys(buf, 'a')
964 sleep 100m
965 call term_sendkeys(buf, 'r')
966 sleep 100m
967 call term_sendkeys(buf, 'g')
968 call VerifyScreenDump(buf, 'Test_incsearch_scrolling_01', {})
969
970 call term_sendkeys(buf, "\<Esc>")
971 call StopVimInTerminal(buf)
Bram Moolenaar9d34d902018-04-27 22:18:12 +0200972endfunc
973
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200974func Test_incsearch_search_dump()
Bram Moolenaarb68df222020-03-19 15:05:28 +0100975 CheckOption incsearch
976 CheckScreendump
977
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200978 call writefile([
979 \ 'set incsearch hlsearch scrolloff=0',
980 \ 'for n in range(1, 8)',
981 \ ' call setline(n, "foo " . n)',
982 \ 'endfor',
983 \ '3',
Bram Moolenaar56564962022-10-10 22:39:42 +0100984 \ ], 'Xis_search_script', 'D')
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200985 let buf = RunVimInTerminal('-S Xis_search_script', {'rows': 9, 'cols': 70})
986 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
987 " the 'ambiwidth' check.
988 sleep 100m
989
990 " Need to send one key at a time to force a redraw.
991 call term_sendkeys(buf, '/fo')
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200992 call VerifyScreenDump(buf, 'Test_incsearch_search_01', {})
993 call term_sendkeys(buf, "\<Esc>")
994 sleep 100m
995
996 call term_sendkeys(buf, '/\v')
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +0200997 call VerifyScreenDump(buf, 'Test_incsearch_search_02', {})
998 call term_sendkeys(buf, "\<Esc>")
999
1000 call StopVimInTerminal(buf)
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +02001001endfunc
1002
Bram Moolenaar41f08952021-02-22 22:13:49 +01001003func Test_hlsearch_dump()
1004 CheckOption hlsearch
1005 CheckScreendump
1006
1007 call writefile([
1008 \ 'set hlsearch cursorline',
1009 \ 'call setline(1, ["xxx", "xxx", "xxx"])',
1010 \ '/.*',
1011 \ '2',
Bram Moolenaar56564962022-10-10 22:39:42 +01001012 \ ], 'Xhlsearch_script', 'D')
Bram Moolenaar41f08952021-02-22 22:13:49 +01001013 let buf = RunVimInTerminal('-S Xhlsearch_script', {'rows': 6, 'cols': 50})
1014 call VerifyScreenDump(buf, 'Test_hlsearch_1', {})
1015
1016 call term_sendkeys(buf, "/\\_.*\<CR>")
1017 call VerifyScreenDump(buf, 'Test_hlsearch_2', {})
1018
1019 call StopVimInTerminal(buf)
Bram Moolenaar41f08952021-02-22 22:13:49 +01001020endfunc
1021
Bram Moolenaar2d5f3852021-04-21 15:11:42 +02001022func Test_hlsearch_and_visual()
1023 CheckOption hlsearch
1024 CheckScreendump
1025
1026 call writefile([
1027 \ 'set hlsearch',
1028 \ 'call setline(1, repeat(["xxx yyy zzz"], 3))',
1029 \ 'hi Search cterm=bold',
1030 \ '/yyy',
1031 \ 'call cursor(1, 6)',
Bram Moolenaar56564962022-10-10 22:39:42 +01001032 \ ], 'Xhlvisual_script', 'D')
Bram Moolenaar2d5f3852021-04-21 15:11:42 +02001033 let buf = RunVimInTerminal('-S Xhlvisual_script', {'rows': 6, 'cols': 40})
1034 call term_sendkeys(buf, "vjj")
1035 call VerifyScreenDump(buf, 'Test_hlsearch_visual_1', {})
1036 call term_sendkeys(buf, "\<Esc>")
1037
1038 call StopVimInTerminal(buf)
Bram Moolenaar2d5f3852021-04-21 15:11:42 +02001039endfunc
1040
Bram Moolenaare71c0eb2021-05-30 16:43:11 +02001041func Test_hlsearch_block_visual_match()
1042 CheckScreendump
1043
1044 let lines =<< trim END
1045 set hlsearch
1046 call setline(1, ['aa', 'bbbb', 'cccccc'])
1047 END
Bram Moolenaar56564962022-10-10 22:39:42 +01001048 call writefile(lines, 'Xhlsearch_block', 'D')
Bram Moolenaare71c0eb2021-05-30 16:43:11 +02001049 let buf = RunVimInTerminal('-S Xhlsearch_block', {'rows': 9, 'cols': 60})
1050
1051 call term_sendkeys(buf, "G\<C-V>$kk\<Esc>")
1052 sleep 100m
1053 call term_sendkeys(buf, "/\\%V\<CR>")
1054 sleep 100m
1055 call VerifyScreenDump(buf, 'Test_hlsearch_block_visual_match', {})
1056
1057 call StopVimInTerminal(buf)
Bram Moolenaare71c0eb2021-05-30 16:43:11 +02001058endfunc
1059
Bram Moolenaar976b8472018-08-12 15:49:47 +02001060func Test_incsearch_substitute()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001061 CheckOption incsearch
1062
Bram Moolenaar976b8472018-08-12 15:49:47 +02001063 call test_override("char_avail", 1)
1064 new
1065 set incsearch
1066 for n in range(1, 10)
1067 call setline(n, 'foo ' . n)
1068 endfor
1069 4
1070 call feedkeys(":.,.+2s/foo\<BS>o\<BS>o/xxx\<cr>", 'tx')
1071 call assert_equal('foo 3', getline(3))
1072 call assert_equal('xxx 4', getline(4))
1073 call assert_equal('xxx 5', getline(5))
1074 call assert_equal('xxx 6', getline(6))
1075 call assert_equal('foo 7', getline(7))
1076
1077 call Incsearch_cleanup()
1078endfunc
1079
Bram Moolenaar795aaa12020-10-02 20:36:01 +02001080func Test_incsearch_substitute_long_line()
1081 new
1082 call test_override("char_avail", 1)
1083 set incsearch
1084
1085 call repeat('x', 100000)->setline(1)
1086 call feedkeys(':s/\%c', 'xt')
1087 redraw
1088 call feedkeys("\<Esc>", 'xt')
1089
1090 call Incsearch_cleanup()
1091 bwipe!
1092endfunc
1093
LemonBoya4399382022-04-09 21:04:08 +01001094func Test_hlsearch_cursearch()
1095 CheckScreendump
1096
1097 let lines =<< trim END
1098 set hlsearch scrolloff=0
Bram Moolenaar9b367502022-04-22 20:07:21 +01001099 call setline(1, ['one', 'foo', 'bar', 'baz', 'foo the foo and foo', 'bar'])
LemonBoya4399382022-04-09 21:04:08 +01001100 hi Search ctermbg=yellow
1101 hi CurSearch ctermbg=blue
1102 END
Bram Moolenaar56564962022-10-10 22:39:42 +01001103 call writefile(lines, 'Xhlsearch_cursearch', 'D')
LemonBoya4399382022-04-09 21:04:08 +01001104 let buf = RunVimInTerminal('-S Xhlsearch_cursearch', {'rows': 9, 'cols': 60})
1105
1106 call term_sendkeys(buf, "gg/foo\<CR>")
1107 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_1', {})
1108
1109 call term_sendkeys(buf, "n")
1110 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2', {})
1111
Bram Moolenaar9b367502022-04-22 20:07:21 +01001112 call term_sendkeys(buf, "n")
1113 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2a', {})
1114
1115 call term_sendkeys(buf, "n")
1116 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2b', {})
1117
1118 call term_sendkeys(buf, ":call setline(5, 'foo')\<CR>")
1119 call term_sendkeys(buf, "0?\<CR>")
LemonBoya4399382022-04-09 21:04:08 +01001120 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_3', {})
1121
1122 call term_sendkeys(buf, "gg/foo\\nbar\<CR>")
Bram Moolenaar693ccd12022-04-16 12:04:37 +01001123 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_1', {})
1124
1125 call term_sendkeys(buf, ":call setline(1, ['---', 'abcdefg', 'hijkl', '---', 'abcdefg', 'hijkl'])\<CR>")
1126 call term_sendkeys(buf, "gg/efg\\nhij\<CR>")
1127 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_2', {})
1128 call term_sendkeys(buf, "h\<C-L>")
1129 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_3', {})
1130 call term_sendkeys(buf, "j\<C-L>")
1131 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_4', {})
1132 call term_sendkeys(buf, "h\<C-L>")
1133 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_5', {})
LemonBoya4399382022-04-09 21:04:08 +01001134
Bram Moolenaar368137a2022-05-31 13:43:12 +01001135 " check clearing CurSearch when using it for another match
1136 call term_sendkeys(buf, "G?^abcd\<CR>Y")
1137 call term_sendkeys(buf, "kkP")
1138 call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_changed_1', {})
1139
LemonBoya4399382022-04-09 21:04:08 +01001140 call StopVimInTerminal(buf)
LemonBoya4399382022-04-09 21:04:08 +01001141endfunc
1142
Bram Moolenaar164251f2018-08-12 16:26:58 +02001143" Similar to Test_incsearch_substitute() but with a screendump halfway.
1144func Test_incsearch_substitute_dump()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001145 CheckOption incsearch
1146 CheckScreendump
1147
Bram Moolenaar164251f2018-08-12 16:26:58 +02001148 call writefile([
1149 \ 'set incsearch hlsearch scrolloff=0',
1150 \ 'for n in range(1, 10)',
1151 \ ' call setline(n, "foo " . n)',
1152 \ 'endfor',
Bram Moolenaar2f6a3462018-08-14 18:16:52 +02001153 \ 'call setline(11, "bar 11")',
Bram Moolenaar164251f2018-08-12 16:26:58 +02001154 \ '3',
Bram Moolenaar56564962022-10-10 22:39:42 +01001155 \ ], 'Xis_subst_script', 'D')
Bram Moolenaar164251f2018-08-12 16:26:58 +02001156 let buf = RunVimInTerminal('-S Xis_subst_script', {'rows': 9, 'cols': 70})
1157 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1158 " the 'ambiwidth' check.
1159 sleep 100m
1160
1161 " Need to send one key at a time to force a redraw.
Bram Moolenaarc7f08b72018-08-12 17:39:14 +02001162 " Select three lines at the cursor with typed pattern.
Bram Moolenaar164251f2018-08-12 16:26:58 +02001163 call term_sendkeys(buf, ':.,.+2s/')
1164 sleep 100m
1165 call term_sendkeys(buf, 'f')
1166 sleep 100m
1167 call term_sendkeys(buf, 'o')
1168 sleep 100m
1169 call term_sendkeys(buf, 'o')
1170 call VerifyScreenDump(buf, 'Test_incsearch_substitute_01', {})
Bram Moolenaarc7f08b72018-08-12 17:39:14 +02001171 call term_sendkeys(buf, "\<Esc>")
1172
1173 " Select three lines at the cursor using previous pattern.
1174 call term_sendkeys(buf, "/foo\<CR>")
1175 sleep 100m
1176 call term_sendkeys(buf, ':.,.+2s//')
Bram Moolenaarc7f08b72018-08-12 17:39:14 +02001177 call VerifyScreenDump(buf, 'Test_incsearch_substitute_02', {})
1178
1179 " Deleting last slash should remove the match.
1180 call term_sendkeys(buf, "\<BS>")
Bram Moolenaarc7f08b72018-08-12 17:39:14 +02001181 call VerifyScreenDump(buf, 'Test_incsearch_substitute_03', {})
Bram Moolenaar60d08712018-08-12 21:53:15 +02001182 call term_sendkeys(buf, "\<Esc>")
1183
1184 " Reverse range is accepted
1185 call term_sendkeys(buf, ':5,2s/foo')
Bram Moolenaar60d08712018-08-12 21:53:15 +02001186 call VerifyScreenDump(buf, 'Test_incsearch_substitute_04', {})
Bram Moolenaar164251f2018-08-12 16:26:58 +02001187 call term_sendkeys(buf, "\<Esc>")
Bram Moolenaar2b926fc2018-08-13 11:07:57 +02001188
1189 " White space after the command is skipped
1190 call term_sendkeys(buf, ':2,3sub /fo')
Bram Moolenaar2b926fc2018-08-13 11:07:57 +02001191 call VerifyScreenDump(buf, 'Test_incsearch_substitute_05', {})
1192 call term_sendkeys(buf, "\<Esc>")
1193
Bram Moolenaar33c4dbb2018-08-14 16:06:16 +02001194 " Command modifiers are skipped
1195 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 +02001196 call VerifyScreenDump(buf, 'Test_incsearch_substitute_06', {})
1197 call term_sendkeys(buf, "\<Esc>")
1198
Bram Moolenaar2f6a3462018-08-14 18:16:52 +02001199 " Cursorline highlighting at match
1200 call term_sendkeys(buf, ":set cursorline\<CR>")
1201 call term_sendkeys(buf, 'G9G')
1202 call term_sendkeys(buf, ':9,11s/bar')
Bram Moolenaar2f6a3462018-08-14 18:16:52 +02001203 call VerifyScreenDump(buf, 'Test_incsearch_substitute_07', {})
1204 call term_sendkeys(buf, "\<Esc>")
1205
1206 " Cursorline highlighting at cursor when no match
1207 call term_sendkeys(buf, ':9,10s/bar')
Bram Moolenaar2f6a3462018-08-14 18:16:52 +02001208 call VerifyScreenDump(buf, 'Test_incsearch_substitute_08', {})
1209 call term_sendkeys(buf, "\<Esc>")
1210
Bram Moolenaar8b0d5ce2018-08-22 23:05:44 +02001211 " Only \v handled as empty pattern, does not move cursor
1212 call term_sendkeys(buf, '3G4G')
1213 call term_sendkeys(buf, ":nohlsearch\<CR>")
1214 call term_sendkeys(buf, ':6,7s/\v')
Bram Moolenaar8b0d5ce2018-08-22 23:05:44 +02001215 call VerifyScreenDump(buf, 'Test_incsearch_substitute_09', {})
1216 call term_sendkeys(buf, "\<Esc>")
1217
Bram Moolenaarf13daa42018-08-31 22:09:54 +02001218 call term_sendkeys(buf, ":set nocursorline\<CR>")
1219
1220 " All matches are highlighted for 'hlsearch' after the incsearch canceled
1221 call term_sendkeys(buf, "1G*")
1222 call term_sendkeys(buf, ":2,5s/foo")
1223 sleep 100m
1224 call term_sendkeys(buf, "\<Esc>")
1225 call VerifyScreenDump(buf, 'Test_incsearch_substitute_10', {})
1226
Bram Moolenaar65985ac2018-09-16 17:08:04 +02001227 call term_sendkeys(buf, ":split\<CR>")
1228 call term_sendkeys(buf, ":let @/ = 'xyz'\<CR>")
1229 call term_sendkeys(buf, ":%s/.")
1230 call VerifyScreenDump(buf, 'Test_incsearch_substitute_11', {})
1231 call term_sendkeys(buf, "\<BS>")
1232 call VerifyScreenDump(buf, 'Test_incsearch_substitute_12', {})
1233 call term_sendkeys(buf, "\<Esc>")
1234 call VerifyScreenDump(buf, 'Test_incsearch_substitute_13', {})
Bram Moolenaarc6725252019-11-23 21:56:46 +01001235 call term_sendkeys(buf, ":%bwipe!\<CR>")
1236 call term_sendkeys(buf, ":only!\<CR>")
1237
1238 " get :'<,'>s command in history
1239 call term_sendkeys(buf, ":set cmdheight=2\<CR>")
1240 call term_sendkeys(buf, "aasdfasdf\<Esc>")
1241 call term_sendkeys(buf, "V:s/a/b/g\<CR>")
1242 " Using '<,'> does not give E20
1243 call term_sendkeys(buf, ":new\<CR>")
1244 call term_sendkeys(buf, "aasdfasdf\<Esc>")
1245 call term_sendkeys(buf, ":\<Up>\<Up>")
1246 call VerifyScreenDump(buf, 'Test_incsearch_substitute_14', {})
1247 call term_sendkeys(buf, "<Esc>")
Bram Moolenaar65985ac2018-09-16 17:08:04 +02001248
Bram Moolenaar164251f2018-08-12 16:26:58 +02001249 call StopVimInTerminal(buf)
Bram Moolenaar164251f2018-08-12 16:26:58 +02001250endfunc
1251
Bram Moolenaarc036e872020-02-21 21:30:52 +01001252func Test_incsearch_highlighting()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001253 CheckOption incsearch
1254 CheckScreendump
Bram Moolenaarc036e872020-02-21 21:30:52 +01001255
1256 call writefile([
1257 \ 'set incsearch hlsearch',
1258 \ 'call setline(1, "hello/there")',
Bram Moolenaar56564962022-10-10 22:39:42 +01001259 \ ], 'Xis_subst_hl_script', 'D')
Bram Moolenaarc036e872020-02-21 21:30:52 +01001260 let buf = RunVimInTerminal('-S Xis_subst_hl_script', {'rows': 4, 'cols': 20})
1261 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1262 " the 'ambiwidth' check.
1263 sleep 300m
1264
1265 " Using a different search delimiter should still highlight matches
1266 " that contain a '/'.
1267 call term_sendkeys(buf, ":%s;ello/the")
1268 call VerifyScreenDump(buf, 'Test_incsearch_substitute_15', {})
1269 call term_sendkeys(buf, "<Esc>")
Bram Moolenaarb68df222020-03-19 15:05:28 +01001270
1271 call StopVimInTerminal(buf)
Bram Moolenaarc036e872020-02-21 21:30:52 +01001272endfunc
1273
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +01001274func Test_incsearch_with_change()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001275 CheckFeature timers
1276 CheckOption incsearch
1277 CheckScreendump
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +01001278
1279 call writefile([
1280 \ 'set incsearch hlsearch scrolloff=0',
1281 \ 'call setline(1, ["one", "two ------ X", "three"])',
1282 \ 'call timer_start(200, { _ -> setline(2, "x")})',
Bram Moolenaar56564962022-10-10 22:39:42 +01001283 \ ], 'Xis_change_script', 'D')
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +01001284 let buf = RunVimInTerminal('-S Xis_change_script', {'rows': 9, 'cols': 70})
1285 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1286 " the 'ambiwidth' check.
Bram Moolenaare86ecbd2019-02-21 17:48:59 +01001287 sleep 300m
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +01001288
1289 " Highlight X, it will be deleted by the timer callback.
1290 call term_sendkeys(buf, ':%s/X')
1291 call VerifyScreenDump(buf, 'Test_incsearch_change_01', {})
1292 call term_sendkeys(buf, "\<Esc>")
1293
1294 call StopVimInTerminal(buf)
Bram Moolenaar4a7d2d32019-02-21 16:25:50 +01001295endfunc
1296
Bram Moolenaar81f56532018-08-18 16:19:42 +02001297" Similar to Test_incsearch_substitute_dump() for :sort
Bram Moolenaar4edfe2d2018-08-23 20:55:45 +02001298func Test_incsearch_sort_dump()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001299 CheckOption incsearch
1300 CheckScreendump
1301
Bram Moolenaar81f56532018-08-18 16:19:42 +02001302 call writefile([
1303 \ 'set incsearch hlsearch scrolloff=0',
1304 \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
Bram Moolenaar56564962022-10-10 22:39:42 +01001305 \ ], 'Xis_sort_script', 'D')
Bram Moolenaar81f56532018-08-18 16:19:42 +02001306 let buf = RunVimInTerminal('-S Xis_sort_script', {'rows': 9, 'cols': 70})
1307 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1308 " the 'ambiwidth' check.
1309 sleep 100m
1310
Bram Moolenaar81f56532018-08-18 16:19:42 +02001311 call term_sendkeys(buf, ':sort ni u /on')
Bram Moolenaar81f56532018-08-18 16:19:42 +02001312 call VerifyScreenDump(buf, 'Test_incsearch_sort_01', {})
1313 call term_sendkeys(buf, "\<Esc>")
1314
Bram Moolenaar333015a2020-04-25 15:54:16 +02001315 call term_sendkeys(buf, ':sort! /on')
1316 call VerifyScreenDump(buf, 'Test_incsearch_sort_02', {})
1317 call term_sendkeys(buf, "\<Esc>")
1318
Bram Moolenaar81f56532018-08-18 16:19:42 +02001319 call StopVimInTerminal(buf)
Bram Moolenaar81f56532018-08-18 16:19:42 +02001320endfunc
1321
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001322" Similar to Test_incsearch_substitute_dump() for :vimgrep famiry
1323func Test_incsearch_vimgrep_dump()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001324 CheckOption incsearch
1325 CheckScreendump
1326
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001327 call writefile([
1328 \ 'set incsearch hlsearch scrolloff=0',
1329 \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
Bram Moolenaar56564962022-10-10 22:39:42 +01001330 \ ], 'Xis_vimgrep_script', 'D')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001331 let buf = RunVimInTerminal('-S Xis_vimgrep_script', {'rows': 9, 'cols': 70})
1332 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1333 " the 'ambiwidth' check.
1334 sleep 100m
1335
1336 " Need to send one key at a time to force a redraw.
1337 call term_sendkeys(buf, ':vimgrep on')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001338 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_01', {})
1339 call term_sendkeys(buf, "\<Esc>")
1340
1341 call term_sendkeys(buf, ':vimg /on/ *.txt')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001342 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_02', {})
1343 call term_sendkeys(buf, "\<Esc>")
1344
1345 call term_sendkeys(buf, ':vimgrepadd "\<on')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001346 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_03', {})
1347 call term_sendkeys(buf, "\<Esc>")
1348
1349 call term_sendkeys(buf, ':lv "tha')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001350 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_04', {})
1351 call term_sendkeys(buf, "\<Esc>")
1352
1353 call term_sendkeys(buf, ':lvimgrepa "the" **/*.txt')
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001354 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_05', {})
1355 call term_sendkeys(buf, "\<Esc>")
1356
1357 call StopVimInTerminal(buf)
Bram Moolenaar264cf5c2018-08-18 21:05:31 +02001358endfunc
1359
Bram Moolenaar198cb662018-09-06 21:44:17 +02001360func Test_keep_last_search_pattern()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001361 CheckOption incsearch
1362
Bram Moolenaar198cb662018-09-06 21:44:17 +02001363 new
1364 call setline(1, ['foo', 'foo', 'foo'])
1365 set incsearch
1366 call test_override("char_avail", 1)
1367 let @/ = 'bar'
1368 call feedkeys(":/foo/s//\<Esc>", 'ntx')
1369 call assert_equal('bar', @/)
1370
Bram Moolenaar50eb16c2018-09-15 15:42:40 +02001371 " no error message if pattern not found
1372 call feedkeys(":/xyz/s//\<Esc>", 'ntx')
1373 call assert_equal('bar', @/)
1374
Bram Moolenaar198cb662018-09-06 21:44:17 +02001375 bwipe!
1376 call test_override("ALL", 0)
1377 set noincsearch
1378endfunc
1379
Bram Moolenaar99f043a2018-09-09 15:54:14 +02001380func Test_word_under_cursor_after_match()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001381 CheckOption incsearch
1382
Bram Moolenaar99f043a2018-09-09 15:54:14 +02001383 new
1384 call setline(1, 'foo bar')
1385 set incsearch
1386 call test_override("char_avail", 1)
1387 try
1388 call feedkeys("/foo\<C-R>\<C-W>\<CR>", 'ntx')
1389 catch /E486:/
1390 endtry
1391 call assert_equal('foobar', @/)
1392
1393 bwipe!
1394 call test_override("ALL", 0)
1395 set noincsearch
1396endfunc
1397
1398func Test_subst_word_under_cursor()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001399 CheckOption incsearch
1400
Bram Moolenaar99f043a2018-09-09 15:54:14 +02001401 new
1402 call setline(1, ['int SomeLongName;', 'for (xxx = 1; xxx < len; ++xxx)'])
1403 set incsearch
1404 call test_override("char_avail", 1)
1405 call feedkeys("/LongName\<CR>", 'ntx')
1406 call feedkeys(":%s/xxx/\<C-R>\<C-W>/g\<CR>", 'ntx')
1407 call assert_equal('for (SomeLongName = 1; SomeLongName < len; ++SomeLongName)', getline(2))
1408
1409 bwipe!
1410 call test_override("ALL", 0)
1411 set noincsearch
1412endfunc
1413
Bram Moolenaar3d79f0a2023-01-22 20:14:26 +00001414func Test_search_skip_all_matches()
1415 enew
1416 call setline(1, ['no match here',
1417 \ 'match this line',
1418 \ 'nope',
1419 \ 'match in this line',
1420 \ 'last line',
1421 \ ])
1422 call cursor(1, 1)
1423 let lnum = search('this', '', 0, 0, 'getline(".") =~ "this line"')
1424 " Only check that no match is found. Previously it searched forever.
1425 call assert_equal(0, lnum)
1426
1427 bwipe!
1428endfunc
1429
Bram Moolenaarf45938c2017-11-02 15:59:57 +01001430func Test_search_undefined_behaviour()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001431 CheckFeature terminal
1432
Bram Moolenaarf45938c2017-11-02 15:59:57 +01001433 let h = winheight(0)
1434 if h < 3
1435 return
1436 endif
1437 " did cause an undefined left shift
1438 let g:buf = term_start([GetVimProg(), '--clean', '-e', '-s', '-c', 'call search(getline("."))', 'samples/test000'], {'term_rows': 3})
1439 call assert_equal([''], getline(1, '$'))
1440 call term_sendkeys(g:buf, ":qa!\<cr>")
1441 bwipe!
1442endfunc
Bram Moolenaar2973daa2017-11-02 23:15:40 +01001443
1444func Test_search_undefined_behaviour2()
1445 call search("\%UC0000000")
1446endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01001447
1448" Test for search('multi-byte char', 'bce')
1449func Test_search_multibyte()
Bram Moolenaarfb094e12017-11-05 20:59:28 +01001450 let save_enc = &encoding
1451 set encoding=utf8
1452 enew!
1453 call append('$', 'A')
1454 call cursor(2, 1)
1455 call assert_equal(2, search('A', 'bce', line('.')))
1456 enew!
1457 let &encoding = save_enc
1458endfunc
Bram Moolenaar890dd052017-12-16 19:59:37 +01001459
1460" This was causing E874. Also causes an invalid read?
1461func Test_look_behind()
1462 new
Bram Moolenaar3ba35402019-12-21 22:00:50 +01001463 call setline(1, '0\|\&\n\@<=')
Bram Moolenaar890dd052017-12-16 19:59:37 +01001464 call search(getline("."))
1465 bwipe!
1466endfunc
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +01001467
Bram Moolenaar872bee52021-05-24 22:56:15 +02001468func Test_search_visual_area_linewise()
1469 new
1470 call setline(1, ['aa', 'bb', 'cc'])
1471 exe "normal 2GV\<Esc>"
1472 for engine in [1, 2]
1473 exe 'set regexpengine=' .. engine
1474 exe "normal gg/\\%'<\<CR>>"
1475 call assert_equal([0, 2, 1, 0, 1], getcurpos(), 'engine ' .. engine)
1476 exe "normal gg/\\%'>\<CR>"
1477 call assert_equal([0, 2, 2, 0, 2], getcurpos(), 'engine ' .. engine)
1478 endfor
1479
1480 bwipe!
1481 set regexpengine&
1482endfunc
1483
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +01001484func Test_search_sentence()
1485 new
1486 " this used to cause a crash
Bram Moolenaar1bd999f2017-12-19 22:25:40 +01001487 /\%'(
1488 /
Bram Moolenaar872bee52021-05-24 22:56:15 +02001489 bwipe
Bram Moolenaar8ada6aa2017-12-19 21:23:21 +01001490endfunc
Bram Moolenaar2fb8f682018-12-01 13:14:45 +01001491
1492" Test that there is no crash when there is a last search pattern but no last
1493" substitute pattern.
1494func Test_no_last_substitute_pat()
1495 " Use viminfo to set the last search pattern to a string and make the last
1496 " substitute pattern the most recent used and make it empty (NULL).
Bram Moolenaar56564962022-10-10 22:39:42 +01001497 call writefile(['~MSle0/bar', '~MSle0~&'], 'Xviminfo', 'D')
Bram Moolenaar2fb8f682018-12-01 13:14:45 +01001498 rviminfo! Xviminfo
1499 call assert_fails('normal n', 'E35:')
Bram Moolenaar2fb8f682018-12-01 13:14:45 +01001500endfunc
Bram Moolenaar5f5e2032018-12-14 15:47:03 +01001501
1502func Test_search_Ctrl_L_combining()
1503 " Make sure, that Ctrl-L works correctly with combining characters.
1504 " It uses an artificial example of an 'a' with 4 combining chars:
Bram Moolenaar3ba35402019-12-21 22:00:50 +01001505 " 'a' U+0061 Dec:97 LATIN SMALL LETTER A &#x61; /\%u61\Z "\u0061"
Bram Moolenaar5f5e2032018-12-14 15:47:03 +01001506 " ' ̀' U+0300 Dec:768 COMBINING GRAVE ACCENT &#x300; /\%u300\Z "\u0300"
1507 " ' ́' U+0301 Dec:769 COMBINING ACUTE ACCENT &#x301; /\%u301\Z "\u0301"
1508 " ' ̇' U+0307 Dec:775 COMBINING DOT ABOVE &#x307; /\%u307\Z "\u0307"
Bram Moolenaar3ba35402019-12-21 22:00:50 +01001509 " ' ̣' U+0323 Dec:803 COMBINING DOT BELOW &#x323; /\%u323 "\u0323"
Bram Moolenaar5f5e2032018-12-14 15:47:03 +01001510 " Those should also appear on the commandline
Bram Moolenaarb68df222020-03-19 15:05:28 +01001511 CheckOption incsearch
1512
Bram Moolenaar5f5e2032018-12-14 15:47:03 +01001513 call Cmdline3_prep()
1514 1
1515 let bufcontent = ['', 'Miạ̀́̇m']
1516 call append('$', bufcontent)
1517 call feedkeys("/Mi\<c-l>\<c-l>\<cr>", 'tx')
1518 call assert_equal(5, line('.'))
1519 call assert_equal(bufcontent[1], @/)
1520 call Incsearch_cleanup()
1521endfunc
Bram Moolenaar527a2d82019-02-21 22:28:51 +01001522
Bram Moolenaarab350f82019-02-28 06:25:00 +01001523func Test_large_hex_chars1()
Bram Moolenaar527a2d82019-02-21 22:28:51 +01001524 " This used to cause a crash, the character becomes an NFA state.
1525 try
1526 /\%Ufffffc23
1527 catch
1528 call assert_match('E678:', v:exception)
1529 endtry
Bram Moolenaarab350f82019-02-28 06:25:00 +01001530 try
1531 set re=1
1532 /\%Ufffffc23
1533 catch
1534 call assert_match('E678:', v:exception)
1535 endtry
1536 set re&
1537endfunc
1538
1539func Test_large_hex_chars2()
1540 " This used to cause a crash, the character becomes an NFA state.
1541 try
1542 /[\Ufffffc1f]
1543 catch
Christian Brabandtf2b16982025-03-29 09:08:58 +01001544 call assert_match('E1541:', v:exception)
Bram Moolenaarab350f82019-02-28 06:25:00 +01001545 endtry
1546 try
1547 set re=1
1548 /[\Ufffffc1f]
1549 catch
Christian Brabandtf2b16982025-03-29 09:08:58 +01001550 call assert_match('E1541:', v:exception)
Bram Moolenaarab350f82019-02-28 06:25:00 +01001551 endtry
1552 set re&
Bram Moolenaar527a2d82019-02-21 22:28:51 +01001553endfunc
Bram Moolenaarcd625122019-02-22 17:29:43 +01001554
Christian Brabandtf2b16982025-03-29 09:08:58 +01001555func Test_large_hex_chars3()
1556 " Validate max number of Unicode char
1557 try
1558 /[\UFFFFFFFF]
1559 catch
1560 call assert_match('E1541:', v:exception)
1561 endtry
1562 try
1563 /[\UFFFFFFF]
1564 catch
1565 call assert_match('E486:', v:exception)
1566 endtry
1567 try
1568 /\%#=2[\d32-\UFFFFFFFF]
1569 catch
1570 call assert_match('E1541:', v:exception)
1571 endtry
1572 try
1573 /\%#=1[\UFFFFFFFF]
1574 catch
1575 call assert_match('E1541:', v:exception)
1576 endtry
1577 try
1578 /\%#=1[\d32-\UFFFFFFFF]
1579 catch
1580 call assert_match('E945:', v:exception)
1581 endtry
1582endfunc
1583
Bram Moolenaarcd625122019-02-22 17:29:43 +01001584func Test_one_error_msg()
Bram Moolenaar8832a342020-04-11 18:36:38 +02001585 " This was also giving an internal error
Bram Moolenaarcd625122019-02-22 17:29:43 +01001586 call assert_fails('call search(" \\((\\v[[=P=]]){185}+ ")', 'E871:')
1587endfunc
Bram Moolenaar730f48f2019-04-11 13:45:57 +02001588
1589func Test_incsearch_add_char_under_cursor()
Bram Moolenaarb68df222020-03-19 15:05:28 +01001590 CheckOption incsearch
1591
Bram Moolenaar730f48f2019-04-11 13:45:57 +02001592 set incsearch
1593 new
1594 call setline(1, ['find match', 'anything'])
1595 1
1596 call test_override('char_avail', 1)
1597 call feedkeys("fc/m\<C-L>\<C-L>\<C-L>\<C-L>\<C-L>\<CR>", 'tx')
1598 call assert_equal('match', @/)
1599 call test_override('char_avail', 0)
1600
1601 set incsearch&
1602 bwipe!
1603endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001604
1605" Test for the search() function with match at the cursor position
1606func Test_search_match_at_curpos()
1607 new
1608 call append(0, ['foobar', '', 'one two', ''])
1609
1610 normal gg
1611
Bram Moolenaar196b4662019-09-06 21:34:30 +02001612 eval 'foobar'->search('c')
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001613 call assert_equal([1, 1], [line('.'), col('.')])
1614
1615 normal j
1616 call search('^$', 'c')
1617 call assert_equal([2, 1], [line('.'), col('.')])
1618
1619 call search('^$', 'bc')
1620 call assert_equal([2, 1], [line('.'), col('.')])
1621
1622 exe "normal /two\<CR>"
1623 call search('.', 'c')
1624 call assert_equal([3, 5], [line('.'), col('.')])
1625
1626 close!
1627endfunc
Bram Moolenaardb294ad2019-06-06 12:49:29 +02001628
Bram Moolenaar0e05de42020-03-25 22:23:46 +01001629" Test for error cases with the search() function
1630func Test_search_errors()
1631 call assert_fails("call search('pat', [])", 'E730:')
1632 call assert_fails("call search('pat', 'b', {})", 'E728:')
1633 call assert_fails("call search('pat', 'b', 1, [])", 'E745:')
1634 call assert_fails("call search('pat', 'ns')", 'E475:')
1635 call assert_fails("call search('pat', 'mr')", 'E475:')
Bram Moolenaar8832a342020-04-11 18:36:38 +02001636
1637 new
1638 call setline(1, ['foo', 'bar'])
1639 call assert_fails('call feedkeys("/foo/;/bar/;\<CR>", "tx")', 'E386:')
1640 bwipe!
Bram Moolenaar0e05de42020-03-25 22:23:46 +01001641endfunc
1642
Paul Ollis65745772022-06-05 16:55:54 +01001643func Test_search_timeout()
Bram Moolenaar73171ba2022-06-20 12:39:39 +01001644 let g:test_is_flaky = 1
Paul Ollis65745772022-06-05 16:55:54 +01001645 new
Bram Moolenaar616592e2022-06-17 15:17:10 +01001646 " use a complicated pattern that should be slow with the BT engine
Paul Ollis65745772022-06-05 16:55:54 +01001647 let pattern = '\%#=1a*.*X\@<=b*'
Bram Moolenaar616592e2022-06-17 15:17:10 +01001648
1649 " use a timeout of 50 msec
1650 let search_timeout = 0.05
1651
1652 " fill the buffer so that it takes 15 times the timeout to search
Paul Ollis65745772022-06-05 16:55:54 +01001653 let slow_target_timeout = search_timeout * 15.0
1654
Bram Moolenaar616592e2022-06-17 15:17:10 +01001655 " Fill the buffer with more and more text until searching takes more time
1656 " than slow_target_timeout.
Paul Ollis65745772022-06-05 16:55:54 +01001657 for n in range(40, 400, 30)
1658 call setline(1, ['aaa', repeat('abc ', n), 'ccc'])
1659 let start = reltime()
1660 call search(pattern, '', 0)
1661 let elapsed = reltimefloat(reltime(start))
1662 if elapsed > slow_target_timeout
1663 break
1664 endif
1665 endfor
1666 call assert_true(elapsed > slow_target_timeout)
1667
Bram Moolenaar616592e2022-06-17 15:17:10 +01001668 " Check that the timeout kicks in, the time should be less than half of what
1669 " we measured without the timeout. This is permissive, because the timer is
1670 " known to overrun, especially when using valgrind.
Paul Ollis65745772022-06-05 16:55:54 +01001671 let max_time = elapsed / 2.0
1672 let start = reltime()
1673 call search(pattern, '', 0, float2nr(search_timeout * 1000))
1674 let elapsed = reltimefloat(reltime(start))
Bram Moolenaar616592e2022-06-17 15:17:10 +01001675 call assert_inrange(search_timeout * 0.9, max_time, elapsed)
Paul Ollis65745772022-06-05 16:55:54 +01001676
1677 bwipe!
1678endfunc
1679
Bram Moolenaardb294ad2019-06-06 12:49:29 +02001680func Test_search_display_pattern()
1681 new
1682 call setline(1, ['foo', 'bar', 'foobar'])
1683
1684 call cursor(1, 1)
1685 let @/ = 'foo'
Bram Moolenaara4208962019-08-24 20:50:19 +02001686 let pat = @/->escape('()*?'. '\s\+')
Bram Moolenaardb294ad2019-06-06 12:49:29 +02001687 let g:a = execute(':unsilent :norm! n')
1688 call assert_match(pat, g:a)
1689
1690 " right-left
1691 if exists("+rightleft")
1692 set rl
1693 call cursor(1, 1)
1694 let @/ = 'foo'
1695 let pat = 'oof/\s\+'
1696 let g:a = execute(':unsilent :norm! n')
1697 call assert_match(pat, g:a)
1698 set norl
1699 endif
1700endfunc
Bram Moolenaar196b4662019-09-06 21:34:30 +02001701
1702func Test_searchdecl()
1703 let lines =<< trim END
1704 int global;
1705
1706 func()
1707 {
1708 int global;
1709 if (cond) {
1710 int local;
1711 }
1712 int local;
1713 // comment
1714 }
1715 END
1716 new
1717 call setline(1, lines)
1718 10
1719 call assert_equal(0, searchdecl('local', 0, 0))
1720 call assert_equal(7, getcurpos()[1])
1721
1722 10
1723 call assert_equal(0, 'local'->searchdecl(0, 1))
1724 call assert_equal(9, getcurpos()[1])
1725
1726 10
1727 call assert_equal(0, searchdecl('global'))
1728 call assert_equal(5, getcurpos()[1])
1729
1730 10
1731 call assert_equal(0, searchdecl('global', 1))
1732 call assert_equal(1, getcurpos()[1])
1733
1734 bwipe!
1735endfunc
Bram Moolenaar98a336d2020-01-20 20:22:30 +01001736
1737func Test_search_special()
Bram Moolenaarfe4bbac2020-01-20 21:12:20 +01001738 " this was causing illegal memory access and an endless loop
1739 set t_PE=
Bram Moolenaar98a336d2020-01-20 20:22:30 +01001740 exe "norm /\x80PS"
1741endfunc
Bram Moolenaar07ada5f2020-02-05 20:38:22 +01001742
1743" Test for command failures when the last search pattern is not set.
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001744" Need to run this in a new vim instance where last search pattern is not set.
Bram Moolenaar07ada5f2020-02-05 20:38:22 +01001745func Test_search_with_no_last_pat()
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001746 let lines =<< trim [SCRIPT]
1747 call assert_fails("normal i\<C-R>/\e", 'E35:')
1748 call assert_fails("exe '/'", 'E35:')
1749 call assert_fails("exe '?'", 'E35:')
1750 call assert_fails("/", 'E35:')
1751 call assert_fails("?", 'E35:')
1752 call assert_fails("normal n", 'E35:')
1753 call assert_fails("normal N", 'E35:')
1754 call assert_fails("normal gn", 'E35:')
1755 call assert_fails("normal gN", 'E35:')
1756 call assert_fails("normal cgn", 'E35:')
1757 call assert_fails("normal cgN", 'E35:')
1758 let p = []
1759 let p = @/
1760 call assert_equal('', p)
1761 call assert_fails("normal :\<C-R>/", 'E35:')
1762 call assert_fails("//p", 'E35:')
1763 call assert_fails(";//p", 'E35:')
1764 call assert_fails("??p", 'E35:')
1765 call assert_fails(";??p", 'E35:')
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001766 call assert_fails('g//p', ['E35:', 'E476:'])
1767 call assert_fails('v//p', ['E35:', 'E476:'])
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001768 call writefile(v:errors, 'Xresult')
1769 qall!
1770 [SCRIPT]
Bram Moolenaar56564962022-10-10 22:39:42 +01001771 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001772
1773 if RunVim([], [], '--clean -S Xscript')
1774 call assert_equal([], readfile('Xresult'))
1775 endif
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001776 call delete('Xresult')
Bram Moolenaar07ada5f2020-02-05 20:38:22 +01001777endfunc
1778
zeertzjqd1c8d2d2024-08-24 11:33:39 +02001779" Test for using the last substitute pattern without last search pattern.
1780func Test_search_with_last_substitute_pat()
1781 let lines =<< trim [SCRIPT]
1782 new
1783 set shortmess+=S
1784 call setline(1, repeat(['foofoo'], 3))
1785 %s/foo/bar/
1786 call assert_equal(repeat(['barfoo'], 3), getline(1, '$'))
1787
1788 call cursor(1, 1)
1789 call assert_equal("/foo", execute('call feedkeys("/\r", "tx")', '')->trim())
1790 call assert_equal([0, 1, 4, 0], getpos('.'))
1791
1792 if has('rightleft')
1793 set rightleft rightleftcmd=search
1794 call cursor(1, 1)
1795 call assert_equal("oof/", execute('call feedkeys("/\r", "tx")', '')->trim())
1796 call assert_equal([0, 1, 4, 0], getpos('.'))
1797 endif
1798
1799 call writefile(v:errors, 'Xresult')
1800 qall!
1801 [SCRIPT]
1802 call writefile(lines, 'Xscript', 'D')
1803
1804 if RunVim([], [], '--clean -S Xscript')
1805 call assert_equal([], readfile('Xresult'))
1806 endif
1807 call delete('Xresult')
1808endfunc
1809
Bram Moolenaar07ada5f2020-02-05 20:38:22 +01001810" Test for using tilde (~) atom in search. This should use the last used
1811" substitute pattern
1812func Test_search_tilde_pat()
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001813 let lines =<< trim [SCRIPT]
1814 set regexpengine=1
1815 call assert_fails('exe "normal /~\<CR>"', 'E33:')
1816 call assert_fails('exe "normal ?~\<CR>"', 'E33:')
1817 set regexpengine=2
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001818 call assert_fails('exe "normal /~\<CR>"', ['E33:', 'E383:'])
1819 call assert_fails('exe "normal ?~\<CR>"', ['E33:', 'E383:'])
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001820 set regexpengine&
1821 call writefile(v:errors, 'Xresult')
1822 qall!
1823 [SCRIPT]
Bram Moolenaar56564962022-10-10 22:39:42 +01001824 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001825 if RunVim([], [], '--clean -S Xscript')
1826 call assert_equal([], readfile('Xresult'))
1827 endif
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001828 call delete('Xresult')
Bram Moolenaar07ada5f2020-02-05 20:38:22 +01001829endfunc
1830
Bram Moolenaar406cd902020-02-18 21:54:41 +01001831" Test for searching a pattern that is not present with 'nowrapscan'
1832func Test_search_pat_not_found()
1833 new
1834 set nowrapscan
1835 let @/ = '1abcxyz2'
1836 call assert_fails('normal n', 'E385:')
1837 call assert_fails('normal N', 'E384:')
1838 set wrapscan&
1839 close
1840endfunc
1841
1842" Test for v:searchforward variable
1843func Test_searchforward_var()
1844 new
1845 call setline(1, ['foo', '', 'foo'])
1846 call cursor(2, 1)
1847 let @/ = 'foo'
1848 let v:searchforward = 0
1849 normal N
1850 call assert_equal(3, line('.'))
1851 call cursor(2, 1)
1852 let v:searchforward = 1
1853 normal N
1854 call assert_equal(1, line('.'))
1855 close!
1856endfunc
1857
Bram Moolenaar476a6132020-04-08 19:48:56 +02001858" Test for invalid regular expressions
1859func Test_invalid_regexp()
1860 set regexpengine=1
1861 call assert_fails("call search(repeat('\\(.\\)', 10))", 'E51:')
Bram Moolenaar4d23c522020-04-09 18:42:11 +02001862 call assert_fails("call search('\\%(')", 'E53:')
1863 call assert_fails("call search('\\(')", 'E54:')
1864 call assert_fails("call search('\\)')", 'E55:')
Bram Moolenaar476a6132020-04-08 19:48:56 +02001865 call assert_fails("call search('x\\@#')", 'E59:')
Bram Moolenaar4d23c522020-04-09 18:42:11 +02001866 call assert_fails('call search(''\v%(%(%(%(%(%(%(%(%(%(%(a){1}){1}){1}){1}){1}){1}){1}){1}){1}){1}){1}'')', 'E60:')
1867 call assert_fails("call search('a\\+*')", 'E61:')
Bram Moolenaar476a6132020-04-08 19:48:56 +02001868 call assert_fails("call search('\\_m')", 'E63:')
1869 call assert_fails("call search('\\+')", 'E64:')
1870 call assert_fails("call search('\\1')", 'E65:')
1871 call assert_fails("call search('\\z\\(\\)')", 'E66:')
1872 call assert_fails("call search('\\z2')", 'E67:')
1873 call assert_fails("call search('\\zx')", 'E68:')
1874 call assert_fails("call search('\\%[ab')", 'E69:')
1875 call assert_fails("call search('\\%[]')", 'E70:')
1876 call assert_fails("call search('\\%a')", 'E71:')
1877 call assert_fails("call search('ab\\%[\\(cd\\)]')", 'E369:')
1878 call assert_fails("call search('ab\\%[\\%(cd\\)]')", 'E369:')
1879 set regexpengine=2
1880 call assert_fails("call search('\\_')", 'E865:')
1881 call assert_fails("call search('\\+')", 'E866:')
1882 call assert_fails("call search('\\zx')", 'E867:')
1883 call assert_fails("call search('\\%a')", 'E867:')
1884 call assert_fails("call search('x\\@#')", 'E869:')
1885 call assert_fails("call search(repeat('\\(.\\)', 10))", 'E872:')
1886 call assert_fails("call search('\\_m')", 'E877:')
1887 call assert_fails("call search('\\%(')", 'E53:')
1888 call assert_fails("call search('\\(')", 'E54:')
1889 call assert_fails("call search('\\)')", 'E55:')
1890 call assert_fails("call search('\\z\\(\\)')", 'E66:')
Dominique Pelle8bfa0eb2022-01-02 16:16:33 +00001891 call assert_fails("call search('\\z2')", 'E67:')
1892 call assert_fails("call search('\\zx')", 'E867:')
Bram Moolenaar476a6132020-04-08 19:48:56 +02001893 call assert_fails("call search('\\%[ab')", 'E69:')
Bram Moolenaar4d23c522020-04-09 18:42:11 +02001894 call assert_fails("call search('\\%[]')", 'E70:')
Bram Moolenaar476a6132020-04-08 19:48:56 +02001895 call assert_fails("call search('\\%9999999999999999999999999999v')", 'E951:')
1896 set regexpengine&
1897 call assert_fails("call search('\\%#=3ab')", 'E864:')
1898endfunc
1899
Bram Moolenaar004a6782020-04-11 17:09:31 +02001900" Test for searching a very complex pattern in a string. Should switch the
1901" regexp engine from NFA to the old engine.
1902func Test_regexp_switch_engine()
1903 let l = readfile('samples/re.freeze.txt')
1904 let v = substitute(l[4], '..\@<!', '', '')
1905 call assert_equal(l[4], v)
1906endfunc
1907
1908" Test for the \%V atom to search within visually selected text
1909func Test_search_in_visual_area()
1910 new
1911 call setline(1, ['foo bar1', 'foo bar2', 'foo bar3', 'foo bar4'])
1912 exe "normal 2GVjo/\\%Vbar\<CR>\<Esc>"
1913 call assert_equal([2, 5], [line('.'), col('.')])
1914 exe "normal 2GVj$?\\%Vbar\<CR>\<Esc>"
1915 call assert_equal([3, 5], [line('.'), col('.')])
1916 close!
1917endfunc
1918
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02001919" Test for searching with 'smartcase' and 'ignorecase'
1920func Test_search_smartcase()
1921 new
1922 call setline(1, ['', 'Hello'])
1923 set noignorecase nosmartcase
1924 call assert_fails('exe "normal /\\a\\_.\\(.*\\)O\<CR>"', 'E486:')
1925
1926 set ignorecase nosmartcase
1927 exe "normal /\\a\\_.\\(.*\\)O\<CR>"
1928 call assert_equal([2, 1], [line('.'), col('.')])
1929
1930 call cursor(1, 1)
1931 set ignorecase smartcase
1932 call assert_fails('exe "normal /\\a\\_.\\(.*\\)O\<CR>"', 'E486:')
1933
1934 exe "normal /\\a\\_.\\(.*\\)o\<CR>"
1935 call assert_equal([2, 1], [line('.'), col('.')])
1936
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001937 " Test for using special atoms with 'smartcase'
1938 call setline(1, ['', ' Hello\ '])
1939 call cursor(1, 1)
1940 call feedkeys('/\_.\%(\uello\)\' .. "\<CR>", 'xt')
1941 call assert_equal([2, 4], [line('.'), col('.')])
1942
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02001943 set ignorecase& smartcase&
1944 close!
Bram Moolenaard66cdcd2020-07-26 13:27:16 +02001945endfun
1946
1947" Test 'smartcase' with utf-8.
1948func Test_search_smartcase_utf8()
1949 new
1950 let save_enc = &encoding
1951 set encoding=utf8 ignorecase smartcase
1952
1953 call setline(1, 'Café cafÉ')
1954 1s/café/x/g
1955 call assert_equal('x x', getline(1))
1956
1957 call setline(1, 'Café cafÉ')
1958 1s/cafÉ/x/g
1959 call assert_equal('Café x', getline(1))
1960
1961 set ignorecase& smartcase&
1962 let &encoding = save_enc
Bram Moolenaarc96311b2022-11-25 21:13:47 +00001963 bwipe!
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02001964endfunc
1965
1966" Test searching past the end of a file
1967func Test_search_past_eof()
1968 new
1969 call setline(1, ['Line'])
1970 exe "normal /\\n\\zs\<CR>"
1971 call assert_equal([1, 4], [line('.'), col('.')])
Bram Moolenaarc96311b2022-11-25 21:13:47 +00001972 bwipe!
1973endfunc
1974
1975" Test setting the start of the match and still finding a next match in the
1976" same line.
1977func Test_search_set_start_same_line()
1978 new
1979 set cpo-=c
1980
1981 call setline(1, ['1', '2', '3 .', '4', '5'])
1982 exe "normal /\\_s\\zs\\S\<CR>"
1983 call assert_equal([2, 1], [line('.'), col('.')])
1984 exe 'normal n'
1985 call assert_equal([3, 1], [line('.'), col('.')])
1986 exe 'normal n'
1987 call assert_equal([3, 3], [line('.'), col('.')])
1988 exe 'normal n'
1989 call assert_equal([4, 1], [line('.'), col('.')])
1990 exe 'normal n'
1991 call assert_equal([5, 1], [line('.'), col('.')])
1992
1993 set cpo+=c
1994 bwipe!
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02001995endfunc
1996
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001997" Test for various search offsets
1998func Test_search_offset()
1999 " With /e, for a match in the first column of a line, the cursor should be
2000 " placed at the end of the previous line.
2001 new
2002 call setline(1, ['one two', 'three four'])
2003 call search('two\_.', 'e')
2004 call assert_equal([1, 7], [line('.'), col('.')])
2005
2006 " with cursor at the beginning of the file, use /s+1
2007 call cursor(1, 1)
2008 exe "normal /two/s+1\<CR>"
2009 call assert_equal([1, 6], [line('.'), col('.')])
2010
2011 " with cursor at the end of the file, use /e-1
2012 call cursor(2, 10)
2013 exe "normal ?three?e-1\<CR>"
2014 call assert_equal([2, 4], [line('.'), col('.')])
2015
2016 " line offset - after the last line
2017 call cursor(1, 1)
2018 exe "normal /three/+1\<CR>"
2019 call assert_equal([2, 1], [line('.'), col('.')])
2020
2021 " line offset - before the first line
2022 call cursor(2, 1)
2023 exe "normal ?one?-1\<CR>"
2024 call assert_equal([1, 1], [line('.'), col('.')])
2025
2026 " character offset - before the first character in the file
2027 call cursor(2, 1)
2028 exe "normal ?one?s-1\<CR>"
2029 call assert_equal([1, 1], [line('.'), col('.')])
2030 call cursor(2, 1)
2031 exe "normal ?one?e-3\<CR>"
2032 call assert_equal([1, 1], [line('.'), col('.')])
2033
2034 " character offset - after the last character in the file
2035 call cursor(1, 1)
2036 exe "normal /four/s+4\<CR>"
2037 call assert_equal([2, 10], [line('.'), col('.')])
2038 call cursor(1, 1)
2039 exe "normal /four/e+1\<CR>"
2040 call assert_equal([2, 10], [line('.'), col('.')])
2041
2042 close!
2043endfunc
2044
2045" Test for searching for matching parenthesis using %
2046func Test_search_match_paren()
2047 new
2048 call setline(1, "abc(def')'ghi'('jk'\\t'lm)no")
2049 " searching for a matching parenthesis should skip single quoted characters
2050 call cursor(1, 4)
2051 normal %
2052 call assert_equal([1, 25], [line('.'), col('.')])
2053 normal %
2054 call assert_equal([1, 4], [line('.'), col('.')])
2055 call cursor(1, 5)
2056 normal ])
2057 call assert_equal([1, 25], [line('.'), col('.')])
2058 call cursor(1, 24)
2059 normal [(
2060 call assert_equal([1, 4], [line('.'), col('.')])
2061
2062 " matching parenthesis in 'virtualedit' mode with cursor after the eol
2063 call setline(1, 'abc(defgh)')
2064 set virtualedit=all
2065 normal 20|%
2066 call assert_equal(4, col('.'))
2067 set virtualedit&
2068 close!
2069endfunc
2070
2071" Test for searching a pattern and stopping before a specified line
2072func Test_search_stopline()
2073 new
2074 call setline(1, ['', '', '', 'vim'])
2075 call assert_equal(0, search('vim', 'n', 3))
2076 call assert_equal(4, search('vim', 'n', 4))
2077 call setline(1, ['vim', '', '', ''])
2078 call cursor(4, 1)
2079 call assert_equal(0, search('vim', 'bn', 2))
2080 call assert_equal(1, search('vim', 'bn', 1))
2081 close!
2082endfunc
2083
Bram Moolenaar6bed0db2020-11-25 17:41:20 +01002084func Test_incsearch_highlighting_newline()
Bram Moolenaar448465e2020-11-25 13:49:27 +01002085 CheckRunVimInTerminal
2086 CheckOption incsearch
2087 CheckScreendump
2088 new
2089 call test_override("char_avail", 1)
2090
2091 let commands =<< trim [CODE]
2092 set incsearch nohls
2093 call setline(1, ['test', 'xxx'])
2094 [CODE]
Bram Moolenaar56564962022-10-10 22:39:42 +01002095 call writefile(commands, 'Xincsearch_nl', 'D')
Bram Moolenaar448465e2020-11-25 13:49:27 +01002096 let buf = RunVimInTerminal('-S Xincsearch_nl', {'rows': 5, 'cols': 10})
Bram Moolenaar448465e2020-11-25 13:49:27 +01002097 call term_sendkeys(buf, '/test')
Bram Moolenaar448465e2020-11-25 13:49:27 +01002098 call VerifyScreenDump(buf, 'Test_incsearch_newline1', {})
Bram Moolenaar6bed0db2020-11-25 17:41:20 +01002099 " Need to send one key at a time to force a redraw
Bram Moolenaar448465e2020-11-25 13:49:27 +01002100 call term_sendkeys(buf, '\n')
Bram Moolenaar448465e2020-11-25 13:49:27 +01002101 call VerifyScreenDump(buf, 'Test_incsearch_newline2', {})
2102 call term_sendkeys(buf, 'x')
Bram Moolenaar448465e2020-11-25 13:49:27 +01002103 call VerifyScreenDump(buf, 'Test_incsearch_newline3', {})
2104 call term_sendkeys(buf, 'x')
2105 call VerifyScreenDump(buf, 'Test_incsearch_newline4', {})
2106 call term_sendkeys(buf, "\<CR>")
Bram Moolenaar448465e2020-11-25 13:49:27 +01002107 call VerifyScreenDump(buf, 'Test_incsearch_newline5', {})
2108 call StopVimInTerminal(buf)
2109
2110 " clean up
Bram Moolenaar448465e2020-11-25 13:49:27 +01002111 call test_override("char_avail", 0)
2112 bw
2113endfunc
2114
Bram Moolenaard93a7fc2021-01-04 12:42:13 +01002115func Test_incsearch_substitute_dump2()
2116 CheckOption incsearch
2117 CheckScreendump
2118
2119 call writefile([
2120 \ 'set incsearch hlsearch scrolloff=0',
2121 \ 'for n in range(1, 4)',
2122 \ ' call setline(n, "foo " . n)',
2123 \ 'endfor',
2124 \ 'call setline(5, "abc|def")',
2125 \ '3',
Bram Moolenaar56564962022-10-10 22:39:42 +01002126 \ ], 'Xis_subst_script2', 'D')
Bram Moolenaard93a7fc2021-01-04 12:42:13 +01002127 let buf = RunVimInTerminal('-S Xis_subst_script2', {'rows': 9, 'cols': 70})
2128
2129 call term_sendkeys(buf, ':%s/\vabc|')
2130 sleep 100m
2131 call VerifyScreenDump(buf, 'Test_incsearch_sub_01', {})
2132 call term_sendkeys(buf, "\<Esc>")
2133
2134 " The following should not be highlighted
2135 call term_sendkeys(buf, ':1,5s/\v|')
2136 sleep 100m
2137 call VerifyScreenDump(buf, 'Test_incsearch_sub_02', {})
2138
2139
2140 call StopVimInTerminal(buf)
Bram Moolenaard93a7fc2021-01-04 12:42:13 +01002141endfunc
2142
zeertzjq7b7b4cb2023-08-11 23:48:27 +02002143func Test_incsearch_restore_view()
2144 CheckOption incsearch
2145 CheckScreendump
2146
2147 let lines =<< trim [CODE]
2148 set incsearch nohlsearch
2149 setlocal scrolloff=0 smoothscroll
2150 call setline(1, [join(range(25), ' '), '', '', '', '', 'xxx'])
2151 call feedkeys("2\<C-E>", 't')
2152 [CODE]
2153 call writefile(lines, 'Xincsearch_restore_view', 'D')
2154 let buf = RunVimInTerminal('-S Xincsearch_restore_view', {'rows': 6, 'cols': 20})
2155
2156 call VerifyScreenDump(buf, 'Test_incsearch_restore_view_01', {})
Christ van Willegen73b82092023-08-12 20:17:26 +02002157 call term_sendkeys(buf, '/xx')
zeertzjq7b7b4cb2023-08-11 23:48:27 +02002158 call VerifyScreenDump(buf, 'Test_incsearch_restore_view_02', {})
Christ van Willegen73b82092023-08-12 20:17:26 +02002159 call term_sendkeys(buf, 'x')
2160 call VerifyScreenDump(buf, 'Test_incsearch_restore_view_03', {})
zeertzjq7b7b4cb2023-08-11 23:48:27 +02002161 call term_sendkeys(buf, "\<Esc>")
2162 call VerifyScreenDump(buf, 'Test_incsearch_restore_view_01', {})
2163
2164 call StopVimInTerminal(buf)
2165endfunc
2166
Christian Brabandt78ba9332021-08-01 12:44:37 +02002167func Test_pattern_is_uppercase_smartcase()
2168 new
2169 let input=['abc', 'ABC', 'Abc', 'abC']
2170 call setline(1, input)
2171 call cursor(1,1)
2172 " default, matches firstline
2173 %s/abc//g
2174 call assert_equal(['', 'ABC', 'Abc', 'abC'],
2175 \ getline(1, '$'))
2176
2177 set smartcase ignorecase
2178 sil %d
2179 call setline(1, input)
2180 call cursor(1,1)
2181 " with smartcase and incsearch set, matches everything
2182 %s/abc//g
2183 call assert_equal(['', '', '', ''], getline(1, '$'))
2184
2185 sil %d
2186 call setline(1, input)
2187 call cursor(1,1)
2188 " with smartcase and incsearch set and found an uppercase letter,
2189 " match only that.
2190 %s/abC//g
2191 call assert_equal(['abc', 'ABC', 'Abc', ''],
2192 \ getline(1, '$'))
2193
2194 sil %d
2195 call setline(1, input)
2196 call cursor(1,1)
2197 exe "norm! vG$\<esc>"
2198 " \%V should not be detected as uppercase letter
2199 %s/\%Vabc//g
2200 call assert_equal(['', '', '', ''], getline(1, '$'))
2201
2202 call setline(1, input)
2203 call cursor(1,1)
2204 exe "norm! vG$\<esc>"
2205 " \v%V should not be detected as uppercase letter
2206 %s/\v%Vabc//g
2207 call assert_equal(['', '', '', ''], getline(1, '$'))
2208
2209 call setline(1, input)
2210 call cursor(1,1)
2211 exe "norm! vG$\<esc>"
2212 " \v%VabC should be detected as uppercase letter
2213 %s/\v%VabC//g
2214 call assert_equal(['abc', 'ABC', 'Abc', ''],
2215 \ getline(1, '$'))
2216
Christian Brabandtbc67e5a2021-08-05 15:24:59 +02002217 call setline(1, input)
2218 call cursor(1,1)
2219 " \Vabc should match everything
2220 %s/\Vabc//g
2221 call assert_equal(['', '', '', ''], getline(1, '$'))
2222
2223 call setline(1, input + ['_abc'])
2224 " _ matches normally
2225 %s/\v_.*//g
2226 call assert_equal(['abc', 'ABC', 'Abc', 'abC', ''], getline(1, '$'))
2227
Christian Brabandt78ba9332021-08-01 12:44:37 +02002228 set smartcase& ignorecase&
2229 bw!
2230endfunc
2231
Bram Moolenaard8d957d2021-10-04 19:47:35 +01002232func Test_no_last_search_pattern()
2233 CheckOption incsearch
2234
2235 let @/ = ""
2236 set incsearch
Bram Moolenaar9af9fd62021-10-04 20:09:19 +01002237 " these were causing a crash
2238 call feedkeys("//\<C-G>", 'xt')
2239 call feedkeys("//\<C-T>", 'xt')
2240 call feedkeys("??\<C-G>", 'xt')
2241 call feedkeys("??\<C-T>", 'xt')
Bram Moolenaard8d957d2021-10-04 19:47:35 +01002242endfunc
2243
Bram Moolenaar35a319b2021-10-09 13:58:55 +01002244func Test_search_with_invalid_range()
2245 new
2246 let lines =<< trim END
2247 /\%.v
2248 5/
2249 c
2250 END
Bram Moolenaar56564962022-10-10 22:39:42 +01002251 call writefile(lines, 'Xrangesearch', 'D')
Bram Moolenaar35a319b2021-10-09 13:58:55 +01002252 source Xrangesearch
2253
2254 bwipe!
Bram Moolenaar35a319b2021-10-09 13:58:55 +01002255endfunc
2256
Bram Moolenaard8d957d2021-10-04 19:47:35 +01002257
Bram Moolenaar07ada5f2020-02-05 20:38:22 +01002258" vim: shiftwidth=2 sts=2 expandtab