1" Test various aspects of the Vim9 script language.
2
3source check.vim
4source term_util.vim
5source view_util.vim
6source vim9.vim
7source shared.vim
8
9def Test_syntax()
10  let var = 234
11  let other: list<string> = ['asdf']
12enddef
13
14def Test_range_only()
15  new
16  setline(1, ['blah', 'Blah'])
17  :/Blah/
18  assert_equal(2, getcurpos()[1])
19  bwipe!
20
21  # without range commands use current line
22  new
23  setline(1, ['one', 'two', 'three'])
24  :2
25  print
26  assert_equal('two', Screenline(&lines))
27  :3
28  list
29  assert_equal('three$', Screenline(&lines))
30  bwipe!
31enddef
32
33let s:appendToMe = 'xxx'
34let s:addToMe = 111
35let g:existing = 'yes'
36let g:inc_counter = 1
37let $SOME_ENV_VAR = 'some'
38let g:alist = [7]
39let g:astring = 'text'
40let g:anumber = 123
41
42def Test_assignment()
43  let bool1: bool = true
44  assert_equal(v:true, bool1)
45  let bool2: bool = false
46  assert_equal(v:false, bool2)
47
48  call CheckDefFailure(['let x:string'], 'E1069:')
49  call CheckDefFailure(['let x:string = "x"'], 'E1069:')
50  call CheckDefFailure(['let a:string = "x"'], 'E1069:')
51  call CheckDefFailure(['let lambda = {-> "lambda"}'], 'E704:')
52
53  let nr: number = 1234
54  call CheckDefFailure(['let nr: number = "asdf"'], 'E1012:')
55
56  let a: number = 6 #comment
57  assert_equal(6, a)
58
59  if has('channel')
60    let chan1: channel
61    let job1: job
62    let job2: job = job_start('willfail')
63  endif
64  if has('float')
65    let float1: float = 3.4
66  endif
67  let Funky1: func
68  let Funky2: func = function('len')
69  let Party2: func = funcref('g:Test_syntax')
70
71  g:newvar = 'new'  #comment
72  assert_equal('new', g:newvar)
73
74  assert_equal('yes', g:existing)
75  g:existing = 'no'
76  assert_equal('no', g:existing)
77
78  v:char = 'abc'
79  assert_equal('abc', v:char)
80
81  $ENVVAR = 'foobar'
82  assert_equal('foobar', $ENVVAR)
83  $ENVVAR = ''
84
85  let lines =<< trim END
86    vim9script
87    $ENVVAR = 'barfoo'
88    assert_equal('barfoo', $ENVVAR)
89    $ENVVAR = ''
90  END
91  call CheckScriptSuccess(lines)
92
93  s:appendToMe ..= 'yyy'
94  assert_equal('xxxyyy', s:appendToMe)
95  s:addToMe += 222
96  assert_equal(333, s:addToMe)
97  s:newVar = 'new'
98  assert_equal('new', s:newVar)
99
100  set ts=7
101  &ts += 1
102  assert_equal(8, &ts)
103  &ts -= 3
104  assert_equal(5, &ts)
105  &ts *= 2
106  assert_equal(10, &ts)
107  &ts /= 3
108  assert_equal(3, &ts)
109  set ts=10
110  &ts %= 4
111  assert_equal(2, &ts)
112
113  if has('float')
114    let f100: float = 100.0
115    f100 /= 5
116    assert_equal(20.0, f100)
117
118    let f200: float = 200.0
119    f200 /= 5.0
120    assert_equal(40.0, f200)
121
122    CheckDefFailure(['let nr: number = 200', 'nr /= 5.0'], 'E1012:')
123  endif
124
125  lines =<< trim END
126    &ts = 6
127    &ts += 3
128    assert_equal(9, &ts)
129
130    &l:ts = 6
131    assert_equal(6, &ts)
132    &l:ts += 2
133    assert_equal(8, &ts)
134
135    &g:ts = 6
136    assert_equal(6, &g:ts)
137    &g:ts += 2
138    assert_equal(8, &g:ts)
139  END
140  CheckDefAndScriptSuccess(lines)
141
142  CheckDefFailure(['&notex += 3'], 'E113:')
143  CheckDefFailure(['&ts ..= "xxx"'], 'E1019:')
144  CheckDefFailure(['&ts = [7]'], 'E1012:')
145  CheckDefExecFailure(['&ts = g:alist'], 'E1029: Expected number but got list')
146  CheckDefFailure(['&ts = "xx"'], 'E1012:')
147  CheckDefExecFailure(['&ts = g:astring'], 'E1029: Expected number but got string')
148  CheckDefFailure(['&path += 3'], 'E1012:')
149  CheckDefExecFailure(['&bs = "asdf"'], 'E474:')
150  # test freeing ISN_STOREOPT
151  CheckDefFailure(['&ts = 3', 'let asdf'], 'E1022:')
152  &ts = 8
153
154  lines =<< trim END
155    let save_TI = &t_TI
156    &t_TI = ''
157    assert_equal('', &t_TI)
158    &t_TI = 'xxx'
159    assert_equal('xxx', &t_TI)
160    &t_TI = save_TI
161  END
162  CheckDefSuccess(lines)
163  CheckScriptSuccess(['vim9script'] + lines)
164
165  CheckDefFailure(['&t_TI = 123'], 'E1012:')
166  CheckScriptFailure(['vim9script', '&t_TI = 123'], 'E928:')
167
168  CheckDefFailure(['let s:var = 123'], 'E1101:')
169  CheckDefFailure(['let s:var: number'], 'E1101:')
170
171  lines =<< trim END
172    vim9script
173    def SomeFunc()
174      s:var = 123
175    enddef
176    defcompile
177  END
178  call CheckScriptFailure(lines, 'E1089:')
179
180  g:inc_counter += 1
181  assert_equal(2, g:inc_counter)
182
183  $SOME_ENV_VAR ..= 'more'
184  assert_equal('somemore', $SOME_ENV_VAR)
185  call CheckDefFailure(['$SOME_ENV_VAR += "more"'], 'E1051:')
186  call CheckDefFailure(['$SOME_ENV_VAR += 123'], 'E1012:')
187
188  lines =<< trim END
189    @c = 'areg'
190    @c ..= 'add'
191    assert_equal('aregadd', @c)
192  END
193  CheckDefAndScriptSuccess(lines)
194
195  call CheckDefFailure(['@a += "more"'], 'E1051:')
196  call CheckDefFailure(['@a += 123'], 'E1012:')
197
198  v:errmsg = 'none'
199  v:errmsg ..= 'again'
200  assert_equal('noneagain', v:errmsg)
201  call CheckDefFailure(['v:errmsg += "more"'], 'E1051:')
202  call CheckDefFailure(['v:errmsg += 123'], 'E1012:')
203
204  # single letter variables
205  a = 123
206  assert_equal(123, a)
207  let b: number
208  b = 123
209  assert_equal(123, b)
210  let g: number
211  g = 123
212  assert_equal(123, g)
213  let s: number
214  s = 123
215  assert_equal(123, s)
216  let t: number
217  t = 123
218  assert_equal(123, t)
219  let v: number
220  v = 123
221  assert_equal(123, v)
222  let w: number
223  w = 123
224  assert_equal(123, w)
225enddef
226
227def Test_vim9_single_char_vars()
228  let lines =<< trim END
229      vim9script
230
231      # single character variable declarations work
232      let a: string
233      let b: number
234      let l: list<any>
235      let s: string
236      let t: number
237      let v: number
238      let w: number
239
240      # script-local variables can be used without s: prefix
241      a = 'script-a'
242      b = 111
243      l = [1, 2, 3]
244      s = 'script-s'
245      t = 222
246      v = 333
247      w = 444
248
249      assert_equal('script-a', a)
250      assert_equal(111, b)
251      assert_equal([1, 2, 3], l)
252      assert_equal('script-s', s)
253      assert_equal(222, t)
254      assert_equal(333, v)
255      assert_equal(444, w)
256  END
257  writefile(lines, 'Xsinglechar')
258  source Xsinglechar
259  delete('Xsinglechar')
260enddef
261
262def Test_assignment_list()
263  let list1: list<bool> = [false, true, false]
264  let list2: list<number> = [1, 2, 3]
265  let list3: list<string> = ['sdf', 'asdf']
266  let list4: list<any> = ['yes', true, 1234]
267  let list5: list<blob> = [0z01, 0z02]
268
269  let listS: list<string> = []
270  let listN: list<number> = []
271
272  assert_equal([1, 2, 3], list2)
273  list2[-1] = 99
274  assert_equal([1, 2, 99], list2)
275  list2[-2] = 88
276  assert_equal([1, 88, 99], list2)
277  list2[-3] = 77
278  assert_equal([77, 88, 99], list2)
279  list2 += [100]
280  assert_equal([77, 88, 99, 100], list2)
281
282  list3 += ['end']
283  assert_equal(['sdf', 'asdf', 'end'], list3)
284
285
286  call CheckDefExecFailure(['let ll = [1, 2, 3]', 'll[-4] = 6'], 'E684:')
287  call CheckDefExecFailure(['let [v1, v2] = [1, 2]'], 'E1092:')
288
289  # type becomes list<any>
290  let somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c']
291enddef
292
293def Test_assignment_list_vim9script()
294  let lines =<< trim END
295    vim9script
296    let v1: number
297    let v2: number
298    let v3: number
299    [v1, v2, v3] = [1, 2, 3]
300    assert_equal([1, 2, 3], [v1, v2, v3])
301  END
302  call CheckScriptSuccess(lines)
303enddef
304
305def Test_assignment_dict()
306  let dict1: dict<bool> = #{one: false, two: true}
307  let dict2: dict<number> = #{one: 1, two: 2}
308  let dict3: dict<string> = #{key: 'value'}
309  let dict4: dict<any> = #{one: 1, two: '2'}
310  let dict5: dict<blob> = #{one: 0z01, two: 0z02}
311
312  # overwrite
313  dict3['key'] = 'another'
314
315  # empty key can be used
316  let dd = {}
317  dd[""] = 6
318  assert_equal({'': 6}, dd)
319
320  # type becomes dict<any>
321  let somedict = rand() > 0 ? #{a: 1, b: 2} : #{a: 'a', b: 'b'}
322
323  # assignment to script-local dict
324  let lines =<< trim END
325    vim9script
326    let test: dict<any> = {}
327    def FillDict(): dict<any>
328      test['a'] = 43
329      return test
330    enddef
331    assert_equal(#{a: 43}, FillDict())
332  END
333  call CheckScriptSuccess(lines)
334
335  lines =<< trim END
336    vim9script
337    let test: dict<any>
338    def FillDict(): dict<any>
339      test['a'] = 43
340      return test
341    enddef
342    FillDict()
343  END
344  call CheckScriptFailure(lines, 'E1103:')
345
346  # assignment to global dict
347  lines =<< trim END
348    vim9script
349    g:test = {}
350    def FillDict(): dict<any>
351      g:test['a'] = 43
352      return g:test
353    enddef
354    assert_equal(#{a: 43}, FillDict())
355  END
356  call CheckScriptSuccess(lines)
357
358  # assignment to buffer dict
359  lines =<< trim END
360    vim9script
361    b:test = {}
362    def FillDict(): dict<any>
363      b:test['a'] = 43
364      return b:test
365    enddef
366    assert_equal(#{a: 43}, FillDict())
367  END
368  call CheckScriptSuccess(lines)
369enddef
370
371def Test_assignment_local()
372  # Test in a separated file in order not to the current buffer/window/tab is
373  # changed.
374  let script_lines: list<string> =<< trim END
375    let b:existing = 'yes'
376    let w:existing = 'yes'
377    let t:existing = 'yes'
378
379    def Test_assignment_local_internal()
380      b:newvar = 'new'
381      assert_equal('new', b:newvar)
382      assert_equal('yes', b:existing)
383      b:existing = 'no'
384      assert_equal('no', b:existing)
385      b:existing ..= 'NO'
386      assert_equal('noNO', b:existing)
387
388      w:newvar = 'new'
389      assert_equal('new', w:newvar)
390      assert_equal('yes', w:existing)
391      w:existing = 'no'
392      assert_equal('no', w:existing)
393      w:existing ..= 'NO'
394      assert_equal('noNO', w:existing)
395
396      t:newvar = 'new'
397      assert_equal('new', t:newvar)
398      assert_equal('yes', t:existing)
399      t:existing = 'no'
400      assert_equal('no', t:existing)
401      t:existing ..= 'NO'
402      assert_equal('noNO', t:existing)
403    enddef
404    call Test_assignment_local_internal()
405  END
406  call CheckScriptSuccess(script_lines)
407enddef
408
409def Test_assignment_default()
410
411  # Test default values.
412  let thebool: bool
413  assert_equal(v:false, thebool)
414
415  let thenumber: number
416  assert_equal(0, thenumber)
417
418  if has('float')
419    let thefloat: float
420    assert_equal(0.0, thefloat)
421  endif
422
423  let thestring: string
424  assert_equal('', thestring)
425
426  let theblob: blob
427  assert_equal(0z, theblob)
428
429  let Thefunc: func
430  assert_equal(test_null_function(), Thefunc)
431
432  let thelist: list<any>
433  assert_equal([], thelist)
434
435  let thedict: dict<any>
436  assert_equal({}, thedict)
437
438  if has('channel')
439    let thejob: job
440    assert_equal(test_null_job(), thejob)
441
442    let thechannel: channel
443    assert_equal(test_null_channel(), thechannel)
444
445    if has('unix') && executable('cat')
446      # check with non-null job and channel, types must match
447      thejob = job_start("cat ", #{})
448      thechannel = job_getchannel(thejob)
449      job_stop(thejob, 'kill')
450    endif
451  endif
452
453  let nr = 1234 | nr = 5678
454  assert_equal(5678, nr)
455enddef
456
457def Test_assignment_var_list()
458  let v1: string
459  let v2: string
460  let vrem: list<string>
461  [v1] = ['aaa']
462  assert_equal('aaa', v1)
463
464  [v1, v2] = ['one', 'two']
465  assert_equal('one', v1)
466  assert_equal('two', v2)
467
468  [v1, v2; vrem] = ['one', 'two']
469  assert_equal('one', v1)
470  assert_equal('two', v2)
471  assert_equal([], vrem)
472
473  [v1, v2; vrem] = ['one', 'two', 'three']
474  assert_equal('one', v1)
475  assert_equal('two', v2)
476  assert_equal(['three'], vrem)
477
478  [&ts, &sw] = [3, 4]
479  assert_equal(3, &ts)
480  assert_equal(4, &sw)
481  set ts=8 sw=4
482enddef
483
484def Test_assignment_vim9script()
485  let lines =<< trim END
486    vim9script
487    def Func(): list<number>
488      return [1, 2]
489    enddef
490    let var1: number
491    let var2: number
492    [var1, var2] =
493          Func()
494    assert_equal(1, var1)
495    assert_equal(2, var2)
496    let ll =
497          Func()
498    assert_equal([1, 2], ll)
499
500    @/ = 'text'
501    assert_equal('text', @/)
502    @0 = 'zero'
503    assert_equal('zero', @0)
504    @1 = 'one'
505    assert_equal('one', @1)
506    @9 = 'nine'
507    assert_equal('nine', @9)
508    @- = 'minus'
509    assert_equal('minus', @-)
510    if has('clipboard_working')
511      @* = 'star'
512      assert_equal('star', @*)
513      @+ = 'plus'
514      assert_equal('plus', @+)
515    endif
516
517    let a: number = 123
518    assert_equal(123, a)
519    let s: string = 'yes'
520    assert_equal('yes', s)
521    let b: number = 42
522    assert_equal(42, b)
523    let w: number = 43
524    assert_equal(43, w)
525    let t: number = 44
526    assert_equal(44, t)
527  END
528  CheckScriptSuccess(lines)
529enddef
530
531def Mess(): string
532  v:foldstart = 123
533  return 'xxx'
534enddef
535
536def Test_assignment_failure()
537  call CheckDefFailure(['let var=234'], 'E1004:')
538  call CheckDefFailure(['let var =234'], 'E1004:')
539  call CheckDefFailure(['let var= 234'], 'E1004:')
540
541  call CheckScriptFailure(['vim9script', 'let var=234'], 'E1004:')
542  call CheckScriptFailure(['vim9script', 'let var=234'], "before and after '='")
543  call CheckScriptFailure(['vim9script', 'let var =234'], 'E1004:')
544  call CheckScriptFailure(['vim9script', 'let var= 234'], 'E1004:')
545  call CheckScriptFailure(['vim9script', 'let var = 234', 'var+=234'], 'E1004:')
546  call CheckScriptFailure(['vim9script', 'let var = 234', 'var+=234'], "before and after '+='")
547  call CheckScriptFailure(['vim9script', 'let var = "x"', 'var..="y"'], 'E1004:')
548  call CheckScriptFailure(['vim9script', 'let var = "x"', 'var..="y"'], "before and after '..='")
549
550  call CheckDefFailure(['let true = 1'], 'E1034:')
551  call CheckDefFailure(['let false = 1'], 'E1034:')
552
553  call CheckDefFailure(['[a; b; c] = g:list'], 'E452:')
554  call CheckDefExecFailure(['let a: number',
555                            '[a] = test_null_list()'], 'E1093:')
556  call CheckDefExecFailure(['let a: number',
557                            '[a] = []'], 'E1093:')
558  call CheckDefExecFailure(['let x: number',
559                            'let y: number',
560                            '[x, y] = [1]'], 'E1093:')
561  call CheckDefExecFailure(['let x: number',
562                            'let y: number',
563                            'let z: list<number>',
564                            '[x, y; z] = [1]'], 'E1093:')
565
566  call CheckDefFailure(['let somevar'], "E1022:")
567  call CheckDefFailure(['let &tabstop = 4'], 'E1052:')
568  call CheckDefFailure(['&g:option = 5'], 'E113:')
569  call CheckScriptFailure(['vim9script', 'let &tabstop = 4'], 'E1052:')
570
571  call CheckDefFailure(['let $VAR = 5'], 'E1016: Cannot declare an environment variable:')
572  call CheckScriptFailure(['vim9script', 'let $ENV = "xxx"'], 'E1016:')
573
574  if has('dnd')
575    call CheckDefFailure(['let @~ = 5'], 'E1066:')
576  else
577    call CheckDefFailure(['let @~ = 5'], 'E354:')
578    call CheckDefFailure(['@~ = 5'], 'E354:')
579  endif
580  call CheckDefFailure(['let @a = 5'], 'E1066:')
581  call CheckDefFailure(['let @/ = "x"'], 'E1066:')
582  call CheckScriptFailure(['vim9script', 'let @a = "abc"'], 'E1066:')
583
584  call CheckDefFailure(['let g:var = 5'], 'E1016: Cannot declare a global variable:')
585  call CheckDefFailure(['let w:var = 5'], 'E1016: Cannot declare a window variable:')
586  call CheckDefFailure(['let b:var = 5'], 'E1016: Cannot declare a buffer variable:')
587  call CheckDefFailure(['let t:var = 5'], 'E1016: Cannot declare a tab variable:')
588
589  call CheckDefFailure(['let anr = 4', 'anr ..= "text"'], 'E1019:')
590  call CheckDefFailure(['let xnr += 4'], 'E1020:', 1)
591  call CheckScriptFailure(['vim9script', 'let xnr += 4'], 'E1020:')
592  call CheckDefFailure(["let xnr = xnr + 1"], 'E1001:', 1)
593  call CheckScriptFailure(['vim9script', 'let xnr = xnr + 4'], 'E121:')
594
595  call CheckScriptFailure(['vim9script', 'def Func()', 'let dummy = s:notfound', 'enddef', 'defcompile'], 'E1108:')
596
597  call CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>')
598  call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
599
600  call CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>')
601  call CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>')
602
603  call CheckDefFailure(['let var = feedkeys("0")'], 'E1031:')
604  call CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void')
605
606  call CheckDefFailure(['let var: dict <number>'], 'E1068:')
607  call CheckDefFailure(['let var: dict<number'], 'E1009:')
608
609  call assert_fails('s/^/\=Mess()/n', 'E794:')
610  call CheckDefFailure(['let var: dict<number'], 'E1009:')
611
612  call CheckDefFailure(['w:foo: number = 10'],
613                       'E488: Trailing characters: : number = 1')
614  call CheckDefFailure(['t:foo: bool = true'],
615                       'E488: Trailing characters: : bool = true')
616  call CheckDefFailure(['b:foo: string = "x"'],
617                       'E488: Trailing characters: : string = "x"')
618  call CheckDefFailure(['g:foo: number = 123'],
619                       'E488: Trailing characters: : number = 123')
620enddef
621
622def Test_unlet()
623  g:somevar = 'yes'
624  assert_true(exists('g:somevar'))
625  unlet g:somevar
626  assert_false(exists('g:somevar'))
627  unlet! g:somevar
628
629  # also works for script-local variable in legacy Vim script
630  s:somevar = 'legacy'
631  assert_true(exists('s:somevar'))
632  unlet s:somevar
633  assert_false(exists('s:somevar'))
634  unlet! s:somevar
635
636  call CheckScriptFailure([
637        'vim9script',
638        'let svar = 123',
639        'unlet svar',
640        ], 'E1081:')
641  call CheckScriptFailure([
642        'vim9script',
643        'let svar = 123',
644        'unlet s:svar',
645        ], 'E1081:')
646  call CheckScriptFailure([
647        'vim9script',
648        'let svar = 123',
649        'def Func()',
650        '  unlet svar',
651        'enddef',
652        'defcompile',
653        ], 'E1081:')
654  call CheckScriptFailure([
655        'vim9script',
656        'let svar = 123',
657        'def Func()',
658        '  unlet s:svar',
659        'enddef',
660        'defcompile',
661        ], 'E1081:')
662
663  $ENVVAR = 'foobar'
664  assert_equal('foobar', $ENVVAR)
665  unlet $ENVVAR
666  assert_equal('', $ENVVAR)
667enddef
668
669def Test_delfunction()
670  # Check function is defined in script namespace
671  CheckScriptSuccess([
672      'vim9script',
673      'func CheckMe()',
674      '  return 123',
675      'endfunc',
676      'assert_equal(123, s:CheckMe())',
677      ])
678
679  # Check function in script namespace cannot be deleted
680  CheckScriptFailure([
681      'vim9script',
682      'func DeleteMe1()',
683      'endfunc',
684      'delfunction DeleteMe1',
685      ], 'E1084:')
686  CheckScriptFailure([
687      'vim9script',
688      'func DeleteMe2()',
689      'endfunc',
690      'def DoThat()',
691      '  delfunction DeleteMe2',
692      'enddef',
693      'DoThat()',
694      ], 'E1084:')
695  CheckScriptFailure([
696      'vim9script',
697      'def DeleteMe3()',
698      'enddef',
699      'delfunction DeleteMe3',
700      ], 'E1084:')
701  CheckScriptFailure([
702      'vim9script',
703      'def DeleteMe4()',
704      'enddef',
705      'def DoThat()',
706      '  delfunction DeleteMe4',
707      'enddef',
708      'DoThat()',
709      ], 'E1084:')
710
711  # Check that global :def function can be replaced and deleted
712  let lines =<< trim END
713      vim9script
714      def g:Global(): string
715        return "yes"
716      enddef
717      assert_equal("yes", g:Global())
718      def! g:Global(): string
719        return "no"
720      enddef
721      assert_equal("no", g:Global())
722      delfunc g:Global
723      assert_false(exists('*g:Global'))
724  END
725  CheckScriptSuccess(lines)
726
727  # Check that global function can be replaced by a :def function and deleted
728  lines =<< trim END
729      vim9script
730      func g:Global()
731        return "yes"
732      endfunc
733      assert_equal("yes", g:Global())
734      def! g:Global(): string
735        return "no"
736      enddef
737      assert_equal("no", g:Global())
738      delfunc g:Global
739      assert_false(exists('*g:Global'))
740  END
741  CheckScriptSuccess(lines)
742
743  # Check that global :def function can be replaced by a function and deleted
744  lines =<< trim END
745      vim9script
746      def g:Global(): string
747        return "yes"
748      enddef
749      assert_equal("yes", g:Global())
750      func! g:Global()
751        return "no"
752      endfunc
753      assert_equal("no", g:Global())
754      delfunc g:Global
755      assert_false(exists('*g:Global'))
756  END
757  CheckScriptSuccess(lines)
758enddef
759
760func Test_wrong_type()
761  call CheckDefFailure(['let var: list<nothing>'], 'E1010:')
762  call CheckDefFailure(['let var: list<list<nothing>>'], 'E1010:')
763  call CheckDefFailure(['let var: dict<nothing>'], 'E1010:')
764  call CheckDefFailure(['let var: dict<dict<nothing>>'], 'E1010:')
765
766  call CheckDefFailure(['let var: dict<number'], 'E1009:')
767  call CheckDefFailure(['let var: dict<list<number>'], 'E1009:')
768
769  call CheckDefFailure(['let var: ally'], 'E1010:')
770  call CheckDefFailure(['let var: bram'], 'E1010:')
771  call CheckDefFailure(['let var: cathy'], 'E1010:')
772  call CheckDefFailure(['let var: dom'], 'E1010:')
773  call CheckDefFailure(['let var: freddy'], 'E1010:')
774  call CheckDefFailure(['let var: john'], 'E1010:')
775  call CheckDefFailure(['let var: larry'], 'E1010:')
776  call CheckDefFailure(['let var: ned'], 'E1010:')
777  call CheckDefFailure(['let var: pam'], 'E1010:')
778  call CheckDefFailure(['let var: sam'], 'E1010:')
779  call CheckDefFailure(['let var: vim'], 'E1010:')
780
781  call CheckDefFailure(['let Ref: number', 'Ref()'], 'E1085:')
782  call CheckDefFailure(['let Ref: string', 'let res = Ref()'], 'E1085:')
783endfunc
784
785func Test_const()
786  call CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
787  call CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
788  call CheckDefFailure(['const two'], 'E1021:')
789  call CheckDefFailure(['const &option'], 'E996:')
790endfunc
791
792def Test_range_no_colon()
793  call CheckDefFailure(['%s/a/b/'], 'E1050:')
794  call CheckDefFailure(['+ s/a/b/'], 'E1050:')
795  call CheckDefFailure(['- s/a/b/'], 'E1050:')
796  call CheckDefFailure(['. s/a/b/'], 'E1050:')
797enddef
798
799
800def Test_block()
801  let outer = 1
802  {
803    let inner = 2
804    assert_equal(1, outer)
805    assert_equal(2, inner)
806  }
807  assert_equal(1, outer)
808enddef
809
810func Test_block_failure()
811  call CheckDefFailure(['{', 'let inner = 1', '}', 'echo inner'], 'E1001:')
812  call CheckDefFailure(['}'], 'E1025:')
813  call CheckDefFailure(['{', 'echo 1'], 'E1026:')
814endfunc
815
816func g:NoSuchFunc()
817  echo 'none'
818endfunc
819
820def Test_try_catch()
821  let l = []
822  try # comment
823    add(l, '1')
824    throw 'wrong'
825    add(l, '2')
826  catch # comment
827    add(l, v:exception)
828  finally # comment
829    add(l, '3')
830  endtry # comment
831  assert_equal(['1', 'wrong', '3'], l)
832
833  l = []
834  try
835    try
836      add(l, '1')
837      throw 'wrong'
838      add(l, '2')
839    catch /right/
840      add(l, v:exception)
841    endtry
842  catch /wrong/
843    add(l, 'caught')
844  finally
845    add(l, 'finally')
846  endtry
847  assert_equal(['1', 'caught', 'finally'], l)
848
849  let n: number
850  try
851    n = l[3]
852  catch /E684:/
853    n = 99
854  endtry
855  assert_equal(99, n)
856
857  try
858    # string slice returns a string, not a number
859    n = g:astring[3]
860  catch /E1029:/
861    n = 77
862  endtry
863  assert_equal(77, n)
864
865  try
866    n = l[g:astring]
867  catch /E1029:/
868    n = 88
869  endtry
870  assert_equal(88, n)
871
872  try
873    n = s:does_not_exist
874  catch /E121:/
875    n = 111
876  endtry
877  assert_equal(111, n)
878
879  try
880    n = g:does_not_exist
881  catch /E121:/
882    n = 121
883  endtry
884  assert_equal(121, n)
885
886  let d = #{one: 1}
887  try
888    n = d[g:astring]
889  catch /E716:/
890    n = 222
891  endtry
892  assert_equal(222, n)
893
894  try
895    n = -g:astring
896  catch /E39:/
897    n = 233
898  endtry
899  assert_equal(233, n)
900
901  try
902    n = +g:astring
903  catch /E1030:/
904    n = 244
905  endtry
906  assert_equal(244, n)
907
908  try
909    n = +g:alist
910  catch /E745:/
911    n = 255
912  endtry
913  assert_equal(255, n)
914
915  let nd: dict<any>
916  try
917    nd = {g:anumber: 1}
918  catch /E1029:/
919    n = 266
920  endtry
921  assert_equal(266, n)
922
923  try
924    [n] = [1, 2, 3]
925  catch /E1093:/
926    n = 277
927  endtry
928  assert_equal(277, n)
929
930  try
931    &ts = g:astring
932  catch /E1029:/
933    n = 288
934  endtry
935  assert_equal(288, n)
936
937  try
938    &backspace = 'asdf'
939  catch /E474:/
940    n = 299
941  endtry
942  assert_equal(299, n)
943
944  l = [1]
945  try
946    l[3] = 3
947  catch /E684:/
948    n = 300
949  endtry
950  assert_equal(300, n)
951
952  try
953    unlet g:does_not_exist
954  catch /E108:/
955    n = 322
956  endtry
957  assert_equal(322, n)
958
959  try
960    d = {'text': 1, g:astring: 2}
961  catch /E721:/
962    n = 333
963  endtry
964  assert_equal(333, n)
965
966  try
967    l = DeletedFunc()
968  catch /E933:/
969    n = 344
970  endtry
971  assert_equal(344, n)
972
973  try
974    echo len(v:true)
975  catch /E701:/
976    n = 355
977  endtry
978  assert_equal(355, n)
979
980  let P = function('g:NoSuchFunc')
981  delfunc g:NoSuchFunc
982  try
983    echo P()
984  catch /E117:/
985    n = 366
986  endtry
987  assert_equal(366, n)
988
989  try
990    echo g:NoSuchFunc()
991  catch /E117:/
992    n = 377
993  endtry
994  assert_equal(377, n)
995
996  try
997    echo g:alist + 4
998  catch /E745:/
999    n = 388
1000  endtry
1001  assert_equal(388, n)
1002
1003  try
1004    echo 4 + g:alist
1005  catch /E745:/
1006    n = 399
1007  endtry
1008  assert_equal(399, n)
1009
1010  try
1011    echo g:alist.member
1012  catch /E715:/
1013    n = 400
1014  endtry
1015  assert_equal(400, n)
1016
1017  try
1018    echo d.member
1019  catch /E716:/
1020    n = 411
1021  endtry
1022  assert_equal(411, n)
1023enddef
1024
1025def DeletedFunc(): list<any>
1026  return ['delete me']
1027enddef
1028defcompile
1029delfunc DeletedFunc
1030
1031def ThrowFromDef()
1032  throw "getout" # comment
1033enddef
1034
1035func CatchInFunc()
1036  try
1037    call ThrowFromDef()
1038  catch
1039    let g:thrown_func = v:exception
1040  endtry
1041endfunc
1042
1043def CatchInDef()
1044  try
1045    ThrowFromDef()
1046  catch
1047    g:thrown_def = v:exception
1048  endtry
1049enddef
1050
1051def ReturnFinally(): string
1052  try
1053    return 'intry'
1054  finally
1055    g:in_finally = 'finally'
1056  endtry
1057  return 'end'
1058enddef
1059
1060def Test_try_catch_nested()
1061  CatchInFunc()
1062  assert_equal('getout', g:thrown_func)
1063
1064  CatchInDef()
1065  assert_equal('getout', g:thrown_def)
1066
1067  assert_equal('intry', ReturnFinally())
1068  assert_equal('finally', g:in_finally)
1069enddef
1070
1071def Test_try_catch_match()
1072  let seq = 'a'
1073  try
1074    throw 'something'
1075  catch /nothing/
1076    seq ..= 'x'
1077  catch /some/
1078    seq ..= 'b'
1079  catch /asdf/
1080    seq ..= 'x'
1081  catch ?a\?sdf?
1082    seq ..= 'y'
1083  finally
1084    seq ..= 'c'
1085  endtry
1086  assert_equal('abc', seq)
1087enddef
1088
1089def Test_try_catch_fails()
1090  call CheckDefFailure(['catch'], 'E603:')
1091  call CheckDefFailure(['try', 'echo 0', 'catch', 'catch'], 'E1033:')
1092  call CheckDefFailure(['try', 'echo 0', 'catch /pat'], 'E1067:')
1093  call CheckDefFailure(['finally'], 'E606:')
1094  call CheckDefFailure(['try', 'echo 0', 'finally', 'echo 1', 'finally'], 'E607:')
1095  call CheckDefFailure(['endtry'], 'E602:')
1096  call CheckDefFailure(['while 1', 'endtry'], 'E170:')
1097  call CheckDefFailure(['for i in range(5)', 'endtry'], 'E170:')
1098  call CheckDefFailure(['if 2', 'endtry'], 'E171:')
1099  call CheckDefFailure(['try', 'echo 1', 'endtry'], 'E1032:')
1100
1101  call CheckDefFailure(['throw'], 'E1015:')
1102  call CheckDefFailure(['throw xxx'], 'E1001:')
1103enddef
1104
1105def Test_throw_vimscript()
1106  # only checks line continuation
1107  let lines =<< trim END
1108      vim9script
1109      try
1110        throw 'one'
1111              .. 'two'
1112      catch
1113        assert_equal('onetwo', v:exception)
1114      endtry
1115  END
1116  CheckScriptSuccess(lines)
1117enddef
1118
1119def Test_error_in_nested_function()
1120  # an error in a nested :function aborts executin in the calling :def function
1121  let lines =<< trim END
1122      vim9script
1123      def Func()
1124        Error()
1125        g:test_var = 1
1126      enddef
1127      func Error() abort
1128        eval [][0]
1129      endfunc
1130      Func()
1131  END
1132  g:test_var = 0
1133  CheckScriptFailure(lines, 'E684:')
1134  assert_equal(0, g:test_var)
1135enddef
1136
1137def Test_cexpr_vimscript()
1138  # only checks line continuation
1139  set errorformat=File\ %f\ line\ %l
1140  let lines =<< trim END
1141      vim9script
1142      cexpr 'File'
1143                .. ' someFile' ..
1144                   ' line 19'
1145      assert_equal(19, getqflist()[0].lnum)
1146  END
1147  CheckScriptSuccess(lines)
1148  set errorformat&
1149enddef
1150
1151def Test_statusline_syntax()
1152  # legacy syntax is used for 'statusline'
1153  let lines =<< trim END
1154      vim9script
1155      func g:Status()
1156        return '%{"x" is# "x"}'
1157      endfunc
1158      set laststatus=2 statusline=%!Status()
1159      redrawstatus
1160      set laststatus statusline=
1161  END
1162  CheckScriptSuccess(lines)
1163enddef
1164
1165def Test_list_vimscript()
1166  # checks line continuation and comments
1167  let lines =<< trim END
1168      vim9script
1169      let mylist = [
1170            'one',
1171            # comment
1172            'two', # empty line follows
1173
1174            'three',
1175            ]
1176      assert_equal(['one', 'two', 'three'], mylist)
1177  END
1178  CheckScriptSuccess(lines)
1179
1180  # check all lines from heredoc are kept
1181  lines =<< trim END
1182      # comment 1
1183      two
1184      # comment 3
1185
1186      five
1187      # comment 6
1188  END
1189  assert_equal(['# comment 1', 'two', '# comment 3', '', 'five', '# comment 6'], lines)
1190enddef
1191
1192if has('channel')
1193  let someJob = test_null_job()
1194
1195  def FuncWithError()
1196    echomsg g:someJob
1197  enddef
1198
1199  func Test_convert_emsg_to_exception()
1200    try
1201      call FuncWithError()
1202    catch
1203      call assert_match('Vim:E908:', v:exception)
1204    endtry
1205  endfunc
1206endif
1207
1208let s:export_script_lines =<< trim END
1209  vim9script
1210  let name: string = 'bob'
1211  def Concat(arg: string): string
1212    return name .. arg
1213  enddef
1214  g:result = Concat('bie')
1215  g:localname = name
1216
1217  export const CONST = 1234
1218  export let exported = 9876
1219  export let exp_name = 'John'
1220  export def Exported(): string
1221    return 'Exported'
1222  enddef
1223END
1224
1225def Undo_export_script_lines()
1226  unlet g:result
1227  unlet g:localname
1228enddef
1229
1230def Test_vim9_import_export()
1231  let import_script_lines =<< trim END
1232    vim9script
1233    import {exported, Exported} from './Xexport.vim'
1234    g:imported = exported
1235    exported += 3
1236    g:imported_added = exported
1237    g:imported_func = Exported()
1238
1239    def GetExported(): string
1240      let local_dict = #{ref: Exported}
1241      return local_dict.ref()
1242    enddef
1243    g:funcref_result = GetExported()
1244
1245    import {exp_name} from './Xexport.vim'
1246    g:imported_name = exp_name
1247    exp_name ..= ' Doe'
1248    g:imported_name_appended = exp_name
1249    g:imported_later = exported
1250  END
1251
1252  writefile(import_script_lines, 'Ximport.vim')
1253  writefile(s:export_script_lines, 'Xexport.vim')
1254
1255  source Ximport.vim
1256
1257  assert_equal('bobbie', g:result)
1258  assert_equal('bob', g:localname)
1259  assert_equal(9876, g:imported)
1260  assert_equal(9879, g:imported_added)
1261  assert_equal(9879, g:imported_later)
1262  assert_equal('Exported', g:imported_func)
1263  assert_equal('Exported', g:funcref_result)
1264  assert_equal('John', g:imported_name)
1265  assert_equal('John Doe', g:imported_name_appended)
1266  assert_false(exists('g:name'))
1267
1268  Undo_export_script_lines()
1269  unlet g:imported
1270  unlet g:imported_added
1271  unlet g:imported_later
1272  unlet g:imported_func
1273  unlet g:imported_name g:imported_name_appended
1274  delete('Ximport.vim')
1275
1276  # similar, with line breaks
1277  let import_line_break_script_lines =<< trim END
1278    vim9script
1279    import {
1280        exported,
1281        Exported,
1282        }
1283        from
1284        './Xexport.vim'
1285    g:imported = exported
1286    exported += 5
1287    g:imported_added = exported
1288    g:imported_func = Exported()
1289  END
1290  writefile(import_line_break_script_lines, 'Ximport_lbr.vim')
1291  source Ximport_lbr.vim
1292
1293  assert_equal(9876, g:imported)
1294  assert_equal(9881, g:imported_added)
1295  assert_equal('Exported', g:imported_func)
1296
1297  # exported script not sourced again
1298  assert_false(exists('g:result'))
1299  unlet g:imported
1300  unlet g:imported_added
1301  unlet g:imported_func
1302  delete('Ximport_lbr.vim')
1303
1304  # import inside :def function
1305  let import_in_def_lines =<< trim END
1306    vim9script
1307    def ImportInDef()
1308      import exported from './Xexport.vim'
1309      g:imported = exported
1310      exported += 7
1311      g:imported_added = exported
1312    enddef
1313    ImportInDef()
1314  END
1315  writefile(import_in_def_lines, 'Ximport2.vim')
1316  source Ximport2.vim
1317  # TODO: this should be 9879
1318  assert_equal(9876, g:imported)
1319  assert_equal(9883, g:imported_added)
1320  unlet g:imported
1321  unlet g:imported_added
1322  delete('Ximport2.vim')
1323
1324  let import_star_as_lines =<< trim END
1325    vim9script
1326    import * as Export from './Xexport.vim'
1327    def UseExport()
1328      g:imported = Export.exported
1329    enddef
1330    UseExport()
1331  END
1332  writefile(import_star_as_lines, 'Ximport.vim')
1333  source Ximport.vim
1334  assert_equal(9883, g:imported)
1335
1336  let import_star_as_lines_no_dot =<< trim END
1337    vim9script
1338    import * as Export from './Xexport.vim'
1339    def Func()
1340      let dummy = 1
1341      let imported = Export + dummy
1342    enddef
1343    defcompile
1344  END
1345  writefile(import_star_as_lines_no_dot, 'Ximport.vim')
1346  assert_fails('source Ximport.vim', 'E1060:')
1347
1348  let import_star_as_lines_dot_space =<< trim END
1349    vim9script
1350    import * as Export from './Xexport.vim'
1351    def Func()
1352      let imported = Export . exported
1353    enddef
1354    defcompile
1355  END
1356  writefile(import_star_as_lines_dot_space, 'Ximport.vim')
1357  assert_fails('source Ximport.vim', 'E1074:')
1358
1359  let import_star_as_lines_missing_name =<< trim END
1360    vim9script
1361    import * as Export from './Xexport.vim'
1362    def Func()
1363      let imported = Export.
1364    enddef
1365    defcompile
1366  END
1367  writefile(import_star_as_lines_missing_name, 'Ximport.vim')
1368  assert_fails('source Ximport.vim', 'E1048:')
1369
1370  let import_star_as_lbr_lines =<< trim END
1371    vim9script
1372    import *
1373        as Export
1374        from
1375        './Xexport.vim'
1376    def UseExport()
1377      g:imported = Export.exported
1378    enddef
1379    UseExport()
1380  END
1381  writefile(import_star_as_lbr_lines, 'Ximport.vim')
1382  source Ximport.vim
1383  assert_equal(9883, g:imported)
1384
1385  let import_star_lines =<< trim END
1386    vim9script
1387    import * from './Xexport.vim'
1388  END
1389  writefile(import_star_lines, 'Ximport.vim')
1390  assert_fails('source Ximport.vim', 'E1045:')
1391
1392  # try to import something that exists but is not exported
1393  let import_not_exported_lines =<< trim END
1394    vim9script
1395    import name from './Xexport.vim'
1396  END
1397  writefile(import_not_exported_lines, 'Ximport.vim')
1398  assert_fails('source Ximport.vim', 'E1049:')
1399
1400  # try to import something that is already defined
1401  let import_already_defined =<< trim END
1402    vim9script
1403    let exported = 'something'
1404    import exported from './Xexport.vim'
1405  END
1406  writefile(import_already_defined, 'Ximport.vim')
1407  assert_fails('source Ximport.vim', 'E1073:')
1408
1409  # try to import something that is already defined
1410  import_already_defined =<< trim END
1411    vim9script
1412    let exported = 'something'
1413    import * as exported from './Xexport.vim'
1414  END
1415  writefile(import_already_defined, 'Ximport.vim')
1416  assert_fails('source Ximport.vim', 'E1073:')
1417
1418  # try to import something that is already defined
1419  import_already_defined =<< trim END
1420    vim9script
1421    let exported = 'something'
1422    import {exported} from './Xexport.vim'
1423  END
1424  writefile(import_already_defined, 'Ximport.vim')
1425  assert_fails('source Ximport.vim', 'E1073:')
1426
1427  # import a very long name, requires making a copy
1428  let import_long_name_lines =<< trim END
1429    vim9script
1430    import name012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 from './Xexport.vim'
1431  END
1432  writefile(import_long_name_lines, 'Ximport.vim')
1433  assert_fails('source Ximport.vim', 'E1048:')
1434
1435  let import_no_from_lines =<< trim END
1436    vim9script
1437    import name './Xexport.vim'
1438  END
1439  writefile(import_no_from_lines, 'Ximport.vim')
1440  assert_fails('source Ximport.vim', 'E1070:')
1441
1442  let import_invalid_string_lines =<< trim END
1443    vim9script
1444    import name from Xexport.vim
1445  END
1446  writefile(import_invalid_string_lines, 'Ximport.vim')
1447  assert_fails('source Ximport.vim', 'E1071:')
1448
1449  let import_wrong_name_lines =<< trim END
1450    vim9script
1451    import name from './XnoExport.vim'
1452  END
1453  writefile(import_wrong_name_lines, 'Ximport.vim')
1454  assert_fails('source Ximport.vim', 'E1053:')
1455
1456  let import_missing_comma_lines =<< trim END
1457    vim9script
1458    import {exported name} from './Xexport.vim'
1459  END
1460  writefile(import_missing_comma_lines, 'Ximport3.vim')
1461  assert_fails('source Ximport3.vim', 'E1046:')
1462
1463  delete('Ximport.vim')
1464  delete('Ximport3.vim')
1465  delete('Xexport.vim')
1466
1467  # Check that in a Vim9 script 'cpo' is set to the Vim default.
1468  set cpo&vi
1469  let cpo_before = &cpo
1470  let lines =<< trim END
1471    vim9script
1472    g:cpo_in_vim9script = &cpo
1473  END
1474  writefile(lines, 'Xvim9_script')
1475  source Xvim9_script
1476  assert_equal(cpo_before, &cpo)
1477  set cpo&vim
1478  assert_equal(&cpo, g:cpo_in_vim9script)
1479  delete('Xvim9_script')
1480enddef
1481
1482func g:Trigger()
1483  source Ximport.vim
1484  return "echo 'yes'\<CR>"
1485endfunc
1486
1487def Test_import_export_expr_map()
1488  # check that :import and :export work when buffer is locked
1489  let export_lines =<< trim END
1490    vim9script
1491    export def That(): string
1492      return 'yes'
1493    enddef
1494  END
1495  writefile(export_lines, 'Xexport_that.vim')
1496
1497  let import_lines =<< trim END
1498    vim9script
1499    import That from './Xexport_that.vim'
1500    assert_equal('yes', That())
1501  END
1502  writefile(import_lines, 'Ximport.vim')
1503
1504  nnoremap <expr> trigger g:Trigger()
1505  feedkeys('trigger', "xt")
1506
1507  delete('Xexport_that.vim')
1508  delete('Ximport.vim')
1509  nunmap trigger
1510enddef
1511
1512def Test_import_in_filetype()
1513  # check that :import works when the buffer is locked
1514  mkdir('ftplugin', 'p')
1515  let export_lines =<< trim END
1516    vim9script
1517    export let That = 'yes'
1518  END
1519  writefile(export_lines, 'ftplugin/Xexport_ft.vim')
1520
1521  let import_lines =<< trim END
1522    vim9script
1523    import That from './Xexport_ft.vim'
1524    assert_equal('yes', That)
1525    g:did_load_mytpe = 1
1526  END
1527  writefile(import_lines, 'ftplugin/qf.vim')
1528
1529  let save_rtp = &rtp
1530  &rtp = getcwd() .. ',' .. &rtp
1531
1532  filetype plugin on
1533  copen
1534  assert_equal(1, g:did_load_mytpe)
1535
1536  quit!
1537  delete('Xexport_ft.vim')
1538  delete('ftplugin', 'rf')
1539  &rtp = save_rtp
1540enddef
1541
1542def Test_use_import_in_mapping()
1543  let lines =<< trim END
1544      vim9script
1545      export def Funcx()
1546        g:result = 42
1547      enddef
1548  END
1549  writefile(lines, 'XsomeExport.vim')
1550  lines =<< trim END
1551      vim9script
1552      import Funcx from './XsomeExport.vim'
1553      nnoremap <F3> :call <sid>Funcx()<cr>
1554  END
1555  writefile(lines, 'Xmapscript.vim')
1556
1557  source Xmapscript.vim
1558  feedkeys("\<F3>", "xt")
1559  assert_equal(42, g:result)
1560
1561  unlet g:result
1562  delete('XsomeExport.vim')
1563  delete('Xmapscript.vim')
1564  nunmap <F3>
1565enddef
1566
1567def Test_vim9script_fails()
1568  CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
1569  CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
1570  CheckScriptFailure(['export let some = 123'], 'E1042:')
1571  CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1048:')
1572  CheckScriptFailure(['vim9script', 'export let g:some'], 'E1022:')
1573  CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
1574
1575  CheckScriptFailure(['vim9script', 'let str: string', 'str = 1234'], 'E1012:')
1576  CheckScriptFailure(['vim9script', 'const str = "asdf"', 'str = "xxx"'], 'E46:')
1577
1578  assert_fails('vim9script', 'E1038')
1579  assert_fails('export something', 'E1043')
1580enddef
1581
1582func Test_import_fails_without_script()
1583  CheckRunVimInTerminal
1584
1585  " call indirectly to avoid compilation error for missing functions
1586  call Run_Test_import_fails_on_command_line()
1587endfunc
1588
1589def Run_Test_import_fails_on_command_line()
1590  let export =<< trim END
1591    vim9script
1592    export def Foo(): number
1593        return 0
1594    enddef
1595  END
1596  writefile(export, 'XexportCmd.vim')
1597
1598  let buf = RunVimInTerminal('-c "import Foo from ''./XexportCmd.vim''"', #{
1599                rows: 6, wait_for_ruler: 0})
1600  WaitForAssert({-> assert_match('^E1094:', term_getline(buf, 5))})
1601
1602  delete('XexportCmd.vim')
1603  StopVimInTerminal(buf)
1604enddef
1605
1606def Test_vim9script_reload_import()
1607  let lines =<< trim END
1608    vim9script
1609    const var = ''
1610    let valone = 1234
1611    def MyFunc(arg: string)
1612       valone = 5678
1613    enddef
1614  END
1615  let morelines =<< trim END
1616    let valtwo = 222
1617    export def GetValtwo(): number
1618      return valtwo
1619    enddef
1620  END
1621  writefile(lines + morelines, 'Xreload.vim')
1622  source Xreload.vim
1623  source Xreload.vim
1624  source Xreload.vim
1625
1626  let testlines =<< trim END
1627    vim9script
1628    def TheFunc()
1629      import GetValtwo from './Xreload.vim'
1630      assert_equal(222, GetValtwo())
1631    enddef
1632    TheFunc()
1633  END
1634  writefile(testlines, 'Ximport.vim')
1635  source Ximport.vim
1636
1637  # Test that when not using "morelines" GetValtwo() and valtwo are still
1638  # defined, because import doesn't reload a script.
1639  writefile(lines, 'Xreload.vim')
1640  source Ximport.vim
1641
1642  # cannot declare a var twice
1643  lines =<< trim END
1644    vim9script
1645    let valone = 1234
1646    let valone = 5678
1647  END
1648  writefile(lines, 'Xreload.vim')
1649  assert_fails('source Xreload.vim', 'E1041:')
1650
1651  delete('Xreload.vim')
1652  delete('Ximport.vim')
1653enddef
1654
1655" Not exported function that is referenced needs to be accessed by the
1656" script-local name.
1657def Test_vim9script_funcref()
1658  let sortlines =<< trim END
1659      vim9script
1660      def Compare(i1: number, i2: number): number
1661        return i2 - i1
1662      enddef
1663
1664      export def FastSort(): list<number>
1665        return range(5)->sort(Compare)
1666      enddef
1667  END
1668  writefile(sortlines, 'Xsort.vim')
1669
1670  let lines =<< trim END
1671    vim9script
1672    import FastSort from './Xsort.vim'
1673    def Test()
1674      g:result = FastSort()
1675    enddef
1676    Test()
1677  END
1678  writefile(lines, 'Xscript.vim')
1679
1680  source Xscript.vim
1681  assert_equal([4, 3, 2, 1, 0], g:result)
1682
1683  unlet g:result
1684  delete('Xsort.vim')
1685  delete('Xscript.vim')
1686enddef
1687
1688" Check that when searching for "FilterFunc" it finds the import in the
1689" script where FastFilter() is called from, both as a string and as a direct
1690" function reference.
1691def Test_vim9script_funcref_other_script()
1692  let filterLines =<< trim END
1693    vim9script
1694    export def FilterFunc(idx: number, val: number): bool
1695      return idx % 2 == 1
1696    enddef
1697    export def FastFilter(): list<number>
1698      return range(10)->filter('FilterFunc')
1699    enddef
1700    export def FastFilterDirect(): list<number>
1701      return range(10)->filter(FilterFunc)
1702    enddef
1703  END
1704  writefile(filterLines, 'Xfilter.vim')
1705
1706  let lines =<< trim END
1707    vim9script
1708    import {FilterFunc, FastFilter, FastFilterDirect} from './Xfilter.vim'
1709    def Test()
1710      let x: list<number> = FastFilter()
1711    enddef
1712    Test()
1713    def TestDirect()
1714      let x: list<number> = FastFilterDirect()
1715    enddef
1716    TestDirect()
1717  END
1718  CheckScriptSuccess(lines)
1719  delete('Xfilter.vim')
1720enddef
1721
1722def Test_vim9script_reload_delfunc()
1723  let first_lines =<< trim END
1724    vim9script
1725    def FuncYes(): string
1726      return 'yes'
1727    enddef
1728  END
1729  let withno_lines =<< trim END
1730    def FuncNo(): string
1731      return 'no'
1732    enddef
1733    def g:DoCheck(no_exists: bool)
1734      assert_equal('yes', FuncYes())
1735      assert_equal('no', FuncNo())
1736    enddef
1737  END
1738  let nono_lines =<< trim END
1739    def g:DoCheck(no_exists: bool)
1740      assert_equal('yes', FuncYes())
1741      assert_fails('call FuncNo()', 'E117:')
1742    enddef
1743  END
1744
1745  # FuncNo() is defined
1746  writefile(first_lines + withno_lines, 'Xreloaded.vim')
1747  source Xreloaded.vim
1748  g:DoCheck(true)
1749
1750  # FuncNo() is not redefined
1751  writefile(first_lines + nono_lines, 'Xreloaded.vim')
1752  source Xreloaded.vim
1753  g:DoCheck()
1754
1755  # FuncNo() is back
1756  writefile(first_lines + withno_lines, 'Xreloaded.vim')
1757  source Xreloaded.vim
1758  g:DoCheck()
1759
1760  delete('Xreloaded.vim')
1761enddef
1762
1763def Test_vim9script_reload_delvar()
1764  # write the script with a script-local variable
1765  let lines =<< trim END
1766    vim9script
1767    let var = 'string'
1768  END
1769  writefile(lines, 'XreloadVar.vim')
1770  source XreloadVar.vim
1771
1772  # now write the script using the same variable locally - works
1773  lines =<< trim END
1774    vim9script
1775    def Func()
1776      let var = 'string'
1777    enddef
1778  END
1779  writefile(lines, 'XreloadVar.vim')
1780  source XreloadVar.vim
1781
1782  delete('XreloadVar.vim')
1783enddef
1784
1785def Test_import_absolute()
1786  let import_lines = [
1787        'vim9script',
1788        'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
1789        'def UseExported()',
1790        '  g:imported_abs = exported',
1791        '  exported = 8888',
1792        '  g:imported_after = exported',
1793        'enddef',
1794        'UseExported()',
1795        'g:import_disassembled = execute("disass UseExported")',
1796        ]
1797  writefile(import_lines, 'Ximport_abs.vim')
1798  writefile(s:export_script_lines, 'Xexport_abs.vim')
1799
1800  source Ximport_abs.vim
1801
1802  assert_equal(9876, g:imported_abs)
1803  assert_equal(8888, g:imported_after)
1804  assert_match('<SNR>\d\+_UseExported.*' ..
1805          'g:imported_abs = exported.*' ..
1806          '0 LOADSCRIPT exported from .*Xexport_abs.vim.*' ..
1807          '1 STOREG g:imported_abs.*' ..
1808          'exported = 8888.*' ..
1809          '3 STORESCRIPT exported in .*Xexport_abs.vim.*' ..
1810          'g:imported_after = exported.*' ..
1811          '4 LOADSCRIPT exported from .*Xexport_abs.vim.*' ..
1812          '5 STOREG g:imported_after.*',
1813        g:import_disassembled)
1814
1815  Undo_export_script_lines()
1816  unlet g:imported_abs
1817  unlet g:import_disassembled
1818
1819  delete('Ximport_abs.vim')
1820  delete('Xexport_abs.vim')
1821enddef
1822
1823def Test_import_rtp()
1824  let import_lines = [
1825        'vim9script',
1826        'import exported from "Xexport_rtp.vim"',
1827        'g:imported_rtp = exported',
1828        ]
1829  writefile(import_lines, 'Ximport_rtp.vim')
1830  mkdir('import')
1831  writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
1832
1833  let save_rtp = &rtp
1834  &rtp = getcwd()
1835  source Ximport_rtp.vim
1836  &rtp = save_rtp
1837
1838  assert_equal(9876, g:imported_rtp)
1839
1840  Undo_export_script_lines()
1841  unlet g:imported_rtp
1842  delete('Ximport_rtp.vim')
1843  delete('import', 'rf')
1844enddef
1845
1846def Test_import_compile_error()
1847  let export_lines = [
1848        'vim9script',
1849        'export def ExpFunc(): string',
1850        '  return notDefined',
1851        'enddef',
1852        ]
1853  writefile(export_lines, 'Xexported.vim')
1854
1855  let import_lines = [
1856        'vim9script',
1857        'import ExpFunc from "./Xexported.vim"',
1858        'def ImpFunc()',
1859        '  echo ExpFunc()',
1860        'enddef',
1861        'defcompile',
1862        ]
1863  writefile(import_lines, 'Ximport.vim')
1864
1865  try
1866    source Ximport.vim
1867  catch /E1001/
1868    # Error should be fore the Xexported.vim file.
1869    assert_match('E1001: variable not found: notDefined', v:exception)
1870    assert_match('function <SNR>\d\+_ImpFunc\[1\]..<SNR>\d\+_ExpFunc, line 1', v:throwpoint)
1871  endtry
1872
1873  delete('Xexported.vim')
1874  delete('Ximport.vim')
1875enddef
1876
1877def Test_func_redefine_error()
1878  let lines = [
1879        'vim9script',
1880        'def Func()',
1881        '  eval [][0]',
1882        'enddef',
1883        'Func()',
1884        ]
1885  writefile(lines, 'Xtestscript.vim')
1886
1887  for count in range(3)
1888    try
1889      source Xtestscript.vim
1890    catch /E684/
1891      # function name should contain <SNR> every time
1892      assert_match('E684: list index out of range', v:exception)
1893      assert_match('function <SNR>\d\+_Func, line 1', v:throwpoint)
1894    endtry
1895  endfor
1896
1897  delete('Xtestscript.vim')
1898enddef
1899
1900def Test_func_overrules_import_fails()
1901  let export_lines =<< trim END
1902      vim9script
1903      export def Func()
1904        echo 'imported'
1905      enddef
1906  END
1907  writefile(export_lines, 'XexportedFunc.vim')
1908
1909  let lines =<< trim END
1910    vim9script
1911    import Func from './XexportedFunc.vim'
1912    def Func()
1913      echo 'local to function'
1914    enddef
1915  END
1916  CheckScriptFailure(lines, 'E1073:')
1917
1918  lines =<< trim END
1919    vim9script
1920    import Func from './XexportedFunc.vim'
1921    def Outer()
1922      def Func()
1923        echo 'local to function'
1924      enddef
1925    enddef
1926    defcompile
1927  END
1928  CheckScriptFailure(lines, 'E1073:')
1929
1930  delete('XexportedFunc.vim')
1931enddef
1932
1933def Test_func_redefine_fails()
1934  let lines =<< trim END
1935    vim9script
1936    def Func()
1937      echo 'one'
1938    enddef
1939    def Func()
1940      echo 'two'
1941    enddef
1942  END
1943  CheckScriptFailure(lines, 'E1073:')
1944
1945  lines =<< trim END
1946    vim9script
1947    def Foo(): string
1948      return 'foo'
1949      enddef
1950    def Func()
1951      let  Foo = {-> 'lambda'}
1952    enddef
1953    defcompile
1954  END
1955  CheckScriptFailure(lines, 'E1073:')
1956enddef
1957
1958def Test_fixed_size_list()
1959  # will be allocated as one piece of memory, check that changes work
1960  let l = [1, 2, 3, 4]
1961  l->remove(0)
1962  l->add(5)
1963  l->insert(99, 1)
1964  assert_equal([2, 99, 3, 4, 5], l)
1965enddef
1966
1967def Test_no_insert_xit()
1968  call CheckDefExecFailure(['a = 1'], 'E1100:')
1969  call CheckDefExecFailure(['c = 1'], 'E1100:')
1970  call CheckDefExecFailure(['i = 1'], 'E1100:')
1971  call CheckDefExecFailure(['t = 1'], 'E1100:')
1972  call CheckDefExecFailure(['x = 1'], 'E1100:')
1973
1974  CheckScriptFailure(['vim9script', 'a = 1'], 'E488:')
1975  CheckScriptFailure(['vim9script', 'a'], 'E1100:')
1976  CheckScriptFailure(['vim9script', 'c = 1'], 'E488:')
1977  CheckScriptFailure(['vim9script', 'c'], 'E1100:')
1978  CheckScriptFailure(['vim9script', 'i = 1'], 'E488:')
1979  CheckScriptFailure(['vim9script', 'i'], 'E1100:')
1980  CheckScriptFailure(['vim9script', 't'], 'E1100:')
1981  CheckScriptFailure(['vim9script', 't = 1'], 'E1100:')
1982  CheckScriptFailure(['vim9script', 'x = 1'], 'E1100:')
1983enddef
1984
1985def IfElse(what: number): string
1986  let res = ''
1987  if what == 1
1988    res = "one"
1989  elseif what == 2
1990    res = "two"
1991  else
1992    res = "three"
1993  endif
1994  return res
1995enddef
1996
1997def Test_if_elseif_else()
1998  assert_equal('one', IfElse(1))
1999  assert_equal('two', IfElse(2))
2000  assert_equal('three', IfElse(3))
2001enddef
2002
2003def Test_if_elseif_else_fails()
2004  call CheckDefFailure(['elseif true'], 'E582:')
2005  call CheckDefFailure(['else'], 'E581:')
2006  call CheckDefFailure(['endif'], 'E580:')
2007  call CheckDefFailure(['if true', 'elseif xxx'], 'E1001:')
2008  call CheckDefFailure(['if true', 'echo 1'], 'E171:')
2009enddef
2010
2011let g:bool_true = v:true
2012let g:bool_false = v:false
2013
2014def Test_if_const_expr()
2015  let res = false
2016  if true ? true : false
2017    res = true
2018  endif
2019  assert_equal(true, res)
2020
2021  g:glob = 2
2022  if false
2023    execute('g:glob = 3')
2024  endif
2025  assert_equal(2, g:glob)
2026  if true
2027    execute('g:glob = 3')
2028  endif
2029  assert_equal(3, g:glob)
2030
2031  res = false
2032  if g:bool_true ? true : false
2033    res = true
2034  endif
2035  assert_equal(true, res)
2036
2037  res = false
2038  if true ? g:bool_true : false
2039    res = true
2040  endif
2041  assert_equal(true, res)
2042
2043  res = false
2044  if true ? true : g:bool_false
2045    res = true
2046  endif
2047  assert_equal(true, res)
2048
2049  res = false
2050  if true ? false : true
2051    res = true
2052  endif
2053  assert_equal(false, res)
2054
2055  res = false
2056  if false ? false : true
2057    res = true
2058  endif
2059  assert_equal(true, res)
2060
2061  res = false
2062  if false ? true : false
2063    res = true
2064  endif
2065  assert_equal(false, res)
2066
2067  res = false
2068  if has('xyz') ? true : false
2069    res = true
2070  endif
2071  assert_equal(false, res)
2072
2073  res = false
2074  if true && true
2075    res = true
2076  endif
2077  assert_equal(true, res)
2078
2079  res = false
2080  if true && false
2081    res = true
2082  endif
2083  assert_equal(false, res)
2084
2085  res = false
2086  if g:bool_true && false
2087    res = true
2088  endif
2089  assert_equal(false, res)
2090
2091  res = false
2092  if true && g:bool_false
2093    res = true
2094  endif
2095  assert_equal(false, res)
2096
2097  res = false
2098  if false && false
2099    res = true
2100  endif
2101  assert_equal(false, res)
2102
2103  res = false
2104  if true || false
2105    res = true
2106  endif
2107  assert_equal(true, res)
2108
2109  res = false
2110  if g:bool_true || false
2111    res = true
2112  endif
2113  assert_equal(true, res)
2114
2115  res = false
2116  if true || g:bool_false
2117    res = true
2118  endif
2119  assert_equal(true, res)
2120
2121  res = false
2122  if false || false
2123    res = true
2124  endif
2125  assert_equal(false, res)
2126
2127  # with constant "false" expression may be invalid so long as the syntax is OK
2128  if false | eval 0 | endif
2129  if false | eval burp + 234 | endif
2130  if false | echo burp 234 'asd' | endif
2131  if false
2132    burp
2133  endif
2134enddef
2135
2136def Test_if_const_expr_fails()
2137  call CheckDefFailure(['if "aaa" == "bbb'], 'E114:')
2138  call CheckDefFailure(["if 'aaa' == 'bbb"], 'E115:')
2139  call CheckDefFailure(["if has('aaa'"], 'E110:')
2140  call CheckDefFailure(["if has('aaa') ? true false"], 'E109:')
2141enddef
2142
2143def RunNested(i: number): number
2144  let x: number = 0
2145  if i % 2
2146    if 1
2147      # comment
2148    else
2149      # comment
2150    endif
2151    x += 1
2152  else
2153    x += 1000
2154  endif
2155  return x
2156enddef
2157
2158def Test_nested_if()
2159  assert_equal(1, RunNested(1))
2160  assert_equal(1000, RunNested(2))
2161enddef
2162
2163def Test_execute_cmd()
2164  new
2165  setline(1, 'default')
2166  execute 'call setline(1, "execute-string")'
2167  assert_equal('execute-string', getline(1))
2168
2169  execute "call setline(1, 'execute-string')"
2170  assert_equal('execute-string', getline(1))
2171
2172  let cmd1 = 'call setline(1,'
2173  let cmd2 = '"execute-var")'
2174  execute cmd1 cmd2 # comment
2175  assert_equal('execute-var', getline(1))
2176
2177  execute cmd1 cmd2 '|call setline(1, "execute-var-string")'
2178  assert_equal('execute-var-string', getline(1))
2179
2180  let cmd_first = 'call '
2181  let cmd_last = 'setline(1, "execute-var-var")'
2182  execute cmd_first .. cmd_last
2183  assert_equal('execute-var-var', getline(1))
2184  bwipe!
2185
2186  let n = true
2187  execute 'echomsg' (n ? '"true"' : '"no"')
2188  assert_match('^true$', Screenline(&lines))
2189
2190  echomsg [1, 2, 3] #{a: 1, b: 2}
2191  assert_match('^\[1, 2, 3\] {''a'': 1, ''b'': 2}$', Screenline(&lines))
2192
2193  call CheckDefFailure(['execute xxx'], 'E1001:', 1)
2194  call CheckDefExecFailure(['execute "tabnext " .. 8'], 'E475:', 1)
2195  call CheckDefFailure(['execute "cmd"# comment'], 'E488:', 1)
2196enddef
2197
2198def Test_execute_cmd_vimscript()
2199  # only checks line continuation
2200  let lines =<< trim END
2201      vim9script
2202      execute 'g:someVar'
2203                .. ' = ' ..
2204                   '28'
2205      assert_equal(28, g:someVar)
2206      unlet g:someVar
2207  END
2208  CheckScriptSuccess(lines)
2209enddef
2210
2211def Test_echo_cmd()
2212  echo 'some' # comment
2213  echon 'thing'
2214  assert_match('^something$', Screenline(&lines))
2215
2216  echo "some" # comment
2217  echon "thing"
2218  assert_match('^something$', Screenline(&lines))
2219
2220  let str1 = 'some'
2221  let str2 = 'more'
2222  echo str1 str2
2223  assert_match('^some more$', Screenline(&lines))
2224
2225  call CheckDefFailure(['echo "xxx"# comment'], 'E488:')
2226enddef
2227
2228def Test_echomsg_cmd()
2229  echomsg 'some' 'more' # comment
2230  assert_match('^some more$', Screenline(&lines))
2231  echo 'clear'
2232  :1messages
2233  assert_match('^some more$', Screenline(&lines))
2234
2235  call CheckDefFailure(['echomsg "xxx"# comment'], 'E488:')
2236enddef
2237
2238def Test_echomsg_cmd_vimscript()
2239  # only checks line continuation
2240  let lines =<< trim END
2241      vim9script
2242      echomsg 'here'
2243                .. ' is ' ..
2244                   'a message'
2245      assert_match('^here is a message$', Screenline(&lines))
2246  END
2247  CheckScriptSuccess(lines)
2248enddef
2249
2250def Test_echoerr_cmd()
2251  try
2252    echoerr 'something' 'wrong' # comment
2253  catch
2254    assert_match('something wrong', v:exception)
2255  endtry
2256enddef
2257
2258def Test_echoerr_cmd_vimscript()
2259  # only checks line continuation
2260  let lines =<< trim END
2261      vim9script
2262      try
2263        echoerr 'this'
2264                .. ' is ' ..
2265                   'wrong'
2266      catch
2267        assert_match('this is wrong', v:exception)
2268      endtry
2269  END
2270  CheckScriptSuccess(lines)
2271enddef
2272
2273def Test_for_outside_of_function()
2274  let lines =<< trim END
2275    vim9script
2276    new
2277    for var in range(0, 3)
2278      append(line('$'), var)
2279    endfor
2280    assert_equal(['', '0', '1', '2', '3'], getline(1, '$'))
2281    bwipe!
2282  END
2283  writefile(lines, 'Xvim9for.vim')
2284  source Xvim9for.vim
2285  delete('Xvim9for.vim')
2286enddef
2287
2288def Test_for_loop()
2289  let result = ''
2290  for cnt in range(7)
2291    if cnt == 4
2292      break
2293    endif
2294    if cnt == 2
2295      continue
2296    endif
2297    result ..= cnt .. '_'
2298  endfor
2299  assert_equal('0_1_3_', result)
2300
2301  let concat = ''
2302  for str in eval('["one", "two"]')
2303    concat ..= str
2304  endfor
2305  assert_equal('onetwo', concat)
2306enddef
2307
2308def Test_for_loop_fails()
2309  CheckDefFailure(['for # in range(5)'], 'E690:')
2310  CheckDefFailure(['for i In range(5)'], 'E690:')
2311  CheckDefFailure(['let x = 5', 'for x in range(5)'], 'E1017:')
2312  CheckScriptFailure(['def Func(arg: any)', 'for arg in range(5)', 'enddef', 'defcompile'], 'E1006:')
2313  CheckDefFailure(['for i in "text"'], 'E1012:')
2314  CheckDefFailure(['for i in xxx'], 'E1001:')
2315  CheckDefFailure(['endfor'], 'E588:')
2316  CheckDefFailure(['for i in range(3)', 'echo 3'], 'E170:')
2317enddef
2318
2319def Test_while_loop()
2320  let result = ''
2321  let cnt = 0
2322  while cnt < 555
2323    if cnt == 3
2324      break
2325    endif
2326    cnt += 1
2327    if cnt == 2
2328      continue
2329    endif
2330    result ..= cnt .. '_'
2331  endwhile
2332  assert_equal('1_3_', result)
2333enddef
2334
2335def Test_while_loop_fails()
2336  CheckDefFailure(['while xxx'], 'E1001:')
2337  CheckDefFailure(['endwhile'], 'E588:')
2338  CheckDefFailure(['continue'], 'E586:')
2339  CheckDefFailure(['if true', 'continue'], 'E586:')
2340  CheckDefFailure(['break'], 'E587:')
2341  CheckDefFailure(['if true', 'break'], 'E587:')
2342  CheckDefFailure(['while 1', 'echo 3'], 'E170:')
2343enddef
2344
2345def Test_interrupt_loop()
2346  let caught = false
2347  let x = 0
2348  try
2349    while 1
2350      x += 1
2351      if x == 100
2352        feedkeys("\<C-C>", 'Lt')
2353      endif
2354    endwhile
2355  catch
2356    caught = true
2357    assert_equal(100, x)
2358  endtry
2359  assert_true(caught, 'should have caught an exception')
2360enddef
2361
2362def Test_automatic_line_continuation()
2363  let mylist = [
2364      'one',
2365      'two',
2366      'three',
2367      ] # comment
2368  assert_equal(['one', 'two', 'three'], mylist)
2369
2370  let mydict = {
2371      'one': 1,
2372      'two': 2,
2373      'three':
2374          3,
2375      } # comment
2376  assert_equal({'one': 1, 'two': 2, 'three': 3}, mydict)
2377  mydict = #{
2378      one: 1,  # comment
2379      two:     # comment
2380           2,  # comment
2381      three: 3 # comment
2382      }
2383  assert_equal(#{one: 1, two: 2, three: 3}, mydict)
2384  mydict = #{
2385      one: 1,
2386      two:
2387           2,
2388      three: 3
2389      }
2390  assert_equal(#{one: 1, two: 2, three: 3}, mydict)
2391
2392  assert_equal(
2393        ['one', 'two', 'three'],
2394        split('one two three')
2395        )
2396enddef
2397
2398def Test_vim9_comment()
2399  CheckScriptSuccess([
2400      'vim9script',
2401      '# something',
2402      ])
2403  CheckScriptFailure([
2404      'vim9script',
2405      ':# something',
2406      ], 'E488:')
2407  CheckScriptFailure([
2408      '# something',
2409      ], 'E488:')
2410  CheckScriptFailure([
2411      ':# something',
2412      ], 'E488:')
2413
2414  { # block start
2415  } # block end
2416  CheckDefFailure([
2417      '{# comment',
2418      ], 'E488:')
2419  CheckDefFailure([
2420      '{',
2421      '}# comment',
2422      ], 'E488:')
2423
2424  echo "yes" # comment
2425  CheckDefFailure([
2426      'echo "yes"# comment',
2427      ], 'E488:')
2428  CheckScriptSuccess([
2429      'vim9script',
2430      'echo "yes" # something',
2431      ])
2432  CheckScriptFailure([
2433      'vim9script',
2434      'echo "yes"# something',
2435      ], 'E121:')
2436  CheckScriptFailure([
2437      'vim9script',
2438      'echo# something',
2439      ], 'E121:')
2440  CheckScriptFailure([
2441      'echo "yes" # something',
2442      ], 'E121:')
2443
2444  exe "echo" # comment
2445  CheckDefFailure([
2446      'exe "echo"# comment',
2447      ], 'E488:')
2448  CheckScriptSuccess([
2449      'vim9script',
2450      'exe "echo" # something',
2451      ])
2452  CheckScriptFailure([
2453      'vim9script',
2454      'exe "echo"# something',
2455      ], 'E121:')
2456  CheckDefFailure([
2457      'exe # comment',
2458      ], 'E1015:')
2459  CheckScriptFailure([
2460      'vim9script',
2461      'exe# something',
2462      ], 'E121:')
2463  CheckScriptFailure([
2464      'exe "echo" # something',
2465      ], 'E121:')
2466
2467  CheckDefFailure([
2468      'try# comment',
2469      '  echo "yes"',
2470      'catch',
2471      'endtry',
2472      ], 'E488:')
2473  CheckScriptFailure([
2474      'vim9script',
2475      'try# comment',
2476      'echo "yes"',
2477      ], 'E488:')
2478  CheckDefFailure([
2479      'try',
2480      '  throw#comment',
2481      'catch',
2482      'endtry',
2483      ], 'E1015:')
2484  CheckDefFailure([
2485      'try',
2486      '  throw "yes"#comment',
2487      'catch',
2488      'endtry',
2489      ], 'E488:')
2490  CheckDefFailure([
2491      'try',
2492      '  echo "yes"',
2493      'catch# comment',
2494      'endtry',
2495      ], 'E488:')
2496  CheckScriptFailure([
2497      'vim9script',
2498      'try',
2499      '  echo "yes"',
2500      'catch# comment',
2501      'endtry',
2502      ], 'E654:')
2503  CheckDefFailure([
2504      'try',
2505      '  echo "yes"',
2506      'catch /pat/# comment',
2507      'endtry',
2508      ], 'E488:')
2509  CheckDefFailure([
2510      'try',
2511      'echo "yes"',
2512      'catch',
2513      'endtry# comment',
2514      ], 'E488:')
2515  CheckScriptFailure([
2516      'vim9script',
2517      'try',
2518      '  echo "yes"',
2519      'catch',
2520      'endtry# comment',
2521      ], 'E488:')
2522
2523  CheckScriptSuccess([
2524      'vim9script',
2525      'hi # comment',
2526      ])
2527  CheckScriptFailure([
2528      'vim9script',
2529      'hi# comment',
2530      ], 'E416:')
2531  CheckScriptSuccess([
2532      'vim9script',
2533      'hi Search # comment',
2534      ])
2535  CheckScriptFailure([
2536      'vim9script',
2537      'hi Search# comment',
2538      ], 'E416:')
2539  CheckScriptSuccess([
2540      'vim9script',
2541      'hi link This Search # comment',
2542      ])
2543  CheckScriptFailure([
2544      'vim9script',
2545      'hi link This That# comment',
2546      ], 'E413:')
2547  CheckScriptSuccess([
2548      'vim9script',
2549      'hi clear This # comment',
2550      'hi clear # comment',
2551      ])
2552  # not tested, because it doesn't give an error but a warning:
2553  # hi clear This# comment',
2554  CheckScriptFailure([
2555      'vim9script',
2556      'hi clear# comment',
2557      ], 'E416:')
2558
2559  CheckScriptSuccess([
2560      'vim9script',
2561      'hi Group term=bold',
2562      'match Group /todo/ # comment',
2563      ])
2564  CheckScriptFailure([
2565      'vim9script',
2566      'hi Group term=bold',
2567      'match Group /todo/# comment',
2568      ], 'E488:')
2569  CheckScriptSuccess([
2570      'vim9script',
2571      'match # comment',
2572      ])
2573  CheckScriptFailure([
2574      'vim9script',
2575      'match# comment',
2576      ], 'E475:')
2577  CheckScriptSuccess([
2578      'vim9script',
2579      'match none # comment',
2580      ])
2581  CheckScriptFailure([
2582      'vim9script',
2583      'match none# comment',
2584      ], 'E475:')
2585
2586  CheckScriptSuccess([
2587      'vim9script',
2588      'menutrans clear # comment',
2589      ])
2590  CheckScriptFailure([
2591      'vim9script',
2592      'menutrans clear# comment text',
2593      ], 'E474:')
2594
2595  CheckScriptSuccess([
2596      'vim9script',
2597      'syntax clear # comment',
2598      ])
2599  CheckScriptFailure([
2600      'vim9script',
2601      'syntax clear# comment text',
2602      ], 'E28:')
2603  CheckScriptSuccess([
2604      'vim9script',
2605      'syntax keyword Word some',
2606      'syntax clear Word # comment',
2607      ])
2608  CheckScriptFailure([
2609      'vim9script',
2610      'syntax keyword Word some',
2611      'syntax clear Word# comment text',
2612      ], 'E28:')
2613
2614  CheckScriptSuccess([
2615      'vim9script',
2616      'syntax list # comment',
2617      ])
2618  CheckScriptFailure([
2619      'vim9script',
2620      'syntax list# comment text',
2621      ], 'E28:')
2622
2623  CheckScriptSuccess([
2624      'vim9script',
2625      'syntax match Word /pat/ oneline # comment',
2626      ])
2627  CheckScriptFailure([
2628      'vim9script',
2629      'syntax match Word /pat/ oneline# comment',
2630      ], 'E475:')
2631
2632  CheckScriptSuccess([
2633      'vim9script',
2634      'syntax keyword Word word # comm[ent',
2635      ])
2636  CheckScriptFailure([
2637      'vim9script',
2638      'syntax keyword Word word# comm[ent',
2639      ], 'E789:')
2640
2641  CheckScriptSuccess([
2642      'vim9script',
2643      'syntax match Word /pat/ # comment',
2644      ])
2645  CheckScriptFailure([
2646      'vim9script',
2647      'syntax match Word /pat/# comment',
2648      ], 'E402:')
2649
2650  CheckScriptSuccess([
2651      'vim9script',
2652      'syntax match Word /pat/ contains=Something # comment',
2653      ])
2654  CheckScriptFailure([
2655      'vim9script',
2656      'syntax match Word /pat/ contains=Something# comment',
2657      ], 'E475:')
2658  CheckScriptFailure([
2659      'vim9script',
2660      'syntax match Word /pat/ contains= # comment',
2661      ], 'E406:')
2662  CheckScriptFailure([
2663      'vim9script',
2664      'syntax match Word /pat/ contains=# comment',
2665      ], 'E475:')
2666
2667  CheckScriptSuccess([
2668      'vim9script',
2669      'syntax region Word start=/pat/ end=/pat/ # comment',
2670      ])
2671  CheckScriptFailure([
2672      'vim9script',
2673      'syntax region Word start=/pat/ end=/pat/# comment',
2674      ], 'E402:')
2675
2676  CheckScriptSuccess([
2677      'vim9script',
2678      'syntax sync # comment',
2679      ])
2680  CheckScriptFailure([
2681      'vim9script',
2682      'syntax sync# comment',
2683      ], 'E404:')
2684  CheckScriptSuccess([
2685      'vim9script',
2686      'syntax sync ccomment # comment',
2687      ])
2688  CheckScriptFailure([
2689      'vim9script',
2690      'syntax sync ccomment# comment',
2691      ], 'E404:')
2692
2693  CheckScriptSuccess([
2694      'vim9script',
2695      'syntax cluster Some contains=Word # comment',
2696      ])
2697  CheckScriptFailure([
2698      'vim9script',
2699      'syntax cluster Some contains=Word# comment',
2700      ], 'E475:')
2701
2702  CheckScriptSuccess([
2703      'vim9script',
2704      'command Echo echo # comment',
2705      'command Echo # comment',
2706      ])
2707  CheckScriptFailure([
2708      'vim9script',
2709      'command Echo echo# comment',
2710      'Echo',
2711      ], 'E121:')
2712  CheckScriptFailure([
2713      'vim9script',
2714      'command Echo# comment',
2715      ], 'E182:')
2716  CheckScriptFailure([
2717      'vim9script',
2718      'command Echo echo',
2719      'command Echo# comment',
2720      ], 'E182:')
2721
2722  CheckScriptSuccess([
2723      'vim9script',
2724      'function # comment',
2725      ])
2726  CheckScriptFailure([
2727      'vim9script',
2728      'function " comment',
2729      ], 'E129:')
2730  CheckScriptFailure([
2731      'vim9script',
2732      'function# comment',
2733      ], 'E129:')
2734  CheckScriptSuccess([
2735      'vim9script',
2736      'function CheckScriptSuccess # comment',
2737      ])
2738  CheckScriptFailure([
2739      'vim9script',
2740      'function CheckScriptSuccess# comment',
2741      ], 'E488:')
2742
2743  CheckScriptSuccess([
2744      'vim9script',
2745      'func g:DeleteMeA()',
2746      'endfunc',
2747      'delfunction g:DeleteMeA # comment',
2748      ])
2749  CheckScriptFailure([
2750      'vim9script',
2751      'func g:DeleteMeB()',
2752      'endfunc',
2753      'delfunction g:DeleteMeB# comment',
2754      ], 'E488:')
2755
2756  CheckScriptSuccess([
2757      'vim9script',
2758      'call execute("ls") # comment',
2759      ])
2760  CheckScriptFailure([
2761      'vim9script',
2762      'call execute("ls")# comment',
2763      ], 'E488:')
2764
2765  CheckScriptFailure([
2766      'def Test() " comment',
2767      'enddef',
2768      ], 'E488:')
2769  CheckScriptFailure([
2770      'vim9script',
2771      'def Test() " comment',
2772      'enddef',
2773      ], 'E488:')
2774
2775  CheckScriptSuccess([
2776      'func Test() " comment',
2777      'endfunc',
2778      ])
2779  CheckScriptSuccess([
2780      'vim9script',
2781      'func Test() " comment',
2782      'endfunc',
2783      ])
2784
2785  CheckScriptSuccess([
2786      'def Test() # comment',
2787      'enddef',
2788      ])
2789  CheckScriptFailure([
2790      'func Test() # comment',
2791      'endfunc',
2792      ], 'E488:')
2793enddef
2794
2795def Test_vim9_comment_gui()
2796  CheckCanRunGui
2797
2798  CheckScriptFailure([
2799      'vim9script',
2800      'gui#comment'
2801      ], 'E499:')
2802  CheckScriptFailure([
2803      'vim9script',
2804      'gui -f#comment'
2805      ], 'E499:')
2806enddef
2807
2808def Test_vim9_comment_not_compiled()
2809  au TabEnter *.vim g:entered = 1
2810  au TabEnter *.x g:entered = 2
2811
2812  edit test.vim
2813  doautocmd TabEnter #comment
2814  assert_equal(1, g:entered)
2815
2816  doautocmd TabEnter f.x
2817  assert_equal(2, g:entered)
2818
2819  g:entered = 0
2820  doautocmd TabEnter f.x #comment
2821  assert_equal(2, g:entered)
2822
2823  assert_fails('doautocmd Syntax#comment', 'E216:')
2824
2825  au! TabEnter
2826  unlet g:entered
2827
2828  CheckScriptSuccess([
2829      'vim9script',
2830      'g:var = 123',
2831      'b:var = 456',
2832      'w:var = 777',
2833      't:var = 888',
2834      'unlet g:var w:var # something',
2835      ])
2836
2837  CheckScriptFailure([
2838      'vim9script',
2839      'let g:var = 123',
2840      ], 'E1016: Cannot declare a global variable:')
2841
2842  CheckScriptFailure([
2843      'vim9script',
2844      'let b:var = 123',
2845      ], 'E1016: Cannot declare a buffer variable:')
2846
2847  CheckScriptFailure([
2848      'vim9script',
2849      'let w:var = 123',
2850      ], 'E1016: Cannot declare a window variable:')
2851
2852  CheckScriptFailure([
2853      'vim9script',
2854      'let t:var = 123',
2855      ], 'E1016: Cannot declare a tab variable:')
2856
2857  CheckScriptFailure([
2858      'vim9script',
2859      'let v:version = 123',
2860      ], 'E1016: Cannot declare a v: variable:')
2861
2862  CheckScriptFailure([
2863      'vim9script',
2864      'let $VARIABLE = "text"',
2865      ], 'E1016: Cannot declare an environment variable:')
2866
2867  CheckScriptFailure([
2868      'vim9script',
2869      'g:var = 123',
2870      'unlet g:var# comment1',
2871      ], 'E108:')
2872
2873  CheckScriptFailure([
2874      'let g:var = 123',
2875      'unlet g:var # something',
2876      ], 'E488:')
2877
2878  CheckScriptSuccess([
2879      'vim9script',
2880      'if 1 # comment2',
2881      '  echo "yes"',
2882      'elseif 2 #comment',
2883      '  echo "no"',
2884      'endif',
2885      ])
2886
2887  CheckScriptFailure([
2888      'vim9script',
2889      'if 1# comment3',
2890      '  echo "yes"',
2891      'endif',
2892      ], 'E15:')
2893
2894  CheckScriptFailure([
2895      'vim9script',
2896      'if 0 # comment4',
2897      '  echo "yes"',
2898      'elseif 2#comment',
2899      '  echo "no"',
2900      'endif',
2901      ], 'E15:')
2902
2903  CheckScriptSuccess([
2904      'vim9script',
2905      'let v = 1 # comment5',
2906      ])
2907
2908  CheckScriptFailure([
2909      'vim9script',
2910      'let v = 1# comment6',
2911      ], 'E15:')
2912
2913  CheckScriptSuccess([
2914      'vim9script',
2915      'new'
2916      'call setline(1, ["# define pat", "last"])',
2917      ':$',
2918      'dsearch /pat/ #comment',
2919      'bwipe!',
2920      ])
2921
2922  CheckScriptFailure([
2923      'vim9script',
2924      'new'
2925      'call setline(1, ["# define pat", "last"])',
2926      ':$',
2927      'dsearch /pat/#comment',
2928      'bwipe!',
2929      ], 'E488:')
2930
2931  CheckScriptFailure([
2932      'vim9script',
2933      'func! SomeFunc()',
2934      ], 'E477:')
2935enddef
2936
2937def Test_finish()
2938  let lines =<< trim END
2939    vim9script
2940    g:res = 'one'
2941    if v:false | finish | endif
2942    g:res = 'two'
2943    finish
2944    g:res = 'three'
2945  END
2946  writefile(lines, 'Xfinished')
2947  source Xfinished
2948  assert_equal('two', g:res)
2949
2950  unlet g:res
2951  delete('Xfinished')
2952enddef
2953
2954def Test_let_func_call()
2955  let lines =<< trim END
2956    vim9script
2957    func GetValue()
2958      if exists('g:count')
2959        let g:count += 1
2960      else
2961        let g:count = 1
2962      endif
2963      return 'this'
2964    endfunc
2965    let val: string = GetValue()
2966    # env var is always a string
2967    let env = $TERM
2968  END
2969  writefile(lines, 'Xfinished')
2970  source Xfinished
2971  # GetValue() is not called during discovery phase
2972  assert_equal(1, g:count)
2973
2974  unlet g:count
2975  delete('Xfinished')
2976enddef
2977
2978def Test_let_missing_type()
2979  let lines =<< trim END
2980    vim9script
2981    let var = g:unknown
2982  END
2983  CheckScriptFailure(lines, 'E121:')
2984
2985  lines =<< trim END
2986    vim9script
2987    let nr: number = 123
2988    let var = nr
2989  END
2990  CheckScriptSuccess(lines)
2991enddef
2992
2993def Test_let_declaration()
2994  let lines =<< trim END
2995    vim9script
2996    let var: string
2997    g:var_uninit = var
2998    var = 'text'
2999    g:var_test = var
3000    # prefixing s: is optional
3001    s:var = 'prefixed'
3002    g:var_prefixed = s:var
3003
3004    let s:other: number
3005    other = 1234
3006    g:other_var = other
3007
3008    # type is inferred
3009    s:dict = {'a': 222}
3010    def GetDictVal(key: any)
3011      g:dict_val = s:dict[key]
3012    enddef
3013    GetDictVal('a')
3014  END
3015  CheckScriptSuccess(lines)
3016  assert_equal('', g:var_uninit)
3017  assert_equal('text', g:var_test)
3018  assert_equal('prefixed', g:var_prefixed)
3019  assert_equal(1234, g:other_var)
3020  assert_equal(222, g:dict_val)
3021
3022  unlet g:var_uninit
3023  unlet g:var_test
3024  unlet g:var_prefixed
3025  unlet g:other_var
3026enddef
3027
3028def Test_let_declaration_fails()
3029  let lines =<< trim END
3030    vim9script
3031    const var: string
3032  END
3033  CheckScriptFailure(lines, 'E1021:')
3034
3035  lines =<< trim END
3036    vim9script
3037    let 9var: string
3038  END
3039  CheckScriptFailure(lines, 'E475:')
3040enddef
3041
3042def Test_let_type_check()
3043  let lines =<< trim END
3044    vim9script
3045    let var: string
3046    var = 1234
3047  END
3048  CheckScriptFailure(lines, 'E1012:')
3049
3050  lines =<< trim END
3051    vim9script
3052    let var:string
3053  END
3054  CheckScriptFailure(lines, 'E1069:')
3055
3056  lines =<< trim END
3057    vim9script
3058    let var: asdf
3059  END
3060  CheckScriptFailure(lines, 'E1010:')
3061
3062  lines =<< trim END
3063    vim9script
3064    let s:l: list<number>
3065    s:l = []
3066  END
3067  CheckScriptSuccess(lines)
3068
3069  lines =<< trim END
3070    vim9script
3071    let s:d: dict<number>
3072    s:d = {}
3073  END
3074  CheckScriptSuccess(lines)
3075enddef
3076
3077def Test_forward_declaration()
3078  let lines =<< trim END
3079    vim9script
3080    def GetValue(): string
3081      return theVal
3082    enddef
3083    let theVal = 'something'
3084    g:initVal = GetValue()
3085    theVal = 'else'
3086    g:laterVal = GetValue()
3087  END
3088  writefile(lines, 'Xforward')
3089  source Xforward
3090  assert_equal('something', g:initVal)
3091  assert_equal('else', g:laterVal)
3092
3093  unlet g:initVal
3094  unlet g:laterVal
3095  delete('Xforward')
3096enddef
3097
3098def Test_source_vim9_from_legacy()
3099  let legacy_lines =<< trim END
3100    source Xvim9_script.vim
3101
3102    call assert_false(exists('local'))
3103    call assert_false(exists('exported'))
3104    call assert_false(exists('s:exported'))
3105    call assert_equal('global', global)
3106    call assert_equal('global', g:global)
3107
3108    " imported variable becomes script-local
3109    import exported from './Xvim9_script.vim'
3110    call assert_equal('exported', s:exported)
3111    call assert_false(exists('exported'))
3112
3113    " imported function becomes script-local
3114    import GetText from './Xvim9_script.vim'
3115    call assert_equal('text', s:GetText())
3116    call assert_false(exists('*GetText'))
3117  END
3118  writefile(legacy_lines, 'Xlegacy_script.vim')
3119
3120  let vim9_lines =<< trim END
3121    vim9script
3122    let local = 'local'
3123    g:global = 'global'
3124    export let exported = 'exported'
3125    export def GetText(): string
3126       return 'text'
3127    enddef
3128  END
3129  writefile(vim9_lines, 'Xvim9_script.vim')
3130
3131  source Xlegacy_script.vim
3132
3133  assert_equal('global', g:global)
3134  unlet g:global
3135
3136  delete('Xlegacy_script.vim')
3137  delete('Xvim9_script.vim')
3138enddef
3139
3140func Test_vim9script_not_global()
3141  " check that items defined in Vim9 script are script-local, not global
3142  let vim9lines =<< trim END
3143    vim9script
3144    let var = 'local'
3145    func TheFunc()
3146      echo 'local'
3147    endfunc
3148    def DefFunc()
3149      echo 'local'
3150    enddef
3151  END
3152  call writefile(vim9lines, 'Xvim9script.vim')
3153  source Xvim9script.vim
3154  try
3155    echo g:var
3156    assert_report('did not fail')
3157  catch /E121:/
3158    " caught
3159  endtry
3160  try
3161    call TheFunc()
3162    assert_report('did not fail')
3163  catch /E117:/
3164    " caught
3165  endtry
3166  try
3167    call DefFunc()
3168    assert_report('did not fail')
3169  catch /E117:/
3170    " caught
3171  endtry
3172
3173  call delete('Xvim9script.vium')
3174endfunc
3175
3176def Test_vim9_copen()
3177  # this was giving an error for setting w:quickfix_title
3178  copen
3179  quit
3180enddef
3181
3182" test using a vim9script that is auto-loaded from an autocmd
3183def Test_vim9_autoload()
3184  let lines =<< trim END
3185     vim9script
3186     def foo#test()
3187         echomsg getreg('"')
3188     enddef
3189  END
3190
3191  mkdir('Xdir/autoload', 'p')
3192  writefile(lines, 'Xdir/autoload/foo.vim')
3193  let save_rtp = &rtp
3194  exe 'set rtp^=' .. getcwd() .. '/Xdir'
3195  augroup test
3196    autocmd TextYankPost * call foo#test()
3197  augroup END
3198
3199  normal Y
3200
3201  augroup test
3202    autocmd!
3203  augroup END
3204  delete('Xdir', 'rf')
3205  &rtp = save_rtp
3206enddef
3207
3208def Test_script_var_in_autocmd()
3209  # using a script variable from an autocommand, defined in a :def function in a
3210  # legacy Vim script, cannot check the variable type.
3211  let lines =<< trim END
3212    let s:counter = 1
3213    def s:Func()
3214      au! CursorHold
3215      au CursorHold * s:counter += 1
3216    enddef
3217    call s:Func()
3218    doau CursorHold
3219    call assert_equal(2, s:counter)
3220    au! CursorHold
3221  END
3222  CheckScriptSuccess(lines)
3223enddef
3224
3225def Test_cmdline_win()
3226  # if the Vim syntax highlighting uses Vim9 constructs they can be used from
3227  # the command line window.
3228  mkdir('rtp/syntax', 'p')
3229  let export_lines =<< trim END
3230    vim9script
3231    export let That = 'yes'
3232  END
3233  writefile(export_lines, 'rtp/syntax/Xexport.vim')
3234  let import_lines =<< trim END
3235    vim9script
3236    import That from './Xexport.vim'
3237  END
3238  writefile(import_lines, 'rtp/syntax/vim.vim')
3239  let save_rtp = &rtp
3240  &rtp = getcwd() .. '/rtp' .. ',' .. &rtp
3241  syntax on
3242  augroup CmdWin
3243    autocmd CmdwinEnter * g:got_there = 'yes'
3244  augroup END
3245  # this will open and also close the cmdline window
3246  feedkeys('q:', 'xt')
3247  assert_equal('yes', g:got_there)
3248
3249  augroup CmdWin
3250    au!
3251  augroup END
3252  &rtp = save_rtp
3253  delete('rtp', 'rf')
3254enddef
3255
3256def Test_invalid_sid()
3257  assert_fails('func <SNR>1234_func', 'E123:')
3258  if RunVim([], ['wq Xdidit'], '+"func <SNR>1_func"')
3259    call assert_equal([], readfile('Xdidit'))
3260  endif
3261  delete('Xdidit')
3262enddef
3263
3264" Keep this last, it messes up highlighting.
3265def Test_substitute_cmd()
3266  new
3267  setline(1, 'something')
3268  :substitute(some(other(
3269  assert_equal('otherthing', getline(1))
3270  bwipe!
3271
3272  # also when the context is Vim9 script
3273  let lines =<< trim END
3274    vim9script
3275    new
3276    setline(1, 'something')
3277    :substitute(some(other(
3278    assert_equal('otherthing', getline(1))
3279    bwipe!
3280  END
3281  writefile(lines, 'Xvim9lines')
3282  source Xvim9lines
3283
3284  delete('Xvim9lines')
3285enddef
3286
3287" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
3288