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