15deeb3f1SBram Moolenaar" Test various aspects of the Vim9 script language.
25deeb3f1SBram Moolenaar
35deeb3f1SBram Moolenaarsource check.vim
4ad304706SBram Moolenaarsource term_util.vim
55deeb3f1SBram Moolenaarsource view_util.vim
604b12697SBram Moolenaarsource vim9.vim
747e7d70bSBram Moolenaarsource screendump.vim
85deeb3f1SBram Moolenaar
95deeb3f1SBram Moolenaarfunc Test_def_basic()
105deeb3f1SBram Moolenaar  def SomeFunc(): string
115deeb3f1SBram Moolenaar    return 'yes'
125deeb3f1SBram Moolenaar  enddef
13c0c71e9dSBram Moolenaar  call SomeFunc()->assert_equal('yes')
145deeb3f1SBram Moolenaarendfunc
155deeb3f1SBram Moolenaar
162b9b17eaSBram Moolenaarfunc Test_compiling_error()
172b9b17eaSBram Moolenaar  " use a terminal to see the whole error message
18f4e8cdd3SBram Moolenaar  CheckRunVimInTerminal
19f4e8cdd3SBram Moolenaar
202b9b17eaSBram Moolenaar  call TestCompilingError()
21e8c4660aSBram Moolenaar  call TestCompilingErrorInTry()
222b9b17eaSBram Moolenaarendfunc
232b9b17eaSBram Moolenaar
242b9b17eaSBram Moolenaardef TestCompilingError()
25f4e8cdd3SBram Moolenaar  var lines =<< trim END
26f4e8cdd3SBram Moolenaar    vim9script
27f4e8cdd3SBram Moolenaar    def Fails()
28f4e8cdd3SBram Moolenaar      echo nothing
29f4e8cdd3SBram Moolenaar    enddef
30f4e8cdd3SBram Moolenaar    defcompile
31f4e8cdd3SBram Moolenaar  END
32e8c4660aSBram Moolenaar  writefile(lines, 'XTest_compile_error')
33f4e8cdd3SBram Moolenaar  var buf = RunVimInTerminal('-S XTest_compile_error',
34e0de171eSBram Moolenaar              {rows: 10, wait_for_ruler: 0})
35e8c4660aSBram Moolenaar  WaitForAssert(() => assert_match('Error detected while compiling command line.*Fails.*Variable not found: nothing',
3603dfde2bSBram Moolenaar                     Term_getlines(buf, range(1, 9))))
37f4e8cdd3SBram Moolenaar
38f4e8cdd3SBram Moolenaar  # clean up
39e8c4660aSBram Moolenaar  StopVimInTerminal(buf)
40e8c4660aSBram Moolenaar  delete('XTest_compile_error')
41e8c4660aSBram Moolenaarenddef
42e8c4660aSBram Moolenaar
43e8c4660aSBram Moolenaardef TestCompilingErrorInTry()
44e8c4660aSBram Moolenaar  var dir = 'Xdir/autoload'
45e8c4660aSBram Moolenaar  mkdir(dir, 'p')
46e8c4660aSBram Moolenaar
47e8c4660aSBram Moolenaar  var lines =<< trim END
48e8c4660aSBram Moolenaar      vim9script
49e8c4660aSBram Moolenaar      def script#OnlyCompiled()
50e8c4660aSBram Moolenaar        g:runtime = 'yes'
51e8c4660aSBram Moolenaar        invalid
52e8c4660aSBram Moolenaar      enddef
53e8c4660aSBram Moolenaar  END
54e8c4660aSBram Moolenaar  writefile(lines, dir .. '/script.vim')
55e8c4660aSBram Moolenaar
56e8c4660aSBram Moolenaar  lines =<< trim END
57e8c4660aSBram Moolenaar      vim9script
58e8c4660aSBram Moolenaar      todo
59e8c4660aSBram Moolenaar      try
60e8c4660aSBram Moolenaar        script#OnlyCompiled()
61e8c4660aSBram Moolenaar      catch /nothing/
62e8c4660aSBram Moolenaar      endtry
63e8c4660aSBram Moolenaar  END
64e8c4660aSBram Moolenaar  lines[1] = 'set rtp=' .. getcwd() .. '/Xdir'
65e8c4660aSBram Moolenaar  writefile(lines, 'XTest_compile_error')
66e8c4660aSBram Moolenaar
67e8c4660aSBram Moolenaar  var buf = RunVimInTerminal('-S XTest_compile_error', {rows: 10, wait_for_ruler: 0})
68e8c4660aSBram Moolenaar  WaitForAssert(() => assert_match('Error detected while compiling command line.*function script#OnlyCompiled.*Invalid command: invalid',
69e8c4660aSBram Moolenaar                     Term_getlines(buf, range(1, 9))))
70e8c4660aSBram Moolenaar
71e8c4660aSBram Moolenaar  # clean up
72e8c4660aSBram Moolenaar  StopVimInTerminal(buf)
73e8c4660aSBram Moolenaar  delete('XTest_compile_error')
74e8c4660aSBram Moolenaar  delete('Xdir', 'rf')
75f4e8cdd3SBram Moolenaarenddef
76f4e8cdd3SBram Moolenaar
770ba48e8cSBram Moolenaardef CallRecursive(n: number): number
780ba48e8cSBram Moolenaar  return CallRecursive(n + 1)
790ba48e8cSBram Moolenaarenddef
800ba48e8cSBram Moolenaar
810ba48e8cSBram Moolenaardef CallMapRecursive(l: list<number>): number
822949cfdbSBram Moolenaar  return map(l, (_, v) => CallMapRecursive([v]))[0]
830ba48e8cSBram Moolenaarenddef
840ba48e8cSBram Moolenaar
850ba48e8cSBram Moolenaardef Test_funcdepth_error()
860ba48e8cSBram Moolenaar  set maxfuncdepth=10
870ba48e8cSBram Moolenaar
880ba48e8cSBram Moolenaar  var caught = false
890ba48e8cSBram Moolenaar  try
900ba48e8cSBram Moolenaar    CallRecursive(1)
910ba48e8cSBram Moolenaar  catch /E132:/
920ba48e8cSBram Moolenaar    caught = true
930ba48e8cSBram Moolenaar  endtry
940ba48e8cSBram Moolenaar  assert_true(caught)
950ba48e8cSBram Moolenaar
960ba48e8cSBram Moolenaar  caught = false
970ba48e8cSBram Moolenaar  try
980ba48e8cSBram Moolenaar    CallMapRecursive([1])
990ba48e8cSBram Moolenaar  catch /E132:/
1000ba48e8cSBram Moolenaar    caught = true
1010ba48e8cSBram Moolenaar  endtry
1020ba48e8cSBram Moolenaar  assert_true(caught)
1030ba48e8cSBram Moolenaar
1040ba48e8cSBram Moolenaar  set maxfuncdepth&
1050ba48e8cSBram Moolenaarenddef
1060ba48e8cSBram Moolenaar
1075178b1b0SBram Moolenaardef Test_endfunc_enddef()
1085178b1b0SBram Moolenaar  var lines =<< trim END
1095178b1b0SBram Moolenaar    def Test()
1105178b1b0SBram Moolenaar      echo 'test'
1115178b1b0SBram Moolenaar      endfunc
1125178b1b0SBram Moolenaar    enddef
1135178b1b0SBram Moolenaar  END
1145178b1b0SBram Moolenaar  CheckScriptFailure(lines, 'E1151:', 3)
1155178b1b0SBram Moolenaar
1165178b1b0SBram Moolenaar  lines =<< trim END
1175178b1b0SBram Moolenaar    def Test()
1185178b1b0SBram Moolenaar      func Nested()
1195178b1b0SBram Moolenaar        echo 'test'
1205178b1b0SBram Moolenaar      enddef
1215178b1b0SBram Moolenaar    enddef
1225178b1b0SBram Moolenaar  END
1235178b1b0SBram Moolenaar  CheckScriptFailure(lines, 'E1152:', 4)
12449f1e9ecSBram Moolenaar
12549f1e9ecSBram Moolenaar  lines =<< trim END
12649f1e9ecSBram Moolenaar    def Ok()
12749f1e9ecSBram Moolenaar      echo 'hello'
12849f1e9ecSBram Moolenaar    enddef | echo 'there'
12949f1e9ecSBram Moolenaar    def Bad()
13049f1e9ecSBram Moolenaar      echo 'hello'
13149f1e9ecSBram Moolenaar    enddef there
13249f1e9ecSBram Moolenaar  END
13349f1e9ecSBram Moolenaar  CheckScriptFailure(lines, 'E1173: Text found after enddef: there', 6)
1345178b1b0SBram Moolenaarenddef
1355178b1b0SBram Moolenaar
136b8ba9b91SBram Moolenaardef Test_missing_endfunc_enddef()
137b8ba9b91SBram Moolenaar  var lines =<< trim END
138b8ba9b91SBram Moolenaar    vim9script
139b8ba9b91SBram Moolenaar    def Test()
140b8ba9b91SBram Moolenaar      echo 'test'
141b8ba9b91SBram Moolenaar    endef
142b8ba9b91SBram Moolenaar  END
143b8ba9b91SBram Moolenaar  CheckScriptFailure(lines, 'E1057:', 2)
144b8ba9b91SBram Moolenaar
145b8ba9b91SBram Moolenaar  lines =<< trim END
146b8ba9b91SBram Moolenaar    vim9script
147b8ba9b91SBram Moolenaar    func Some()
148b8ba9b91SBram Moolenaar      echo 'test'
149b8ba9b91SBram Moolenaar    enfffunc
150b8ba9b91SBram Moolenaar  END
151b8ba9b91SBram Moolenaar  CheckScriptFailure(lines, 'E126:', 2)
152b8ba9b91SBram Moolenaarenddef
153b8ba9b91SBram Moolenaar
1544efd9948SBram Moolenaardef Test_white_space_before_paren()
1554efd9948SBram Moolenaar  var lines =<< trim END
1564efd9948SBram Moolenaar    vim9script
1574efd9948SBram Moolenaar    def Test ()
1584efd9948SBram Moolenaar      echo 'test'
1594efd9948SBram Moolenaar    enddef
1604efd9948SBram Moolenaar  END
1614efd9948SBram Moolenaar  CheckScriptFailure(lines, 'E1068:', 2)
1624efd9948SBram Moolenaar
1634efd9948SBram Moolenaar  lines =<< trim END
1644efd9948SBram Moolenaar    vim9script
1654efd9948SBram Moolenaar    func Test ()
1664efd9948SBram Moolenaar      echo 'test'
1674efd9948SBram Moolenaar    endfunc
1684efd9948SBram Moolenaar  END
1694efd9948SBram Moolenaar  CheckScriptFailure(lines, 'E1068:', 2)
1704efd9948SBram Moolenaar
1714efd9948SBram Moolenaar  lines =<< trim END
1724efd9948SBram Moolenaar    def Test ()
1734efd9948SBram Moolenaar      echo 'test'
1744efd9948SBram Moolenaar    enddef
1754efd9948SBram Moolenaar  END
1764efd9948SBram Moolenaar  CheckScriptFailure(lines, 'E1068:', 1)
1774efd9948SBram Moolenaar
1784efd9948SBram Moolenaar  lines =<< trim END
1794efd9948SBram Moolenaar    func Test ()
1804efd9948SBram Moolenaar      echo 'test'
1814efd9948SBram Moolenaar    endfunc
1824efd9948SBram Moolenaar  END
1834efd9948SBram Moolenaar  CheckScriptSuccess(lines)
1844efd9948SBram Moolenaarenddef
1854efd9948SBram Moolenaar
186832ea89cSBram Moolenaardef Test_enddef_dict_key()
187832ea89cSBram Moolenaar  var d = {
188832ea89cSBram Moolenaar    enddef: 'x',
189832ea89cSBram Moolenaar    endfunc: 'y',
190832ea89cSBram Moolenaar  }
191832ea89cSBram Moolenaar  assert_equal({enddef: 'x', endfunc: 'y'}, d)
192832ea89cSBram Moolenaarenddef
193832ea89cSBram Moolenaar
1945deeb3f1SBram Moolenaardef ReturnString(): string
1955deeb3f1SBram Moolenaar  return 'string'
1965deeb3f1SBram Moolenaarenddef
1975deeb3f1SBram Moolenaar
1985deeb3f1SBram Moolenaardef ReturnNumber(): number
1995deeb3f1SBram Moolenaar  return 123
2005deeb3f1SBram Moolenaarenddef
2015deeb3f1SBram Moolenaar
2025deeb3f1SBram Moolenaarlet g:notNumber = 'string'
2035deeb3f1SBram Moolenaar
2045deeb3f1SBram Moolenaardef ReturnGlobal(): number
2055deeb3f1SBram Moolenaar  return g:notNumber
2065deeb3f1SBram Moolenaarenddef
2075deeb3f1SBram Moolenaar
2085deeb3f1SBram Moolenaardef Test_return_something()
209c0c71e9dSBram Moolenaar  ReturnString()->assert_equal('string')
210c0c71e9dSBram Moolenaar  ReturnNumber()->assert_equal(123)
2115e654230SBram Moolenaar  assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal')
2125deeb3f1SBram Moolenaarenddef
2135deeb3f1SBram Moolenaar
214e32e516dSBram Moolenaardef Test_check_argument_type()
215e32e516dSBram Moolenaar  var lines =<< trim END
216e32e516dSBram Moolenaar      vim9script
217e32e516dSBram Moolenaar      def Val(a: number, b: number): number
218e32e516dSBram Moolenaar        return 0
219e32e516dSBram Moolenaar      enddef
220e32e516dSBram Moolenaar      def Func()
221e32e516dSBram Moolenaar        var x: any = true
222e32e516dSBram Moolenaar        Val(0, x)
223e32e516dSBram Moolenaar      enddef
224e32e516dSBram Moolenaar      disass Func
225e32e516dSBram Moolenaar      Func()
226e32e516dSBram Moolenaar  END
227e32e516dSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got bool', 2)
228e32e516dSBram Moolenaarenddef
229e32e516dSBram Moolenaar
230efd88555SBram Moolenaardef Test_missing_return()
231efd88555SBram Moolenaar  CheckDefFailure(['def Missing(): number',
232efd88555SBram Moolenaar                   '  if g:cond',
233efd88555SBram Moolenaar                   '    echo "no return"',
234efd88555SBram Moolenaar                   '  else',
235efd88555SBram Moolenaar                   '    return 0',
236efd88555SBram Moolenaar                   '  endif'
237efd88555SBram Moolenaar                   'enddef'], 'E1027:')
238efd88555SBram Moolenaar  CheckDefFailure(['def Missing(): number',
239efd88555SBram Moolenaar                   '  if g:cond',
240efd88555SBram Moolenaar                   '    return 1',
241efd88555SBram Moolenaar                   '  else',
242efd88555SBram Moolenaar                   '    echo "no return"',
243efd88555SBram Moolenaar                   '  endif'
244efd88555SBram Moolenaar                   'enddef'], 'E1027:')
245efd88555SBram Moolenaar  CheckDefFailure(['def Missing(): number',
246efd88555SBram Moolenaar                   '  if g:cond',
247efd88555SBram Moolenaar                   '    return 1',
248efd88555SBram Moolenaar                   '  else',
249efd88555SBram Moolenaar                   '    return 2',
250efd88555SBram Moolenaar                   '  endif'
251efd88555SBram Moolenaar                   '  return 3'
252efd88555SBram Moolenaar                   'enddef'], 'E1095:')
253efd88555SBram Moolenaarenddef
254efd88555SBram Moolenaar
255403dc31fSBram Moolenaardef Test_return_bool()
256403dc31fSBram Moolenaar  var lines =<< trim END
257403dc31fSBram Moolenaar      vim9script
258403dc31fSBram Moolenaar      def MenuFilter(id: number, key: string): bool
259403dc31fSBram Moolenaar        return popup_filter_menu(id, key)
260403dc31fSBram Moolenaar      enddef
261403dc31fSBram Moolenaar      def YesnoFilter(id: number, key: string): bool
262403dc31fSBram Moolenaar        return popup_filter_yesno(id, key)
263403dc31fSBram Moolenaar      enddef
264403dc31fSBram Moolenaar      defcompile
265403dc31fSBram Moolenaar  END
266403dc31fSBram Moolenaar  CheckScriptSuccess(lines)
267403dc31fSBram Moolenaarenddef
268403dc31fSBram Moolenaar
2695deeb3f1SBram Moolenaarlet s:nothing = 0
2705deeb3f1SBram Moolenaardef ReturnNothing()
2715deeb3f1SBram Moolenaar  s:nothing = 1
2725deeb3f1SBram Moolenaar  if true
2735deeb3f1SBram Moolenaar    return
2745deeb3f1SBram Moolenaar  endif
2755deeb3f1SBram Moolenaar  s:nothing = 2
2765deeb3f1SBram Moolenaarenddef
2775deeb3f1SBram Moolenaar
2785deeb3f1SBram Moolenaardef Test_return_nothing()
2795deeb3f1SBram Moolenaar  ReturnNothing()
280c0c71e9dSBram Moolenaar  s:nothing->assert_equal(1)
2815deeb3f1SBram Moolenaarenddef
2825deeb3f1SBram Moolenaar
283648ea76eSBram Moolenaardef Test_return_invalid()
284648ea76eSBram Moolenaar  var lines =<< trim END
285648ea76eSBram Moolenaar    vim9script
286648ea76eSBram Moolenaar    def Func(): invalid
287648ea76eSBram Moolenaar      return xxx
288648ea76eSBram Moolenaar    enddef
289648ea76eSBram Moolenaar    defcompile
290648ea76eSBram Moolenaar  END
291648ea76eSBram Moolenaar  CheckScriptFailure(lines, 'E1010:', 2)
29231842cd0SBram Moolenaar
29331842cd0SBram Moolenaar  lines =<< trim END
29431842cd0SBram Moolenaar      vim9script
29531842cd0SBram Moolenaar      def Test(Fun: func(number): number): list<number>
29631842cd0SBram Moolenaar          return map([1, 2, 3], (_, i) => Fun(i))
29731842cd0SBram Moolenaar      enddef
29831842cd0SBram Moolenaar      defcompile
29931842cd0SBram Moolenaar      def Inc(nr: number): nr
30031842cd0SBram Moolenaar        return nr + 2
30131842cd0SBram Moolenaar      enddef
30231842cd0SBram Moolenaar      echo Test(Inc)
30331842cd0SBram Moolenaar  END
30431842cd0SBram Moolenaar  # doing this twice was leaking memory
30531842cd0SBram Moolenaar  CheckScriptFailure(lines, 'E1010:')
30631842cd0SBram Moolenaar  CheckScriptFailure(lines, 'E1010:')
307648ea76eSBram Moolenaarenddef
308648ea76eSBram Moolenaar
3095deeb3f1SBram Moolenaarfunc Increment()
3105deeb3f1SBram Moolenaar  let g:counter += 1
3115deeb3f1SBram Moolenaarendfunc
3125deeb3f1SBram Moolenaar
3135deeb3f1SBram Moolenaardef Test_call_ufunc_count()
3145deeb3f1SBram Moolenaar  g:counter = 1
3155deeb3f1SBram Moolenaar  Increment()
3165deeb3f1SBram Moolenaar  Increment()
3175deeb3f1SBram Moolenaar  Increment()
318f5be8cdbSBram Moolenaar  # works with and without :call
319c0c71e9dSBram Moolenaar  g:counter->assert_equal(4)
320c0c71e9dSBram Moolenaar  eval g:counter->assert_equal(4)
3215deeb3f1SBram Moolenaar  unlet g:counter
3225deeb3f1SBram Moolenaarenddef
3235deeb3f1SBram Moolenaar
3245deeb3f1SBram Moolenaardef MyVarargs(arg: string, ...rest: list<string>): string
3257a9cbca0SBram Moolenaar  var res = arg
3265deeb3f1SBram Moolenaar  for s in rest
3275deeb3f1SBram Moolenaar    res ..= ',' .. s
3285deeb3f1SBram Moolenaar  endfor
3295deeb3f1SBram Moolenaar  return res
3305deeb3f1SBram Moolenaarenddef
3315deeb3f1SBram Moolenaar
3325deeb3f1SBram Moolenaardef Test_call_varargs()
333c0c71e9dSBram Moolenaar  MyVarargs('one')->assert_equal('one')
334c0c71e9dSBram Moolenaar  MyVarargs('one', 'two')->assert_equal('one,two')
335c0c71e9dSBram Moolenaar  MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
3365deeb3f1SBram Moolenaarenddef
3375deeb3f1SBram Moolenaar
3385deeb3f1SBram Moolenaardef MyDefaultArgs(name = 'string'): string
3395deeb3f1SBram Moolenaar  return name
3405deeb3f1SBram Moolenaarenddef
3415deeb3f1SBram Moolenaar
342e30f64b4SBram Moolenaardef MyDefaultSecond(name: string, second: bool  = true): string
343e30f64b4SBram Moolenaar  return second ? name : 'none'
344e30f64b4SBram Moolenaarenddef
345e30f64b4SBram Moolenaar
34638a3bfa9SBram Moolenaar
3475deeb3f1SBram Moolenaardef Test_call_default_args()
348c0c71e9dSBram Moolenaar  MyDefaultArgs()->assert_equal('string')
34938a3bfa9SBram Moolenaar  MyDefaultArgs(v:none)->assert_equal('string')
350c0c71e9dSBram Moolenaar  MyDefaultArgs('one')->assert_equal('one')
35138a3bfa9SBram Moolenaar  assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 4, 'Test_call_default_args')
3525deeb3f1SBram Moolenaar
353c0c71e9dSBram Moolenaar  MyDefaultSecond('test')->assert_equal('test')
354c0c71e9dSBram Moolenaar  MyDefaultSecond('test', true)->assert_equal('test')
355c0c71e9dSBram Moolenaar  MyDefaultSecond('test', false)->assert_equal('none')
356e30f64b4SBram Moolenaar
35738a3bfa9SBram Moolenaar  var lines =<< trim END
35838a3bfa9SBram Moolenaar      def MyDefaultThird(name: string, aa = 'aa', bb = 'bb'): string
35938a3bfa9SBram Moolenaar        return name .. aa .. bb
36038a3bfa9SBram Moolenaar      enddef
36138a3bfa9SBram Moolenaar
36238a3bfa9SBram Moolenaar      MyDefaultThird('->')->assert_equal('->aabb')
36338a3bfa9SBram Moolenaar      MyDefaultThird('->', v:none)->assert_equal('->aabb')
36438a3bfa9SBram Moolenaar      MyDefaultThird('->', 'xx')->assert_equal('->xxbb')
36538a3bfa9SBram Moolenaar      MyDefaultThird('->', v:none, v:none)->assert_equal('->aabb')
36638a3bfa9SBram Moolenaar      MyDefaultThird('->', 'xx', v:none)->assert_equal('->xxbb')
36738a3bfa9SBram Moolenaar      MyDefaultThird('->', v:none, 'yy')->assert_equal('->aayy')
36838a3bfa9SBram Moolenaar      MyDefaultThird('->', 'xx', 'yy')->assert_equal('->xxyy')
36938a3bfa9SBram Moolenaar  END
37038a3bfa9SBram Moolenaar  CheckDefAndScriptSuccess(lines)
37138a3bfa9SBram Moolenaar
372822ba247SBram Moolenaar  CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
3732d870f8dSBram Moolenaar  delfunc g:Func
3747707228aSBram Moolenaar  CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string')
3752d870f8dSBram Moolenaar  delfunc g:Func
37612bce958SBram Moolenaar
37738a3bfa9SBram Moolenaar  lines =<< trim END
37812bce958SBram Moolenaar      vim9script
37912bce958SBram Moolenaar      def Func(a = b == 0 ? 1 : 2, b = 0)
38012bce958SBram Moolenaar      enddef
38112bce958SBram Moolenaar      defcompile
38212bce958SBram Moolenaar  END
38312bce958SBram Moolenaar  CheckScriptFailure(lines, 'E1001: Variable not found: b')
38404b12697SBram Moolenaarenddef
38504b12697SBram Moolenaar
386cef1270dSBram Moolenaardef FuncWithComment(  # comment
387cef1270dSBram Moolenaar  a: number, #comment
388cef1270dSBram Moolenaar  b: bool, # comment
389cef1270dSBram Moolenaar  c: string) #comment
390cef1270dSBram Moolenaar  assert_equal(4, a)
391cef1270dSBram Moolenaar  assert_equal(true, b)
392cef1270dSBram Moolenaar  assert_equal('yes', c)
393cef1270dSBram Moolenaarenddef
394cef1270dSBram Moolenaar
395cef1270dSBram Moolenaardef Test_func_with_comments()
396cef1270dSBram Moolenaar  FuncWithComment(4, true, 'yes')
397cef1270dSBram Moolenaar
398cef1270dSBram Moolenaar  var lines =<< trim END
399cef1270dSBram Moolenaar      def Func(# comment
400cef1270dSBram Moolenaar        arg: string)
401cef1270dSBram Moolenaar      enddef
402cef1270dSBram Moolenaar  END
403cef1270dSBram Moolenaar  CheckScriptFailure(lines, 'E125:', 1)
404cef1270dSBram Moolenaar
405cef1270dSBram Moolenaar  lines =<< trim END
406cef1270dSBram Moolenaar      def Func(
407cef1270dSBram Moolenaar        arg: string# comment
408cef1270dSBram Moolenaar        )
409cef1270dSBram Moolenaar      enddef
410cef1270dSBram Moolenaar  END
411cef1270dSBram Moolenaar  CheckScriptFailure(lines, 'E475:', 2)
412cef1270dSBram Moolenaar
413cef1270dSBram Moolenaar  lines =<< trim END
414cef1270dSBram Moolenaar      def Func(
415cef1270dSBram Moolenaar        arg: string
416cef1270dSBram Moolenaar        )# comment
417cef1270dSBram Moolenaar      enddef
418cef1270dSBram Moolenaar  END
419cef1270dSBram Moolenaar  CheckScriptFailure(lines, 'E488:', 3)
420cef1270dSBram Moolenaarenddef
421cef1270dSBram Moolenaar
42204b12697SBram Moolenaardef Test_nested_function()
42304b12697SBram Moolenaar  def Nested(arg: string): string
42404b12697SBram Moolenaar    return 'nested ' .. arg
42504b12697SBram Moolenaar  enddef
426c0c71e9dSBram Moolenaar  Nested('function')->assert_equal('nested function')
42704b12697SBram Moolenaar
4280e65d3deSBram Moolenaar  CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
4290e65d3deSBram Moolenaar  CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
4300e65d3deSBram Moolenaar
43104b12697SBram Moolenaar  CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:')
432bcbf4139SBram Moolenaar  CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
433bcbf4139SBram Moolenaar  CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
4348b848cafSBram Moolenaar
43554021758SBram Moolenaar  var lines =<< trim END
43654021758SBram Moolenaar      def Outer()
43754021758SBram Moolenaar        def Inner()
43854021758SBram Moolenaar          # comment
43954021758SBram Moolenaar        enddef
44054021758SBram Moolenaar        def Inner()
44154021758SBram Moolenaar        enddef
44254021758SBram Moolenaar      enddef
44354021758SBram Moolenaar  END
44454021758SBram Moolenaar  CheckDefFailure(lines, 'E1073:')
44554021758SBram Moolenaar
44654021758SBram Moolenaar  lines =<< trim END
44754021758SBram Moolenaar      def Outer()
44854021758SBram Moolenaar        def Inner()
44954021758SBram Moolenaar          # comment
45054021758SBram Moolenaar        enddef
45154021758SBram Moolenaar        def! Inner()
45254021758SBram Moolenaar        enddef
45354021758SBram Moolenaar      enddef
45454021758SBram Moolenaar  END
45554021758SBram Moolenaar  CheckDefFailure(lines, 'E1117:')
45654021758SBram Moolenaar
45754021758SBram Moolenaar  # nested function inside conditional
45854021758SBram Moolenaar  lines =<< trim END
45954021758SBram Moolenaar      vim9script
46054021758SBram Moolenaar      var thecount = 0
46154021758SBram Moolenaar      if true
46254021758SBram Moolenaar        def Test(): number
46354021758SBram Moolenaar          def TheFunc(): number
46454021758SBram Moolenaar            thecount += 1
46554021758SBram Moolenaar            return thecount
46654021758SBram Moolenaar          enddef
46754021758SBram Moolenaar          return TheFunc()
46854021758SBram Moolenaar        enddef
46954021758SBram Moolenaar      endif
47054021758SBram Moolenaar      defcompile
47154021758SBram Moolenaar      assert_equal(1, Test())
47254021758SBram Moolenaar      assert_equal(2, Test())
47354021758SBram Moolenaar  END
47454021758SBram Moolenaar  CheckScriptSuccess(lines)
4758863bda2SBram Moolenaar
4768863bda2SBram Moolenaar  # also works when "thecount" is inside the "if" block
4778863bda2SBram Moolenaar  lines =<< trim END
4788863bda2SBram Moolenaar      vim9script
4798863bda2SBram Moolenaar      if true
4808863bda2SBram Moolenaar        var thecount = 0
4818863bda2SBram Moolenaar        def Test(): number
4828863bda2SBram Moolenaar          def TheFunc(): number
4838863bda2SBram Moolenaar            thecount += 1
4848863bda2SBram Moolenaar            return thecount
4858863bda2SBram Moolenaar          enddef
4868863bda2SBram Moolenaar          return TheFunc()
4878863bda2SBram Moolenaar        enddef
4888863bda2SBram Moolenaar      endif
4898863bda2SBram Moolenaar      defcompile
4908863bda2SBram Moolenaar      assert_equal(1, Test())
4918863bda2SBram Moolenaar      assert_equal(2, Test())
4928863bda2SBram Moolenaar  END
4938863bda2SBram Moolenaar  CheckScriptSuccess(lines)
4945deeb3f1SBram Moolenaarenddef
4955deeb3f1SBram Moolenaar
496adc8e446SBram Moolenaardef Test_not_nested_function()
497adc8e446SBram Moolenaar  echo printf('%d',
498adc8e446SBram Moolenaar      function('len')('xxx'))
499adc8e446SBram Moolenaarenddef
500adc8e446SBram Moolenaar
501af8edbb8SBram Moolenaarfunc Test_call_default_args_from_func()
502c0c71e9dSBram Moolenaar  call MyDefaultArgs()->assert_equal('string')
503c0c71e9dSBram Moolenaar  call MyDefaultArgs('one')->assert_equal('one')
5049bd5d879SBram Moolenaar  call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
505af8edbb8SBram Moolenaarendfunc
506af8edbb8SBram Moolenaar
50738ddf333SBram Moolenaardef Test_nested_global_function()
5087a9cbca0SBram Moolenaar  var lines =<< trim END
50938ddf333SBram Moolenaar      vim9script
51038ddf333SBram Moolenaar      def Outer()
51138ddf333SBram Moolenaar          def g:Inner(): string
51238ddf333SBram Moolenaar              return 'inner'
51338ddf333SBram Moolenaar          enddef
51438ddf333SBram Moolenaar      enddef
515af8edbb8SBram Moolenaar      defcompile
516af8edbb8SBram Moolenaar      Outer()
517c0c71e9dSBram Moolenaar      g:Inner()->assert_equal('inner')
518af8edbb8SBram Moolenaar      delfunc g:Inner
519af8edbb8SBram Moolenaar      Outer()
520c0c71e9dSBram Moolenaar      g:Inner()->assert_equal('inner')
521af8edbb8SBram Moolenaar      delfunc g:Inner
522af8edbb8SBram Moolenaar      Outer()
523c0c71e9dSBram Moolenaar      g:Inner()->assert_equal('inner')
524af8edbb8SBram Moolenaar      delfunc g:Inner
52538ddf333SBram Moolenaar  END
52638ddf333SBram Moolenaar  CheckScriptSuccess(lines)
5272c79e9d1SBram Moolenaar
5282c79e9d1SBram Moolenaar  lines =<< trim END
5292c79e9d1SBram Moolenaar      vim9script
5302c79e9d1SBram Moolenaar      def Outer()
5312c79e9d1SBram Moolenaar          def g:Inner(): string
5322c79e9d1SBram Moolenaar              return 'inner'
5332c79e9d1SBram Moolenaar          enddef
5342c79e9d1SBram Moolenaar      enddef
5352c79e9d1SBram Moolenaar      defcompile
5362c79e9d1SBram Moolenaar      Outer()
5372c79e9d1SBram Moolenaar      Outer()
5382c79e9d1SBram Moolenaar  END
5392c79e9d1SBram Moolenaar  CheckScriptFailure(lines, "E122:")
540cd45ed03SBram Moolenaar  delfunc g:Inner
541ad486a0fSBram Moolenaar
542ad486a0fSBram Moolenaar  lines =<< trim END
543ad486a0fSBram Moolenaar      vim9script
54458a52f21SBram Moolenaar      def Outer()
54558a52f21SBram Moolenaar        def g:Inner()
5462949cfdbSBram Moolenaar          echo map([1, 2, 3], (_, v) => v + 1)
54758a52f21SBram Moolenaar        enddef
54858a52f21SBram Moolenaar        g:Inner()
54958a52f21SBram Moolenaar      enddef
55058a52f21SBram Moolenaar      Outer()
55158a52f21SBram Moolenaar  END
55258a52f21SBram Moolenaar  CheckScriptSuccess(lines)
55358a52f21SBram Moolenaar  delfunc g:Inner
55458a52f21SBram Moolenaar
55558a52f21SBram Moolenaar  lines =<< trim END
55658a52f21SBram Moolenaar      vim9script
557ad486a0fSBram Moolenaar      def Func()
558ad486a0fSBram Moolenaar        echo 'script'
559ad486a0fSBram Moolenaar      enddef
560ad486a0fSBram Moolenaar      def Outer()
561ad486a0fSBram Moolenaar        def Func()
562ad486a0fSBram Moolenaar          echo 'inner'
563ad486a0fSBram Moolenaar        enddef
564ad486a0fSBram Moolenaar      enddef
565ad486a0fSBram Moolenaar      defcompile
566ad486a0fSBram Moolenaar  END
567ad486a0fSBram Moolenaar  CheckScriptFailure(lines, "E1073:")
56838ddf333SBram Moolenaarenddef
56938ddf333SBram Moolenaar
5706abdcf82SBram Moolenaardef DefListAll()
5716abdcf82SBram Moolenaar  def
5726abdcf82SBram Moolenaarenddef
5736abdcf82SBram Moolenaar
5746abdcf82SBram Moolenaardef DefListOne()
5756abdcf82SBram Moolenaar  def DefListOne
5766abdcf82SBram Moolenaarenddef
5776abdcf82SBram Moolenaar
5786abdcf82SBram Moolenaardef DefListMatches()
5796abdcf82SBram Moolenaar  def /DefList
5806abdcf82SBram Moolenaarenddef
5816abdcf82SBram Moolenaar
5826abdcf82SBram Moolenaardef Test_nested_def_list()
5836abdcf82SBram Moolenaar  var funcs = split(execute('call DefListAll()'), "\n")
5846abdcf82SBram Moolenaar  assert_true(len(funcs) > 10)
5856abdcf82SBram Moolenaar  assert_true(funcs->index('def DefListAll()') >= 0)
5866abdcf82SBram Moolenaar
5876abdcf82SBram Moolenaar  funcs = split(execute('call DefListOne()'), "\n")
5886abdcf82SBram Moolenaar  assert_equal(['   def DefListOne()', '1    def DefListOne', '   enddef'], funcs)
5896abdcf82SBram Moolenaar
5906abdcf82SBram Moolenaar  funcs = split(execute('call DefListMatches()'), "\n")
5916abdcf82SBram Moolenaar  assert_true(len(funcs) >= 3)
5926abdcf82SBram Moolenaar  assert_true(funcs->index('def DefListAll()') >= 0)
5936abdcf82SBram Moolenaar  assert_true(funcs->index('def DefListOne()') >= 0)
5946abdcf82SBram Moolenaar  assert_true(funcs->index('def DefListMatches()') >= 0)
59554021758SBram Moolenaar
59654021758SBram Moolenaar  var lines =<< trim END
59754021758SBram Moolenaar    vim9script
59854021758SBram Moolenaar    def Func()
59954021758SBram Moolenaar      def +Func+
60054021758SBram Moolenaar    enddef
60154021758SBram Moolenaar    defcompile
60254021758SBram Moolenaar  END
60354021758SBram Moolenaar  CheckScriptFailure(lines, 'E476:', 1)
6046abdcf82SBram Moolenaarenddef
6056abdcf82SBram Moolenaar
606333894b1SBram Moolenaardef Test_global_local_function()
6077a9cbca0SBram Moolenaar  var lines =<< trim END
608333894b1SBram Moolenaar      vim9script
609333894b1SBram Moolenaar      def g:Func(): string
610333894b1SBram Moolenaar          return 'global'
611333894b1SBram Moolenaar      enddef
612333894b1SBram Moolenaar      def Func(): string
613333894b1SBram Moolenaar          return 'local'
614333894b1SBram Moolenaar      enddef
615c0c71e9dSBram Moolenaar      g:Func()->assert_equal('global')
616c0c71e9dSBram Moolenaar      Func()->assert_equal('local')
6172d870f8dSBram Moolenaar      delfunc g:Func
618333894b1SBram Moolenaar  END
619333894b1SBram Moolenaar  CheckScriptSuccess(lines)
620035d6e91SBram Moolenaar
621035d6e91SBram Moolenaar  lines =<< trim END
622035d6e91SBram Moolenaar      vim9script
623035d6e91SBram Moolenaar      def g:Funcy()
624035d6e91SBram Moolenaar        echo 'funcy'
625035d6e91SBram Moolenaar      enddef
626035d6e91SBram Moolenaar      s:Funcy()
627035d6e91SBram Moolenaar  END
628035d6e91SBram Moolenaar  CheckScriptFailure(lines, 'E117:')
629333894b1SBram Moolenaarenddef
630333894b1SBram Moolenaar
6310f769815SBram Moolenaardef Test_local_function_shadows_global()
6327a9cbca0SBram Moolenaar  var lines =<< trim END
6330f769815SBram Moolenaar      vim9script
6340f769815SBram Moolenaar      def g:Gfunc(): string
6350f769815SBram Moolenaar        return 'global'
6360f769815SBram Moolenaar      enddef
6370f769815SBram Moolenaar      def AnotherFunc(): number
6387a9cbca0SBram Moolenaar        var Gfunc = function('len')
6390f769815SBram Moolenaar        return Gfunc('testing')
6400f769815SBram Moolenaar      enddef
6410f769815SBram Moolenaar      g:Gfunc()->assert_equal('global')
6420f769815SBram Moolenaar      AnotherFunc()->assert_equal(7)
6430f769815SBram Moolenaar      delfunc g:Gfunc
6440f769815SBram Moolenaar  END
6450f769815SBram Moolenaar  CheckScriptSuccess(lines)
6460f769815SBram Moolenaar
6470f769815SBram Moolenaar  lines =<< trim END
6480f769815SBram Moolenaar      vim9script
6490f769815SBram Moolenaar      def g:Func(): string
6500f769815SBram Moolenaar        return 'global'
6510f769815SBram Moolenaar      enddef
6520f769815SBram Moolenaar      def AnotherFunc()
6530f769815SBram Moolenaar        g:Func = function('len')
6540f769815SBram Moolenaar      enddef
6550f769815SBram Moolenaar      AnotherFunc()
6560f769815SBram Moolenaar  END
6570f769815SBram Moolenaar  CheckScriptFailure(lines, 'E705:')
6580f769815SBram Moolenaar  delfunc g:Func
6590865b15bSBram Moolenaar
6600865b15bSBram Moolenaar  # global function is found without g: prefix
6610865b15bSBram Moolenaar  lines =<< trim END
6620865b15bSBram Moolenaar      vim9script
6630865b15bSBram Moolenaar      def g:Func(): string
6640865b15bSBram Moolenaar        return 'global'
6650865b15bSBram Moolenaar      enddef
6660865b15bSBram Moolenaar      def AnotherFunc(): string
6670865b15bSBram Moolenaar        return Func()
6680865b15bSBram Moolenaar      enddef
6690865b15bSBram Moolenaar      assert_equal('global', AnotherFunc())
6700865b15bSBram Moolenaar    delfunc g:Func
6710865b15bSBram Moolenaar  END
6720865b15bSBram Moolenaar  CheckScriptSuccess(lines)
6730865b15bSBram Moolenaar
6740865b15bSBram Moolenaar  lines =<< trim END
6750865b15bSBram Moolenaar      vim9script
6760865b15bSBram Moolenaar      def g:Func(): string
6770865b15bSBram Moolenaar        return 'global'
6780865b15bSBram Moolenaar      enddef
6790865b15bSBram Moolenaar      assert_equal('global', Func())
6800865b15bSBram Moolenaar      delfunc g:Func
6810865b15bSBram Moolenaar  END
6820865b15bSBram Moolenaar  CheckScriptSuccess(lines)
6830f769815SBram Moolenaarenddef
6840f769815SBram Moolenaar
6855deeb3f1SBram Moolenaarfunc TakesOneArg(arg)
6865deeb3f1SBram Moolenaar  echo a:arg
6875deeb3f1SBram Moolenaarendfunc
6885deeb3f1SBram Moolenaar
6895deeb3f1SBram Moolenaardef Test_call_wrong_args()
690d2c61705SBram Moolenaar  CheckDefFailure(['TakesOneArg()'], 'E119:')
691d2c61705SBram Moolenaar  CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
692d2c61705SBram Moolenaar  CheckDefFailure(['bufnr(xxx)'], 'E1001:')
693d2c61705SBram Moolenaar  CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
694ee8580e5SBram Moolenaar
6957a9cbca0SBram Moolenaar  var lines =<< trim END
696ee8580e5SBram Moolenaar    vim9script
697ee8580e5SBram Moolenaar    def Func(s: string)
698ee8580e5SBram Moolenaar      echo s
699ee8580e5SBram Moolenaar    enddef
700ee8580e5SBram Moolenaar    Func([])
701ee8580e5SBram Moolenaar  END
7027707228aSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
703b185a407SBram Moolenaar
704b185a407SBram Moolenaar  lines =<< trim END
705b185a407SBram Moolenaar    vim9script
706b4893b84SBram Moolenaar    var name = 'piet'
707b4893b84SBram Moolenaar    def FuncOne(name: string)
708b4893b84SBram Moolenaar      echo nr
709b4893b84SBram Moolenaar    enddef
710b4893b84SBram Moolenaar  END
711057e84afSBram Moolenaar  CheckScriptFailure(lines, 'E1168:')
712b4893b84SBram Moolenaar
713b4893b84SBram Moolenaar  lines =<< trim END
714b4893b84SBram Moolenaar    vim9script
715b185a407SBram Moolenaar    def FuncOne(nr: number)
716b185a407SBram Moolenaar      echo nr
717b185a407SBram Moolenaar    enddef
718b185a407SBram Moolenaar    def FuncTwo()
719b185a407SBram Moolenaar      FuncOne()
720b185a407SBram Moolenaar    enddef
721b185a407SBram Moolenaar    defcompile
722b185a407SBram Moolenaar  END
723b185a407SBram Moolenaar  writefile(lines, 'Xscript')
7247a9cbca0SBram Moolenaar  var didCatch = false
725b185a407SBram Moolenaar  try
726b185a407SBram Moolenaar    source Xscript
727b185a407SBram Moolenaar  catch
728b185a407SBram Moolenaar    assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
729b185a407SBram Moolenaar    assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
730b185a407SBram Moolenaar    didCatch = true
731b185a407SBram Moolenaar  endtry
732b185a407SBram Moolenaar  assert_true(didCatch)
733b185a407SBram Moolenaar
734b185a407SBram Moolenaar  lines =<< trim END
735b185a407SBram Moolenaar    vim9script
736b185a407SBram Moolenaar    def FuncOne(nr: number)
737b185a407SBram Moolenaar      echo nr
738b185a407SBram Moolenaar    enddef
739b185a407SBram Moolenaar    def FuncTwo()
740b185a407SBram Moolenaar      FuncOne(1, 2)
741b185a407SBram Moolenaar    enddef
742b185a407SBram Moolenaar    defcompile
743b185a407SBram Moolenaar  END
744b185a407SBram Moolenaar  writefile(lines, 'Xscript')
745b185a407SBram Moolenaar  didCatch = false
746b185a407SBram Moolenaar  try
747b185a407SBram Moolenaar    source Xscript
748b185a407SBram Moolenaar  catch
749b185a407SBram Moolenaar    assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
750b185a407SBram Moolenaar    assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
751b185a407SBram Moolenaar    didCatch = true
752b185a407SBram Moolenaar  endtry
753b185a407SBram Moolenaar  assert_true(didCatch)
754b185a407SBram Moolenaar
755b185a407SBram Moolenaar  delete('Xscript')
7565deeb3f1SBram Moolenaarenddef
7575deeb3f1SBram Moolenaar
7585082471fSBram Moolenaardef Test_call_funcref_wrong_args()
7595082471fSBram Moolenaar  var head =<< trim END
7605082471fSBram Moolenaar      vim9script
7615082471fSBram Moolenaar      def Func3(a1: string, a2: number, a3: list<number>)
7625082471fSBram Moolenaar        echo a1 .. a2 .. a3[0]
7635082471fSBram Moolenaar      enddef
7645082471fSBram Moolenaar      def Testme()
7655082471fSBram Moolenaar        var funcMap: dict<func> = {func: Func3}
7665082471fSBram Moolenaar  END
7675082471fSBram Moolenaar  var tail =<< trim END
7685082471fSBram Moolenaar      enddef
7695082471fSBram Moolenaar      Testme()
7705082471fSBram Moolenaar  END
7715082471fSBram Moolenaar  CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
7725082471fSBram Moolenaar
7735082471fSBram Moolenaar  CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
7745082471fSBram Moolenaar  CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
77532b3f820SBram Moolenaar
77632b3f820SBram Moolenaar  var lines =<< trim END
77732b3f820SBram Moolenaar      vim9script
77832b3f820SBram Moolenaar      var Ref: func(number): any
77932b3f820SBram Moolenaar      Ref = (j) => !j
78032b3f820SBram Moolenaar      echo Ref(false)
78132b3f820SBram Moolenaar  END
78232b3f820SBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
78332b3f820SBram Moolenaar
78432b3f820SBram Moolenaar  lines =<< trim END
78532b3f820SBram Moolenaar      vim9script
78632b3f820SBram Moolenaar      var Ref: func(number): any
78732b3f820SBram Moolenaar      Ref = (j) => !j
78832b3f820SBram Moolenaar      call Ref(false)
78932b3f820SBram Moolenaar  END
79032b3f820SBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
7915082471fSBram Moolenaarenddef
7925082471fSBram Moolenaar
793b4d16cb1SBram Moolenaardef Test_call_lambda_args()
7942a38908bSBram Moolenaar  var lines =<< trim END
7952a38908bSBram Moolenaar    var Callback = (..._) => 'anything'
7962a38908bSBram Moolenaar    assert_equal('anything', Callback())
7972a38908bSBram Moolenaar    assert_equal('anything', Callback(1))
7982a38908bSBram Moolenaar    assert_equal('anything', Callback('a', 2))
7991088b694SBram Moolenaar
8001088b694SBram Moolenaar    assert_equal('xyz', ((a: string): string => a)('xyz'))
8012a38908bSBram Moolenaar  END
8022a38908bSBram Moolenaar  CheckDefAndScriptSuccess(lines)
8032a38908bSBram Moolenaar
8042949cfdbSBram Moolenaar  CheckDefFailure(['echo ((i) => 0)()'],
8052949cfdbSBram Moolenaar                  'E119: Not enough arguments for function: ((i) => 0)()')
806b4d16cb1SBram Moolenaar
8072a38908bSBram Moolenaar  lines =<< trim END
8082949cfdbSBram Moolenaar      var Ref = (x: number, y: number) => x + y
809b4d16cb1SBram Moolenaar      echo Ref(1, 'x')
810b4d16cb1SBram Moolenaar  END
811b4d16cb1SBram Moolenaar  CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
812e68b02a1SBram Moolenaar
813e68b02a1SBram Moolenaar  lines =<< trim END
814e68b02a1SBram Moolenaar    var Ref: func(job, string, number)
815e68b02a1SBram Moolenaar    Ref = (x, y) => 0
816e68b02a1SBram Moolenaar  END
817e68b02a1SBram Moolenaar  CheckDefAndScriptFailure(lines, 'E1012:')
818e68b02a1SBram Moolenaar
819e68b02a1SBram Moolenaar  lines =<< trim END
820e68b02a1SBram Moolenaar    var Ref: func(job, string)
821e68b02a1SBram Moolenaar    Ref = (x, y, z) => 0
822e68b02a1SBram Moolenaar  END
823e68b02a1SBram Moolenaar  CheckDefAndScriptFailure(lines, 'E1012:')
824057e84afSBram Moolenaar
825057e84afSBram Moolenaar  lines =<< trim END
826057e84afSBram Moolenaar      var one = 1
827057e84afSBram Moolenaar      var l = [1, 2, 3]
828057e84afSBram Moolenaar      echo map(l, (one) => one)
829057e84afSBram Moolenaar  END
830057e84afSBram Moolenaar  CheckDefFailure(lines, 'E1167:')
831057e84afSBram Moolenaar  CheckScriptFailure(['vim9script'] + lines, 'E1168:')
832057e84afSBram Moolenaar
833057e84afSBram Moolenaar  lines =<< trim END
834057e84afSBram Moolenaar      def ShadowLocal()
835057e84afSBram Moolenaar        var one = 1
836057e84afSBram Moolenaar        var l = [1, 2, 3]
837057e84afSBram Moolenaar        echo map(l, (one) => one)
838057e84afSBram Moolenaar      enddef
839057e84afSBram Moolenaar  END
840057e84afSBram Moolenaar  CheckDefFailure(lines, 'E1167:')
841057e84afSBram Moolenaar
842057e84afSBram Moolenaar  lines =<< trim END
843057e84afSBram Moolenaar      def Shadowarg(one: number)
844057e84afSBram Moolenaar        var l = [1, 2, 3]
845057e84afSBram Moolenaar        echo map(l, (one) => one)
846057e84afSBram Moolenaar      enddef
847057e84afSBram Moolenaar  END
848057e84afSBram Moolenaar  CheckDefFailure(lines, 'E1167:')
849767034c5SBram Moolenaar
850767034c5SBram Moolenaar  lines =<< trim END
851767034c5SBram Moolenaar    echo ((a) => a)('aa', 'bb')
852767034c5SBram Moolenaar  END
853767034c5SBram Moolenaar  CheckDefAndScriptFailure(lines, 'E118:', 1)
854b4d16cb1SBram Moolenaarenddef
855b4d16cb1SBram Moolenaar
8565f91e74bSBram Moolenaardef FilterWithCond(x: string, Cond: func(string): bool): bool
8575f91e74bSBram Moolenaar  return Cond(x)
8585f91e74bSBram Moolenaarenddef
8595f91e74bSBram Moolenaar
8600346b799SBram Moolenaardef Test_lambda_return_type()
8610346b799SBram Moolenaar  var lines =<< trim END
8620346b799SBram Moolenaar    var Ref = (): => 123
8630346b799SBram Moolenaar  END
8640346b799SBram Moolenaar  CheckDefAndScriptFailure(lines, 'E1157:', 1)
8655f91e74bSBram Moolenaar
8665f91e74bSBram Moolenaar  # this works
8675f91e74bSBram Moolenaar  for x in ['foo', 'boo']
8685f91e74bSBram Moolenaar    echo FilterWithCond(x, (v) => v =~ '^b')
8695f91e74bSBram Moolenaar  endfor
8705f91e74bSBram Moolenaar
8715f91e74bSBram Moolenaar  # this fails
8725f91e74bSBram Moolenaar  lines =<< trim END
8735f91e74bSBram Moolenaar      echo FilterWithCond('foo', (v) => v .. '^b')
8745f91e74bSBram Moolenaar  END
8755f91e74bSBram Moolenaar  CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected func(string): bool but got func(any): string', 1)
8760346b799SBram Moolenaarenddef
8770346b799SBram Moolenaar
878709664ccSBram Moolenaardef Test_lambda_uses_assigned_var()
879709664ccSBram Moolenaar  CheckDefSuccess([
880709664ccSBram Moolenaar        'var x: any = "aaa"'
8812949cfdbSBram Moolenaar        'x = filter(["bbb"], (_, v) => v =~ x)'])
882709664ccSBram Moolenaarenddef
883709664ccSBram Moolenaar
88418062fcaSBram Moolenaardef Test_pass_legacy_lambda_to_def_func()
88518062fcaSBram Moolenaar  var lines =<< trim END
88618062fcaSBram Moolenaar      vim9script
88718062fcaSBram Moolenaar      func Foo()
88818062fcaSBram Moolenaar        eval s:Bar({x -> 0})
88918062fcaSBram Moolenaar      endfunc
89018062fcaSBram Moolenaar      def Bar(y: any)
89118062fcaSBram Moolenaar      enddef
89218062fcaSBram Moolenaar      Foo()
89318062fcaSBram Moolenaar  END
89418062fcaSBram Moolenaar  CheckScriptSuccess(lines)
89518062fcaSBram Moolenaarenddef
89618062fcaSBram Moolenaar
8975deeb3f1SBram Moolenaar" Default arg and varargs
8985deeb3f1SBram Moolenaardef MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
8997a9cbca0SBram Moolenaar  var res = one .. ',' .. two
9005deeb3f1SBram Moolenaar  for s in rest
9015deeb3f1SBram Moolenaar    res ..= ',' .. s
9025deeb3f1SBram Moolenaar  endfor
9035deeb3f1SBram Moolenaar  return res
9045deeb3f1SBram Moolenaarenddef
9055deeb3f1SBram Moolenaar
9065deeb3f1SBram Moolenaardef Test_call_def_varargs()
9079bd5d879SBram Moolenaar  assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
908c0c71e9dSBram Moolenaar  MyDefVarargs('one')->assert_equal('one,foo')
909c0c71e9dSBram Moolenaar  MyDefVarargs('one', 'two')->assert_equal('one,two')
910c0c71e9dSBram Moolenaar  MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
91124aa48b7SBram Moolenaar  CheckDefFailure(['MyDefVarargs("one", 22)'],
9127707228aSBram Moolenaar      'E1013: Argument 2: type mismatch, expected string but got number')
91324aa48b7SBram Moolenaar  CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
9147707228aSBram Moolenaar      'E1013: Argument 3: type mismatch, expected string but got number')
91524aa48b7SBram Moolenaar
9167a9cbca0SBram Moolenaar  var lines =<< trim END
91724aa48b7SBram Moolenaar      vim9script
91824aa48b7SBram Moolenaar      def Func(...l: list<string>)
91924aa48b7SBram Moolenaar        echo l
92024aa48b7SBram Moolenaar      enddef
92124aa48b7SBram Moolenaar      Func('a', 'b', 'c')
92224aa48b7SBram Moolenaar  END
92324aa48b7SBram Moolenaar  CheckScriptSuccess(lines)
92424aa48b7SBram Moolenaar
92524aa48b7SBram Moolenaar  lines =<< trim END
92624aa48b7SBram Moolenaar      vim9script
92724aa48b7SBram Moolenaar      def Func(...l: list<string>)
92824aa48b7SBram Moolenaar        echo l
92924aa48b7SBram Moolenaar      enddef
93024aa48b7SBram Moolenaar      Func()
93124aa48b7SBram Moolenaar  END
93224aa48b7SBram Moolenaar  CheckScriptSuccess(lines)
93324aa48b7SBram Moolenaar
93424aa48b7SBram Moolenaar  lines =<< trim END
93524aa48b7SBram Moolenaar      vim9script
9362a38908bSBram Moolenaar      def Func(...l: list<any>)
9372f8cbc4bSBram Moolenaar        echo l
9382f8cbc4bSBram Moolenaar      enddef
9392f8cbc4bSBram Moolenaar      Func(0)
9402f8cbc4bSBram Moolenaar  END
9412f8cbc4bSBram Moolenaar  CheckScriptSuccess(lines)
9422f8cbc4bSBram Moolenaar
9432f8cbc4bSBram Moolenaar  lines =<< trim END
9442f8cbc4bSBram Moolenaar      vim9script
9452a38908bSBram Moolenaar      def Func(...l: any)
9462a38908bSBram Moolenaar        echo l
9472a38908bSBram Moolenaar      enddef
9482a38908bSBram Moolenaar      Func(0)
9492a38908bSBram Moolenaar  END
9502a38908bSBram Moolenaar  CheckScriptFailure(lines, 'E1180:', 2)
9512a38908bSBram Moolenaar
9522a38908bSBram Moolenaar  lines =<< trim END
9532a38908bSBram Moolenaar      vim9script
95428022727SBram Moolenaar      def Func(..._l: list<string>)
95528022727SBram Moolenaar        echo _l
95628022727SBram Moolenaar      enddef
95728022727SBram Moolenaar      Func('a', 'b', 'c')
95828022727SBram Moolenaar  END
95928022727SBram Moolenaar  CheckScriptSuccess(lines)
96028022727SBram Moolenaar
96128022727SBram Moolenaar  lines =<< trim END
96228022727SBram Moolenaar      vim9script
96324aa48b7SBram Moolenaar      def Func(...l: list<string>)
96424aa48b7SBram Moolenaar        echo l
96524aa48b7SBram Moolenaar      enddef
96624aa48b7SBram Moolenaar      Func(1, 2, 3)
96724aa48b7SBram Moolenaar  END
9687707228aSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
96924aa48b7SBram Moolenaar
97024aa48b7SBram Moolenaar  lines =<< trim END
97124aa48b7SBram Moolenaar      vim9script
97224aa48b7SBram Moolenaar      def Func(...l: list<string>)
97324aa48b7SBram Moolenaar        echo l
97424aa48b7SBram Moolenaar      enddef
97524aa48b7SBram Moolenaar      Func('a', 9)
97624aa48b7SBram Moolenaar  END
9777707228aSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
97824aa48b7SBram Moolenaar
97924aa48b7SBram Moolenaar  lines =<< trim END
98024aa48b7SBram Moolenaar      vim9script
98124aa48b7SBram Moolenaar      def Func(...l: list<string>)
98224aa48b7SBram Moolenaar        echo l
98324aa48b7SBram Moolenaar      enddef
98424aa48b7SBram Moolenaar      Func(1, 'a')
98524aa48b7SBram Moolenaar  END
9867707228aSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
9874f53b79bSBram Moolenaar
9884f53b79bSBram Moolenaar  lines =<< trim END
9894f53b79bSBram Moolenaar      vim9script
9904f53b79bSBram Moolenaar      def Func(  # some comment
9914f53b79bSBram Moolenaar                ...l = []
9924f53b79bSBram Moolenaar                )
9934f53b79bSBram Moolenaar        echo l
9944f53b79bSBram Moolenaar      enddef
9954f53b79bSBram Moolenaar  END
9964f53b79bSBram Moolenaar  CheckScriptFailure(lines, 'E1160:')
9975deeb3f1SBram Moolenaarenddef
9985deeb3f1SBram Moolenaar
9991378fbc4SBram Moolenaarlet s:value = ''
10001378fbc4SBram Moolenaar
10011378fbc4SBram Moolenaardef FuncOneDefArg(opt = 'text')
10021378fbc4SBram Moolenaar  s:value = opt
10031378fbc4SBram Moolenaarenddef
10041378fbc4SBram Moolenaar
10051378fbc4SBram Moolenaardef FuncTwoDefArg(nr = 123, opt = 'text'): string
10061378fbc4SBram Moolenaar  return nr .. opt
10071378fbc4SBram Moolenaarenddef
10081378fbc4SBram Moolenaar
10091378fbc4SBram Moolenaardef FuncVarargs(...arg: list<string>): string
10101378fbc4SBram Moolenaar  return join(arg, ',')
10111378fbc4SBram Moolenaarenddef
10121378fbc4SBram Moolenaar
10131378fbc4SBram Moolenaardef Test_func_type_varargs()
10147a9cbca0SBram Moolenaar  var RefDefArg: func(?string)
10151378fbc4SBram Moolenaar  RefDefArg = FuncOneDefArg
10161378fbc4SBram Moolenaar  RefDefArg()
1017c0c71e9dSBram Moolenaar  s:value->assert_equal('text')
10181378fbc4SBram Moolenaar  RefDefArg('some')
1019c0c71e9dSBram Moolenaar  s:value->assert_equal('some')
10201378fbc4SBram Moolenaar
10217a9cbca0SBram Moolenaar  var RefDef2Arg: func(?number, ?string): string
10221378fbc4SBram Moolenaar  RefDef2Arg = FuncTwoDefArg
1023c0c71e9dSBram Moolenaar  RefDef2Arg()->assert_equal('123text')
1024c0c71e9dSBram Moolenaar  RefDef2Arg(99)->assert_equal('99text')
1025c0c71e9dSBram Moolenaar  RefDef2Arg(77, 'some')->assert_equal('77some')
10261378fbc4SBram Moolenaar
10277a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
10287a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
10291378fbc4SBram Moolenaar
10307a9cbca0SBram Moolenaar  var RefVarargs: func(...list<string>): string
10311378fbc4SBram Moolenaar  RefVarargs = FuncVarargs
1032c0c71e9dSBram Moolenaar  RefVarargs()->assert_equal('')
1033c0c71e9dSBram Moolenaar  RefVarargs('one')->assert_equal('one')
1034c0c71e9dSBram Moolenaar  RefVarargs('one', 'two')->assert_equal('one,two')
10351378fbc4SBram Moolenaar
10367a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
10377a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
10381378fbc4SBram Moolenaarenddef
10391378fbc4SBram Moolenaar
10400b76b42dSBram Moolenaar" Only varargs
10410b76b42dSBram Moolenaardef MyVarargsOnly(...args: list<string>): string
10420b76b42dSBram Moolenaar  return join(args, ',')
10430b76b42dSBram Moolenaarenddef
10440b76b42dSBram Moolenaar
10450b76b42dSBram Moolenaardef Test_call_varargs_only()
1046c0c71e9dSBram Moolenaar  MyVarargsOnly()->assert_equal('')
1047c0c71e9dSBram Moolenaar  MyVarargsOnly('one')->assert_equal('one')
1048c0c71e9dSBram Moolenaar  MyVarargsOnly('one', 'two')->assert_equal('one,two')
10497707228aSBram Moolenaar  CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
10507707228aSBram Moolenaar  CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
10510b76b42dSBram Moolenaarenddef
10520b76b42dSBram Moolenaar
10535deeb3f1SBram Moolenaardef Test_using_var_as_arg()
10547a9cbca0SBram Moolenaar  writefile(['def Func(x: number)',  'var x = 234', 'enddef', 'defcompile'], 'Xdef')
10559bd5d879SBram Moolenaar  assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
1056d2c61705SBram Moolenaar  delete('Xdef')
10575deeb3f1SBram Moolenaarenddef
10585deeb3f1SBram Moolenaar
1059cb2bdb1cSBram Moolenaardef DictArg(arg: dict<string>)
1060cb2bdb1cSBram Moolenaar  arg['key'] = 'value'
1061cb2bdb1cSBram Moolenaarenddef
1062cb2bdb1cSBram Moolenaar
1063cb2bdb1cSBram Moolenaardef ListArg(arg: list<string>)
1064cb2bdb1cSBram Moolenaar  arg[0] = 'value'
1065cb2bdb1cSBram Moolenaarenddef
1066cb2bdb1cSBram Moolenaar
1067cb2bdb1cSBram Moolenaardef Test_assign_to_argument()
1068f5be8cdbSBram Moolenaar  # works for dict and list
10697a9cbca0SBram Moolenaar  var d: dict<string> = {}
1070cb2bdb1cSBram Moolenaar  DictArg(d)
1071c0c71e9dSBram Moolenaar  d['key']->assert_equal('value')
10727a9cbca0SBram Moolenaar  var l: list<string> = []
1073cb2bdb1cSBram Moolenaar  ListArg(l)
1074c0c71e9dSBram Moolenaar  l[0]->assert_equal('value')
1075cb2bdb1cSBram Moolenaar
1076d2c61705SBram Moolenaar  CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
10772d870f8dSBram Moolenaar  delfunc! g:Func
1078cb2bdb1cSBram Moolenaarenddef
1079cb2bdb1cSBram Moolenaar
1080b816dae1SBram Moolenaar" These argument names are reserved in legacy functions.
1081b816dae1SBram Moolenaardef WithReservedNames(firstline: string, lastline: string): string
1082b816dae1SBram Moolenaar  return firstline .. lastline
1083b816dae1SBram Moolenaarenddef
1084b816dae1SBram Moolenaar
1085b816dae1SBram Moolenaardef Test_argument_names()
1086b816dae1SBram Moolenaar  assert_equal('OK', WithReservedNames('O', 'K'))
1087b816dae1SBram Moolenaarenddef
1088b816dae1SBram Moolenaar
10895deeb3f1SBram Moolenaardef Test_call_func_defined_later()
1090c0c71e9dSBram Moolenaar  g:DefinedLater('one')->assert_equal('one')
10919bd5d879SBram Moolenaar  assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
10925deeb3f1SBram Moolenaarenddef
10935deeb3f1SBram Moolenaar
10941df8b3fbSBram Moolenaarfunc DefinedLater(arg)
10951df8b3fbSBram Moolenaar  return a:arg
10961df8b3fbSBram Moolenaarendfunc
10971df8b3fbSBram Moolenaar
10981df8b3fbSBram Moolenaardef Test_call_funcref()
1099c0c71e9dSBram Moolenaar  g:SomeFunc('abc')->assert_equal(3)
11009bd5d879SBram Moolenaar  assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
11019bd5d879SBram Moolenaar  assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
11022f1980f7SBram Moolenaar
11037a9cbca0SBram Moolenaar  var lines =<< trim END
11042f1980f7SBram Moolenaar    vim9script
11052f1980f7SBram Moolenaar    def RetNumber(): number
11062f1980f7SBram Moolenaar      return 123
11072f1980f7SBram Moolenaar    enddef
11087a9cbca0SBram Moolenaar    var Funcref: func: number = function('RetNumber')
1109c0c71e9dSBram Moolenaar    Funcref()->assert_equal(123)
11102f1980f7SBram Moolenaar  END
11112f1980f7SBram Moolenaar  CheckScriptSuccess(lines)
11120f60e80fSBram Moolenaar
11130f60e80fSBram Moolenaar  lines =<< trim END
11140f60e80fSBram Moolenaar    vim9script
11150f60e80fSBram Moolenaar    def RetNumber(): number
11160f60e80fSBram Moolenaar      return 123
11170f60e80fSBram Moolenaar    enddef
11180f60e80fSBram Moolenaar    def Bar(F: func: number): number
11190f60e80fSBram Moolenaar      return F()
11200f60e80fSBram Moolenaar    enddef
11217a9cbca0SBram Moolenaar    var Funcref = function('RetNumber')
1122c0c71e9dSBram Moolenaar    Bar(Funcref)->assert_equal(123)
11230f60e80fSBram Moolenaar  END
11240f60e80fSBram Moolenaar  CheckScriptSuccess(lines)
1125bfba8651SBram Moolenaar
1126bfba8651SBram Moolenaar  lines =<< trim END
1127bfba8651SBram Moolenaar    vim9script
1128bfba8651SBram Moolenaar    def UseNumber(nr: number)
1129bfba8651SBram Moolenaar      echo nr
1130bfba8651SBram Moolenaar    enddef
11317a9cbca0SBram Moolenaar    var Funcref: func(number) = function('UseNumber')
1132bfba8651SBram Moolenaar    Funcref(123)
1133bfba8651SBram Moolenaar  END
1134bfba8651SBram Moolenaar  CheckScriptSuccess(lines)
1135b8070e31SBram Moolenaar
1136b8070e31SBram Moolenaar  lines =<< trim END
1137b8070e31SBram Moolenaar    vim9script
1138b8070e31SBram Moolenaar    def UseNumber(nr: number)
1139b8070e31SBram Moolenaar      echo nr
1140b8070e31SBram Moolenaar    enddef
11417a9cbca0SBram Moolenaar    var Funcref: func(string) = function('UseNumber')
1142b8070e31SBram Moolenaar  END
11435e654230SBram Moolenaar  CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
11444fc224caSBram Moolenaar
11454fc224caSBram Moolenaar  lines =<< trim END
11464fc224caSBram Moolenaar    vim9script
11474fc224caSBram Moolenaar    def EchoNr(nr = 34)
11484fc224caSBram Moolenaar      g:echo = nr
11494fc224caSBram Moolenaar    enddef
11507a9cbca0SBram Moolenaar    var Funcref: func(?number) = function('EchoNr')
11514fc224caSBram Moolenaar    Funcref()
1152c0c71e9dSBram Moolenaar    g:echo->assert_equal(34)
11534fc224caSBram Moolenaar    Funcref(123)
1154c0c71e9dSBram Moolenaar    g:echo->assert_equal(123)
11554fc224caSBram Moolenaar  END
11564fc224caSBram Moolenaar  CheckScriptSuccess(lines)
1157ace6132aSBram Moolenaar
1158ace6132aSBram Moolenaar  lines =<< trim END
1159ace6132aSBram Moolenaar    vim9script
1160ace6132aSBram Moolenaar    def EchoList(...l: list<number>)
1161ace6132aSBram Moolenaar      g:echo = l
1162ace6132aSBram Moolenaar    enddef
11637a9cbca0SBram Moolenaar    var Funcref: func(...list<number>) = function('EchoList')
1164ace6132aSBram Moolenaar    Funcref()
1165c0c71e9dSBram Moolenaar    g:echo->assert_equal([])
1166ace6132aSBram Moolenaar    Funcref(1, 2, 3)
1167c0c71e9dSBram Moolenaar    g:echo->assert_equal([1, 2, 3])
1168ace6132aSBram Moolenaar  END
1169ace6132aSBram Moolenaar  CheckScriptSuccess(lines)
117001865adeSBram Moolenaar
117101865adeSBram Moolenaar  lines =<< trim END
117201865adeSBram Moolenaar    vim9script
117301865adeSBram Moolenaar    def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
117401865adeSBram Moolenaar      g:optarg = opt
117501865adeSBram Moolenaar      g:listarg = l
117601865adeSBram Moolenaar      return nr
117701865adeSBram Moolenaar    enddef
11787a9cbca0SBram Moolenaar    var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
1179c0c71e9dSBram Moolenaar    Funcref(10)->assert_equal(10)
1180c0c71e9dSBram Moolenaar    g:optarg->assert_equal(12)
1181c0c71e9dSBram Moolenaar    g:listarg->assert_equal([])
118201865adeSBram Moolenaar
1183c0c71e9dSBram Moolenaar    Funcref(11, 22)->assert_equal(11)
1184c0c71e9dSBram Moolenaar    g:optarg->assert_equal(22)
1185c0c71e9dSBram Moolenaar    g:listarg->assert_equal([])
118601865adeSBram Moolenaar
1187c0c71e9dSBram Moolenaar    Funcref(17, 18, 1, 2, 3)->assert_equal(17)
1188c0c71e9dSBram Moolenaar    g:optarg->assert_equal(18)
1189c0c71e9dSBram Moolenaar    g:listarg->assert_equal([1, 2, 3])
119001865adeSBram Moolenaar  END
119101865adeSBram Moolenaar  CheckScriptSuccess(lines)
11921df8b3fbSBram Moolenaarenddef
11931df8b3fbSBram Moolenaar
11941df8b3fbSBram Moolenaarlet SomeFunc = function('len')
11951df8b3fbSBram Moolenaarlet NotAFunc = 'text'
11961df8b3fbSBram Moolenaar
119799aaf0ceSBram Moolenaardef CombineFuncrefTypes()
1198f5be8cdbSBram Moolenaar  # same arguments, different return type
11997a9cbca0SBram Moolenaar  var Ref1: func(bool): string
12007a9cbca0SBram Moolenaar  var Ref2: func(bool): number
12017a9cbca0SBram Moolenaar  var Ref3: func(bool): any
120299aaf0ceSBram Moolenaar  Ref3 = g:cond ? Ref1 : Ref2
120399aaf0ceSBram Moolenaar
1204f5be8cdbSBram Moolenaar  # different number of arguments
12057a9cbca0SBram Moolenaar  var Refa1: func(bool): number
12067a9cbca0SBram Moolenaar  var Refa2: func(bool, number): number
12077a9cbca0SBram Moolenaar  var Refa3: func: number
120899aaf0ceSBram Moolenaar  Refa3 = g:cond ? Refa1 : Refa2
120999aaf0ceSBram Moolenaar
1210f5be8cdbSBram Moolenaar  # different argument types
12117a9cbca0SBram Moolenaar  var Refb1: func(bool, string): number
12127a9cbca0SBram Moolenaar  var Refb2: func(string, number): number
12137a9cbca0SBram Moolenaar  var Refb3: func(any, any): number
121499aaf0ceSBram Moolenaar  Refb3 = g:cond ? Refb1 : Refb2
121599aaf0ceSBram Moolenaarenddef
121699aaf0ceSBram Moolenaar
12175deeb3f1SBram Moolenaardef FuncWithForwardCall()
12181df8b3fbSBram Moolenaar  return g:DefinedEvenLater("yes")
12195deeb3f1SBram Moolenaarenddef
12205deeb3f1SBram Moolenaar
12215deeb3f1SBram Moolenaardef DefinedEvenLater(arg: string): string
12225deeb3f1SBram Moolenaar  return arg
12235deeb3f1SBram Moolenaarenddef
12245deeb3f1SBram Moolenaar
12255deeb3f1SBram Moolenaardef Test_error_in_nested_function()
1226f5be8cdbSBram Moolenaar  # Error in called function requires unwinding the call stack.
122744d6652dSBram Moolenaar  assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
12285deeb3f1SBram Moolenaarenddef
12295deeb3f1SBram Moolenaar
12305deeb3f1SBram Moolenaardef Test_return_type_wrong()
12315a849da5SBram Moolenaar  CheckScriptFailure([
12325a849da5SBram Moolenaar        'def Func(): number',
12335a849da5SBram Moolenaar        'return "a"',
12345a849da5SBram Moolenaar        'enddef',
12355a849da5SBram Moolenaar        'defcompile'], 'expected number but got string')
12362d870f8dSBram Moolenaar  delfunc! g:Func
12375a849da5SBram Moolenaar  CheckScriptFailure([
12385a849da5SBram Moolenaar        'def Func(): string',
12395a849da5SBram Moolenaar        'return 1',
12405a849da5SBram Moolenaar        'enddef',
12415a849da5SBram Moolenaar        'defcompile'], 'expected string but got number')
12422d870f8dSBram Moolenaar  delfunc! g:Func
12435a849da5SBram Moolenaar  CheckScriptFailure([
12445a849da5SBram Moolenaar        'def Func(): void',
12455a849da5SBram Moolenaar        'return "a"',
12465a849da5SBram Moolenaar        'enddef',
12475a849da5SBram Moolenaar        'defcompile'],
12485a849da5SBram Moolenaar        'E1096: Returning a value in a function without a return type')
12492d870f8dSBram Moolenaar  delfunc! g:Func
12505a849da5SBram Moolenaar  CheckScriptFailure([
12515a849da5SBram Moolenaar        'def Func()',
12525a849da5SBram Moolenaar        'return "a"',
12535a849da5SBram Moolenaar        'enddef',
12545a849da5SBram Moolenaar        'defcompile'],
12555a849da5SBram Moolenaar        'E1096: Returning a value in a function without a return type')
12562d870f8dSBram Moolenaar  delfunc! g:Func
12575deeb3f1SBram Moolenaar
12585a849da5SBram Moolenaar  CheckScriptFailure([
12595a849da5SBram Moolenaar        'def Func(): number',
12605a849da5SBram Moolenaar        'return',
12615a849da5SBram Moolenaar        'enddef',
12625a849da5SBram Moolenaar        'defcompile'], 'E1003:')
12632d870f8dSBram Moolenaar  delfunc! g:Func
12645deeb3f1SBram Moolenaar
12655deeb3f1SBram Moolenaar  CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
12662d870f8dSBram Moolenaar  delfunc! g:Func
12675deeb3f1SBram Moolenaar  CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
12682d870f8dSBram Moolenaar  delfunc! g:Func
1269ee4e0c1eSBram Moolenaar  CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
12702d870f8dSBram Moolenaar  delfunc! g:Func
12715a849da5SBram Moolenaar
12725a849da5SBram Moolenaar  CheckScriptFailure([
12735a849da5SBram Moolenaar        'vim9script',
12745a849da5SBram Moolenaar        'def FuncB()',
12755a849da5SBram Moolenaar        '  return 123',
12765a849da5SBram Moolenaar        'enddef',
12775a849da5SBram Moolenaar        'def FuncA()',
12785a849da5SBram Moolenaar        '   FuncB()',
12795a849da5SBram Moolenaar        'enddef',
12805a849da5SBram Moolenaar        'defcompile'], 'E1096:')
12815deeb3f1SBram Moolenaarenddef
12825deeb3f1SBram Moolenaar
12835deeb3f1SBram Moolenaardef Test_arg_type_wrong()
12845deeb3f1SBram Moolenaar  CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
1285ee4e0c1eSBram Moolenaar  CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
1286f93c7feaSBram Moolenaar  CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
12876e949784SBram Moolenaar  CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
12885deeb3f1SBram Moolenaarenddef
12895deeb3f1SBram Moolenaar
129086cdb8a4SBram Moolenaardef Test_white_space_before_comma()
129186cdb8a4SBram Moolenaar  var lines =<< trim END
129286cdb8a4SBram Moolenaar    vim9script
129386cdb8a4SBram Moolenaar    def Func(a: number , b: number)
129486cdb8a4SBram Moolenaar    enddef
129586cdb8a4SBram Moolenaar  END
129686cdb8a4SBram Moolenaar  CheckScriptFailure(lines, 'E1068:')
129786cdb8a4SBram Moolenaarenddef
129886cdb8a4SBram Moolenaar
1299608d78fbSBram Moolenaardef Test_white_space_after_comma()
1300608d78fbSBram Moolenaar  var lines =<< trim END
1301608d78fbSBram Moolenaar    vim9script
1302608d78fbSBram Moolenaar    def Func(a: number,b: number)
1303608d78fbSBram Moolenaar    enddef
1304608d78fbSBram Moolenaar  END
1305608d78fbSBram Moolenaar  CheckScriptFailure(lines, 'E1069:')
1306608d78fbSBram Moolenaar
1307608d78fbSBram Moolenaar  # OK in legacy function
1308608d78fbSBram Moolenaar  lines =<< trim END
1309608d78fbSBram Moolenaar    vim9script
1310608d78fbSBram Moolenaar    func Func(a,b)
1311608d78fbSBram Moolenaar    endfunc
1312608d78fbSBram Moolenaar  END
1313608d78fbSBram Moolenaar  CheckScriptSuccess(lines)
1314608d78fbSBram Moolenaarenddef
1315608d78fbSBram Moolenaar
13165deeb3f1SBram Moolenaardef Test_vim9script_call()
13177a9cbca0SBram Moolenaar  var lines =<< trim END
13185deeb3f1SBram Moolenaar    vim9script
13197a9cbca0SBram Moolenaar    var name = ''
13205deeb3f1SBram Moolenaar    def MyFunc(arg: string)
13217a9cbca0SBram Moolenaar       name = arg
13225deeb3f1SBram Moolenaar    enddef
13235deeb3f1SBram Moolenaar    MyFunc('foobar')
13247a9cbca0SBram Moolenaar    name->assert_equal('foobar')
13255deeb3f1SBram Moolenaar
13267a9cbca0SBram Moolenaar    var str = 'barfoo'
13275deeb3f1SBram Moolenaar    str->MyFunc()
13287a9cbca0SBram Moolenaar    name->assert_equal('barfoo')
13295deeb3f1SBram Moolenaar
13306797966dSBram Moolenaar    g:value = 'value'
13315deeb3f1SBram Moolenaar    g:value->MyFunc()
13327a9cbca0SBram Moolenaar    name->assert_equal('value')
13335deeb3f1SBram Moolenaar
13347a9cbca0SBram Moolenaar    var listvar = []
13355deeb3f1SBram Moolenaar    def ListFunc(arg: list<number>)
13365deeb3f1SBram Moolenaar       listvar = arg
13375deeb3f1SBram Moolenaar    enddef
13385deeb3f1SBram Moolenaar    [1, 2, 3]->ListFunc()
1339c0c71e9dSBram Moolenaar    listvar->assert_equal([1, 2, 3])
13405deeb3f1SBram Moolenaar
13417a9cbca0SBram Moolenaar    var dictvar = {}
13425deeb3f1SBram Moolenaar    def DictFunc(arg: dict<number>)
13435deeb3f1SBram Moolenaar       dictvar = arg
13445deeb3f1SBram Moolenaar    enddef
1345e0de171eSBram Moolenaar    {a: 1, b: 2}->DictFunc()
1346e0de171eSBram Moolenaar    dictvar->assert_equal({a: 1, b: 2})
13475deeb3f1SBram Moolenaar    def CompiledDict()
1348e0de171eSBram Moolenaar      {a: 3, b: 4}->DictFunc()
13495deeb3f1SBram Moolenaar    enddef
13505deeb3f1SBram Moolenaar    CompiledDict()
1351e0de171eSBram Moolenaar    dictvar->assert_equal({a: 3, b: 4})
13525deeb3f1SBram Moolenaar
1353e0de171eSBram Moolenaar    {a: 3, b: 4}->DictFunc()
1354e0de171eSBram Moolenaar    dictvar->assert_equal({a: 3, b: 4})
13555deeb3f1SBram Moolenaar
13565deeb3f1SBram Moolenaar    ('text')->MyFunc()
13577a9cbca0SBram Moolenaar    name->assert_equal('text')
13585deeb3f1SBram Moolenaar    ("some")->MyFunc()
13597a9cbca0SBram Moolenaar    name->assert_equal('some')
1360e6b5324eSBram Moolenaar
136113e12b8aSBram Moolenaar    # line starting with single quote is not a mark
136210409562SBram Moolenaar    # line starting with double quote can be a method call
13633d48e25dSBram Moolenaar    'asdfasdf'->MyFunc()
13647a9cbca0SBram Moolenaar    name->assert_equal('asdfasdf')
136510409562SBram Moolenaar    "xyz"->MyFunc()
13667a9cbca0SBram Moolenaar    name->assert_equal('xyz')
13673d48e25dSBram Moolenaar
13683d48e25dSBram Moolenaar    def UseString()
13693d48e25dSBram Moolenaar      'xyork'->MyFunc()
13703d48e25dSBram Moolenaar    enddef
13713d48e25dSBram Moolenaar    UseString()
13727a9cbca0SBram Moolenaar    name->assert_equal('xyork')
13733d48e25dSBram Moolenaar
137410409562SBram Moolenaar    def UseString2()
137510409562SBram Moolenaar      "knife"->MyFunc()
137610409562SBram Moolenaar    enddef
137710409562SBram Moolenaar    UseString2()
13787a9cbca0SBram Moolenaar    name->assert_equal('knife')
137910409562SBram Moolenaar
138013e12b8aSBram Moolenaar    # prepending a colon makes it a mark
138113e12b8aSBram Moolenaar    new
138213e12b8aSBram Moolenaar    setline(1, ['aaa', 'bbb', 'ccc'])
138313e12b8aSBram Moolenaar    normal! 3Gmt1G
138413e12b8aSBram Moolenaar    :'t
1385c0c71e9dSBram Moolenaar    getcurpos()[1]->assert_equal(3)
138613e12b8aSBram Moolenaar    bwipe!
138713e12b8aSBram Moolenaar
1388e6b5324eSBram Moolenaar    MyFunc(
1389e6b5324eSBram Moolenaar        'continued'
1390e6b5324eSBram Moolenaar        )
1391e6b5324eSBram Moolenaar    assert_equal('continued',
13927a9cbca0SBram Moolenaar            name
1393e6b5324eSBram Moolenaar            )
1394e6b5324eSBram Moolenaar
1395e6b5324eSBram Moolenaar    call MyFunc(
1396e6b5324eSBram Moolenaar        'more'
1397e6b5324eSBram Moolenaar          ..
1398e6b5324eSBram Moolenaar          'lines'
1399e6b5324eSBram Moolenaar        )
1400e6b5324eSBram Moolenaar    assert_equal(
1401e6b5324eSBram Moolenaar        'morelines',
14027a9cbca0SBram Moolenaar        name)
14035deeb3f1SBram Moolenaar  END
14045deeb3f1SBram Moolenaar  writefile(lines, 'Xcall.vim')
14055deeb3f1SBram Moolenaar  source Xcall.vim
14065deeb3f1SBram Moolenaar  delete('Xcall.vim')
14075deeb3f1SBram Moolenaarenddef
14085deeb3f1SBram Moolenaar
14095deeb3f1SBram Moolenaardef Test_vim9script_call_fail_decl()
14107a9cbca0SBram Moolenaar  var lines =<< trim END
14115deeb3f1SBram Moolenaar    vim9script
14127a9cbca0SBram Moolenaar    var name = ''
14135deeb3f1SBram Moolenaar    def MyFunc(arg: string)
14147a9cbca0SBram Moolenaar       var name = 123
14155deeb3f1SBram Moolenaar    enddef
1416822ba247SBram Moolenaar    defcompile
14175deeb3f1SBram Moolenaar  END
14186c4bfe4bSBram Moolenaar  CheckScriptFailure(lines, 'E1054:')
14195deeb3f1SBram Moolenaarenddef
14205deeb3f1SBram Moolenaar
142165b9545fSBram Moolenaardef Test_vim9script_call_fail_type()
14227a9cbca0SBram Moolenaar  var lines =<< trim END
142365b9545fSBram Moolenaar    vim9script
142465b9545fSBram Moolenaar    def MyFunc(arg: string)
142565b9545fSBram Moolenaar      echo arg
142665b9545fSBram Moolenaar    enddef
142765b9545fSBram Moolenaar    MyFunc(1234)
142865b9545fSBram Moolenaar  END
14297707228aSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
143065b9545fSBram Moolenaarenddef
143165b9545fSBram Moolenaar
14325deeb3f1SBram Moolenaardef Test_vim9script_call_fail_const()
14337a9cbca0SBram Moolenaar  var lines =<< trim END
14345deeb3f1SBram Moolenaar    vim9script
14355deeb3f1SBram Moolenaar    const var = ''
14365deeb3f1SBram Moolenaar    def MyFunc(arg: string)
14375deeb3f1SBram Moolenaar       var = 'asdf'
14385deeb3f1SBram Moolenaar    enddef
1439822ba247SBram Moolenaar    defcompile
14405deeb3f1SBram Moolenaar  END
14415deeb3f1SBram Moolenaar  writefile(lines, 'Xcall_const.vim')
14429bd5d879SBram Moolenaar  assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
14435deeb3f1SBram Moolenaar  delete('Xcall_const.vim')
14443bdc90b7SBram Moolenaar
14453bdc90b7SBram Moolenaar  lines =<< trim END
14463bdc90b7SBram Moolenaar      const g:Aconst = 77
14473bdc90b7SBram Moolenaar      def Change()
14483bdc90b7SBram Moolenaar        # comment
14493bdc90b7SBram Moolenaar        g:Aconst = 99
14503bdc90b7SBram Moolenaar      enddef
14513bdc90b7SBram Moolenaar      call Change()
14523bdc90b7SBram Moolenaar      unlet g:Aconst
14533bdc90b7SBram Moolenaar  END
14541dcf55d4SBram Moolenaar  CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2)
14555deeb3f1SBram Moolenaarenddef
14565deeb3f1SBram Moolenaar
14575deeb3f1SBram Moolenaar" Test that inside :function a Python function can be defined, :def is not
14585deeb3f1SBram Moolenaar" recognized.
14595deeb3f1SBram Moolenaarfunc Test_function_python()
14605deeb3f1SBram Moolenaar  CheckFeature python3
1461727345ebSBram Moolenaar  let py = 'python3'
14625deeb3f1SBram Moolenaar  execute py "<< EOF"
14635deeb3f1SBram Moolenaardef do_something():
14645deeb3f1SBram Moolenaar  return 1
14655deeb3f1SBram MoolenaarEOF
14665deeb3f1SBram Moolenaarendfunc
14675deeb3f1SBram Moolenaar
14685deeb3f1SBram Moolenaardef Test_delfunc()
14697a9cbca0SBram Moolenaar  var lines =<< trim END
14705deeb3f1SBram Moolenaar    vim9script
14714c17ad94SBram Moolenaar    def g:GoneSoon()
14725deeb3f1SBram Moolenaar      echo 'hello'
14735deeb3f1SBram Moolenaar    enddef
14745deeb3f1SBram Moolenaar
14755deeb3f1SBram Moolenaar    def CallGoneSoon()
14765deeb3f1SBram Moolenaar      GoneSoon()
14775deeb3f1SBram Moolenaar    enddef
1478822ba247SBram Moolenaar    defcompile
14795deeb3f1SBram Moolenaar
14804c17ad94SBram Moolenaar    delfunc g:GoneSoon
14815deeb3f1SBram Moolenaar    CallGoneSoon()
14825deeb3f1SBram Moolenaar  END
14835deeb3f1SBram Moolenaar  writefile(lines, 'XToDelFunc')
14849bd5d879SBram Moolenaar  assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
14859bd5d879SBram Moolenaar  assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
14865deeb3f1SBram Moolenaar
14875deeb3f1SBram Moolenaar  delete('XToDelFunc')
14885deeb3f1SBram Moolenaarenddef
14895deeb3f1SBram Moolenaar
14905deeb3f1SBram Moolenaardef Test_redef_failure()
1491d2c61705SBram Moolenaar  writefile(['def Func0(): string',  'return "Func0"', 'enddef'], 'Xdef')
14925deeb3f1SBram Moolenaar  so Xdef
1493d2c61705SBram Moolenaar  writefile(['def Func1(): string',  'return "Func1"', 'enddef'], 'Xdef')
14945deeb3f1SBram Moolenaar  so Xdef
1495d2c61705SBram Moolenaar  writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
14969bd5d879SBram Moolenaar  assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
1497d2c61705SBram Moolenaar  writefile(['def Func2(): string',  'return "Func2"', 'enddef'], 'Xdef')
14985deeb3f1SBram Moolenaar  so Xdef
1499d2c61705SBram Moolenaar  delete('Xdef')
15005deeb3f1SBram Moolenaar
1501701cc6caSBram Moolenaar  assert_fails('g:Func0()', 'E1091:')
1502c0c71e9dSBram Moolenaar  g:Func1()->assert_equal('Func1')
1503c0c71e9dSBram Moolenaar  g:Func2()->assert_equal('Func2')
15045deeb3f1SBram Moolenaar
15055deeb3f1SBram Moolenaar  delfunc! Func0
15065deeb3f1SBram Moolenaar  delfunc! Func1
15075deeb3f1SBram Moolenaar  delfunc! Func2
15085deeb3f1SBram Moolenaarenddef
15095deeb3f1SBram Moolenaar
1510f93c7feaSBram Moolenaardef Test_vim9script_func()
15117a9cbca0SBram Moolenaar  var lines =<< trim END
1512f93c7feaSBram Moolenaar    vim9script
1513f93c7feaSBram Moolenaar    func Func(arg)
1514f93c7feaSBram Moolenaar      echo a:arg
1515f93c7feaSBram Moolenaar    endfunc
1516f93c7feaSBram Moolenaar    Func('text')
1517f93c7feaSBram Moolenaar  END
1518f93c7feaSBram Moolenaar  writefile(lines, 'XVim9Func')
1519f93c7feaSBram Moolenaar  so XVim9Func
1520f93c7feaSBram Moolenaar
1521f93c7feaSBram Moolenaar  delete('XVim9Func')
1522f93c7feaSBram Moolenaarenddef
1523f93c7feaSBram Moolenaar
15245deeb3f1SBram Moolenaarlet s:funcResult = 0
15255deeb3f1SBram Moolenaar
15265deeb3f1SBram Moolenaardef FuncNoArgNoRet()
15275390099aSBram Moolenaar  s:funcResult = 11
15285deeb3f1SBram Moolenaarenddef
15295deeb3f1SBram Moolenaar
15305deeb3f1SBram Moolenaardef FuncNoArgRetNumber(): number
15315390099aSBram Moolenaar  s:funcResult = 22
15325deeb3f1SBram Moolenaar  return 1234
15335deeb3f1SBram Moolenaarenddef
15345deeb3f1SBram Moolenaar
1535ec5929d0SBram Moolenaardef FuncNoArgRetString(): string
15365390099aSBram Moolenaar  s:funcResult = 45
1537ec5929d0SBram Moolenaar  return 'text'
1538ec5929d0SBram Moolenaarenddef
1539ec5929d0SBram Moolenaar
15405deeb3f1SBram Moolenaardef FuncOneArgNoRet(arg: number)
15415390099aSBram Moolenaar  s:funcResult = arg
15425deeb3f1SBram Moolenaarenddef
15435deeb3f1SBram Moolenaar
15445deeb3f1SBram Moolenaardef FuncOneArgRetNumber(arg: number): number
15455390099aSBram Moolenaar  s:funcResult = arg
15465deeb3f1SBram Moolenaar  return arg
15475deeb3f1SBram Moolenaarenddef
15485deeb3f1SBram Moolenaar
154908938eebSBram Moolenaardef FuncTwoArgNoRet(one: bool, two: number)
15505390099aSBram Moolenaar  s:funcResult = two
155108938eebSBram Moolenaarenddef
155208938eebSBram Moolenaar
1553ec5929d0SBram Moolenaardef FuncOneArgRetString(arg: string): string
1554ec5929d0SBram Moolenaar  return arg
1555ec5929d0SBram Moolenaarenddef
1556ec5929d0SBram Moolenaar
15578922860aSBram Moolenaardef FuncOneArgRetAny(arg: any): any
15588922860aSBram Moolenaar  return arg
15598922860aSBram Moolenaarenddef
15608922860aSBram Moolenaar
15615deeb3f1SBram Moolenaardef Test_func_type()
15627a9cbca0SBram Moolenaar  var Ref1: func()
15635390099aSBram Moolenaar  s:funcResult = 0
15645deeb3f1SBram Moolenaar  Ref1 = FuncNoArgNoRet
15655deeb3f1SBram Moolenaar  Ref1()
1566c0c71e9dSBram Moolenaar  s:funcResult->assert_equal(11)
15674c683750SBram Moolenaar
15687a9cbca0SBram Moolenaar  var Ref2: func
15695390099aSBram Moolenaar  s:funcResult = 0
15704c683750SBram Moolenaar  Ref2 = FuncNoArgNoRet
15714c683750SBram Moolenaar  Ref2()
1572c0c71e9dSBram Moolenaar  s:funcResult->assert_equal(11)
15734c683750SBram Moolenaar
15745390099aSBram Moolenaar  s:funcResult = 0
15754c683750SBram Moolenaar  Ref2 = FuncOneArgNoRet
15764c683750SBram Moolenaar  Ref2(12)
1577c0c71e9dSBram Moolenaar  s:funcResult->assert_equal(12)
15784c683750SBram Moolenaar
15795390099aSBram Moolenaar  s:funcResult = 0
15804c683750SBram Moolenaar  Ref2 = FuncNoArgRetNumber
1581c0c71e9dSBram Moolenaar  Ref2()->assert_equal(1234)
1582c0c71e9dSBram Moolenaar  s:funcResult->assert_equal(22)
15834c683750SBram Moolenaar
15845390099aSBram Moolenaar  s:funcResult = 0
15854c683750SBram Moolenaar  Ref2 = FuncOneArgRetNumber
1586c0c71e9dSBram Moolenaar  Ref2(13)->assert_equal(13)
1587c0c71e9dSBram Moolenaar  s:funcResult->assert_equal(13)
15885deeb3f1SBram Moolenaarenddef
15895deeb3f1SBram Moolenaar
15909978d473SBram Moolenaardef Test_repeat_return_type()
15917a9cbca0SBram Moolenaar  var res = 0
15929978d473SBram Moolenaar  for n in repeat([1], 3)
15939978d473SBram Moolenaar    res += n
15949978d473SBram Moolenaar  endfor
1595c0c71e9dSBram Moolenaar  res->assert_equal(3)
1596fce82b3aSBram Moolenaar
1597fce82b3aSBram Moolenaar  res = 0
1598fce82b3aSBram Moolenaar  for n in add([1, 2], 3)
1599fce82b3aSBram Moolenaar    res += n
1600fce82b3aSBram Moolenaar  endfor
1601c0c71e9dSBram Moolenaar  res->assert_equal(6)
16029978d473SBram Moolenaarenddef
16039978d473SBram Moolenaar
1604846178a7SBram Moolenaardef Test_argv_return_type()
1605846178a7SBram Moolenaar  next fileone filetwo
16067a9cbca0SBram Moolenaar  var res = ''
1607846178a7SBram Moolenaar  for name in argv()
1608846178a7SBram Moolenaar    res ..= name
1609846178a7SBram Moolenaar  endfor
1610c0c71e9dSBram Moolenaar  res->assert_equal('fileonefiletwo')
1611846178a7SBram Moolenaarenddef
1612846178a7SBram Moolenaar
1613ec5929d0SBram Moolenaardef Test_func_type_part()
16147a9cbca0SBram Moolenaar  var RefVoid: func: void
1615ec5929d0SBram Moolenaar  RefVoid = FuncNoArgNoRet
1616ec5929d0SBram Moolenaar  RefVoid = FuncOneArgNoRet
16177a9cbca0SBram Moolenaar  CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
16187a9cbca0SBram Moolenaar  CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
1619ec5929d0SBram Moolenaar
16207a9cbca0SBram Moolenaar  var RefAny: func(): any
1621ec5929d0SBram Moolenaar  RefAny = FuncNoArgRetNumber
1622ec5929d0SBram Moolenaar  RefAny = FuncNoArgRetString
16237a9cbca0SBram Moolenaar  CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
16247a9cbca0SBram Moolenaar  CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
1625ec5929d0SBram Moolenaar
16266abd3dc2SBram Moolenaar  var RefAnyNoArgs: func: any = RefAny
16276abd3dc2SBram Moolenaar
16287a9cbca0SBram Moolenaar  var RefNr: func: number
1629ec5929d0SBram Moolenaar  RefNr = FuncNoArgRetNumber
1630ec5929d0SBram Moolenaar  RefNr = FuncOneArgRetNumber
16317a9cbca0SBram Moolenaar  CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
16327a9cbca0SBram Moolenaar  CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
1633ec5929d0SBram Moolenaar
16347a9cbca0SBram Moolenaar  var RefStr: func: string
1635ec5929d0SBram Moolenaar  RefStr = FuncNoArgRetString
1636ec5929d0SBram Moolenaar  RefStr = FuncOneArgRetString
16377a9cbca0SBram Moolenaar  CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
16387a9cbca0SBram Moolenaar  CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
1639ec5929d0SBram Moolenaarenddef
1640ec5929d0SBram Moolenaar
16415deeb3f1SBram Moolenaardef Test_func_type_fails()
16427a9cbca0SBram Moolenaar  CheckDefFailure(['var ref1: func()'], 'E704:')
16435deeb3f1SBram Moolenaar
16447a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
16457a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
16467a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
16477a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
16487a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
16497a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(...bool) but got func(bool, number)')
165008938eebSBram Moolenaar
16517a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
16527a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
16537a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool)'], 'E1005:')
16547a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
16555deeb3f1SBram Moolenaarenddef
16565deeb3f1SBram Moolenaar
16578922860aSBram Moolenaardef Test_func_return_type()
16587a9cbca0SBram Moolenaar  var nr: number
16598922860aSBram Moolenaar  nr = FuncNoArgRetNumber()
1660c0c71e9dSBram Moolenaar  nr->assert_equal(1234)
16618922860aSBram Moolenaar
16628922860aSBram Moolenaar  nr = FuncOneArgRetAny(122)
1663c0c71e9dSBram Moolenaar  nr->assert_equal(122)
16648922860aSBram Moolenaar
16657a9cbca0SBram Moolenaar  var str: string
16668922860aSBram Moolenaar  str = FuncOneArgRetAny('yes')
1667c0c71e9dSBram Moolenaar  str->assert_equal('yes')
16688922860aSBram Moolenaar
16697a9cbca0SBram Moolenaar  CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
16708922860aSBram Moolenaarenddef
16718922860aSBram Moolenaar
16726abd3dc2SBram Moolenaardef Test_func_common_type()
16736abd3dc2SBram Moolenaar  def FuncOne(n: number): number
16746abd3dc2SBram Moolenaar    return n
16756abd3dc2SBram Moolenaar  enddef
16766abd3dc2SBram Moolenaar  def FuncTwo(s: string): number
16776abd3dc2SBram Moolenaar    return len(s)
16786abd3dc2SBram Moolenaar  enddef
16796abd3dc2SBram Moolenaar  def FuncThree(n: number, s: string): number
16806abd3dc2SBram Moolenaar    return n + len(s)
16816abd3dc2SBram Moolenaar  enddef
16826abd3dc2SBram Moolenaar  var list = [FuncOne, FuncTwo, FuncThree]
16836abd3dc2SBram Moolenaar  assert_equal(8, list[0](8))
16846abd3dc2SBram Moolenaar  assert_equal(4, list[1]('word'))
16856abd3dc2SBram Moolenaar  assert_equal(7, list[2](3, 'word'))
16866abd3dc2SBram Moolenaarenddef
16876abd3dc2SBram Moolenaar
16885e774c75SBram Moolenaardef MultiLine(
16895e774c75SBram Moolenaar    arg1: string,
16905e774c75SBram Moolenaar    arg2 = 1234,
16915e774c75SBram Moolenaar    ...rest: list<string>
16925e774c75SBram Moolenaar      ): string
16935e774c75SBram Moolenaar  return arg1 .. arg2 .. join(rest, '-')
16945e774c75SBram Moolenaarenddef
16955e774c75SBram Moolenaar
16962c330432SBram Moolenaardef MultiLineComment(
16972c330432SBram Moolenaar    arg1: string, # comment
16982c330432SBram Moolenaar    arg2 = 1234, # comment
16992c330432SBram Moolenaar    ...rest: list<string> # comment
17002c330432SBram Moolenaar      ): string # comment
17012c330432SBram Moolenaar  return arg1 .. arg2 .. join(rest, '-')
17022c330432SBram Moolenaarenddef
17032c330432SBram Moolenaar
17045e774c75SBram Moolenaardef Test_multiline()
1705c0c71e9dSBram Moolenaar  MultiLine('text')->assert_equal('text1234')
1706c0c71e9dSBram Moolenaar  MultiLine('text', 777)->assert_equal('text777')
1707c0c71e9dSBram Moolenaar  MultiLine('text', 777, 'one')->assert_equal('text777one')
1708c0c71e9dSBram Moolenaar  MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
17095e774c75SBram Moolenaarenddef
17105e774c75SBram Moolenaar
171123e03252SBram Moolenaarfunc Test_multiline_not_vim9()
1712c0c71e9dSBram Moolenaar  call MultiLine('text')->assert_equal('text1234')
1713c0c71e9dSBram Moolenaar  call MultiLine('text', 777)->assert_equal('text777')
1714c0c71e9dSBram Moolenaar  call MultiLine('text', 777, 'one')->assert_equal('text777one')
1715c0c71e9dSBram Moolenaar  call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
171623e03252SBram Moolenaarendfunc
171723e03252SBram Moolenaar
17185e774c75SBram Moolenaar
1719ee4e0c1eSBram Moolenaar" When using CheckScriptFailure() for the below test, E1010 is generated instead
1720ee4e0c1eSBram Moolenaar" of E1056.
1721ee4e0c1eSBram Moolenaarfunc Test_E1056_1059()
1722ee4e0c1eSBram Moolenaar  let caught_1056 = 0
1723ee4e0c1eSBram Moolenaar  try
1724ee4e0c1eSBram Moolenaar    def F():
1725ee4e0c1eSBram Moolenaar      return 1
1726ee4e0c1eSBram Moolenaar    enddef
1727ee4e0c1eSBram Moolenaar  catch /E1056:/
1728ee4e0c1eSBram Moolenaar    let caught_1056 = 1
1729ee4e0c1eSBram Moolenaar  endtry
1730c0c71e9dSBram Moolenaar  eval caught_1056->assert_equal(1)
1731ee4e0c1eSBram Moolenaar
1732ee4e0c1eSBram Moolenaar  let caught_1059 = 0
1733ee4e0c1eSBram Moolenaar  try
1734ee4e0c1eSBram Moolenaar    def F5(items : list)
1735ee4e0c1eSBram Moolenaar      echo 'a'
1736ee4e0c1eSBram Moolenaar    enddef
1737ee4e0c1eSBram Moolenaar  catch /E1059:/
1738ee4e0c1eSBram Moolenaar    let caught_1059 = 1
1739ee4e0c1eSBram Moolenaar  endtry
1740c0c71e9dSBram Moolenaar  eval caught_1059->assert_equal(1)
1741ee4e0c1eSBram Moolenaarendfunc
17425deeb3f1SBram Moolenaar
1743015f4267SBram Moolenaarfunc DelMe()
1744015f4267SBram Moolenaar  echo 'DelMe'
1745015f4267SBram Moolenaarendfunc
1746015f4267SBram Moolenaar
1747bf8feb5aSBram Moolenaardef Test_error_reporting()
1748bf8feb5aSBram Moolenaar  # comment lines at the start of the function
17497a9cbca0SBram Moolenaar  var lines =<< trim END
1750bf8feb5aSBram Moolenaar    " comment
1751bf8feb5aSBram Moolenaar    def Func()
1752bf8feb5aSBram Moolenaar      # comment
1753bf8feb5aSBram Moolenaar      # comment
1754bf8feb5aSBram Moolenaar      invalid
1755bf8feb5aSBram Moolenaar    enddef
1756bf8feb5aSBram Moolenaar    defcompile
1757bf8feb5aSBram Moolenaar  END
175808052228SBram Moolenaar  writefile(lines, 'Xdef')
1759bf8feb5aSBram Moolenaar  try
1760bf8feb5aSBram Moolenaar    source Xdef
17617517ffdbSBram Moolenaar    assert_report('should have failed')
1762bf8feb5aSBram Moolenaar  catch /E476:/
1763c0c71e9dSBram Moolenaar    v:exception->assert_match('Invalid command: invalid')
1764c0c71e9dSBram Moolenaar    v:throwpoint->assert_match(', line 3$')
1765bf8feb5aSBram Moolenaar  endtry
17662d870f8dSBram Moolenaar  delfunc! g:Func
1767bf8feb5aSBram Moolenaar
1768bf8feb5aSBram Moolenaar  # comment lines after the start of the function
1769bf8feb5aSBram Moolenaar  lines =<< trim END
1770bf8feb5aSBram Moolenaar    " comment
1771bf8feb5aSBram Moolenaar    def Func()
17727a9cbca0SBram Moolenaar      var x = 1234
1773bf8feb5aSBram Moolenaar      # comment
1774bf8feb5aSBram Moolenaar      # comment
1775bf8feb5aSBram Moolenaar      invalid
1776bf8feb5aSBram Moolenaar    enddef
1777bf8feb5aSBram Moolenaar    defcompile
1778bf8feb5aSBram Moolenaar  END
177908052228SBram Moolenaar  writefile(lines, 'Xdef')
1780bf8feb5aSBram Moolenaar  try
1781bf8feb5aSBram Moolenaar    source Xdef
17827517ffdbSBram Moolenaar    assert_report('should have failed')
1783bf8feb5aSBram Moolenaar  catch /E476:/
1784c0c71e9dSBram Moolenaar    v:exception->assert_match('Invalid command: invalid')
1785c0c71e9dSBram Moolenaar    v:throwpoint->assert_match(', line 4$')
1786bf8feb5aSBram Moolenaar  endtry
17872d870f8dSBram Moolenaar  delfunc! g:Func
1788bf8feb5aSBram Moolenaar
17897517ffdbSBram Moolenaar  lines =<< trim END
17907517ffdbSBram Moolenaar    vim9script
17917517ffdbSBram Moolenaar    def Func()
1792e0de171eSBram Moolenaar      var db = {foo: 1, bar: 2}
17937517ffdbSBram Moolenaar      # comment
17947a9cbca0SBram Moolenaar      var x = db.asdf
17957517ffdbSBram Moolenaar    enddef
17967517ffdbSBram Moolenaar    defcompile
17977517ffdbSBram Moolenaar    Func()
17987517ffdbSBram Moolenaar  END
179908052228SBram Moolenaar  writefile(lines, 'Xdef')
18007517ffdbSBram Moolenaar  try
18017517ffdbSBram Moolenaar    source Xdef
18027517ffdbSBram Moolenaar    assert_report('should have failed')
18037517ffdbSBram Moolenaar  catch /E716:/
1804c0c71e9dSBram Moolenaar    v:throwpoint->assert_match('_Func, line 3$')
18057517ffdbSBram Moolenaar  endtry
18062d870f8dSBram Moolenaar  delfunc! g:Func
18077517ffdbSBram Moolenaar
180808052228SBram Moolenaar  delete('Xdef')
1809bf8feb5aSBram Moolenaarenddef
1810bf8feb5aSBram Moolenaar
1811015f4267SBram Moolenaardef Test_deleted_function()
1812015f4267SBram Moolenaar  CheckDefExecFailure([
18137a9cbca0SBram Moolenaar      'var RefMe: func = function("g:DelMe")',
1814015f4267SBram Moolenaar      'delfunc g:DelMe',
1815015f4267SBram Moolenaar      'echo RefMe()'], 'E117:')
1816015f4267SBram Moolenaarenddef
1817015f4267SBram Moolenaar
1818015f4267SBram Moolenaardef Test_unknown_function()
1819015f4267SBram Moolenaar  CheckDefExecFailure([
18207a9cbca0SBram Moolenaar      'var Ref: func = function("NotExist")',
18219b7bf9e9SBram Moolenaar      'delfunc g:NotExist'], 'E700:')
1822015f4267SBram Moolenaarenddef
1823015f4267SBram Moolenaar
1824328eac2bSBram Moolenaardef RefFunc(Ref: func(any): any): string
1825c8cd2b34SBram Moolenaar  return Ref('more')
1826c8cd2b34SBram Moolenaarenddef
1827c8cd2b34SBram Moolenaar
1828c8cd2b34SBram Moolenaardef Test_closure_simple()
18297a9cbca0SBram Moolenaar  var local = 'some '
18302949cfdbSBram Moolenaar  RefFunc((s) => local .. s)->assert_equal('some more')
1831c8cd2b34SBram Moolenaarenddef
1832c8cd2b34SBram Moolenaar
1833bf67ea1aSBram Moolenaardef MakeRef()
18347a9cbca0SBram Moolenaar  var local = 'some '
18352949cfdbSBram Moolenaar  g:Ref = (s) => local .. s
1836bf67ea1aSBram Moolenaarenddef
1837bf67ea1aSBram Moolenaar
1838bf67ea1aSBram Moolenaardef Test_closure_ref_after_return()
1839bf67ea1aSBram Moolenaar  MakeRef()
1840c0c71e9dSBram Moolenaar  g:Ref('thing')->assert_equal('some thing')
1841bf67ea1aSBram Moolenaar  unlet g:Ref
1842bf67ea1aSBram Moolenaarenddef
1843bf67ea1aSBram Moolenaar
18445adc55cbSBram Moolenaardef MakeTwoRefs()
18457a9cbca0SBram Moolenaar  var local = ['some']
18462949cfdbSBram Moolenaar  g:Extend = (s) => local->add(s)
18472949cfdbSBram Moolenaar  g:Read = () => local
18485adc55cbSBram Moolenaarenddef
18495adc55cbSBram Moolenaar
18505adc55cbSBram Moolenaardef Test_closure_two_refs()
18515adc55cbSBram Moolenaar  MakeTwoRefs()
1852c0c71e9dSBram Moolenaar  join(g:Read(), ' ')->assert_equal('some')
18535adc55cbSBram Moolenaar  g:Extend('more')
1854c0c71e9dSBram Moolenaar  join(g:Read(), ' ')->assert_equal('some more')
18555adc55cbSBram Moolenaar  g:Extend('even')
1856c0c71e9dSBram Moolenaar  join(g:Read(), ' ')->assert_equal('some more even')
18575adc55cbSBram Moolenaar
18585adc55cbSBram Moolenaar  unlet g:Extend
18595adc55cbSBram Moolenaar  unlet g:Read
18605adc55cbSBram Moolenaarenddef
18615adc55cbSBram Moolenaar
18625adc55cbSBram Moolenaardef ReadRef(Ref: func(): list<string>): string
18635adc55cbSBram Moolenaar  return join(Ref(), ' ')
18645adc55cbSBram Moolenaarenddef
18655adc55cbSBram Moolenaar
18665e654230SBram Moolenaardef ExtendRef(Ref: func(string): list<string>, add: string)
18675adc55cbSBram Moolenaar  Ref(add)
18685adc55cbSBram Moolenaarenddef
18695adc55cbSBram Moolenaar
18705adc55cbSBram Moolenaardef Test_closure_two_indirect_refs()
1871f7779c63SBram Moolenaar  MakeTwoRefs()
1872c0c71e9dSBram Moolenaar  ReadRef(g:Read)->assert_equal('some')
18735adc55cbSBram Moolenaar  ExtendRef(g:Extend, 'more')
1874c0c71e9dSBram Moolenaar  ReadRef(g:Read)->assert_equal('some more')
18755adc55cbSBram Moolenaar  ExtendRef(g:Extend, 'even')
1876c0c71e9dSBram Moolenaar  ReadRef(g:Read)->assert_equal('some more even')
18775adc55cbSBram Moolenaar
18785adc55cbSBram Moolenaar  unlet g:Extend
18795adc55cbSBram Moolenaar  unlet g:Read
18805adc55cbSBram Moolenaarenddef
1881bf67ea1aSBram Moolenaar
18822fd4cd75SBram Moolenaardef MakeArgRefs(theArg: string)
18837a9cbca0SBram Moolenaar  var local = 'loc_val'
18842949cfdbSBram Moolenaar  g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s
18852fd4cd75SBram Moolenaarenddef
18862fd4cd75SBram Moolenaar
18872fd4cd75SBram Moolenaardef MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
18887a9cbca0SBram Moolenaar  var local = 'the_loc'
18892949cfdbSBram Moolenaar  g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)
18902fd4cd75SBram Moolenaarenddef
18912fd4cd75SBram Moolenaar
18922fd4cd75SBram Moolenaardef Test_closure_using_argument()
18932fd4cd75SBram Moolenaar  MakeArgRefs('arg_val')
1894c0c71e9dSBram Moolenaar  g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
18952fd4cd75SBram Moolenaar
18962fd4cd75SBram Moolenaar  MakeArgRefsVarargs('arg_val', 'one', 'two')
1897c0c71e9dSBram Moolenaar  g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
18982fd4cd75SBram Moolenaar
18992fd4cd75SBram Moolenaar  unlet g:UseArg
19002fd4cd75SBram Moolenaar  unlet g:UseVararg
190144ec21c4SBram Moolenaar
190244ec21c4SBram Moolenaar  var lines =<< trim END
190344ec21c4SBram Moolenaar      vim9script
190444ec21c4SBram Moolenaar      def Test(Fun: func(number): number): list<number>
190544ec21c4SBram Moolenaar        return map([1, 2, 3], (_, i) => Fun(i))
190644ec21c4SBram Moolenaar      enddef
190744ec21c4SBram Moolenaar      def Inc(nr: number): number
190844ec21c4SBram Moolenaar        return nr + 2
190944ec21c4SBram Moolenaar      enddef
191044ec21c4SBram Moolenaar      assert_equal([3, 4, 5], Test(Inc))
191144ec21c4SBram Moolenaar  END
191244ec21c4SBram Moolenaar  CheckScriptSuccess(lines)
19132fd4cd75SBram Moolenaarenddef
19142fd4cd75SBram Moolenaar
191585d5e2b7SBram Moolenaardef MakeGetAndAppendRefs()
191685d5e2b7SBram Moolenaar  var local = 'a'
191785d5e2b7SBram Moolenaar
191885d5e2b7SBram Moolenaar  def Append(arg: string)
191985d5e2b7SBram Moolenaar    local ..= arg
192085d5e2b7SBram Moolenaar  enddef
192185d5e2b7SBram Moolenaar  g:Append = Append
192285d5e2b7SBram Moolenaar
192385d5e2b7SBram Moolenaar  def Get(): string
192485d5e2b7SBram Moolenaar    return local
192585d5e2b7SBram Moolenaar  enddef
192685d5e2b7SBram Moolenaar  g:Get = Get
192785d5e2b7SBram Moolenaarenddef
192885d5e2b7SBram Moolenaar
192985d5e2b7SBram Moolenaardef Test_closure_append_get()
193085d5e2b7SBram Moolenaar  MakeGetAndAppendRefs()
193185d5e2b7SBram Moolenaar  g:Get()->assert_equal('a')
193285d5e2b7SBram Moolenaar  g:Append('-b')
193385d5e2b7SBram Moolenaar  g:Get()->assert_equal('a-b')
193485d5e2b7SBram Moolenaar  g:Append('-c')
193585d5e2b7SBram Moolenaar  g:Get()->assert_equal('a-b-c')
193685d5e2b7SBram Moolenaar
193785d5e2b7SBram Moolenaar  unlet g:Append
193885d5e2b7SBram Moolenaar  unlet g:Get
193985d5e2b7SBram Moolenaarenddef
1940b68b346eSBram Moolenaar
194104b12697SBram Moolenaardef Test_nested_closure()
19427a9cbca0SBram Moolenaar  var local = 'text'
194304b12697SBram Moolenaar  def Closure(arg: string): string
194404b12697SBram Moolenaar    return local .. arg
194504b12697SBram Moolenaar  enddef
1946c0c71e9dSBram Moolenaar  Closure('!!!')->assert_equal('text!!!')
194704b12697SBram Moolenaarenddef
194804b12697SBram Moolenaar
19496f5b6dfbSBram Moolenaarfunc GetResult(Ref)
19506f5b6dfbSBram Moolenaar  return a:Ref('some')
19516f5b6dfbSBram Moolenaarendfunc
19526f5b6dfbSBram Moolenaar
19536f5b6dfbSBram Moolenaardef Test_call_closure_not_compiled()
19547a9cbca0SBram Moolenaar  var text = 'text'
19552949cfdbSBram Moolenaar  g:Ref = (s) =>  s .. text
1956c0c71e9dSBram Moolenaar  GetResult(g:Ref)->assert_equal('sometext')
19576f5b6dfbSBram Moolenaarenddef
19586f5b6dfbSBram Moolenaar
19597cbfaa51SBram Moolenaardef Test_double_closure_fails()
19607a9cbca0SBram Moolenaar  var lines =<< trim END
19617cbfaa51SBram Moolenaar    vim9script
19627cbfaa51SBram Moolenaar    def Func()
19637a9cbca0SBram Moolenaar      var name = 0
19647cbfaa51SBram Moolenaar      for i in range(2)
19652949cfdbSBram Moolenaar          timer_start(0, () => name)
19667cbfaa51SBram Moolenaar      endfor
19677cbfaa51SBram Moolenaar    enddef
19687cbfaa51SBram Moolenaar    Func()
19697cbfaa51SBram Moolenaar  END
1970148ce7aeSBram Moolenaar  CheckScriptSuccess(lines)
19717cbfaa51SBram Moolenaarenddef
19727cbfaa51SBram Moolenaar
197385d5e2b7SBram Moolenaardef Test_nested_closure_used()
197485d5e2b7SBram Moolenaar  var lines =<< trim END
197585d5e2b7SBram Moolenaar      vim9script
197685d5e2b7SBram Moolenaar      def Func()
197785d5e2b7SBram Moolenaar        var x = 'hello'
19782949cfdbSBram Moolenaar        var Closure = () => x
19792949cfdbSBram Moolenaar        g:Myclosure = () => Closure()
198085d5e2b7SBram Moolenaar      enddef
198185d5e2b7SBram Moolenaar      Func()
198285d5e2b7SBram Moolenaar      assert_equal('hello', g:Myclosure())
198385d5e2b7SBram Moolenaar  END
198485d5e2b7SBram Moolenaar  CheckScriptSuccess(lines)
198585d5e2b7SBram Moolenaarenddef
19860876c785SBram Moolenaar
1987c70bdab0SBram Moolenaardef Test_nested_closure_fails()
19887a9cbca0SBram Moolenaar  var lines =<< trim END
1989c70bdab0SBram Moolenaar    vim9script
1990c70bdab0SBram Moolenaar    def FuncA()
1991c70bdab0SBram Moolenaar      FuncB(0)
1992c70bdab0SBram Moolenaar    enddef
1993c70bdab0SBram Moolenaar    def FuncB(n: number): list<string>
19942949cfdbSBram Moolenaar      return map([0], (_, v) => n)
1995c70bdab0SBram Moolenaar    enddef
1996c70bdab0SBram Moolenaar    FuncA()
1997c70bdab0SBram Moolenaar  END
1998c70bdab0SBram Moolenaar  CheckScriptFailure(lines, 'E1012:')
1999c70bdab0SBram Moolenaarenddef
2000c70bdab0SBram Moolenaar
2001f112f30aSBram Moolenaardef Test_global_closure()
2002f112f30aSBram Moolenaar  var lines =<< trim END
2003f112f30aSBram Moolenaar      vim9script
2004f112f30aSBram Moolenaar      def ReverseEveryNLines(n: number, line1: number, line2: number)
2005f112f30aSBram Moolenaar        var mods = 'sil keepj keepp lockm '
2006f112f30aSBram Moolenaar        var range = ':' .. line1 .. ',' .. line2
2007f112f30aSBram Moolenaar        def g:Offset(): number
2008f112f30aSBram Moolenaar            var offset = (line('.') - line1 + 1) % n
2009f112f30aSBram Moolenaar            return offset != 0 ? offset : n
2010f112f30aSBram Moolenaar        enddef
2011f112f30aSBram Moolenaar        exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
2012f112f30aSBram Moolenaar      enddef
2013f112f30aSBram Moolenaar
2014f112f30aSBram Moolenaar      new
2015f112f30aSBram Moolenaar      repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
2016f112f30aSBram Moolenaar      ReverseEveryNLines(3, 1, 9)
2017f112f30aSBram Moolenaar  END
2018f112f30aSBram Moolenaar  CheckScriptSuccess(lines)
2019f112f30aSBram Moolenaar  var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
2020f112f30aSBram Moolenaar  assert_equal(expected, getline(1, 9))
2021f112f30aSBram Moolenaar  bwipe!
2022f112f30aSBram Moolenaarenddef
2023f112f30aSBram Moolenaar
2024cd45ed03SBram Moolenaardef Test_global_closure_called_directly()
2025cd45ed03SBram Moolenaar  var lines =<< trim END
2026cd45ed03SBram Moolenaar      vim9script
2027cd45ed03SBram Moolenaar      def Outer()
2028cd45ed03SBram Moolenaar        var x = 1
2029cd45ed03SBram Moolenaar        def g:Inner()
2030cd45ed03SBram Moolenaar          var y = x
2031cd45ed03SBram Moolenaar          x += 1
2032cd45ed03SBram Moolenaar          assert_equal(1, y)
2033cd45ed03SBram Moolenaar        enddef
2034cd45ed03SBram Moolenaar        g:Inner()
2035cd45ed03SBram Moolenaar        assert_equal(2, x)
2036cd45ed03SBram Moolenaar      enddef
2037cd45ed03SBram Moolenaar      Outer()
2038cd45ed03SBram Moolenaar  END
2039cd45ed03SBram Moolenaar  CheckScriptSuccess(lines)
2040cd45ed03SBram Moolenaar  delfunc g:Inner
2041cd45ed03SBram Moolenaarenddef
2042cd45ed03SBram Moolenaar
204334c54eb6SBram Moolenaardef Test_failure_in_called_function()
204434c54eb6SBram Moolenaar  # this was using the frame index as the return value
204534c54eb6SBram Moolenaar  var lines =<< trim END
204634c54eb6SBram Moolenaar      vim9script
204734c54eb6SBram Moolenaar      au TerminalWinOpen * eval [][0]
204834c54eb6SBram Moolenaar      def PopupTerm(a: any)
204934c54eb6SBram Moolenaar        # make sure typvals on stack are string
205034c54eb6SBram Moolenaar        ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
205134c54eb6SBram Moolenaar        FireEvent()
205234c54eb6SBram Moolenaar      enddef
205334c54eb6SBram Moolenaar      def FireEvent()
205434c54eb6SBram Moolenaar          do TerminalWinOpen
205534c54eb6SBram Moolenaar      enddef
205634c54eb6SBram Moolenaar      # use try/catch to make eval fail
205734c54eb6SBram Moolenaar      try
205834c54eb6SBram Moolenaar          call PopupTerm(0)
205934c54eb6SBram Moolenaar      catch
206034c54eb6SBram Moolenaar      endtry
206134c54eb6SBram Moolenaar      au! TerminalWinOpen
206234c54eb6SBram Moolenaar  END
206334c54eb6SBram Moolenaar  CheckScriptSuccess(lines)
206434c54eb6SBram Moolenaarenddef
206534c54eb6SBram Moolenaar
20665366e1aeSBram Moolenaardef Test_nested_lambda()
20675366e1aeSBram Moolenaar  var lines =<< trim END
20685366e1aeSBram Moolenaar    vim9script
20695366e1aeSBram Moolenaar    def Func()
20705366e1aeSBram Moolenaar      var x = 4
20712949cfdbSBram Moolenaar      var Lambda1 = () => 7
20722949cfdbSBram Moolenaar      var Lambda2 = () => [Lambda1(), x]
20735366e1aeSBram Moolenaar      var res = Lambda2()
20745366e1aeSBram Moolenaar      assert_equal([7, 4], res)
20755366e1aeSBram Moolenaar    enddef
20765366e1aeSBram Moolenaar    Func()
20775366e1aeSBram Moolenaar  END
20785366e1aeSBram Moolenaar  CheckScriptSuccess(lines)
20795366e1aeSBram Moolenaarenddef
20805366e1aeSBram Moolenaar
208152bf81c2SBram Moolenaardef Shadowed(): list<number>
20822949cfdbSBram Moolenaar  var FuncList: list<func: number> = [() => 42]
208375ab91ffSBram Moolenaar  return FuncList->mapnew((_, Shadowed) => Shadowed())
208452bf81c2SBram Moolenaarenddef
208552bf81c2SBram Moolenaar
208652bf81c2SBram Moolenaardef Test_lambda_arg_shadows_func()
208752bf81c2SBram Moolenaar  assert_equal([42], Shadowed())
208852bf81c2SBram Moolenaarenddef
208952bf81c2SBram Moolenaar
2090acd4c5e9SBram Moolenaardef Line_continuation_in_def(dir: string = ''): string
20917a9cbca0SBram Moolenaar  var path: string = empty(dir)
2092acd4c5e9SBram Moolenaar          \ ? 'empty'
2093acd4c5e9SBram Moolenaar          \ : 'full'
2094acd4c5e9SBram Moolenaar  return path
2095acd4c5e9SBram Moolenaarenddef
2096acd4c5e9SBram Moolenaar
2097acd4c5e9SBram Moolenaardef Test_line_continuation_in_def()
2098c0c71e9dSBram Moolenaar  Line_continuation_in_def('.')->assert_equal('full')
2099acd4c5e9SBram Moolenaarenddef
2100acd4c5e9SBram Moolenaar
21012ea95b61SBram Moolenaardef Test_script_var_in_lambda()
21022ea95b61SBram Moolenaar  var lines =<< trim END
21032ea95b61SBram Moolenaar      vim9script
21042ea95b61SBram Moolenaar      var script = 'test'
2105*bb8a7ce0SBram Moolenaar      assert_equal(['test'], map(['one'], (_, _) => script))
21062ea95b61SBram Moolenaar  END
21072ea95b61SBram Moolenaar  CheckScriptSuccess(lines)
21082ea95b61SBram Moolenaarenddef
21092ea95b61SBram Moolenaar
21105e654230SBram Moolenaardef Line_continuation_in_lambda(): list<string>
21117a9cbca0SBram Moolenaar  var x = range(97, 100)
211275ab91ffSBram Moolenaar      ->mapnew((_, v) => nr2char(v)
21132949cfdbSBram Moolenaar          ->toupper())
21147a4b8980SBram Moolenaar      ->reverse()
21157a4b8980SBram Moolenaar  return x
21167a4b8980SBram Moolenaarenddef
21177a4b8980SBram Moolenaar
21187a4b8980SBram Moolenaardef Test_line_continuation_in_lambda()
2119c0c71e9dSBram Moolenaar  Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
2120f898f7c6SBram Moolenaar
2121f898f7c6SBram Moolenaar  var lines =<< trim END
2122f898f7c6SBram Moolenaar      vim9script
2123f898f7c6SBram Moolenaar      var res = [{n: 1, m: 2, s: 'xxx'}]
2124f898f7c6SBram Moolenaar                ->mapnew((_, v: dict<any>): string => printf('%d:%d:%s',
2125f898f7c6SBram Moolenaar                    v.n,
2126f898f7c6SBram Moolenaar                    v.m,
2127f898f7c6SBram Moolenaar                    substitute(v.s, '.*', 'yyy', '')
2128f898f7c6SBram Moolenaar                    ))
2129f898f7c6SBram Moolenaar      assert_equal(['1:2:yyy'], res)
2130f898f7c6SBram Moolenaar  END
2131f898f7c6SBram Moolenaar  CheckScriptSuccess(lines)
21327a4b8980SBram Moolenaarenddef
21337a4b8980SBram Moolenaar
2134b657198cSBram Moolenaardef Test_list_lambda()
2135b657198cSBram Moolenaar  timer_start(1000, (_) => 0)
2136b657198cSBram Moolenaar  var body = execute(timer_info()[0].callback
2137b657198cSBram Moolenaar         ->string()
2138b657198cSBram Moolenaar         ->substitute("('", ' ', '')
2139b657198cSBram Moolenaar         ->substitute("')", '', '')
2140b657198cSBram Moolenaar         ->substitute('function\zs', ' ', ''))
2141767034c5SBram Moolenaar  assert_match('def <lambda>\d\+(_: any): number\n1  return 0\n   enddef', body)
2142b657198cSBram Moolenaarenddef
2143b657198cSBram Moolenaar
2144ab360526SBram Moolenaardef DoFilterThis(a: string): list<string>
2145ab360526SBram Moolenaar  # closure nested inside another closure using argument
2146ab360526SBram Moolenaar  var Filter = (l) => filter(l, (_, v) => stridx(v, a) == 0)
2147ab360526SBram Moolenaar  return ['x', 'y', 'a', 'x2', 'c']->Filter()
2148ab360526SBram Moolenaarenddef
2149ab360526SBram Moolenaar
2150ab360526SBram Moolenaardef Test_nested_closure_using_argument()
2151ab360526SBram Moolenaar  assert_equal(['x', 'x2'], DoFilterThis('x'))
2152ab360526SBram Moolenaarenddef
2153ab360526SBram Moolenaar
21540186e586SBram Moolenaardef Test_triple_nested_closure()
21550186e586SBram Moolenaar  var what = 'x'
21560186e586SBram Moolenaar  var Match = (val: string, cmp: string): bool => stridx(val, cmp) == 0
21570186e586SBram Moolenaar  var Filter = (l) => filter(l, (_, v) => Match(v, what))
21580186e586SBram Moolenaar  assert_equal(['x', 'x2'], ['x', 'y', 'a', 'x2', 'c']->Filter())
21590186e586SBram Moolenaarenddef
21600186e586SBram Moolenaar
21618f510afcSBram Moolenaarfunc Test_silent_echo()
216247e7d70bSBram Moolenaar  CheckScreendump
216347e7d70bSBram Moolenaar
216447e7d70bSBram Moolenaar  let lines =<< trim END
216547e7d70bSBram Moolenaar    vim9script
216647e7d70bSBram Moolenaar    def EchoNothing()
216747e7d70bSBram Moolenaar      silent echo ''
216847e7d70bSBram Moolenaar    enddef
216947e7d70bSBram Moolenaar    defcompile
217047e7d70bSBram Moolenaar  END
21718f510afcSBram Moolenaar  call writefile(lines, 'XTest_silent_echo')
217247e7d70bSBram Moolenaar
217347e7d70bSBram Moolenaar  " Check that the balloon shows up after a mouse move
217447e7d70bSBram Moolenaar  let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
21758f510afcSBram Moolenaar  call term_sendkeys(buf, ":abc")
217647e7d70bSBram Moolenaar  call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
217747e7d70bSBram Moolenaar
217847e7d70bSBram Moolenaar  " clean up
217947e7d70bSBram Moolenaar  call StopVimInTerminal(buf)
218047e7d70bSBram Moolenaar  call delete('XTest_silent_echo')
21818f510afcSBram Moolenaarendfunc
218247e7d70bSBram Moolenaar
2183171fb923SBram Moolenaardef SilentlyError()
2184171fb923SBram Moolenaar  execute('silent! invalid')
2185171fb923SBram Moolenaar  g:did_it = 'yes'
2186171fb923SBram Moolenaarenddef
2187171fb923SBram Moolenaar
218828ee892aSBram Moolenaarfunc UserError()
218928ee892aSBram Moolenaar  silent! invalid
219028ee892aSBram Moolenaarendfunc
219128ee892aSBram Moolenaar
219228ee892aSBram Moolenaardef SilentlyUserError()
219328ee892aSBram Moolenaar  UserError()
219428ee892aSBram Moolenaar  g:did_it = 'yes'
219528ee892aSBram Moolenaarenddef
2196171fb923SBram Moolenaar
2197171fb923SBram Moolenaar" This can't be a :def function, because the assert would not be reached.
2198171fb923SBram Moolenaarfunc Test_ignore_silent_error()
2199171fb923SBram Moolenaar  let g:did_it = 'no'
2200171fb923SBram Moolenaar  call SilentlyError()
2201171fb923SBram Moolenaar  call assert_equal('yes', g:did_it)
2202171fb923SBram Moolenaar
220328ee892aSBram Moolenaar  let g:did_it = 'no'
220428ee892aSBram Moolenaar  call SilentlyUserError()
220528ee892aSBram Moolenaar  call assert_equal('yes', g:did_it)
2206171fb923SBram Moolenaar
2207171fb923SBram Moolenaar  unlet g:did_it
2208171fb923SBram Moolenaarendfunc
2209171fb923SBram Moolenaar
2210cd030c4bSBram Moolenaardef Test_ignore_silent_error_in_filter()
2211cd030c4bSBram Moolenaar  var lines =<< trim END
2212cd030c4bSBram Moolenaar      vim9script
2213cd030c4bSBram Moolenaar      def Filter(winid: number, key: string): bool
2214cd030c4bSBram Moolenaar          if key == 'o'
2215cd030c4bSBram Moolenaar              silent! eval [][0]
2216cd030c4bSBram Moolenaar              return true
2217cd030c4bSBram Moolenaar          endif
2218cd030c4bSBram Moolenaar          return popup_filter_menu(winid, key)
2219cd030c4bSBram Moolenaar      enddef
2220cd030c4bSBram Moolenaar
2221e0de171eSBram Moolenaar      popup_create('popup', {filter: Filter})
2222cd030c4bSBram Moolenaar      feedkeys("o\r", 'xnt')
2223cd030c4bSBram Moolenaar  END
2224cd030c4bSBram Moolenaar  CheckScriptSuccess(lines)
2225cd030c4bSBram Moolenaarenddef
2226cd030c4bSBram Moolenaar
22274b9bd692SBram Moolenaardef Fibonacci(n: number): number
22284b9bd692SBram Moolenaar  if n < 2
22294b9bd692SBram Moolenaar    return n
22304b9bd692SBram Moolenaar  else
22314b9bd692SBram Moolenaar    return Fibonacci(n - 1) + Fibonacci(n - 2)
22324b9bd692SBram Moolenaar  endif
22334b9bd692SBram Moolenaarenddef
22344b9bd692SBram Moolenaar
2235985116aeSBram Moolenaardef Test_recursive_call()
2236c0c71e9dSBram Moolenaar  Fibonacci(20)->assert_equal(6765)
2237985116aeSBram Moolenaarenddef
2238985116aeSBram Moolenaar
223908f7a41bSBram Moolenaardef TreeWalk(dir: string): list<any>
224075ab91ffSBram Moolenaar  return readdir(dir)->mapnew((_, val) =>
224108f7a41bSBram Moolenaar            fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
22422bede173SBram Moolenaar               ? {[val]: TreeWalk(dir .. '/' .. val)}
224308f7a41bSBram Moolenaar               : val
22442949cfdbSBram Moolenaar             )
224508f7a41bSBram Moolenaarenddef
224608f7a41bSBram Moolenaar
224708f7a41bSBram Moolenaardef Test_closure_in_map()
224808f7a41bSBram Moolenaar  mkdir('XclosureDir/tdir', 'p')
224908f7a41bSBram Moolenaar  writefile(['111'], 'XclosureDir/file1')
225008f7a41bSBram Moolenaar  writefile(['222'], 'XclosureDir/file2')
225108f7a41bSBram Moolenaar  writefile(['333'], 'XclosureDir/tdir/file3')
225208f7a41bSBram Moolenaar
2253e0de171eSBram Moolenaar  TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
225408f7a41bSBram Moolenaar
225508f7a41bSBram Moolenaar  delete('XclosureDir', 'rf')
225608f7a41bSBram Moolenaarenddef
225708f7a41bSBram Moolenaar
22587b5d5442SBram Moolenaardef Test_invalid_function_name()
22597b5d5442SBram Moolenaar  var lines =<< trim END
22607b5d5442SBram Moolenaar      vim9script
22617b5d5442SBram Moolenaar      def s: list<string>
22627b5d5442SBram Moolenaar  END
22637b5d5442SBram Moolenaar  CheckScriptFailure(lines, 'E129:')
22647b5d5442SBram Moolenaar
22657b5d5442SBram Moolenaar  lines =<< trim END
22667b5d5442SBram Moolenaar      vim9script
22677b5d5442SBram Moolenaar      def g: list<string>
22687b5d5442SBram Moolenaar  END
22697b5d5442SBram Moolenaar  CheckScriptFailure(lines, 'E129:')
22707b5d5442SBram Moolenaar
22717b5d5442SBram Moolenaar  lines =<< trim END
22727b5d5442SBram Moolenaar      vim9script
22737b5d5442SBram Moolenaar      def <SID>: list<string>
22747b5d5442SBram Moolenaar  END
22757b5d5442SBram Moolenaar  CheckScriptFailure(lines, 'E884:')
22767b5d5442SBram Moolenaar
22777b5d5442SBram Moolenaar  lines =<< trim END
22787b5d5442SBram Moolenaar      vim9script
22797b5d5442SBram Moolenaar      def F list<string>
22807b5d5442SBram Moolenaar  END
22817b5d5442SBram Moolenaar  CheckScriptFailure(lines, 'E488:')
22827b5d5442SBram Moolenaarenddef
22837b5d5442SBram Moolenaar
2284a90afb9aSBram Moolenaardef Test_partial_call()
22857a9cbca0SBram Moolenaar  var Xsetlist = function('setloclist', [0])
2286e0de171eSBram Moolenaar  Xsetlist([], ' ', {title: 'test'})
2287e0de171eSBram Moolenaar  getloclist(0, {title: 1})->assert_equal({title: 'test'})
2288a90afb9aSBram Moolenaar
2289a90afb9aSBram Moolenaar  Xsetlist = function('setloclist', [0, [], ' '])
2290e0de171eSBram Moolenaar  Xsetlist({title: 'test'})
2291e0de171eSBram Moolenaar  getloclist(0, {title: 1})->assert_equal({title: 'test'})
2292a90afb9aSBram Moolenaar
2293a90afb9aSBram Moolenaar  Xsetlist = function('setqflist')
2294e0de171eSBram Moolenaar  Xsetlist([], ' ', {title: 'test'})
2295e0de171eSBram Moolenaar  getqflist({title: 1})->assert_equal({title: 'test'})
2296a90afb9aSBram Moolenaar
2297a90afb9aSBram Moolenaar  Xsetlist = function('setqflist', [[], ' '])
2298e0de171eSBram Moolenaar  Xsetlist({title: 'test'})
2299e0de171eSBram Moolenaar  getqflist({title: 1})->assert_equal({title: 'test'})
23006abd3dc2SBram Moolenaar
23016abd3dc2SBram Moolenaar  var Len: func: number = function('len', ['word'])
23026abd3dc2SBram Moolenaar  assert_equal(4, Len())
2303a90afb9aSBram Moolenaarenddef
2304a90afb9aSBram Moolenaar
23052dd0a2c3SBram Moolenaardef Test_cmd_modifier()
23062dd0a2c3SBram Moolenaar  tab echo '0'
2307d2c61705SBram Moolenaar  CheckDefFailure(['5tab echo 3'], 'E16:')
23082dd0a2c3SBram Moolenaarenddef
23092dd0a2c3SBram Moolenaar
23102dd0a2c3SBram Moolenaardef Test_restore_modifiers()
23112dd0a2c3SBram Moolenaar  # check that when compiling a :def function command modifiers are not messed
23122dd0a2c3SBram Moolenaar  # up.
23137a9cbca0SBram Moolenaar  var lines =<< trim END
23142dd0a2c3SBram Moolenaar      vim9script
23152dd0a2c3SBram Moolenaar      set eventignore=
23162dd0a2c3SBram Moolenaar      autocmd QuickFixCmdPost * copen
23172dd0a2c3SBram Moolenaar      def AutocmdsDisabled()
23182dd0a2c3SBram Moolenaar        eval 0
23192dd0a2c3SBram Moolenaar      enddef
23202dd0a2c3SBram Moolenaar      func Func()
23212dd0a2c3SBram Moolenaar        noautocmd call s:AutocmdsDisabled()
23222dd0a2c3SBram Moolenaar        let g:ei_after = &eventignore
23232dd0a2c3SBram Moolenaar      endfunc
23242dd0a2c3SBram Moolenaar      Func()
23252dd0a2c3SBram Moolenaar  END
23262dd0a2c3SBram Moolenaar  CheckScriptSuccess(lines)
2327c0c71e9dSBram Moolenaar  g:ei_after->assert_equal('')
23282dd0a2c3SBram Moolenaarenddef
23292dd0a2c3SBram Moolenaar
2330dfa3d552SBram Moolenaardef StackTop()
2331dfa3d552SBram Moolenaar  eval 1
2332dfa3d552SBram Moolenaar  eval 2
2333dfa3d552SBram Moolenaar  # call not on fourth line
2334dfa3d552SBram Moolenaar  StackBot()
2335dfa3d552SBram Moolenaarenddef
2336dfa3d552SBram Moolenaar
2337dfa3d552SBram Moolenaardef StackBot()
2338dfa3d552SBram Moolenaar  # throw an error
2339dfa3d552SBram Moolenaar  eval [][0]
2340dfa3d552SBram Moolenaarenddef
2341dfa3d552SBram Moolenaar
2342dfa3d552SBram Moolenaardef Test_callstack_def()
2343dfa3d552SBram Moolenaar  try
2344dfa3d552SBram Moolenaar    StackTop()
2345dfa3d552SBram Moolenaar  catch
2346c0c71e9dSBram Moolenaar    v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
2347dfa3d552SBram Moolenaar  endtry
2348dfa3d552SBram Moolenaarenddef
2349dfa3d552SBram Moolenaar
2350e8211a33SBram Moolenaar" Re-using spot for variable used in block
2351e8211a33SBram Moolenaardef Test_block_scoped_var()
2352e8211a33SBram Moolenaar  var lines =<< trim END
2353e8211a33SBram Moolenaar      vim9script
2354e8211a33SBram Moolenaar      def Func()
2355e8211a33SBram Moolenaar        var x = ['a', 'b', 'c']
2356e8211a33SBram Moolenaar        if 1
2357e8211a33SBram Moolenaar          var y = 'x'
2358*bb8a7ce0SBram Moolenaar          map(x, (_, _) => y)
2359e8211a33SBram Moolenaar        endif
2360e8211a33SBram Moolenaar        var z = x
2361e8211a33SBram Moolenaar        assert_equal(['x', 'x', 'x'], z)
2362e8211a33SBram Moolenaar      enddef
2363e8211a33SBram Moolenaar      Func()
2364e8211a33SBram Moolenaar  END
2365e8211a33SBram Moolenaar  CheckScriptSuccess(lines)
2366e8211a33SBram Moolenaarenddef
2367e8211a33SBram Moolenaar
2368eeece9e4SBram Moolenaardef Test_reset_did_emsg()
2369eeece9e4SBram Moolenaar  var lines =<< trim END
2370eeece9e4SBram Moolenaar      @s = 'blah'
2371eeece9e4SBram Moolenaar      au BufWinLeave * #
2372eeece9e4SBram Moolenaar      def Func()
2373eeece9e4SBram Moolenaar        var winid = popup_create('popup', {})
2374eeece9e4SBram Moolenaar        exe '*s'
2375eeece9e4SBram Moolenaar        popup_close(winid)
2376eeece9e4SBram Moolenaar      enddef
2377eeece9e4SBram Moolenaar      Func()
2378eeece9e4SBram Moolenaar  END
2379eeece9e4SBram Moolenaar  CheckScriptFailure(lines, 'E492:', 8)
23802d870f8dSBram Moolenaar  delfunc! g:Func
2381eeece9e4SBram Moolenaarenddef
2382eeece9e4SBram Moolenaar
238357f799e6SBram Moolenaardef Test_did_emsg_reset()
238457f799e6SBram Moolenaar  # executing an autocommand resets did_emsg, this should not result in a
238557f799e6SBram Moolenaar  # builtin function considered failing
238657f799e6SBram Moolenaar  var lines =<< trim END
238757f799e6SBram Moolenaar      vim9script
238857f799e6SBram Moolenaar      au BufWinLeave * #
238957f799e6SBram Moolenaar      def Func()
2390767034c5SBram Moolenaar          popup_menu('', {callback: (a, b) => popup_create('', {})->popup_close()})
239157f799e6SBram Moolenaar          eval [][0]
239257f799e6SBram Moolenaar      enddef
239357f799e6SBram Moolenaar      nno <F3> <cmd>call <sid>Func()<cr>
239457f799e6SBram Moolenaar      feedkeys("\<F3>\e", 'xt')
239557f799e6SBram Moolenaar  END
239657f799e6SBram Moolenaar  writefile(lines, 'XemsgReset')
239757f799e6SBram Moolenaar  assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
239857f799e6SBram Moolenaar  delete('XemsgReset')
239957f799e6SBram Moolenaar  nunmap <F3>
240057f799e6SBram Moolenaar  au! BufWinLeave
240157f799e6SBram Moolenaarenddef
240257f799e6SBram Moolenaar
240356602ba1SBram Moolenaardef Test_abort_with_silent_call()
240456602ba1SBram Moolenaar  var lines =<< trim END
240556602ba1SBram Moolenaar      vim9script
240656602ba1SBram Moolenaar      g:result = 'none'
240756602ba1SBram Moolenaar      def Func()
240856602ba1SBram Moolenaar        g:result += 3
240956602ba1SBram Moolenaar        g:result = 'yes'
241056602ba1SBram Moolenaar      enddef
241156602ba1SBram Moolenaar      # error is silenced, but function aborts on error
241256602ba1SBram Moolenaar      silent! Func()
241356602ba1SBram Moolenaar      assert_equal('none', g:result)
241456602ba1SBram Moolenaar      unlet g:result
241556602ba1SBram Moolenaar  END
241656602ba1SBram Moolenaar  CheckScriptSuccess(lines)
241756602ba1SBram Moolenaarenddef
241856602ba1SBram Moolenaar
2419f665e97fSBram Moolenaardef Test_continues_with_silent_error()
2420f665e97fSBram Moolenaar  var lines =<< trim END
2421f665e97fSBram Moolenaar      vim9script
2422f665e97fSBram Moolenaar      g:result = 'none'
2423f665e97fSBram Moolenaar      def Func()
2424f665e97fSBram Moolenaar        silent!  g:result += 3
2425f665e97fSBram Moolenaar        g:result = 'yes'
2426f665e97fSBram Moolenaar      enddef
2427f665e97fSBram Moolenaar      # error is silenced, function does not abort
2428f665e97fSBram Moolenaar      Func()
2429f665e97fSBram Moolenaar      assert_equal('yes', g:result)
2430f665e97fSBram Moolenaar      unlet g:result
2431f665e97fSBram Moolenaar  END
2432f665e97fSBram Moolenaar  CheckScriptSuccess(lines)
2433f665e97fSBram Moolenaarenddef
2434f665e97fSBram Moolenaar
2435af0df47aSBram Moolenaardef Test_abort_even_with_silent()
2436af0df47aSBram Moolenaar  var lines =<< trim END
2437af0df47aSBram Moolenaar      vim9script
2438af0df47aSBram Moolenaar      g:result = 'none'
2439af0df47aSBram Moolenaar      def Func()
2440af0df47aSBram Moolenaar        eval {-> ''}() .. '' .. {}['X']
2441af0df47aSBram Moolenaar        g:result = 'yes'
2442af0df47aSBram Moolenaar      enddef
2443f665e97fSBram Moolenaar      silent! Func()
2444af0df47aSBram Moolenaar      assert_equal('none', g:result)
24454029cabbSBram Moolenaar      unlet g:result
24464029cabbSBram Moolenaar  END
24474029cabbSBram Moolenaar  CheckScriptSuccess(lines)
24484029cabbSBram Moolenaarenddef
24494029cabbSBram Moolenaar
2450f665e97fSBram Moolenaardef Test_cmdmod_silent_restored()
2451f665e97fSBram Moolenaar  var lines =<< trim END
2452f665e97fSBram Moolenaar      vim9script
2453f665e97fSBram Moolenaar      def Func()
2454f665e97fSBram Moolenaar        g:result = 'none'
2455f665e97fSBram Moolenaar        silent! g:result += 3
2456f665e97fSBram Moolenaar        g:result = 'none'
2457f665e97fSBram Moolenaar        g:result += 3
2458f665e97fSBram Moolenaar      enddef
2459f665e97fSBram Moolenaar      Func()
2460f665e97fSBram Moolenaar  END
2461f665e97fSBram Moolenaar  # can't use CheckScriptFailure, it ignores the :silent!
2462f665e97fSBram Moolenaar  var fname = 'Xdefsilent'
2463f665e97fSBram Moolenaar  writefile(lines, fname)
2464f665e97fSBram Moolenaar  var caught = 'no'
2465f665e97fSBram Moolenaar  try
2466f665e97fSBram Moolenaar    exe 'source ' .. fname
2467f665e97fSBram Moolenaar  catch /E1030:/
2468f665e97fSBram Moolenaar    caught = 'yes'
2469f665e97fSBram Moolenaar    assert_match('Func, line 4', v:throwpoint)
2470f665e97fSBram Moolenaar  endtry
2471f665e97fSBram Moolenaar  assert_equal('yes', caught)
2472f665e97fSBram Moolenaar  delete(fname)
2473f665e97fSBram Moolenaarenddef
2474f665e97fSBram Moolenaar
24752fecb531SBram Moolenaardef Test_cmdmod_silent_nested()
24762fecb531SBram Moolenaar  var lines =<< trim END
24772fecb531SBram Moolenaar      vim9script
24782fecb531SBram Moolenaar      var result = ''
24792fecb531SBram Moolenaar
24802fecb531SBram Moolenaar      def Error()
24812fecb531SBram Moolenaar          result ..= 'Eb'
24822fecb531SBram Moolenaar          eval [][0]
24832fecb531SBram Moolenaar          result ..= 'Ea'
24842fecb531SBram Moolenaar      enddef
24852fecb531SBram Moolenaar
24862fecb531SBram Moolenaar      def Crash()
24872fecb531SBram Moolenaar          result ..= 'Cb'
24882fecb531SBram Moolenaar          sil! Error()
24892fecb531SBram Moolenaar          result ..= 'Ca'
24902fecb531SBram Moolenaar      enddef
24912fecb531SBram Moolenaar
24922fecb531SBram Moolenaar      Crash()
24932fecb531SBram Moolenaar      assert_equal('CbEbEaCa', result)
24942fecb531SBram Moolenaar  END
24952fecb531SBram Moolenaar  CheckScriptSuccess(lines)
24962fecb531SBram Moolenaarenddef
24972fecb531SBram Moolenaar
24984029cabbSBram Moolenaardef Test_dict_member_with_silent()
24994029cabbSBram Moolenaar  var lines =<< trim END
25004029cabbSBram Moolenaar      vim9script
25014029cabbSBram Moolenaar      g:result = 'none'
25024029cabbSBram Moolenaar      var d: dict<any>
25034029cabbSBram Moolenaar      def Func()
25044029cabbSBram Moolenaar        try
25052949cfdbSBram Moolenaar          g:result = map([], (_, v) => ({}[v]))->join() .. d['']
25064029cabbSBram Moolenaar        catch
25074029cabbSBram Moolenaar        endtry
25084029cabbSBram Moolenaar      enddef
25094029cabbSBram Moolenaar      silent! Func()
25104029cabbSBram Moolenaar      assert_equal('0', g:result)
25114029cabbSBram Moolenaar      unlet g:result
2512af0df47aSBram Moolenaar  END
2513af0df47aSBram Moolenaar  CheckScriptSuccess(lines)
2514af0df47aSBram Moolenaarenddef
2515af0df47aSBram Moolenaar
2516f904133eSBram Moolenaardef Test_skip_cmds_with_silent()
2517f904133eSBram Moolenaar  var lines =<< trim END
2518f904133eSBram Moolenaar      vim9script
2519f904133eSBram Moolenaar
2520f904133eSBram Moolenaar      def Func(b: bool)
2521f904133eSBram Moolenaar        Crash()
2522f904133eSBram Moolenaar      enddef
2523f904133eSBram Moolenaar
2524f904133eSBram Moolenaar      def Crash()
2525f904133eSBram Moolenaar        sil! :/not found/d _
2526f904133eSBram Moolenaar        sil! :/not found/put _
2527f904133eSBram Moolenaar      enddef
2528f904133eSBram Moolenaar
2529f904133eSBram Moolenaar      Func(true)
2530f904133eSBram Moolenaar  END
2531f904133eSBram Moolenaar  CheckScriptSuccess(lines)
2532f904133eSBram Moolenaarenddef
2533f904133eSBram Moolenaar
25345b3d1bb0SBram Moolenaardef Test_opfunc()
25355b3d1bb0SBram Moolenaar  nnoremap <F3> <cmd>set opfunc=Opfunc<cr>g@
25365b3d1bb0SBram Moolenaar  def g:Opfunc(_: any): string
25375b3d1bb0SBram Moolenaar    setline(1, 'ASDF')
25385b3d1bb0SBram Moolenaar    return ''
25395b3d1bb0SBram Moolenaar  enddef
25405b3d1bb0SBram Moolenaar  new
25415b3d1bb0SBram Moolenaar  setline(1, 'asdf')
25425b3d1bb0SBram Moolenaar  feedkeys("\<F3>$", 'x')
25435b3d1bb0SBram Moolenaar  assert_equal('ASDF', getline(1))
25445b3d1bb0SBram Moolenaar
25455b3d1bb0SBram Moolenaar  bwipe!
25465b3d1bb0SBram Moolenaar  nunmap <F3>
25475b3d1bb0SBram Moolenaarenddef
25485b3d1bb0SBram Moolenaar
2549077a4231SBram Moolenaar" this was crashing on exit
2550077a4231SBram Moolenaardef Test_nested_lambda_in_closure()
2551077a4231SBram Moolenaar  var lines =<< trim END
2552077a4231SBram Moolenaar      vim9script
2553077a4231SBram Moolenaar      def Outer()
2554077a4231SBram Moolenaar          def g:Inner()
2555077a4231SBram Moolenaar              echo map([1, 2, 3], {_, v -> v + 1})
2556077a4231SBram Moolenaar          enddef
2557077a4231SBram Moolenaar          g:Inner()
2558077a4231SBram Moolenaar      enddef
2559077a4231SBram Moolenaar      defcompile
2560077a4231SBram Moolenaar      writefile(['Done'], 'XnestedDone')
2561077a4231SBram Moolenaar      quit
2562077a4231SBram Moolenaar  END
2563077a4231SBram Moolenaar  if !RunVim([], lines, '--clean')
2564077a4231SBram Moolenaar    return
2565077a4231SBram Moolenaar  endif
2566077a4231SBram Moolenaar  assert_equal(['Done'], readfile('XnestedDone'))
2567077a4231SBram Moolenaar  delete('XnestedDone')
2568077a4231SBram Moolenaarenddef
2569077a4231SBram Moolenaar
257004947cc6SBram Moolenaardef Test_check_func_arg_types()
257104947cc6SBram Moolenaar  var lines =<< trim END
257204947cc6SBram Moolenaar      vim9script
257304947cc6SBram Moolenaar      def F1(x: string): string
257404947cc6SBram Moolenaar        return x
257504947cc6SBram Moolenaar      enddef
257604947cc6SBram Moolenaar
257704947cc6SBram Moolenaar      def F2(x: number): number
257804947cc6SBram Moolenaar        return x + 1
257904947cc6SBram Moolenaar      enddef
258004947cc6SBram Moolenaar
258104947cc6SBram Moolenaar      def G(g: func): dict<func>
258204947cc6SBram Moolenaar        return {f: g}
258304947cc6SBram Moolenaar      enddef
258404947cc6SBram Moolenaar
258504947cc6SBram Moolenaar      def H(d: dict<func>): string
258604947cc6SBram Moolenaar        return d.f('a')
258704947cc6SBram Moolenaar      enddef
258804947cc6SBram Moolenaar  END
258904947cc6SBram Moolenaar
259004947cc6SBram Moolenaar  CheckScriptSuccess(lines + ['echo H(G(F1))'])
259104947cc6SBram Moolenaar  CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
259204947cc6SBram Moolenaarenddef
259304947cc6SBram Moolenaar
2594701cc6caSBram Moolenaardef Test_compile_error()
2595701cc6caSBram Moolenaar  var lines =<< trim END
2596701cc6caSBram Moolenaar    def g:Broken()
2597701cc6caSBram Moolenaar      echo 'a' + {}
2598701cc6caSBram Moolenaar    enddef
2599701cc6caSBram Moolenaar    call g:Broken()
2600701cc6caSBram Moolenaar  END
2601701cc6caSBram Moolenaar  # First call: compilation error
2602701cc6caSBram Moolenaar  CheckScriptFailure(lines, 'E1051: Wrong argument type for +')
2603701cc6caSBram Moolenaar
2604701cc6caSBram Moolenaar  # Second call won't try compiling again
2605701cc6caSBram Moolenaar  assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
2606599410cbSBram Moolenaar  delfunc g:Broken
2607599410cbSBram Moolenaar
2608599410cbSBram Moolenaar  # No error when compiling with :silent!
2609599410cbSBram Moolenaar  lines =<< trim END
2610599410cbSBram Moolenaar    def g:Broken()
2611599410cbSBram Moolenaar      echo 'a' + []
2612599410cbSBram Moolenaar    enddef
2613599410cbSBram Moolenaar    silent! defcompile
2614599410cbSBram Moolenaar  END
2615599410cbSBram Moolenaar  CheckScriptSuccess(lines)
2616599410cbSBram Moolenaar
2617599410cbSBram Moolenaar  # Calling the function won't try compiling again
2618599410cbSBram Moolenaar  assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
2619599410cbSBram Moolenaar  delfunc g:Broken
2620701cc6caSBram Moolenaarenddef
2621701cc6caSBram Moolenaar
2622962c43bfSBram Moolenaardef Test_ignored_argument()
2623962c43bfSBram Moolenaar  var lines =<< trim END
2624962c43bfSBram Moolenaar      vim9script
2625962c43bfSBram Moolenaar      def Ignore(_, _): string
2626962c43bfSBram Moolenaar        return 'yes'
2627962c43bfSBram Moolenaar      enddef
2628962c43bfSBram Moolenaar      assert_equal('yes', Ignore(1, 2))
2629962c43bfSBram Moolenaar
2630962c43bfSBram Moolenaar      func Ok(_)
2631962c43bfSBram Moolenaar        return a:_
2632962c43bfSBram Moolenaar      endfunc
2633962c43bfSBram Moolenaar      assert_equal('ok', Ok('ok'))
2634962c43bfSBram Moolenaar
2635962c43bfSBram Moolenaar      func Oktoo()
2636962c43bfSBram Moolenaar        let _ = 'too'
2637962c43bfSBram Moolenaar        return _
2638962c43bfSBram Moolenaar      endfunc
2639962c43bfSBram Moolenaar      assert_equal('too', Oktoo())
2640962c43bfSBram Moolenaar  END
2641962c43bfSBram Moolenaar  CheckScriptSuccess(lines)
2642962c43bfSBram Moolenaar
2643962c43bfSBram Moolenaar  lines =<< trim END
2644962c43bfSBram Moolenaar      def Ignore(_: string): string
2645962c43bfSBram Moolenaar        return _
2646962c43bfSBram Moolenaar      enddef
2647962c43bfSBram Moolenaar      defcompile
2648962c43bfSBram Moolenaar  END
2649962c43bfSBram Moolenaar  CheckScriptFailure(lines, 'E1181:', 1)
2650962c43bfSBram Moolenaar
2651962c43bfSBram Moolenaar  lines =<< trim END
2652962c43bfSBram Moolenaar      var _ = 1
2653962c43bfSBram Moolenaar  END
2654962c43bfSBram Moolenaar  CheckDefAndScriptFailure(lines, 'E1181:', 1)
2655962c43bfSBram Moolenaarenddef
2656962c43bfSBram Moolenaar
2657*bb8a7ce0SBram Moolenaardef Test_too_many_arguments()
2658*bb8a7ce0SBram Moolenaar  var lines =<< trim END
2659*bb8a7ce0SBram Moolenaar    echo [0, 1, 2]->map(() => 123)
2660*bb8a7ce0SBram Moolenaar  END
2661*bb8a7ce0SBram Moolenaar  CheckDefExecAndScriptFailure(lines, 'E1106: 2 arguments too many', 1)
2662*bb8a7ce0SBram Moolenaar
2663*bb8a7ce0SBram Moolenaar  lines =<< trim END
2664*bb8a7ce0SBram Moolenaar    echo [0, 1, 2]->map((_) => 123)
2665*bb8a7ce0SBram Moolenaar  END
2666*bb8a7ce0SBram Moolenaar  CheckDefExecAndScriptFailure(lines, 'E1106: One argument too many', 1)
2667*bb8a7ce0SBram Moolenaarenddef
2668077a4231SBram Moolenaar
2669f7779c63SBram Moolenaar
26705deeb3f1SBram Moolenaar" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
2671