blob: 4db5850fe6c27558d31d79273d77c3f18f469f59 [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
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100362 " Function that doesn't any argument
363 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
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100482 set findfunc=
483 delfunc s:FindFuncScript
Yegappan Lakshmananaeb1c972024-10-22 23:42:20 +0200484endfunc
485
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100486" Test for expanding the argument to the :find command using 'findfunc'
487func Test_findfunc_expand_arg()
488 let s:fnames = ['Xfindfunc1.c', 'Xfindfunc2.c', 'Xfindfunc3.c']
zeertzjq20e045f2024-10-28 22:05:26 +0100489
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100490 " 'findfunc' that accepts a regular expression
491 func FindFuncRegexp(pat, cmdcomplete)
492 return s:fnames->copy()->filter('v:val =~? a:pat')
Yegappan Lakshmanan2f6efac2024-10-23 21:06:10 +0200493 endfunc
Yegappan Lakshmanan2f6efac2024-10-23 21:06:10 +0200494
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100495 " 'findfunc' that accepts a glob
496 func FindFuncGlob(pat_arg, cmdcomplete)
497 let pat = glob2regpat(a:cmdcomplete ? $'*{a:pat_arg}*' : a:pat_arg)
zeertzjq20e045f2024-10-28 22:05:26 +0100498 return s:fnames->copy()->filter('v:val =~? pat')
499 endfunc
Yegappan Lakshmanan2f6efac2024-10-23 21:06:10 +0200500
zeertzjq20e045f2024-10-28 22:05:26 +0100501 for regexp in [v:true, v:false]
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100502 let &findfunc = regexp ? 'FindFuncRegexp' : 'FindFuncGlob'
Yegappan Lakshmanan2f6efac2024-10-23 21:06:10 +0200503
zeertzjq20e045f2024-10-28 22:05:26 +0100504 call feedkeys(":find \<Tab>\<C-B>\"\<CR>", "xt")
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100505 call assert_equal('"find Xfindfunc1.c', @:)
Yegappan Lakshmanan2f6efac2024-10-23 21:06:10 +0200506
zeertzjq20e045f2024-10-28 22:05:26 +0100507 call feedkeys(":find Xfind\<Tab>\<Tab>\<C-B>\"\<CR>", "xt")
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100508 call assert_equal('"find Xfindfunc2.c', @:)
Yegappan Lakshmanan2f6efac2024-10-23 21:06:10 +0200509
zeertzjq20e045f2024-10-28 22:05:26 +0100510 call assert_equal(s:fnames, getcompletion('find ', 'cmdline'))
511 call assert_equal(s:fnames, getcompletion('find Xfind', 'cmdline'))
512
513 let pat = regexp ? 'X.*1\.c' : 'X*1.c'
514 call feedkeys($":find {pat}\<Tab>\<C-B>\"\<CR>", "xt")
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100515 call assert_equal('"find Xfindfunc1.c', @:)
516 call assert_equal(['Xfindfunc1.c'], getcompletion($'find {pat}', 'cmdline'))
zeertzjq20e045f2024-10-28 22:05:26 +0100517
518 call feedkeys(":find 3\<Tab>\<C-B>\"\<CR>", "xt")
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100519 call assert_equal('"find Xfindfunc3.c', @:)
520 call assert_equal(['Xfindfunc3.c'], getcompletion($'find 3', 'cmdline'))
zeertzjq20e045f2024-10-28 22:05:26 +0100521
522 call feedkeys(":find Xfind\<C-A>\<C-B>\"\<CR>", "xt")
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100523 call assert_equal('"find Xfindfunc1.c Xfindfunc2.c Xfindfunc3.c', @:)
zeertzjq20e045f2024-10-28 22:05:26 +0100524
525 call feedkeys(":find abc\<Tab>\<C-B>\"\<CR>", "xt")
526 call assert_equal('"find abc', @:)
527 call assert_equal([], getcompletion('find abc', 'cmdline'))
528 endfor
Yegappan Lakshmanan2f6efac2024-10-23 21:06:10 +0200529
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100530 set findfunc&
531 delfunc! FindFuncRegexp
532 delfunc! FindFuncGlob
zeertzjq20e045f2024-10-28 22:05:26 +0100533 unlet s:fnames
Yegappan Lakshmanan2f6efac2024-10-23 21:06:10 +0200534endfunc
535
Yegappan Lakshmanana13f3a42024-11-02 18:40:10 +0100536" Test for different ways of setting the 'findfunc' option
537func Test_findfunc_callback()
538 new
539 func FindFunc1(pat, cmdexpand)
540 let g:FindFunc1Args = [a:pat, a:cmdexpand]
541 return ['findfunc1']
542 endfunc
543
544 let lines =<< trim END
545 #" Test for using a function name
546 LET &findfunc = 'g:FindFunc1'
547 LET g:FindFunc1Args = []
548 find abc1
549 call assert_equal(['abc1', v:false], g:FindFunc1Args)
550
551 #" Test for using a function()
552 set findfunc=function('g:FindFunc1')
553 LET g:FindFunc1Args = []
554 find abc2
555 call assert_equal(['abc2', v:false], g:FindFunc1Args)
556
557 #" Using a funcref variable to set 'findfunc'
558 VAR Fn = function('g:FindFunc1')
559 LET &findfunc = Fn
560 LET g:FindFunc1Args = []
561 find abc3
562 call assert_equal(['abc3', v:false], g:FindFunc1Args)
563
564 #" Using a string(funcref_variable) to set 'findfunc'
565 LET Fn = function('g:FindFunc1')
566 LET &findfunc = string(Fn)
567 LET g:FindFunc1Args = []
568 find abc4
569 call assert_equal(['abc4', v:false], g:FindFunc1Args)
570
571 #" Test for using a funcref()
572 set findfunc=funcref('g:FindFunc1')
573 LET g:FindFunc1Args = []
574 find abc5
575 call assert_equal(['abc5', v:false], g:FindFunc1Args)
576
577 #" Using a funcref variable to set 'findfunc'
578 LET Fn = funcref('g:FindFunc1')
579 LET &findfunc = Fn
580 LET g:FindFunc1Args = []
581 find abc6
582 call assert_equal(['abc6', v:false], g:FindFunc1Args)
583
584 #" Using a string(funcref_variable) to set 'findfunc'
585 LET Fn = funcref('g:FindFunc1')
586 LET &findfunc = string(Fn)
587 LET g:FindFunc1Args = []
588 find abc7
589 call assert_equal(['abc7', v:false], g:FindFunc1Args)
590
591 #" Test for using a lambda function using set
592 VAR optval = "LSTART pat, cmdexpand LMIDDLE FindFunc1(pat, cmdexpand) LEND"
593 LET optval = substitute(optval, ' ', '\\ ', 'g')
594 exe "set findfunc=" .. optval
595 LET g:FindFunc1Args = []
596 find abc8
597 call assert_equal(['abc8', v:false], g:FindFunc1Args)
598
599 #" Test for using a lambda function using LET
600 LET &findfunc = LSTART pat, _ LMIDDLE FindFunc1(pat, v:false) LEND
601 LET g:FindFunc1Args = []
602 find abc9
603 call assert_equal(['abc9', v:false], g:FindFunc1Args)
604
605 #" Set 'findfunc' to a string(lambda expression)
606 LET &findfunc = 'LSTART pat, _ LMIDDLE FindFunc1(pat, v:false) LEND'
607 LET g:FindFunc1Args = []
608 find abc10
609 call assert_equal(['abc10', v:false], g:FindFunc1Args)
610
611 #" Set 'findfunc' to a variable with a lambda expression
612 VAR Lambda = LSTART pat, _ LMIDDLE FindFunc1(pat, v:false) LEND
613 LET &findfunc = Lambda
614 LET g:FindFunc1Args = []
615 find abc11
616 call assert_equal(['abc11', v:false], g:FindFunc1Args)
617
618 #" Set 'findfunc' to a string(variable with a lambda expression)
619 LET Lambda = LSTART pat, _ LMIDDLE FindFunc1(pat, v:false) LEND
620 LET &findfunc = string(Lambda)
621 LET g:FindFunc1Args = []
622 find abc12
623 call assert_equal(['abc12', v:false], g:FindFunc1Args)
624
625 #" Try to use 'findfunc' after the function is deleted
626 func g:TmpFindFunc(pat, cmdexpand)
627 let g:TmpFindFunc1Args = [a:pat, a:cmdexpand]
628 endfunc
629 LET &findfunc = function('g:TmpFindFunc')
630 delfunc g:TmpFindFunc
631 call test_garbagecollect_now()
632 LET g:TmpFindFunc1Args = []
633 call assert_fails('find abc13', 'E117:')
634 call assert_equal([], g:TmpFindFunc1Args)
635
636 #" Try to use a function with three arguments for 'findfunc'
637 func g:TmpFindFunc2(x, y, z)
638 let g:TmpFindFunc2Args = [a:x, a:y, a:z]
639 endfunc
640 set findfunc=TmpFindFunc2
641 LET g:TmpFindFunc2Args = []
642 call assert_fails('find abc14', 'E119:')
643 call assert_equal([], g:TmpFindFunc2Args)
644 delfunc TmpFindFunc2
645
646 #" Try to use a function with zero arguments for 'findfunc'
647 func g:TmpFindFunc3()
648 let g:TmpFindFunc3Called = v:true
649 endfunc
650 set findfunc=TmpFindFunc3
651 LET g:TmpFindFunc3Called = v:false
652 call assert_fails('find abc15', 'E118:')
653 call assert_equal(v:false, g:TmpFindFunc3Called)
654 delfunc TmpFindFunc3
655
656 #" Try to use a lambda function with three arguments for 'findfunc'
657 LET &findfunc = LSTART a, b, c LMIDDLE FindFunc1(a, v:false) LEND
658 LET g:FindFunc1Args = []
659 call assert_fails('find abc16', 'E119:')
660 call assert_equal([], g:FindFunc1Args)
661
662 #" Test for clearing the 'findfunc' option
663 set findfunc=''
664 set findfunc&
665 call assert_fails("set findfunc=function('abc')", "E700:")
666 call assert_fails("set findfunc=funcref('abc')", "E700:")
667
668 #" set 'findfunc' to a non-existing function
669 LET &findfunc = function('g:FindFunc1')
670 call assert_fails("set findfunc=function('NonExistingFunc')", 'E700:')
671 call assert_fails("LET &findfunc = function('NonExistingFunc')", 'E700:')
672 LET g:FindFunc1Args = []
673 find abc17
674 call assert_equal(['abc17', v:false], g:FindFunc1Args)
675 END
676 call v9.CheckTransLegacySuccess(lines)
677
678 " Test for using a script-local function name
679 func s:FindFunc2(pat, cmdexpand)
680 let g:FindFunc2Args = [a:pat, a:cmdexpand]
681 return ['findfunc2']
682 endfunc
683 set findfunc=s:FindFunc2
684 let g:FindFunc2Args = []
685 find abc18
686 call assert_equal(['abc18', v:false], g:FindFunc2Args)
687
688 let &findfunc = 's:FindFunc2'
689 let g:FindFunc2Args = []
690 find abc19
691 call assert_equal(['abc19', v:false], g:FindFunc2Args)
692 delfunc s:FindFunc2
693
694 " Using Vim9 lambda expression in legacy context should fail
695 set findfunc=(pat,\ cmdexpand)\ =>\ FindFunc1(pat,\ v:false)
696 let g:FindFunc1Args = []
697 call assert_fails('find abc20', 'E117:')
698 call assert_equal([], g:FindFunc1Args)
699
700 " set 'findfunc' to a partial with dict.
701 func SetFindFunc()
702 let operator = {'execute': function('FindFuncExecute')}
703 let &findfunc = operator.execute
704 endfunc
705 func FindFuncExecute(pat, cmdexpand) dict
706 return ['findfuncexecute']
707 endfunc
708 call SetFindFunc()
709 call test_garbagecollect_now()
710 set findfunc=
711 delfunc SetFindFunc
712 delfunc FindFuncExecute
713
714 func FindFunc2(pat, cmdexpand)
715 let g:FindFunc2Args = [a:pat, a:cmdexpand]
716 return ['findfunc2']
717 endfunc
718
719 " Vim9 tests
720 let lines =<< trim END
721 vim9script
722
723 def g:Vim9findFunc(pat: string, cmdexpand: bool): list<string>
724 g:FindFunc1Args = [pat, cmdexpand]
725 return ['vim9findfunc']
726 enddef
727
728 # Test for using a def function with findfunc
729 set findfunc=function('g:Vim9findFunc')
730 g:FindFunc1Args = []
731 find abc21
732 assert_equal(['abc21', false], g:FindFunc1Args)
733
734 # Test for using a global function name
735 &findfunc = g:FindFunc2
736 g:FindFunc2Args = []
737 find abc22
738 assert_equal(['abc22', false], g:FindFunc2Args)
739 bw!
740
741 # Test for using a script-local function name
742 def LocalFindFunc(pat: string, cmdexpand: bool): list<string>
743 g:LocalFindFuncArgs = [pat, cmdexpand]
744 return ['localfindfunc']
745 enddef
746 &findfunc = LocalFindFunc
747 g:LocalFindFuncArgs = []
748 find abc23
749 assert_equal(['abc23', false], g:LocalFindFuncArgs)
750 bw!
751 END
752 call v9.CheckScriptSuccess(lines)
753
754 " setting 'findfunc' to a script local function outside of a script context
755 " should fail
756 let cleanup =<< trim END
757 call writefile([execute('messages')], 'Xtest.out')
758 qall
759 END
760 call writefile(cleanup, 'Xverify.vim', 'D')
761 call RunVim([], [], "-c \"set findfunc=s:abc\" -S Xverify.vim")
762 call assert_match('E81: Using <SID> not in a', readfile('Xtest.out')[0])
763 call delete('Xtest.out')
764
765 " cleanup
766 set findfunc&
767 delfunc FindFunc1
768 delfunc FindFunc2
769 unlet g:FindFunc1Args g:FindFunc2Args
770 %bw!
771endfunc
772
773
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200774" vim: shiftwidth=2 sts=2 expandtab