1" Test commands that are not compiled in a :def function
2
3source check.vim
4source vim9.vim
5source term_util.vim
6source view_util.vim
7
8def Test_vim9cmd()
9  var lines =<< trim END
10    vim9cmd var x = 123
11    let s:y = 'yes'
12    vim9c assert_equal(123, x)
13    vim9cm assert_equal('yes', y)
14  END
15  CheckScriptSuccess(lines)
16
17  assert_fails('vim9cmd', 'E1164:')
18  assert_fails('legacy', 'E1234:')
19  assert_fails('vim9cmd echo "con" . "cat"', 'E15:')
20
21  lines =<< trim END
22      let str = 'con'
23      vim9cmd str .= 'cat'
24  END
25  CheckScriptFailure(lines, 'E492:')
26
27  lines =<< trim END
28      vim9script
29      legacy echo "con" . "cat"
30      legacy let str = 'con'
31      legacy let str .= 'cat'
32  END
33  CheckScriptSuccess(lines)
34
35  lines =<< trim END
36      vim9script
37      def Foo()
38        g:found_bar = "bar"
39      enddef
40      nmap ,; :vim9cmd <SID>Foo()<CR>
41  END
42  CheckScriptSuccess(lines)
43
44  feedkeys(',;', 'xt')
45  assert_equal("bar", g:found_bar)
46  nunmap ,;
47  unlet g:found_bar
48
49  lines =<< trim END
50      vim9script
51      legacy echo 1'000
52  END
53  CheckScriptFailure(lines, 'E115:')
54
55  if has('float')
56    lines =<< trim END
57        vim9script
58        echo .10
59    END
60    CheckScriptSuccess(lines)
61    lines =<< trim END
62        vim9cmd echo .10
63    END
64    CheckScriptSuccess(lines)
65    lines =<< trim END
66        vim9script
67        legacy echo .10
68    END
69    CheckScriptFailure(lines, 'E15:')
70  endif
71
72  echo v:version
73  assert_fails('vim9cmd echo version', 'E121:')
74  lines =<< trim END
75      vim9script
76      echo version
77  END
78  CheckScriptFailure(lines, 'E121:')
79  lines =<< trim END
80      vim9script
81      legacy echo version
82  END
83  CheckScriptSuccess(lines)
84enddef
85
86def Test_edit_wildcards()
87  var filename = 'Xtest'
88  edit `=filename`
89  assert_equal('Xtest', bufname())
90
91  var filenr = 123
92  edit Xtest`=filenr`
93  assert_equal('Xtest123', bufname())
94
95  filenr = 77
96  edit `=filename``=filenr`
97  assert_equal('Xtest77', bufname())
98
99  edit X`=filename`xx`=filenr`yy
100  assert_equal('XXtestxx77yy', bufname())
101
102  CheckDefFailure(['edit `=xxx`'], 'E1001:')
103  CheckDefFailure(['edit `="foo"'], 'E1083:')
104
105  var files = ['file 1', 'file%2', 'file# 3']
106  args `=files`
107  assert_equal(files, argv())
108enddef
109
110def Test_expand_alternate_file()
111  var lines =<< trim END
112    edit Xfileone
113    var bone = bufnr()
114    edit Xfiletwo
115    var btwo = bufnr()
116    edit Xfilethree
117    var bthree = bufnr()
118
119    edit #
120    assert_equal(bthree, bufnr())
121    edit %%
122    assert_equal(btwo, bufnr())
123    edit %% # comment
124    assert_equal(bthree, bufnr())
125    edit %%yy
126    assert_equal('Xfiletwoyy', bufname())
127
128    exe "edit %%" .. bone
129    assert_equal(bone, bufnr())
130    exe "edit %%" .. btwo .. "xx"
131    assert_equal('Xfiletwoxx', bufname())
132
133    next Xfileone Xfiletwo Xfilethree
134    assert_equal('Xfileone', argv(0))
135    assert_equal('Xfiletwo', argv(1))
136    assert_equal('Xfilethree', argv(2))
137    next %%%zz
138    assert_equal('Xfileone', argv(0))
139    assert_equal('Xfiletwo', argv(1))
140    assert_equal('Xfilethreezz', argv(2))
141
142    v:oldfiles = ['Xonefile', 'Xtwofile']
143    edit %%<1
144    assert_equal('Xonefile', bufname())
145    edit %%<2
146    assert_equal('Xtwofile', bufname())
147    assert_fails('edit %%<3', 'E684:')
148
149    edit Xfileone.vim
150    edit Xfiletwo
151    edit %%:r
152    assert_equal('Xfileone', bufname())
153
154    assert_false(bufexists('altfoo'))
155    edit altfoo
156    edit bar
157    assert_true(bufexists('altfoo'))
158    assert_true(buflisted('altfoo'))
159    bdel %%
160    assert_true(bufexists('altfoo'))
161    assert_false(buflisted('altfoo'))
162    bwipe! altfoo
163    bwipe! bar
164  END
165  CheckDefAndScriptSuccess(lines)
166enddef
167
168def Test_global_backtick_expansion()
169  new
170  setline(1, 'xx')
171  var name = 'foobar'
172  g/^xx/s/.*/`=name`
173  assert_equal('foobar', getline(1))
174  bwipe!
175enddef
176
177def Test_folddo_backtick_expansion()
178  new
179  var name = 'xxx'
180  folddoopen edit `=name`
181  assert_equal('xxx', bufname())
182  bwipe!
183
184  new
185  setline(1, ['one', 'two'])
186  set nomodified
187  :1,2fold
188  foldclose
189  folddoclose edit `=name`
190  assert_equal('xxx', bufname())
191  bwipe!
192enddef
193
194def Test_hardcopy_wildcards()
195  CheckUnix
196  CheckFeature postscript
197
198  var outfile = 'print'
199  hardcopy > X`=outfile`.ps
200  assert_true(filereadable('Xprint.ps'))
201
202  delete('Xprint.ps')
203enddef
204
205def Test_syn_include_wildcards()
206  writefile(['syn keyword Found found'], 'Xthemine.vim')
207  var save_rtp = &rtp
208  &rtp = '.'
209
210  var fname = 'mine'
211  syn include @Group Xthe`=fname`.vim
212  assert_match('Found.* contained found', execute('syn list Found'))
213
214  &rtp = save_rtp
215  delete('Xthemine.vim')
216enddef
217
218def Test_echo_linebreak()
219  var lines =<< trim END
220      vim9script
221      redir @a
222      echo 'one'
223            .. 'two'
224      redir END
225      assert_equal("\nonetwo", @a)
226  END
227  CheckScriptSuccess(lines)
228
229  lines =<< trim END
230      vim9script
231      redir @a
232      echo 11 +
233            77
234            - 22
235      redir END
236      assert_equal("\n66", @a)
237  END
238  CheckScriptSuccess(lines)
239enddef
240
241def Test_condition_types()
242  var lines =<< trim END
243      if 'text'
244      endif
245  END
246  CheckDefAndScriptFailure(lines, 'E1135:', 1)
247
248  lines =<< trim END
249      if [1]
250      endif
251  END
252  CheckDefFailure(lines, 'E1012:', 1)
253  CheckScriptFailure(['vim9script'] + lines, 'E745:', 2)
254
255  lines =<< trim END
256      g:cond = 'text'
257      if g:cond
258      endif
259  END
260  CheckDefExecAndScriptFailure(lines, 'E1135:', 2)
261
262  lines =<< trim END
263      g:cond = 0
264      if g:cond
265      elseif 'text'
266      endif
267  END
268  CheckDefFailure(lines, 'E1012:', 3)
269  CheckScriptFailure(['vim9script'] + lines, 'E1135:', 4)
270
271  lines =<< trim END
272      if g:cond
273      elseif [1]
274      endif
275  END
276  CheckDefFailure(lines, 'E1012:', 2)
277  CheckScriptFailure(['vim9script'] + lines, 'E745:', 3)
278
279  lines =<< trim END
280      g:cond = 'text'
281      if 0
282      elseif g:cond
283      endif
284  END
285  CheckDefExecAndScriptFailure(lines, 'E1135:', 3)
286
287  lines =<< trim END
288      while 'text'
289      endwhile
290  END
291  CheckDefFailure(lines, 'E1012:', 1)
292  CheckScriptFailure(['vim9script'] + lines, 'E1135:', 2)
293
294  lines =<< trim END
295      while [1]
296      endwhile
297  END
298  CheckDefFailure(lines, 'E1012:', 1)
299  CheckScriptFailure(['vim9script'] + lines, 'E745:', 2)
300
301  lines =<< trim END
302      g:cond = 'text'
303      while g:cond
304      endwhile
305  END
306  CheckDefExecAndScriptFailure(lines, 'E1135:', 2)
307enddef
308
309def Test_if_linebreak()
310  var lines =<< trim END
311      vim9script
312      if 1 &&
313            true
314            || 1
315        g:res = 42
316      endif
317      assert_equal(42, g:res)
318  END
319  CheckScriptSuccess(lines)
320  unlet g:res
321
322  lines =<< trim END
323      vim9script
324      if 1 &&
325            0
326        g:res = 0
327      elseif 0 ||
328              0
329              || 1
330        g:res = 12
331      endif
332      assert_equal(12, g:res)
333  END
334  CheckScriptSuccess(lines)
335  unlet g:res
336enddef
337
338def Test_while_linebreak()
339  var lines =<< trim END
340      vim9script
341      var nr = 0
342      while nr <
343              10 + 3
344            nr = nr
345                  + 4
346      endwhile
347      assert_equal(16, nr)
348  END
349  CheckScriptSuccess(lines)
350
351  lines =<< trim END
352      vim9script
353      var nr = 0
354      while nr
355            <
356              10
357              +
358              3
359            nr = nr
360                  +
361                  4
362      endwhile
363      assert_equal(16, nr)
364  END
365  CheckScriptSuccess(lines)
366enddef
367
368def Test_for_linebreak()
369  var lines =<< trim END
370      vim9script
371      var nr = 0
372      for x
373            in
374              [1, 2, 3, 4]
375          nr = nr + x
376      endfor
377      assert_equal(10, nr)
378  END
379  CheckScriptSuccess(lines)
380
381  lines =<< trim END
382      vim9script
383      var nr = 0
384      for x
385            in
386              [1, 2,
387                  3, 4
388                  ]
389          nr = nr
390                 +
391                  x
392      endfor
393      assert_equal(10, nr)
394  END
395  CheckScriptSuccess(lines)
396enddef
397
398def MethodAfterLinebreak(arg: string)
399  arg
400    ->setline(1)
401enddef
402
403def Test_method_call_linebreak()
404  var lines =<< trim END
405      vim9script
406      var res = []
407      func RetArg(
408            arg
409            )
410            let s:res = a:arg
411      endfunc
412      [1,
413          2,
414          3]->RetArg()
415      assert_equal([1, 2, 3], res)
416  END
417  CheckScriptSuccess(lines)
418
419  lines =<< trim END
420      new
421      var name = [1, 2]
422      name
423          ->copy()
424          ->setline(1)
425      assert_equal(['1', '2'], getline(1, 2))
426      bwipe!
427  END
428  CheckDefAndScriptSuccess(lines)
429
430  lines =<< trim END
431      new
432      def Foo(): string
433        return 'the text'
434      enddef
435      def Bar(F: func): string
436        return F()
437      enddef
438      def Test()
439        Foo  ->Bar()
440             ->setline(1)
441      enddef
442      Test()
443      assert_equal('the text', getline(1))
444      bwipe!
445  END
446  CheckDefAndScriptSuccess(lines)
447
448  lines =<< trim END
449      new
450      g:shortlist
451          ->copy()
452          ->setline(1)
453      assert_equal(['1', '2'], getline(1, 2))
454      bwipe!
455  END
456  g:shortlist = [1, 2]
457  CheckDefAndScriptSuccess(lines)
458  unlet g:shortlist
459
460  new
461  MethodAfterLinebreak('foobar')
462  assert_equal('foobar', getline(1))
463  bwipe!
464
465  lines =<< trim END
466      vim9script
467      def Foo(): string
468          return '# some text'
469      enddef
470
471      def Bar(F: func): string
472          return F()
473      enddef
474
475      Foo->Bar()
476         ->setline(1)
477  END
478  CheckScriptSuccess(lines)
479  assert_equal('# some text', getline(1))
480  bwipe!
481enddef
482
483def Test_method_call_whitespace()
484  var lines =<< trim END
485    new
486    var yank = 'text'
487    yank->setline(1)
488    yank  ->setline(2)
489    yank->  setline(3)
490    yank  ->  setline(4)
491    assert_equal(['text', 'text', 'text', 'text'], getline(1, 4))
492    bwipe!
493  END
494  CheckDefAndScriptSuccess(lines)
495enddef
496
497def Test_method_and_user_command()
498  var lines =<< trim END
499      vim9script
500      def Cmd()
501        g:didFunc = 1
502      enddef
503      command Cmd g:didCmd = 1
504      Cmd
505      assert_equal(1, g:didCmd)
506      Cmd()
507      assert_equal(1, g:didFunc)
508      unlet g:didFunc
509      unlet g:didCmd
510
511      def InDefFunc()
512        Cmd
513        assert_equal(1, g:didCmd)
514        Cmd()
515        assert_equal(1, g:didFunc)
516        unlet g:didFunc
517        unlet g:didCmd
518      enddef
519      InDefFunc()
520  END
521  CheckScriptSuccess(lines)
522enddef
523
524def Test_option_use_linebreak()
525  var lines =<< trim END
526      new
527      &matchpairs = '(:)'
528      &matchpairs->setline(1)
529      &matchpairs = '[:]'
530      &matchpairs   ->setline(2)
531      &matchpairs = '{:}'
532      &matchpairs
533          ->setline(3)
534      assert_equal(['(:)', '[:]', '{:}'], getline(1, '$'))
535      bwipe!
536  END
537  CheckDefAndScriptSuccess(lines)
538enddef
539
540def Test_skipped_expr_linebreak()
541  if 0
542    var x = []
543               ->map(() => 0)
544  endif
545enddef
546
547def Test_dict_member()
548   var test: dict<list<number>> = {data: [3, 1, 2]}
549   test.data->sort()
550   assert_equal({data: [1, 2, 3]}, test)
551   test.data
552      ->reverse()
553   assert_equal({data: [3, 2, 1]}, test)
554
555  var lines =<< trim END
556      vim9script
557      var test: dict<list<number>> = {data: [3, 1, 2]}
558      test.data->sort()
559      assert_equal({data: [1, 2, 3]}, test)
560  END
561  CheckScriptSuccess(lines)
562enddef
563
564def Test_bar_after_command()
565  def RedrawAndEcho()
566    var x = 'did redraw'
567    redraw | echo x
568  enddef
569  RedrawAndEcho()
570  assert_match('did redraw', Screenline(&lines))
571
572  def CallAndEcho()
573    var x = 'did redraw'
574    reg_executing() | echo x
575  enddef
576  CallAndEcho()
577  assert_match('did redraw', Screenline(&lines))
578
579  if has('unix')
580    # bar in filter write command does not start new command
581    def WriteToShell()
582      new
583      setline(1, 'some text')
584      w !cat | cat > Xoutfile
585      bwipe!
586    enddef
587    WriteToShell()
588    assert_equal(['some text'], readfile('Xoutfile'))
589    delete('Xoutfile')
590
591    # bar in filter read command does not start new command
592    def ReadFromShell()
593      new
594      r! echo hello there | cat > Xoutfile
595      r !echo again | cat >> Xoutfile
596      bwipe!
597    enddef
598    ReadFromShell()
599    assert_equal(['hello there', 'again'], readfile('Xoutfile'))
600    delete('Xoutfile')
601  endif
602enddef
603
604def Test_filter_is_not_modifier()
605  var tags = [{a: 1, b: 2}, {x: 3, y: 4}]
606  filter(tags, ( _, v) => has_key(v, 'x') ? 1 : 0 )
607  assert_equal([{x: 3, y: 4}], tags)
608enddef
609
610def Test_command_modifier_filter()
611  var lines =<< trim END
612    final expected = "\nType Name Content\n  c  \"c   piyo"
613    @a = 'hoge'
614    @b = 'fuga'
615    @c = 'piyo'
616
617    assert_equal(execute('filter /piyo/ registers abc'), expected)
618  END
619  CheckDefAndScriptSuccess(lines)
620
621  # also do this compiled
622  lines =<< trim END
623      @a = 'very specific z3d37dh234 string'
624      filter z3d37dh234 registers
625      assert_match('very specific z3d37dh234 string', Screenline(&lines))
626  END
627  CheckDefAndScriptSuccess(lines)
628enddef
629
630def Test_win_command_modifiers()
631  assert_equal(1, winnr('$'))
632
633  set splitright
634  vsplit
635  assert_equal(2, winnr())
636  close
637  aboveleft vsplit
638  assert_equal(1, winnr())
639  close
640  set splitright&
641
642  vsplit
643  assert_equal(1, winnr())
644  close
645  belowright vsplit
646  assert_equal(2, winnr())
647  close
648  rightbelow vsplit
649  assert_equal(2, winnr())
650  close
651
652  if has('browse')
653    browse set
654    assert_equal('option-window', expand('%'))
655    close
656  endif
657
658  vsplit
659  botright split
660  assert_equal(3, winnr())
661  assert_equal(&columns, winwidth(0))
662  close
663  close
664
665  vsplit
666  topleft split
667  assert_equal(1, winnr())
668  assert_equal(&columns, winwidth(0))
669  close
670  close
671
672  gettabinfo()->len()->assert_equal(1)
673  tab split
674  gettabinfo()->len()->assert_equal(2)
675  tabclose
676
677  vertical new
678  assert_inrange(&columns / 2 - 2, &columns / 2 + 1, winwidth(0))
679  close
680enddef
681
682func Test_command_modifier_confirm()
683  CheckNotGui
684  CheckRunVimInTerminal
685
686  " Test for saving all the modified buffers
687  let lines =<< trim END
688    call setline(1, 'changed')
689    def Getout()
690      confirm write Xfile
691    enddef
692  END
693  call writefile(lines, 'Xconfirmscript')
694  call writefile(['empty'], 'Xfile')
695  let buf = RunVimInTerminal('-S Xconfirmscript', {'rows': 8})
696  call term_sendkeys(buf, ":call Getout()\n")
697  call WaitForAssert({-> assert_match('(Y)es, \[N\]o: ', term_getline(buf, 8))}, 1000)
698  call term_sendkeys(buf, "y")
699  call WaitForAssert({-> assert_match('(Y)es, \[N\]o: ', term_getline(buf, 8))}, 1000)
700  call term_sendkeys(buf, "\<CR>")
701  call TermWait(buf)
702  call StopVimInTerminal(buf)
703
704  call assert_equal(['changed'], readfile('Xfile'))
705  call delete('Xfile')
706  call delete('.Xfile.swp')  " in case Vim was killed
707  call delete('Xconfirmscript')
708endfunc
709
710def Test_command_modifiers_keep()
711  if has('unix')
712    def DoTest(addRflag: bool, keepMarks: bool, hasMarks: bool)
713      new
714      setline(1, ['one', 'two', 'three'])
715      normal 1Gma
716      normal 2Gmb
717      normal 3Gmc
718      if addRflag
719        set cpo+=R
720      else
721        set cpo-=R
722      endif
723      if keepMarks
724        keepmarks :%!cat
725      else
726        :%!cat
727      endif
728      if hasMarks
729        assert_equal(1, line("'a"))
730        assert_equal(2, line("'b"))
731        assert_equal(3, line("'c"))
732      else
733        assert_equal(0, line("'a"))
734        assert_equal(0, line("'b"))
735        assert_equal(0, line("'c"))
736      endif
737      quit!
738    enddef
739    DoTest(false, false, true)
740    DoTest(true, false, false)
741    DoTest(false, true, true)
742    DoTest(true, true, true)
743    set cpo&vim
744
745    new
746    setline(1, ['one', 'two', 'three', 'four'])
747    assert_equal(4, line("$"))
748    normal 1Gma
749    normal 2Gmb
750    normal 3Gmc
751    lockmarks :1,2!wc
752    # line is deleted, marks don't move
753    assert_equal(3, line("$"))
754    assert_equal('four', getline(3))
755    assert_equal(1, line("'a"))
756    assert_equal(2, line("'b"))
757    assert_equal(3, line("'c"))
758    quit!
759  endif
760
761  edit Xone
762  edit Xtwo
763  assert_equal('Xone', expand('#'))
764  keepalt edit Xthree
765  assert_equal('Xone', expand('#'))
766
767  normal /a*b*
768  assert_equal('a*b*', histget("search"))
769  keeppatterns normal /c*d*
770  assert_equal('a*b*', histget("search"))
771
772  new
773  setline(1, range(10))
774  :10
775  normal gg
776  assert_equal(10, getpos("''")[1])
777  keepjumps normal 5G
778  assert_equal(10, getpos("''")[1])
779  quit!
780enddef
781
782def Test_bar_line_continuation()
783  var lines =<< trim END
784      au BufNewFile Xfile g:readFile = 1
785          | g:readExtra = 2
786      g:readFile = 0
787      g:readExtra = 0
788      edit Xfile
789      assert_equal(1, g:readFile)
790      assert_equal(2, g:readExtra)
791      bwipe!
792      au! BufNewFile
793
794      au BufNewFile Xfile g:readFile = 1
795          | g:readExtra = 2
796          | g:readMore = 3
797      g:readFile = 0
798      g:readExtra = 0
799      g:readMore = 0
800      edit Xfile
801      assert_equal(1, g:readFile)
802      assert_equal(2, g:readExtra)
803      assert_equal(3, g:readMore)
804      bwipe!
805      au! BufNewFile
806      unlet g:readFile
807      unlet g:readExtra
808      unlet g:readMore
809  END
810  CheckDefAndScriptSuccess(lines)
811enddef
812
813def Test_command_modifier_other()
814  new Xsomefile
815  setline(1, 'changed')
816  var buf = bufnr()
817  hide edit Xotherfile
818  var info = getbufinfo(buf)
819  assert_equal(1, info[0].hidden)
820  assert_equal(1, info[0].changed)
821  edit Xsomefile
822  bwipe!
823
824  au BufNewFile Xfile g:readFile = 1
825  g:readFile = 0
826  edit Xfile
827  assert_equal(1, g:readFile)
828  bwipe!
829  g:readFile = 0
830  noautocmd edit Xfile
831  assert_equal(0, g:readFile)
832  au! BufNewFile
833  unlet g:readFile
834
835  noswapfile edit XnoSwap
836  assert_equal(false, &l:swapfile)
837  bwipe!
838
839  var caught = false
840  try
841    sandbox !ls
842  catch /E48:/
843    caught = true
844  endtry
845  assert_true(caught)
846
847  :8verbose g:verbose_now = &verbose
848  assert_equal(8, g:verbose_now)
849  unlet g:verbose_now
850enddef
851
852def EchoHere()
853  echomsg 'here'
854enddef
855def EchoThere()
856  unsilent echomsg 'there'
857enddef
858
859def Test_modifier_silent_unsilent()
860  echomsg 'last one'
861  silent echomsg "text"
862  assert_equal("\nlast one", execute(':1messages'))
863
864  silent! echoerr "error"
865
866  echomsg 'last one'
867  silent EchoHere()
868  assert_equal("\nlast one", execute(':1messages'))
869
870  silent EchoThere()
871  assert_equal("\nthere", execute(':1messages'))
872
873  try
874    silent eval [][0]
875  catch
876    echomsg "caught"
877  endtry
878  assert_equal("\ncaught", execute(':1messages'))
879
880  var lines =<< trim END
881      vim9script
882      set history=11
883      silent! while 0
884        set history=22
885      silent! endwhile
886      assert_equal(11, &history)
887      set history&
888  END
889  CheckScriptSuccess(lines)
890enddef
891
892def Test_range_after_command_modifier()
893  CheckScriptFailure(['vim9script', 'silent keepjump 1d _'], 'E1050: Colon required before a range: 1d _', 2)
894  new
895  setline(1, 'xxx')
896  CheckScriptSuccess(['vim9script', 'silent keepjump :1d _'])
897  assert_equal('', getline(1))
898  bwipe!
899enddef
900
901def Test_silent_pattern()
902  new
903  silent! :/pat/put _
904  bwipe!
905enddef
906
907def Test_useless_command_modifier()
908  g:maybe = true
909  var lines =<< trim END
910      if g:maybe
911      silent endif
912  END
913  CheckDefAndScriptFailure(lines, 'E1176:', 2)
914
915  lines =<< trim END
916      for i in [0]
917      silent endfor
918  END
919  CheckDefFailure(lines, 'E1176:', 2)
920  CheckScriptSuccess(['vim9script'] + lines)
921
922  lines =<< trim END
923      while g:maybe
924      silent endwhile
925  END
926  CheckDefFailure(lines, 'E1176:', 2)
927  g:maybe = false
928  CheckScriptSuccess(['vim9script'] + lines)
929
930  lines =<< trim END
931      silent try
932      finally
933      endtry
934  END
935  CheckDefAndScriptFailure(lines, 'E1176:', 1)
936
937  lines =<< trim END
938      try
939      silent catch
940      endtry
941  END
942  CheckDefAndScriptFailure(lines, 'E1176:', 2)
943
944  lines =<< trim END
945      try
946      silent finally
947      endtry
948  END
949  CheckDefAndScriptFailure(lines, 'E1176:', 2)
950
951  lines =<< trim END
952      try
953      finally
954      silent endtry
955  END
956  CheckDefAndScriptFailure(lines, 'E1176:', 3)
957enddef
958
959def Test_eval_command()
960  var from = 3
961  var to = 5
962  g:val = 111
963  def Increment(nrs: list<number>)
964    for nr in nrs
965      g:val += nr
966    endfor
967  enddef
968  eval range(from, to)
969        ->Increment()
970  assert_equal(111 + 3 + 4 + 5, g:val)
971  unlet g:val
972
973  var lines =<< trim END
974    vim9script
975    g:caught = 'no'
976    try
977      eval 123 || 0
978    catch
979      g:caught = 'yes'
980    endtry
981    assert_equal('yes', g:caught)
982    unlet g:caught
983  END
984  CheckScriptSuccess(lines)
985enddef
986
987def Test_map_command()
988  var lines =<< trim END
989      nnoremap <F3> :echo 'hit F3 #'<CR>
990      assert_equal(":echo 'hit F3 #'<CR>", maparg("<F3>", "n"))
991  END
992  CheckDefSuccess(lines)
993  CheckScriptSuccess(['vim9script'] + lines)
994enddef
995
996def Test_normal_command()
997  new
998  setline(1, 'doesnotexist')
999  var caught = 0
1000  try
1001    exe "norm! \<C-]>"
1002  catch /E433/
1003    caught = 2
1004  endtry
1005  assert_equal(2, caught)
1006
1007  try
1008    exe "norm! 3\<C-]>"
1009  catch /E433/
1010    caught = 3
1011  endtry
1012  assert_equal(3, caught)
1013  bwipe!
1014enddef
1015
1016def Test_put_command()
1017  new
1018  @p = 'ppp'
1019  put p
1020  assert_equal('ppp', getline(2))
1021
1022  put ='below'
1023  assert_equal('below', getline(3))
1024  put! ='above'
1025  assert_equal('above', getline(3))
1026  assert_equal('below', getline(4))
1027
1028  :2put =['a', 'b', 'c']
1029  assert_equal(['ppp', 'a', 'b', 'c', 'above'], getline(2, 6))
1030
1031  # compute range at runtime
1032  setline(1, range(1, 8))
1033  @a = 'aaa'
1034  :$-2put a
1035  assert_equal('aaa', getline(7))
1036
1037  setline(1, range(1, 8))
1038  :2
1039  :+2put! a
1040  assert_equal('aaa', getline(4))
1041
1042  []->mapnew(() => 0)
1043  :$put ='end'
1044  assert_equal('end', getline('$'))
1045
1046  bwipe!
1047
1048  CheckDefFailure(['put =xxx'], 'E1001:')
1049enddef
1050
1051def Test_put_with_linebreak()
1052  new
1053  var lines =<< trim END
1054    vim9script
1055    pu =split('abc', '\zs')
1056            ->join()
1057  END
1058  CheckScriptSuccess(lines)
1059  getline(2)->assert_equal('a b c')
1060  bwipe!
1061enddef
1062
1063def Test_command_star_range()
1064  new
1065  setline(1, ['xxx foo xxx', 'xxx bar xxx', 'xxx foo xx bar'])
1066  setpos("'<", [0, 1, 0, 0])
1067  setpos("'>", [0, 3, 0, 0])
1068  :*s/\(foo\|bar\)/baz/g
1069  getline(1, 3)->assert_equal(['xxx baz xxx', 'xxx baz xxx', 'xxx baz xx baz'])
1070
1071  bwipe!
1072enddef
1073
1074def Test_f_args()
1075  var lines =<< trim END
1076    vim9script
1077
1078    func SaveCmdArgs(...)
1079      let g:args = a:000
1080    endfunc
1081
1082    command -nargs=* TestFArgs call SaveCmdArgs(<f-args>)
1083
1084    TestFArgs
1085    assert_equal([], g:args)
1086
1087    TestFArgs one two three
1088    assert_equal(['one', 'two', 'three'], g:args)
1089  END
1090  CheckScriptSuccess(lines)
1091enddef
1092
1093def Test_user_command_comment()
1094  command -nargs=1 Comd echom <q-args>
1095
1096  var lines =<< trim END
1097      vim9script
1098      Comd # comment
1099  END
1100  CheckScriptSuccess(lines)
1101
1102  lines =<< trim END
1103      vim9script
1104      Comd# comment
1105  END
1106  CheckScriptFailure(lines, 'E1144:')
1107  delcommand Comd
1108
1109  lines =<< trim END
1110      vim9script
1111      command Foo echo 'Foo'
1112      Foo3Bar
1113  END
1114  CheckScriptFailure(lines, 'E1144: Command "Foo" is not followed by white space: Foo3Bar')
1115
1116  delcommand Foo
1117enddef
1118
1119def Test_star_command()
1120  var lines =<< trim END
1121    vim9script
1122    @s = 'g:success = 8'
1123    set cpo+=*
1124    exe '*s'
1125    assert_equal(8, g:success)
1126    unlet g:success
1127    set cpo-=*
1128    assert_fails("exe '*s'", 'E1050:')
1129  END
1130  CheckScriptSuccess(lines)
1131enddef
1132
1133def Test_cmd_argument_without_colon()
1134  new Xfile
1135  setline(1, ['a', 'b', 'c', 'd'])
1136  write
1137  edit +3 %
1138  assert_equal(3, getcurpos()[1])
1139  edit +/a %
1140  assert_equal(1, getcurpos()[1])
1141  bwipe
1142  delete('Xfile')
1143enddef
1144
1145def Test_ambiguous_user_cmd()
1146  command Cmd1 eval 0
1147  command Cmd2 eval 0
1148  var lines =<< trim END
1149      Cmd
1150  END
1151  CheckDefAndScriptFailure(lines, 'E464:', 1)
1152  delcommand Cmd1
1153  delcommand Cmd2
1154enddef
1155
1156def Test_command_not_recognized()
1157  var lines =<< trim END
1158    d.key = 'asdf'
1159  END
1160  CheckDefFailure(lines, 'E1146:', 1)
1161
1162  lines =<< trim END
1163    d['key'] = 'asdf'
1164  END
1165  CheckDefFailure(lines, 'E1146:', 1)
1166enddef
1167
1168def Test_magic_not_used()
1169  new
1170  for cmd in ['set magic', 'set nomagic']
1171    exe cmd
1172    setline(1, 'aaa')
1173    s/.../bbb/
1174    assert_equal('bbb', getline(1))
1175  endfor
1176
1177  set magic
1178  setline(1, 'aaa')
1179  assert_fails('s/.\M../bbb/', 'E486:')
1180  assert_fails('snomagic/.../bbb/', 'E486:')
1181  assert_equal('aaa', getline(1))
1182
1183  bwipe!
1184enddef
1185
1186def Test_gdefault_not_used()
1187  new
1188  for cmd in ['set gdefault', 'set nogdefault']
1189    exe cmd
1190    setline(1, 'aaa')
1191    s/./b/
1192    assert_equal('baa', getline(1))
1193  endfor
1194
1195  set nogdefault
1196  bwipe!
1197enddef
1198
1199def g:SomeComplFunc(findstart: number, base: string): any
1200  if findstart
1201    return 0
1202  else
1203    return ['aaa', 'bbb']
1204  endif
1205enddef
1206
1207def Test_insert_complete()
1208  # this was running into an error with the matchparen hack
1209  new
1210  set completefunc=SomeComplFunc
1211  feedkeys("i\<c-x>\<c-u>\<Esc>", 'ntx')
1212  assert_equal('aaa', getline(1))
1213
1214  set completefunc=
1215  bwipe!
1216enddef
1217
1218def Test_wincmd()
1219  split
1220  var id1 = win_getid()
1221  if true
1222    try | wincmd w | catch | endtry
1223  endif
1224  assert_notequal(id1, win_getid())
1225  close
1226
1227  split
1228  var id = win_getid()
1229  split
1230  :2wincmd o
1231  assert_equal(id, win_getid())
1232  only
1233
1234  split
1235  split
1236  assert_equal(3, winnr('$'))
1237  :2wincmd c
1238  assert_equal(2, winnr('$'))
1239  only
1240
1241  split
1242  split
1243  assert_equal(3, winnr('$'))
1244  :2wincmd q
1245  assert_equal(2, winnr('$'))
1246  only
1247enddef
1248
1249def Test_windo_missing_endif()
1250  var lines =<< trim END
1251      windo if 1
1252  END
1253  CheckDefExecFailure(lines, 'E171:', 1)
1254enddef
1255
1256let s:theList = [1, 2, 3]
1257
1258def Test_lockvar()
1259  s:theList[1] = 22
1260  assert_equal([1, 22, 3], s:theList)
1261  lockvar s:theList
1262  assert_fails('theList[1] = 77', 'E741:')
1263  unlockvar s:theList
1264  s:theList[1] = 44
1265  assert_equal([1, 44, 3], s:theList)
1266
1267  var d = {a: 1, b: 2}
1268  d.a = 3
1269  d.b = 4
1270  assert_equal({a: 3, b: 4}, d)
1271  lockvar d.a
1272  d.b = 5
1273  var ex = ''
1274  try
1275    d.a = 6
1276  catch
1277    ex = v:exception
1278  endtry
1279  assert_match('E1121:', ex)
1280  unlockvar d.a
1281  d.a = 7
1282  assert_equal({a: 7, b: 5}, d)
1283
1284  var lines =<< trim END
1285      vim9script
1286      var theList = [1, 2, 3]
1287      def SetList()
1288        theList[1] = 22
1289        assert_equal([1, 22, 3], theList)
1290        lockvar theList
1291        theList[1] = 77
1292      enddef
1293      SetList()
1294  END
1295  CheckScriptFailure(lines, 'E1119', 4)
1296
1297  lines =<< trim END
1298      var theList = [1, 2, 3]
1299      lockvar theList
1300  END
1301  CheckDefFailure(lines, 'E1178', 2)
1302
1303  lines =<< trim END
1304      var theList = [1, 2, 3]
1305      unlockvar theList
1306  END
1307  CheckDefFailure(lines, 'E1178', 2)
1308enddef
1309
1310def Test_substitute_expr()
1311  var to = 'repl'
1312  new
1313  setline(1, 'one from two')
1314  s/from/\=to
1315  assert_equal('one repl two', getline(1))
1316
1317  setline(1, 'one from two')
1318  s/from/\=to .. '_x'
1319  assert_equal('one repl_x two', getline(1))
1320
1321  setline(1, 'one from two from three')
1322  var also = 'also'
1323  s/from/\=to .. '_' .. also/g#e
1324  assert_equal('one repl_also two repl_also three', getline(1))
1325
1326  setline(1, 'abc abc abc')
1327  for choice in [true, false]
1328    :1s/abc/\=choice ? 'yes' : 'no'/
1329  endfor
1330  assert_equal('yes no abc', getline(1))
1331
1332  bwipe!
1333
1334  CheckDefFailure(['s/from/\="x")/'], 'E488:')
1335  CheckDefFailure(['s/from/\="x"/9'], 'E488:')
1336
1337  # When calling a function the right instruction list needs to be restored.
1338  g:cond = true
1339  var lines =<< trim END
1340      vim9script
1341      def Foo()
1342          Bar([])
1343      enddef
1344      def Bar(l: list<number>)
1345        if g:cond
1346          s/^/\=Rep()/
1347          for n in l[:]
1348          endfor
1349        endif
1350      enddef
1351      def Rep(): string
1352          return 'rep'
1353      enddef
1354      new
1355      Foo()
1356      assert_equal('rep', getline(1))
1357      bwipe!
1358  END
1359  CheckScriptSuccess(lines)
1360  unlet g:cond
1361
1362  # List results in multiple lines
1363  new
1364  setline(1, 'some text here')
1365  s/text/\=['aaa', 'bbb', 'ccc']/
1366  assert_equal(['some aaa', 'bbb', 'ccc', ' here'], getline(1, '$'))
1367  bwipe!
1368enddef
1369
1370def Test_redir_to_var()
1371  var result: string
1372  redir => result
1373    echo 'something'
1374  redir END
1375  assert_equal("\nsomething", result)
1376
1377  redir =>> result
1378    echo 'more'
1379  redir END
1380  assert_equal("\nsomething\nmore", result)
1381
1382  var d: dict<string>
1383  redir => d.redir
1384    echo 'dict'
1385  redir END
1386  assert_equal({redir: "\ndict"}, d)
1387
1388  var l = ['a', 'b', 'c']
1389  redir => l[1]
1390    echo 'list'
1391  redir END
1392  assert_equal(['a', "\nlist", 'c'], l)
1393
1394  var dl = {l: ['x']}
1395  redir => dl.l[0]
1396    echo 'dict-list'
1397  redir END
1398  assert_equal({l: ["\ndict-list"]}, dl)
1399
1400  redir =>> d.redir
1401    echo 'more'
1402  redir END
1403  assert_equal({redir: "\ndict\nmore"}, d)
1404
1405  var lines =<< trim END
1406    redir => notexist
1407  END
1408  CheckDefFailure(lines, 'E1089:')
1409
1410  lines =<< trim END
1411    var ls = 'asdf'
1412    redir => ls[1]
1413    redir END
1414  END
1415  CheckDefFailure(lines, 'E1141:')
1416enddef
1417
1418def Test_echo_void()
1419  var lines =<< trim END
1420      vim9script
1421      def NoReturn()
1422        echo 'nothing'
1423      enddef
1424      echo NoReturn()
1425  END
1426  CheckScriptFailure(lines, 'E1186:', 5)
1427
1428  lines =<< trim END
1429      vim9script
1430      def NoReturn()
1431        echo 'nothing'
1432      enddef
1433      def Try()
1434        echo NoReturn()
1435      enddef
1436      defcompile
1437  END
1438  CheckScriptFailure(lines, 'E1186:', 1)
1439enddef
1440
1441def Test_cmdwin_block()
1442  augroup justTesting
1443    autocmd BufEnter * {
1444      echomsg 'in block'
1445    }
1446  augroup END
1447  feedkeys('q:', 'xt')
1448  redraw
1449  feedkeys("aclose\<CR>", 'xt')
1450
1451  au! justTesting
1452enddef
1453
1454
1455" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
1456