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_skipped_expr_linebreak()
525  if 0
526    var x = []
527               ->map(() => 0)
528  endif
529enddef
530
531def Test_dict_member()
532   var test: dict<list<number>> = {data: [3, 1, 2]}
533   test.data->sort()
534   assert_equal({data: [1, 2, 3]}, test)
535   test.data
536      ->reverse()
537   assert_equal({data: [3, 2, 1]}, test)
538
539  var lines =<< trim END
540      vim9script
541      var test: dict<list<number>> = {data: [3, 1, 2]}
542      test.data->sort()
543      assert_equal({data: [1, 2, 3]}, test)
544  END
545  CheckScriptSuccess(lines)
546enddef
547
548def Test_bar_after_command()
549  def RedrawAndEcho()
550    var x = 'did redraw'
551    redraw | echo x
552  enddef
553  RedrawAndEcho()
554  assert_match('did redraw', Screenline(&lines))
555
556  def CallAndEcho()
557    var x = 'did redraw'
558    reg_executing() | echo x
559  enddef
560  CallAndEcho()
561  assert_match('did redraw', Screenline(&lines))
562
563  if has('unix')
564    # bar in filter write command does not start new command
565    def WriteToShell()
566      new
567      setline(1, 'some text')
568      w !cat | cat > Xoutfile
569      bwipe!
570    enddef
571    WriteToShell()
572    assert_equal(['some text'], readfile('Xoutfile'))
573    delete('Xoutfile')
574
575    # bar in filter read command does not start new command
576    def ReadFromShell()
577      new
578      r! echo hello there | cat > Xoutfile
579      r !echo again | cat >> Xoutfile
580      bwipe!
581    enddef
582    ReadFromShell()
583    assert_equal(['hello there', 'again'], readfile('Xoutfile'))
584    delete('Xoutfile')
585  endif
586enddef
587
588def Test_filter_is_not_modifier()
589  var tags = [{a: 1, b: 2}, {x: 3, y: 4}]
590  filter(tags, ( _, v) => has_key(v, 'x') ? 1 : 0 )
591  assert_equal([{x: 3, y: 4}], tags)
592enddef
593
594def Test_command_modifier_filter()
595  var lines =<< trim END
596    final expected = "\nType Name Content\n  c  \"c   piyo"
597    @a = 'hoge'
598    @b = 'fuga'
599    @c = 'piyo'
600
601    assert_equal(execute('filter /piyo/ registers abc'), expected)
602  END
603  CheckDefAndScriptSuccess(lines)
604
605  # also do this compiled
606  lines =<< trim END
607      @a = 'very specific z3d37dh234 string'
608      filter z3d37dh234 registers
609      assert_match('very specific z3d37dh234 string', Screenline(&lines))
610  END
611  CheckDefAndScriptSuccess(lines)
612enddef
613
614def Test_win_command_modifiers()
615  assert_equal(1, winnr('$'))
616
617  set splitright
618  vsplit
619  assert_equal(2, winnr())
620  close
621  aboveleft vsplit
622  assert_equal(1, winnr())
623  close
624  set splitright&
625
626  vsplit
627  assert_equal(1, winnr())
628  close
629  belowright vsplit
630  assert_equal(2, winnr())
631  close
632  rightbelow vsplit
633  assert_equal(2, winnr())
634  close
635
636  if has('browse')
637    browse set
638    assert_equal('option-window', expand('%'))
639    close
640  endif
641
642  vsplit
643  botright split
644  assert_equal(3, winnr())
645  assert_equal(&columns, winwidth(0))
646  close
647  close
648
649  vsplit
650  topleft split
651  assert_equal(1, winnr())
652  assert_equal(&columns, winwidth(0))
653  close
654  close
655
656  gettabinfo()->len()->assert_equal(1)
657  tab split
658  gettabinfo()->len()->assert_equal(2)
659  tabclose
660
661  vertical new
662  assert_inrange(&columns / 2 - 2, &columns / 2 + 1, winwidth(0))
663  close
664enddef
665
666func Test_command_modifier_confirm()
667  CheckNotGui
668  CheckRunVimInTerminal
669
670  " Test for saving all the modified buffers
671  let lines =<< trim END
672    call setline(1, 'changed')
673    def Getout()
674      confirm write Xfile
675    enddef
676  END
677  call writefile(lines, 'Xconfirmscript')
678  call writefile(['empty'], 'Xfile')
679  let buf = RunVimInTerminal('-S Xconfirmscript', {'rows': 8})
680  call term_sendkeys(buf, ":call Getout()\n")
681  call WaitForAssert({-> assert_match('(Y)es, \[N\]o: ', term_getline(buf, 8))}, 1000)
682  call term_sendkeys(buf, "y")
683  call WaitForAssert({-> assert_match('(Y)es, \[N\]o: ', term_getline(buf, 8))}, 1000)
684  call term_sendkeys(buf, "\<CR>")
685  call TermWait(buf)
686  call StopVimInTerminal(buf)
687
688  call assert_equal(['changed'], readfile('Xfile'))
689  call delete('Xfile')
690  call delete('.Xfile.swp')  " in case Vim was killed
691  call delete('Xconfirmscript')
692endfunc
693
694def Test_command_modifiers_keep()
695  if has('unix')
696    def DoTest(addRflag: bool, keepMarks: bool, hasMarks: bool)
697      new
698      setline(1, ['one', 'two', 'three'])
699      normal 1Gma
700      normal 2Gmb
701      normal 3Gmc
702      if addRflag
703        set cpo+=R
704      else
705        set cpo-=R
706      endif
707      if keepMarks
708        keepmarks :%!cat
709      else
710        :%!cat
711      endif
712      if hasMarks
713        assert_equal(1, line("'a"))
714        assert_equal(2, line("'b"))
715        assert_equal(3, line("'c"))
716      else
717        assert_equal(0, line("'a"))
718        assert_equal(0, line("'b"))
719        assert_equal(0, line("'c"))
720      endif
721      quit!
722    enddef
723    DoTest(false, false, true)
724    DoTest(true, false, false)
725    DoTest(false, true, true)
726    DoTest(true, true, true)
727    set cpo&vim
728
729    new
730    setline(1, ['one', 'two', 'three', 'four'])
731    assert_equal(4, line("$"))
732    normal 1Gma
733    normal 2Gmb
734    normal 3Gmc
735    lockmarks :1,2!wc
736    # line is deleted, marks don't move
737    assert_equal(3, line("$"))
738    assert_equal('four', getline(3))
739    assert_equal(1, line("'a"))
740    assert_equal(2, line("'b"))
741    assert_equal(3, line("'c"))
742    quit!
743  endif
744
745  edit Xone
746  edit Xtwo
747  assert_equal('Xone', expand('#'))
748  keepalt edit Xthree
749  assert_equal('Xone', expand('#'))
750
751  normal /a*b*
752  assert_equal('a*b*', histget("search"))
753  keeppatterns normal /c*d*
754  assert_equal('a*b*', histget("search"))
755
756  new
757  setline(1, range(10))
758  :10
759  normal gg
760  assert_equal(10, getpos("''")[1])
761  keepjumps normal 5G
762  assert_equal(10, getpos("''")[1])
763  quit!
764enddef
765
766def Test_bar_line_continuation()
767  var lines =<< trim END
768      au BufNewFile Xfile g:readFile = 1
769          | g:readExtra = 2
770      g:readFile = 0
771      g:readExtra = 0
772      edit Xfile
773      assert_equal(1, g:readFile)
774      assert_equal(2, g:readExtra)
775      bwipe!
776      au! BufNewFile
777
778      au BufNewFile Xfile g:readFile = 1
779          | g:readExtra = 2
780          | g:readMore = 3
781      g:readFile = 0
782      g:readExtra = 0
783      g:readMore = 0
784      edit Xfile
785      assert_equal(1, g:readFile)
786      assert_equal(2, g:readExtra)
787      assert_equal(3, g:readMore)
788      bwipe!
789      au! BufNewFile
790      unlet g:readFile
791      unlet g:readExtra
792      unlet g:readMore
793  END
794  CheckDefAndScriptSuccess(lines)
795enddef
796
797def Test_command_modifier_other()
798  new Xsomefile
799  setline(1, 'changed')
800  var buf = bufnr()
801  hide edit Xotherfile
802  var info = getbufinfo(buf)
803  assert_equal(1, info[0].hidden)
804  assert_equal(1, info[0].changed)
805  edit Xsomefile
806  bwipe!
807
808  au BufNewFile Xfile g:readFile = 1
809  g:readFile = 0
810  edit Xfile
811  assert_equal(1, g:readFile)
812  bwipe!
813  g:readFile = 0
814  noautocmd edit Xfile
815  assert_equal(0, g:readFile)
816  au! BufNewFile
817  unlet g:readFile
818
819  noswapfile edit XnoSwap
820  assert_equal(false, &l:swapfile)
821  bwipe!
822
823  var caught = false
824  try
825    sandbox !ls
826  catch /E48:/
827    caught = true
828  endtry
829  assert_true(caught)
830
831  :8verbose g:verbose_now = &verbose
832  assert_equal(8, g:verbose_now)
833  unlet g:verbose_now
834enddef
835
836def EchoHere()
837  echomsg 'here'
838enddef
839def EchoThere()
840  unsilent echomsg 'there'
841enddef
842
843def Test_modifier_silent_unsilent()
844  echomsg 'last one'
845  silent echomsg "text"
846  assert_equal("\nlast one", execute(':1messages'))
847
848  silent! echoerr "error"
849
850  echomsg 'last one'
851  silent EchoHere()
852  assert_equal("\nlast one", execute(':1messages'))
853
854  silent EchoThere()
855  assert_equal("\nthere", execute(':1messages'))
856
857  try
858    silent eval [][0]
859  catch
860    echomsg "caught"
861  endtry
862  assert_equal("\ncaught", execute(':1messages'))
863
864  var lines =<< trim END
865      vim9script
866      set history=11
867      silent! while 0
868        set history=22
869      silent! endwhile
870      assert_equal(11, &history)
871      set history&
872  END
873  CheckScriptSuccess(lines)
874enddef
875
876def Test_range_after_command_modifier()
877  CheckScriptFailure(['vim9script', 'silent keepjump 1d _'], 'E1050: Colon required before a range: 1d _', 2)
878  new
879  setline(1, 'xxx')
880  CheckScriptSuccess(['vim9script', 'silent keepjump :1d _'])
881  assert_equal('', getline(1))
882  bwipe!
883enddef
884
885def Test_silent_pattern()
886  new
887  silent! :/pat/put _
888  bwipe!
889enddef
890
891def Test_useless_command_modifier()
892  g:maybe = true
893  var lines =<< trim END
894      if g:maybe
895      silent endif
896  END
897  CheckDefAndScriptFailure(lines, 'E1176:', 2)
898
899  lines =<< trim END
900      for i in [0]
901      silent endfor
902  END
903  CheckDefFailure(lines, 'E1176:', 2)
904  CheckScriptSuccess(['vim9script'] + lines)
905
906  lines =<< trim END
907      while g:maybe
908      silent endwhile
909  END
910  CheckDefFailure(lines, 'E1176:', 2)
911  g:maybe = false
912  CheckScriptSuccess(['vim9script'] + lines)
913
914  lines =<< trim END
915      silent try
916      finally
917      endtry
918  END
919  CheckDefAndScriptFailure(lines, 'E1176:', 1)
920
921  lines =<< trim END
922      try
923      silent catch
924      endtry
925  END
926  CheckDefAndScriptFailure(lines, 'E1176:', 2)
927
928  lines =<< trim END
929      try
930      silent finally
931      endtry
932  END
933  CheckDefAndScriptFailure(lines, 'E1176:', 2)
934
935  lines =<< trim END
936      try
937      finally
938      silent endtry
939  END
940  CheckDefAndScriptFailure(lines, 'E1176:', 3)
941enddef
942
943def Test_eval_command()
944  var from = 3
945  var to = 5
946  g:val = 111
947  def Increment(nrs: list<number>)
948    for nr in nrs
949      g:val += nr
950    endfor
951  enddef
952  eval range(from, to)
953        ->Increment()
954  assert_equal(111 + 3 + 4 + 5, g:val)
955  unlet g:val
956
957  var lines =<< trim END
958    vim9script
959    g:caught = 'no'
960    try
961      eval 123 || 0
962    catch
963      g:caught = 'yes'
964    endtry
965    assert_equal('yes', g:caught)
966    unlet g:caught
967  END
968  CheckScriptSuccess(lines)
969enddef
970
971def Test_map_command()
972  var lines =<< trim END
973      nnoremap <F3> :echo 'hit F3 #'<CR>
974      assert_equal(":echo 'hit F3 #'<CR>", maparg("<F3>", "n"))
975  END
976  CheckDefSuccess(lines)
977  CheckScriptSuccess(['vim9script'] + lines)
978enddef
979
980def Test_normal_command()
981  new
982  setline(1, 'doesnotexist')
983  var caught = 0
984  try
985    exe "norm! \<C-]>"
986  catch /E433/
987    caught = 2
988  endtry
989  assert_equal(2, caught)
990
991  try
992    exe "norm! 3\<C-]>"
993  catch /E433/
994    caught = 3
995  endtry
996  assert_equal(3, caught)
997  bwipe!
998enddef
999
1000def Test_put_command()
1001  new
1002  @p = 'ppp'
1003  put p
1004  assert_equal('ppp', getline(2))
1005
1006  put ='below'
1007  assert_equal('below', getline(3))
1008  put! ='above'
1009  assert_equal('above', getline(3))
1010  assert_equal('below', getline(4))
1011
1012  :2put =['a', 'b', 'c']
1013  assert_equal(['ppp', 'a', 'b', 'c', 'above'], getline(2, 6))
1014
1015  # compute range at runtime
1016  setline(1, range(1, 8))
1017  @a = 'aaa'
1018  :$-2put a
1019  assert_equal('aaa', getline(7))
1020
1021  setline(1, range(1, 8))
1022  :2
1023  :+2put! a
1024  assert_equal('aaa', getline(4))
1025
1026  []->mapnew(() => 0)
1027  :$put ='end'
1028  assert_equal('end', getline('$'))
1029
1030  bwipe!
1031
1032  CheckDefFailure(['put =xxx'], 'E1001:')
1033enddef
1034
1035def Test_put_with_linebreak()
1036  new
1037  var lines =<< trim END
1038    vim9script
1039    pu =split('abc', '\zs')
1040            ->join()
1041  END
1042  CheckScriptSuccess(lines)
1043  getline(2)->assert_equal('a b c')
1044  bwipe!
1045enddef
1046
1047def Test_command_star_range()
1048  new
1049  setline(1, ['xxx foo xxx', 'xxx bar xxx', 'xxx foo xx bar'])
1050  setpos("'<", [0, 1, 0, 0])
1051  setpos("'>", [0, 3, 0, 0])
1052  :*s/\(foo\|bar\)/baz/g
1053  getline(1, 3)->assert_equal(['xxx baz xxx', 'xxx baz xxx', 'xxx baz xx baz'])
1054
1055  bwipe!
1056enddef
1057
1058def Test_f_args()
1059  var lines =<< trim END
1060    vim9script
1061
1062    func SaveCmdArgs(...)
1063      let g:args = a:000
1064    endfunc
1065
1066    command -nargs=* TestFArgs call SaveCmdArgs(<f-args>)
1067
1068    TestFArgs
1069    assert_equal([], g:args)
1070
1071    TestFArgs one two three
1072    assert_equal(['one', 'two', 'three'], g:args)
1073  END
1074  CheckScriptSuccess(lines)
1075enddef
1076
1077def Test_user_command_comment()
1078  command -nargs=1 Comd echom <q-args>
1079
1080  var lines =<< trim END
1081      vim9script
1082      Comd # comment
1083  END
1084  CheckScriptSuccess(lines)
1085
1086  lines =<< trim END
1087      vim9script
1088      Comd# comment
1089  END
1090  CheckScriptFailure(lines, 'E1144:')
1091  delcommand Comd
1092
1093  lines =<< trim END
1094      vim9script
1095      command Foo echo 'Foo'
1096      Foo3Bar
1097  END
1098  CheckScriptFailure(lines, 'E1144: Command "Foo" is not followed by white space: Foo3Bar')
1099
1100  delcommand Foo
1101enddef
1102
1103def Test_star_command()
1104  var lines =<< trim END
1105    vim9script
1106    @s = 'g:success = 8'
1107    set cpo+=*
1108    exe '*s'
1109    assert_equal(8, g:success)
1110    unlet g:success
1111    set cpo-=*
1112    assert_fails("exe '*s'", 'E1050:')
1113  END
1114  CheckScriptSuccess(lines)
1115enddef
1116
1117def Test_cmd_argument_without_colon()
1118  new Xfile
1119  setline(1, ['a', 'b', 'c', 'd'])
1120  write
1121  edit +3 %
1122  assert_equal(3, getcurpos()[1])
1123  edit +/a %
1124  assert_equal(1, getcurpos()[1])
1125  bwipe
1126  delete('Xfile')
1127enddef
1128
1129def Test_ambiguous_user_cmd()
1130  command Cmd1 eval 0
1131  command Cmd2 eval 0
1132  var lines =<< trim END
1133      Cmd
1134  END
1135  CheckDefAndScriptFailure(lines, 'E464:', 1)
1136  delcommand Cmd1
1137  delcommand Cmd2
1138enddef
1139
1140def Test_command_not_recognized()
1141  var lines =<< trim END
1142    d.key = 'asdf'
1143  END
1144  CheckDefFailure(lines, 'E1146:', 1)
1145
1146  lines =<< trim END
1147    d['key'] = 'asdf'
1148  END
1149  CheckDefFailure(lines, 'E1146:', 1)
1150enddef
1151
1152def Test_magic_not_used()
1153  new
1154  for cmd in ['set magic', 'set nomagic']
1155    exe cmd
1156    setline(1, 'aaa')
1157    s/.../bbb/
1158    assert_equal('bbb', getline(1))
1159  endfor
1160
1161  set magic
1162  setline(1, 'aaa')
1163  assert_fails('s/.\M../bbb/', 'E486:')
1164  assert_fails('snomagic/.../bbb/', 'E486:')
1165  assert_equal('aaa', getline(1))
1166
1167  bwipe!
1168enddef
1169
1170def Test_gdefault_not_used()
1171  new
1172  for cmd in ['set gdefault', 'set nogdefault']
1173    exe cmd
1174    setline(1, 'aaa')
1175    s/./b/
1176    assert_equal('baa', getline(1))
1177  endfor
1178
1179  set nogdefault
1180  bwipe!
1181enddef
1182
1183def g:SomeComplFunc(findstart: number, base: string): any
1184  if findstart
1185    return 0
1186  else
1187    return ['aaa', 'bbb']
1188  endif
1189enddef
1190
1191def Test_insert_complete()
1192  # this was running into an error with the matchparen hack
1193  new
1194  set completefunc=SomeComplFunc
1195  feedkeys("i\<c-x>\<c-u>\<Esc>", 'ntx')
1196  assert_equal('aaa', getline(1))
1197
1198  set completefunc=
1199  bwipe!
1200enddef
1201
1202def Test_wincmd()
1203  split
1204  var id1 = win_getid()
1205  if true
1206    try | wincmd w | catch | endtry
1207  endif
1208  assert_notequal(id1, win_getid())
1209  close
1210
1211  split
1212  var id = win_getid()
1213  split
1214  :2wincmd o
1215  assert_equal(id, win_getid())
1216  only
1217
1218  split
1219  split
1220  assert_equal(3, winnr('$'))
1221  :2wincmd c
1222  assert_equal(2, winnr('$'))
1223  only
1224
1225  split
1226  split
1227  assert_equal(3, winnr('$'))
1228  :2wincmd q
1229  assert_equal(2, winnr('$'))
1230  only
1231enddef
1232
1233def Test_windo_missing_endif()
1234  var lines =<< trim END
1235      windo if 1
1236  END
1237  CheckDefExecFailure(lines, 'E171:', 1)
1238enddef
1239
1240let s:theList = [1, 2, 3]
1241
1242def Test_lockvar()
1243  s:theList[1] = 22
1244  assert_equal([1, 22, 3], s:theList)
1245  lockvar s:theList
1246  assert_fails('theList[1] = 77', 'E741:')
1247  unlockvar s:theList
1248  s:theList[1] = 44
1249  assert_equal([1, 44, 3], s:theList)
1250
1251  var d = {a: 1, b: 2}
1252  d.a = 3
1253  d.b = 4
1254  assert_equal({a: 3, b: 4}, d)
1255  lockvar d.a
1256  d.b = 5
1257  var ex = ''
1258  try
1259    d.a = 6
1260  catch
1261    ex = v:exception
1262  endtry
1263  assert_match('E1121:', ex)
1264  unlockvar d.a
1265  d.a = 7
1266  assert_equal({a: 7, b: 5}, d)
1267
1268  var lines =<< trim END
1269      vim9script
1270      var theList = [1, 2, 3]
1271      def SetList()
1272        theList[1] = 22
1273        assert_equal([1, 22, 3], theList)
1274        lockvar theList
1275        theList[1] = 77
1276      enddef
1277      SetList()
1278  END
1279  CheckScriptFailure(lines, 'E1119', 4)
1280
1281  lines =<< trim END
1282      var theList = [1, 2, 3]
1283      lockvar theList
1284  END
1285  CheckDefFailure(lines, 'E1178', 2)
1286
1287  lines =<< trim END
1288      var theList = [1, 2, 3]
1289      unlockvar theList
1290  END
1291  CheckDefFailure(lines, 'E1178', 2)
1292enddef
1293
1294def Test_substitute_expr()
1295  var to = 'repl'
1296  new
1297  setline(1, 'one from two')
1298  s/from/\=to
1299  assert_equal('one repl two', getline(1))
1300
1301  setline(1, 'one from two')
1302  s/from/\=to .. '_x'
1303  assert_equal('one repl_x two', getline(1))
1304
1305  setline(1, 'one from two from three')
1306  var also = 'also'
1307  s/from/\=to .. '_' .. also/g#e
1308  assert_equal('one repl_also two repl_also three', getline(1))
1309
1310  setline(1, 'abc abc abc')
1311  for choice in [true, false]
1312    :1s/abc/\=choice ? 'yes' : 'no'/
1313  endfor
1314  assert_equal('yes no abc', getline(1))
1315
1316  bwipe!
1317
1318  CheckDefFailure(['s/from/\="x")/'], 'E488:')
1319  CheckDefFailure(['s/from/\="x"/9'], 'E488:')
1320
1321  # When calling a function the right instruction list needs to be restored.
1322  g:cond = true
1323  var lines =<< trim END
1324      vim9script
1325      def Foo()
1326          Bar([])
1327      enddef
1328      def Bar(l: list<number>)
1329        if g:cond
1330          s/^/\=Rep()/
1331          for n in l[:]
1332          endfor
1333        endif
1334      enddef
1335      def Rep(): string
1336          return 'rep'
1337      enddef
1338      new
1339      Foo()
1340      assert_equal('rep', getline(1))
1341      bwipe!
1342  END
1343  CheckScriptSuccess(lines)
1344  unlet g:cond
1345
1346  # List results in multiple lines
1347  new
1348  setline(1, 'some text here')
1349  s/text/\=['aaa', 'bbb', 'ccc']/
1350  assert_equal(['some aaa', 'bbb', 'ccc', ' here'], getline(1, '$'))
1351  bwipe!
1352enddef
1353
1354def Test_redir_to_var()
1355  var result: string
1356  redir => result
1357    echo 'something'
1358  redir END
1359  assert_equal("\nsomething", result)
1360
1361  redir =>> result
1362    echo 'more'
1363  redir END
1364  assert_equal("\nsomething\nmore", result)
1365
1366  var d: dict<string>
1367  redir => d.redir
1368    echo 'dict'
1369  redir END
1370  assert_equal({redir: "\ndict"}, d)
1371
1372  var l = ['a', 'b', 'c']
1373  redir => l[1]
1374    echo 'list'
1375  redir END
1376  assert_equal(['a', "\nlist", 'c'], l)
1377
1378  var dl = {l: ['x']}
1379  redir => dl.l[0]
1380    echo 'dict-list'
1381  redir END
1382  assert_equal({l: ["\ndict-list"]}, dl)
1383
1384  redir =>> d.redir
1385    echo 'more'
1386  redir END
1387  assert_equal({redir: "\ndict\nmore"}, d)
1388
1389  var lines =<< trim END
1390    redir => notexist
1391  END
1392  CheckDefFailure(lines, 'E1089:')
1393
1394  lines =<< trim END
1395    var ls = 'asdf'
1396    redir => ls[1]
1397    redir END
1398  END
1399  CheckDefFailure(lines, 'E1141:')
1400enddef
1401
1402def Test_echo_void()
1403  var lines =<< trim END
1404      vim9script
1405      def NoReturn()
1406        echo 'nothing'
1407      enddef
1408      echo NoReturn()
1409  END
1410  CheckScriptFailure(lines, 'E1186:', 5)
1411
1412  lines =<< trim END
1413      vim9script
1414      def NoReturn()
1415        echo 'nothing'
1416      enddef
1417      def Try()
1418        echo NoReturn()
1419      enddef
1420      defcompile
1421  END
1422  CheckScriptFailure(lines, 'E1186:', 1)
1423enddef
1424
1425def Test_cmdwin_block()
1426  augroup justTesting
1427    autocmd BufEnter * {
1428      echomsg 'in block'
1429    }
1430  augroup END
1431  feedkeys('q:', 'xt')
1432  redraw
1433  feedkeys("aclose\<CR>", 'xt')
1434
1435  au! justTesting
1436enddef
1437
1438
1439" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
1440