blob: c26ccf80aa71b5ef0f77079481019bc9100f6c4a [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
6source vim9.vim
7
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
36def Undo_export_script_lines()
37 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
145 var line_break_before_dot =<< trim END
146 vim9script
147 import './Xexport.vim' as expo
148 g:exported = expo
149 .exported
150 END
151 writefile(line_break_before_dot, 'Ximport_lbr_before_dot.vim')
152 assert_fails('source Ximport_lbr_before_dot.vim', 'E1060:', '', 3)
153 delete('Ximport_lbr_before_dot.vim')
154
155 var line_break_after_dot =<< trim END
156 vim9script
157 import './Xexport.vim' as expo
158 g:exported = expo.
159 exported
160 END
161 writefile(line_break_after_dot, 'Ximport_lbr_after_dot.vim')
162 assert_fails('source Ximport_lbr_after_dot.vim', 'E1074:', '', 3)
163 delete('Ximport_lbr_after_dot.vim')
164
165 var import_star_as_lines =<< trim END
166 vim9script
167 import './Xexport.vim' as Export
168 def UseExport()
169 g:exported_def = Export.exported
170 enddef
171 g:exported_script = Export.exported
172 assert_equal(1, exists('Export.exported'))
173 assert_equal(0, exists('Export.notexported'))
174 UseExport()
175 END
176 writefile(import_star_as_lines, 'Ximport.vim')
177 source Ximport.vim
178
179 assert_equal(18, g:exported_def)
180 assert_equal(18, g:exported_script)
181 unlet g:exported_def
182 unlet g:exported_script
183
184 var import_star_as_lines_no_dot =<< trim END
185 vim9script
186 import './Xexport.vim' as Export
187 def Func()
188 var dummy = 1
189 var imported = Export + dummy
190 enddef
191 defcompile
192 END
193 writefile(import_star_as_lines_no_dot, 'Ximport.vim')
194 assert_fails('source Ximport.vim', 'E1060:', '', 2, 'Func')
195
196 var import_star_as_lines_dot_space =<< trim END
197 vim9script
198 import './Xexport.vim' as Export
199 def Func()
200 var imported = Export . exported
201 enddef
202 defcompile
203 END
204 writefile(import_star_as_lines_dot_space, 'Ximport.vim')
205 assert_fails('source Ximport.vim', 'E1074:', '', 1, 'Func')
206
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000207 writefile(s:export_script_lines, 'Xexport2.vim')
208 var import_as_duplicated =<< trim END
Bram Moolenaard8448622022-01-07 21:39:52 +0000209 vim9script
210 import './Xexport.vim' as expo
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000211 import './Xexport2.vim' as expo
Bram Moolenaard8448622022-01-07 21:39:52 +0000212 END
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000213 writefile(import_as_duplicated, 'Ximport.vim')
Bram Moolenaard8448622022-01-07 21:39:52 +0000214 assert_fails('source Ximport.vim', 'E1073:', '', 3, 'Ximport.vim')
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000215 delete('Xexport2.vim')
Bram Moolenaard8448622022-01-07 21:39:52 +0000216
217 var import_star_as_lines_script_no_dot =<< trim END
218 vim9script
219 import './Xexport.vim' as Export
220 g:imported_script = Export exported
221 END
222 writefile(import_star_as_lines_script_no_dot, 'Ximport.vim')
223 assert_fails('source Ximport.vim', 'E1060: Expected dot after name: Export exported')
224
225 var import_star_as_lines_script_space_after_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_space_after_dot, 'Ximport.vim')
231 assert_fails('source Ximport.vim', 'E1074:')
232
233 var import_star_as_lines_missing_name =<< trim END
234 vim9script
235 import './Xexport.vim' as Export
236 def Func()
237 var imported = Export.
238 enddef
239 defcompile
240 END
241 writefile(import_star_as_lines_missing_name, 'Ximport.vim')
242 assert_fails('source Ximport.vim', 'E1048:', '', 1, 'Func')
243
244 var import_star_as_lbr_lines =<< trim END
245 vim9script
246 import './Xexport.vim'
247 as Export
248 def UseExport()
249 g:exported = Export.exported
250 enddef
251 UseExport()
252 END
253 writefile(import_star_as_lbr_lines, 'Ximport.vim')
254 source Ximport.vim
255 assert_equal(18, g:exported)
256 unlet g:exported
257
258 # try to use something that exists but is not exported
259 var import_not_exported_lines =<< trim END
260 vim9script
261 import './Xexport.vim' as expo
262 echo expo.name
263 END
264 writefile(import_not_exported_lines, 'Ximport.vim')
265 assert_fails('source Ximport.vim', 'E1049:', '', 3, 'Ximport.vim')
266
267 # try to import something that is already defined
268 var import_already_defined =<< trim END
269 vim9script
270 var exported = 'something'
271 import './Xexport.vim' as exported
272 END
273 writefile(import_already_defined, 'Ximport.vim')
274 assert_fails('source Ximport.vim', 'E1054:', '', 3, 'Ximport.vim')
275
276 # try changing an imported const
277 var import_assign_to_const =<< trim END
278 vim9script
279 import './Xexport.vim' as expo
280 def Assign()
281 expo.CONST = 987
282 enddef
283 defcompile
284 END
285 writefile(import_assign_to_const, 'Ximport.vim')
286 assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign')
287
288 # try changing an imported final
289 var import_assign_to_final =<< trim END
290 vim9script
291 import './Xexport.vim' as expo
292 def Assign()
293 expo.theList = [2]
294 enddef
295 defcompile
296 END
297 writefile(import_assign_to_final, 'Ximport.vim')
298 assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign')
299
300 var import_no_as_lines =<< trim END
301 vim9script
302 import './Xexport.vim' name
303 END
304 writefile(import_no_as_lines, 'Ximport.vim')
305 assert_fails('source Ximport.vim', 'E488:', '', 2, 'Ximport.vim')
306
307 var import_invalid_string_lines =<< trim END
308 vim9script
309 import Xexport.vim
310 END
311 writefile(import_invalid_string_lines, 'Ximport.vim')
312 assert_fails('source Ximport.vim', 'E121:', '', 2, 'Ximport.vim')
313
314 var import_wrong_name_lines =<< trim END
315 vim9script
316 import './XnoExport.vim'
317 END
318 writefile(import_wrong_name_lines, 'Ximport.vim')
319 assert_fails('source Ximport.vim', 'E1053:', '', 2, 'Ximport.vim')
320
321 var import_redefining_lines =<< trim END
322 vim9script
323 import './Xexport.vim' as exported
324 var exported = 5
325 END
326 writefile(import_redefining_lines, 'Ximport.vim')
327 assert_fails('source Ximport.vim', 'E1213: Redefining imported item "exported"', '', 3)
328
Bram Moolenaar160aa862022-01-10 21:29:57 +0000329 var import_missing_dot_lines =<< trim END
330 vim9script
331 import './Xexport.vim' as expo
332 def Test()
333 expo = 9
334 enddef
335 defcompile
336 END
337 writefile(import_missing_dot_lines, 'Ximport.vim')
338 assert_fails('source Ximport.vim', 'E1258:', '', 1)
339
340 var import_missing_name_lines =<< trim END
341 vim9script
342 import './Xexport.vim' as expo
343 def Test()
344 expo.99 = 9
345 enddef
346 defcompile
347 END
348 writefile(import_missing_name_lines, 'Ximport.vim')
Bram Moolenaar76283822022-01-10 21:39:03 +0000349 assert_fails('source Ximport.vim', 'E1259:', '', 1)
Bram Moolenaar160aa862022-01-10 21:29:57 +0000350
Bram Moolenaard8448622022-01-07 21:39:52 +0000351 var import_assign_wrong_type_lines =<< trim END
352 vim9script
353 import './Xexport.vim' as expo
354 expo.exported = 'xxx'
355 END
356 writefile(import_assign_wrong_type_lines, 'Ximport.vim')
357 assert_fails('source Ximport.vim', 'E1012: Type mismatch; expected number but got string', '', 3)
358
359 var import_assign_const_lines =<< trim END
360 vim9script
361 import './Xexport.vim' as expo
362 expo.CONST = 4321
363 END
364 writefile(import_assign_const_lines, 'Ximport.vim')
365 assert_fails('source Ximport.vim', 'E46: Cannot change read-only variable "CONST"', '', 3)
366
367 delete('Ximport.vim')
368 delete('Ximport3.vim')
369 delete('Xexport.vim')
370
371 # Check that in a Vim9 script 'cpo' is set to the Vim default.
372 # Flags added or removed are also applied to the restored value.
373 set cpo=abcd
374 var lines =<< trim END
375 vim9script
376 g:cpo_in_vim9script = &cpo
377 set cpo+=f
378 set cpo-=c
379 g:cpo_after_vim9script = &cpo
380 END
381 writefile(lines, 'Xvim9_script')
382 source Xvim9_script
383 assert_equal('fabd', &cpo)
384 set cpo&vim
385 assert_equal(&cpo, g:cpo_in_vim9script)
386 var newcpo = substitute(&cpo, 'c', '', '') .. 'f'
387 assert_equal(newcpo, g:cpo_after_vim9script)
388
389 delete('Xvim9_script')
390enddef
391
392def Test_import_funcref()
393 var lines =<< trim END
394 vim9script
395 export def F(): number
396 return 42
397 enddef
398 export const G = F
399 END
400 writefile(lines, 'Xlib.vim')
401
402 lines =<< trim END
403 vim9script
404 import './Xlib.vim' as lib
405 const Foo = lib.G()
406 assert_equal(42, Foo)
407
408 def DoTest()
409 const Goo = lib.G()
410 assert_equal(42, Goo)
411 enddef
412 DoTest()
413 END
414 CheckScriptSuccess(lines)
415
416 delete('Xlib.vim')
417enddef
418
419def Test_import_fails()
420 writefile([], 'Xfoo.vim')
421 var lines =<< trim END
422 import './Xfoo.vim' as foo
423 foo = 'bar'
424 END
425 CheckDefAndScriptFailure(lines, ['E1094:', 'E1236: Cannot use foo itself'])
426 lines =<< trim END
427 vim9script
428 import './Xfoo.vim' as foo
429 var that = foo
430 END
431 CheckScriptFailure(lines, 'E1060: Expected dot after name: foo')
432
433 lines =<< trim END
434 vim9script
435 import './Xfoo.vim' as 9foo
436 END
437 CheckScriptFailure(lines, 'E1047:')
438 lines =<< trim END
439 vim9script
440 import './Xfoo.vim' as the#foo
441 END
442 CheckScriptFailure(lines, 'E1047:')
443 lines =<< trim END
444 vim9script
445 import './Xfoo.vim' as g:foo
446 END
447 CheckScriptFailure(lines, 'E1047:')
448
449 delete('Xfoo.vim')
450
451 lines =<< trim END
452 vim9script
453 def TheFunc()
454 echo 'the func'
455 enddef
456 export var Ref = TheFunc
457 END
458 writefile([], 'Xthat.vim')
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000459
Bram Moolenaard8448622022-01-07 21:39:52 +0000460 lines =<< trim END
461 import './Xthat.vim' as That
462 That()
463 END
464 CheckDefAndScriptFailure(lines, ['E1094:', 'E1236: Cannot use That itself'])
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000465
466 lines =<< trim END
Bram Moolenaar937610b2022-01-19 17:21:29 +0000467 vim9script
468 import './Xthat.vim' as That
469 def Func()
470 echo That()
471 enddef
472 Func()
473 END
474 CheckScriptFailure(lines, 'E1236: Cannot use That itself')
475
476 lines =<< trim END
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000477 import './Xthat.vim' as one
478 import './Xthat.vim' as two
479 END
480 CheckScriptFailure(lines, 'E1262:')
481
482 delete('Xthat.vim')
Bram Moolenaard8448622022-01-07 21:39:52 +0000483
484 mkdir('Ximport')
485
486 writefile(['vim9script'], 'Ximport/.vim')
487 lines =<< trim END
488 vim9script
489 import './Ximport/.vim'
490 END
491 CheckScriptFailure(lines, 'E1261: Cannot import .vim without using "as"')
492 lines =<< trim END
493 vim9script
494 import './Ximport/.vim' as vim
495 END
496 CheckScriptSuccess(lines)
497
498 writefile(['vim9script'], 'Ximport/.vimrc')
499 lines =<< trim END
500 vim9script
501 import './Ximport/.vimrc'
502 END
503 CheckScriptFailure(lines, 'E1257: Imported script must use "as" or end in .vim')
504 lines =<< trim END
505 vim9script
506 import './Ximport/.vimrc' as vimrc
507 END
508 CheckScriptSuccess(lines)
509
510 delete('Ximport', 'rf')
511enddef
512
513func g:Trigger()
514 source Ximport.vim
515 return "echo 'yes'\<CR>"
516endfunc
517
518def Test_import_export_expr_map()
519 # check that :import and :export work when buffer is locked
520 var export_lines =<< trim END
521 vim9script
522 export def That(): string
523 return 'yes'
524 enddef
525 END
526 writefile(export_lines, 'Xexport_that.vim')
527
528 var import_lines =<< trim END
529 vim9script
530 import './Xexport_that.vim' as that
531 assert_equal('yes', that.That())
532 END
533 writefile(import_lines, 'Ximport.vim')
534
535 nnoremap <expr> trigger g:Trigger()
536 feedkeys('trigger', "xt")
537
538 delete('Xexport_that.vim')
539 delete('Ximport.vim')
540 nunmap trigger
541enddef
542
543def Test_import_in_filetype()
544 # check that :import works when the buffer is locked
545 mkdir('ftplugin', 'p')
546 var export_lines =<< trim END
547 vim9script
548 export var That = 'yes'
549 END
550 writefile(export_lines, 'ftplugin/Xexport_ft.vim')
551
552 var import_lines =<< trim END
553 vim9script
554 import './Xexport_ft.vim' as ft
555 assert_equal('yes', ft.That)
556 g:did_load_mytpe = 1
557 END
558 writefile(import_lines, 'ftplugin/qf.vim')
559
560 var save_rtp = &rtp
561 &rtp = getcwd() .. ',' .. &rtp
562
563 filetype plugin on
564 copen
565 assert_equal(1, g:did_load_mytpe)
566
567 quit!
568 delete('Xexport_ft.vim')
569 delete('ftplugin', 'rf')
570 &rtp = save_rtp
571enddef
572
573def Test_use_import_in_mapping()
574 var lines =<< trim END
575 vim9script
576 export def Funcx()
577 g:result = 42
578 enddef
579 END
580 writefile(lines, 'XsomeExport.vim')
581 lines =<< trim END
582 vim9script
583 import './XsomeExport.vim' as some
584 var Funcy = some.Funcx
585 nnoremap <F3> :call <sid>Funcy()<cr>
586 END
587 writefile(lines, 'Xmapscript.vim')
588
589 source Xmapscript.vim
590 feedkeys("\<F3>", "xt")
591 assert_equal(42, g:result)
592
593 unlet g:result
594 delete('XsomeExport.vim')
595 delete('Xmapscript.vim')
596 nunmap <F3>
597enddef
598
Bram Moolenaar15d16352022-01-17 20:09:08 +0000599def Test_use_import_in_completion()
600 var lines =<< trim END
601 vim9script
602 export def Complete(..._): list<string>
603 return ['abcd']
604 enddef
605 END
606 writefile(lines, 'Xscript.vim')
607
608 lines =<< trim END
609 vim9script
610 import './Xscript.vim'
611
612 command -nargs=1 -complete=customlist,Xscript.Complete Cmd echo 'ok'
613 feedkeys(":Cmd ab\<Tab>\<C-B>#\<CR>", 'xnt')
614 assert_equal('#Cmd abcd', @:)
615 END
616 CheckScriptSuccess(lines)
617
618 delcommand Cmd
619 delete('Xscript.vim')
620enddef
621
Bram Moolenaard8448622022-01-07 21:39:52 +0000622def Test_export_fails()
623 CheckScriptFailure(['export var some = 123'], 'E1042:')
624 CheckScriptFailure(['vim9script', 'export var g:some'], 'E1022:')
625 CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
626
627 assert_fails('export something', 'E1043:')
628enddef
629
630func Test_import_fails_without_script()
631 CheckRunVimInTerminal
632
633 " call indirectly to avoid compilation error for missing functions
634 call Run_Test_import_fails_on_command_line()
635endfunc
636
637def Run_Test_import_fails_on_command_line()
638 var export =<< trim END
639 vim9script
640 export def Foo(): number
641 return 0
642 enddef
643 END
644 writefile(export, 'XexportCmd.vim')
645
646 var buf = RunVimInTerminal('-c "import Foo from ''./XexportCmd.vim''"', {
647 rows: 6, wait_for_ruler: 0})
648 WaitForAssert(() => assert_match('^E1094:', term_getline(buf, 5)))
649
650 delete('XexportCmd.vim')
651 StopVimInTerminal(buf)
652enddef
653
654def Test_vim9_reload_noclear()
655 var lines =<< trim END
656 vim9script
657 export var exported = 'thexport'
658
659 export def TheFunc(x = 0)
660 enddef
661 END
662 writefile(lines, 'XExportReload')
663 lines =<< trim END
664 vim9script noclear
665 g:loadCount += 1
666 var s:reloaded = 'init'
667 import './XExportReload' as exp
668
669 def Again(): string
670 return 'again'
671 enddef
672
673 exp.TheFunc()
674
675 if exists('s:loaded') | finish | endif
676 var s:loaded = true
677
678 var s:notReloaded = 'yes'
679 s:reloaded = 'first'
680 def g:Values(): list<string>
681 return [s:reloaded, s:notReloaded, Again(), Once(), exp.exported]
682 enddef
683
684 def Once(): string
685 return 'once'
686 enddef
687 END
688 writefile(lines, 'XReloaded')
689 g:loadCount = 0
690 source XReloaded
691 assert_equal(1, g:loadCount)
692 assert_equal(['first', 'yes', 'again', 'once', 'thexport'], g:Values())
693 source XReloaded
694 assert_equal(2, g:loadCount)
695 assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values())
696 source XReloaded
697 assert_equal(3, g:loadCount)
698 assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values())
699
700 delete('XReloaded')
701 delete('XExportReload')
702 delfunc g:Values
703 unlet g:loadCount
704
705 lines =<< trim END
706 vim9script
707 def Inner()
708 enddef
709 END
710 lines->writefile('XreloadScript.vim')
711 source XreloadScript.vim
712
713 lines =<< trim END
714 vim9script
715 def Outer()
716 def Inner()
717 enddef
718 enddef
719 defcompile
720 END
721 lines->writefile('XreloadScript.vim')
722 source XreloadScript.vim
723
724 delete('XreloadScript.vim')
725enddef
726
727def Test_vim9_reload_import()
728 var lines =<< trim END
729 vim9script
730 const var = ''
731 var valone = 1234
732 def MyFunc(arg: string)
733 valone = 5678
734 enddef
735 END
736 var morelines =<< trim END
737 var valtwo = 222
738 export def GetValtwo(): number
739 return valtwo
740 enddef
741 END
742 writefile(lines + morelines, 'Xreload.vim')
743 source Xreload.vim
744 source Xreload.vim
745 source Xreload.vim
746
747 # cannot declare a var twice
748 lines =<< trim END
749 vim9script
750 var valone = 1234
751 var valone = 5678
752 END
753 writefile(lines, 'Xreload.vim')
754 assert_fails('source Xreload.vim', 'E1041:', '', 3, 'Xreload.vim')
755
756 delete('Xreload.vim')
757 delete('Ximport.vim')
758enddef
759
760" if a script is reloaded with a script-local variable that changed its type, a
761" compiled function using that variable must fail.
762def Test_script_reload_change_type()
763 var lines =<< trim END
764 vim9script noclear
765 var str = 'string'
766 def g:GetStr(): string
767 return str .. 'xxx'
768 enddef
769 END
770 writefile(lines, 'Xreload.vim')
771 source Xreload.vim
772 echo g:GetStr()
773
774 lines =<< trim END
775 vim9script noclear
776 var str = 1234
777 END
778 writefile(lines, 'Xreload.vim')
779 source Xreload.vim
780 assert_fails('echo g:GetStr()', 'E1150:')
781
782 delfunc g:GetStr
783 delete('Xreload.vim')
784enddef
785
786" Define CallFunc so that the test can be compiled
787command CallFunc echo 'nop'
788
789def Test_script_reload_from_function()
790 var lines =<< trim END
791 vim9script
792
793 if exists('g:loaded')
794 finish
795 endif
796 g:loaded = 1
797 delcommand CallFunc
798 command CallFunc Func()
799 def Func()
800 so XreloadFunc.vim
801 g:didTheFunc = 1
802 enddef
803 END
804 writefile(lines, 'XreloadFunc.vim')
805 source XreloadFunc.vim
806 CallFunc
807 assert_equal(1, g:didTheFunc)
808
809 delete('XreloadFunc.vim')
810 delcommand CallFunc
811 unlet g:loaded
812 unlet g:didTheFunc
813enddef
814
815def s:RetSome(): string
816 return 'some'
817enddef
818
819" Not exported function that is referenced needs to be accessed by the
820" script-local name.
821def Test_vim9_funcref()
822 var sortlines =<< trim END
823 vim9script
824 def Compare(i1: number, i2: number): number
825 return i2 - i1
826 enddef
827
828 export def FastSort(): list<number>
829 return range(5)->sort(Compare)
830 enddef
831
832 export def GetString(arg: string): string
833 return arg
834 enddef
835 END
836 writefile(sortlines, 'Xsort.vim')
837
838 var lines =<< trim END
839 vim9script
840 import './Xsort.vim'
841 def Test()
842 g:result = Xsort.FastSort()
843 enddef
844 Test()
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000845 END
846 writefile(lines, 'Xscript.vim')
847 source Xscript.vim
848 assert_equal([4, 3, 2, 1, 0], g:result)
849 unlet g:result
Bram Moolenaard8448622022-01-07 21:39:52 +0000850
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000851 lines =<< trim END
852 vim9script
Bram Moolenaard8448622022-01-07 21:39:52 +0000853 # using a function imported with "as"
854 import './Xsort.vim' as anAlias
855 assert_equal('yes', anAlias.GetString('yes'))
856
857 # using the function from a compiled function
858 def TestMore(): string
859 var s = s:anAlias.GetString('foo')
860 return s .. anAlias.GetString('bar')
861 enddef
862 assert_equal('foobar', TestMore())
863
864 # error when using a function that isn't exported
865 assert_fails('anAlias.Compare(1, 2)', 'E1049:')
866 END
867 writefile(lines, 'Xscript.vim')
868
Bram Moolenaard8448622022-01-07 21:39:52 +0000869 delete('Xsort.vim')
870 delete('Xscript.vim')
871
872 var Funcref = function('s:RetSome')
873 assert_equal('some', Funcref())
874enddef
875
876" Check that when searching for "FilterFunc" it finds the import in the
877" script where FastFilter() is called from, both as a string and as a direct
878" function reference.
879def Test_vim9_funcref_other_script()
880 var filterLines =<< trim END
881 vim9script
882 export def FilterFunc(idx: number, val: number): bool
883 return idx % 2 == 1
884 enddef
885 export def FastFilter(): list<number>
886 return range(10)->filter('FilterFunc(v:key, v:val)')
887 enddef
888 export def FastFilterDirect(): list<number>
889 return range(10)->filter(FilterFunc)
890 enddef
891 END
892 writefile(filterLines, 'Xfilter.vim')
893
894 var lines =<< trim END
895 vim9script
896 import './Xfilter.vim' as filter
897 def Test()
898 var x: list<number> = filter.FastFilter()
899 enddef
900 Test()
901 def TestDirect()
902 var x: list<number> = filter.FastFilterDirect()
903 enddef
904 TestDirect()
905 END
906 CheckScriptSuccess(lines)
907 delete('Xfilter.vim')
908enddef
909
910def Test_import_absolute()
911 var import_lines = [
912 'vim9script',
913 'import "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim" as abs',
914 'def UseExported()',
915 ' g:imported_abs = abs.exported',
916 ' abs.exported = 8888',
917 ' g:imported_after = abs.exported',
918 'enddef',
919 'UseExported()',
920 'g:import_disassembled = execute("disass UseExported")',
921 ]
922 writefile(import_lines, 'Ximport_abs.vim')
923 writefile(s:export_script_lines, 'Xexport_abs.vim')
924
925 source Ximport_abs.vim
926
927 assert_equal(9876, g:imported_abs)
928 assert_equal(8888, g:imported_after)
929 assert_match('<SNR>\d\+_UseExported\_s*' ..
930 'g:imported_abs = abs.exported\_s*' ..
931 '0 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' ..
932 '1 STOREG g:imported_abs\_s*' ..
933 'abs.exported = 8888\_s*' ..
934 '2 PUSHNR 8888\_s*' ..
935 '3 STORESCRIPT exported-2 in .*Xexport_abs.vim\_s*' ..
936 'g:imported_after = abs.exported\_s*' ..
937 '4 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' ..
938 '5 STOREG g:imported_after',
939 g:import_disassembled)
940
941 Undo_export_script_lines()
942 unlet g:imported_abs
943 unlet g:import_disassembled
944
945 delete('Ximport_abs.vim')
946 delete('Xexport_abs.vim')
947enddef
948
949def Test_import_rtp()
950 var import_lines = [
951 'vim9script',
952 'import "Xexport_rtp.vim" as rtp',
953 'g:imported_rtp = rtp.exported',
954 ]
955 writefile(import_lines, 'Ximport_rtp.vim')
956 mkdir('import', 'p')
957 writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
958
959 var save_rtp = &rtp
960 &rtp = getcwd()
961 source Ximport_rtp.vim
962 &rtp = save_rtp
963
964 assert_equal(9876, g:imported_rtp)
965
966 Undo_export_script_lines()
967 unlet g:imported_rtp
968 delete('Ximport_rtp.vim')
969 delete('import', 'rf')
970enddef
971
972def Test_import_compile_error()
973 var export_lines = [
974 'vim9script',
975 'export def ExpFunc(): string',
976 ' return notDefined',
977 'enddef',
978 ]
979 writefile(export_lines, 'Xexported.vim')
980
981 var import_lines = [
982 'vim9script',
983 'import "./Xexported.vim" as expo',
984 'def ImpFunc()',
985 ' echo expo.ExpFunc()',
986 'enddef',
987 'defcompile',
988 ]
989 writefile(import_lines, 'Ximport.vim')
990
991 try
992 source Ximport.vim
993 catch /E1001/
994 # Error should be before the Xexported.vim file.
995 assert_match('E1001: Variable not found: notDefined', v:exception)
996 assert_match('function <SNR>\d\+_ImpFunc\[1\]..<SNR>\d\+_ExpFunc, line 1', v:throwpoint)
997 endtry
998
999 delete('Xexported.vim')
1000 delete('Ximport.vim')
1001enddef
1002
1003def Test_func_overrules_import_fails()
1004 var export_lines =<< trim END
1005 vim9script
1006 export def Func()
1007 echo 'imported'
1008 enddef
1009 END
1010 writefile(export_lines, 'XexportedFunc.vim')
1011
1012 var lines =<< trim END
1013 vim9script
1014 import './XexportedFunc.vim' as Func
1015 def Func()
1016 echo 'local to function'
1017 enddef
1018 END
Bram Moolenaar937610b2022-01-19 17:21:29 +00001019 CheckScriptFailure(lines, 'E1213: Redefining imported item "Func"')
Bram Moolenaard8448622022-01-07 21:39:52 +00001020
1021 lines =<< trim END
1022 vim9script
1023 import './XexportedFunc.vim' as Func
1024 def Outer()
1025 def Func()
1026 echo 'local to function'
1027 enddef
1028 enddef
1029 defcompile
1030 END
1031 CheckScriptFailure(lines, 'E1236:')
1032
1033 delete('XexportedFunc.vim')
1034enddef
1035
1036def Test_source_vim9_from_legacy()
1037 var vim9_lines =<< trim END
1038 vim9script
1039 var local = 'local'
1040 g:global = 'global'
1041 export var exported = 'exported'
1042 export def GetText(): string
1043 return 'text'
1044 enddef
1045 END
1046 writefile(vim9_lines, 'Xvim9_script.vim')
1047
1048 var legacy_lines =<< trim END
1049 source Xvim9_script.vim
1050
1051 call assert_false(exists('local'))
1052 call assert_false(exists('exported'))
1053 call assert_false(exists('s:exported'))
1054 call assert_equal('global', global)
1055 call assert_equal('global', g:global)
Bram Moolenaard8448622022-01-07 21:39:52 +00001056 END
1057 writefile(legacy_lines, 'Xlegacy_script.vim')
1058
1059 source Xlegacy_script.vim
1060 assert_equal('global', g:global)
1061 unlet g:global
1062
1063 delete('Xlegacy_script.vim')
1064 delete('Xvim9_script.vim')
1065enddef
1066
Bram Moolenaarc43e6232022-01-13 20:51:56 +00001067def Test_import_vim9_from_legacy()
1068 var vim9_lines =<< trim END
1069 vim9script
1070 var local = 'local'
1071 g:global = 'global'
1072 export var exported = 'exported'
1073 export def GetText(): string
1074 return 'text'
1075 enddef
1076 END
1077 writefile(vim9_lines, 'Xvim9_export.vim')
1078
1079 var legacy_lines =<< trim END
1080 import './Xvim9_export.vim' as vim9
1081
1082 call assert_false(exists('vim9'))
1083 call assert_false(exists('local'))
1084 call assert_false(exists('s:vim9.local'))
1085 call assert_equal('global', global)
1086 call assert_equal('global', g:global)
1087 call assert_false(exists('exported'))
1088 call assert_false(exists('s:exported'))
1089 call assert_false(exists('*GetText'))
1090
1091 " imported symbol is script-local
1092 call assert_equal('exported', s:vim9.exported)
1093 call assert_equal('text', s:vim9.GetText())
1094 END
1095 writefile(legacy_lines, 'Xlegacy_script.vim')
1096
1097 source Xlegacy_script.vim
1098 assert_equal('global', g:global)
1099 unlet g:global
1100
1101 delete('Xlegacy_script.vim')
1102 delete('Xvim9_export.vim')
1103enddef
1104
Bram Moolenaard8448622022-01-07 21:39:52 +00001105def Test_cmdline_win()
1106 # if the Vim syntax highlighting uses Vim9 constructs they can be used from
1107 # the command line window.
1108 mkdir('rtp/syntax', 'p')
1109 var export_lines =<< trim END
1110 vim9script
1111 export var That = 'yes'
1112 END
1113 writefile(export_lines, 'rtp/syntax/Xexport.vim')
1114 var import_lines =<< trim END
1115 vim9script
1116 import './Xexport.vim' as exp
1117 echo exp.That
1118 END
1119 writefile(import_lines, 'rtp/syntax/vim.vim')
1120 var save_rtp = &rtp
1121 &rtp = getcwd() .. '/rtp' .. ',' .. &rtp
1122 syntax on
1123 augroup CmdWin
1124 autocmd CmdwinEnter * g:got_there = 'yes'
1125 augroup END
1126 # this will open and also close the cmdline window
1127 feedkeys('q:', 'xt')
1128 assert_equal('yes', g:got_there)
1129
1130 augroup CmdWin
1131 au!
1132 augroup END
1133 &rtp = save_rtp
1134 delete('rtp', 'rf')
1135enddef
1136
1137def Test_import_gone_when_sourced_twice()
1138 var exportlines =<< trim END
1139 vim9script
1140 if exists('g:guard')
1141 finish
1142 endif
1143 g:guard = 1
1144 export var name = 'someName'
1145 END
1146 writefile(exportlines, 'XexportScript.vim')
1147
1148 var lines =<< trim END
1149 vim9script
1150 import './XexportScript.vim' as expo
1151 def g:GetName(): string
1152 return expo.name
1153 enddef
1154 END
1155 writefile(lines, 'XscriptImport.vim')
1156 so XscriptImport.vim
1157 assert_equal('someName', g:GetName())
1158
1159 so XexportScript.vim
1160 assert_fails('call g:GetName()', 'E1149:')
1161
1162 delfunc g:GetName
1163 delete('XexportScript.vim')
1164 delete('XscriptImport.vim')
1165 unlet g:guard
1166enddef
1167
Bram Moolenaar160aa862022-01-10 21:29:57 +00001168" test using an auto-loaded function and variable
Bram Moolenaar0e3e7ba2022-01-13 20:18:56 +00001169def Test_vim9_autoload_full_name()
Bram Moolenaar160aa862022-01-10 21:29:57 +00001170 var lines =<< trim END
1171 vim9script
1172 def some#gettest(): string
1173 return 'test'
1174 enddef
1175 g:some#name = 'name'
1176 g:some#dict = {key: 'value'}
1177
1178 def some#varargs(a1: string, ...l: list<string>): string
1179 return a1 .. l[0] .. l[1]
1180 enddef
1181 END
1182
1183 mkdir('Xdir/autoload', 'p')
1184 writefile(lines, 'Xdir/autoload/some.vim')
1185 var save_rtp = &rtp
1186 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1187
1188 assert_equal('test', g:some#gettest())
1189 assert_equal('name', g:some#name)
1190 assert_equal('value', g:some#dict.key)
1191 g:some#other = 'other'
1192 assert_equal('other', g:some#other)
1193
1194 assert_equal('abc', some#varargs('a', 'b', 'c'))
1195
1196 # upper case script name works
1197 lines =<< trim END
1198 vim9script
1199 def Other#getOther(): string
1200 return 'other'
1201 enddef
1202 END
1203 writefile(lines, 'Xdir/autoload/Other.vim')
1204 assert_equal('other', g:Other#getOther())
1205
1206 delete('Xdir', 'rf')
1207 &rtp = save_rtp
1208enddef
1209
1210def Test_vim9script_autoload()
1211 mkdir('Xdir/autoload', 'p')
1212 var save_rtp = &rtp
1213 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1214
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001215 # when the path has "/autoload/" prefix is not needed
Bram Moolenaar160aa862022-01-10 21:29:57 +00001216 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001217 vim9script
Bram Moolenaar17d36cb2022-01-12 11:46:40 +00001218 g:prefixed_loaded += 1
Bram Moolenaar160aa862022-01-10 21:29:57 +00001219
1220 export def Gettest(): string
1221 return 'test'
1222 enddef
1223
Bram Moolenaar0e3e7ba2022-01-13 20:18:56 +00001224 export var name = 'name'
1225
1226 export func GetFunc()
1227 return Gettest() .. 'more' .. s:name
Bram Moolenaar160aa862022-01-10 21:29:57 +00001228 endfunc
1229
Bram Moolenaar0e3e7ba2022-01-13 20:18:56 +00001230 export def GetDef(): string
1231 return Gettest() .. 'more' .. name
1232 enddef
1233
Bram Moolenaar160aa862022-01-10 21:29:57 +00001234 export final fname = 'final'
1235 export const cname = 'const'
1236 END
1237 writefile(lines, 'Xdir/autoload/prefixed.vim')
1238
Bram Moolenaar17d36cb2022-01-12 11:46:40 +00001239 g:prefixed_loaded = 0
1240 g:expected_loaded = 0
Bram Moolenaar160aa862022-01-10 21:29:57 +00001241 lines =<< trim END
1242 vim9script
1243 import autoload 'prefixed.vim'
Bram Moolenaar17d36cb2022-01-12 11:46:40 +00001244 assert_equal(g:expected_loaded, g:prefixed_loaded)
Bram Moolenaar160aa862022-01-10 21:29:57 +00001245 assert_equal('test', prefixed.Gettest())
Bram Moolenaar17d36cb2022-01-12 11:46:40 +00001246 assert_equal(1, g:prefixed_loaded)
Bram Moolenaar160aa862022-01-10 21:29:57 +00001247
Bram Moolenaar0e3e7ba2022-01-13 20:18:56 +00001248 assert_equal('testmorename', prefixed.GetFunc())
1249 assert_equal('testmorename', prefixed.GetDef())
Bram Moolenaar160aa862022-01-10 21:29:57 +00001250 assert_equal('name', prefixed.name)
1251 assert_equal('final', prefixed.fname)
1252 assert_equal('const', prefixed.cname)
1253 END
1254 CheckScriptSuccess(lines)
Bram Moolenaar17d36cb2022-01-12 11:46:40 +00001255 # can source it again, autoload script not loaded again
1256 g:expected_loaded = 1
1257 CheckScriptSuccess(lines)
Bram Moolenaar160aa862022-01-10 21:29:57 +00001258
1259 # can also get the items by autoload name
1260 lines =<< trim END
1261 call assert_equal('test', prefixed#Gettest())
Bram Moolenaar0e3e7ba2022-01-13 20:18:56 +00001262 call assert_equal('testmorename', prefixed#GetFunc())
Bram Moolenaar160aa862022-01-10 21:29:57 +00001263 call assert_equal('name', prefixed#name)
1264 call assert_equal('final', prefixed#fname)
1265 call assert_equal('const', prefixed#cname)
1266 END
1267 CheckScriptSuccess(lines)
1268
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00001269 unlet g:prefixed_loaded
1270 unlet g:expected_loaded
1271 delete('Xdir', 'rf')
1272 &rtp = save_rtp
1273enddef
1274
Bram Moolenaard02dce22022-01-18 17:43:04 +00001275def Test_import_autoload_not_exported()
1276 mkdir('Xdir/autoload', 'p')
1277 var save_rtp = &rtp
1278 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1279
1280 # error when using an item that is not exported from an autoload script
1281 var exportLines =<< trim END
1282 vim9script
1283 var notExported = 123
1284 def NotExport()
1285 echo 'nop'
1286 enddef
1287 END
1288 writefile(exportLines, 'Xdir/autoload/notExport1.vim')
1289
1290 var lines =<< trim END
1291 vim9script
1292 import autoload 'notExport1.vim'
1293 echo notExport1.notFound
1294 END
1295 CheckScriptFailure(lines, 'E1048: Item not found in script: notFound')
1296
1297 lines =<< trim END
1298 vim9script
1299 import autoload 'notExport1.vim'
1300 echo notExport1.notExported
1301 END
1302 CheckScriptFailure(lines, 'E1049: Item not exported in script: notExported')
1303
1304 lines =<< trim END
1305 vim9script
1306 import autoload 'notExport1.vim'
1307 echo notExport1.NotFunc()
1308 END
1309 CheckScriptFailure(lines, 'E1048: Item not found in script: NotFunc')
1310
1311 lines =<< trim END
1312 vim9script
1313 import autoload 'notExport1.vim'
1314 echo notExport1.NotExport()
1315 END
1316 CheckScriptFailure(lines, 'E1049: Item not exported in script: NotExport')
1317
1318 lines =<< trim END
1319 vim9script
1320 import autoload 'notExport1.vim'
1321 echo 'text'->notExport1.NotFunc()
1322 END
1323 CheckScriptFailure(lines, 'E1048: Item not found in script: NotFunc')
1324
1325 lines =<< trim END
1326 vim9script
1327 import autoload 'notExport1.vim'
1328 echo 'text'->notExport1.NotExport()
1329 END
1330 CheckScriptFailure(lines, 'E1049: Item not exported in script: NotExport')
1331
1332 # using a :def function we use a different autoload script every time so that
1333 # the function is compiled without the script loaded
1334 writefile(exportLines, 'Xdir/autoload/notExport2.vim')
1335 lines =<< trim END
1336 vim9script
1337 import autoload 'notExport2.vim'
1338 def Testit()
1339 echo notExport2.notFound
1340 enddef
1341 Testit()
1342 END
1343 CheckScriptFailure(lines, 'E1048: Item not found in script: notExport2#notFound')
1344
1345 writefile(exportLines, 'Xdir/autoload/notExport3.vim')
1346 lines =<< trim END
1347 vim9script
1348 import autoload 'notExport3.vim'
1349 def Testit()
1350 echo notExport3.notExported
1351 enddef
1352 Testit()
1353 END
1354 # don't get E1049 because it is too complicated to figure out
1355 CheckScriptFailure(lines, 'E1048: Item not found in script: notExport3#notExported')
1356
1357 writefile(exportLines, 'Xdir/autoload/notExport4.vim')
1358 lines =<< trim END
1359 vim9script
1360 import autoload 'notExport4.vim'
1361 def Testit()
1362 echo notExport4.NotFunc()
1363 enddef
1364 Testit()
1365 END
1366 CheckScriptFailure(lines, 'E117: Unknown function: notExport4#NotFunc')
1367
1368 writefile(exportLines, 'Xdir/autoload/notExport5.vim')
1369 lines =<< trim END
1370 vim9script
1371 import autoload 'notExport5.vim'
1372 def Testit()
1373 echo notExport5.NotExport()
1374 enddef
1375 Testit()
1376 END
1377 CheckScriptFailure(lines, 'E117: Unknown function: notExport5#NotExport')
1378
1379 writefile(exportLines, 'Xdir/autoload/notExport6.vim')
1380 lines =<< trim END
1381 vim9script
1382 import autoload 'notExport6.vim'
1383 def Testit()
1384 echo 'text'->notExport6.NotFunc()
1385 enddef
1386 Testit()
1387 END
1388 CheckScriptFailure(lines, 'E117: Unknown function: notExport6#NotFunc')
1389
1390 writefile(exportLines, 'Xdir/autoload/notExport7.vim')
1391 lines =<< trim END
1392 vim9script
1393 import autoload 'notExport7.vim'
1394 def Testit()
1395 echo 'text'->notExport7.NotExport()
1396 enddef
1397 Testit()
1398 END
1399 CheckScriptFailure(lines, 'E117: Unknown function: notExport7#NotExport')
1400
1401 delete('Xdir', 'rf')
1402 &rtp = save_rtp
1403enddef
1404
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00001405def Test_vim9script_autoload_call()
1406 mkdir('Xdir/autoload', 'p')
1407 var save_rtp = &rtp
1408 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1409
1410 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001411 vim9script
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00001412
Bram Moolenaarcbbc48f2022-01-18 12:58:28 +00001413 export def RetArg(arg: string): string
1414 return arg
1415 enddef
1416
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00001417 export def Getother()
1418 g:result = 'other'
1419 enddef
1420 END
Bram Moolenaar5d982692022-01-12 15:15:27 +00001421 writefile(lines, 'Xdir/autoload/another.vim')
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00001422
1423 lines =<< trim END
1424 vim9script
Bram Moolenaar5d982692022-01-12 15:15:27 +00001425 import autoload 'another.vim'
Bram Moolenaarcbbc48f2022-01-18 12:58:28 +00001426
1427 # compile this before 'another.vim' is loaded
1428 def CallAnother()
1429 assert_equal('foo', 'foo'->another.RetArg())
1430 enddef
1431 CallAnother()
1432
Bram Moolenaar5d982692022-01-12 15:15:27 +00001433 call another.Getother()
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00001434 assert_equal('other', g:result)
1435 END
1436 CheckScriptSuccess(lines)
1437
1438 unlet g:result
Bram Moolenaar160aa862022-01-10 21:29:57 +00001439 delete('Xdir', 'rf')
1440 &rtp = save_rtp
1441enddef
1442
Bram Moolenaar9c7cae62022-01-20 19:10:25 +00001443def Test_vim9script_autoload_duplicate()
1444 mkdir('Xdir/autoload', 'p')
1445
1446 var lines =<< trim END
1447 vim9script
1448
1449 export def Func()
1450 enddef
1451
1452 def Func()
1453 enddef
1454 END
1455 writefile(lines, 'Xdir/autoload/dupfunc.vim')
1456 assert_fails('source Xdir/autoload/dupfunc.vim', 'E1073:')
1457
1458 lines =<< trim END
1459 vim9script
1460
1461 def Func()
1462 enddef
1463
1464 export def Func()
1465 enddef
1466 END
1467 writefile(lines, 'Xdir/autoload/dup2func.vim')
1468 assert_fails('source Xdir/autoload/dup2func.vim', 'E1073:')
1469
1470 lines =<< trim END
1471 vim9script
1472
1473 def Func()
1474 enddef
1475
1476 export var Func = 'asdf'
1477 END
1478 writefile(lines, 'Xdir/autoload/dup3func.vim')
1479 assert_fails('source Xdir/autoload/dup3func.vim', 'E1041: Redefining script item Func')
1480
1481 lines =<< trim END
1482 vim9script
1483
1484 export var Func = 'asdf'
1485
1486 def Func()
1487 enddef
1488 END
1489 writefile(lines, 'Xdir/autoload/dup4func.vim')
1490 assert_fails('source Xdir/autoload/dup4func.vim', 'E707:')
1491
1492 lines =<< trim END
1493 vim9script
1494
1495 var Func = 'asdf'
1496
1497 export def Func()
1498 enddef
1499 END
1500 writefile(lines, 'Xdir/autoload/dup5func.vim')
1501 assert_fails('source Xdir/autoload/dup5func.vim', 'E707:')
1502
1503 lines =<< trim END
1504 vim9script
1505
1506 export def Func()
1507 enddef
1508
1509 var Func = 'asdf'
1510 END
1511 writefile(lines, 'Xdir/autoload/dup6func.vim')
1512 assert_fails('source Xdir/autoload/dup6func.vim', 'E1041: Redefining script item Func')
1513
1514 delete('Xdir', 'rf')
1515enddef
1516
Bram Moolenaard041f422022-01-12 19:54:00 +00001517def Test_import_autoload_postponed()
1518 mkdir('Xdir/autoload', 'p')
1519 var save_rtp = &rtp
1520 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1521
1522 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001523 vim9script
Bram Moolenaard041f422022-01-12 19:54:00 +00001524
1525 g:loaded_postponed = 'true'
1526 export var variable = 'bla'
1527 export def Function(): string
1528 return 'bla'
1529 enddef
1530 END
1531 writefile(lines, 'Xdir/autoload/postponed.vim')
1532
1533 lines =<< trim END
1534 vim9script
1535
1536 import autoload 'postponed.vim'
1537 def Tryit()
1538 echo postponed.variable
1539 echo postponed.Function()
1540 enddef
1541 defcompile
1542 END
1543 CheckScriptSuccess(lines)
1544 assert_false(exists('g:loaded_postponed'))
1545 CheckScriptSuccess(lines + ['Tryit()'])
1546 assert_equal('true', g:loaded_postponed)
1547
1548 unlet g:loaded_postponed
1549 delete('Xdir', 'rf')
1550 &rtp = save_rtp
1551enddef
1552
Bram Moolenaar3e4fa3d2022-01-13 22:05:09 +00001553def Test_import_autoload_override()
1554 mkdir('Xdir/autoload', 'p')
1555 var save_rtp = &rtp
1556 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1557 test_override('autoload', 1)
1558
1559 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001560 vim9script
Bram Moolenaar3e4fa3d2022-01-13 22:05:09 +00001561
1562 g:loaded_override = 'true'
1563 export var variable = 'bla'
1564 export def Function(): string
1565 return 'bla'
1566 enddef
1567 END
1568 writefile(lines, 'Xdir/autoload/override.vim')
1569
1570 lines =<< trim END
1571 vim9script
1572
1573 import autoload 'override.vim'
1574 assert_equal('true', g:loaded_override)
1575
1576 def Tryit()
1577 echo override.doesNotExist
1578 enddef
1579 defcompile
1580 END
1581 CheckScriptFailure(lines, 'E1048: Item not found in script: doesNotExist', 1)
1582
1583 test_override('autoload', 0)
1584 unlet g:loaded_override
1585 delete('Xdir', 'rf')
1586 &rtp = save_rtp
1587enddef
1588
Bram Moolenaar19db9e62022-01-11 11:58:19 +00001589def Test_autoload_mapping()
1590 mkdir('Xdir/autoload', 'p')
1591 var save_rtp = &rtp
1592 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1593
1594 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001595 vim9script
Bram Moolenaar19db9e62022-01-11 11:58:19 +00001596
1597 g:toggle_loaded = 'yes'
1598
1599 export def Toggle(): string
1600 return ":g:toggle_called = 'yes'\<CR>"
1601 enddef
Bram Moolenaare32c3c42022-01-15 18:26:04 +00001602 export def Doit()
1603 g:doit_called = 'yes'
1604 enddef
Bram Moolenaar19db9e62022-01-11 11:58:19 +00001605 END
1606 writefile(lines, 'Xdir/autoload/toggle.vim')
1607
1608 lines =<< trim END
1609 vim9script
1610
1611 import autoload 'toggle.vim'
1612
1613 nnoremap <silent> <expr> tt toggle.Toggle()
Bram Moolenaare32c3c42022-01-15 18:26:04 +00001614 nnoremap <silent> xx <ScriptCmd>toggle.Doit()<CR>
1615 nnoremap <silent> yy <Cmd>toggle.Doit()<CR>
Bram Moolenaar19db9e62022-01-11 11:58:19 +00001616 END
1617 CheckScriptSuccess(lines)
1618 assert_false(exists("g:toggle_loaded"))
1619 assert_false(exists("g:toggle_called"))
Bram Moolenaar6079da72022-01-18 14:16:59 +00001620 assert_match('\d A: \f*[/\\]toggle.vim', execute('scriptnames'))
Bram Moolenaar19db9e62022-01-11 11:58:19 +00001621
1622 feedkeys("tt", 'xt')
1623 assert_equal('yes', g:toggle_loaded)
1624 assert_equal('yes', g:toggle_called)
Bram Moolenaar6079da72022-01-18 14:16:59 +00001625 assert_match('\d: \f*[/\\]toggle.vim', execute('scriptnames'))
Bram Moolenaar19db9e62022-01-11 11:58:19 +00001626
Bram Moolenaare32c3c42022-01-15 18:26:04 +00001627 feedkeys("xx", 'xt')
1628 assert_equal('yes', g:doit_called)
1629
1630 assert_fails('call feedkeys("yy", "xt")', 'E121: Undefined variable: toggle')
1631
Bram Moolenaar19db9e62022-01-11 11:58:19 +00001632 nunmap tt
Bram Moolenaare32c3c42022-01-15 18:26:04 +00001633 nunmap xx
1634 nunmap yy
Bram Moolenaar19db9e62022-01-11 11:58:19 +00001635 unlet g:toggle_loaded
1636 unlet g:toggle_called
1637 delete('Xdir', 'rf')
1638 &rtp = save_rtp
1639enddef
1640
Bram Moolenaar160aa862022-01-10 21:29:57 +00001641def Test_vim9script_autoload_fails()
1642 var lines =<< trim END
1643 vim9script autoload
1644 var n = 0
1645 END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001646 CheckScriptFailure(lines, 'E475: Invalid argument: autoload')
1647
1648 lines =<< trim END
1649 vim9script noclear noclear
1650 var n = 0
1651 END
1652 CheckScriptFailure(lines, 'E983: Duplicate argument: noclear')
Bram Moolenaar160aa862022-01-10 21:29:57 +00001653enddef
1654
1655def Test_import_autoload_fails()
1656 var lines =<< trim END
1657 vim9script
1658 import autoload autoload 'prefixed.vim'
1659 END
1660 CheckScriptFailure(lines, 'E121: Undefined variable: autoload')
1661
1662 lines =<< trim END
1663 vim9script
Bram Moolenaar1836d612022-01-18 13:14:47 +00001664 import autoload './doesNotExist.vim'
Bram Moolenaar160aa862022-01-10 21:29:57 +00001665 END
1666 CheckScriptFailure(lines, 'E1264:')
Bram Moolenaar1836d612022-01-18 13:14:47 +00001667
1668 lines =<< trim END
1669 vim9script
1670 import autoload '/dir/doesNotExist.vim'
1671 END
1672 CheckScriptFailure(lines, 'E1264:')
1673
1674 lines =<< trim END
1675 vim9script
1676 import autoload 'doesNotExist.vim'
1677 END
1678 CheckScriptFailure(lines, 'E1053: Could not import "doesNotExist.vim"')
Bram Moolenaar160aa862022-01-10 21:29:57 +00001679enddef
1680
1681" test disassembling an auto-loaded function starting with "debug"
1682def Test_vim9_autoload_disass()
1683 mkdir('Xdir/autoload', 'p')
1684 var save_rtp = &rtp
1685 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1686
1687 var lines =<< trim END
1688 vim9script
1689 def debugit#test(): string
1690 return 'debug'
1691 enddef
1692 END
1693 writefile(lines, 'Xdir/autoload/debugit.vim')
1694
1695 lines =<< trim END
1696 vim9script
1697 def profileit#test(): string
1698 return 'profile'
1699 enddef
1700 END
1701 writefile(lines, 'Xdir/autoload/profileit.vim')
1702
1703 lines =<< trim END
1704 vim9script
1705 assert_equal('debug', debugit#test())
1706 disass debugit#test
1707 assert_equal('profile', profileit#test())
1708 disass profileit#test
1709 END
1710 CheckScriptSuccess(lines)
1711
1712 delete('Xdir', 'rf')
1713 &rtp = save_rtp
1714enddef
1715
1716" test using a vim9script that is auto-loaded from an autocmd
1717def Test_vim9_aucmd_autoload()
1718 var lines =<< trim END
1719 vim9script
1720 def foo#test()
1721 echomsg getreg('"')
1722 enddef
1723 END
1724
1725 mkdir('Xdir/autoload', 'p')
1726 writefile(lines, 'Xdir/autoload/foo.vim')
1727 var save_rtp = &rtp
1728 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1729 augroup test
1730 autocmd TextYankPost * call foo#test()
1731 augroup END
1732
1733 normal Y
1734
1735 augroup test
1736 autocmd!
1737 augroup END
1738 delete('Xdir', 'rf')
1739 &rtp = save_rtp
1740enddef
1741
Bram Moolenaar3049fcf2022-01-13 19:25:50 +00001742" test using a autoloaded file that is case sensitive
1743def Test_vim9_autoload_case_sensitive()
1744 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001745 vim9script
Bram Moolenaar3049fcf2022-01-13 19:25:50 +00001746 export def CaseSensitive(): string
1747 return 'done'
1748 enddef
1749 END
1750
1751 mkdir('Xdir/autoload', 'p')
1752 writefile(lines, 'Xdir/autoload/CaseSensitive.vim')
1753 var save_rtp = &rtp
1754 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1755
1756 lines =<< trim END
1757 vim9script
1758 import autoload 'CaseSensitive.vim'
1759 assert_equal('done', CaseSensitive.CaseSensitive())
1760 END
1761 CheckScriptSuccess(lines)
1762
Bram Moolenaarbfac4092022-01-16 11:12:12 +00001763 if !has('fname_case')
1764 lines =<< trim END
1765 vim9script
1766 import autoload 'CaseSensitive.vim'
1767 import autoload 'casesensitive.vim'
1768 END
1769 CheckScriptFailure(lines, 'E1262:')
1770 endif
1771
Bram Moolenaar3049fcf2022-01-13 19:25:50 +00001772 delete('Xdir', 'rf')
1773 &rtp = save_rtp
1774enddef
1775
Bram Moolenaar160aa862022-01-10 21:29:57 +00001776" This was causing a crash because suppress_errthrow wasn't reset.
1777def Test_vim9_autoload_error()
1778 var lines =<< trim END
1779 vim9script
1780 def crash#func()
1781 try
1782 for x in List()
1783 endfor
1784 catch
1785 endtry
1786 g:ok = true
1787 enddef
1788 fu List()
1789 invalid
1790 endfu
1791 try
1792 alsoinvalid
1793 catch /wontmatch/
1794 endtry
1795 END
1796 call mkdir('Xruntime/autoload', 'p')
1797 call writefile(lines, 'Xruntime/autoload/crash.vim')
1798
1799 # run in a separate Vim to avoid the side effects of assert_fails()
1800 lines =<< trim END
1801 exe 'set rtp^=' .. getcwd() .. '/Xruntime'
1802 call crash#func()
1803 call writefile(['ok'], 'Xdidit')
1804 qall!
1805 END
1806 writefile(lines, 'Xscript')
1807 RunVim([], [], '-S Xscript')
1808 assert_equal(['ok'], readfile('Xdidit'))
1809
1810 delete('Xdidit')
1811 delete('Xscript')
1812 delete('Xruntime', 'rf')
1813
1814 lines =<< trim END
1815 vim9script
1816 var foo#bar = 'asdf'
1817 END
1818 CheckScriptFailure(lines, 'E461: Illegal variable name: foo#bar', 2)
1819enddef
1820
Bram Moolenaard8448622022-01-07 21:39:52 +00001821
1822" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker