blob: 90e81c1eb441b6f6c27be48c16308b3c4d46bb3f [file] [log] [blame]
Bram Moolenaard8448622022-01-07 21:39:52 +00001" Test import/export of the Vim9 script language.
Bram Moolenaar160aa862022-01-10 21:29:57 +00002" Also the autoload mechanism.
Bram Moolenaard8448622022-01-07 21:39:52 +00003
4source check.vim
5source term_util.vim
Bram Moolenaar62aec932022-01-29 21:45:34 +00006import './vim9.vim' as v9
Bram Moolenaard8448622022-01-07 21:39:52 +00007
8let s:export_script_lines =<< trim END
9 vim9script
10 var name: string = 'bob'
11 def Concat(arg: string): string
12 return name .. arg
13 enddef
14 g:result = Concat('bie')
15 g:localname = name
16
17 export const CONST = 1234
18 export var exported = 9876
19 export var exp_name = 'John'
20 export def Exported(): string
21 return 'Exported'
22 enddef
23 export def ExportedValue(): number
24 return exported
25 enddef
26 export def ExportedInc()
27 exported += 5
28 enddef
29 export final theList = [1]
Bram Moolenaar857c8bb2022-01-15 21:08:19 +000030 export def AddSome(s: string): string
31 return s .. 'some'
32 enddef
33 export var AddRef = AddSome
Bram Moolenaard8448622022-01-07 21:39:52 +000034END
35
Bram Moolenaar62aec932022-01-29 21:45:34 +000036def s:Undo_export_script_lines()
Bram Moolenaard8448622022-01-07 21:39:52 +000037 unlet g:result
38 unlet g:localname
39enddef
40
41def Test_vim9_import_export()
42 writefile(s:export_script_lines, 'Xexport.vim')
43 var import_script_lines =<< trim END
44 vim9script
45 var dir = './'
46 var ext = ".vim"
47 import dir .. 'Xexport' .. ext as expo
48
49 g:exported1 = expo.exported
50 expo.exported += 3
51 g:exported2 = expo.exported
52 g:exported3 = expo.ExportedValue()
53
54 expo.ExportedInc()
55 g:exported_i1 = expo.exported
56 g:exported_i2 = expo.ExportedValue()
57
58 expo.exported = 11
59 g:exported_s1 = expo.exported
60 g:exported_s2 = expo.ExportedValue()
61
62 g:imported_func = expo.Exported()
63
64 def GetExported(): string
65 var local_dict = {ref: expo.Exported}
66 return local_dict.ref()
67 enddef
68 g:funcref_result = GetExported()
69
Bram Moolenaar21f0d6c2022-01-20 17:35:49 +000070 def GetName(): string
71 return expo.exp_name .. 'son'
72 enddef
73 g:long_name = GetName()
74
Bram Moolenaard8448622022-01-07 21:39:52 +000075 g:imported_name = expo.exp_name
76 expo.exp_name ..= ' Doe'
Bram Moolenaar47036b62022-01-16 21:18:53 +000077 expo.exp_name = expo.exp_name .. ' Maar'
Bram Moolenaard8448622022-01-07 21:39:52 +000078 g:imported_name_appended = expo.exp_name
79 g:exported_later = expo.exported
80
81 expo.theList->add(2)
82 assert_equal([1, 2], expo.theList)
Bram Moolenaar857c8bb2022-01-15 21:08:19 +000083
84 assert_equal('andthensome', 'andthen'->expo.AddSome())
85 assert_equal('awesome', 'awe'->expo.AddRef())
Bram Moolenaard8448622022-01-07 21:39:52 +000086 END
87 writefile(import_script_lines, 'Ximport.vim')
88 source Ximport.vim
89
90 assert_equal('bobbie', g:result)
91 assert_equal('bob', g:localname)
92 assert_equal(9876, g:exported1)
93 assert_equal(9879, g:exported2)
94 assert_equal(9879, g:exported3)
95
96 assert_equal(9884, g:exported_i1)
97 assert_equal(9884, g:exported_i2)
98
99 assert_equal(11, g:exported_s1)
100 assert_equal(11, g:exported_s2)
101 assert_equal(11, g:exported_later)
102
103 assert_equal('Exported', g:imported_func)
104 assert_equal('Exported', g:funcref_result)
105 assert_equal('John', g:imported_name)
Bram Moolenaar21f0d6c2022-01-20 17:35:49 +0000106 assert_equal('Johnson', g:long_name)
Bram Moolenaar47036b62022-01-16 21:18:53 +0000107 assert_equal('John Doe Maar', g:imported_name_appended)
Bram Moolenaard8448622022-01-07 21:39:52 +0000108 assert_false(exists('g:name'))
109
110 Undo_export_script_lines()
111 unlet g:exported1
112 unlet g:exported2
113 unlet g:exported3
114 unlet g:exported_i1
115 unlet g:exported_i2
116 unlet g:exported_later
117 unlet g:imported_func
Bram Moolenaar21f0d6c2022-01-20 17:35:49 +0000118 unlet g:imported_name g:long_name g:imported_name_appended
Bram Moolenaard8448622022-01-07 21:39:52 +0000119 delete('Ximport.vim')
120
121 # similar, with line breaks
122 var import_line_break_script_lines =<< trim END
123 vim9script
124 import './Xexport.vim'
125 as expo
126 g:exported = expo.exported
127 expo.exported += 7
128 g:exported_added = expo.exported
129 g:imported_func = expo.Exported()
130 END
131 writefile(import_line_break_script_lines, 'Ximport_lbr.vim')
132 source Ximport_lbr.vim
133
134 assert_equal(11, g:exported)
135 assert_equal(18, g:exported_added)
136 assert_equal('Exported', g:imported_func)
137
138 # exported script not sourced again
139 assert_false(exists('g:result'))
140 unlet g:exported
141 unlet g:exported_added
142 unlet g:imported_func
143 delete('Ximport_lbr.vim')
144
Bram Moolenaar68854a82022-01-31 18:59:13 +0000145 var import_shadows_cmdmod_lines =<< trim END
146 vim9script
147 import './Xexport.vim' as vim9
148 vim9.exp_name = 'Shadow'
149 assert_equal('Shadow', vim9.exp_name)
150 END
151 v9.CheckScriptSuccess(import_shadows_cmdmod_lines)
152
Bram Moolenaard8448622022-01-07 21:39:52 +0000153 var line_break_before_dot =<< trim END
154 vim9script
155 import './Xexport.vim' as expo
156 g:exported = expo
157 .exported
158 END
159 writefile(line_break_before_dot, 'Ximport_lbr_before_dot.vim')
160 assert_fails('source Ximport_lbr_before_dot.vim', 'E1060:', '', 3)
161 delete('Ximport_lbr_before_dot.vim')
162
163 var line_break_after_dot =<< trim END
164 vim9script
165 import './Xexport.vim' as expo
166 g:exported = expo.
167 exported
168 END
169 writefile(line_break_after_dot, 'Ximport_lbr_after_dot.vim')
170 assert_fails('source Ximport_lbr_after_dot.vim', 'E1074:', '', 3)
171 delete('Ximport_lbr_after_dot.vim')
172
173 var import_star_as_lines =<< trim END
174 vim9script
175 import './Xexport.vim' as Export
176 def UseExport()
177 g:exported_def = Export.exported
178 enddef
179 g:exported_script = Export.exported
180 assert_equal(1, exists('Export.exported'))
181 assert_equal(0, exists('Export.notexported'))
182 UseExport()
183 END
184 writefile(import_star_as_lines, 'Ximport.vim')
185 source Ximport.vim
186
187 assert_equal(18, g:exported_def)
188 assert_equal(18, g:exported_script)
189 unlet g:exported_def
190 unlet g:exported_script
191
192 var import_star_as_lines_no_dot =<< trim END
193 vim9script
194 import './Xexport.vim' as Export
195 def Func()
196 var dummy = 1
197 var imported = Export + dummy
198 enddef
199 defcompile
200 END
201 writefile(import_star_as_lines_no_dot, 'Ximport.vim')
202 assert_fails('source Ximport.vim', 'E1060:', '', 2, 'Func')
203
204 var import_star_as_lines_dot_space =<< trim END
205 vim9script
206 import './Xexport.vim' as Export
207 def Func()
208 var imported = Export . exported
209 enddef
210 defcompile
211 END
212 writefile(import_star_as_lines_dot_space, 'Ximport.vim')
213 assert_fails('source Ximport.vim', 'E1074:', '', 1, 'Func')
214
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000215 writefile(s:export_script_lines, 'Xexport2.vim')
216 var import_as_duplicated =<< trim END
Bram Moolenaard8448622022-01-07 21:39:52 +0000217 vim9script
218 import './Xexport.vim' as expo
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000219 import './Xexport2.vim' as expo
Bram Moolenaard8448622022-01-07 21:39:52 +0000220 END
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000221 writefile(import_as_duplicated, 'Ximport.vim')
Bram Moolenaard8448622022-01-07 21:39:52 +0000222 assert_fails('source Ximport.vim', 'E1073:', '', 3, 'Ximport.vim')
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000223 delete('Xexport2.vim')
Bram Moolenaard8448622022-01-07 21:39:52 +0000224
225 var import_star_as_lines_script_no_dot =<< trim END
226 vim9script
227 import './Xexport.vim' as Export
228 g:imported_script = Export exported
229 END
230 writefile(import_star_as_lines_script_no_dot, 'Ximport.vim')
231 assert_fails('source Ximport.vim', 'E1060: Expected dot after name: Export exported')
232
233 var import_star_as_lines_script_space_after_dot =<< trim END
234 vim9script
235 import './Xexport.vim' as Export
236 g:imported_script = Export. exported
237 END
238 writefile(import_star_as_lines_script_space_after_dot, 'Ximport.vim')
239 assert_fails('source Ximport.vim', 'E1074:')
240
241 var import_star_as_lines_missing_name =<< trim END
242 vim9script
243 import './Xexport.vim' as Export
244 def Func()
245 var imported = Export.
246 enddef
247 defcompile
248 END
249 writefile(import_star_as_lines_missing_name, 'Ximport.vim')
250 assert_fails('source Ximport.vim', 'E1048:', '', 1, 'Func')
251
252 var import_star_as_lbr_lines =<< trim END
253 vim9script
254 import './Xexport.vim'
255 as Export
256 def UseExport()
257 g:exported = Export.exported
258 enddef
259 UseExport()
260 END
261 writefile(import_star_as_lbr_lines, 'Ximport.vim')
262 source Ximport.vim
263 assert_equal(18, g:exported)
264 unlet g:exported
265
266 # try to use something that exists but is not exported
267 var import_not_exported_lines =<< trim END
268 vim9script
269 import './Xexport.vim' as expo
270 echo expo.name
271 END
272 writefile(import_not_exported_lines, 'Ximport.vim')
273 assert_fails('source Ximport.vim', 'E1049:', '', 3, 'Ximport.vim')
274
275 # try to import something that is already defined
276 var import_already_defined =<< trim END
277 vim9script
278 var exported = 'something'
279 import './Xexport.vim' as exported
280 END
281 writefile(import_already_defined, 'Ximport.vim')
282 assert_fails('source Ximport.vim', 'E1054:', '', 3, 'Ximport.vim')
283
284 # try changing an imported const
285 var import_assign_to_const =<< trim END
286 vim9script
287 import './Xexport.vim' as expo
288 def Assign()
289 expo.CONST = 987
290 enddef
291 defcompile
292 END
293 writefile(import_assign_to_const, 'Ximport.vim')
294 assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign')
295
296 # try changing an imported final
297 var import_assign_to_final =<< trim END
298 vim9script
299 import './Xexport.vim' as expo
300 def Assign()
301 expo.theList = [2]
302 enddef
303 defcompile
304 END
305 writefile(import_assign_to_final, 'Ximport.vim')
306 assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign')
307
308 var import_no_as_lines =<< trim END
309 vim9script
310 import './Xexport.vim' name
311 END
312 writefile(import_no_as_lines, 'Ximport.vim')
313 assert_fails('source Ximport.vim', 'E488:', '', 2, 'Ximport.vim')
314
315 var import_invalid_string_lines =<< trim END
316 vim9script
317 import Xexport.vim
318 END
319 writefile(import_invalid_string_lines, 'Ximport.vim')
320 assert_fails('source Ximport.vim', 'E121:', '', 2, 'Ximport.vim')
321
322 var import_wrong_name_lines =<< trim END
323 vim9script
324 import './XnoExport.vim'
325 END
326 writefile(import_wrong_name_lines, 'Ximport.vim')
327 assert_fails('source Ximport.vim', 'E1053:', '', 2, 'Ximport.vim')
328
329 var import_redefining_lines =<< trim END
330 vim9script
331 import './Xexport.vim' as exported
332 var exported = 5
333 END
334 writefile(import_redefining_lines, 'Ximport.vim')
335 assert_fails('source Ximport.vim', 'E1213: Redefining imported item "exported"', '', 3)
336
Bram Moolenaar160aa862022-01-10 21:29:57 +0000337 var import_missing_dot_lines =<< trim END
338 vim9script
339 import './Xexport.vim' as expo
340 def Test()
341 expo = 9
342 enddef
343 defcompile
344 END
345 writefile(import_missing_dot_lines, 'Ximport.vim')
346 assert_fails('source Ximport.vim', 'E1258:', '', 1)
347
348 var import_missing_name_lines =<< trim END
349 vim9script
350 import './Xexport.vim' as expo
351 def Test()
352 expo.99 = 9
353 enddef
354 defcompile
355 END
356 writefile(import_missing_name_lines, 'Ximport.vim')
Bram Moolenaar76283822022-01-10 21:39:03 +0000357 assert_fails('source Ximport.vim', 'E1259:', '', 1)
Bram Moolenaar160aa862022-01-10 21:29:57 +0000358
Bram Moolenaard8448622022-01-07 21:39:52 +0000359 var import_assign_wrong_type_lines =<< trim END
360 vim9script
361 import './Xexport.vim' as expo
362 expo.exported = 'xxx'
363 END
364 writefile(import_assign_wrong_type_lines, 'Ximport.vim')
365 assert_fails('source Ximport.vim', 'E1012: Type mismatch; expected number but got string', '', 3)
366
367 var import_assign_const_lines =<< trim END
368 vim9script
369 import './Xexport.vim' as expo
370 expo.CONST = 4321
371 END
372 writefile(import_assign_const_lines, 'Ximport.vim')
373 assert_fails('source Ximport.vim', 'E46: Cannot change read-only variable "CONST"', '', 3)
374
375 delete('Ximport.vim')
Bram Moolenaard8448622022-01-07 21:39:52 +0000376 delete('Xexport.vim')
377
378 # Check that in a Vim9 script 'cpo' is set to the Vim default.
379 # Flags added or removed are also applied to the restored value.
380 set cpo=abcd
381 var lines =<< trim END
382 vim9script
383 g:cpo_in_vim9script = &cpo
384 set cpo+=f
385 set cpo-=c
386 g:cpo_after_vim9script = &cpo
387 END
388 writefile(lines, 'Xvim9_script')
389 source Xvim9_script
390 assert_equal('fabd', &cpo)
391 set cpo&vim
392 assert_equal(&cpo, g:cpo_in_vim9script)
393 var newcpo = substitute(&cpo, 'c', '', '') .. 'f'
394 assert_equal(newcpo, g:cpo_after_vim9script)
395
396 delete('Xvim9_script')
397enddef
398
399def Test_import_funcref()
400 var lines =<< trim END
401 vim9script
402 export def F(): number
403 return 42
404 enddef
405 export const G = F
406 END
407 writefile(lines, 'Xlib.vim')
408
409 lines =<< trim END
410 vim9script
411 import './Xlib.vim' as lib
412 const Foo = lib.G()
413 assert_equal(42, Foo)
414
415 def DoTest()
416 const Goo = lib.G()
417 assert_equal(42, Goo)
418 enddef
419 DoTest()
420 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000421 v9.CheckScriptSuccess(lines)
Bram Moolenaard8448622022-01-07 21:39:52 +0000422
423 delete('Xlib.vim')
424enddef
425
426def Test_import_fails()
427 writefile([], 'Xfoo.vim')
428 var lines =<< trim END
429 import './Xfoo.vim' as foo
430 foo = 'bar'
431 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000432 v9.CheckDefAndScriptFailure(lines, ['E1094:', 'E1236: Cannot use foo itself'])
Bram Moolenaard8448622022-01-07 21:39:52 +0000433 lines =<< trim END
434 vim9script
435 import './Xfoo.vim' as foo
436 var that = foo
437 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000438 v9.CheckScriptFailure(lines, 'E1060: Expected dot after name: foo')
Bram Moolenaardd5893b2022-01-20 21:32:54 +0000439 lines =<< trim END
440 vim9script
441 import './Xfoo.vim' as foo
442 var that: any
443 that += foo
444 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000445 v9.CheckScriptFailure(lines, 'E1060: Expected dot after name: foo')
Bram Moolenaardd5893b2022-01-20 21:32:54 +0000446 lines =<< trim END
447 vim9script
448 import './Xfoo.vim' as foo
449 foo += 9
450 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000451 v9.CheckScriptFailure(lines, 'E1060: Expected dot after name: foo')
Bram Moolenaard8448622022-01-07 21:39:52 +0000452
453 lines =<< trim END
454 vim9script
455 import './Xfoo.vim' as 9foo
456 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000457 v9.CheckScriptFailure(lines, 'E1047:')
Bram Moolenaard8448622022-01-07 21:39:52 +0000458 lines =<< trim END
459 vim9script
460 import './Xfoo.vim' as the#foo
461 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000462 v9.CheckScriptFailure(lines, 'E1047:')
Bram Moolenaard8448622022-01-07 21:39:52 +0000463 lines =<< trim END
464 vim9script
465 import './Xfoo.vim' as g:foo
466 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000467 v9.CheckScriptFailure(lines, 'E1047:')
Bram Moolenaard8448622022-01-07 21:39:52 +0000468
469 delete('Xfoo.vim')
470
471 lines =<< trim END
472 vim9script
473 def TheFunc()
474 echo 'the func'
475 enddef
476 export var Ref = TheFunc
477 END
478 writefile([], 'Xthat.vim')
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000479
Bram Moolenaard8448622022-01-07 21:39:52 +0000480 lines =<< trim END
481 import './Xthat.vim' as That
482 That()
483 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000484 v9.CheckDefAndScriptFailure(lines, ['E1094:', 'E1236: Cannot use That itself'])
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000485
486 lines =<< trim END
Bram Moolenaar937610b2022-01-19 17:21:29 +0000487 vim9script
488 import './Xthat.vim' as That
489 def Func()
490 echo That()
491 enddef
492 Func()
493 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000494 v9.CheckScriptFailure(lines, 'E1236: Cannot use That itself')
Bram Moolenaar937610b2022-01-19 17:21:29 +0000495
496 lines =<< trim END
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000497 import './Xthat.vim' as one
498 import './Xthat.vim' as two
499 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000500 v9.CheckScriptFailure(lines, 'E1262:')
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000501
502 delete('Xthat.vim')
Bram Moolenaar779aeff2022-02-08 19:12:19 +0000503
504 lines =<< trim END
505 vim9script
506 export var item = 'hello'
507 import './Xyourself.vim'
508 END
509 writefile(lines, 'Xyourself.vim')
510 assert_fails('source Xyourself.vim', 'E1088:')
511 delete('Xyourself.vim')
512
Bram Moolenaard8448622022-01-07 21:39:52 +0000513 mkdir('Ximport')
514
515 writefile(['vim9script'], 'Ximport/.vim')
516 lines =<< trim END
517 vim9script
518 import './Ximport/.vim'
519 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000520 v9.CheckScriptFailure(lines, 'E1261: Cannot import .vim without using "as"')
Bram Moolenaard8448622022-01-07 21:39:52 +0000521 lines =<< trim END
522 vim9script
523 import './Ximport/.vim' as vim
524 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000525 v9.CheckScriptSuccess(lines)
Bram Moolenaard8448622022-01-07 21:39:52 +0000526
527 writefile(['vim9script'], 'Ximport/.vimrc')
528 lines =<< trim END
529 vim9script
530 import './Ximport/.vimrc'
531 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000532 v9.CheckScriptFailure(lines, 'E1257: Imported script must use "as" or end in .vim')
Bram Moolenaard8448622022-01-07 21:39:52 +0000533 lines =<< trim END
534 vim9script
535 import './Ximport/.vimrc' as vimrc
536 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000537 v9.CheckScriptSuccess(lines)
Bram Moolenaard8448622022-01-07 21:39:52 +0000538
539 delete('Ximport', 'rf')
540enddef
541
542func g:Trigger()
543 source Ximport.vim
544 return "echo 'yes'\<CR>"
545endfunc
546
547def Test_import_export_expr_map()
548 # check that :import and :export work when buffer is locked
549 var export_lines =<< trim END
550 vim9script
551 export def That(): string
552 return 'yes'
553 enddef
554 END
555 writefile(export_lines, 'Xexport_that.vim')
556
557 var import_lines =<< trim END
558 vim9script
559 import './Xexport_that.vim' as that
560 assert_equal('yes', that.That())
561 END
562 writefile(import_lines, 'Ximport.vim')
563
564 nnoremap <expr> trigger g:Trigger()
565 feedkeys('trigger', "xt")
566
567 delete('Xexport_that.vim')
568 delete('Ximport.vim')
569 nunmap trigger
570enddef
571
572def Test_import_in_filetype()
573 # check that :import works when the buffer is locked
574 mkdir('ftplugin', 'p')
575 var export_lines =<< trim END
576 vim9script
577 export var That = 'yes'
578 END
579 writefile(export_lines, 'ftplugin/Xexport_ft.vim')
580
581 var import_lines =<< trim END
582 vim9script
583 import './Xexport_ft.vim' as ft
584 assert_equal('yes', ft.That)
585 g:did_load_mytpe = 1
586 END
587 writefile(import_lines, 'ftplugin/qf.vim')
588
589 var save_rtp = &rtp
590 &rtp = getcwd() .. ',' .. &rtp
591
592 filetype plugin on
593 copen
594 assert_equal(1, g:did_load_mytpe)
595
596 quit!
597 delete('Xexport_ft.vim')
598 delete('ftplugin', 'rf')
599 &rtp = save_rtp
600enddef
601
602def Test_use_import_in_mapping()
603 var lines =<< trim END
604 vim9script
605 export def Funcx()
606 g:result = 42
607 enddef
608 END
609 writefile(lines, 'XsomeExport.vim')
610 lines =<< trim END
611 vim9script
612 import './XsomeExport.vim' as some
613 var Funcy = some.Funcx
614 nnoremap <F3> :call <sid>Funcy()<cr>
615 END
616 writefile(lines, 'Xmapscript.vim')
617
618 source Xmapscript.vim
619 feedkeys("\<F3>", "xt")
620 assert_equal(42, g:result)
621
622 unlet g:result
623 delete('XsomeExport.vim')
624 delete('Xmapscript.vim')
625 nunmap <F3>
626enddef
627
Bram Moolenaarf0e7e632022-01-21 13:29:56 +0000628def Test_use_import_in_command_completion()
Bram Moolenaar15d16352022-01-17 20:09:08 +0000629 var lines =<< trim END
630 vim9script
631 export def Complete(..._): list<string>
632 return ['abcd']
633 enddef
634 END
635 writefile(lines, 'Xscript.vim')
636
637 lines =<< trim END
638 vim9script
639 import './Xscript.vim'
640
641 command -nargs=1 -complete=customlist,Xscript.Complete Cmd echo 'ok'
642 feedkeys(":Cmd ab\<Tab>\<C-B>#\<CR>", 'xnt')
643 assert_equal('#Cmd abcd', @:)
644 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000645 v9.CheckScriptSuccess(lines)
Bram Moolenaar15d16352022-01-17 20:09:08 +0000646
647 delcommand Cmd
648 delete('Xscript.vim')
649enddef
650
Bram Moolenaarf0e7e632022-01-21 13:29:56 +0000651def Test_use_autoload_import_in_insert_completion()
652 mkdir('Xdir/autoload', 'p')
653 var save_rtp = &rtp
654 exe 'set rtp^=' .. getcwd() .. '/Xdir'
655
656 var lines =<< trim END
657 vim9script
658 export def ThesaurusFunc(findbase: bool, _): any
659 if findbase
660 return 1
661 endif
662 return [
663 'check',
664 'experiment',
665 'test',
666 'verification'
667 ]
668 enddef
669 g:completion_loaded = 'yes'
670 END
671 writefile(lines, 'Xdir/autoload/completion.vim')
672
673 new
674 lines =<< trim END
675 vim9script
676 g:completion_loaded = 'no'
677 import autoload 'completion.vim'
678 set thesaurusfunc=completion.ThesaurusFunc
679 assert_equal('no', g:completion_loaded)
680 feedkeys("i\<C-X>\<C-T>\<C-N>\<Esc>", 'xt')
681 assert_equal('experiment', getline(1))
682 assert_equal('yes', g:completion_loaded)
683 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000684 v9.CheckScriptSuccess(lines)
Bram Moolenaarf0e7e632022-01-21 13:29:56 +0000685
686 set thesaurusfunc=
687 bwipe!
688 delete('Xdir', 'rf')
689 &rtp = save_rtp
690enddef
691
Bram Moolenaar3e93a2b2022-01-24 21:28:01 +0000692def Test_use_autoload_import_partial_in_opfunc()
693 mkdir('Xdir/autoload', 'p')
694 var save_rtp = &rtp
695 exe 'set rtp^=' .. getcwd() .. '/Xdir'
696
697 var lines =<< trim END
698 vim9script
699 export def Opfunc(..._)
700 g:opfunc_called = 'yes'
701 enddef
702 END
703 writefile(lines, 'Xdir/autoload/opfunc.vim')
704
705 new
706 lines =<< trim END
707 vim9script
708 import autoload 'opfunc.vim'
709 nnoremap <expr> <F3> TheFunc()
710 def TheFunc(): string
711 &operatorfunc = function('opfunc.Opfunc', [0])
712 return 'g@'
713 enddef
714 feedkeys("\<F3>l", 'xt')
715 assert_equal('yes', g:opfunc_called)
716 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000717 v9.CheckScriptSuccess(lines)
Bram Moolenaar3e93a2b2022-01-24 21:28:01 +0000718
719 set opfunc=
720 bwipe!
721 delete('Xdir', 'rf')
Bram Moolenaar06b77222022-01-25 15:51:56 +0000722 nunmap <F3>
723 &rtp = save_rtp
724enddef
725
726def Test_set_opfunc_to_autoload_func_directly()
727 mkdir('Xdir/autoload', 'p')
728 var save_rtp = &rtp
729 exe 'set rtp^=' .. getcwd() .. '/Xdir'
730
731 var lines =<< trim END
732 vim9script
733 export def Opfunc(..._)
734 g:opfunc_called = 'yes'
735 enddef
736 END
737 writefile(lines, 'Xdir/autoload/opfunc.vim')
738
739 new
740 lines =<< trim END
741 vim9script
742 import autoload 'opfunc.vim'
743 nnoremap <expr> <F3> TheFunc()
744 def TheFunc(): string
745 &operatorfunc = opfunc.Opfunc
746 return 'g@'
747 enddef
748 feedkeys("\<F3>l", 'xt')
749 assert_equal('yes', g:opfunc_called)
750 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000751 v9.CheckScriptSuccess(lines)
Bram Moolenaar06b77222022-01-25 15:51:56 +0000752
753 set opfunc=
754 bwipe!
755 delete('Xdir', 'rf')
756 nunmap <F3>
Bram Moolenaar3e93a2b2022-01-24 21:28:01 +0000757 &rtp = save_rtp
758enddef
759
Bram Moolenaare70dd112022-01-21 16:31:11 +0000760def Test_use_autoload_import_in_fold_expression()
761 mkdir('Xdir/autoload', 'p')
762 var save_rtp = &rtp
763 exe 'set rtp^=' .. getcwd() .. '/Xdir'
764
765 var lines =<< trim END
766 vim9script
767 export def Expr(): string
768 return getline(v:lnum) =~ '^#' ? '>1' : '1'
769 enddef
Bram Moolenaar9530b582022-01-22 13:39:08 +0000770 export def Text(): string
771 return 'fold text'
772 enddef
Bram Moolenaare70dd112022-01-21 16:31:11 +0000773 g:fold_loaded = 'yes'
774 END
775 writefile(lines, 'Xdir/autoload/fold.vim')
776
777 lines =<< trim END
778 vim9script
779 import autoload 'fold.vim'
780 &foldexpr = 'fold.Expr()'
Bram Moolenaar9530b582022-01-22 13:39:08 +0000781 &foldtext = 'fold.Text()'
Bram Moolenaare70dd112022-01-21 16:31:11 +0000782 &foldmethod = 'expr'
783 &debug = 'throw'
784 END
785 new
786 setline(1, ['# one', 'text', '# two', 'text'])
787 g:fold_loaded = 'no'
Bram Moolenaar62aec932022-01-29 21:45:34 +0000788 v9.CheckScriptSuccess(lines)
Bram Moolenaare70dd112022-01-21 16:31:11 +0000789 assert_equal('no', g:fold_loaded)
790 redraw
791 assert_equal('yes', g:fold_loaded)
792
793 # Check that script context of 'foldexpr' is copied to another buffer.
794 edit! otherfile
795 redraw
796
Bram Moolenaar9530b582022-01-22 13:39:08 +0000797 set foldexpr= foldtext& foldmethod& debug=
Bram Moolenaare70dd112022-01-21 16:31:11 +0000798 bwipe!
799 delete('Xdir', 'rf')
800 &rtp = save_rtp
801enddef
802
Bram Moolenaar7b29f6a2022-01-22 17:58:13 +0000803func Test_import_in_diffexpr()
804 CheckExecutable diff
805
806 call Run_Test_import_in_diffexpr()
807endfunc
808
809def Run_Test_import_in_diffexpr()
810 var lines =<< trim END
811 vim9script
812
813 export def DiffExpr()
814 # Prepend some text to check diff type detection
815 writefile(['warning', ' message'], v:fname_out)
816 silent exe '!diff ' .. v:fname_in .. ' '
817 .. v:fname_new .. '>>' .. v:fname_out
818 enddef
819 END
820 writefile(lines, 'Xdiffexpr')
821
822 lines =<< trim END
823 vim9script
824 import './Xdiffexpr' as diff
825
826 set diffexpr=diff.DiffExpr()
827 set diffopt=foldcolumn:0
828 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000829 v9.CheckScriptSuccess(lines)
Bram Moolenaar7b29f6a2022-01-22 17:58:13 +0000830
831 enew!
832 call setline(1, ['one', 'two', 'three'])
833 diffthis
834
835 botright vert new
836 call setline(1, ['one', 'two', 'three.'])
837 diffthis
838 # we only check if this does not cause errors
839 redraw
840
841 diffoff!
842 bwipe!
843 bwipe!
Yegappan Lakshmanan7e765a32022-01-24 11:40:37 +0000844 delete('Xdiffexpr')
Bram Moolenaar7b29f6a2022-01-22 17:58:13 +0000845enddef
846
Bram Moolenaar36c2add2022-01-22 20:55:30 +0000847def Test_import_in_patchexpr()
848 var lines =<< trim END
849 vim9script
850 export def TPatch()
851 call writefile(['output file'], v:fname_out)
852 enddef
853 END
854 writefile(lines, 'Xpatchexpr')
855
856 lines =<< trim END
857 vim9script
858 import './Xpatchexpr' as patch
859 set patchexpr=patch.TPatch()
860 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000861 v9.CheckScriptSuccess(lines)
Bram Moolenaar36c2add2022-01-22 20:55:30 +0000862
863 call writefile(['input file'], 'Xinput')
864 call writefile(['diff file'], 'Xdiff')
865 :%bwipe!
866 edit Xinput
867 diffpatch Xdiff
868 call assert_equal('output file', getline(1))
869
870 call delete('Xinput')
871 call delete('Xdiff')
872 call delete('Xpatchexpr')
873 set patchexpr&
874 :%bwipe!
875enddef
876
Bram Moolenaar3ba685e2022-01-22 19:17:31 +0000877def Test_import_in_formatexpr()
878 var lines =<< trim END
879 vim9script
880 export def MyFormatExpr(): number
881 g:did_format = 'yes'
882 return 0
883 enddef
884 END
885 writefile(lines, 'Xformatter')
886
887 lines =<< trim END
888 vim9script
889 import './Xformatter' as format
890 set formatexpr=format.MyFormatExpr()
891 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000892 v9.CheckScriptSuccess(lines)
Bram Moolenaar3ba685e2022-01-22 19:17:31 +0000893
894 new
895 setline(1, ['a', 'b', 'c'])
896 normal gqG
897 assert_equal('yes', g:did_format)
898
899 bwipe!
900 delete('Xformatter')
901 unlet g:did_format
902 set formatexpr=
903enddef
904
Bram Moolenaar47bcc5f2022-01-22 20:19:22 +0000905def Test_import_in_includeexpr()
906 writefile(['found it'], 'Xthisfile')
907 new
908
909 var lines =<< trim END
910 vim9script
911 export def DoSub(): string
912 return substitute(v:fname, 'that', 'this', '')
913 enddef
914 END
915 writefile(lines, 'Xinclude.vim')
916
917 lines =<< trim END
918 vim9script
919 import './Xinclude.vim'
920 set includeexpr=Xinclude.DoSub()
921 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000922 v9.CheckScriptSuccess(lines)
Bram Moolenaar47bcc5f2022-01-22 20:19:22 +0000923
924 setline(1, ['Xthatfile'])
925 exe "normal \<C-W>f"
926 assert_equal('Xthisfile', expand('%'))
927
928 bwipe!
929 bwipe!
930 set includeexpr=
Yegappan Lakshmanan7e765a32022-01-24 11:40:37 +0000931 delete('Xinclude.vim')
Bram Moolenaar47bcc5f2022-01-22 20:19:22 +0000932 delete('Xthisfile')
933enddef
934
Bram Moolenaar28e60cc2022-01-22 20:32:00 +0000935def Test_import_in_indentexpr()
936 var lines =<< trim END
937 vim9script
938 export def GetIndent(): number
939 return 5
940 enddef
941 END
942 writefile(lines, 'Xindenter')
943
944 lines =<< trim END
945 vim9script
946 import './Xindenter' as indent
947 set indentexpr=indent.GetIndent()
948 set debug=throw
949 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000950 v9.CheckScriptSuccess(lines)
Bram Moolenaar28e60cc2022-01-22 20:32:00 +0000951
952 new
953 setline(1, 'hello')
954 normal ==
955 assert_equal(' hello', getline(1))
956
957 bwipe!
958 set indentexpr= debug=
959 delete('Xindenter')
960enddef
961
Bram Moolenaar7ef4a2f2022-01-23 13:44:35 +0000962func Test_import_in_printexpr()
963 CheckFeature postscript
964 call Run_Test_import_in_printexpr()
965endfunc
966
967def Run_Test_import_in_printexpr()
968 var lines =<< trim END
969 vim9script
970 export def PrintFile(): bool
971 g:printed = 'yes'
972 delete('v:fname_in')
973 return false
974 enddef
975 END
976 writefile(lines, 'Xprint.vim')
977
978 lines =<< trim END
979 vim9script
980 import './Xprint.vim'
981 set printexpr=Xprint.PrintFile()
982 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000983 v9.CheckScriptSuccess(lines)
Bram Moolenaar7ef4a2f2022-01-23 13:44:35 +0000984
985 help
986 hardcopy dummy args
987 assert_equal('yes', g:printed)
988
989 delete('Xprint.vim')
990 set printexpr=
991enddef
992
Bram Moolenaarf4e88f22022-01-23 14:17:28 +0000993def Test_import_in_charconvert()
994 var lines =<< trim END
995 vim9script
996 export def MakeUpper(): bool
997 var data = readfile(v:fname_in)
998 map(data, 'toupper(v:val)')
999 writefile(data, v:fname_out)
1000 return false # success
1001 enddef
1002 END
1003 writefile(lines, 'Xconvert.vim')
1004
1005 lines =<< trim END
1006 vim9script
1007 import './Xconvert.vim' as conv
1008 set charconvert=conv.MakeUpper()
1009 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001010 v9.CheckScriptSuccess(lines)
Bram Moolenaarf4e88f22022-01-23 14:17:28 +00001011
1012 writefile(['one', 'two'], 'Xfile')
1013 new Xfile
1014 write ++enc=ucase Xfile1
1015 assert_equal(['ONE', 'TWO'], readfile('Xfile1'))
1016
1017 delete('Xfile')
1018 delete('Xfile1')
1019 delete('Xconvert.vim')
1020 bwipe!
1021 set charconvert&
1022enddef
1023
Bram Moolenaar2a7aa832022-01-23 17:59:06 +00001024func Test_import_in_spellsuggest_expr()
1025 CheckFeature spell
1026 call Run_Test_import_in_spellsuggest_expr()
1027endfunc
1028
1029def Run_Test_import_in_spellsuggest_expr()
1030 var lines =<< trim END
1031 vim9script
1032 export def MySuggest(): list<any>
1033 return [['Fox', 8], ['Fop', 9]]
1034 enddef
1035 END
1036 writefile(lines, 'Xsuggest.vim')
1037
1038 lines =<< trim END
1039 vim9script
1040 import './Xsuggest.vim' as sugg
1041 set spell spellsuggest=expr:sugg.MySuggest()
1042 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001043 v9.CheckScriptSuccess(lines)
Bram Moolenaar2a7aa832022-01-23 17:59:06 +00001044
1045 set verbose=1 # report errors
1046 call assert_equal(['Fox', 'Fop'], spellsuggest('Fo', 2))
1047
1048 delete('Xsuggest.vim')
1049 set nospell spellsuggest& verbose=0
1050enddef
1051
Bram Moolenaaracc4b562022-01-24 13:54:45 +00001052def Test_export_shadows_global_function()
1053 mkdir('Xdir/autoload', 'p')
1054 var save_rtp = &rtp
1055 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1056
1057 var lines =<< trim END
1058 vim9script
1059 export def Shadow(): string
1060 return 'Shadow()'
1061 enddef
1062 END
1063 writefile(lines, 'Xdir/autoload/shadow.vim')
1064
1065 lines =<< trim END
1066 vim9script
1067
1068 def g:Shadow(): string
1069 return 'global'
1070 enddef
1071
1072 import autoload 'shadow.vim'
1073 assert_equal('Shadow()', shadow.Shadow())
1074 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001075 v9.CheckScriptSuccess(lines)
Bram Moolenaaracc4b562022-01-24 13:54:45 +00001076
1077 delfunc g:Shadow
1078 bwipe!
1079 delete('Xdir', 'rf')
1080 &rtp = save_rtp
1081enddef
1082
Bram Moolenaard8448622022-01-07 21:39:52 +00001083def Test_export_fails()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001084 v9.CheckScriptFailure(['export var some = 123'], 'E1042:')
1085 v9.CheckScriptFailure(['vim9script', 'export var g:some'], 'E1022:')
1086 v9.CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
Bram Moolenaard8448622022-01-07 21:39:52 +00001087
1088 assert_fails('export something', 'E1043:')
1089enddef
1090
1091func Test_import_fails_without_script()
1092 CheckRunVimInTerminal
1093
1094 " call indirectly to avoid compilation error for missing functions
1095 call Run_Test_import_fails_on_command_line()
1096endfunc
1097
1098def Run_Test_import_fails_on_command_line()
1099 var export =<< trim END
1100 vim9script
1101 export def Foo(): number
1102 return 0
1103 enddef
1104 END
1105 writefile(export, 'XexportCmd.vim')
1106
Bram Moolenaar62aec932022-01-29 21:45:34 +00001107 var buf = g:RunVimInTerminal('-c "import Foo from ''./XexportCmd.vim''"', {
Bram Moolenaard8448622022-01-07 21:39:52 +00001108 rows: 6, wait_for_ruler: 0})
Bram Moolenaar62aec932022-01-29 21:45:34 +00001109 g:WaitForAssert(() => assert_match('^E1094:', term_getline(buf, 5)))
Bram Moolenaard8448622022-01-07 21:39:52 +00001110
1111 delete('XexportCmd.vim')
Bram Moolenaar62aec932022-01-29 21:45:34 +00001112 g:StopVimInTerminal(buf)
Bram Moolenaard8448622022-01-07 21:39:52 +00001113enddef
1114
1115def Test_vim9_reload_noclear()
1116 var lines =<< trim END
1117 vim9script
1118 export var exported = 'thexport'
1119
1120 export def TheFunc(x = 0)
1121 enddef
1122 END
1123 writefile(lines, 'XExportReload')
1124 lines =<< trim END
1125 vim9script noclear
1126 g:loadCount += 1
Bram Moolenaara749a422022-02-12 19:52:25 +00001127 var reloaded = 'init'
Bram Moolenaard8448622022-01-07 21:39:52 +00001128 import './XExportReload' as exp
1129
1130 def Again(): string
1131 return 'again'
1132 enddef
1133
1134 exp.TheFunc()
1135
Bram Moolenaara749a422022-02-12 19:52:25 +00001136 if exists('loaded') | finish | endif
1137 var loaded = true
Bram Moolenaard8448622022-01-07 21:39:52 +00001138
Bram Moolenaara749a422022-02-12 19:52:25 +00001139 var notReloaded = 'yes'
1140 reloaded = 'first'
Bram Moolenaard8448622022-01-07 21:39:52 +00001141 def g:Values(): list<string>
Bram Moolenaara749a422022-02-12 19:52:25 +00001142 return [reloaded, notReloaded, Again(), Once(), exp.exported]
Bram Moolenaard8448622022-01-07 21:39:52 +00001143 enddef
1144
1145 def Once(): string
1146 return 'once'
1147 enddef
1148 END
1149 writefile(lines, 'XReloaded')
1150 g:loadCount = 0
1151 source XReloaded
1152 assert_equal(1, g:loadCount)
1153 assert_equal(['first', 'yes', 'again', 'once', 'thexport'], g:Values())
1154 source XReloaded
1155 assert_equal(2, g:loadCount)
1156 assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values())
1157 source XReloaded
1158 assert_equal(3, g:loadCount)
1159 assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values())
1160
1161 delete('XReloaded')
1162 delete('XExportReload')
1163 delfunc g:Values
1164 unlet g:loadCount
1165
1166 lines =<< trim END
1167 vim9script
1168 def Inner()
1169 enddef
1170 END
1171 lines->writefile('XreloadScript.vim')
1172 source XreloadScript.vim
1173
1174 lines =<< trim END
1175 vim9script
1176 def Outer()
1177 def Inner()
1178 enddef
1179 enddef
1180 defcompile
1181 END
1182 lines->writefile('XreloadScript.vim')
1183 source XreloadScript.vim
1184
1185 delete('XreloadScript.vim')
1186enddef
1187
Bram Moolenaarcd1cda22022-02-16 21:48:25 +00001188def Test_vim_reload_noclear_arg_count()
1189 var lines =<< trim END
1190 vim9script noclear
1191
1192 if !exists('g:didload')
1193 def Test(a: string, b: string)
1194 echo a b
1195 enddef
1196 def Call()
1197 Test('a', 'b')
1198 enddef
1199 else
1200 # redefine with one argument less
1201 def Test(a: string)
1202 echo a
1203 enddef
1204 endif
1205 Call()
1206 g:didload = 1
1207 END
1208 lines->writefile('XreloadScript_1.vim')
1209 source XreloadScript_1.vim
1210 assert_fails('source XreloadScript_1.vim', 'E1106: One argument too many')
1211 unlet g:didload
1212
1213 lines =<< trim END
1214 vim9script noclear
1215
1216 if !exists('g:didload')
1217 def Test(a: string, b: string, c: string)
1218 echo a b
1219 enddef
1220 def Call()
1221 Test('a', 'b', 'c')
1222 enddef
1223 else
1224 # redefine with one argument less
1225 def Test(a: string)
1226 echo a
1227 enddef
1228 endif
1229 Call()
1230 g:didload = 1
1231 END
1232 lines->writefile('XreloadScript_2.vim')
1233 source XreloadScript_2.vim
1234 assert_fails('source XreloadScript_2.vim', 'E1106: 2 arguments too many')
1235 unlet g:didload
1236
1237 lines =<< trim END
1238 vim9script noclear
1239
1240 if !exists('g:didload')
1241 def Test(a: string)
1242 echo a
1243 enddef
1244 def Call()
1245 Test('a')
1246 enddef
1247 else
1248 # redefine with one argument extra
1249 def Test(a: string, b: string)
1250 echo a b
1251 enddef
1252 endif
1253 Call()
1254 g:didload = 1
1255 END
1256 lines->writefile('XreloadScript_3.vim')
1257 source XreloadScript_3.vim
1258 assert_fails('source XreloadScript_3.vim', 'E1190: One argument too few')
1259 unlet g:didload
1260
1261 lines =<< trim END
1262 vim9script noclear
1263
1264 if !exists('g:didload')
1265 def Test(a: string)
1266 echo a
1267 enddef
1268 def Call()
1269 Test('a')
1270 enddef
1271 else
1272 # redefine with two arguments extra
1273 def Test(a: string, b: string, c: string)
1274 echo a b
1275 enddef
1276 endif
1277 Call()
1278 g:didload = 1
1279 END
1280 lines->writefile('XreloadScript_4.vim')
1281 source XreloadScript_4.vim
1282 assert_fails('source XreloadScript_4.vim', 'E1190: 2 arguments too few')
1283 unlet g:didload
1284
1285 delete('XreloadScript_1.vim')
1286 delete('XreloadScript_2.vim')
1287 delete('XreloadScript_3.vim')
1288 delete('XreloadScript_4.vim')
1289enddef
1290
1291def Test_vim9_reload_noclear_error()
1292 var lines =<< trim END
1293 vim9script noclear
1294
1295 if !exists('g:didload')
1296 def Test(a: string)
1297 echo a
1298 enddef
1299 def Call()
1300 Test('a')
1301 enddef
1302 else
1303 # redefine with a compile error
1304 def Test(a: string)
1305 echo ax
1306 enddef
1307 endif
1308 Call()
1309 g:didload = 1
1310 END
1311 lines->writefile('XreloadScriptErr.vim')
1312 source XreloadScriptErr.vim
1313 assert_fails('source XreloadScriptErr.vim', 'E1001: Variable not found: ax')
1314
1315 unlet g:didload
1316 delete('XreloadScriptErr.vim')
1317enddef
1318
Bram Moolenaard8448622022-01-07 21:39:52 +00001319def Test_vim9_reload_import()
1320 var lines =<< trim END
1321 vim9script
1322 const var = ''
1323 var valone = 1234
1324 def MyFunc(arg: string)
1325 valone = 5678
1326 enddef
1327 END
1328 var morelines =<< trim END
1329 var valtwo = 222
1330 export def GetValtwo(): number
1331 return valtwo
1332 enddef
1333 END
1334 writefile(lines + morelines, 'Xreload.vim')
1335 source Xreload.vim
1336 source Xreload.vim
1337 source Xreload.vim
1338
1339 # cannot declare a var twice
1340 lines =<< trim END
1341 vim9script
1342 var valone = 1234
1343 var valone = 5678
1344 END
1345 writefile(lines, 'Xreload.vim')
1346 assert_fails('source Xreload.vim', 'E1041:', '', 3, 'Xreload.vim')
1347
1348 delete('Xreload.vim')
1349 delete('Ximport.vim')
1350enddef
1351
1352" if a script is reloaded with a script-local variable that changed its type, a
1353" compiled function using that variable must fail.
1354def Test_script_reload_change_type()
1355 var lines =<< trim END
1356 vim9script noclear
1357 var str = 'string'
1358 def g:GetStr(): string
1359 return str .. 'xxx'
1360 enddef
1361 END
1362 writefile(lines, 'Xreload.vim')
1363 source Xreload.vim
1364 echo g:GetStr()
1365
1366 lines =<< trim END
1367 vim9script noclear
1368 var str = 1234
1369 END
1370 writefile(lines, 'Xreload.vim')
1371 source Xreload.vim
1372 assert_fails('echo g:GetStr()', 'E1150:')
1373
1374 delfunc g:GetStr
1375 delete('Xreload.vim')
1376enddef
1377
1378" Define CallFunc so that the test can be compiled
1379command CallFunc echo 'nop'
1380
1381def Test_script_reload_from_function()
1382 var lines =<< trim END
1383 vim9script
1384
1385 if exists('g:loaded')
1386 finish
1387 endif
1388 g:loaded = 1
1389 delcommand CallFunc
1390 command CallFunc Func()
1391 def Func()
1392 so XreloadFunc.vim
1393 g:didTheFunc = 1
1394 enddef
1395 END
1396 writefile(lines, 'XreloadFunc.vim')
1397 source XreloadFunc.vim
1398 CallFunc
1399 assert_equal(1, g:didTheFunc)
1400
1401 delete('XreloadFunc.vim')
1402 delcommand CallFunc
1403 unlet g:loaded
1404 unlet g:didTheFunc
1405enddef
1406
1407def s:RetSome(): string
1408 return 'some'
1409enddef
1410
1411" Not exported function that is referenced needs to be accessed by the
1412" script-local name.
1413def Test_vim9_funcref()
1414 var sortlines =<< trim END
1415 vim9script
1416 def Compare(i1: number, i2: number): number
1417 return i2 - i1
1418 enddef
1419
1420 export def FastSort(): list<number>
1421 return range(5)->sort(Compare)
1422 enddef
1423
1424 export def GetString(arg: string): string
1425 return arg
1426 enddef
1427 END
1428 writefile(sortlines, 'Xsort.vim')
1429
1430 var lines =<< trim END
1431 vim9script
1432 import './Xsort.vim'
1433 def Test()
1434 g:result = Xsort.FastSort()
1435 enddef
1436 Test()
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +00001437 END
1438 writefile(lines, 'Xscript.vim')
1439 source Xscript.vim
1440 assert_equal([4, 3, 2, 1, 0], g:result)
1441 unlet g:result
Bram Moolenaard8448622022-01-07 21:39:52 +00001442
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +00001443 lines =<< trim END
1444 vim9script
Bram Moolenaard8448622022-01-07 21:39:52 +00001445 # using a function imported with "as"
1446 import './Xsort.vim' as anAlias
1447 assert_equal('yes', anAlias.GetString('yes'))
1448
1449 # using the function from a compiled function
1450 def TestMore(): string
1451 var s = s:anAlias.GetString('foo')
1452 return s .. anAlias.GetString('bar')
1453 enddef
1454 assert_equal('foobar', TestMore())
1455
1456 # error when using a function that isn't exported
1457 assert_fails('anAlias.Compare(1, 2)', 'E1049:')
1458 END
1459 writefile(lines, 'Xscript.vim')
1460
Bram Moolenaard8448622022-01-07 21:39:52 +00001461 delete('Xsort.vim')
1462 delete('Xscript.vim')
1463
1464 var Funcref = function('s:RetSome')
1465 assert_equal('some', Funcref())
1466enddef
1467
1468" Check that when searching for "FilterFunc" it finds the import in the
1469" script where FastFilter() is called from, both as a string and as a direct
1470" function reference.
1471def Test_vim9_funcref_other_script()
1472 var filterLines =<< trim END
1473 vim9script
1474 export def FilterFunc(idx: number, val: number): bool
1475 return idx % 2 == 1
1476 enddef
1477 export def FastFilter(): list<number>
1478 return range(10)->filter('FilterFunc(v:key, v:val)')
1479 enddef
1480 export def FastFilterDirect(): list<number>
1481 return range(10)->filter(FilterFunc)
1482 enddef
1483 END
1484 writefile(filterLines, 'Xfilter.vim')
1485
1486 var lines =<< trim END
1487 vim9script
1488 import './Xfilter.vim' as filter
1489 def Test()
1490 var x: list<number> = filter.FastFilter()
1491 enddef
1492 Test()
1493 def TestDirect()
1494 var x: list<number> = filter.FastFilterDirect()
1495 enddef
1496 TestDirect()
1497 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001498 v9.CheckScriptSuccess(lines)
Bram Moolenaard8448622022-01-07 21:39:52 +00001499 delete('Xfilter.vim')
1500enddef
1501
1502def Test_import_absolute()
1503 var import_lines = [
1504 'vim9script',
1505 'import "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim" as abs',
1506 'def UseExported()',
1507 ' g:imported_abs = abs.exported',
1508 ' abs.exported = 8888',
1509 ' g:imported_after = abs.exported',
1510 'enddef',
1511 'UseExported()',
1512 'g:import_disassembled = execute("disass UseExported")',
1513 ]
1514 writefile(import_lines, 'Ximport_abs.vim')
1515 writefile(s:export_script_lines, 'Xexport_abs.vim')
1516
1517 source Ximport_abs.vim
1518
1519 assert_equal(9876, g:imported_abs)
1520 assert_equal(8888, g:imported_after)
1521 assert_match('<SNR>\d\+_UseExported\_s*' ..
1522 'g:imported_abs = abs.exported\_s*' ..
1523 '0 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' ..
1524 '1 STOREG g:imported_abs\_s*' ..
1525 'abs.exported = 8888\_s*' ..
1526 '2 PUSHNR 8888\_s*' ..
1527 '3 STORESCRIPT exported-2 in .*Xexport_abs.vim\_s*' ..
1528 'g:imported_after = abs.exported\_s*' ..
1529 '4 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' ..
1530 '5 STOREG g:imported_after',
1531 g:import_disassembled)
1532
1533 Undo_export_script_lines()
1534 unlet g:imported_abs
1535 unlet g:import_disassembled
1536
1537 delete('Ximport_abs.vim')
1538 delete('Xexport_abs.vim')
1539enddef
1540
1541def Test_import_rtp()
1542 var import_lines = [
1543 'vim9script',
1544 'import "Xexport_rtp.vim" as rtp',
1545 'g:imported_rtp = rtp.exported',
1546 ]
1547 writefile(import_lines, 'Ximport_rtp.vim')
1548 mkdir('import', 'p')
1549 writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
1550
1551 var save_rtp = &rtp
1552 &rtp = getcwd()
1553 source Ximport_rtp.vim
1554 &rtp = save_rtp
1555
1556 assert_equal(9876, g:imported_rtp)
1557
1558 Undo_export_script_lines()
1559 unlet g:imported_rtp
1560 delete('Ximport_rtp.vim')
1561 delete('import', 'rf')
1562enddef
1563
1564def Test_import_compile_error()
1565 var export_lines = [
1566 'vim9script',
1567 'export def ExpFunc(): string',
1568 ' return notDefined',
1569 'enddef',
1570 ]
1571 writefile(export_lines, 'Xexported.vim')
1572
1573 var import_lines = [
1574 'vim9script',
1575 'import "./Xexported.vim" as expo',
1576 'def ImpFunc()',
1577 ' echo expo.ExpFunc()',
1578 'enddef',
1579 'defcompile',
1580 ]
1581 writefile(import_lines, 'Ximport.vim')
1582
1583 try
1584 source Ximport.vim
1585 catch /E1001/
1586 # Error should be before the Xexported.vim file.
1587 assert_match('E1001: Variable not found: notDefined', v:exception)
1588 assert_match('function <SNR>\d\+_ImpFunc\[1\]..<SNR>\d\+_ExpFunc, line 1', v:throwpoint)
1589 endtry
1590
1591 delete('Xexported.vim')
1592 delete('Ximport.vim')
1593enddef
1594
1595def Test_func_overrules_import_fails()
1596 var export_lines =<< trim END
1597 vim9script
1598 export def Func()
1599 echo 'imported'
1600 enddef
1601 END
1602 writefile(export_lines, 'XexportedFunc.vim')
1603
1604 var lines =<< trim END
1605 vim9script
1606 import './XexportedFunc.vim' as Func
1607 def Func()
1608 echo 'local to function'
1609 enddef
1610 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001611 v9.CheckScriptFailure(lines, 'E1213: Redefining imported item "Func"')
Bram Moolenaard8448622022-01-07 21:39:52 +00001612
1613 lines =<< trim END
1614 vim9script
1615 import './XexportedFunc.vim' as Func
1616 def Outer()
1617 def Func()
1618 echo 'local to function'
1619 enddef
1620 enddef
1621 defcompile
1622 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001623 v9.CheckScriptFailure(lines, 'E1236:')
Bram Moolenaard8448622022-01-07 21:39:52 +00001624
1625 delete('XexportedFunc.vim')
1626enddef
1627
1628def Test_source_vim9_from_legacy()
1629 var vim9_lines =<< trim END
1630 vim9script
1631 var local = 'local'
1632 g:global = 'global'
1633 export var exported = 'exported'
1634 export def GetText(): string
1635 return 'text'
1636 enddef
1637 END
1638 writefile(vim9_lines, 'Xvim9_script.vim')
1639
1640 var legacy_lines =<< trim END
1641 source Xvim9_script.vim
1642
1643 call assert_false(exists('local'))
1644 call assert_false(exists('exported'))
1645 call assert_false(exists('s:exported'))
1646 call assert_equal('global', global)
1647 call assert_equal('global', g:global)
Bram Moolenaard8448622022-01-07 21:39:52 +00001648 END
1649 writefile(legacy_lines, 'Xlegacy_script.vim')
1650
1651 source Xlegacy_script.vim
1652 assert_equal('global', g:global)
1653 unlet g:global
1654
1655 delete('Xlegacy_script.vim')
1656 delete('Xvim9_script.vim')
1657enddef
1658
Bram Moolenaarc43e6232022-01-13 20:51:56 +00001659def Test_import_vim9_from_legacy()
1660 var vim9_lines =<< trim END
1661 vim9script
1662 var local = 'local'
1663 g:global = 'global'
1664 export var exported = 'exported'
1665 export def GetText(): string
1666 return 'text'
1667 enddef
1668 END
1669 writefile(vim9_lines, 'Xvim9_export.vim')
1670
1671 var legacy_lines =<< trim END
1672 import './Xvim9_export.vim' as vim9
1673
1674 call assert_false(exists('vim9'))
1675 call assert_false(exists('local'))
1676 call assert_false(exists('s:vim9.local'))
1677 call assert_equal('global', global)
1678 call assert_equal('global', g:global)
1679 call assert_false(exists('exported'))
1680 call assert_false(exists('s:exported'))
1681 call assert_false(exists('*GetText'))
1682
1683 " imported symbol is script-local
1684 call assert_equal('exported', s:vim9.exported)
1685 call assert_equal('text', s:vim9.GetText())
1686 END
1687 writefile(legacy_lines, 'Xlegacy_script.vim')
1688
1689 source Xlegacy_script.vim
1690 assert_equal('global', g:global)
1691 unlet g:global
1692
1693 delete('Xlegacy_script.vim')
1694 delete('Xvim9_export.vim')
1695enddef
1696
Bram Moolenaard8448622022-01-07 21:39:52 +00001697def Test_cmdline_win()
1698 # if the Vim syntax highlighting uses Vim9 constructs they can be used from
1699 # the command line window.
1700 mkdir('rtp/syntax', 'p')
1701 var export_lines =<< trim END
1702 vim9script
1703 export var That = 'yes'
1704 END
1705 writefile(export_lines, 'rtp/syntax/Xexport.vim')
1706 var import_lines =<< trim END
1707 vim9script
1708 import './Xexport.vim' as exp
1709 echo exp.That
1710 END
1711 writefile(import_lines, 'rtp/syntax/vim.vim')
1712 var save_rtp = &rtp
1713 &rtp = getcwd() .. '/rtp' .. ',' .. &rtp
1714 syntax on
1715 augroup CmdWin
1716 autocmd CmdwinEnter * g:got_there = 'yes'
1717 augroup END
1718 # this will open and also close the cmdline window
1719 feedkeys('q:', 'xt')
1720 assert_equal('yes', g:got_there)
1721
1722 augroup CmdWin
1723 au!
1724 augroup END
1725 &rtp = save_rtp
1726 delete('rtp', 'rf')
1727enddef
1728
1729def Test_import_gone_when_sourced_twice()
1730 var exportlines =<< trim END
1731 vim9script
1732 if exists('g:guard')
1733 finish
1734 endif
1735 g:guard = 1
1736 export var name = 'someName'
1737 END
1738 writefile(exportlines, 'XexportScript.vim')
1739
1740 var lines =<< trim END
1741 vim9script
1742 import './XexportScript.vim' as expo
1743 def g:GetName(): string
1744 return expo.name
1745 enddef
1746 END
1747 writefile(lines, 'XscriptImport.vim')
1748 so XscriptImport.vim
1749 assert_equal('someName', g:GetName())
1750
1751 so XexportScript.vim
1752 assert_fails('call g:GetName()', 'E1149:')
1753
1754 delfunc g:GetName
1755 delete('XexportScript.vim')
1756 delete('XscriptImport.vim')
1757 unlet g:guard
1758enddef
1759
Bram Moolenaar160aa862022-01-10 21:29:57 +00001760" test using an auto-loaded function and variable
Bram Moolenaar0e3e7ba2022-01-13 20:18:56 +00001761def Test_vim9_autoload_full_name()
Bram Moolenaar160aa862022-01-10 21:29:57 +00001762 var lines =<< trim END
1763 vim9script
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00001764 export def Gettest(): string
Bram Moolenaar160aa862022-01-10 21:29:57 +00001765 return 'test'
1766 enddef
1767 g:some#name = 'name'
1768 g:some#dict = {key: 'value'}
1769
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00001770 export def Varargs(a1: string, ...l: list<string>): string
Bram Moolenaar160aa862022-01-10 21:29:57 +00001771 return a1 .. l[0] .. l[1]
1772 enddef
1773 END
1774
1775 mkdir('Xdir/autoload', 'p')
1776 writefile(lines, 'Xdir/autoload/some.vim')
1777 var save_rtp = &rtp
1778 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1779
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00001780 assert_equal('test', g:some#Gettest())
Bram Moolenaar160aa862022-01-10 21:29:57 +00001781 assert_equal('name', g:some#name)
1782 assert_equal('value', g:some#dict.key)
1783 g:some#other = 'other'
1784 assert_equal('other', g:some#other)
1785
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00001786 assert_equal('abc', some#Varargs('a', 'b', 'c'))
Bram Moolenaar160aa862022-01-10 21:29:57 +00001787
1788 # upper case script name works
1789 lines =<< trim END
1790 vim9script
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00001791 export def GetOther(): string
Bram Moolenaar160aa862022-01-10 21:29:57 +00001792 return 'other'
1793 enddef
1794 END
1795 writefile(lines, 'Xdir/autoload/Other.vim')
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00001796 assert_equal('other', g:Other#GetOther())
Bram Moolenaar160aa862022-01-10 21:29:57 +00001797
1798 delete('Xdir', 'rf')
1799 &rtp = save_rtp
1800enddef
1801
1802def Test_vim9script_autoload()
1803 mkdir('Xdir/autoload', 'p')
1804 var save_rtp = &rtp
1805 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1806
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001807 # when the path has "/autoload/" prefix is not needed
Bram Moolenaar160aa862022-01-10 21:29:57 +00001808 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001809 vim9script
Bram Moolenaar17d36cb2022-01-12 11:46:40 +00001810 g:prefixed_loaded += 1
Bram Moolenaar160aa862022-01-10 21:29:57 +00001811
1812 export def Gettest(): string
1813 return 'test'
1814 enddef
1815
Bram Moolenaar0e3e7ba2022-01-13 20:18:56 +00001816 export var name = 'name'
1817
1818 export func GetFunc()
1819 return Gettest() .. 'more' .. s:name
Bram Moolenaar160aa862022-01-10 21:29:57 +00001820 endfunc
1821
Bram Moolenaar0e3e7ba2022-01-13 20:18:56 +00001822 export def GetDef(): string
1823 return Gettest() .. 'more' .. name
1824 enddef
1825
Bram Moolenaar160aa862022-01-10 21:29:57 +00001826 export final fname = 'final'
1827 export const cname = 'const'
1828 END
1829 writefile(lines, 'Xdir/autoload/prefixed.vim')
1830
Bram Moolenaar17d36cb2022-01-12 11:46:40 +00001831 g:prefixed_loaded = 0
1832 g:expected_loaded = 0
Bram Moolenaar160aa862022-01-10 21:29:57 +00001833 lines =<< trim END
1834 vim9script
1835 import autoload 'prefixed.vim'
Bram Moolenaar17d36cb2022-01-12 11:46:40 +00001836 assert_equal(g:expected_loaded, g:prefixed_loaded)
Bram Moolenaar160aa862022-01-10 21:29:57 +00001837 assert_equal('test', prefixed.Gettest())
Bram Moolenaar17d36cb2022-01-12 11:46:40 +00001838 assert_equal(1, g:prefixed_loaded)
Bram Moolenaar160aa862022-01-10 21:29:57 +00001839
Bram Moolenaar0e3e7ba2022-01-13 20:18:56 +00001840 assert_equal('testmorename', prefixed.GetFunc())
1841 assert_equal('testmorename', prefixed.GetDef())
Bram Moolenaar160aa862022-01-10 21:29:57 +00001842 assert_equal('name', prefixed.name)
1843 assert_equal('final', prefixed.fname)
1844 assert_equal('const', prefixed.cname)
1845 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001846 v9.CheckScriptSuccess(lines)
Bram Moolenaar17d36cb2022-01-12 11:46:40 +00001847 # can source it again, autoload script not loaded again
1848 g:expected_loaded = 1
Bram Moolenaar62aec932022-01-29 21:45:34 +00001849 v9.CheckScriptSuccess(lines)
Bram Moolenaar160aa862022-01-10 21:29:57 +00001850
1851 # can also get the items by autoload name
1852 lines =<< trim END
1853 call assert_equal('test', prefixed#Gettest())
Bram Moolenaar0e3e7ba2022-01-13 20:18:56 +00001854 call assert_equal('testmorename', prefixed#GetFunc())
Bram Moolenaar160aa862022-01-10 21:29:57 +00001855 call assert_equal('name', prefixed#name)
1856 call assert_equal('final', prefixed#fname)
1857 call assert_equal('const', prefixed#cname)
1858 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001859 v9.CheckScriptSuccess(lines)
Bram Moolenaar160aa862022-01-10 21:29:57 +00001860
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00001861 unlet g:prefixed_loaded
1862 unlet g:expected_loaded
1863 delete('Xdir', 'rf')
1864 &rtp = save_rtp
1865enddef
1866
Bram Moolenaard02dce22022-01-18 17:43:04 +00001867def Test_import_autoload_not_exported()
1868 mkdir('Xdir/autoload', 'p')
1869 var save_rtp = &rtp
1870 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1871
1872 # error when using an item that is not exported from an autoload script
1873 var exportLines =<< trim END
1874 vim9script
1875 var notExported = 123
1876 def NotExport()
1877 echo 'nop'
1878 enddef
1879 END
1880 writefile(exportLines, 'Xdir/autoload/notExport1.vim')
1881
1882 var lines =<< trim END
1883 vim9script
1884 import autoload 'notExport1.vim'
1885 echo notExport1.notFound
1886 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001887 v9.CheckScriptFailure(lines, 'E1048: Item not found in script: notFound')
Bram Moolenaard02dce22022-01-18 17:43:04 +00001888
1889 lines =<< trim END
1890 vim9script
1891 import autoload 'notExport1.vim'
1892 echo notExport1.notExported
1893 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001894 v9.CheckScriptFailure(lines, 'E1049: Item not exported in script: notExported')
Bram Moolenaard02dce22022-01-18 17:43:04 +00001895
1896 lines =<< trim END
1897 vim9script
1898 import autoload 'notExport1.vim'
1899 echo notExport1.NotFunc()
1900 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001901 v9.CheckScriptFailure(lines, 'E1048: Item not found in script: NotFunc')
Bram Moolenaard02dce22022-01-18 17:43:04 +00001902
1903 lines =<< trim END
1904 vim9script
1905 import autoload 'notExport1.vim'
1906 echo notExport1.NotExport()
1907 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001908 v9.CheckScriptFailure(lines, 'E1049: Item not exported in script: NotExport')
Bram Moolenaard02dce22022-01-18 17:43:04 +00001909
1910 lines =<< trim END
1911 vim9script
1912 import autoload 'notExport1.vim'
1913 echo 'text'->notExport1.NotFunc()
1914 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001915 v9.CheckScriptFailure(lines, 'E1048: Item not found in script: NotFunc')
Bram Moolenaard02dce22022-01-18 17:43:04 +00001916
1917 lines =<< trim END
1918 vim9script
1919 import autoload 'notExport1.vim'
1920 echo 'text'->notExport1.NotExport()
1921 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001922 v9.CheckScriptFailure(lines, 'E1049: Item not exported in script: NotExport')
Bram Moolenaard02dce22022-01-18 17:43:04 +00001923
1924 # using a :def function we use a different autoload script every time so that
1925 # the function is compiled without the script loaded
1926 writefile(exportLines, 'Xdir/autoload/notExport2.vim')
1927 lines =<< trim END
1928 vim9script
1929 import autoload 'notExport2.vim'
1930 def Testit()
1931 echo notExport2.notFound
1932 enddef
1933 Testit()
1934 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001935 v9.CheckScriptFailure(lines, 'E1048: Item not found in script: notExport2#notFound')
Bram Moolenaard02dce22022-01-18 17:43:04 +00001936
1937 writefile(exportLines, 'Xdir/autoload/notExport3.vim')
1938 lines =<< trim END
1939 vim9script
1940 import autoload 'notExport3.vim'
1941 def Testit()
1942 echo notExport3.notExported
1943 enddef
1944 Testit()
1945 END
1946 # don't get E1049 because it is too complicated to figure out
Bram Moolenaar62aec932022-01-29 21:45:34 +00001947 v9.CheckScriptFailure(lines, 'E1048: Item not found in script: notExport3#notExported')
Bram Moolenaard02dce22022-01-18 17:43:04 +00001948
1949 writefile(exportLines, 'Xdir/autoload/notExport4.vim')
1950 lines =<< trim END
1951 vim9script
1952 import autoload 'notExport4.vim'
1953 def Testit()
1954 echo notExport4.NotFunc()
1955 enddef
1956 Testit()
1957 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001958 v9.CheckScriptFailure(lines, 'E117: Unknown function: notExport4#NotFunc')
Bram Moolenaard02dce22022-01-18 17:43:04 +00001959
1960 writefile(exportLines, 'Xdir/autoload/notExport5.vim')
1961 lines =<< trim END
1962 vim9script
1963 import autoload 'notExport5.vim'
1964 def Testit()
1965 echo notExport5.NotExport()
1966 enddef
1967 Testit()
1968 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001969 v9.CheckScriptFailure(lines, 'E117: Unknown function: notExport5#NotExport')
Bram Moolenaard02dce22022-01-18 17:43:04 +00001970
1971 writefile(exportLines, 'Xdir/autoload/notExport6.vim')
1972 lines =<< trim END
1973 vim9script
1974 import autoload 'notExport6.vim'
1975 def Testit()
1976 echo 'text'->notExport6.NotFunc()
1977 enddef
1978 Testit()
1979 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001980 v9.CheckScriptFailure(lines, 'E117: Unknown function: notExport6#NotFunc')
Bram Moolenaard02dce22022-01-18 17:43:04 +00001981
1982 writefile(exportLines, 'Xdir/autoload/notExport7.vim')
1983 lines =<< trim END
1984 vim9script
1985 import autoload 'notExport7.vim'
1986 def Testit()
1987 echo 'text'->notExport7.NotExport()
1988 enddef
1989 Testit()
1990 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001991 v9.CheckScriptFailure(lines, 'E117: Unknown function: notExport7#NotExport')
Bram Moolenaard02dce22022-01-18 17:43:04 +00001992
1993 delete('Xdir', 'rf')
1994 &rtp = save_rtp
1995enddef
1996
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00001997def Test_vim9script_autoload_call()
1998 mkdir('Xdir/autoload', 'p')
1999 var save_rtp = &rtp
2000 exe 'set rtp^=' .. getcwd() .. '/Xdir'
2001
2002 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00002003 vim9script
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00002004
Bram Moolenaarcbbc48f2022-01-18 12:58:28 +00002005 export def RetArg(arg: string): string
2006 return arg
2007 enddef
2008
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00002009 export def Getother()
2010 g:result = 'other'
2011 enddef
2012 END
Bram Moolenaar5d982692022-01-12 15:15:27 +00002013 writefile(lines, 'Xdir/autoload/another.vim')
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00002014
2015 lines =<< trim END
2016 vim9script
Bram Moolenaar5d982692022-01-12 15:15:27 +00002017 import autoload 'another.vim'
Bram Moolenaarcbbc48f2022-01-18 12:58:28 +00002018
2019 # compile this before 'another.vim' is loaded
2020 def CallAnother()
2021 assert_equal('foo', 'foo'->another.RetArg())
2022 enddef
2023 CallAnother()
2024
Bram Moolenaar5d982692022-01-12 15:15:27 +00002025 call another.Getother()
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00002026 assert_equal('other', g:result)
Bram Moolenaar3d8e25a2022-01-22 11:00:02 +00002027
2028 assert_equal('arg', call('another.RetArg', ['arg']))
Bram Moolenaar8164f6e2022-02-06 13:08:41 +00002029
2030 verbose function another.Getother
2031 # should we disallow this?
2032 verbose function another#Getother
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00002033 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002034 v9.CheckScriptSuccess(lines)
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00002035
2036 unlet g:result
Bram Moolenaar160aa862022-01-10 21:29:57 +00002037 delete('Xdir', 'rf')
2038 &rtp = save_rtp
2039enddef
2040
Bram Moolenaarb697dc22022-01-22 11:27:29 +00002041def Test_vim9script_noclear_autoload()
2042 mkdir('Xdir/autoload', 'p')
2043 var save_rtp = &rtp
2044 exe 'set rtp^=' .. getcwd() .. '/Xdir'
2045
2046 var lines =<< trim END
2047 vim9script
2048 export def Func(): string
2049 return 'called'
2050 enddef
2051 g:double_loaded = 'yes'
2052 END
2053 writefile(lines, 'Xdir/autoload/double.vim')
2054
2055 lines =<< trim END
2056 vim9script noclear
2057 if exists('g:script_loaded')
2058 finish
2059 endif
2060 g:script_loaded = true
2061
2062 import autoload 'double.vim'
2063 nnoremap <F3> <ScriptCmd>g:result = double.Func()<CR>
2064 END
2065 g:double_loaded = 'no'
2066 writefile(lines, 'Xloaddouble')
2067 source Xloaddouble
2068 assert_equal('no', g:double_loaded)
2069 assert_equal(true, g:script_loaded)
2070 source Xloaddouble
2071 feedkeys("\<F3>", 'xt')
2072 assert_equal('called', g:result)
2073 assert_equal('yes', g:double_loaded)
2074
2075 delete('Xloaddouble')
2076 unlet g:double_loaded
2077 unlet g:script_loaded
2078 unlet g:result
2079 delete('Xdir', 'rf')
2080 &rtp = save_rtp
2081enddef
2082
Bram Moolenaar9c7cae62022-01-20 19:10:25 +00002083def Test_vim9script_autoload_duplicate()
2084 mkdir('Xdir/autoload', 'p')
2085
2086 var lines =<< trim END
2087 vim9script
2088
2089 export def Func()
2090 enddef
2091
2092 def Func()
2093 enddef
2094 END
2095 writefile(lines, 'Xdir/autoload/dupfunc.vim')
2096 assert_fails('source Xdir/autoload/dupfunc.vim', 'E1073:')
2097
2098 lines =<< trim END
2099 vim9script
2100
2101 def Func()
2102 enddef
2103
2104 export def Func()
2105 enddef
2106 END
2107 writefile(lines, 'Xdir/autoload/dup2func.vim')
2108 assert_fails('source Xdir/autoload/dup2func.vim', 'E1073:')
2109
2110 lines =<< trim END
2111 vim9script
2112
2113 def Func()
2114 enddef
2115
2116 export var Func = 'asdf'
2117 END
2118 writefile(lines, 'Xdir/autoload/dup3func.vim')
2119 assert_fails('source Xdir/autoload/dup3func.vim', 'E1041: Redefining script item Func')
2120
2121 lines =<< trim END
2122 vim9script
2123
2124 export var Func = 'asdf'
2125
2126 def Func()
2127 enddef
2128 END
2129 writefile(lines, 'Xdir/autoload/dup4func.vim')
2130 assert_fails('source Xdir/autoload/dup4func.vim', 'E707:')
2131
2132 lines =<< trim END
2133 vim9script
2134
2135 var Func = 'asdf'
2136
2137 export def Func()
2138 enddef
2139 END
2140 writefile(lines, 'Xdir/autoload/dup5func.vim')
2141 assert_fails('source Xdir/autoload/dup5func.vim', 'E707:')
2142
2143 lines =<< trim END
2144 vim9script
2145
2146 export def Func()
2147 enddef
2148
2149 var Func = 'asdf'
2150 END
2151 writefile(lines, 'Xdir/autoload/dup6func.vim')
2152 assert_fails('source Xdir/autoload/dup6func.vim', 'E1041: Redefining script item Func')
2153
2154 delete('Xdir', 'rf')
2155enddef
2156
Bram Moolenaar2017d6f2022-01-20 19:38:46 +00002157def Test_autoload_missing_function_name()
2158 mkdir('Xdir/autoload', 'p')
2159
2160 var lines =<< trim END
2161 vim9script
2162
2163 def loadme#()
2164 enddef
2165 END
2166 writefile(lines, 'Xdir/autoload/loadme.vim')
2167 assert_fails('source Xdir/autoload/loadme.vim', 'E129:')
2168
2169 delete('Xdir', 'rf')
2170enddef
2171
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002172def Test_autoload_name_wrong()
Bram Moolenaar19e69a62022-01-21 20:37:05 +00002173 var lines =<< trim END
Bram Moolenaar19e69a62022-01-21 20:37:05 +00002174 def Xscriptname#Func()
2175 enddef
2176 END
2177 writefile(lines, 'Xscriptname.vim')
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00002178 v9.CheckScriptFailure(lines, 'E746:')
Yegappan Lakshmanan7e765a32022-01-24 11:40:37 +00002179 delete('Xscriptname.vim')
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00002180
2181 mkdir('Xdir/autoload', 'p')
2182 lines =<< trim END
2183 vim9script
2184 def somescript#Func()
2185 enddef
2186 END
2187 writefile(lines, 'Xdir/autoload/somescript.vim')
2188 assert_fails('source Xdir/autoload/somescript.vim', 'E1263:')
2189
2190 delete('Xdir', 'rf')
Bram Moolenaar19e69a62022-01-21 20:37:05 +00002191enddef
2192
Bram Moolenaard041f422022-01-12 19:54:00 +00002193def Test_import_autoload_postponed()
2194 mkdir('Xdir/autoload', 'p')
2195 var save_rtp = &rtp
2196 exe 'set rtp^=' .. getcwd() .. '/Xdir'
2197
2198 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00002199 vim9script
Bram Moolenaard041f422022-01-12 19:54:00 +00002200
2201 g:loaded_postponed = 'true'
2202 export var variable = 'bla'
2203 export def Function(): string
2204 return 'bla'
2205 enddef
2206 END
2207 writefile(lines, 'Xdir/autoload/postponed.vim')
2208
2209 lines =<< trim END
2210 vim9script
2211
2212 import autoload 'postponed.vim'
2213 def Tryit()
2214 echo postponed.variable
2215 echo postponed.Function()
2216 enddef
2217 defcompile
2218 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002219 v9.CheckScriptSuccess(lines)
Bram Moolenaard041f422022-01-12 19:54:00 +00002220 assert_false(exists('g:loaded_postponed'))
Bram Moolenaar62aec932022-01-29 21:45:34 +00002221 v9.CheckScriptSuccess(lines + ['Tryit()'])
Bram Moolenaard041f422022-01-12 19:54:00 +00002222 assert_equal('true', g:loaded_postponed)
2223
2224 unlet g:loaded_postponed
2225 delete('Xdir', 'rf')
2226 &rtp = save_rtp
2227enddef
2228
Bram Moolenaar3e4fa3d2022-01-13 22:05:09 +00002229def Test_import_autoload_override()
2230 mkdir('Xdir/autoload', 'p')
2231 var save_rtp = &rtp
2232 exe 'set rtp^=' .. getcwd() .. '/Xdir'
2233 test_override('autoload', 1)
2234
2235 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00002236 vim9script
Bram Moolenaar3e4fa3d2022-01-13 22:05:09 +00002237
2238 g:loaded_override = 'true'
2239 export var variable = 'bla'
2240 export def Function(): string
2241 return 'bla'
2242 enddef
2243 END
2244 writefile(lines, 'Xdir/autoload/override.vim')
2245
2246 lines =<< trim END
2247 vim9script
2248
2249 import autoload 'override.vim'
2250 assert_equal('true', g:loaded_override)
2251
2252 def Tryit()
2253 echo override.doesNotExist
2254 enddef
2255 defcompile
2256 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002257 v9.CheckScriptFailure(lines, 'E1048: Item not found in script: doesNotExist', 1)
Bram Moolenaar3e4fa3d2022-01-13 22:05:09 +00002258
2259 test_override('autoload', 0)
2260 unlet g:loaded_override
2261 delete('Xdir', 'rf')
2262 &rtp = save_rtp
2263enddef
2264
Bram Moolenaar19db9e62022-01-11 11:58:19 +00002265def Test_autoload_mapping()
2266 mkdir('Xdir/autoload', 'p')
2267 var save_rtp = &rtp
2268 exe 'set rtp^=' .. getcwd() .. '/Xdir'
2269
2270 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00002271 vim9script
Bram Moolenaar19db9e62022-01-11 11:58:19 +00002272
2273 g:toggle_loaded = 'yes'
2274
2275 export def Toggle(): string
2276 return ":g:toggle_called = 'yes'\<CR>"
2277 enddef
Bram Moolenaare32c3c42022-01-15 18:26:04 +00002278 export def Doit()
2279 g:doit_called = 'yes'
2280 enddef
Bram Moolenaar19db9e62022-01-11 11:58:19 +00002281 END
2282 writefile(lines, 'Xdir/autoload/toggle.vim')
2283
2284 lines =<< trim END
2285 vim9script
2286
2287 import autoload 'toggle.vim'
2288
2289 nnoremap <silent> <expr> tt toggle.Toggle()
Bram Moolenaare32c3c42022-01-15 18:26:04 +00002290 nnoremap <silent> xx <ScriptCmd>toggle.Doit()<CR>
2291 nnoremap <silent> yy <Cmd>toggle.Doit()<CR>
Bram Moolenaar19db9e62022-01-11 11:58:19 +00002292 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002293 v9.CheckScriptSuccess(lines)
Bram Moolenaar19db9e62022-01-11 11:58:19 +00002294 assert_false(exists("g:toggle_loaded"))
2295 assert_false(exists("g:toggle_called"))
Bram Moolenaar6079da72022-01-18 14:16:59 +00002296 assert_match('\d A: \f*[/\\]toggle.vim', execute('scriptnames'))
Bram Moolenaar19db9e62022-01-11 11:58:19 +00002297
2298 feedkeys("tt", 'xt')
2299 assert_equal('yes', g:toggle_loaded)
2300 assert_equal('yes', g:toggle_called)
Bram Moolenaar6079da72022-01-18 14:16:59 +00002301 assert_match('\d: \f*[/\\]toggle.vim', execute('scriptnames'))
Bram Moolenaar19db9e62022-01-11 11:58:19 +00002302
Bram Moolenaare32c3c42022-01-15 18:26:04 +00002303 feedkeys("xx", 'xt')
2304 assert_equal('yes', g:doit_called)
2305
2306 assert_fails('call feedkeys("yy", "xt")', 'E121: Undefined variable: toggle')
2307
Bram Moolenaar19db9e62022-01-11 11:58:19 +00002308 nunmap tt
Bram Moolenaare32c3c42022-01-15 18:26:04 +00002309 nunmap xx
2310 nunmap yy
Bram Moolenaar19db9e62022-01-11 11:58:19 +00002311 unlet g:toggle_loaded
2312 unlet g:toggle_called
2313 delete('Xdir', 'rf')
2314 &rtp = save_rtp
2315enddef
2316
Bram Moolenaar160aa862022-01-10 21:29:57 +00002317def Test_vim9script_autoload_fails()
2318 var lines =<< trim END
2319 vim9script autoload
2320 var n = 0
2321 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002322 v9.CheckScriptFailure(lines, 'E475: Invalid argument: autoload')
Bram Moolenaarfd218c82022-01-18 16:26:24 +00002323
2324 lines =<< trim END
2325 vim9script noclear noclear
2326 var n = 0
2327 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002328 v9.CheckScriptFailure(lines, 'E983: Duplicate argument: noclear')
Bram Moolenaar160aa862022-01-10 21:29:57 +00002329enddef
2330
2331def Test_import_autoload_fails()
2332 var lines =<< trim END
2333 vim9script
2334 import autoload autoload 'prefixed.vim'
2335 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002336 v9.CheckScriptFailure(lines, 'E121: Undefined variable: autoload')
Bram Moolenaar160aa862022-01-10 21:29:57 +00002337
2338 lines =<< trim END
2339 vim9script
Bram Moolenaar1836d612022-01-18 13:14:47 +00002340 import autoload './doesNotExist.vim'
Bram Moolenaar160aa862022-01-10 21:29:57 +00002341 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002342 v9.CheckScriptFailure(lines, 'E1264:')
Bram Moolenaar1836d612022-01-18 13:14:47 +00002343
2344 lines =<< trim END
2345 vim9script
2346 import autoload '/dir/doesNotExist.vim'
2347 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002348 v9.CheckScriptFailure(lines, 'E1264:')
Bram Moolenaar1836d612022-01-18 13:14:47 +00002349
2350 lines =<< trim END
2351 vim9script
2352 import autoload 'doesNotExist.vim'
2353 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002354 v9.CheckScriptFailure(lines, 'E1053: Could not import "doesNotExist.vim"')
Bram Moolenaar160aa862022-01-10 21:29:57 +00002355enddef
2356
2357" test disassembling an auto-loaded function starting with "debug"
2358def Test_vim9_autoload_disass()
2359 mkdir('Xdir/autoload', 'p')
2360 var save_rtp = &rtp
2361 exe 'set rtp^=' .. getcwd() .. '/Xdir'
2362
2363 var lines =<< trim END
2364 vim9script
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00002365 export def Test(): string
Bram Moolenaar160aa862022-01-10 21:29:57 +00002366 return 'debug'
2367 enddef
2368 END
2369 writefile(lines, 'Xdir/autoload/debugit.vim')
2370
2371 lines =<< trim END
2372 vim9script
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00002373 export def Test(): string
Bram Moolenaar160aa862022-01-10 21:29:57 +00002374 return 'profile'
2375 enddef
2376 END
2377 writefile(lines, 'Xdir/autoload/profileit.vim')
2378
2379 lines =<< trim END
2380 vim9script
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00002381 assert_equal('debug', debugit#Test())
2382 disass debugit#Test
2383 assert_equal('profile', profileit#Test())
2384 disass profileit#Test
Bram Moolenaar160aa862022-01-10 21:29:57 +00002385 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002386 v9.CheckScriptSuccess(lines)
Bram Moolenaar160aa862022-01-10 21:29:57 +00002387
2388 delete('Xdir', 'rf')
2389 &rtp = save_rtp
2390enddef
2391
2392" test using a vim9script that is auto-loaded from an autocmd
2393def Test_vim9_aucmd_autoload()
2394 var lines =<< trim END
2395 vim9script
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00002396 export def Test()
Bram Moolenaar160aa862022-01-10 21:29:57 +00002397 echomsg getreg('"')
2398 enddef
2399 END
2400
2401 mkdir('Xdir/autoload', 'p')
2402 writefile(lines, 'Xdir/autoload/foo.vim')
2403 var save_rtp = &rtp
2404 exe 'set rtp^=' .. getcwd() .. '/Xdir'
2405 augroup test
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00002406 autocmd TextYankPost * call foo#Test()
Bram Moolenaar160aa862022-01-10 21:29:57 +00002407 augroup END
2408
2409 normal Y
2410
2411 augroup test
2412 autocmd!
2413 augroup END
2414 delete('Xdir', 'rf')
2415 &rtp = save_rtp
2416enddef
2417
Bram Moolenaar3049fcf2022-01-13 19:25:50 +00002418" test using a autoloaded file that is case sensitive
2419def Test_vim9_autoload_case_sensitive()
2420 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00002421 vim9script
Bram Moolenaar3049fcf2022-01-13 19:25:50 +00002422 export def CaseSensitive(): string
2423 return 'done'
2424 enddef
2425 END
2426
2427 mkdir('Xdir/autoload', 'p')
2428 writefile(lines, 'Xdir/autoload/CaseSensitive.vim')
2429 var save_rtp = &rtp
2430 exe 'set rtp^=' .. getcwd() .. '/Xdir'
2431
2432 lines =<< trim END
2433 vim9script
2434 import autoload 'CaseSensitive.vim'
2435 assert_equal('done', CaseSensitive.CaseSensitive())
2436 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002437 v9.CheckScriptSuccess(lines)
Bram Moolenaar3049fcf2022-01-13 19:25:50 +00002438
Bram Moolenaarbfac4092022-01-16 11:12:12 +00002439 if !has('fname_case')
2440 lines =<< trim END
2441 vim9script
2442 import autoload 'CaseSensitive.vim'
2443 import autoload 'casesensitive.vim'
2444 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002445 v9.CheckScriptFailure(lines, 'E1262:')
Bram Moolenaarbfac4092022-01-16 11:12:12 +00002446 endif
2447
Bram Moolenaar3049fcf2022-01-13 19:25:50 +00002448 delete('Xdir', 'rf')
2449 &rtp = save_rtp
2450enddef
2451
Bram Moolenaar160aa862022-01-10 21:29:57 +00002452" This was causing a crash because suppress_errthrow wasn't reset.
2453def Test_vim9_autoload_error()
2454 var lines =<< trim END
2455 vim9script
2456 def crash#func()
2457 try
2458 for x in List()
2459 endfor
2460 catch
2461 endtry
2462 g:ok = true
2463 enddef
2464 fu List()
2465 invalid
2466 endfu
2467 try
2468 alsoinvalid
2469 catch /wontmatch/
2470 endtry
2471 END
2472 call mkdir('Xruntime/autoload', 'p')
2473 call writefile(lines, 'Xruntime/autoload/crash.vim')
2474
2475 # run in a separate Vim to avoid the side effects of assert_fails()
2476 lines =<< trim END
2477 exe 'set rtp^=' .. getcwd() .. '/Xruntime'
2478 call crash#func()
2479 call writefile(['ok'], 'Xdidit')
2480 qall!
2481 END
2482 writefile(lines, 'Xscript')
Bram Moolenaar62aec932022-01-29 21:45:34 +00002483 g:RunVim([], [], '-S Xscript')
Bram Moolenaar160aa862022-01-10 21:29:57 +00002484 assert_equal(['ok'], readfile('Xdidit'))
2485
2486 delete('Xdidit')
2487 delete('Xscript')
2488 delete('Xruntime', 'rf')
2489
2490 lines =<< trim END
2491 vim9script
2492 var foo#bar = 'asdf'
2493 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002494 v9.CheckScriptFailure(lines, 'E461: Illegal variable name: foo#bar', 2)
Bram Moolenaar160aa862022-01-10 21:29:57 +00002495enddef
2496
Bram Moolenaard8448622022-01-07 21:39:52 +00002497
2498" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker