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