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