blob: c974c401476cc7bfa82e3e24fa8e21cde22d57a3 [file] [log] [blame]
Bram Moolenaared71ed32019-01-30 22:13:35 +01001" Test findfile() and finddir()
2
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +02003source check.vim
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +01004import './vim9.vim' as v9
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +02005
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01006let s:files = [ 'Xfinddir1/foo',
7 \ 'Xfinddir1/bar',
8 \ 'Xfinddir1/Xdir2/foo',
9 \ 'Xfinddir1/Xdir2/foobar',
10 \ 'Xfinddir1/Xdir2/Xdir3/bar',
11 \ 'Xfinddir1/Xdir2/Xdir3/barfoo' ]
Bram Moolenaared71ed32019-01-30 22:13:35 +010012
13func CreateFiles()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +010014 call mkdir('Xfinddir1/Xdir2/Xdir3/Xdir2', 'p')
Bram Moolenaared71ed32019-01-30 22:13:35 +010015 for f in s:files
16 call writefile([], f)
17 endfor
18endfunc
19
20func CleanFiles()
21 " Safer to delete each file even if it's more verbose
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +010022 " than doing a recursive delete('Xfinddir1', 'rf').
Bram Moolenaared71ed32019-01-30 22:13:35 +010023 for f in s:files
24 call delete(f)
25 endfor
26
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +010027 call delete('Xfinddir1/Xdir2/Xdir3/Xdir2', 'd')
28 call delete('Xfinddir1/Xdir2/Xdir3', 'd')
29 call delete('Xfinddir1/Xdir2', 'd')
30 call delete('Xfinddir1', 'd')
Bram Moolenaared71ed32019-01-30 22:13:35 +010031endfunc
32
33" Test findfile({name} [, {path} [, {count}]])
Bram Moolenaardc9a0812017-02-23 18:46:50 +010034func Test_findfile()
Bram Moolenaared71ed32019-01-30 22:13:35 +010035 let save_path = &path
36 let save_shellslash = &shellslash
37 let save_dir = getcwd()
38 set shellslash
39 call CreateFiles()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +010040 cd Xfinddir1
Bram Moolenaared71ed32019-01-30 22:13:35 +010041 e Xdir2/foo
42
43 " With ,, in path, findfile() searches in current directory.
44 set path=,,
45 call assert_equal('foo', findfile('foo'))
46 call assert_equal('bar', findfile('bar'))
47 call assert_equal('', findfile('foobar'))
48
49 " Directories should not be found (finddir() finds them).
50 call assert_equal('', findfile('Xdir2'))
51
52 " With . in 'path', findfile() searches relatively to current file.
53 set path=.
54 call assert_equal('Xdir2/foo', findfile('foo'))
55 call assert_equal('', findfile('bar'))
Bram Moolenaara4208962019-08-24 20:50:19 +020056 call assert_equal('Xdir2/foobar', 'foobar'->findfile())
Bram Moolenaared71ed32019-01-30 22:13:35 +010057
58 " Empty {path} 2nd argument is the same as no 2nd argument.
59 call assert_equal('Xdir2/foo', findfile('foo', ''))
60 call assert_equal('', findfile('bar', ''))
61
62 " Test with *
63 call assert_equal('Xdir2/foo', findfile('foo', '*'))
64 call assert_equal('', findfile('bar', '*'))
65 call assert_equal('Xdir2/Xdir3/bar', findfile('bar', '*/*'))
66 call assert_equal('Xdir2/Xdir3/bar', findfile('bar', 'Xdir2/*'))
67 call assert_equal('Xdir2/Xdir3/bar', findfile('bar', 'Xdir*/Xdir3'))
68 call assert_equal('Xdir2/Xdir3/bar', findfile('bar', '*2/*3'))
69
70 " Test with **
71 call assert_equal('bar', findfile('bar', '**'))
72 call assert_equal('Xdir2/Xdir3/bar', findfile('bar', '**/Xdir3'))
73 call assert_equal('Xdir2/Xdir3/bar', findfile('bar', 'Xdir2/**'))
74
75 call assert_equal('Xdir2/Xdir3/barfoo', findfile('barfoo', '**2'))
76 call assert_equal('', findfile('barfoo', '**1'))
77 call assert_equal('Xdir2/foobar', findfile('foobar', '**1'))
78
79 " Test with {count} 3rd argument.
80 call assert_equal('bar', findfile('bar', '**', 0))
81 call assert_equal('bar', findfile('bar', '**', 1))
82 call assert_equal('Xdir2/Xdir3/bar', findfile('bar', '**', 2))
83 call assert_equal('', findfile('bar', '**', 3))
84 call assert_equal(['bar', 'Xdir2/Xdir3/bar'], findfile('bar', '**', -1))
85
86 " Test upwards search.
87 cd Xdir2/Xdir3
88 call assert_equal('bar', findfile('bar', ';'))
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +010089 call assert_match('.*/Xfinddir1/Xdir2/foo', findfile('foo', ';'))
90 call assert_match('.*/Xfinddir1/Xdir2/foo', findfile('foo', ';', 1))
91 call assert_match('.*/Xfinddir1/foo', findfile('foo', ';', 2))
92 call assert_match('.*/Xfinddir1/foo', findfile('foo', ';', 2))
93 call assert_match('.*/Xfinddir1/Xdir2/foo', findfile('foo', 'Xdir2;', 1))
Bram Moolenaared71ed32019-01-30 22:13:35 +010094 call assert_equal('', findfile('foo', 'Xdir2;', 2))
95
96 " List l should have at least 2 values (possibly more if foo file
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +010097 " happens to be found upwards above Xfinddir1).
Bram Moolenaared71ed32019-01-30 22:13:35 +010098 let l = findfile('foo', ';', -1)
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +010099 call assert_match('.*/Xfinddir1/Xdir2/foo', l[0])
100 call assert_match('.*/Xfinddir1/foo', l[1])
Bram Moolenaared71ed32019-01-30 22:13:35 +0100101
102 " Test upwards search with stop-directory.
103 cd Xdir2
zeertzjq764526e2024-07-11 22:24:15 +0200104 let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/Xdir3/', -1)
105 call assert_equal(1, len(l))
106 call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
107 let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/Xdir3', -1)
108 call assert_equal(1, len(l))
109 call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
110 let l = findfile('bar', ';../', -1)
111 call assert_equal(1, len(l))
112 call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
zeertzjq1ee74202024-07-12 07:29:14 +0200113 let l = findfile('bar', ';..', -1)
114 call assert_equal(1, len(l))
115 call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
zeertzjq764526e2024-07-11 22:24:15 +0200116
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100117 let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/', -1)
Bram Moolenaared71ed32019-01-30 22:13:35 +0100118 call assert_equal(1, len(l))
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100119 call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
zeertzjqe6ab23b2024-07-11 22:22:26 +0200120 let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2', -1)
121 call assert_equal(1, len(l))
122 call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
zeertzjq764526e2024-07-11 22:24:15 +0200123 let l = findfile('bar', ';../../', -1)
124 call assert_equal(1, len(l))
125 call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
zeertzjq1ee74202024-07-12 07:29:14 +0200126 let l = findfile('bar', ';../..', -1)
127 call assert_equal(1, len(l))
128 call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
Bram Moolenaared71ed32019-01-30 22:13:35 +0100129
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100130 let l = findfile('bar', ';' . save_dir . '/Xfinddir1/', -1)
Bram Moolenaared71ed32019-01-30 22:13:35 +0100131 call assert_equal(2, len(l))
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100132 call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
133 call assert_match('.*/Xfinddir1/bar', l[1])
zeertzjqe6ab23b2024-07-11 22:22:26 +0200134 let l = findfile('bar', ';' . save_dir . '/Xfinddir1', -1)
135 call assert_equal(2, len(l))
136 call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
137 call assert_match('.*/Xfinddir1/bar', l[1])
zeertzjq764526e2024-07-11 22:24:15 +0200138 let l = findfile('bar', ';../../../', -1)
139 call assert_equal(2, len(l))
140 call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
141 call assert_match('.*/Xfinddir1/bar', l[1])
zeertzjq1ee74202024-07-12 07:29:14 +0200142 let l = findfile('bar', ';../../..', -1)
143 call assert_equal(2, len(l))
144 call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
145 call assert_match('.*/Xfinddir1/bar', l[1])
Bram Moolenaared71ed32019-01-30 22:13:35 +0100146
147 " Test combined downwards and upwards search from Xdir2/.
148 cd ../..
149 call assert_equal('Xdir3/bar', findfile('bar', '**;', 1))
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100150 call assert_match('.*/Xfinddir1/bar', findfile('bar', '**;', 2))
Bram Moolenaared71ed32019-01-30 22:13:35 +0100151
152 bwipe!
Bram Moolenaar3503d7c2019-11-09 20:10:17 +0100153 call chdir(save_dir)
Bram Moolenaared71ed32019-01-30 22:13:35 +0100154 call CleanFiles()
155 let &path = save_path
156 let &shellslash = save_shellslash
157endfunc
158
Bram Moolenaar71b13e92019-02-04 21:14:45 +0100159func Test_findfile_error()
160 call assert_fails('call findfile([])', 'E730:')
161 call assert_fails('call findfile("x", [])', 'E730:')
162 call assert_fails('call findfile("x", "", [])', 'E745:')
163 call assert_fails('call findfile("x", "**x")', 'E343:')
164 call assert_fails('call findfile("x", repeat("x", 5000))', 'E854:')
165endfunc
166
Bram Moolenaared71ed32019-01-30 22:13:35 +0100167" Test finddir({name} [, {path} [, {count}]])
168func Test_finddir()
169 let save_path = &path
170 let save_shellslash = &shellslash
171 let save_dir = getcwd()
172 set path=,,
zeertzjqe7b98ab2024-07-11 21:48:09 +0200173 set shellslash
Bram Moolenaared71ed32019-01-30 22:13:35 +0100174 call CreateFiles()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100175 cd Xfinddir1
Bram Moolenaared71ed32019-01-30 22:13:35 +0100176
177 call assert_equal('Xdir2', finddir('Xdir2'))
Bram Moolenaara4208962019-08-24 20:50:19 +0200178 call assert_equal('', 'Xdir3'->finddir())
Bram Moolenaared71ed32019-01-30 22:13:35 +0100179
180 " Files should not be found (findfile() finds them).
181 call assert_equal('', finddir('foo'))
182
183 call assert_equal('Xdir2', finddir('Xdir2', '**'))
184 call assert_equal('Xdir2/Xdir3', finddir('Xdir3', '**'))
185
186 call assert_equal('Xdir2', finddir('Xdir2', '**', 1))
187 call assert_equal('Xdir2/Xdir3/Xdir2', finddir('Xdir2', '**', 2))
188 call assert_equal(['Xdir2',
189 \ 'Xdir2/Xdir3/Xdir2'], finddir('Xdir2', '**', -1))
190
191 call assert_equal('Xdir2', finddir('Xdir2', '**1'))
192 call assert_equal('Xdir2', finddir('Xdir2', '**0'))
193 call assert_equal('Xdir2/Xdir3', finddir('Xdir3', '**1'))
194 call assert_equal('', finddir('Xdir3', '**0'))
195
196 " Test upwards dir search.
197 cd Xdir2/Xdir3
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100198 call assert_match('.*/Xfinddir1', finddir('Xfinddir1', ';'))
Bram Moolenaared71ed32019-01-30 22:13:35 +0100199
200 " Test upwards search with stop-directory.
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100201 call assert_match('.*/Xfinddir1', finddir('Xfinddir1', ';' . save_dir . '/'))
202 call assert_equal('', finddir('Xfinddir1', ';' . save_dir . '/Xfinddir1/'))
Bram Moolenaared71ed32019-01-30 22:13:35 +0100203
204 " Test combined downwards and upwards dir search from Xdir2/.
Bram Moolenaardc9a0812017-02-23 18:46:50 +0100205 cd ..
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100206 call assert_match('.*/Xfinddir1', finddir('Xfinddir1', '**;', 1))
Bram Moolenaared71ed32019-01-30 22:13:35 +0100207 call assert_equal('Xdir3/Xdir2', finddir('Xdir2', '**;', 1))
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100208 call assert_match('.*/Xfinddir1/Xdir2', finddir('Xdir2', '**;', 2))
Bram Moolenaared71ed32019-01-30 22:13:35 +0100209 call assert_equal('Xdir3', finddir('Xdir3', '**;', 1))
Bram Moolenaardc9a0812017-02-23 18:46:50 +0100210
Bram Moolenaar3503d7c2019-11-09 20:10:17 +0100211 call chdir(save_dir)
Bram Moolenaared71ed32019-01-30 22:13:35 +0100212 call CleanFiles()
213 let &path = save_path
214 let &shellslash = save_shellslash
Bram Moolenaardc9a0812017-02-23 18:46:50 +0100215endfunc
Bram Moolenaar71b13e92019-02-04 21:14:45 +0100216
217func Test_finddir_error()
218 call assert_fails('call finddir([])', 'E730:')
219 call assert_fails('call finddir("x", [])', 'E730:')
220 call assert_fails('call finddir("x", "", [])', 'E745:')
221 call assert_fails('call finddir("x", "**x")', 'E343:')
222 call assert_fails('call finddir("x", repeat("x", 5000))', 'E854:')
223endfunc
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +0100224
225" Test for the :find, :sfind and :tabfind commands
226func Test_find_cmd()
227 new
228 let save_path = &path
229 let save_dir = getcwd()
230 set path=.,./**/*
231 call CreateFiles()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100232 cd Xfinddir1
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +0100233
234 " Test for :find
235 find foo
236 call assert_equal('foo', expand('%:.'))
237 2find foo
238 call assert_equal('Xdir2/foo', expand('%:.'))
239 call assert_fails('3find foo', 'E347:')
240
241 " Test for :sfind
242 enew
243 sfind barfoo
244 call assert_equal('Xdir2/Xdir3/barfoo', expand('%:.'))
245 call assert_equal(3, winnr('$'))
246 close
247 call assert_fails('sfind baz', 'E345:')
248 call assert_equal(2, winnr('$'))
249
250 " Test for :tabfind
251 enew
252 tabfind foobar
253 call assert_equal('Xdir2/foobar', expand('%:.'))
254 call assert_equal(2, tabpagenr('$'))
255 tabclose
256 call assert_fails('tabfind baz', 'E345:')
257 call assert_equal(1, tabpagenr('$'))
258
259 call chdir(save_dir)
260 call CleanFiles()
261 let &path = save_path
262 close
Bram Moolenaar2d10cd42020-03-19 14:37:30 +0100263
264 call assert_fails('find', 'E471:')
265 call assert_fails('sfind', 'E471:')
266 call assert_fails('tabfind', 'E471:')
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +0100267endfunc
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200268
Christian Brabandt7a4ca322021-07-25 15:08:05 +0200269func Test_find_non_existing_path()
270 new
271 let save_path = &path
272 let save_dir = getcwd()
Bram Moolenaar70e67252022-09-27 19:34:35 +0100273 call mkdir('dir1/dir2', 'pR')
Christian Brabandt7a4ca322021-07-25 15:08:05 +0200274 call writefile([], 'dir1/file.txt')
275 call writefile([], 'dir1/dir2/base.txt')
276 call chdir('dir1/dir2')
277 e base.txt
278 set path=../include
279
280 call assert_fails(':find file.txt', 'E345:')
281
282 call chdir(save_dir)
283 bw!
Christian Brabandt7a4ca322021-07-25 15:08:05 +0200284 let &path = save_path
285endfunc
286
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100287" Test for 'findfunc'
288func Test_findfunc()
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200289 CheckUnix
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100290 call assert_equal('', &findfunc)
291 call writefile(['aFile'], 'Xfindfunc1.c', 'D')
292 call writefile(['bFile'], 'Xfindfunc2.c', 'D')
293 call writefile(['cFile'], 'Xfindfunc3.c', 'D')
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200294
295 " basic tests
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100296 func FindFuncBasic(pat, cmdcomplete)
297 let fnames = ['Xfindfunc1.c', 'Xfindfunc2.c', 'Xfindfunc3.c']
298 return fnames->copy()->filter('v:val =~? a:pat')
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200299 endfunc
300
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100301 set findfunc=FindFuncBasic
302 find Xfindfunc3
303 call assert_match('Xfindfunc3.c', @%)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200304 bw!
305 2find Xfind
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100306 call assert_match('Xfindfunc2.c', @%)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200307 bw!
308 call assert_fails('4find Xfind', 'E347: No more file "Xfind" found in path')
309 call assert_fails('find foobar', 'E345: Can''t find file "foobar" in path')
310
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100311 sfind Xfindfunc2.c
312 call assert_match('Xfindfunc2.c', @%)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200313 call assert_equal(2, winnr('$'))
314 %bw!
315 call assert_fails('sfind foobar', 'E345: Can''t find file "foobar" in path')
316
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100317 tabfind Xfindfunc3.c
318 call assert_match('Xfindfunc3.c', @%)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200319 call assert_equal(2, tabpagenr())
320 %bw!
321 call assert_fails('tabfind foobar', 'E345: Can''t find file "foobar" in path')
322
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100323 " Test garbage collection
324 call test_garbagecollect_now()
325 find Xfindfunc2
326 call assert_match('Xfindfunc2.c', @%)
327 bw!
328 delfunc FindFuncBasic
329 call test_garbagecollect_now()
330 call assert_fails('find Xfindfunc2', 'E117: Unknown function: FindFuncBasic')
331
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200332 " Buffer-local option
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100333 func GlobalFindFunc(pat, cmdcomplete)
334 return ['global']
335 endfunc
336 func LocalFindFunc(pat, cmdcomplete)
337 return ['local']
338 endfunc
339 set findfunc=GlobalFindFunc
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200340 new
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100341 setlocal findfunc=LocalFindFunc
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200342 find xxxx
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100343 call assert_equal('local', @%)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200344 wincmd w
345 find xxxx
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100346 call assert_equal('global', @%)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200347 aboveleft new
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100348 call assert_equal("GlobalFindFunc", &findfunc)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200349 wincmd k
350 aboveleft new
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100351 call assert_equal("GlobalFindFunc", &findfunc)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200352 %bw!
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100353 delfunc GlobalFindFunc
354 delfunc LocalFindFunc
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200355
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100356 " Assign an expression
357 set findfunc=[]
358 call assert_fails('find xxxx', 'E117: Unknown function: []')
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200359
360 " Error cases
361
zeertzjq6eda2692024-11-03 09:23:33 +0100362 " Function that doesn't take any arguments
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100363 func FindFuncNoArg()
364 endfunc
365 set findfunc=FindFuncNoArg
366 call assert_fails('find Xfindfunc1.c', 'E118: Too many arguments for function: FindFuncNoArg')
367 delfunc FindFuncNoArg
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200368
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100369 " Syntax error in the function
370 func FindFuncSyntaxError(pat, cmdcomplete)
371 return l
372 endfunc
373 set findfunc=FindFuncSyntaxError
374 call assert_fails('find Xfindfunc1.c', 'E121: Undefined variable: l')
375 delfunc FindFuncSyntaxError
376
377 " Find function throws an error
378 func FindFuncWithThrow(pat, cmdcomplete)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200379 throw 'find error'
380 endfunc
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100381 set findfunc=FindFuncWithThrow
382 call assert_fails('find Xfindfunc1.c', 'find error')
383 delfunc FindFuncWithThrow
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200384
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100385 " Try using a null function
386 call assert_fails('let &findfunc = test_null_function()', 'E129: Function name required')
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200387
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100388 " Try to create a new window from the find function
389 func FindFuncNewWindow(pat, cmdexpand)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200390 new
391 return ["foo"]
392 endfunc
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100393 set findfunc=FindFuncNewWindow
394 call assert_fails('find Xfindfunc1.c', 'E565: Not allowed to change text or change window')
395 delfunc FindFuncNewWindow
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200396
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100397 " Try to modify the current buffer from the find function
398 func FindFuncModifyBuf(pat, cmdexpand)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200399 call setline(1, ['abc'])
400 return ["foo"]
401 endfunc
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100402 set findfunc=FindFuncModifyBuf
403 call assert_fails('find Xfindfunc1.c', 'E565: Not allowed to change text or change window')
404 delfunc FindFuncModifyBuf
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200405
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100406 " Return the wrong type from the function
407 func FindFuncWrongRet(pat, cmdexpand)
408 return 'foo'
409 endfunc
410 set findfunc=FindFuncWrongRet
411 call assert_fails('find Xfindfunc1.c', "E1514: 'findfunc' did not return a List type")
412 delfunc FindFuncWrongRet
Yegappan Lakshmanan2f6efac2024-10-23 21:06:10 +0200413
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100414 set findfunc&
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200415endfunc
416
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100417" Test for using a script-local function for 'findfunc'
418func Test_findfunc_scriptlocal_func()
419 func! s:FindFuncScript(pat, cmdexpand)
420 let g:FindFuncArg = a:pat
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200421 return ['xxx']
422 endfunc
423
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100424 set findfunc=s:FindFuncScript
425 call assert_equal(expand('<SID>') .. 'FindFuncScript', &findfunc)
426 call assert_equal(expand('<SID>') .. 'FindFuncScript', &g:findfunc)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200427 new | only
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100428 let g:FindFuncArg = ''
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200429 find abc
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100430 call assert_equal('abc', g:FindFuncArg)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200431 bw!
432
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100433 set findfunc=<SID>FindFuncScript
434 call assert_equal(expand('<SID>') .. 'FindFuncScript', &findfunc)
435 call assert_equal(expand('<SID>') .. 'FindFuncScript', &g:findfunc)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200436 new | only
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100437 let g:FindFuncArg = ''
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200438 find abc
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100439 call assert_equal('abc', g:FindFuncArg)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200440 bw!
441
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100442 let &findfunc = 's:FindFuncScript'
443 call assert_equal(expand('<SID>') .. 'FindFuncScript', &g:findfunc)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200444 new | only
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100445 let g:FindFuncArg = ''
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200446 find abc
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100447 call assert_equal('abc', g:FindFuncArg)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200448 bw!
449
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100450 let &findfunc = '<SID>FindFuncScript'
451 call assert_equal(expand('<SID>') .. 'FindFuncScript', &g:findfunc)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200452 new | only
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100453 let g:FindFuncArg = ''
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200454 find abc
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100455 call assert_equal('abc', g:FindFuncArg)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200456 bw!
457
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100458 set findfunc=
459 setglobal findfunc=s:FindFuncScript
460 setlocal findfunc=
461 call assert_equal(expand('<SID>') .. 'FindFuncScript', &findfunc)
462 call assert_equal(expand('<SID>') .. 'FindFuncScript', &g:findfunc)
463 call assert_equal('', &l:findfunc)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200464 new | only
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100465 let g:FindFuncArg = ''
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200466 find abc
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100467 call assert_equal('abc', g:FindFuncArg)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200468 bw!
469
470 new | only
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100471 set findfunc=
472 setglobal findfunc=
473 setlocal findfunc=s:FindFuncScript
474 call assert_equal(expand('<SID>') .. 'FindFuncScript', &findfunc)
475 call assert_equal(expand('<SID>') .. 'FindFuncScript', &l:findfunc)
476 call assert_equal('', &g:findfunc)
477 let g:FindFuncArg = ''
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200478 find abc
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100479 call assert_equal('abc', g:FindFuncArg)
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200480 bw!
481
zeertzjq6eda2692024-11-03 09:23:33 +0100482 new | only
483 set findfunc=
484 setlocal findfunc=NoSuchFunc
485 setglobal findfunc=s:FindFuncScript
486 call assert_equal('NoSuchFunc', &findfunc)
487 call assert_equal('NoSuchFunc', &l:findfunc)
488 call assert_equal(expand('<SID>') .. 'FindFuncScript', &g:findfunc)
489 new | only
490 call assert_equal(expand('<SID>') .. 'FindFuncScript', &findfunc)
491 call assert_equal(expand('<SID>') .. 'FindFuncScript', &g:findfunc)
492 call assert_equal('', &l:findfunc)
493 let g:FindFuncArg = ''
494 find abc
495 call assert_equal('abc', g:FindFuncArg)
496 bw!
497
498 new | only
499 set findfunc=
500 setlocal findfunc=NoSuchFunc
501 set findfunc=s:FindFuncScript
502 call assert_equal(expand('<SID>') .. 'FindFuncScript', &findfunc)
503 call assert_equal(expand('<SID>') .. 'FindFuncScript', &g:findfunc)
504 call assert_equal('', &l:findfunc)
505 let g:FindFuncArg = ''
506 find abc
507 call assert_equal('abc', g:FindFuncArg)
508 new | only
509 call assert_equal(expand('<SID>') .. 'FindFuncScript', &findfunc)
510 call assert_equal(expand('<SID>') .. 'FindFuncScript', &g:findfunc)
511 call assert_equal('', &l:findfunc)
512 let g:FindFuncArg = ''
513 find abc
514 call assert_equal('abc', g:FindFuncArg)
515 bw!
516
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100517 set findfunc=
518 delfunc s:FindFuncScript
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200519endfunc
520
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100521" Test for expanding the argument to the :find command using 'findfunc'
522func Test_findfunc_expand_arg()
523 let s:fnames = ['Xfindfunc1.c', 'Xfindfunc2.c', 'Xfindfunc3.c']
zeertzjq20e045f2024-10-28 22:05:26 +0100524
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100525 " 'findfunc' that accepts a regular expression
526 func FindFuncRegexp(pat, cmdcomplete)
527 return s:fnames->copy()->filter('v:val =~? a:pat')
Yegappan Lakshmanan2f6efac2024-10-23 21:06:10 +0200528 endfunc
Yegappan Lakshmanan2f6efac2024-10-23 21:06:10 +0200529
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100530 " 'findfunc' that accepts a glob
531 func FindFuncGlob(pat_arg, cmdcomplete)
532 let pat = glob2regpat(a:cmdcomplete ? $'*{a:pat_arg}*' : a:pat_arg)
zeertzjq20e045f2024-10-28 22:05:26 +0100533 return s:fnames->copy()->filter('v:val =~? pat')
534 endfunc
Yegappan Lakshmanan2f6efac2024-10-23 21:06:10 +0200535
zeertzjq20e045f2024-10-28 22:05:26 +0100536 for regexp in [v:true, v:false]
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100537 let &findfunc = regexp ? 'FindFuncRegexp' : 'FindFuncGlob'
Yegappan Lakshmanan2f6efac2024-10-23 21:06:10 +0200538
zeertzjq20e045f2024-10-28 22:05:26 +0100539 call feedkeys(":find \<Tab>\<C-B>\"\<CR>", "xt")
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100540 call assert_equal('"find Xfindfunc1.c', @:)
Yegappan Lakshmanan2f6efac2024-10-23 21:06:10 +0200541
zeertzjq20e045f2024-10-28 22:05:26 +0100542 call feedkeys(":find Xfind\<Tab>\<Tab>\<C-B>\"\<CR>", "xt")
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100543 call assert_equal('"find Xfindfunc2.c', @:)
Yegappan Lakshmanan2f6efac2024-10-23 21:06:10 +0200544
zeertzjq20e045f2024-10-28 22:05:26 +0100545 call assert_equal(s:fnames, getcompletion('find ', 'cmdline'))
546 call assert_equal(s:fnames, getcompletion('find Xfind', 'cmdline'))
547
548 let pat = regexp ? 'X.*1\.c' : 'X*1.c'
549 call feedkeys($":find {pat}\<Tab>\<C-B>\"\<CR>", "xt")
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100550 call assert_equal('"find Xfindfunc1.c', @:)
551 call assert_equal(['Xfindfunc1.c'], getcompletion($'find {pat}', 'cmdline'))
zeertzjq20e045f2024-10-28 22:05:26 +0100552
553 call feedkeys(":find 3\<Tab>\<C-B>\"\<CR>", "xt")
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100554 call assert_equal('"find Xfindfunc3.c', @:)
555 call assert_equal(['Xfindfunc3.c'], getcompletion($'find 3', 'cmdline'))
zeertzjq20e045f2024-10-28 22:05:26 +0100556
557 call feedkeys(":find Xfind\<C-A>\<C-B>\"\<CR>", "xt")
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100558 call assert_equal('"find Xfindfunc1.c Xfindfunc2.c Xfindfunc3.c', @:)
zeertzjq20e045f2024-10-28 22:05:26 +0100559
560 call feedkeys(":find abc\<Tab>\<C-B>\"\<CR>", "xt")
561 call assert_equal('"find abc', @:)
562 call assert_equal([], getcompletion('find abc', 'cmdline'))
563 endfor
Yegappan Lakshmanan2f6efac2024-10-23 21:06:10 +0200564
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100565 set findfunc&
566 delfunc! FindFuncRegexp
567 delfunc! FindFuncGlob
zeertzjq20e045f2024-10-28 22:05:26 +0100568 unlet s:fnames
Yegappan Lakshmanan2f6efac2024-10-23 21:06:10 +0200569endfunc
570
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100571" Test for different ways of setting the 'findfunc' option
572func Test_findfunc_callback()
573 new
574 func FindFunc1(pat, cmdexpand)
575 let g:FindFunc1Args = [a:pat, a:cmdexpand]
576 return ['findfunc1']
577 endfunc
578
579 let lines =<< trim END
580 #" Test for using a function name
581 LET &findfunc = 'g:FindFunc1'
582 LET g:FindFunc1Args = []
583 find abc1
584 call assert_equal(['abc1', v:false], g:FindFunc1Args)
585
586 #" Test for using a function()
587 set findfunc=function('g:FindFunc1')
588 LET g:FindFunc1Args = []
589 find abc2
590 call assert_equal(['abc2', v:false], g:FindFunc1Args)
591
592 #" Using a funcref variable to set 'findfunc'
593 VAR Fn = function('g:FindFunc1')
594 LET &findfunc = Fn
595 LET g:FindFunc1Args = []
596 find abc3
597 call assert_equal(['abc3', v:false], g:FindFunc1Args)
598
599 #" Using a string(funcref_variable) to set 'findfunc'
600 LET Fn = function('g:FindFunc1')
601 LET &findfunc = string(Fn)
602 LET g:FindFunc1Args = []
603 find abc4
604 call assert_equal(['abc4', v:false], g:FindFunc1Args)
605
606 #" Test for using a funcref()
607 set findfunc=funcref('g:FindFunc1')
608 LET g:FindFunc1Args = []
609 find abc5
610 call assert_equal(['abc5', v:false], g:FindFunc1Args)
611
612 #" Using a funcref variable to set 'findfunc'
613 LET Fn = funcref('g:FindFunc1')
614 LET &findfunc = Fn
615 LET g:FindFunc1Args = []
616 find abc6
617 call assert_equal(['abc6', v:false], g:FindFunc1Args)
618
619 #" Using a string(funcref_variable) to set 'findfunc'
620 LET Fn = funcref('g:FindFunc1')
621 LET &findfunc = string(Fn)
622 LET g:FindFunc1Args = []
623 find abc7
624 call assert_equal(['abc7', v:false], g:FindFunc1Args)
625
626 #" Test for using a lambda function using set
627 VAR optval = "LSTART pat, cmdexpand LMIDDLE FindFunc1(pat, cmdexpand) LEND"
628 LET optval = substitute(optval, ' ', '\\ ', 'g')
629 exe "set findfunc=" .. optval
630 LET g:FindFunc1Args = []
631 find abc8
632 call assert_equal(['abc8', v:false], g:FindFunc1Args)
633
634 #" Test for using a lambda function using LET
635 LET &findfunc = LSTART pat, _ LMIDDLE FindFunc1(pat, v:false) LEND
636 LET g:FindFunc1Args = []
637 find abc9
638 call assert_equal(['abc9', v:false], g:FindFunc1Args)
639
640 #" Set 'findfunc' to a string(lambda expression)
641 LET &findfunc = 'LSTART pat, _ LMIDDLE FindFunc1(pat, v:false) LEND'
642 LET g:FindFunc1Args = []
643 find abc10
644 call assert_equal(['abc10', v:false], g:FindFunc1Args)
645
646 #" Set 'findfunc' to a variable with a lambda expression
647 VAR Lambda = LSTART pat, _ LMIDDLE FindFunc1(pat, v:false) LEND
648 LET &findfunc = Lambda
649 LET g:FindFunc1Args = []
650 find abc11
651 call assert_equal(['abc11', v:false], g:FindFunc1Args)
652
653 #" Set 'findfunc' to a string(variable with a lambda expression)
654 LET Lambda = LSTART pat, _ LMIDDLE FindFunc1(pat, v:false) LEND
655 LET &findfunc = string(Lambda)
656 LET g:FindFunc1Args = []
657 find abc12
658 call assert_equal(['abc12', v:false], g:FindFunc1Args)
659
660 #" Try to use 'findfunc' after the function is deleted
661 func g:TmpFindFunc(pat, cmdexpand)
662 let g:TmpFindFunc1Args = [a:pat, a:cmdexpand]
663 endfunc
664 LET &findfunc = function('g:TmpFindFunc')
665 delfunc g:TmpFindFunc
666 call test_garbagecollect_now()
667 LET g:TmpFindFunc1Args = []
668 call assert_fails('find abc13', 'E117:')
669 call assert_equal([], g:TmpFindFunc1Args)
670
671 #" Try to use a function with three arguments for 'findfunc'
672 func g:TmpFindFunc2(x, y, z)
673 let g:TmpFindFunc2Args = [a:x, a:y, a:z]
674 endfunc
675 set findfunc=TmpFindFunc2
676 LET g:TmpFindFunc2Args = []
677 call assert_fails('find abc14', 'E119:')
678 call assert_equal([], g:TmpFindFunc2Args)
679 delfunc TmpFindFunc2
680
681 #" Try to use a function with zero arguments for 'findfunc'
682 func g:TmpFindFunc3()
683 let g:TmpFindFunc3Called = v:true
684 endfunc
685 set findfunc=TmpFindFunc3
686 LET g:TmpFindFunc3Called = v:false
687 call assert_fails('find abc15', 'E118:')
688 call assert_equal(v:false, g:TmpFindFunc3Called)
689 delfunc TmpFindFunc3
690
691 #" Try to use a lambda function with three arguments for 'findfunc'
692 LET &findfunc = LSTART a, b, c LMIDDLE FindFunc1(a, v:false) LEND
693 LET g:FindFunc1Args = []
694 call assert_fails('find abc16', 'E119:')
695 call assert_equal([], g:FindFunc1Args)
696
697 #" Test for clearing the 'findfunc' option
698 set findfunc=''
699 set findfunc&
700 call assert_fails("set findfunc=function('abc')", "E700:")
701 call assert_fails("set findfunc=funcref('abc')", "E700:")
702
703 #" set 'findfunc' to a non-existing function
704 LET &findfunc = function('g:FindFunc1')
705 call assert_fails("set findfunc=function('NonExistingFunc')", 'E700:')
706 call assert_fails("LET &findfunc = function('NonExistingFunc')", 'E700:')
707 LET g:FindFunc1Args = []
708 find abc17
709 call assert_equal(['abc17', v:false], g:FindFunc1Args)
710 END
711 call v9.CheckTransLegacySuccess(lines)
712
713 " Test for using a script-local function name
714 func s:FindFunc2(pat, cmdexpand)
715 let g:FindFunc2Args = [a:pat, a:cmdexpand]
716 return ['findfunc2']
717 endfunc
718 set findfunc=s:FindFunc2
719 let g:FindFunc2Args = []
720 find abc18
721 call assert_equal(['abc18', v:false], g:FindFunc2Args)
722
723 let &findfunc = 's:FindFunc2'
724 let g:FindFunc2Args = []
725 find abc19
726 call assert_equal(['abc19', v:false], g:FindFunc2Args)
727 delfunc s:FindFunc2
728
729 " Using Vim9 lambda expression in legacy context should fail
730 set findfunc=(pat,\ cmdexpand)\ =>\ FindFunc1(pat,\ v:false)
731 let g:FindFunc1Args = []
732 call assert_fails('find abc20', 'E117:')
733 call assert_equal([], g:FindFunc1Args)
734
735 " set 'findfunc' to a partial with dict.
736 func SetFindFunc()
737 let operator = {'execute': function('FindFuncExecute')}
738 let &findfunc = operator.execute
739 endfunc
740 func FindFuncExecute(pat, cmdexpand) dict
741 return ['findfuncexecute']
742 endfunc
743 call SetFindFunc()
744 call test_garbagecollect_now()
745 set findfunc=
746 delfunc SetFindFunc
747 delfunc FindFuncExecute
748
749 func FindFunc2(pat, cmdexpand)
750 let g:FindFunc2Args = [a:pat, a:cmdexpand]
751 return ['findfunc2']
752 endfunc
753
754 " Vim9 tests
755 let lines =<< trim END
756 vim9script
757
758 def g:Vim9findFunc(pat: string, cmdexpand: bool): list<string>
759 g:FindFunc1Args = [pat, cmdexpand]
760 return ['vim9findfunc']
761 enddef
762
763 # Test for using a def function with findfunc
764 set findfunc=function('g:Vim9findFunc')
765 g:FindFunc1Args = []
766 find abc21
767 assert_equal(['abc21', false], g:FindFunc1Args)
768
769 # Test for using a global function name
770 &findfunc = g:FindFunc2
771 g:FindFunc2Args = []
772 find abc22
773 assert_equal(['abc22', false], g:FindFunc2Args)
774 bw!
775
776 # Test for using a script-local function name
777 def LocalFindFunc(pat: string, cmdexpand: bool): list<string>
778 g:LocalFindFuncArgs = [pat, cmdexpand]
779 return ['localfindfunc']
780 enddef
781 &findfunc = LocalFindFunc
782 g:LocalFindFuncArgs = []
783 find abc23
784 assert_equal(['abc23', false], g:LocalFindFuncArgs)
785 bw!
786 END
787 call v9.CheckScriptSuccess(lines)
788
789 " setting 'findfunc' to a script local function outside of a script context
790 " should fail
791 let cleanup =<< trim END
792 call writefile([execute('messages')], 'Xtest.out')
793 qall
794 END
795 call writefile(cleanup, 'Xverify.vim', 'D')
796 call RunVim([], [], "-c \"set findfunc=s:abc\" -S Xverify.vim")
797 call assert_match('E81: Using <SID> not in a', readfile('Xtest.out')[0])
798 call delete('Xtest.out')
799
800 " cleanup
801 set findfunc&
802 delfunc FindFunc1
803 delfunc FindFunc2
804 unlet g:FindFunc1Args g:FindFunc2Args
805 %bw!
806endfunc
807
808
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200809" vim: shiftwidth=2 sts=2 expandtab