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