1" Test various aspects of the Vim9 script language. 2 3source check.vim 4source term_util.vim 5source view_util.vim 6source vim9.vim 7source screendump.vim 8 9func Test_def_basic() 10 def SomeFunc(): string 11 return 'yes' 12 enddef 13 call SomeFunc()->assert_equal('yes') 14endfunc 15 16func Test_compiling_error() 17 " use a terminal to see the whole error message 18 CheckRunVimInTerminal 19 20 call TestCompilingError() 21endfunc 22 23def TestCompilingError() 24 var lines =<< trim END 25 vim9script 26 def Fails() 27 echo nothing 28 enddef 29 defcompile 30 END 31 call writefile(lines, 'XTest_compile_error') 32 var buf = RunVimInTerminal('-S XTest_compile_error', 33 {rows: 10, wait_for_ruler: 0}) 34 call WaitForAssert(() => assert_match('Error detected while compiling command line.*Fails.*Variable not found: nothing', 35 Term_getlines(buf, range(1, 9)))) 36 37 # clean up 38 call StopVimInTerminal(buf) 39 call delete('XTest_compile_error') 40enddef 41 42def CallRecursive(n: number): number 43 return CallRecursive(n + 1) 44enddef 45 46def CallMapRecursive(l: list<number>): number 47 return map(l, (_, v) => CallMapRecursive([v]))[0] 48enddef 49 50def Test_funcdepth_error() 51 set maxfuncdepth=10 52 53 var caught = false 54 try 55 CallRecursive(1) 56 catch /E132:/ 57 caught = true 58 endtry 59 assert_true(caught) 60 61 caught = false 62 try 63 CallMapRecursive([1]) 64 catch /E132:/ 65 caught = true 66 endtry 67 assert_true(caught) 68 69 set maxfuncdepth& 70enddef 71 72def Test_endfunc_enddef() 73 var lines =<< trim END 74 def Test() 75 echo 'test' 76 endfunc 77 enddef 78 END 79 CheckScriptFailure(lines, 'E1151:', 3) 80 81 lines =<< trim END 82 def Test() 83 func Nested() 84 echo 'test' 85 enddef 86 enddef 87 END 88 CheckScriptFailure(lines, 'E1152:', 4) 89 90 lines =<< trim END 91 def Ok() 92 echo 'hello' 93 enddef | echo 'there' 94 def Bad() 95 echo 'hello' 96 enddef there 97 END 98 CheckScriptFailure(lines, 'E1173: Text found after enddef: there', 6) 99enddef 100 101def Test_missing_endfunc_enddef() 102 var lines =<< trim END 103 vim9script 104 def Test() 105 echo 'test' 106 endef 107 END 108 CheckScriptFailure(lines, 'E1057:', 2) 109 110 lines =<< trim END 111 vim9script 112 func Some() 113 echo 'test' 114 enfffunc 115 END 116 CheckScriptFailure(lines, 'E126:', 2) 117enddef 118 119def Test_white_space_before_paren() 120 var lines =<< trim END 121 vim9script 122 def Test () 123 echo 'test' 124 enddef 125 END 126 CheckScriptFailure(lines, 'E1068:', 2) 127 128 lines =<< trim END 129 vim9script 130 func Test () 131 echo 'test' 132 endfunc 133 END 134 CheckScriptFailure(lines, 'E1068:', 2) 135 136 lines =<< trim END 137 def Test () 138 echo 'test' 139 enddef 140 END 141 CheckScriptFailure(lines, 'E1068:', 1) 142 143 lines =<< trim END 144 func Test () 145 echo 'test' 146 endfunc 147 END 148 CheckScriptSuccess(lines) 149enddef 150 151def Test_enddef_dict_key() 152 var d = { 153 enddef: 'x', 154 endfunc: 'y', 155 } 156 assert_equal({enddef: 'x', endfunc: 'y'}, d) 157enddef 158 159def ReturnString(): string 160 return 'string' 161enddef 162 163def ReturnNumber(): number 164 return 123 165enddef 166 167let g:notNumber = 'string' 168 169def ReturnGlobal(): number 170 return g:notNumber 171enddef 172 173def Test_return_something() 174 ReturnString()->assert_equal('string') 175 ReturnNumber()->assert_equal(123) 176 assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal') 177enddef 178 179def Test_check_argument_type() 180 var lines =<< trim END 181 vim9script 182 def Val(a: number, b: number): number 183 return 0 184 enddef 185 def Func() 186 var x: any = true 187 Val(0, x) 188 enddef 189 disass Func 190 Func() 191 END 192 CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got bool', 2) 193enddef 194 195def Test_missing_return() 196 CheckDefFailure(['def Missing(): number', 197 ' if g:cond', 198 ' echo "no return"', 199 ' else', 200 ' return 0', 201 ' endif' 202 'enddef'], 'E1027:') 203 CheckDefFailure(['def Missing(): number', 204 ' if g:cond', 205 ' return 1', 206 ' else', 207 ' echo "no return"', 208 ' endif' 209 'enddef'], 'E1027:') 210 CheckDefFailure(['def Missing(): number', 211 ' if g:cond', 212 ' return 1', 213 ' else', 214 ' return 2', 215 ' endif' 216 ' return 3' 217 'enddef'], 'E1095:') 218enddef 219 220def Test_return_bool() 221 var lines =<< trim END 222 vim9script 223 def MenuFilter(id: number, key: string): bool 224 return popup_filter_menu(id, key) 225 enddef 226 def YesnoFilter(id: number, key: string): bool 227 return popup_filter_yesno(id, key) 228 enddef 229 defcompile 230 END 231 CheckScriptSuccess(lines) 232enddef 233 234let s:nothing = 0 235def ReturnNothing() 236 s:nothing = 1 237 if true 238 return 239 endif 240 s:nothing = 2 241enddef 242 243def Test_return_nothing() 244 ReturnNothing() 245 s:nothing->assert_equal(1) 246enddef 247 248def Test_return_invalid() 249 var lines =<< trim END 250 vim9script 251 def Func(): invalid 252 return xxx 253 enddef 254 defcompile 255 END 256 CheckScriptFailure(lines, 'E1010:', 2) 257 258 lines =<< trim END 259 vim9script 260 def Test(Fun: func(number): number): list<number> 261 return map([1, 2, 3], (_, i) => Fun(i)) 262 enddef 263 defcompile 264 def Inc(nr: number): nr 265 return nr + 2 266 enddef 267 echo Test(Inc) 268 END 269 # doing this twice was leaking memory 270 CheckScriptFailure(lines, 'E1010:') 271 CheckScriptFailure(lines, 'E1010:') 272enddef 273 274func Increment() 275 let g:counter += 1 276endfunc 277 278def Test_call_ufunc_count() 279 g:counter = 1 280 Increment() 281 Increment() 282 Increment() 283 # works with and without :call 284 g:counter->assert_equal(4) 285 eval g:counter->assert_equal(4) 286 unlet g:counter 287enddef 288 289def MyVarargs(arg: string, ...rest: list<string>): string 290 var res = arg 291 for s in rest 292 res ..= ',' .. s 293 endfor 294 return res 295enddef 296 297def Test_call_varargs() 298 MyVarargs('one')->assert_equal('one') 299 MyVarargs('one', 'two')->assert_equal('one,two') 300 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three') 301enddef 302 303def MyDefaultArgs(name = 'string'): string 304 return name 305enddef 306 307def MyDefaultSecond(name: string, second: bool = true): string 308 return second ? name : 'none' 309enddef 310 311 312def Test_call_default_args() 313 MyDefaultArgs()->assert_equal('string') 314 MyDefaultArgs(v:none)->assert_equal('string') 315 MyDefaultArgs('one')->assert_equal('one') 316 assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 4, 'Test_call_default_args') 317 318 MyDefaultSecond('test')->assert_equal('test') 319 MyDefaultSecond('test', true)->assert_equal('test') 320 MyDefaultSecond('test', false)->assert_equal('none') 321 322 var lines =<< trim END 323 def MyDefaultThird(name: string, aa = 'aa', bb = 'bb'): string 324 return name .. aa .. bb 325 enddef 326 327 MyDefaultThird('->')->assert_equal('->aabb') 328 MyDefaultThird('->', v:none)->assert_equal('->aabb') 329 MyDefaultThird('->', 'xx')->assert_equal('->xxbb') 330 MyDefaultThird('->', v:none, v:none)->assert_equal('->aabb') 331 MyDefaultThird('->', 'xx', v:none)->assert_equal('->xxbb') 332 MyDefaultThird('->', v:none, 'yy')->assert_equal('->aayy') 333 MyDefaultThird('->', 'xx', 'yy')->assert_equal('->xxyy') 334 END 335 CheckDefAndScriptSuccess(lines) 336 337 CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:') 338 delfunc g:Func 339 CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string') 340 delfunc g:Func 341 342 lines =<< trim END 343 vim9script 344 def Func(a = b == 0 ? 1 : 2, b = 0) 345 enddef 346 defcompile 347 END 348 CheckScriptFailure(lines, 'E1001: Variable not found: b') 349enddef 350 351def FuncWithComment( # comment 352 a: number, #comment 353 b: bool, # comment 354 c: string) #comment 355 assert_equal(4, a) 356 assert_equal(true, b) 357 assert_equal('yes', c) 358enddef 359 360def Test_func_with_comments() 361 FuncWithComment(4, true, 'yes') 362 363 var lines =<< trim END 364 def Func(# comment 365 arg: string) 366 enddef 367 END 368 CheckScriptFailure(lines, 'E125:', 1) 369 370 lines =<< trim END 371 def Func( 372 arg: string# comment 373 ) 374 enddef 375 END 376 CheckScriptFailure(lines, 'E475:', 2) 377 378 lines =<< trim END 379 def Func( 380 arg: string 381 )# comment 382 enddef 383 END 384 CheckScriptFailure(lines, 'E488:', 3) 385enddef 386 387def Test_nested_function() 388 def Nested(arg: string): string 389 return 'nested ' .. arg 390 enddef 391 Nested('function')->assert_equal('nested function') 392 393 CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:') 394 CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:') 395 396 CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:') 397 CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:') 398 CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:') 399 400 var lines =<< trim END 401 def Outer() 402 def Inner() 403 # comment 404 enddef 405 def Inner() 406 enddef 407 enddef 408 END 409 CheckDefFailure(lines, 'E1073:') 410 411 lines =<< trim END 412 def Outer() 413 def Inner() 414 # comment 415 enddef 416 def! Inner() 417 enddef 418 enddef 419 END 420 CheckDefFailure(lines, 'E1117:') 421 422 # nested function inside conditional 423 lines =<< trim END 424 vim9script 425 var thecount = 0 426 if true 427 def Test(): number 428 def TheFunc(): number 429 thecount += 1 430 return thecount 431 enddef 432 return TheFunc() 433 enddef 434 endif 435 defcompile 436 assert_equal(1, Test()) 437 assert_equal(2, Test()) 438 END 439 CheckScriptSuccess(lines) 440 441 # also works when "thecount" is inside the "if" block 442 lines =<< trim END 443 vim9script 444 if true 445 var thecount = 0 446 def Test(): number 447 def TheFunc(): number 448 thecount += 1 449 return thecount 450 enddef 451 return TheFunc() 452 enddef 453 endif 454 defcompile 455 assert_equal(1, Test()) 456 assert_equal(2, Test()) 457 END 458 CheckScriptSuccess(lines) 459enddef 460 461def Test_not_nested_function() 462 echo printf('%d', 463 function('len')('xxx')) 464enddef 465 466func Test_call_default_args_from_func() 467 call MyDefaultArgs()->assert_equal('string') 468 call MyDefaultArgs('one')->assert_equal('one') 469 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func') 470endfunc 471 472def Test_nested_global_function() 473 var lines =<< trim END 474 vim9script 475 def Outer() 476 def g:Inner(): string 477 return 'inner' 478 enddef 479 enddef 480 defcompile 481 Outer() 482 g:Inner()->assert_equal('inner') 483 delfunc g:Inner 484 Outer() 485 g:Inner()->assert_equal('inner') 486 delfunc g:Inner 487 Outer() 488 g:Inner()->assert_equal('inner') 489 delfunc g:Inner 490 END 491 CheckScriptSuccess(lines) 492 493 lines =<< trim END 494 vim9script 495 def Outer() 496 def g:Inner(): string 497 return 'inner' 498 enddef 499 enddef 500 defcompile 501 Outer() 502 Outer() 503 END 504 CheckScriptFailure(lines, "E122:") 505 delfunc g:Inner 506 507 lines =<< trim END 508 vim9script 509 def Outer() 510 def g:Inner() 511 echo map([1, 2, 3], (_, v) => v + 1) 512 enddef 513 g:Inner() 514 enddef 515 Outer() 516 END 517 CheckScriptSuccess(lines) 518 delfunc g:Inner 519 520 lines =<< trim END 521 vim9script 522 def Func() 523 echo 'script' 524 enddef 525 def Outer() 526 def Func() 527 echo 'inner' 528 enddef 529 enddef 530 defcompile 531 END 532 CheckScriptFailure(lines, "E1073:") 533enddef 534 535def DefListAll() 536 def 537enddef 538 539def DefListOne() 540 def DefListOne 541enddef 542 543def DefListMatches() 544 def /DefList 545enddef 546 547def Test_nested_def_list() 548 var funcs = split(execute('call DefListAll()'), "\n") 549 assert_true(len(funcs) > 10) 550 assert_true(funcs->index('def DefListAll()') >= 0) 551 552 funcs = split(execute('call DefListOne()'), "\n") 553 assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs) 554 555 funcs = split(execute('call DefListMatches()'), "\n") 556 assert_true(len(funcs) >= 3) 557 assert_true(funcs->index('def DefListAll()') >= 0) 558 assert_true(funcs->index('def DefListOne()') >= 0) 559 assert_true(funcs->index('def DefListMatches()') >= 0) 560 561 var lines =<< trim END 562 vim9script 563 def Func() 564 def +Func+ 565 enddef 566 defcompile 567 END 568 CheckScriptFailure(lines, 'E476:', 1) 569enddef 570 571def Test_global_local_function() 572 var lines =<< trim END 573 vim9script 574 def g:Func(): string 575 return 'global' 576 enddef 577 def Func(): string 578 return 'local' 579 enddef 580 g:Func()->assert_equal('global') 581 Func()->assert_equal('local') 582 delfunc g:Func 583 END 584 CheckScriptSuccess(lines) 585 586 lines =<< trim END 587 vim9script 588 def g:Funcy() 589 echo 'funcy' 590 enddef 591 s:Funcy() 592 END 593 CheckScriptFailure(lines, 'E117:') 594enddef 595 596def Test_local_function_shadows_global() 597 var lines =<< trim END 598 vim9script 599 def g:Gfunc(): string 600 return 'global' 601 enddef 602 def AnotherFunc(): number 603 var Gfunc = function('len') 604 return Gfunc('testing') 605 enddef 606 g:Gfunc()->assert_equal('global') 607 AnotherFunc()->assert_equal(7) 608 delfunc g:Gfunc 609 END 610 CheckScriptSuccess(lines) 611 612 lines =<< trim END 613 vim9script 614 def g:Func(): string 615 return 'global' 616 enddef 617 def AnotherFunc() 618 g:Func = function('len') 619 enddef 620 AnotherFunc() 621 END 622 CheckScriptFailure(lines, 'E705:') 623 delfunc g:Func 624enddef 625 626func TakesOneArg(arg) 627 echo a:arg 628endfunc 629 630def Test_call_wrong_args() 631 CheckDefFailure(['TakesOneArg()'], 'E119:') 632 CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:') 633 CheckDefFailure(['bufnr(xxx)'], 'E1001:') 634 CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:') 635 636 var lines =<< trim END 637 vim9script 638 def Func(s: string) 639 echo s 640 enddef 641 Func([]) 642 END 643 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5) 644 645 lines =<< trim END 646 vim9script 647 var name = 'piet' 648 def FuncOne(name: string) 649 echo nr 650 enddef 651 END 652 CheckScriptFailure(lines, 'E1168:') 653 654 lines =<< trim END 655 vim9script 656 def FuncOne(nr: number) 657 echo nr 658 enddef 659 def FuncTwo() 660 FuncOne() 661 enddef 662 defcompile 663 END 664 writefile(lines, 'Xscript') 665 var didCatch = false 666 try 667 source Xscript 668 catch 669 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception) 670 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint) 671 didCatch = true 672 endtry 673 assert_true(didCatch) 674 675 lines =<< trim END 676 vim9script 677 def FuncOne(nr: number) 678 echo nr 679 enddef 680 def FuncTwo() 681 FuncOne(1, 2) 682 enddef 683 defcompile 684 END 685 writefile(lines, 'Xscript') 686 didCatch = false 687 try 688 source Xscript 689 catch 690 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception) 691 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint) 692 didCatch = true 693 endtry 694 assert_true(didCatch) 695 696 delete('Xscript') 697enddef 698 699def Test_call_funcref_wrong_args() 700 var head =<< trim END 701 vim9script 702 def Func3(a1: string, a2: number, a3: list<number>) 703 echo a1 .. a2 .. a3[0] 704 enddef 705 def Testme() 706 var funcMap: dict<func> = {func: Func3} 707 END 708 var tail =<< trim END 709 enddef 710 Testme() 711 END 712 CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail) 713 714 CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:') 715 CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:') 716 717 var lines =<< trim END 718 vim9script 719 var Ref: func(number): any 720 Ref = (j) => !j 721 echo Ref(false) 722 END 723 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4) 724 725 lines =<< trim END 726 vim9script 727 var Ref: func(number): any 728 Ref = (j) => !j 729 call Ref(false) 730 END 731 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4) 732enddef 733 734def Test_call_lambda_args() 735 CheckDefFailure(['echo ((i) => 0)()'], 736 'E119: Not enough arguments for function: ((i) => 0)()') 737 738 var lines =<< trim END 739 var Ref = (x: number, y: number) => x + y 740 echo Ref(1, 'x') 741 END 742 CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string') 743 744 lines =<< trim END 745 var Ref: func(job, string, number) 746 Ref = (x, y) => 0 747 END 748 CheckDefAndScriptFailure(lines, 'E1012:') 749 750 lines =<< trim END 751 var Ref: func(job, string) 752 Ref = (x, y, z) => 0 753 END 754 CheckDefAndScriptFailure(lines, 'E1012:') 755 756 lines =<< trim END 757 var one = 1 758 var l = [1, 2, 3] 759 echo map(l, (one) => one) 760 END 761 CheckDefFailure(lines, 'E1167:') 762 CheckScriptFailure(['vim9script'] + lines, 'E1168:') 763 764 lines =<< trim END 765 def ShadowLocal() 766 var one = 1 767 var l = [1, 2, 3] 768 echo map(l, (one) => one) 769 enddef 770 END 771 CheckDefFailure(lines, 'E1167:') 772 773 lines =<< trim END 774 def Shadowarg(one: number) 775 var l = [1, 2, 3] 776 echo map(l, (one) => one) 777 enddef 778 END 779 CheckDefFailure(lines, 'E1167:') 780enddef 781 782def FilterWithCond(x: string, Cond: func(string): bool): bool 783 return Cond(x) 784enddef 785 786def Test_lambda_return_type() 787 var lines =<< trim END 788 var Ref = (): => 123 789 END 790 CheckDefAndScriptFailure(lines, 'E1157:', 1) 791 792 # this works 793 for x in ['foo', 'boo'] 794 echo FilterWithCond(x, (v) => v =~ '^b') 795 endfor 796 797 # this fails 798 lines =<< trim END 799 echo FilterWithCond('foo', (v) => v .. '^b') 800 END 801 CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected func(string): bool but got func(any): string', 1) 802enddef 803 804def Test_lambda_uses_assigned_var() 805 CheckDefSuccess([ 806 'var x: any = "aaa"' 807 'x = filter(["bbb"], (_, v) => v =~ x)']) 808enddef 809 810def Test_pass_legacy_lambda_to_def_func() 811 var lines =<< trim END 812 vim9script 813 func Foo() 814 eval s:Bar({x -> 0}) 815 endfunc 816 def Bar(y: any) 817 enddef 818 Foo() 819 END 820 CheckScriptSuccess(lines) 821enddef 822 823" Default arg and varargs 824def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string 825 var res = one .. ',' .. two 826 for s in rest 827 res ..= ',' .. s 828 endfor 829 return res 830enddef 831 832def Test_call_def_varargs() 833 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs') 834 MyDefVarargs('one')->assert_equal('one,foo') 835 MyDefVarargs('one', 'two')->assert_equal('one,two') 836 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three') 837 CheckDefFailure(['MyDefVarargs("one", 22)'], 838 'E1013: Argument 2: type mismatch, expected string but got number') 839 CheckDefFailure(['MyDefVarargs("one", "two", 123)'], 840 'E1013: Argument 3: type mismatch, expected string but got number') 841 842 var lines =<< trim END 843 vim9script 844 def Func(...l: list<string>) 845 echo l 846 enddef 847 Func('a', 'b', 'c') 848 END 849 CheckScriptSuccess(lines) 850 851 lines =<< trim END 852 vim9script 853 def Func(...l: list<string>) 854 echo l 855 enddef 856 Func() 857 END 858 CheckScriptSuccess(lines) 859 860 lines =<< trim END 861 vim9script 862 def Func(...l: any) 863 echo l 864 enddef 865 Func(0) 866 END 867 CheckScriptSuccess(lines) 868 869 lines =<< trim END 870 vim9script 871 def Func(..._l: list<string>) 872 echo _l 873 enddef 874 Func('a', 'b', 'c') 875 END 876 CheckScriptSuccess(lines) 877 878 lines =<< trim END 879 vim9script 880 def Func(...l: list<string>) 881 echo l 882 enddef 883 Func(1, 2, 3) 884 END 885 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch') 886 887 lines =<< trim END 888 vim9script 889 def Func(...l: list<string>) 890 echo l 891 enddef 892 Func('a', 9) 893 END 894 CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch') 895 896 lines =<< trim END 897 vim9script 898 def Func(...l: list<string>) 899 echo l 900 enddef 901 Func(1, 'a') 902 END 903 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch') 904 905 lines =<< trim END 906 vim9script 907 def Func( # some comment 908 ...l = [] 909 ) 910 echo l 911 enddef 912 END 913 CheckScriptFailure(lines, 'E1160:') 914enddef 915 916let s:value = '' 917 918def FuncOneDefArg(opt = 'text') 919 s:value = opt 920enddef 921 922def FuncTwoDefArg(nr = 123, opt = 'text'): string 923 return nr .. opt 924enddef 925 926def FuncVarargs(...arg: list<string>): string 927 return join(arg, ',') 928enddef 929 930def Test_func_type_varargs() 931 var RefDefArg: func(?string) 932 RefDefArg = FuncOneDefArg 933 RefDefArg() 934 s:value->assert_equal('text') 935 RefDefArg('some') 936 s:value->assert_equal('some') 937 938 var RefDef2Arg: func(?number, ?string): string 939 RefDef2Arg = FuncTwoDefArg 940 RefDef2Arg()->assert_equal('123text') 941 RefDef2Arg(99)->assert_equal('99text') 942 RefDef2Arg(77, 'some')->assert_equal('77some') 943 944 CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:') 945 CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:') 946 947 var RefVarargs: func(...list<string>): string 948 RefVarargs = FuncVarargs 949 RefVarargs()->assert_equal('') 950 RefVarargs('one')->assert_equal('one') 951 RefVarargs('one', 'two')->assert_equal('one,two') 952 953 CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:') 954 CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:') 955enddef 956 957" Only varargs 958def MyVarargsOnly(...args: list<string>): string 959 return join(args, ',') 960enddef 961 962def Test_call_varargs_only() 963 MyVarargsOnly()->assert_equal('') 964 MyVarargsOnly('one')->assert_equal('one') 965 MyVarargsOnly('one', 'two')->assert_equal('one,two') 966 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number') 967 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number') 968enddef 969 970def Test_using_var_as_arg() 971 writefile(['def Func(x: number)', 'var x = 234', 'enddef', 'defcompile'], 'Xdef') 972 assert_fails('so Xdef', 'E1006:', '', 1, 'Func') 973 delete('Xdef') 974enddef 975 976def DictArg(arg: dict<string>) 977 arg['key'] = 'value' 978enddef 979 980def ListArg(arg: list<string>) 981 arg[0] = 'value' 982enddef 983 984def Test_assign_to_argument() 985 # works for dict and list 986 var d: dict<string> = {} 987 DictArg(d) 988 d['key']->assert_equal('value') 989 var l: list<string> = [] 990 ListArg(l) 991 l[0]->assert_equal('value') 992 993 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:') 994 delfunc! g:Func 995enddef 996 997" These argument names are reserved in legacy functions. 998def WithReservedNames(firstline: string, lastline: string): string 999 return firstline .. lastline 1000enddef 1001 1002def Test_argument_names() 1003 assert_equal('OK', WithReservedNames('O', 'K')) 1004enddef 1005 1006def Test_call_func_defined_later() 1007 g:DefinedLater('one')->assert_equal('one') 1008 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later') 1009enddef 1010 1011func DefinedLater(arg) 1012 return a:arg 1013endfunc 1014 1015def Test_call_funcref() 1016 g:SomeFunc('abc')->assert_equal(3) 1017 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call 1018 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref') 1019 1020 var lines =<< trim END 1021 vim9script 1022 def RetNumber(): number 1023 return 123 1024 enddef 1025 var Funcref: func: number = function('RetNumber') 1026 Funcref()->assert_equal(123) 1027 END 1028 CheckScriptSuccess(lines) 1029 1030 lines =<< trim END 1031 vim9script 1032 def RetNumber(): number 1033 return 123 1034 enddef 1035 def Bar(F: func: number): number 1036 return F() 1037 enddef 1038 var Funcref = function('RetNumber') 1039 Bar(Funcref)->assert_equal(123) 1040 END 1041 CheckScriptSuccess(lines) 1042 1043 lines =<< trim END 1044 vim9script 1045 def UseNumber(nr: number) 1046 echo nr 1047 enddef 1048 var Funcref: func(number) = function('UseNumber') 1049 Funcref(123) 1050 END 1051 CheckScriptSuccess(lines) 1052 1053 lines =<< trim END 1054 vim9script 1055 def UseNumber(nr: number) 1056 echo nr 1057 enddef 1058 var Funcref: func(string) = function('UseNumber') 1059 END 1060 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)') 1061 1062 lines =<< trim END 1063 vim9script 1064 def EchoNr(nr = 34) 1065 g:echo = nr 1066 enddef 1067 var Funcref: func(?number) = function('EchoNr') 1068 Funcref() 1069 g:echo->assert_equal(34) 1070 Funcref(123) 1071 g:echo->assert_equal(123) 1072 END 1073 CheckScriptSuccess(lines) 1074 1075 lines =<< trim END 1076 vim9script 1077 def EchoList(...l: list<number>) 1078 g:echo = l 1079 enddef 1080 var Funcref: func(...list<number>) = function('EchoList') 1081 Funcref() 1082 g:echo->assert_equal([]) 1083 Funcref(1, 2, 3) 1084 g:echo->assert_equal([1, 2, 3]) 1085 END 1086 CheckScriptSuccess(lines) 1087 1088 lines =<< trim END 1089 vim9script 1090 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number 1091 g:optarg = opt 1092 g:listarg = l 1093 return nr 1094 enddef 1095 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar') 1096 Funcref(10)->assert_equal(10) 1097 g:optarg->assert_equal(12) 1098 g:listarg->assert_equal([]) 1099 1100 Funcref(11, 22)->assert_equal(11) 1101 g:optarg->assert_equal(22) 1102 g:listarg->assert_equal([]) 1103 1104 Funcref(17, 18, 1, 2, 3)->assert_equal(17) 1105 g:optarg->assert_equal(18) 1106 g:listarg->assert_equal([1, 2, 3]) 1107 END 1108 CheckScriptSuccess(lines) 1109enddef 1110 1111let SomeFunc = function('len') 1112let NotAFunc = 'text' 1113 1114def CombineFuncrefTypes() 1115 # same arguments, different return type 1116 var Ref1: func(bool): string 1117 var Ref2: func(bool): number 1118 var Ref3: func(bool): any 1119 Ref3 = g:cond ? Ref1 : Ref2 1120 1121 # different number of arguments 1122 var Refa1: func(bool): number 1123 var Refa2: func(bool, number): number 1124 var Refa3: func: number 1125 Refa3 = g:cond ? Refa1 : Refa2 1126 1127 # different argument types 1128 var Refb1: func(bool, string): number 1129 var Refb2: func(string, number): number 1130 var Refb3: func(any, any): number 1131 Refb3 = g:cond ? Refb1 : Refb2 1132enddef 1133 1134def FuncWithForwardCall() 1135 return g:DefinedEvenLater("yes") 1136enddef 1137 1138def DefinedEvenLater(arg: string): string 1139 return arg 1140enddef 1141 1142def Test_error_in_nested_function() 1143 # Error in called function requires unwinding the call stack. 1144 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall') 1145enddef 1146 1147def Test_return_type_wrong() 1148 CheckScriptFailure([ 1149 'def Func(): number', 1150 'return "a"', 1151 'enddef', 1152 'defcompile'], 'expected number but got string') 1153 delfunc! g:Func 1154 CheckScriptFailure([ 1155 'def Func(): string', 1156 'return 1', 1157 'enddef', 1158 'defcompile'], 'expected string but got number') 1159 delfunc! g:Func 1160 CheckScriptFailure([ 1161 'def Func(): void', 1162 'return "a"', 1163 'enddef', 1164 'defcompile'], 1165 'E1096: Returning a value in a function without a return type') 1166 delfunc! g:Func 1167 CheckScriptFailure([ 1168 'def Func()', 1169 'return "a"', 1170 'enddef', 1171 'defcompile'], 1172 'E1096: Returning a value in a function without a return type') 1173 delfunc! g:Func 1174 1175 CheckScriptFailure([ 1176 'def Func(): number', 1177 'return', 1178 'enddef', 1179 'defcompile'], 'E1003:') 1180 delfunc! g:Func 1181 1182 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:') 1183 delfunc! g:Func 1184 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:') 1185 delfunc! g:Func 1186 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:') 1187 delfunc! g:Func 1188 1189 CheckScriptFailure([ 1190 'vim9script', 1191 'def FuncB()', 1192 ' return 123', 1193 'enddef', 1194 'def FuncA()', 1195 ' FuncB()', 1196 'enddef', 1197 'defcompile'], 'E1096:') 1198enddef 1199 1200def Test_arg_type_wrong() 1201 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>') 1202 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...') 1203 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:') 1204 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:') 1205enddef 1206 1207def Test_white_space_after_comma() 1208 var lines =<< trim END 1209 vim9script 1210 def Func(a: number,b: number) 1211 enddef 1212 END 1213 CheckScriptFailure(lines, 'E1069:') 1214 1215 # OK in legacy function 1216 lines =<< trim END 1217 vim9script 1218 func Func(a,b) 1219 endfunc 1220 END 1221 CheckScriptSuccess(lines) 1222enddef 1223 1224def Test_vim9script_call() 1225 var lines =<< trim END 1226 vim9script 1227 var name = '' 1228 def MyFunc(arg: string) 1229 name = arg 1230 enddef 1231 MyFunc('foobar') 1232 name->assert_equal('foobar') 1233 1234 var str = 'barfoo' 1235 str->MyFunc() 1236 name->assert_equal('barfoo') 1237 1238 g:value = 'value' 1239 g:value->MyFunc() 1240 name->assert_equal('value') 1241 1242 var listvar = [] 1243 def ListFunc(arg: list<number>) 1244 listvar = arg 1245 enddef 1246 [1, 2, 3]->ListFunc() 1247 listvar->assert_equal([1, 2, 3]) 1248 1249 var dictvar = {} 1250 def DictFunc(arg: dict<number>) 1251 dictvar = arg 1252 enddef 1253 {a: 1, b: 2}->DictFunc() 1254 dictvar->assert_equal({a: 1, b: 2}) 1255 def CompiledDict() 1256 {a: 3, b: 4}->DictFunc() 1257 enddef 1258 CompiledDict() 1259 dictvar->assert_equal({a: 3, b: 4}) 1260 1261 {a: 3, b: 4}->DictFunc() 1262 dictvar->assert_equal({a: 3, b: 4}) 1263 1264 ('text')->MyFunc() 1265 name->assert_equal('text') 1266 ("some")->MyFunc() 1267 name->assert_equal('some') 1268 1269 # line starting with single quote is not a mark 1270 # line starting with double quote can be a method call 1271 'asdfasdf'->MyFunc() 1272 name->assert_equal('asdfasdf') 1273 "xyz"->MyFunc() 1274 name->assert_equal('xyz') 1275 1276 def UseString() 1277 'xyork'->MyFunc() 1278 enddef 1279 UseString() 1280 name->assert_equal('xyork') 1281 1282 def UseString2() 1283 "knife"->MyFunc() 1284 enddef 1285 UseString2() 1286 name->assert_equal('knife') 1287 1288 # prepending a colon makes it a mark 1289 new 1290 setline(1, ['aaa', 'bbb', 'ccc']) 1291 normal! 3Gmt1G 1292 :'t 1293 getcurpos()[1]->assert_equal(3) 1294 bwipe! 1295 1296 MyFunc( 1297 'continued' 1298 ) 1299 assert_equal('continued', 1300 name 1301 ) 1302 1303 call MyFunc( 1304 'more' 1305 .. 1306 'lines' 1307 ) 1308 assert_equal( 1309 'morelines', 1310 name) 1311 END 1312 writefile(lines, 'Xcall.vim') 1313 source Xcall.vim 1314 delete('Xcall.vim') 1315enddef 1316 1317def Test_vim9script_call_fail_decl() 1318 var lines =<< trim END 1319 vim9script 1320 var name = '' 1321 def MyFunc(arg: string) 1322 var name = 123 1323 enddef 1324 defcompile 1325 END 1326 CheckScriptFailure(lines, 'E1054:') 1327enddef 1328 1329def Test_vim9script_call_fail_type() 1330 var lines =<< trim END 1331 vim9script 1332 def MyFunc(arg: string) 1333 echo arg 1334 enddef 1335 MyFunc(1234) 1336 END 1337 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number') 1338enddef 1339 1340def Test_vim9script_call_fail_const() 1341 var lines =<< trim END 1342 vim9script 1343 const var = '' 1344 def MyFunc(arg: string) 1345 var = 'asdf' 1346 enddef 1347 defcompile 1348 END 1349 writefile(lines, 'Xcall_const.vim') 1350 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc') 1351 delete('Xcall_const.vim') 1352 1353 lines =<< trim END 1354 const g:Aconst = 77 1355 def Change() 1356 # comment 1357 g:Aconst = 99 1358 enddef 1359 call Change() 1360 unlet g:Aconst 1361 END 1362 CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2) 1363enddef 1364 1365" Test that inside :function a Python function can be defined, :def is not 1366" recognized. 1367func Test_function_python() 1368 CheckFeature python3 1369 let py = 'python3' 1370 execute py "<< EOF" 1371def do_something(): 1372 return 1 1373EOF 1374endfunc 1375 1376def Test_delfunc() 1377 var lines =<< trim END 1378 vim9script 1379 def g:GoneSoon() 1380 echo 'hello' 1381 enddef 1382 1383 def CallGoneSoon() 1384 GoneSoon() 1385 enddef 1386 defcompile 1387 1388 delfunc g:GoneSoon 1389 CallGoneSoon() 1390 END 1391 writefile(lines, 'XToDelFunc') 1392 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon') 1393 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon') 1394 1395 delete('XToDelFunc') 1396enddef 1397 1398def Test_redef_failure() 1399 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef') 1400 so Xdef 1401 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef') 1402 so Xdef 1403 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef') 1404 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0') 1405 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef') 1406 so Xdef 1407 delete('Xdef') 1408 1409 g:Func0()->assert_equal(0) 1410 g:Func1()->assert_equal('Func1') 1411 g:Func2()->assert_equal('Func2') 1412 1413 delfunc! Func0 1414 delfunc! Func1 1415 delfunc! Func2 1416enddef 1417 1418def Test_vim9script_func() 1419 var lines =<< trim END 1420 vim9script 1421 func Func(arg) 1422 echo a:arg 1423 endfunc 1424 Func('text') 1425 END 1426 writefile(lines, 'XVim9Func') 1427 so XVim9Func 1428 1429 delete('XVim9Func') 1430enddef 1431 1432let s:funcResult = 0 1433 1434def FuncNoArgNoRet() 1435 s:funcResult = 11 1436enddef 1437 1438def FuncNoArgRetNumber(): number 1439 s:funcResult = 22 1440 return 1234 1441enddef 1442 1443def FuncNoArgRetString(): string 1444 s:funcResult = 45 1445 return 'text' 1446enddef 1447 1448def FuncOneArgNoRet(arg: number) 1449 s:funcResult = arg 1450enddef 1451 1452def FuncOneArgRetNumber(arg: number): number 1453 s:funcResult = arg 1454 return arg 1455enddef 1456 1457def FuncTwoArgNoRet(one: bool, two: number) 1458 s:funcResult = two 1459enddef 1460 1461def FuncOneArgRetString(arg: string): string 1462 return arg 1463enddef 1464 1465def FuncOneArgRetAny(arg: any): any 1466 return arg 1467enddef 1468 1469def Test_func_type() 1470 var Ref1: func() 1471 s:funcResult = 0 1472 Ref1 = FuncNoArgNoRet 1473 Ref1() 1474 s:funcResult->assert_equal(11) 1475 1476 var Ref2: func 1477 s:funcResult = 0 1478 Ref2 = FuncNoArgNoRet 1479 Ref2() 1480 s:funcResult->assert_equal(11) 1481 1482 s:funcResult = 0 1483 Ref2 = FuncOneArgNoRet 1484 Ref2(12) 1485 s:funcResult->assert_equal(12) 1486 1487 s:funcResult = 0 1488 Ref2 = FuncNoArgRetNumber 1489 Ref2()->assert_equal(1234) 1490 s:funcResult->assert_equal(22) 1491 1492 s:funcResult = 0 1493 Ref2 = FuncOneArgRetNumber 1494 Ref2(13)->assert_equal(13) 1495 s:funcResult->assert_equal(13) 1496enddef 1497 1498def Test_repeat_return_type() 1499 var res = 0 1500 for n in repeat([1], 3) 1501 res += n 1502 endfor 1503 res->assert_equal(3) 1504 1505 res = 0 1506 for n in add([1, 2], 3) 1507 res += n 1508 endfor 1509 res->assert_equal(6) 1510enddef 1511 1512def Test_argv_return_type() 1513 next fileone filetwo 1514 var res = '' 1515 for name in argv() 1516 res ..= name 1517 endfor 1518 res->assert_equal('fileonefiletwo') 1519enddef 1520 1521def Test_func_type_part() 1522 var RefVoid: func: void 1523 RefVoid = FuncNoArgNoRet 1524 RefVoid = FuncOneArgNoRet 1525 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number') 1526 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string') 1527 1528 var RefAny: func(): any 1529 RefAny = FuncNoArgRetNumber 1530 RefAny = FuncNoArgRetString 1531 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()') 1532 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)') 1533 1534 var RefAnyNoArgs: func: any = RefAny 1535 1536 var RefNr: func: number 1537 RefNr = FuncNoArgRetNumber 1538 RefNr = FuncOneArgRetNumber 1539 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()') 1540 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string') 1541 1542 var RefStr: func: string 1543 RefStr = FuncNoArgRetString 1544 RefStr = FuncOneArgRetString 1545 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()') 1546 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number') 1547enddef 1548 1549def Test_func_type_fails() 1550 CheckDefFailure(['var ref1: func()'], 'E704:') 1551 1552 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number') 1553 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)') 1554 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number') 1555 CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)') 1556 CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)') 1557 CheckDefFailure(['var Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(...bool) but got func(bool, number)') 1558 1559 CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:') 1560 CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:') 1561 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:') 1562 CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:') 1563enddef 1564 1565def Test_func_return_type() 1566 var nr: number 1567 nr = FuncNoArgRetNumber() 1568 nr->assert_equal(1234) 1569 1570 nr = FuncOneArgRetAny(122) 1571 nr->assert_equal(122) 1572 1573 var str: string 1574 str = FuncOneArgRetAny('yes') 1575 str->assert_equal('yes') 1576 1577 CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number') 1578enddef 1579 1580def Test_func_common_type() 1581 def FuncOne(n: number): number 1582 return n 1583 enddef 1584 def FuncTwo(s: string): number 1585 return len(s) 1586 enddef 1587 def FuncThree(n: number, s: string): number 1588 return n + len(s) 1589 enddef 1590 var list = [FuncOne, FuncTwo, FuncThree] 1591 assert_equal(8, list[0](8)) 1592 assert_equal(4, list[1]('word')) 1593 assert_equal(7, list[2](3, 'word')) 1594enddef 1595 1596def MultiLine( 1597 arg1: string, 1598 arg2 = 1234, 1599 ...rest: list<string> 1600 ): string 1601 return arg1 .. arg2 .. join(rest, '-') 1602enddef 1603 1604def MultiLineComment( 1605 arg1: string, # comment 1606 arg2 = 1234, # comment 1607 ...rest: list<string> # comment 1608 ): string # comment 1609 return arg1 .. arg2 .. join(rest, '-') 1610enddef 1611 1612def Test_multiline() 1613 MultiLine('text')->assert_equal('text1234') 1614 MultiLine('text', 777)->assert_equal('text777') 1615 MultiLine('text', 777, 'one')->assert_equal('text777one') 1616 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two') 1617enddef 1618 1619func Test_multiline_not_vim9() 1620 call MultiLine('text')->assert_equal('text1234') 1621 call MultiLine('text', 777)->assert_equal('text777') 1622 call MultiLine('text', 777, 'one')->assert_equal('text777one') 1623 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two') 1624endfunc 1625 1626 1627" When using CheckScriptFailure() for the below test, E1010 is generated instead 1628" of E1056. 1629func Test_E1056_1059() 1630 let caught_1056 = 0 1631 try 1632 def F(): 1633 return 1 1634 enddef 1635 catch /E1056:/ 1636 let caught_1056 = 1 1637 endtry 1638 eval caught_1056->assert_equal(1) 1639 1640 let caught_1059 = 0 1641 try 1642 def F5(items : list) 1643 echo 'a' 1644 enddef 1645 catch /E1059:/ 1646 let caught_1059 = 1 1647 endtry 1648 eval caught_1059->assert_equal(1) 1649endfunc 1650 1651func DelMe() 1652 echo 'DelMe' 1653endfunc 1654 1655def Test_error_reporting() 1656 # comment lines at the start of the function 1657 var lines =<< trim END 1658 " comment 1659 def Func() 1660 # comment 1661 # comment 1662 invalid 1663 enddef 1664 defcompile 1665 END 1666 writefile(lines, 'Xdef') 1667 try 1668 source Xdef 1669 assert_report('should have failed') 1670 catch /E476:/ 1671 v:exception->assert_match('Invalid command: invalid') 1672 v:throwpoint->assert_match(', line 3$') 1673 endtry 1674 delfunc! g:Func 1675 1676 # comment lines after the start of the function 1677 lines =<< trim END 1678 " comment 1679 def Func() 1680 var x = 1234 1681 # comment 1682 # comment 1683 invalid 1684 enddef 1685 defcompile 1686 END 1687 writefile(lines, 'Xdef') 1688 try 1689 source Xdef 1690 assert_report('should have failed') 1691 catch /E476:/ 1692 v:exception->assert_match('Invalid command: invalid') 1693 v:throwpoint->assert_match(', line 4$') 1694 endtry 1695 delfunc! g:Func 1696 1697 lines =<< trim END 1698 vim9script 1699 def Func() 1700 var db = {foo: 1, bar: 2} 1701 # comment 1702 var x = db.asdf 1703 enddef 1704 defcompile 1705 Func() 1706 END 1707 writefile(lines, 'Xdef') 1708 try 1709 source Xdef 1710 assert_report('should have failed') 1711 catch /E716:/ 1712 v:throwpoint->assert_match('_Func, line 3$') 1713 endtry 1714 delfunc! g:Func 1715 1716 delete('Xdef') 1717enddef 1718 1719def Test_deleted_function() 1720 CheckDefExecFailure([ 1721 'var RefMe: func = function("g:DelMe")', 1722 'delfunc g:DelMe', 1723 'echo RefMe()'], 'E117:') 1724enddef 1725 1726def Test_unknown_function() 1727 CheckDefExecFailure([ 1728 'var Ref: func = function("NotExist")', 1729 'delfunc g:NotExist'], 'E700:') 1730enddef 1731 1732def RefFunc(Ref: func(any): any): string 1733 return Ref('more') 1734enddef 1735 1736def Test_closure_simple() 1737 var local = 'some ' 1738 RefFunc((s) => local .. s)->assert_equal('some more') 1739enddef 1740 1741def MakeRef() 1742 var local = 'some ' 1743 g:Ref = (s) => local .. s 1744enddef 1745 1746def Test_closure_ref_after_return() 1747 MakeRef() 1748 g:Ref('thing')->assert_equal('some thing') 1749 unlet g:Ref 1750enddef 1751 1752def MakeTwoRefs() 1753 var local = ['some'] 1754 g:Extend = (s) => local->add(s) 1755 g:Read = () => local 1756enddef 1757 1758def Test_closure_two_refs() 1759 MakeTwoRefs() 1760 join(g:Read(), ' ')->assert_equal('some') 1761 g:Extend('more') 1762 join(g:Read(), ' ')->assert_equal('some more') 1763 g:Extend('even') 1764 join(g:Read(), ' ')->assert_equal('some more even') 1765 1766 unlet g:Extend 1767 unlet g:Read 1768enddef 1769 1770def ReadRef(Ref: func(): list<string>): string 1771 return join(Ref(), ' ') 1772enddef 1773 1774def ExtendRef(Ref: func(string): list<string>, add: string) 1775 Ref(add) 1776enddef 1777 1778def Test_closure_two_indirect_refs() 1779 MakeTwoRefs() 1780 ReadRef(g:Read)->assert_equal('some') 1781 ExtendRef(g:Extend, 'more') 1782 ReadRef(g:Read)->assert_equal('some more') 1783 ExtendRef(g:Extend, 'even') 1784 ReadRef(g:Read)->assert_equal('some more even') 1785 1786 unlet g:Extend 1787 unlet g:Read 1788enddef 1789 1790def MakeArgRefs(theArg: string) 1791 var local = 'loc_val' 1792 g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s 1793enddef 1794 1795def MakeArgRefsVarargs(theArg: string, ...rest: list<string>) 1796 var local = 'the_loc' 1797 g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest) 1798enddef 1799 1800def Test_closure_using_argument() 1801 MakeArgRefs('arg_val') 1802 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val') 1803 1804 MakeArgRefsVarargs('arg_val', 'one', 'two') 1805 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two') 1806 1807 unlet g:UseArg 1808 unlet g:UseVararg 1809 1810 var lines =<< trim END 1811 vim9script 1812 def Test(Fun: func(number): number): list<number> 1813 return map([1, 2, 3], (_, i) => Fun(i)) 1814 enddef 1815 def Inc(nr: number): number 1816 return nr + 2 1817 enddef 1818 assert_equal([3, 4, 5], Test(Inc)) 1819 END 1820 CheckScriptSuccess(lines) 1821enddef 1822 1823def MakeGetAndAppendRefs() 1824 var local = 'a' 1825 1826 def Append(arg: string) 1827 local ..= arg 1828 enddef 1829 g:Append = Append 1830 1831 def Get(): string 1832 return local 1833 enddef 1834 g:Get = Get 1835enddef 1836 1837def Test_closure_append_get() 1838 MakeGetAndAppendRefs() 1839 g:Get()->assert_equal('a') 1840 g:Append('-b') 1841 g:Get()->assert_equal('a-b') 1842 g:Append('-c') 1843 g:Get()->assert_equal('a-b-c') 1844 1845 unlet g:Append 1846 unlet g:Get 1847enddef 1848 1849def Test_nested_closure() 1850 var local = 'text' 1851 def Closure(arg: string): string 1852 return local .. arg 1853 enddef 1854 Closure('!!!')->assert_equal('text!!!') 1855enddef 1856 1857func GetResult(Ref) 1858 return a:Ref('some') 1859endfunc 1860 1861def Test_call_closure_not_compiled() 1862 var text = 'text' 1863 g:Ref = (s) => s .. text 1864 GetResult(g:Ref)->assert_equal('sometext') 1865enddef 1866 1867def Test_double_closure_fails() 1868 var lines =<< trim END 1869 vim9script 1870 def Func() 1871 var name = 0 1872 for i in range(2) 1873 timer_start(0, () => name) 1874 endfor 1875 enddef 1876 Func() 1877 END 1878 CheckScriptSuccess(lines) 1879enddef 1880 1881def Test_nested_closure_used() 1882 var lines =<< trim END 1883 vim9script 1884 def Func() 1885 var x = 'hello' 1886 var Closure = () => x 1887 g:Myclosure = () => Closure() 1888 enddef 1889 Func() 1890 assert_equal('hello', g:Myclosure()) 1891 END 1892 CheckScriptSuccess(lines) 1893enddef 1894 1895def Test_nested_closure_fails() 1896 var lines =<< trim END 1897 vim9script 1898 def FuncA() 1899 FuncB(0) 1900 enddef 1901 def FuncB(n: number): list<string> 1902 return map([0], (_, v) => n) 1903 enddef 1904 FuncA() 1905 END 1906 CheckScriptFailure(lines, 'E1012:') 1907enddef 1908 1909def Test_global_closure() 1910 var lines =<< trim END 1911 vim9script 1912 def ReverseEveryNLines(n: number, line1: number, line2: number) 1913 var mods = 'sil keepj keepp lockm ' 1914 var range = ':' .. line1 .. ',' .. line2 1915 def g:Offset(): number 1916 var offset = (line('.') - line1 + 1) % n 1917 return offset != 0 ? offset : n 1918 enddef 1919 exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()' 1920 enddef 1921 1922 new 1923 repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1) 1924 ReverseEveryNLines(3, 1, 9) 1925 END 1926 CheckScriptSuccess(lines) 1927 var expected = repeat(['ccc', 'bbb', 'aaa'], 3) 1928 assert_equal(expected, getline(1, 9)) 1929 bwipe! 1930enddef 1931 1932def Test_global_closure_called_directly() 1933 var lines =<< trim END 1934 vim9script 1935 def Outer() 1936 var x = 1 1937 def g:Inner() 1938 var y = x 1939 x += 1 1940 assert_equal(1, y) 1941 enddef 1942 g:Inner() 1943 assert_equal(2, x) 1944 enddef 1945 Outer() 1946 END 1947 CheckScriptSuccess(lines) 1948 delfunc g:Inner 1949enddef 1950 1951def Test_failure_in_called_function() 1952 # this was using the frame index as the return value 1953 var lines =<< trim END 1954 vim9script 1955 au TerminalWinOpen * eval [][0] 1956 def PopupTerm(a: any) 1957 # make sure typvals on stack are string 1958 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join() 1959 FireEvent() 1960 enddef 1961 def FireEvent() 1962 do TerminalWinOpen 1963 enddef 1964 # use try/catch to make eval fail 1965 try 1966 call PopupTerm(0) 1967 catch 1968 endtry 1969 au! TerminalWinOpen 1970 END 1971 CheckScriptSuccess(lines) 1972enddef 1973 1974def Test_nested_lambda() 1975 var lines =<< trim END 1976 vim9script 1977 def Func() 1978 var x = 4 1979 var Lambda1 = () => 7 1980 var Lambda2 = () => [Lambda1(), x] 1981 var res = Lambda2() 1982 assert_equal([7, 4], res) 1983 enddef 1984 Func() 1985 END 1986 CheckScriptSuccess(lines) 1987enddef 1988 1989def Shadowed(): list<number> 1990 var FuncList: list<func: number> = [() => 42] 1991 return FuncList->mapnew((_, Shadowed) => Shadowed()) 1992enddef 1993 1994def Test_lambda_arg_shadows_func() 1995 assert_equal([42], Shadowed()) 1996enddef 1997 1998def Line_continuation_in_def(dir: string = ''): string 1999 var path: string = empty(dir) 2000 \ ? 'empty' 2001 \ : 'full' 2002 return path 2003enddef 2004 2005def Test_line_continuation_in_def() 2006 Line_continuation_in_def('.')->assert_equal('full') 2007enddef 2008 2009def Test_script_var_in_lambda() 2010 var lines =<< trim END 2011 vim9script 2012 var script = 'test' 2013 assert_equal(['test'], map(['one'], () => script)) 2014 END 2015 CheckScriptSuccess(lines) 2016enddef 2017 2018def Line_continuation_in_lambda(): list<string> 2019 var x = range(97, 100) 2020 ->mapnew((_, v) => nr2char(v) 2021 ->toupper()) 2022 ->reverse() 2023 return x 2024enddef 2025 2026def Test_line_continuation_in_lambda() 2027 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A']) 2028 2029 var lines =<< trim END 2030 vim9script 2031 var res = [{n: 1, m: 2, s: 'xxx'}] 2032 ->mapnew((_, v: dict<any>): string => printf('%d:%d:%s', 2033 v.n, 2034 v.m, 2035 substitute(v.s, '.*', 'yyy', '') 2036 )) 2037 assert_equal(['1:2:yyy'], res) 2038 END 2039 CheckScriptSuccess(lines) 2040enddef 2041 2042def Test_list_lambda() 2043 timer_start(1000, (_) => 0) 2044 var body = execute(timer_info()[0].callback 2045 ->string() 2046 ->substitute("('", ' ', '') 2047 ->substitute("')", '', '') 2048 ->substitute('function\zs', ' ', '')) 2049 assert_match('def <lambda>\d\+(_: any, ...): number\n1 return 0\n enddef', body) 2050enddef 2051 2052def DoFilterThis(a: string): list<string> 2053 # closure nested inside another closure using argument 2054 var Filter = (l) => filter(l, (_, v) => stridx(v, a) == 0) 2055 return ['x', 'y', 'a', 'x2', 'c']->Filter() 2056enddef 2057 2058def Test_nested_closure_using_argument() 2059 assert_equal(['x', 'x2'], DoFilterThis('x')) 2060enddef 2061 2062def Test_triple_nested_closure() 2063 var what = 'x' 2064 var Match = (val: string, cmp: string): bool => stridx(val, cmp) == 0 2065 var Filter = (l) => filter(l, (_, v) => Match(v, what)) 2066 assert_equal(['x', 'x2'], ['x', 'y', 'a', 'x2', 'c']->Filter()) 2067enddef 2068 2069func Test_silent_echo() 2070 CheckScreendump 2071 2072 let lines =<< trim END 2073 vim9script 2074 def EchoNothing() 2075 silent echo '' 2076 enddef 2077 defcompile 2078 END 2079 call writefile(lines, 'XTest_silent_echo') 2080 2081 " Check that the balloon shows up after a mouse move 2082 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6}) 2083 call term_sendkeys(buf, ":abc") 2084 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {}) 2085 2086 " clean up 2087 call StopVimInTerminal(buf) 2088 call delete('XTest_silent_echo') 2089endfunc 2090 2091def SilentlyError() 2092 execute('silent! invalid') 2093 g:did_it = 'yes' 2094enddef 2095 2096func UserError() 2097 silent! invalid 2098endfunc 2099 2100def SilentlyUserError() 2101 UserError() 2102 g:did_it = 'yes' 2103enddef 2104 2105" This can't be a :def function, because the assert would not be reached. 2106func Test_ignore_silent_error() 2107 let g:did_it = 'no' 2108 call SilentlyError() 2109 call assert_equal('yes', g:did_it) 2110 2111 let g:did_it = 'no' 2112 call SilentlyUserError() 2113 call assert_equal('yes', g:did_it) 2114 2115 unlet g:did_it 2116endfunc 2117 2118def Test_ignore_silent_error_in_filter() 2119 var lines =<< trim END 2120 vim9script 2121 def Filter(winid: number, key: string): bool 2122 if key == 'o' 2123 silent! eval [][0] 2124 return true 2125 endif 2126 return popup_filter_menu(winid, key) 2127 enddef 2128 2129 popup_create('popup', {filter: Filter}) 2130 feedkeys("o\r", 'xnt') 2131 END 2132 CheckScriptSuccess(lines) 2133enddef 2134 2135def Fibonacci(n: number): number 2136 if n < 2 2137 return n 2138 else 2139 return Fibonacci(n - 1) + Fibonacci(n - 2) 2140 endif 2141enddef 2142 2143def Test_recursive_call() 2144 Fibonacci(20)->assert_equal(6765) 2145enddef 2146 2147def TreeWalk(dir: string): list<any> 2148 return readdir(dir)->mapnew((_, val) => 2149 fnamemodify(dir .. '/' .. val, ':p')->isdirectory() 2150 ? {[val]: TreeWalk(dir .. '/' .. val)} 2151 : val 2152 ) 2153enddef 2154 2155def Test_closure_in_map() 2156 mkdir('XclosureDir/tdir', 'p') 2157 writefile(['111'], 'XclosureDir/file1') 2158 writefile(['222'], 'XclosureDir/file2') 2159 writefile(['333'], 'XclosureDir/tdir/file3') 2160 2161 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}]) 2162 2163 delete('XclosureDir', 'rf') 2164enddef 2165 2166def Test_invalid_function_name() 2167 var lines =<< trim END 2168 vim9script 2169 def s: list<string> 2170 END 2171 CheckScriptFailure(lines, 'E129:') 2172 2173 lines =<< trim END 2174 vim9script 2175 def g: list<string> 2176 END 2177 CheckScriptFailure(lines, 'E129:') 2178 2179 lines =<< trim END 2180 vim9script 2181 def <SID>: list<string> 2182 END 2183 CheckScriptFailure(lines, 'E884:') 2184 2185 lines =<< trim END 2186 vim9script 2187 def F list<string> 2188 END 2189 CheckScriptFailure(lines, 'E488:') 2190enddef 2191 2192def Test_partial_call() 2193 var Xsetlist = function('setloclist', [0]) 2194 Xsetlist([], ' ', {title: 'test'}) 2195 getloclist(0, {title: 1})->assert_equal({title: 'test'}) 2196 2197 Xsetlist = function('setloclist', [0, [], ' ']) 2198 Xsetlist({title: 'test'}) 2199 getloclist(0, {title: 1})->assert_equal({title: 'test'}) 2200 2201 Xsetlist = function('setqflist') 2202 Xsetlist([], ' ', {title: 'test'}) 2203 getqflist({title: 1})->assert_equal({title: 'test'}) 2204 2205 Xsetlist = function('setqflist', [[], ' ']) 2206 Xsetlist({title: 'test'}) 2207 getqflist({title: 1})->assert_equal({title: 'test'}) 2208 2209 var Len: func: number = function('len', ['word']) 2210 assert_equal(4, Len()) 2211enddef 2212 2213def Test_cmd_modifier() 2214 tab echo '0' 2215 CheckDefFailure(['5tab echo 3'], 'E16:') 2216enddef 2217 2218def Test_restore_modifiers() 2219 # check that when compiling a :def function command modifiers are not messed 2220 # up. 2221 var lines =<< trim END 2222 vim9script 2223 set eventignore= 2224 autocmd QuickFixCmdPost * copen 2225 def AutocmdsDisabled() 2226 eval 0 2227 enddef 2228 func Func() 2229 noautocmd call s:AutocmdsDisabled() 2230 let g:ei_after = &eventignore 2231 endfunc 2232 Func() 2233 END 2234 CheckScriptSuccess(lines) 2235 g:ei_after->assert_equal('') 2236enddef 2237 2238def StackTop() 2239 eval 1 2240 eval 2 2241 # call not on fourth line 2242 StackBot() 2243enddef 2244 2245def StackBot() 2246 # throw an error 2247 eval [][0] 2248enddef 2249 2250def Test_callstack_def() 2251 try 2252 StackTop() 2253 catch 2254 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2') 2255 endtry 2256enddef 2257 2258" Re-using spot for variable used in block 2259def Test_block_scoped_var() 2260 var lines =<< trim END 2261 vim9script 2262 def Func() 2263 var x = ['a', 'b', 'c'] 2264 if 1 2265 var y = 'x' 2266 map(x, () => y) 2267 endif 2268 var z = x 2269 assert_equal(['x', 'x', 'x'], z) 2270 enddef 2271 Func() 2272 END 2273 CheckScriptSuccess(lines) 2274enddef 2275 2276def Test_reset_did_emsg() 2277 var lines =<< trim END 2278 @s = 'blah' 2279 au BufWinLeave * # 2280 def Func() 2281 var winid = popup_create('popup', {}) 2282 exe '*s' 2283 popup_close(winid) 2284 enddef 2285 Func() 2286 END 2287 CheckScriptFailure(lines, 'E492:', 8) 2288 delfunc! g:Func 2289enddef 2290 2291def Test_did_emsg_reset() 2292 # executing an autocommand resets did_emsg, this should not result in a 2293 # builtin function considered failing 2294 var lines =<< trim END 2295 vim9script 2296 au BufWinLeave * # 2297 def Func() 2298 popup_menu('', {callback: () => popup_create('', {})->popup_close()}) 2299 eval [][0] 2300 enddef 2301 nno <F3> <cmd>call <sid>Func()<cr> 2302 feedkeys("\<F3>\e", 'xt') 2303 END 2304 writefile(lines, 'XemsgReset') 2305 assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2) 2306 delete('XemsgReset') 2307 nunmap <F3> 2308 au! BufWinLeave 2309enddef 2310 2311def Test_abort_with_silent_call() 2312 var lines =<< trim END 2313 vim9script 2314 g:result = 'none' 2315 def Func() 2316 g:result += 3 2317 g:result = 'yes' 2318 enddef 2319 # error is silenced, but function aborts on error 2320 silent! Func() 2321 assert_equal('none', g:result) 2322 unlet g:result 2323 END 2324 CheckScriptSuccess(lines) 2325enddef 2326 2327def Test_continues_with_silent_error() 2328 var lines =<< trim END 2329 vim9script 2330 g:result = 'none' 2331 def Func() 2332 silent! g:result += 3 2333 g:result = 'yes' 2334 enddef 2335 # error is silenced, function does not abort 2336 Func() 2337 assert_equal('yes', g:result) 2338 unlet g:result 2339 END 2340 CheckScriptSuccess(lines) 2341enddef 2342 2343def Test_abort_even_with_silent() 2344 var lines =<< trim END 2345 vim9script 2346 g:result = 'none' 2347 def Func() 2348 eval {-> ''}() .. '' .. {}['X'] 2349 g:result = 'yes' 2350 enddef 2351 silent! Func() 2352 assert_equal('none', g:result) 2353 unlet g:result 2354 END 2355 CheckScriptSuccess(lines) 2356enddef 2357 2358def Test_cmdmod_silent_restored() 2359 var lines =<< trim END 2360 vim9script 2361 def Func() 2362 g:result = 'none' 2363 silent! g:result += 3 2364 g:result = 'none' 2365 g:result += 3 2366 enddef 2367 Func() 2368 END 2369 # can't use CheckScriptFailure, it ignores the :silent! 2370 var fname = 'Xdefsilent' 2371 writefile(lines, fname) 2372 var caught = 'no' 2373 try 2374 exe 'source ' .. fname 2375 catch /E1030:/ 2376 caught = 'yes' 2377 assert_match('Func, line 4', v:throwpoint) 2378 endtry 2379 assert_equal('yes', caught) 2380 delete(fname) 2381enddef 2382 2383def Test_cmdmod_silent_nested() 2384 var lines =<< trim END 2385 vim9script 2386 var result = '' 2387 2388 def Error() 2389 result ..= 'Eb' 2390 eval [][0] 2391 result ..= 'Ea' 2392 enddef 2393 2394 def Crash() 2395 result ..= 'Cb' 2396 sil! Error() 2397 result ..= 'Ca' 2398 enddef 2399 2400 Crash() 2401 assert_equal('CbEbEaCa', result) 2402 END 2403 CheckScriptSuccess(lines) 2404enddef 2405 2406def Test_dict_member_with_silent() 2407 var lines =<< trim END 2408 vim9script 2409 g:result = 'none' 2410 var d: dict<any> 2411 def Func() 2412 try 2413 g:result = map([], (_, v) => ({}[v]))->join() .. d[''] 2414 catch 2415 endtry 2416 enddef 2417 silent! Func() 2418 assert_equal('0', g:result) 2419 unlet g:result 2420 END 2421 CheckScriptSuccess(lines) 2422enddef 2423 2424def Test_skip_cmds_with_silent() 2425 var lines =<< trim END 2426 vim9script 2427 2428 def Func(b: bool) 2429 Crash() 2430 enddef 2431 2432 def Crash() 2433 sil! :/not found/d _ 2434 sil! :/not found/put _ 2435 enddef 2436 2437 Func(true) 2438 END 2439 CheckScriptSuccess(lines) 2440enddef 2441 2442def Test_opfunc() 2443 nnoremap <F3> <cmd>set opfunc=Opfunc<cr>g@ 2444 def g:Opfunc(_: any): string 2445 setline(1, 'ASDF') 2446 return '' 2447 enddef 2448 new 2449 setline(1, 'asdf') 2450 feedkeys("\<F3>$", 'x') 2451 assert_equal('ASDF', getline(1)) 2452 2453 bwipe! 2454 nunmap <F3> 2455enddef 2456 2457" this was crashing on exit 2458def Test_nested_lambda_in_closure() 2459 var lines =<< trim END 2460 vim9script 2461 def Outer() 2462 def g:Inner() 2463 echo map([1, 2, 3], {_, v -> v + 1}) 2464 enddef 2465 g:Inner() 2466 enddef 2467 defcompile 2468 writefile(['Done'], 'XnestedDone') 2469 quit 2470 END 2471 if !RunVim([], lines, '--clean') 2472 return 2473 endif 2474 assert_equal(['Done'], readfile('XnestedDone')) 2475 delete('XnestedDone') 2476enddef 2477 2478def Test_check_func_arg_types() 2479 var lines =<< trim END 2480 vim9script 2481 def F1(x: string): string 2482 return x 2483 enddef 2484 2485 def F2(x: number): number 2486 return x + 1 2487 enddef 2488 2489 def G(g: func): dict<func> 2490 return {f: g} 2491 enddef 2492 2493 def H(d: dict<func>): string 2494 return d.f('a') 2495 enddef 2496 END 2497 2498 CheckScriptSuccess(lines + ['echo H(G(F1))']) 2499 CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:') 2500enddef 2501 2502 2503 2504" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 2505