blob: 3734709f08133e4e91872bf640e5e17c87d6ab0d [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')
Bram Moolenaardd5893b2022-01-20 21:32:54 +0000432 lines =<< trim END
433 vim9script
434 import './Xfoo.vim' as foo
435 var that: any
436 that += foo
437 END
438 CheckScriptFailure(lines, 'E1060: Expected dot after name: foo')
439 lines =<< trim END
440 vim9script
441 import './Xfoo.vim' as foo
442 foo += 9
443 END
444 CheckScriptFailure(lines, 'E1060: Expected dot after name: foo')
Bram Moolenaard8448622022-01-07 21:39:52 +0000445
446 lines =<< trim END
447 vim9script
448 import './Xfoo.vim' as 9foo
449 END
450 CheckScriptFailure(lines, 'E1047:')
451 lines =<< trim END
452 vim9script
453 import './Xfoo.vim' as the#foo
454 END
455 CheckScriptFailure(lines, 'E1047:')
456 lines =<< trim END
457 vim9script
458 import './Xfoo.vim' as g:foo
459 END
460 CheckScriptFailure(lines, 'E1047:')
461
462 delete('Xfoo.vim')
463
464 lines =<< trim END
465 vim9script
466 def TheFunc()
467 echo 'the func'
468 enddef
469 export var Ref = TheFunc
470 END
471 writefile([], 'Xthat.vim')
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000472
Bram Moolenaard8448622022-01-07 21:39:52 +0000473 lines =<< trim END
474 import './Xthat.vim' as That
475 That()
476 END
477 CheckDefAndScriptFailure(lines, ['E1094:', 'E1236: Cannot use That itself'])
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000478
479 lines =<< trim END
Bram Moolenaar937610b2022-01-19 17:21:29 +0000480 vim9script
481 import './Xthat.vim' as That
482 def Func()
483 echo That()
484 enddef
485 Func()
486 END
487 CheckScriptFailure(lines, 'E1236: Cannot use That itself')
488
489 lines =<< trim END
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000490 import './Xthat.vim' as one
491 import './Xthat.vim' as two
492 END
493 CheckScriptFailure(lines, 'E1262:')
494
495 delete('Xthat.vim')
Bram Moolenaard8448622022-01-07 21:39:52 +0000496
497 mkdir('Ximport')
498
499 writefile(['vim9script'], 'Ximport/.vim')
500 lines =<< trim END
501 vim9script
502 import './Ximport/.vim'
503 END
504 CheckScriptFailure(lines, 'E1261: Cannot import .vim without using "as"')
505 lines =<< trim END
506 vim9script
507 import './Ximport/.vim' as vim
508 END
509 CheckScriptSuccess(lines)
510
511 writefile(['vim9script'], 'Ximport/.vimrc')
512 lines =<< trim END
513 vim9script
514 import './Ximport/.vimrc'
515 END
516 CheckScriptFailure(lines, 'E1257: Imported script must use "as" or end in .vim')
517 lines =<< trim END
518 vim9script
519 import './Ximport/.vimrc' as vimrc
520 END
521 CheckScriptSuccess(lines)
522
523 delete('Ximport', 'rf')
524enddef
525
526func g:Trigger()
527 source Ximport.vim
528 return "echo 'yes'\<CR>"
529endfunc
530
531def Test_import_export_expr_map()
532 # check that :import and :export work when buffer is locked
533 var export_lines =<< trim END
534 vim9script
535 export def That(): string
536 return 'yes'
537 enddef
538 END
539 writefile(export_lines, 'Xexport_that.vim')
540
541 var import_lines =<< trim END
542 vim9script
543 import './Xexport_that.vim' as that
544 assert_equal('yes', that.That())
545 END
546 writefile(import_lines, 'Ximport.vim')
547
548 nnoremap <expr> trigger g:Trigger()
549 feedkeys('trigger', "xt")
550
551 delete('Xexport_that.vim')
552 delete('Ximport.vim')
553 nunmap trigger
554enddef
555
556def Test_import_in_filetype()
557 # check that :import works when the buffer is locked
558 mkdir('ftplugin', 'p')
559 var export_lines =<< trim END
560 vim9script
561 export var That = 'yes'
562 END
563 writefile(export_lines, 'ftplugin/Xexport_ft.vim')
564
565 var import_lines =<< trim END
566 vim9script
567 import './Xexport_ft.vim' as ft
568 assert_equal('yes', ft.That)
569 g:did_load_mytpe = 1
570 END
571 writefile(import_lines, 'ftplugin/qf.vim')
572
573 var save_rtp = &rtp
574 &rtp = getcwd() .. ',' .. &rtp
575
576 filetype plugin on
577 copen
578 assert_equal(1, g:did_load_mytpe)
579
580 quit!
581 delete('Xexport_ft.vim')
582 delete('ftplugin', 'rf')
583 &rtp = save_rtp
584enddef
585
586def Test_use_import_in_mapping()
587 var lines =<< trim END
588 vim9script
589 export def Funcx()
590 g:result = 42
591 enddef
592 END
593 writefile(lines, 'XsomeExport.vim')
594 lines =<< trim END
595 vim9script
596 import './XsomeExport.vim' as some
597 var Funcy = some.Funcx
598 nnoremap <F3> :call <sid>Funcy()<cr>
599 END
600 writefile(lines, 'Xmapscript.vim')
601
602 source Xmapscript.vim
603 feedkeys("\<F3>", "xt")
604 assert_equal(42, g:result)
605
606 unlet g:result
607 delete('XsomeExport.vim')
608 delete('Xmapscript.vim')
609 nunmap <F3>
610enddef
611
Bram Moolenaarf0e7e632022-01-21 13:29:56 +0000612def Test_use_import_in_command_completion()
Bram Moolenaar15d16352022-01-17 20:09:08 +0000613 var lines =<< trim END
614 vim9script
615 export def Complete(..._): list<string>
616 return ['abcd']
617 enddef
618 END
619 writefile(lines, 'Xscript.vim')
620
621 lines =<< trim END
622 vim9script
623 import './Xscript.vim'
624
625 command -nargs=1 -complete=customlist,Xscript.Complete Cmd echo 'ok'
626 feedkeys(":Cmd ab\<Tab>\<C-B>#\<CR>", 'xnt')
627 assert_equal('#Cmd abcd', @:)
628 END
629 CheckScriptSuccess(lines)
630
631 delcommand Cmd
632 delete('Xscript.vim')
633enddef
634
Bram Moolenaarf0e7e632022-01-21 13:29:56 +0000635def Test_use_autoload_import_in_insert_completion()
636 mkdir('Xdir/autoload', 'p')
637 var save_rtp = &rtp
638 exe 'set rtp^=' .. getcwd() .. '/Xdir'
639
640 var lines =<< trim END
641 vim9script
642 export def ThesaurusFunc(findbase: bool, _): any
643 if findbase
644 return 1
645 endif
646 return [
647 'check',
648 'experiment',
649 'test',
650 'verification'
651 ]
652 enddef
653 g:completion_loaded = 'yes'
654 END
655 writefile(lines, 'Xdir/autoload/completion.vim')
656
657 new
658 lines =<< trim END
659 vim9script
660 g:completion_loaded = 'no'
661 import autoload 'completion.vim'
662 set thesaurusfunc=completion.ThesaurusFunc
663 assert_equal('no', g:completion_loaded)
664 feedkeys("i\<C-X>\<C-T>\<C-N>\<Esc>", 'xt')
665 assert_equal('experiment', getline(1))
666 assert_equal('yes', g:completion_loaded)
667 END
668 CheckScriptSuccess(lines)
669
670 set thesaurusfunc=
671 bwipe!
672 delete('Xdir', 'rf')
673 &rtp = save_rtp
674enddef
675
Bram Moolenaare70dd112022-01-21 16:31:11 +0000676def Test_use_autoload_import_in_fold_expression()
677 mkdir('Xdir/autoload', 'p')
678 var save_rtp = &rtp
679 exe 'set rtp^=' .. getcwd() .. '/Xdir'
680
681 var lines =<< trim END
682 vim9script
683 export def Expr(): string
684 return getline(v:lnum) =~ '^#' ? '>1' : '1'
685 enddef
686 g:fold_loaded = 'yes'
687 END
688 writefile(lines, 'Xdir/autoload/fold.vim')
689
690 lines =<< trim END
691 vim9script
692 import autoload 'fold.vim'
693 &foldexpr = 'fold.Expr()'
694 &foldmethod = 'expr'
695 &debug = 'throw'
696 END
697 new
698 setline(1, ['# one', 'text', '# two', 'text'])
699 g:fold_loaded = 'no'
700 CheckScriptSuccess(lines)
701 assert_equal('no', g:fold_loaded)
702 redraw
703 assert_equal('yes', g:fold_loaded)
704
705 # Check that script context of 'foldexpr' is copied to another buffer.
706 edit! otherfile
707 redraw
708
709 set foldexpr= foldmethod&
710 bwipe!
711 delete('Xdir', 'rf')
712 &rtp = save_rtp
713enddef
714
Bram Moolenaard8448622022-01-07 21:39:52 +0000715def Test_export_fails()
716 CheckScriptFailure(['export var some = 123'], 'E1042:')
717 CheckScriptFailure(['vim9script', 'export var g:some'], 'E1022:')
718 CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
719
720 assert_fails('export something', 'E1043:')
721enddef
722
723func Test_import_fails_without_script()
724 CheckRunVimInTerminal
725
726 " call indirectly to avoid compilation error for missing functions
727 call Run_Test_import_fails_on_command_line()
728endfunc
729
730def Run_Test_import_fails_on_command_line()
731 var export =<< trim END
732 vim9script
733 export def Foo(): number
734 return 0
735 enddef
736 END
737 writefile(export, 'XexportCmd.vim')
738
739 var buf = RunVimInTerminal('-c "import Foo from ''./XexportCmd.vim''"', {
740 rows: 6, wait_for_ruler: 0})
741 WaitForAssert(() => assert_match('^E1094:', term_getline(buf, 5)))
742
743 delete('XexportCmd.vim')
744 StopVimInTerminal(buf)
745enddef
746
747def Test_vim9_reload_noclear()
748 var lines =<< trim END
749 vim9script
750 export var exported = 'thexport'
751
752 export def TheFunc(x = 0)
753 enddef
754 END
755 writefile(lines, 'XExportReload')
756 lines =<< trim END
757 vim9script noclear
758 g:loadCount += 1
759 var s:reloaded = 'init'
760 import './XExportReload' as exp
761
762 def Again(): string
763 return 'again'
764 enddef
765
766 exp.TheFunc()
767
768 if exists('s:loaded') | finish | endif
769 var s:loaded = true
770
771 var s:notReloaded = 'yes'
772 s:reloaded = 'first'
773 def g:Values(): list<string>
774 return [s:reloaded, s:notReloaded, Again(), Once(), exp.exported]
775 enddef
776
777 def Once(): string
778 return 'once'
779 enddef
780 END
781 writefile(lines, 'XReloaded')
782 g:loadCount = 0
783 source XReloaded
784 assert_equal(1, g:loadCount)
785 assert_equal(['first', 'yes', 'again', 'once', 'thexport'], g:Values())
786 source XReloaded
787 assert_equal(2, g:loadCount)
788 assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values())
789 source XReloaded
790 assert_equal(3, g:loadCount)
791 assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values())
792
793 delete('XReloaded')
794 delete('XExportReload')
795 delfunc g:Values
796 unlet g:loadCount
797
798 lines =<< trim END
799 vim9script
800 def Inner()
801 enddef
802 END
803 lines->writefile('XreloadScript.vim')
804 source XreloadScript.vim
805
806 lines =<< trim END
807 vim9script
808 def Outer()
809 def Inner()
810 enddef
811 enddef
812 defcompile
813 END
814 lines->writefile('XreloadScript.vim')
815 source XreloadScript.vim
816
817 delete('XreloadScript.vim')
818enddef
819
820def Test_vim9_reload_import()
821 var lines =<< trim END
822 vim9script
823 const var = ''
824 var valone = 1234
825 def MyFunc(arg: string)
826 valone = 5678
827 enddef
828 END
829 var morelines =<< trim END
830 var valtwo = 222
831 export def GetValtwo(): number
832 return valtwo
833 enddef
834 END
835 writefile(lines + morelines, 'Xreload.vim')
836 source Xreload.vim
837 source Xreload.vim
838 source Xreload.vim
839
840 # cannot declare a var twice
841 lines =<< trim END
842 vim9script
843 var valone = 1234
844 var valone = 5678
845 END
846 writefile(lines, 'Xreload.vim')
847 assert_fails('source Xreload.vim', 'E1041:', '', 3, 'Xreload.vim')
848
849 delete('Xreload.vim')
850 delete('Ximport.vim')
851enddef
852
853" if a script is reloaded with a script-local variable that changed its type, a
854" compiled function using that variable must fail.
855def Test_script_reload_change_type()
856 var lines =<< trim END
857 vim9script noclear
858 var str = 'string'
859 def g:GetStr(): string
860 return str .. 'xxx'
861 enddef
862 END
863 writefile(lines, 'Xreload.vim')
864 source Xreload.vim
865 echo g:GetStr()
866
867 lines =<< trim END
868 vim9script noclear
869 var str = 1234
870 END
871 writefile(lines, 'Xreload.vim')
872 source Xreload.vim
873 assert_fails('echo g:GetStr()', 'E1150:')
874
875 delfunc g:GetStr
876 delete('Xreload.vim')
877enddef
878
879" Define CallFunc so that the test can be compiled
880command CallFunc echo 'nop'
881
882def Test_script_reload_from_function()
883 var lines =<< trim END
884 vim9script
885
886 if exists('g:loaded')
887 finish
888 endif
889 g:loaded = 1
890 delcommand CallFunc
891 command CallFunc Func()
892 def Func()
893 so XreloadFunc.vim
894 g:didTheFunc = 1
895 enddef
896 END
897 writefile(lines, 'XreloadFunc.vim')
898 source XreloadFunc.vim
899 CallFunc
900 assert_equal(1, g:didTheFunc)
901
902 delete('XreloadFunc.vim')
903 delcommand CallFunc
904 unlet g:loaded
905 unlet g:didTheFunc
906enddef
907
908def s:RetSome(): string
909 return 'some'
910enddef
911
912" Not exported function that is referenced needs to be accessed by the
913" script-local name.
914def Test_vim9_funcref()
915 var sortlines =<< trim END
916 vim9script
917 def Compare(i1: number, i2: number): number
918 return i2 - i1
919 enddef
920
921 export def FastSort(): list<number>
922 return range(5)->sort(Compare)
923 enddef
924
925 export def GetString(arg: string): string
926 return arg
927 enddef
928 END
929 writefile(sortlines, 'Xsort.vim')
930
931 var lines =<< trim END
932 vim9script
933 import './Xsort.vim'
934 def Test()
935 g:result = Xsort.FastSort()
936 enddef
937 Test()
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000938 END
939 writefile(lines, 'Xscript.vim')
940 source Xscript.vim
941 assert_equal([4, 3, 2, 1, 0], g:result)
942 unlet g:result
Bram Moolenaard8448622022-01-07 21:39:52 +0000943
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000944 lines =<< trim END
945 vim9script
Bram Moolenaard8448622022-01-07 21:39:52 +0000946 # using a function imported with "as"
947 import './Xsort.vim' as anAlias
948 assert_equal('yes', anAlias.GetString('yes'))
949
950 # using the function from a compiled function
951 def TestMore(): string
952 var s = s:anAlias.GetString('foo')
953 return s .. anAlias.GetString('bar')
954 enddef
955 assert_equal('foobar', TestMore())
956
957 # error when using a function that isn't exported
958 assert_fails('anAlias.Compare(1, 2)', 'E1049:')
959 END
960 writefile(lines, 'Xscript.vim')
961
Bram Moolenaard8448622022-01-07 21:39:52 +0000962 delete('Xsort.vim')
963 delete('Xscript.vim')
964
965 var Funcref = function('s:RetSome')
966 assert_equal('some', Funcref())
967enddef
968
969" Check that when searching for "FilterFunc" it finds the import in the
970" script where FastFilter() is called from, both as a string and as a direct
971" function reference.
972def Test_vim9_funcref_other_script()
973 var filterLines =<< trim END
974 vim9script
975 export def FilterFunc(idx: number, val: number): bool
976 return idx % 2 == 1
977 enddef
978 export def FastFilter(): list<number>
979 return range(10)->filter('FilterFunc(v:key, v:val)')
980 enddef
981 export def FastFilterDirect(): list<number>
982 return range(10)->filter(FilterFunc)
983 enddef
984 END
985 writefile(filterLines, 'Xfilter.vim')
986
987 var lines =<< trim END
988 vim9script
989 import './Xfilter.vim' as filter
990 def Test()
991 var x: list<number> = filter.FastFilter()
992 enddef
993 Test()
994 def TestDirect()
995 var x: list<number> = filter.FastFilterDirect()
996 enddef
997 TestDirect()
998 END
999 CheckScriptSuccess(lines)
1000 delete('Xfilter.vim')
1001enddef
1002
1003def Test_import_absolute()
1004 var import_lines = [
1005 'vim9script',
1006 'import "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim" as abs',
1007 'def UseExported()',
1008 ' g:imported_abs = abs.exported',
1009 ' abs.exported = 8888',
1010 ' g:imported_after = abs.exported',
1011 'enddef',
1012 'UseExported()',
1013 'g:import_disassembled = execute("disass UseExported")',
1014 ]
1015 writefile(import_lines, 'Ximport_abs.vim')
1016 writefile(s:export_script_lines, 'Xexport_abs.vim')
1017
1018 source Ximport_abs.vim
1019
1020 assert_equal(9876, g:imported_abs)
1021 assert_equal(8888, g:imported_after)
1022 assert_match('<SNR>\d\+_UseExported\_s*' ..
1023 'g:imported_abs = abs.exported\_s*' ..
1024 '0 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' ..
1025 '1 STOREG g:imported_abs\_s*' ..
1026 'abs.exported = 8888\_s*' ..
1027 '2 PUSHNR 8888\_s*' ..
1028 '3 STORESCRIPT exported-2 in .*Xexport_abs.vim\_s*' ..
1029 'g:imported_after = abs.exported\_s*' ..
1030 '4 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' ..
1031 '5 STOREG g:imported_after',
1032 g:import_disassembled)
1033
1034 Undo_export_script_lines()
1035 unlet g:imported_abs
1036 unlet g:import_disassembled
1037
1038 delete('Ximport_abs.vim')
1039 delete('Xexport_abs.vim')
1040enddef
1041
1042def Test_import_rtp()
1043 var import_lines = [
1044 'vim9script',
1045 'import "Xexport_rtp.vim" as rtp',
1046 'g:imported_rtp = rtp.exported',
1047 ]
1048 writefile(import_lines, 'Ximport_rtp.vim')
1049 mkdir('import', 'p')
1050 writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
1051
1052 var save_rtp = &rtp
1053 &rtp = getcwd()
1054 source Ximport_rtp.vim
1055 &rtp = save_rtp
1056
1057 assert_equal(9876, g:imported_rtp)
1058
1059 Undo_export_script_lines()
1060 unlet g:imported_rtp
1061 delete('Ximport_rtp.vim')
1062 delete('import', 'rf')
1063enddef
1064
1065def Test_import_compile_error()
1066 var export_lines = [
1067 'vim9script',
1068 'export def ExpFunc(): string',
1069 ' return notDefined',
1070 'enddef',
1071 ]
1072 writefile(export_lines, 'Xexported.vim')
1073
1074 var import_lines = [
1075 'vim9script',
1076 'import "./Xexported.vim" as expo',
1077 'def ImpFunc()',
1078 ' echo expo.ExpFunc()',
1079 'enddef',
1080 'defcompile',
1081 ]
1082 writefile(import_lines, 'Ximport.vim')
1083
1084 try
1085 source Ximport.vim
1086 catch /E1001/
1087 # Error should be before the Xexported.vim file.
1088 assert_match('E1001: Variable not found: notDefined', v:exception)
1089 assert_match('function <SNR>\d\+_ImpFunc\[1\]..<SNR>\d\+_ExpFunc, line 1', v:throwpoint)
1090 endtry
1091
1092 delete('Xexported.vim')
1093 delete('Ximport.vim')
1094enddef
1095
1096def Test_func_overrules_import_fails()
1097 var export_lines =<< trim END
1098 vim9script
1099 export def Func()
1100 echo 'imported'
1101 enddef
1102 END
1103 writefile(export_lines, 'XexportedFunc.vim')
1104
1105 var lines =<< trim END
1106 vim9script
1107 import './XexportedFunc.vim' as Func
1108 def Func()
1109 echo 'local to function'
1110 enddef
1111 END
Bram Moolenaar937610b2022-01-19 17:21:29 +00001112 CheckScriptFailure(lines, 'E1213: Redefining imported item "Func"')
Bram Moolenaard8448622022-01-07 21:39:52 +00001113
1114 lines =<< trim END
1115 vim9script
1116 import './XexportedFunc.vim' as Func
1117 def Outer()
1118 def Func()
1119 echo 'local to function'
1120 enddef
1121 enddef
1122 defcompile
1123 END
1124 CheckScriptFailure(lines, 'E1236:')
1125
1126 delete('XexportedFunc.vim')
1127enddef
1128
1129def Test_source_vim9_from_legacy()
1130 var vim9_lines =<< trim END
1131 vim9script
1132 var local = 'local'
1133 g:global = 'global'
1134 export var exported = 'exported'
1135 export def GetText(): string
1136 return 'text'
1137 enddef
1138 END
1139 writefile(vim9_lines, 'Xvim9_script.vim')
1140
1141 var legacy_lines =<< trim END
1142 source Xvim9_script.vim
1143
1144 call assert_false(exists('local'))
1145 call assert_false(exists('exported'))
1146 call assert_false(exists('s:exported'))
1147 call assert_equal('global', global)
1148 call assert_equal('global', g:global)
Bram Moolenaard8448622022-01-07 21:39:52 +00001149 END
1150 writefile(legacy_lines, 'Xlegacy_script.vim')
1151
1152 source Xlegacy_script.vim
1153 assert_equal('global', g:global)
1154 unlet g:global
1155
1156 delete('Xlegacy_script.vim')
1157 delete('Xvim9_script.vim')
1158enddef
1159
Bram Moolenaarc43e6232022-01-13 20:51:56 +00001160def Test_import_vim9_from_legacy()
1161 var vim9_lines =<< trim END
1162 vim9script
1163 var local = 'local'
1164 g:global = 'global'
1165 export var exported = 'exported'
1166 export def GetText(): string
1167 return 'text'
1168 enddef
1169 END
1170 writefile(vim9_lines, 'Xvim9_export.vim')
1171
1172 var legacy_lines =<< trim END
1173 import './Xvim9_export.vim' as vim9
1174
1175 call assert_false(exists('vim9'))
1176 call assert_false(exists('local'))
1177 call assert_false(exists('s:vim9.local'))
1178 call assert_equal('global', global)
1179 call assert_equal('global', g:global)
1180 call assert_false(exists('exported'))
1181 call assert_false(exists('s:exported'))
1182 call assert_false(exists('*GetText'))
1183
1184 " imported symbol is script-local
1185 call assert_equal('exported', s:vim9.exported)
1186 call assert_equal('text', s:vim9.GetText())
1187 END
1188 writefile(legacy_lines, 'Xlegacy_script.vim')
1189
1190 source Xlegacy_script.vim
1191 assert_equal('global', g:global)
1192 unlet g:global
1193
1194 delete('Xlegacy_script.vim')
1195 delete('Xvim9_export.vim')
1196enddef
1197
Bram Moolenaard8448622022-01-07 21:39:52 +00001198def Test_cmdline_win()
1199 # if the Vim syntax highlighting uses Vim9 constructs they can be used from
1200 # the command line window.
1201 mkdir('rtp/syntax', 'p')
1202 var export_lines =<< trim END
1203 vim9script
1204 export var That = 'yes'
1205 END
1206 writefile(export_lines, 'rtp/syntax/Xexport.vim')
1207 var import_lines =<< trim END
1208 vim9script
1209 import './Xexport.vim' as exp
1210 echo exp.That
1211 END
1212 writefile(import_lines, 'rtp/syntax/vim.vim')
1213 var save_rtp = &rtp
1214 &rtp = getcwd() .. '/rtp' .. ',' .. &rtp
1215 syntax on
1216 augroup CmdWin
1217 autocmd CmdwinEnter * g:got_there = 'yes'
1218 augroup END
1219 # this will open and also close the cmdline window
1220 feedkeys('q:', 'xt')
1221 assert_equal('yes', g:got_there)
1222
1223 augroup CmdWin
1224 au!
1225 augroup END
1226 &rtp = save_rtp
1227 delete('rtp', 'rf')
1228enddef
1229
1230def Test_import_gone_when_sourced_twice()
1231 var exportlines =<< trim END
1232 vim9script
1233 if exists('g:guard')
1234 finish
1235 endif
1236 g:guard = 1
1237 export var name = 'someName'
1238 END
1239 writefile(exportlines, 'XexportScript.vim')
1240
1241 var lines =<< trim END
1242 vim9script
1243 import './XexportScript.vim' as expo
1244 def g:GetName(): string
1245 return expo.name
1246 enddef
1247 END
1248 writefile(lines, 'XscriptImport.vim')
1249 so XscriptImport.vim
1250 assert_equal('someName', g:GetName())
1251
1252 so XexportScript.vim
1253 assert_fails('call g:GetName()', 'E1149:')
1254
1255 delfunc g:GetName
1256 delete('XexportScript.vim')
1257 delete('XscriptImport.vim')
1258 unlet g:guard
1259enddef
1260
Bram Moolenaar160aa862022-01-10 21:29:57 +00001261" test using an auto-loaded function and variable
Bram Moolenaar0e3e7ba2022-01-13 20:18:56 +00001262def Test_vim9_autoload_full_name()
Bram Moolenaar160aa862022-01-10 21:29:57 +00001263 var lines =<< trim END
1264 vim9script
1265 def some#gettest(): string
1266 return 'test'
1267 enddef
1268 g:some#name = 'name'
1269 g:some#dict = {key: 'value'}
1270
1271 def some#varargs(a1: string, ...l: list<string>): string
1272 return a1 .. l[0] .. l[1]
1273 enddef
1274 END
1275
1276 mkdir('Xdir/autoload', 'p')
1277 writefile(lines, 'Xdir/autoload/some.vim')
1278 var save_rtp = &rtp
1279 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1280
1281 assert_equal('test', g:some#gettest())
1282 assert_equal('name', g:some#name)
1283 assert_equal('value', g:some#dict.key)
1284 g:some#other = 'other'
1285 assert_equal('other', g:some#other)
1286
1287 assert_equal('abc', some#varargs('a', 'b', 'c'))
1288
1289 # upper case script name works
1290 lines =<< trim END
1291 vim9script
1292 def Other#getOther(): string
1293 return 'other'
1294 enddef
1295 END
1296 writefile(lines, 'Xdir/autoload/Other.vim')
1297 assert_equal('other', g:Other#getOther())
1298
1299 delete('Xdir', 'rf')
1300 &rtp = save_rtp
1301enddef
1302
1303def Test_vim9script_autoload()
1304 mkdir('Xdir/autoload', 'p')
1305 var save_rtp = &rtp
1306 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1307
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001308 # when the path has "/autoload/" prefix is not needed
Bram Moolenaar160aa862022-01-10 21:29:57 +00001309 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001310 vim9script
Bram Moolenaar17d36cb2022-01-12 11:46:40 +00001311 g:prefixed_loaded += 1
Bram Moolenaar160aa862022-01-10 21:29:57 +00001312
1313 export def Gettest(): string
1314 return 'test'
1315 enddef
1316
Bram Moolenaar0e3e7ba2022-01-13 20:18:56 +00001317 export var name = 'name'
1318
1319 export func GetFunc()
1320 return Gettest() .. 'more' .. s:name
Bram Moolenaar160aa862022-01-10 21:29:57 +00001321 endfunc
1322
Bram Moolenaar0e3e7ba2022-01-13 20:18:56 +00001323 export def GetDef(): string
1324 return Gettest() .. 'more' .. name
1325 enddef
1326
Bram Moolenaar160aa862022-01-10 21:29:57 +00001327 export final fname = 'final'
1328 export const cname = 'const'
1329 END
1330 writefile(lines, 'Xdir/autoload/prefixed.vim')
1331
Bram Moolenaar17d36cb2022-01-12 11:46:40 +00001332 g:prefixed_loaded = 0
1333 g:expected_loaded = 0
Bram Moolenaar160aa862022-01-10 21:29:57 +00001334 lines =<< trim END
1335 vim9script
1336 import autoload 'prefixed.vim'
Bram Moolenaar17d36cb2022-01-12 11:46:40 +00001337 assert_equal(g:expected_loaded, g:prefixed_loaded)
Bram Moolenaar160aa862022-01-10 21:29:57 +00001338 assert_equal('test', prefixed.Gettest())
Bram Moolenaar17d36cb2022-01-12 11:46:40 +00001339 assert_equal(1, g:prefixed_loaded)
Bram Moolenaar160aa862022-01-10 21:29:57 +00001340
Bram Moolenaar0e3e7ba2022-01-13 20:18:56 +00001341 assert_equal('testmorename', prefixed.GetFunc())
1342 assert_equal('testmorename', prefixed.GetDef())
Bram Moolenaar160aa862022-01-10 21:29:57 +00001343 assert_equal('name', prefixed.name)
1344 assert_equal('final', prefixed.fname)
1345 assert_equal('const', prefixed.cname)
1346 END
1347 CheckScriptSuccess(lines)
Bram Moolenaar17d36cb2022-01-12 11:46:40 +00001348 # can source it again, autoload script not loaded again
1349 g:expected_loaded = 1
1350 CheckScriptSuccess(lines)
Bram Moolenaar160aa862022-01-10 21:29:57 +00001351
1352 # can also get the items by autoload name
1353 lines =<< trim END
1354 call assert_equal('test', prefixed#Gettest())
Bram Moolenaar0e3e7ba2022-01-13 20:18:56 +00001355 call assert_equal('testmorename', prefixed#GetFunc())
Bram Moolenaar160aa862022-01-10 21:29:57 +00001356 call assert_equal('name', prefixed#name)
1357 call assert_equal('final', prefixed#fname)
1358 call assert_equal('const', prefixed#cname)
1359 END
1360 CheckScriptSuccess(lines)
1361
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00001362 unlet g:prefixed_loaded
1363 unlet g:expected_loaded
1364 delete('Xdir', 'rf')
1365 &rtp = save_rtp
1366enddef
1367
Bram Moolenaard02dce22022-01-18 17:43:04 +00001368def Test_import_autoload_not_exported()
1369 mkdir('Xdir/autoload', 'p')
1370 var save_rtp = &rtp
1371 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1372
1373 # error when using an item that is not exported from an autoload script
1374 var exportLines =<< trim END
1375 vim9script
1376 var notExported = 123
1377 def NotExport()
1378 echo 'nop'
1379 enddef
1380 END
1381 writefile(exportLines, 'Xdir/autoload/notExport1.vim')
1382
1383 var lines =<< trim END
1384 vim9script
1385 import autoload 'notExport1.vim'
1386 echo notExport1.notFound
1387 END
1388 CheckScriptFailure(lines, 'E1048: Item not found in script: notFound')
1389
1390 lines =<< trim END
1391 vim9script
1392 import autoload 'notExport1.vim'
1393 echo notExport1.notExported
1394 END
1395 CheckScriptFailure(lines, 'E1049: Item not exported in script: notExported')
1396
1397 lines =<< trim END
1398 vim9script
1399 import autoload 'notExport1.vim'
1400 echo notExport1.NotFunc()
1401 END
1402 CheckScriptFailure(lines, 'E1048: Item not found in script: NotFunc')
1403
1404 lines =<< trim END
1405 vim9script
1406 import autoload 'notExport1.vim'
1407 echo notExport1.NotExport()
1408 END
1409 CheckScriptFailure(lines, 'E1049: Item not exported in script: NotExport')
1410
1411 lines =<< trim END
1412 vim9script
1413 import autoload 'notExport1.vim'
1414 echo 'text'->notExport1.NotFunc()
1415 END
1416 CheckScriptFailure(lines, 'E1048: Item not found in script: NotFunc')
1417
1418 lines =<< trim END
1419 vim9script
1420 import autoload 'notExport1.vim'
1421 echo 'text'->notExport1.NotExport()
1422 END
1423 CheckScriptFailure(lines, 'E1049: Item not exported in script: NotExport')
1424
1425 # using a :def function we use a different autoload script every time so that
1426 # the function is compiled without the script loaded
1427 writefile(exportLines, 'Xdir/autoload/notExport2.vim')
1428 lines =<< trim END
1429 vim9script
1430 import autoload 'notExport2.vim'
1431 def Testit()
1432 echo notExport2.notFound
1433 enddef
1434 Testit()
1435 END
1436 CheckScriptFailure(lines, 'E1048: Item not found in script: notExport2#notFound')
1437
1438 writefile(exportLines, 'Xdir/autoload/notExport3.vim')
1439 lines =<< trim END
1440 vim9script
1441 import autoload 'notExport3.vim'
1442 def Testit()
1443 echo notExport3.notExported
1444 enddef
1445 Testit()
1446 END
1447 # don't get E1049 because it is too complicated to figure out
1448 CheckScriptFailure(lines, 'E1048: Item not found in script: notExport3#notExported')
1449
1450 writefile(exportLines, 'Xdir/autoload/notExport4.vim')
1451 lines =<< trim END
1452 vim9script
1453 import autoload 'notExport4.vim'
1454 def Testit()
1455 echo notExport4.NotFunc()
1456 enddef
1457 Testit()
1458 END
1459 CheckScriptFailure(lines, 'E117: Unknown function: notExport4#NotFunc')
1460
1461 writefile(exportLines, 'Xdir/autoload/notExport5.vim')
1462 lines =<< trim END
1463 vim9script
1464 import autoload 'notExport5.vim'
1465 def Testit()
1466 echo notExport5.NotExport()
1467 enddef
1468 Testit()
1469 END
1470 CheckScriptFailure(lines, 'E117: Unknown function: notExport5#NotExport')
1471
1472 writefile(exportLines, 'Xdir/autoload/notExport6.vim')
1473 lines =<< trim END
1474 vim9script
1475 import autoload 'notExport6.vim'
1476 def Testit()
1477 echo 'text'->notExport6.NotFunc()
1478 enddef
1479 Testit()
1480 END
1481 CheckScriptFailure(lines, 'E117: Unknown function: notExport6#NotFunc')
1482
1483 writefile(exportLines, 'Xdir/autoload/notExport7.vim')
1484 lines =<< trim END
1485 vim9script
1486 import autoload 'notExport7.vim'
1487 def Testit()
1488 echo 'text'->notExport7.NotExport()
1489 enddef
1490 Testit()
1491 END
1492 CheckScriptFailure(lines, 'E117: Unknown function: notExport7#NotExport')
1493
1494 delete('Xdir', 'rf')
1495 &rtp = save_rtp
1496enddef
1497
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00001498def Test_vim9script_autoload_call()
1499 mkdir('Xdir/autoload', 'p')
1500 var save_rtp = &rtp
1501 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1502
1503 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001504 vim9script
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00001505
Bram Moolenaarcbbc48f2022-01-18 12:58:28 +00001506 export def RetArg(arg: string): string
1507 return arg
1508 enddef
1509
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00001510 export def Getother()
1511 g:result = 'other'
1512 enddef
1513 END
Bram Moolenaar5d982692022-01-12 15:15:27 +00001514 writefile(lines, 'Xdir/autoload/another.vim')
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00001515
1516 lines =<< trim END
1517 vim9script
Bram Moolenaar5d982692022-01-12 15:15:27 +00001518 import autoload 'another.vim'
Bram Moolenaarcbbc48f2022-01-18 12:58:28 +00001519
1520 # compile this before 'another.vim' is loaded
1521 def CallAnother()
1522 assert_equal('foo', 'foo'->another.RetArg())
1523 enddef
1524 CallAnother()
1525
Bram Moolenaar5d982692022-01-12 15:15:27 +00001526 call another.Getother()
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00001527 assert_equal('other', g:result)
1528 END
1529 CheckScriptSuccess(lines)
1530
1531 unlet g:result
Bram Moolenaar160aa862022-01-10 21:29:57 +00001532 delete('Xdir', 'rf')
1533 &rtp = save_rtp
1534enddef
1535
Bram Moolenaar9c7cae62022-01-20 19:10:25 +00001536def Test_vim9script_autoload_duplicate()
1537 mkdir('Xdir/autoload', 'p')
1538
1539 var lines =<< trim END
1540 vim9script
1541
1542 export def Func()
1543 enddef
1544
1545 def Func()
1546 enddef
1547 END
1548 writefile(lines, 'Xdir/autoload/dupfunc.vim')
1549 assert_fails('source Xdir/autoload/dupfunc.vim', 'E1073:')
1550
1551 lines =<< trim END
1552 vim9script
1553
1554 def Func()
1555 enddef
1556
1557 export def Func()
1558 enddef
1559 END
1560 writefile(lines, 'Xdir/autoload/dup2func.vim')
1561 assert_fails('source Xdir/autoload/dup2func.vim', 'E1073:')
1562
1563 lines =<< trim END
1564 vim9script
1565
1566 def Func()
1567 enddef
1568
1569 export var Func = 'asdf'
1570 END
1571 writefile(lines, 'Xdir/autoload/dup3func.vim')
1572 assert_fails('source Xdir/autoload/dup3func.vim', 'E1041: Redefining script item Func')
1573
1574 lines =<< trim END
1575 vim9script
1576
1577 export var Func = 'asdf'
1578
1579 def Func()
1580 enddef
1581 END
1582 writefile(lines, 'Xdir/autoload/dup4func.vim')
1583 assert_fails('source Xdir/autoload/dup4func.vim', 'E707:')
1584
1585 lines =<< trim END
1586 vim9script
1587
1588 var Func = 'asdf'
1589
1590 export def Func()
1591 enddef
1592 END
1593 writefile(lines, 'Xdir/autoload/dup5func.vim')
1594 assert_fails('source Xdir/autoload/dup5func.vim', 'E707:')
1595
1596 lines =<< trim END
1597 vim9script
1598
1599 export def Func()
1600 enddef
1601
1602 var Func = 'asdf'
1603 END
1604 writefile(lines, 'Xdir/autoload/dup6func.vim')
1605 assert_fails('source Xdir/autoload/dup6func.vim', 'E1041: Redefining script item Func')
1606
1607 delete('Xdir', 'rf')
1608enddef
1609
Bram Moolenaar2017d6f2022-01-20 19:38:46 +00001610def Test_autoload_missing_function_name()
1611 mkdir('Xdir/autoload', 'p')
1612
1613 var lines =<< trim END
1614 vim9script
1615
1616 def loadme#()
1617 enddef
1618 END
1619 writefile(lines, 'Xdir/autoload/loadme.vim')
1620 assert_fails('source Xdir/autoload/loadme.vim', 'E129:')
1621
1622 delete('Xdir', 'rf')
1623enddef
1624
Bram Moolenaar19e69a62022-01-21 20:37:05 +00001625def Test_autoload_name_wring()
1626 var lines =<< trim END
1627 vim9script
1628 def Xscriptname#Func()
1629 enddef
1630 END
1631 writefile(lines, 'Xscriptname.vim')
1632 CheckScriptFailure(lines, 'E1263:')
1633
1634 delete('Xscriptname')
1635enddef
1636
Bram Moolenaard041f422022-01-12 19:54:00 +00001637def Test_import_autoload_postponed()
1638 mkdir('Xdir/autoload', 'p')
1639 var save_rtp = &rtp
1640 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1641
1642 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001643 vim9script
Bram Moolenaard041f422022-01-12 19:54:00 +00001644
1645 g:loaded_postponed = 'true'
1646 export var variable = 'bla'
1647 export def Function(): string
1648 return 'bla'
1649 enddef
1650 END
1651 writefile(lines, 'Xdir/autoload/postponed.vim')
1652
1653 lines =<< trim END
1654 vim9script
1655
1656 import autoload 'postponed.vim'
1657 def Tryit()
1658 echo postponed.variable
1659 echo postponed.Function()
1660 enddef
1661 defcompile
1662 END
1663 CheckScriptSuccess(lines)
1664 assert_false(exists('g:loaded_postponed'))
1665 CheckScriptSuccess(lines + ['Tryit()'])
1666 assert_equal('true', g:loaded_postponed)
1667
1668 unlet g:loaded_postponed
1669 delete('Xdir', 'rf')
1670 &rtp = save_rtp
1671enddef
1672
Bram Moolenaar3e4fa3d2022-01-13 22:05:09 +00001673def Test_import_autoload_override()
1674 mkdir('Xdir/autoload', 'p')
1675 var save_rtp = &rtp
1676 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1677 test_override('autoload', 1)
1678
1679 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001680 vim9script
Bram Moolenaar3e4fa3d2022-01-13 22:05:09 +00001681
1682 g:loaded_override = 'true'
1683 export var variable = 'bla'
1684 export def Function(): string
1685 return 'bla'
1686 enddef
1687 END
1688 writefile(lines, 'Xdir/autoload/override.vim')
1689
1690 lines =<< trim END
1691 vim9script
1692
1693 import autoload 'override.vim'
1694 assert_equal('true', g:loaded_override)
1695
1696 def Tryit()
1697 echo override.doesNotExist
1698 enddef
1699 defcompile
1700 END
1701 CheckScriptFailure(lines, 'E1048: Item not found in script: doesNotExist', 1)
1702
1703 test_override('autoload', 0)
1704 unlet g:loaded_override
1705 delete('Xdir', 'rf')
1706 &rtp = save_rtp
1707enddef
1708
Bram Moolenaar19db9e62022-01-11 11:58:19 +00001709def Test_autoload_mapping()
1710 mkdir('Xdir/autoload', 'p')
1711 var save_rtp = &rtp
1712 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1713
1714 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001715 vim9script
Bram Moolenaar19db9e62022-01-11 11:58:19 +00001716
1717 g:toggle_loaded = 'yes'
1718
1719 export def Toggle(): string
1720 return ":g:toggle_called = 'yes'\<CR>"
1721 enddef
Bram Moolenaare32c3c42022-01-15 18:26:04 +00001722 export def Doit()
1723 g:doit_called = 'yes'
1724 enddef
Bram Moolenaar19db9e62022-01-11 11:58:19 +00001725 END
1726 writefile(lines, 'Xdir/autoload/toggle.vim')
1727
1728 lines =<< trim END
1729 vim9script
1730
1731 import autoload 'toggle.vim'
1732
1733 nnoremap <silent> <expr> tt toggle.Toggle()
Bram Moolenaare32c3c42022-01-15 18:26:04 +00001734 nnoremap <silent> xx <ScriptCmd>toggle.Doit()<CR>
1735 nnoremap <silent> yy <Cmd>toggle.Doit()<CR>
Bram Moolenaar19db9e62022-01-11 11:58:19 +00001736 END
1737 CheckScriptSuccess(lines)
1738 assert_false(exists("g:toggle_loaded"))
1739 assert_false(exists("g:toggle_called"))
Bram Moolenaar6079da72022-01-18 14:16:59 +00001740 assert_match('\d A: \f*[/\\]toggle.vim', execute('scriptnames'))
Bram Moolenaar19db9e62022-01-11 11:58:19 +00001741
1742 feedkeys("tt", 'xt')
1743 assert_equal('yes', g:toggle_loaded)
1744 assert_equal('yes', g:toggle_called)
Bram Moolenaar6079da72022-01-18 14:16:59 +00001745 assert_match('\d: \f*[/\\]toggle.vim', execute('scriptnames'))
Bram Moolenaar19db9e62022-01-11 11:58:19 +00001746
Bram Moolenaare32c3c42022-01-15 18:26:04 +00001747 feedkeys("xx", 'xt')
1748 assert_equal('yes', g:doit_called)
1749
1750 assert_fails('call feedkeys("yy", "xt")', 'E121: Undefined variable: toggle')
1751
Bram Moolenaar19db9e62022-01-11 11:58:19 +00001752 nunmap tt
Bram Moolenaare32c3c42022-01-15 18:26:04 +00001753 nunmap xx
1754 nunmap yy
Bram Moolenaar19db9e62022-01-11 11:58:19 +00001755 unlet g:toggle_loaded
1756 unlet g:toggle_called
1757 delete('Xdir', 'rf')
1758 &rtp = save_rtp
1759enddef
1760
Bram Moolenaar160aa862022-01-10 21:29:57 +00001761def Test_vim9script_autoload_fails()
1762 var lines =<< trim END
1763 vim9script autoload
1764 var n = 0
1765 END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001766 CheckScriptFailure(lines, 'E475: Invalid argument: autoload')
1767
1768 lines =<< trim END
1769 vim9script noclear noclear
1770 var n = 0
1771 END
1772 CheckScriptFailure(lines, 'E983: Duplicate argument: noclear')
Bram Moolenaar160aa862022-01-10 21:29:57 +00001773enddef
1774
1775def Test_import_autoload_fails()
1776 var lines =<< trim END
1777 vim9script
1778 import autoload autoload 'prefixed.vim'
1779 END
1780 CheckScriptFailure(lines, 'E121: Undefined variable: autoload')
1781
1782 lines =<< trim END
1783 vim9script
Bram Moolenaar1836d612022-01-18 13:14:47 +00001784 import autoload './doesNotExist.vim'
Bram Moolenaar160aa862022-01-10 21:29:57 +00001785 END
1786 CheckScriptFailure(lines, 'E1264:')
Bram Moolenaar1836d612022-01-18 13:14:47 +00001787
1788 lines =<< trim END
1789 vim9script
1790 import autoload '/dir/doesNotExist.vim'
1791 END
1792 CheckScriptFailure(lines, 'E1264:')
1793
1794 lines =<< trim END
1795 vim9script
1796 import autoload 'doesNotExist.vim'
1797 END
1798 CheckScriptFailure(lines, 'E1053: Could not import "doesNotExist.vim"')
Bram Moolenaar160aa862022-01-10 21:29:57 +00001799enddef
1800
1801" test disassembling an auto-loaded function starting with "debug"
1802def Test_vim9_autoload_disass()
1803 mkdir('Xdir/autoload', 'p')
1804 var save_rtp = &rtp
1805 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1806
1807 var lines =<< trim END
1808 vim9script
1809 def debugit#test(): string
1810 return 'debug'
1811 enddef
1812 END
1813 writefile(lines, 'Xdir/autoload/debugit.vim')
1814
1815 lines =<< trim END
1816 vim9script
1817 def profileit#test(): string
1818 return 'profile'
1819 enddef
1820 END
1821 writefile(lines, 'Xdir/autoload/profileit.vim')
1822
1823 lines =<< trim END
1824 vim9script
1825 assert_equal('debug', debugit#test())
1826 disass debugit#test
1827 assert_equal('profile', profileit#test())
1828 disass profileit#test
1829 END
1830 CheckScriptSuccess(lines)
1831
1832 delete('Xdir', 'rf')
1833 &rtp = save_rtp
1834enddef
1835
1836" test using a vim9script that is auto-loaded from an autocmd
1837def Test_vim9_aucmd_autoload()
1838 var lines =<< trim END
1839 vim9script
1840 def foo#test()
1841 echomsg getreg('"')
1842 enddef
1843 END
1844
1845 mkdir('Xdir/autoload', 'p')
1846 writefile(lines, 'Xdir/autoload/foo.vim')
1847 var save_rtp = &rtp
1848 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1849 augroup test
1850 autocmd TextYankPost * call foo#test()
1851 augroup END
1852
1853 normal Y
1854
1855 augroup test
1856 autocmd!
1857 augroup END
1858 delete('Xdir', 'rf')
1859 &rtp = save_rtp
1860enddef
1861
Bram Moolenaar3049fcf2022-01-13 19:25:50 +00001862" test using a autoloaded file that is case sensitive
1863def Test_vim9_autoload_case_sensitive()
1864 var lines =<< trim END
Bram Moolenaarfd218c82022-01-18 16:26:24 +00001865 vim9script
Bram Moolenaar3049fcf2022-01-13 19:25:50 +00001866 export def CaseSensitive(): string
1867 return 'done'
1868 enddef
1869 END
1870
1871 mkdir('Xdir/autoload', 'p')
1872 writefile(lines, 'Xdir/autoload/CaseSensitive.vim')
1873 var save_rtp = &rtp
1874 exe 'set rtp^=' .. getcwd() .. '/Xdir'
1875
1876 lines =<< trim END
1877 vim9script
1878 import autoload 'CaseSensitive.vim'
1879 assert_equal('done', CaseSensitive.CaseSensitive())
1880 END
1881 CheckScriptSuccess(lines)
1882
Bram Moolenaarbfac4092022-01-16 11:12:12 +00001883 if !has('fname_case')
1884 lines =<< trim END
1885 vim9script
1886 import autoload 'CaseSensitive.vim'
1887 import autoload 'casesensitive.vim'
1888 END
1889 CheckScriptFailure(lines, 'E1262:')
1890 endif
1891
Bram Moolenaar3049fcf2022-01-13 19:25:50 +00001892 delete('Xdir', 'rf')
1893 &rtp = save_rtp
1894enddef
1895
Bram Moolenaar160aa862022-01-10 21:29:57 +00001896" This was causing a crash because suppress_errthrow wasn't reset.
1897def Test_vim9_autoload_error()
1898 var lines =<< trim END
1899 vim9script
1900 def crash#func()
1901 try
1902 for x in List()
1903 endfor
1904 catch
1905 endtry
1906 g:ok = true
1907 enddef
1908 fu List()
1909 invalid
1910 endfu
1911 try
1912 alsoinvalid
1913 catch /wontmatch/
1914 endtry
1915 END
1916 call mkdir('Xruntime/autoload', 'p')
1917 call writefile(lines, 'Xruntime/autoload/crash.vim')
1918
1919 # run in a separate Vim to avoid the side effects of assert_fails()
1920 lines =<< trim END
1921 exe 'set rtp^=' .. getcwd() .. '/Xruntime'
1922 call crash#func()
1923 call writefile(['ok'], 'Xdidit')
1924 qall!
1925 END
1926 writefile(lines, 'Xscript')
1927 RunVim([], [], '-S Xscript')
1928 assert_equal(['ok'], readfile('Xdidit'))
1929
1930 delete('Xdidit')
1931 delete('Xscript')
1932 delete('Xruntime', 'rf')
1933
1934 lines =<< trim END
1935 vim9script
1936 var foo#bar = 'asdf'
1937 END
1938 CheckScriptFailure(lines, 'E461: Illegal variable name: foo#bar', 2)
1939enddef
1940
Bram Moolenaard8448622022-01-07 21:39:52 +00001941
1942" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker