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 16def ReturnString(): string 17 return 'string' 18enddef 19 20def ReturnNumber(): number 21 return 123 22enddef 23 24let g:notNumber = 'string' 25 26def ReturnGlobal(): number 27 return g:notNumber 28enddef 29 30def Test_return_something() 31 ReturnString()->assert_equal('string') 32 ReturnNumber()->assert_equal(123) 33 assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal') 34enddef 35 36def Test_missing_return() 37 CheckDefFailure(['def Missing(): number', 38 ' if g:cond', 39 ' echo "no return"', 40 ' else', 41 ' return 0', 42 ' endif' 43 'enddef'], 'E1027:') 44 CheckDefFailure(['def Missing(): number', 45 ' if g:cond', 46 ' return 1', 47 ' else', 48 ' echo "no return"', 49 ' endif' 50 'enddef'], 'E1027:') 51 CheckDefFailure(['def Missing(): number', 52 ' if g:cond', 53 ' return 1', 54 ' else', 55 ' return 2', 56 ' endif' 57 ' return 3' 58 'enddef'], 'E1095:') 59enddef 60 61let s:nothing = 0 62def ReturnNothing() 63 s:nothing = 1 64 if true 65 return 66 endif 67 s:nothing = 2 68enddef 69 70def Test_return_nothing() 71 ReturnNothing() 72 s:nothing->assert_equal(1) 73enddef 74 75func Increment() 76 let g:counter += 1 77endfunc 78 79def Test_call_ufunc_count() 80 g:counter = 1 81 Increment() 82 Increment() 83 Increment() 84 # works with and without :call 85 g:counter->assert_equal(4) 86 eval g:counter->assert_equal(4) 87 unlet g:counter 88enddef 89 90def MyVarargs(arg: string, ...rest: list<string>): string 91 let res = arg 92 for s in rest 93 res ..= ',' .. s 94 endfor 95 return res 96enddef 97 98def Test_call_varargs() 99 MyVarargs('one')->assert_equal('one') 100 MyVarargs('one', 'two')->assert_equal('one,two') 101 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three') 102enddef 103 104def MyDefaultArgs(name = 'string'): string 105 return name 106enddef 107 108def MyDefaultSecond(name: string, second: bool = true): string 109 return second ? name : 'none' 110enddef 111 112def Test_call_default_args() 113 MyDefaultArgs()->assert_equal('string') 114 MyDefaultArgs('one')->assert_equal('one') 115 assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args') 116 117 MyDefaultSecond('test')->assert_equal('test') 118 MyDefaultSecond('test', true)->assert_equal('test') 119 MyDefaultSecond('test', false)->assert_equal('none') 120 121 CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:') 122 CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string') 123enddef 124 125def Test_nested_function() 126 def Nested(arg: string): string 127 return 'nested ' .. arg 128 enddef 129 Nested('function')->assert_equal('nested function') 130 131 CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:') 132 CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:') 133 134 CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:') 135 CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:') 136 CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:') 137 138 CheckDefFailure([ 139 'def Outer()', 140 ' def Inner()', 141 ' # comment', 142 ' enddef', 143 ' def Inner()', 144 ' enddef', 145 'enddef'], 'E1073:') 146 CheckDefFailure([ 147 'def Outer()', 148 ' def Inner()', 149 ' # comment', 150 ' enddef', 151 ' def! Inner()', 152 ' enddef', 153 'enddef'], 'E1117:') 154enddef 155 156func Test_call_default_args_from_func() 157 call MyDefaultArgs()->assert_equal('string') 158 call MyDefaultArgs('one')->assert_equal('one') 159 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func') 160endfunc 161 162def Test_nested_global_function() 163 let lines =<< trim END 164 vim9script 165 def Outer() 166 def g:Inner(): string 167 return 'inner' 168 enddef 169 enddef 170 defcompile 171 Outer() 172 g:Inner()->assert_equal('inner') 173 delfunc g:Inner 174 Outer() 175 g:Inner()->assert_equal('inner') 176 delfunc g:Inner 177 Outer() 178 g:Inner()->assert_equal('inner') 179 delfunc g:Inner 180 END 181 CheckScriptSuccess(lines) 182 183 lines =<< trim END 184 vim9script 185 def Outer() 186 def g:Inner(): string 187 return 'inner' 188 enddef 189 enddef 190 defcompile 191 Outer() 192 Outer() 193 END 194 CheckScriptFailure(lines, "E122:") 195 196 lines =<< trim END 197 vim9script 198 def Func() 199 echo 'script' 200 enddef 201 def Outer() 202 def Func() 203 echo 'inner' 204 enddef 205 enddef 206 defcompile 207 END 208 CheckScriptFailure(lines, "E1073:") 209enddef 210 211def Test_global_local_function() 212 let lines =<< trim END 213 vim9script 214 def g:Func(): string 215 return 'global' 216 enddef 217 def Func(): string 218 return 'local' 219 enddef 220 g:Func()->assert_equal('global') 221 Func()->assert_equal('local') 222 END 223 CheckScriptSuccess(lines) 224 225 lines =<< trim END 226 vim9script 227 def g:Funcy() 228 echo 'funcy' 229 enddef 230 s:Funcy() 231 END 232 CheckScriptFailure(lines, 'E117:') 233enddef 234 235def Test_local_function_shadows_global() 236 let lines =<< trim END 237 vim9script 238 def g:Gfunc(): string 239 return 'global' 240 enddef 241 def AnotherFunc(): number 242 let Gfunc = function('len') 243 return Gfunc('testing') 244 enddef 245 g:Gfunc()->assert_equal('global') 246 AnotherFunc()->assert_equal(7) 247 delfunc g:Gfunc 248 END 249 CheckScriptSuccess(lines) 250 251 lines =<< trim END 252 vim9script 253 def g:Func(): string 254 return 'global' 255 enddef 256 def AnotherFunc() 257 g:Func = function('len') 258 enddef 259 AnotherFunc() 260 END 261 CheckScriptFailure(lines, 'E705:') 262 delfunc g:Func 263enddef 264 265func TakesOneArg(arg) 266 echo a:arg 267endfunc 268 269def Test_call_wrong_args() 270 CheckDefFailure(['TakesOneArg()'], 'E119:') 271 CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:') 272 CheckDefFailure(['bufnr(xxx)'], 'E1001:') 273 CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:') 274 275 let lines =<< trim END 276 vim9script 277 def Func(s: string) 278 echo s 279 enddef 280 Func([]) 281 END 282 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5) 283 284 lines =<< trim END 285 vim9script 286 def FuncOne(nr: number) 287 echo nr 288 enddef 289 def FuncTwo() 290 FuncOne() 291 enddef 292 defcompile 293 END 294 writefile(lines, 'Xscript') 295 let didCatch = false 296 try 297 source Xscript 298 catch 299 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception) 300 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint) 301 didCatch = true 302 endtry 303 assert_true(didCatch) 304 305 lines =<< trim END 306 vim9script 307 def FuncOne(nr: number) 308 echo nr 309 enddef 310 def FuncTwo() 311 FuncOne(1, 2) 312 enddef 313 defcompile 314 END 315 writefile(lines, 'Xscript') 316 didCatch = false 317 try 318 source Xscript 319 catch 320 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception) 321 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint) 322 didCatch = true 323 endtry 324 assert_true(didCatch) 325 326 delete('Xscript') 327enddef 328 329" Default arg and varargs 330def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string 331 let res = one .. ',' .. two 332 for s in rest 333 res ..= ',' .. s 334 endfor 335 return res 336enddef 337 338def Test_call_def_varargs() 339 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs') 340 MyDefVarargs('one')->assert_equal('one,foo') 341 MyDefVarargs('one', 'two')->assert_equal('one,two') 342 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three') 343 CheckDefFailure(['MyDefVarargs("one", 22)'], 344 'E1013: Argument 2: type mismatch, expected string but got number') 345 CheckDefFailure(['MyDefVarargs("one", "two", 123)'], 346 'E1013: Argument 3: type mismatch, expected string but got number') 347 348 let lines =<< trim END 349 vim9script 350 def Func(...l: list<string>) 351 echo l 352 enddef 353 Func('a', 'b', 'c') 354 END 355 CheckScriptSuccess(lines) 356 357 lines =<< trim END 358 vim9script 359 def Func(...l: list<string>) 360 echo l 361 enddef 362 Func() 363 END 364 CheckScriptSuccess(lines) 365 366 lines =<< trim END 367 vim9script 368 def Func(...l: any) 369 echo l 370 enddef 371 Func(0) 372 END 373 CheckScriptSuccess(lines) 374 375 lines =<< trim END 376 vim9script 377 def Func(..._l: list<string>) 378 echo _l 379 enddef 380 Func('a', 'b', 'c') 381 END 382 CheckScriptSuccess(lines) 383 384 lines =<< trim END 385 vim9script 386 def Func(...l: list<string>) 387 echo l 388 enddef 389 Func(1, 2, 3) 390 END 391 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch') 392 393 lines =<< trim END 394 vim9script 395 def Func(...l: list<string>) 396 echo l 397 enddef 398 Func('a', 9) 399 END 400 CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch') 401 402 lines =<< trim END 403 vim9script 404 def Func(...l: list<string>) 405 echo l 406 enddef 407 Func(1, 'a') 408 END 409 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch') 410enddef 411 412def Test_call_call() 413 let l = [3, 2, 1] 414 call('reverse', [l]) 415 l->assert_equal([1, 2, 3]) 416enddef 417 418let s:value = '' 419 420def FuncOneDefArg(opt = 'text') 421 s:value = opt 422enddef 423 424def FuncTwoDefArg(nr = 123, opt = 'text'): string 425 return nr .. opt 426enddef 427 428def FuncVarargs(...arg: list<string>): string 429 return join(arg, ',') 430enddef 431 432def Test_func_type_varargs() 433 let RefDefArg: func(?string) 434 RefDefArg = FuncOneDefArg 435 RefDefArg() 436 s:value->assert_equal('text') 437 RefDefArg('some') 438 s:value->assert_equal('some') 439 440 let RefDef2Arg: func(?number, ?string): string 441 RefDef2Arg = FuncTwoDefArg 442 RefDef2Arg()->assert_equal('123text') 443 RefDef2Arg(99)->assert_equal('99text') 444 RefDef2Arg(77, 'some')->assert_equal('77some') 445 446 CheckDefFailure(['let RefWrong: func(string?)'], 'E1010:') 447 CheckDefFailure(['let RefWrong: func(?string, string)'], 'E1007:') 448 449 let RefVarargs: func(...list<string>): string 450 RefVarargs = FuncVarargs 451 RefVarargs()->assert_equal('') 452 RefVarargs('one')->assert_equal('one') 453 RefVarargs('one', 'two')->assert_equal('one,two') 454 455 CheckDefFailure(['let RefWrong: func(...list<string>, string)'], 'E110:') 456 CheckDefFailure(['let RefWrong: func(...list<string>, ?string)'], 'E110:') 457enddef 458 459" Only varargs 460def MyVarargsOnly(...args: list<string>): string 461 return join(args, ',') 462enddef 463 464def Test_call_varargs_only() 465 MyVarargsOnly()->assert_equal('') 466 MyVarargsOnly('one')->assert_equal('one') 467 MyVarargsOnly('one', 'two')->assert_equal('one,two') 468 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number') 469 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number') 470enddef 471 472def Test_using_var_as_arg() 473 writefile(['def Func(x: number)', 'let x = 234', 'enddef', 'defcompile'], 'Xdef') 474 assert_fails('so Xdef', 'E1006:', '', 1, 'Func') 475 delete('Xdef') 476enddef 477 478def DictArg(arg: dict<string>) 479 arg['key'] = 'value' 480enddef 481 482def ListArg(arg: list<string>) 483 arg[0] = 'value' 484enddef 485 486def Test_assign_to_argument() 487 # works for dict and list 488 let d: dict<string> = {} 489 DictArg(d) 490 d['key']->assert_equal('value') 491 let l: list<string> = [] 492 ListArg(l) 493 l[0]->assert_equal('value') 494 495 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:') 496enddef 497 498" These argument names are reserved in legacy functions. 499def WithReservedNames(firstline: string, lastline: string): string 500 return firstline .. lastline 501enddef 502 503def Test_argument_names() 504 assert_equal('OK', WithReservedNames('O', 'K')) 505enddef 506 507def Test_call_func_defined_later() 508 g:DefinedLater('one')->assert_equal('one') 509 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later') 510enddef 511 512func DefinedLater(arg) 513 return a:arg 514endfunc 515 516def Test_call_funcref() 517 g:SomeFunc('abc')->assert_equal(3) 518 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call 519 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref') 520 521 let lines =<< trim END 522 vim9script 523 def RetNumber(): number 524 return 123 525 enddef 526 let Funcref: func: number = function('RetNumber') 527 Funcref()->assert_equal(123) 528 END 529 CheckScriptSuccess(lines) 530 531 lines =<< trim END 532 vim9script 533 def RetNumber(): number 534 return 123 535 enddef 536 def Bar(F: func: number): number 537 return F() 538 enddef 539 let Funcref = function('RetNumber') 540 Bar(Funcref)->assert_equal(123) 541 END 542 CheckScriptSuccess(lines) 543 544 lines =<< trim END 545 vim9script 546 def UseNumber(nr: number) 547 echo nr 548 enddef 549 let Funcref: func(number) = function('UseNumber') 550 Funcref(123) 551 END 552 CheckScriptSuccess(lines) 553 554 lines =<< trim END 555 vim9script 556 def UseNumber(nr: number) 557 echo nr 558 enddef 559 let Funcref: func(string) = function('UseNumber') 560 END 561 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)') 562 563 lines =<< trim END 564 vim9script 565 def EchoNr(nr = 34) 566 g:echo = nr 567 enddef 568 let Funcref: func(?number) = function('EchoNr') 569 Funcref() 570 g:echo->assert_equal(34) 571 Funcref(123) 572 g:echo->assert_equal(123) 573 END 574 CheckScriptSuccess(lines) 575 576 lines =<< trim END 577 vim9script 578 def EchoList(...l: list<number>) 579 g:echo = l 580 enddef 581 let Funcref: func(...list<number>) = function('EchoList') 582 Funcref() 583 g:echo->assert_equal([]) 584 Funcref(1, 2, 3) 585 g:echo->assert_equal([1, 2, 3]) 586 END 587 CheckScriptSuccess(lines) 588 589 lines =<< trim END 590 vim9script 591 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number 592 g:optarg = opt 593 g:listarg = l 594 return nr 595 enddef 596 let Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar') 597 Funcref(10)->assert_equal(10) 598 g:optarg->assert_equal(12) 599 g:listarg->assert_equal([]) 600 601 Funcref(11, 22)->assert_equal(11) 602 g:optarg->assert_equal(22) 603 g:listarg->assert_equal([]) 604 605 Funcref(17, 18, 1, 2, 3)->assert_equal(17) 606 g:optarg->assert_equal(18) 607 g:listarg->assert_equal([1, 2, 3]) 608 END 609 CheckScriptSuccess(lines) 610enddef 611 612let SomeFunc = function('len') 613let NotAFunc = 'text' 614 615def CombineFuncrefTypes() 616 # same arguments, different return type 617 let Ref1: func(bool): string 618 let Ref2: func(bool): number 619 let Ref3: func(bool): any 620 Ref3 = g:cond ? Ref1 : Ref2 621 622 # different number of arguments 623 let Refa1: func(bool): number 624 let Refa2: func(bool, number): number 625 let Refa3: func: number 626 Refa3 = g:cond ? Refa1 : Refa2 627 628 # different argument types 629 let Refb1: func(bool, string): number 630 let Refb2: func(string, number): number 631 let Refb3: func(any, any): number 632 Refb3 = g:cond ? Refb1 : Refb2 633enddef 634 635def FuncWithForwardCall() 636 return g:DefinedEvenLater("yes") 637enddef 638 639def DefinedEvenLater(arg: string): string 640 return arg 641enddef 642 643def Test_error_in_nested_function() 644 # Error in called function requires unwinding the call stack. 645 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall') 646enddef 647 648def Test_return_type_wrong() 649 CheckScriptFailure([ 650 'def Func(): number', 651 'return "a"', 652 'enddef', 653 'defcompile'], 'expected number but got string') 654 CheckScriptFailure([ 655 'def Func(): string', 656 'return 1', 657 'enddef', 658 'defcompile'], 'expected string but got number') 659 CheckScriptFailure([ 660 'def Func(): void', 661 'return "a"', 662 'enddef', 663 'defcompile'], 664 'E1096: Returning a value in a function without a return type') 665 CheckScriptFailure([ 666 'def Func()', 667 'return "a"', 668 'enddef', 669 'defcompile'], 670 'E1096: Returning a value in a function without a return type') 671 672 CheckScriptFailure([ 673 'def Func(): number', 674 'return', 675 'enddef', 676 'defcompile'], 'E1003:') 677 678 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:') 679 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:') 680 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:') 681 682 CheckScriptFailure([ 683 'vim9script', 684 'def FuncB()', 685 ' return 123', 686 'enddef', 687 'def FuncA()', 688 ' FuncB()', 689 'enddef', 690 'defcompile'], 'E1096:') 691enddef 692 693def Test_arg_type_wrong() 694 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>') 695 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...') 696 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:') 697 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:') 698enddef 699 700def Test_vim9script_call() 701 let lines =<< trim END 702 vim9script 703 let var = '' 704 def MyFunc(arg: string) 705 var = arg 706 enddef 707 MyFunc('foobar') 708 var->assert_equal('foobar') 709 710 let str = 'barfoo' 711 str->MyFunc() 712 var->assert_equal('barfoo') 713 714 g:value = 'value' 715 g:value->MyFunc() 716 var->assert_equal('value') 717 718 let listvar = [] 719 def ListFunc(arg: list<number>) 720 listvar = arg 721 enddef 722 [1, 2, 3]->ListFunc() 723 listvar->assert_equal([1, 2, 3]) 724 725 let dictvar = {} 726 def DictFunc(arg: dict<number>) 727 dictvar = arg 728 enddef 729 {'a': 1, 'b': 2}->DictFunc() 730 dictvar->assert_equal(#{a: 1, b: 2}) 731 def CompiledDict() 732 {'a': 3, 'b': 4}->DictFunc() 733 enddef 734 CompiledDict() 735 dictvar->assert_equal(#{a: 3, b: 4}) 736 737 #{a: 3, b: 4}->DictFunc() 738 dictvar->assert_equal(#{a: 3, b: 4}) 739 740 ('text')->MyFunc() 741 var->assert_equal('text') 742 ("some")->MyFunc() 743 var->assert_equal('some') 744 745 # line starting with single quote is not a mark 746 # line starting with double quote can be a method call 747 'asdfasdf'->MyFunc() 748 var->assert_equal('asdfasdf') 749 "xyz"->MyFunc() 750 var->assert_equal('xyz') 751 752 def UseString() 753 'xyork'->MyFunc() 754 enddef 755 UseString() 756 var->assert_equal('xyork') 757 758 def UseString2() 759 "knife"->MyFunc() 760 enddef 761 UseString2() 762 var->assert_equal('knife') 763 764 # prepending a colon makes it a mark 765 new 766 setline(1, ['aaa', 'bbb', 'ccc']) 767 normal! 3Gmt1G 768 :'t 769 getcurpos()[1]->assert_equal(3) 770 bwipe! 771 772 MyFunc( 773 'continued' 774 ) 775 assert_equal('continued', 776 var 777 ) 778 779 call MyFunc( 780 'more' 781 .. 782 'lines' 783 ) 784 assert_equal( 785 'morelines', 786 var) 787 END 788 writefile(lines, 'Xcall.vim') 789 source Xcall.vim 790 delete('Xcall.vim') 791enddef 792 793def Test_vim9script_call_fail_decl() 794 let lines =<< trim END 795 vim9script 796 let var = '' 797 def MyFunc(arg: string) 798 let var = 123 799 enddef 800 defcompile 801 END 802 CheckScriptFailure(lines, 'E1054:') 803enddef 804 805def Test_vim9script_call_fail_type() 806 let lines =<< trim END 807 vim9script 808 def MyFunc(arg: string) 809 echo arg 810 enddef 811 MyFunc(1234) 812 END 813 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number') 814enddef 815 816def Test_vim9script_call_fail_const() 817 let lines =<< trim END 818 vim9script 819 const var = '' 820 def MyFunc(arg: string) 821 var = 'asdf' 822 enddef 823 defcompile 824 END 825 writefile(lines, 'Xcall_const.vim') 826 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc') 827 delete('Xcall_const.vim') 828enddef 829 830" Test that inside :function a Python function can be defined, :def is not 831" recognized. 832func Test_function_python() 833 CheckFeature python3 834 let py = 'python3' 835 execute py "<< EOF" 836def do_something(): 837 return 1 838EOF 839endfunc 840 841def Test_delfunc() 842 let lines =<< trim END 843 vim9script 844 def g:GoneSoon() 845 echo 'hello' 846 enddef 847 848 def CallGoneSoon() 849 GoneSoon() 850 enddef 851 defcompile 852 853 delfunc g:GoneSoon 854 CallGoneSoon() 855 END 856 writefile(lines, 'XToDelFunc') 857 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon') 858 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon') 859 860 delete('XToDelFunc') 861enddef 862 863def Test_redef_failure() 864 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef') 865 so Xdef 866 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef') 867 so Xdef 868 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef') 869 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0') 870 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef') 871 so Xdef 872 delete('Xdef') 873 874 g:Func0()->assert_equal(0) 875 g:Func1()->assert_equal('Func1') 876 g:Func2()->assert_equal('Func2') 877 878 delfunc! Func0 879 delfunc! Func1 880 delfunc! Func2 881enddef 882 883def Test_vim9script_func() 884 let lines =<< trim END 885 vim9script 886 func Func(arg) 887 echo a:arg 888 endfunc 889 Func('text') 890 END 891 writefile(lines, 'XVim9Func') 892 so XVim9Func 893 894 delete('XVim9Func') 895enddef 896 897" Test for internal functions returning different types 898func Test_InternalFuncRetType() 899 let lines =<< trim END 900 def RetFloat(): float 901 return ceil(1.456) 902 enddef 903 904 def RetListAny(): list<any> 905 return items({'k': 'v'}) 906 enddef 907 908 def RetListString(): list<string> 909 return split('a:b:c', ':') 910 enddef 911 912 def RetListDictAny(): list<dict<any>> 913 return getbufinfo() 914 enddef 915 916 def RetDictNumber(): dict<number> 917 return wordcount() 918 enddef 919 920 def RetDictString(): dict<string> 921 return environ() 922 enddef 923 END 924 call writefile(lines, 'Xscript') 925 source Xscript 926 927 call RetFloat()->assert_equal(2.0) 928 call RetListAny()->assert_equal([['k', 'v']]) 929 call RetListString()->assert_equal(['a', 'b', 'c']) 930 call RetListDictAny()->assert_notequal([]) 931 call RetDictNumber()->assert_notequal({}) 932 call RetDictString()->assert_notequal({}) 933 call delete('Xscript') 934endfunc 935 936" Test for passing too many or too few arguments to internal functions 937func Test_internalfunc_arg_error() 938 let l =<< trim END 939 def! FArgErr(): float 940 return ceil(1.1, 2) 941 enddef 942 defcompile 943 END 944 call writefile(l, 'Xinvalidarg') 945 call assert_fails('so Xinvalidarg', 'E118:', '', 1, 'FArgErr') 946 let l =<< trim END 947 def! FArgErr(): float 948 return ceil() 949 enddef 950 defcompile 951 END 952 call writefile(l, 'Xinvalidarg') 953 call assert_fails('so Xinvalidarg', 'E119:', '', 1, 'FArgErr') 954 call delete('Xinvalidarg') 955endfunc 956 957let s:funcResult = 0 958 959def FuncNoArgNoRet() 960 s:funcResult = 11 961enddef 962 963def FuncNoArgRetNumber(): number 964 s:funcResult = 22 965 return 1234 966enddef 967 968def FuncNoArgRetString(): string 969 s:funcResult = 45 970 return 'text' 971enddef 972 973def FuncOneArgNoRet(arg: number) 974 s:funcResult = arg 975enddef 976 977def FuncOneArgRetNumber(arg: number): number 978 s:funcResult = arg 979 return arg 980enddef 981 982def FuncTwoArgNoRet(one: bool, two: number) 983 s:funcResult = two 984enddef 985 986def FuncOneArgRetString(arg: string): string 987 return arg 988enddef 989 990def FuncOneArgRetAny(arg: any): any 991 return arg 992enddef 993 994def Test_func_type() 995 let Ref1: func() 996 s:funcResult = 0 997 Ref1 = FuncNoArgNoRet 998 Ref1() 999 s:funcResult->assert_equal(11) 1000 1001 let Ref2: func 1002 s:funcResult = 0 1003 Ref2 = FuncNoArgNoRet 1004 Ref2() 1005 s:funcResult->assert_equal(11) 1006 1007 s:funcResult = 0 1008 Ref2 = FuncOneArgNoRet 1009 Ref2(12) 1010 s:funcResult->assert_equal(12) 1011 1012 s:funcResult = 0 1013 Ref2 = FuncNoArgRetNumber 1014 Ref2()->assert_equal(1234) 1015 s:funcResult->assert_equal(22) 1016 1017 s:funcResult = 0 1018 Ref2 = FuncOneArgRetNumber 1019 Ref2(13)->assert_equal(13) 1020 s:funcResult->assert_equal(13) 1021enddef 1022 1023def Test_repeat_return_type() 1024 let res = 0 1025 for n in repeat([1], 3) 1026 res += n 1027 endfor 1028 res->assert_equal(3) 1029 1030 res = 0 1031 for n in add([1, 2], 3) 1032 res += n 1033 endfor 1034 res->assert_equal(6) 1035enddef 1036 1037def Test_argv_return_type() 1038 next fileone filetwo 1039 let res = '' 1040 for name in argv() 1041 res ..= name 1042 endfor 1043 res->assert_equal('fileonefiletwo') 1044enddef 1045 1046def Test_func_type_part() 1047 let RefVoid: func: void 1048 RefVoid = FuncNoArgNoRet 1049 RefVoid = FuncOneArgNoRet 1050 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number') 1051 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string') 1052 1053 let RefAny: func(): any 1054 RefAny = FuncNoArgRetNumber 1055 RefAny = FuncNoArgRetString 1056 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()') 1057 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)') 1058 1059 let RefNr: func: number 1060 RefNr = FuncNoArgRetNumber 1061 RefNr = FuncOneArgRetNumber 1062 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()') 1063 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string') 1064 1065 let RefStr: func: string 1066 RefStr = FuncNoArgRetString 1067 RefStr = FuncOneArgRetString 1068 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()') 1069 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number') 1070enddef 1071 1072def Test_func_type_fails() 1073 CheckDefFailure(['let ref1: func()'], 'E704:') 1074 1075 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number') 1076 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)') 1077 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number') 1078 CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)') 1079 CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)') 1080 CheckDefFailure(['let Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(...bool) but got func(bool, number)') 1081 1082 CheckDefFailure(['let RefWrong: func(string ,number)'], 'E1068:') 1083 CheckDefFailure(['let RefWrong: func(string,number)'], 'E1069:') 1084 CheckDefFailure(['let RefWrong: func(bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool)'], 'E1005:') 1085 CheckDefFailure(['let RefWrong: func(bool):string'], 'E1069:') 1086enddef 1087 1088def Test_func_return_type() 1089 let nr: number 1090 nr = FuncNoArgRetNumber() 1091 nr->assert_equal(1234) 1092 1093 nr = FuncOneArgRetAny(122) 1094 nr->assert_equal(122) 1095 1096 let str: string 1097 str = FuncOneArgRetAny('yes') 1098 str->assert_equal('yes') 1099 1100 CheckDefFailure(['let str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number') 1101enddef 1102 1103def MultiLine( 1104 arg1: string, 1105 arg2 = 1234, 1106 ...rest: list<string> 1107 ): string 1108 return arg1 .. arg2 .. join(rest, '-') 1109enddef 1110 1111def MultiLineComment( 1112 arg1: string, # comment 1113 arg2 = 1234, # comment 1114 ...rest: list<string> # comment 1115 ): string # comment 1116 return arg1 .. arg2 .. join(rest, '-') 1117enddef 1118 1119def Test_multiline() 1120 MultiLine('text')->assert_equal('text1234') 1121 MultiLine('text', 777)->assert_equal('text777') 1122 MultiLine('text', 777, 'one')->assert_equal('text777one') 1123 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two') 1124enddef 1125 1126func Test_multiline_not_vim9() 1127 call MultiLine('text')->assert_equal('text1234') 1128 call MultiLine('text', 777)->assert_equal('text777') 1129 call MultiLine('text', 777, 'one')->assert_equal('text777one') 1130 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two') 1131endfunc 1132 1133 1134" When using CheckScriptFailure() for the below test, E1010 is generated instead 1135" of E1056. 1136func Test_E1056_1059() 1137 let caught_1056 = 0 1138 try 1139 def F(): 1140 return 1 1141 enddef 1142 catch /E1056:/ 1143 let caught_1056 = 1 1144 endtry 1145 eval caught_1056->assert_equal(1) 1146 1147 let caught_1059 = 0 1148 try 1149 def F5(items : list) 1150 echo 'a' 1151 enddef 1152 catch /E1059:/ 1153 let caught_1059 = 1 1154 endtry 1155 eval caught_1059->assert_equal(1) 1156endfunc 1157 1158func DelMe() 1159 echo 'DelMe' 1160endfunc 1161 1162def Test_error_reporting() 1163 # comment lines at the start of the function 1164 let lines =<< trim END 1165 " comment 1166 def Func() 1167 # comment 1168 # comment 1169 invalid 1170 enddef 1171 defcompile 1172 END 1173 writefile(lines, 'Xdef') 1174 try 1175 source Xdef 1176 assert_report('should have failed') 1177 catch /E476:/ 1178 v:exception->assert_match('Invalid command: invalid') 1179 v:throwpoint->assert_match(', line 3$') 1180 endtry 1181 1182 # comment lines after the start of the function 1183 lines =<< trim END 1184 " comment 1185 def Func() 1186 let x = 1234 1187 # comment 1188 # comment 1189 invalid 1190 enddef 1191 defcompile 1192 END 1193 writefile(lines, 'Xdef') 1194 try 1195 source Xdef 1196 assert_report('should have failed') 1197 catch /E476:/ 1198 v:exception->assert_match('Invalid command: invalid') 1199 v:throwpoint->assert_match(', line 4$') 1200 endtry 1201 1202 lines =<< trim END 1203 vim9script 1204 def Func() 1205 let db = #{foo: 1, bar: 2} 1206 # comment 1207 let x = db.asdf 1208 enddef 1209 defcompile 1210 Func() 1211 END 1212 writefile(lines, 'Xdef') 1213 try 1214 source Xdef 1215 assert_report('should have failed') 1216 catch /E716:/ 1217 v:throwpoint->assert_match('_Func, line 3$') 1218 endtry 1219 1220 delete('Xdef') 1221enddef 1222 1223def Test_deleted_function() 1224 CheckDefExecFailure([ 1225 'let RefMe: func = function("g:DelMe")', 1226 'delfunc g:DelMe', 1227 'echo RefMe()'], 'E117:') 1228enddef 1229 1230def Test_unknown_function() 1231 CheckDefExecFailure([ 1232 'let Ref: func = function("NotExist")', 1233 'delfunc g:NotExist'], 'E700:') 1234enddef 1235 1236def RefFunc(Ref: func(string): string): string 1237 return Ref('more') 1238enddef 1239 1240def Test_closure_simple() 1241 let local = 'some ' 1242 RefFunc({s -> local .. s})->assert_equal('some more') 1243enddef 1244 1245def MakeRef() 1246 let local = 'some ' 1247 g:Ref = {s -> local .. s} 1248enddef 1249 1250def Test_closure_ref_after_return() 1251 MakeRef() 1252 g:Ref('thing')->assert_equal('some thing') 1253 unlet g:Ref 1254enddef 1255 1256def MakeTwoRefs() 1257 let local = ['some'] 1258 g:Extend = {s -> local->add(s)} 1259 g:Read = {-> local} 1260enddef 1261 1262def Test_closure_two_refs() 1263 MakeTwoRefs() 1264 join(g:Read(), ' ')->assert_equal('some') 1265 g:Extend('more') 1266 join(g:Read(), ' ')->assert_equal('some more') 1267 g:Extend('even') 1268 join(g:Read(), ' ')->assert_equal('some more even') 1269 1270 unlet g:Extend 1271 unlet g:Read 1272enddef 1273 1274def ReadRef(Ref: func(): list<string>): string 1275 return join(Ref(), ' ') 1276enddef 1277 1278def ExtendRef(Ref: func(string): list<string>, add: string) 1279 Ref(add) 1280enddef 1281 1282def Test_closure_two_indirect_refs() 1283 MakeTwoRefs() 1284 ReadRef(g:Read)->assert_equal('some') 1285 ExtendRef(g:Extend, 'more') 1286 ReadRef(g:Read)->assert_equal('some more') 1287 ExtendRef(g:Extend, 'even') 1288 ReadRef(g:Read)->assert_equal('some more even') 1289 1290 unlet g:Extend 1291 unlet g:Read 1292enddef 1293 1294def MakeArgRefs(theArg: string) 1295 let local = 'loc_val' 1296 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s} 1297enddef 1298 1299def MakeArgRefsVarargs(theArg: string, ...rest: list<string>) 1300 let local = 'the_loc' 1301 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)} 1302enddef 1303 1304def Test_closure_using_argument() 1305 MakeArgRefs('arg_val') 1306 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val') 1307 1308 MakeArgRefsVarargs('arg_val', 'one', 'two') 1309 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two') 1310 1311 unlet g:UseArg 1312 unlet g:UseVararg 1313enddef 1314 1315def MakeGetAndAppendRefs() 1316 let local = 'a' 1317 1318 def Append(arg: string) 1319 local ..= arg 1320 enddef 1321 g:Append = Append 1322 1323 def Get(): string 1324 return local 1325 enddef 1326 g:Get = Get 1327enddef 1328 1329def Test_closure_append_get() 1330 MakeGetAndAppendRefs() 1331 g:Get()->assert_equal('a') 1332 g:Append('-b') 1333 g:Get()->assert_equal('a-b') 1334 g:Append('-c') 1335 g:Get()->assert_equal('a-b-c') 1336 1337 unlet g:Append 1338 unlet g:Get 1339enddef 1340 1341def Test_nested_closure() 1342 let local = 'text' 1343 def Closure(arg: string): string 1344 return local .. arg 1345 enddef 1346 Closure('!!!')->assert_equal('text!!!') 1347enddef 1348 1349func GetResult(Ref) 1350 return a:Ref('some') 1351endfunc 1352 1353def Test_call_closure_not_compiled() 1354 let text = 'text' 1355 g:Ref = {s -> s .. text} 1356 GetResult(g:Ref)->assert_equal('sometext') 1357enddef 1358 1359def Test_double_closure_fails() 1360 let lines =<< trim END 1361 vim9script 1362 def Func() 1363 let var = 0 1364 for i in range(2) 1365 timer_start(0, {-> var}) 1366 endfor 1367 enddef 1368 Func() 1369 END 1370 CheckScriptSuccess(lines) 1371enddef 1372 1373def Test_sort_return_type() 1374 let res: list<number> 1375 res = [1, 2, 3]->sort() 1376enddef 1377 1378def Test_sort_argument() 1379 let res = ['b', 'a', 'c']->sort('i') 1380 res->assert_equal(['a', 'b', 'c']) 1381enddef 1382 1383def Test_getqflist_return_type() 1384 let l = getqflist() 1385 l->assert_equal([]) 1386 1387 let d = getqflist(#{items: 0}) 1388 d->assert_equal(#{items: []}) 1389enddef 1390 1391def Test_getloclist_return_type() 1392 let l = getloclist(1) 1393 l->assert_equal([]) 1394 1395 let d = getloclist(1, #{items: 0}) 1396 d->assert_equal(#{items: []}) 1397enddef 1398 1399def Test_copy_return_type() 1400 let l = copy([1, 2, 3]) 1401 let res = 0 1402 for n in l 1403 res += n 1404 endfor 1405 res->assert_equal(6) 1406 1407 let dl = deepcopy([1, 2, 3]) 1408 res = 0 1409 for n in dl 1410 res += n 1411 endfor 1412 res->assert_equal(6) 1413 1414 dl = deepcopy([1, 2, 3], true) 1415enddef 1416 1417def Test_extend_return_type() 1418 let l = extend([1, 2], [3]) 1419 let res = 0 1420 for n in l 1421 res += n 1422 endfor 1423 res->assert_equal(6) 1424enddef 1425 1426def Test_garbagecollect() 1427 garbagecollect(true) 1428enddef 1429 1430def Test_insert_return_type() 1431 let l = insert([2, 1], 3) 1432 let res = 0 1433 for n in l 1434 res += n 1435 endfor 1436 res->assert_equal(6) 1437enddef 1438 1439def Test_keys_return_type() 1440 const var: list<string> = #{a: 1, b: 2}->keys() 1441 var->assert_equal(['a', 'b']) 1442enddef 1443 1444def Test_reverse_return_type() 1445 let l = reverse([1, 2, 3]) 1446 let res = 0 1447 for n in l 1448 res += n 1449 endfor 1450 res->assert_equal(6) 1451enddef 1452 1453def Test_remove_return_type() 1454 let l = remove(#{one: [1, 2], two: [3, 4]}, 'one') 1455 let res = 0 1456 for n in l 1457 res += n 1458 endfor 1459 res->assert_equal(3) 1460enddef 1461 1462def Test_filter_return_type() 1463 let l = filter([1, 2, 3], {-> 1}) 1464 let res = 0 1465 for n in l 1466 res += n 1467 endfor 1468 res->assert_equal(6) 1469enddef 1470 1471def Test_bufnr() 1472 let buf = bufnr() 1473 bufnr('%')->assert_equal(buf) 1474 1475 buf = bufnr('Xdummy', true) 1476 buf->assert_notequal(-1) 1477 exe 'bwipe! ' .. buf 1478enddef 1479 1480def Test_col() 1481 new 1482 setline(1, 'asdf') 1483 col([1, '$'])->assert_equal(5) 1484enddef 1485 1486def Test_char2nr() 1487 char2nr('あ', true)->assert_equal(12354) 1488enddef 1489 1490def Test_getreg_return_type() 1491 let s1: string = getreg('"') 1492 let s2: string = getreg('"', 1) 1493 let s3: list<string> = getreg('"', 1, 1) 1494enddef 1495 1496def Wrong_dict_key_type(items: list<number>): list<number> 1497 return filter(items, {_, val -> get({val: 1}, 'x')}) 1498enddef 1499 1500def Test_wrong_dict_key_type() 1501 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1012:') 1502enddef 1503 1504def Line_continuation_in_def(dir: string = ''): string 1505 let path: string = empty(dir) 1506 \ ? 'empty' 1507 \ : 'full' 1508 return path 1509enddef 1510 1511def Test_line_continuation_in_def() 1512 Line_continuation_in_def('.')->assert_equal('full') 1513enddef 1514 1515def Line_continuation_in_lambda(): list<string> 1516 let x = range(97, 100) 1517 ->map({_, v -> nr2char(v) 1518 ->toupper()}) 1519 ->reverse() 1520 return x 1521enddef 1522 1523def Test_line_continuation_in_lambda() 1524 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A']) 1525enddef 1526 1527func Test_silent_echo() 1528 CheckScreendump 1529 1530 let lines =<< trim END 1531 vim9script 1532 def EchoNothing() 1533 silent echo '' 1534 enddef 1535 defcompile 1536 END 1537 call writefile(lines, 'XTest_silent_echo') 1538 1539 " Check that the balloon shows up after a mouse move 1540 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6}) 1541 call term_sendkeys(buf, ":abc") 1542 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {}) 1543 1544 " clean up 1545 call StopVimInTerminal(buf) 1546 call delete('XTest_silent_echo') 1547endfunc 1548 1549""""""" builtin functions that behave differently in Vim9 1550 1551def Test_bufname() 1552 split SomeFile 1553 bufname('%')->assert_equal('SomeFile') 1554 edit OtherFile 1555 bufname('#')->assert_equal('SomeFile') 1556 close 1557enddef 1558 1559def Test_bufwinid() 1560 let origwin = win_getid() 1561 below split SomeFile 1562 let SomeFileID = win_getid() 1563 below split OtherFile 1564 below split SomeFile 1565 bufwinid('SomeFile')->assert_equal(SomeFileID) 1566 1567 win_gotoid(origwin) 1568 only 1569 bwipe SomeFile 1570 bwipe OtherFile 1571enddef 1572 1573def Test_count() 1574 count('ABC ABC ABC', 'b', true)->assert_equal(3) 1575 count('ABC ABC ABC', 'b', false)->assert_equal(0) 1576enddef 1577 1578def Test_expand() 1579 split SomeFile 1580 expand('%', true, true)->assert_equal(['SomeFile']) 1581 close 1582enddef 1583 1584def Test_getbufinfo() 1585 let bufinfo = getbufinfo(bufnr()) 1586 getbufinfo('%')->assert_equal(bufinfo) 1587 1588 edit Xtestfile1 1589 hide edit Xtestfile2 1590 hide enew 1591 getbufinfo(#{bufloaded: true, buflisted: true, bufmodified: false}) 1592 ->len()->assert_equal(3) 1593 bwipe Xtestfile1 Xtestfile2 1594enddef 1595 1596def Test_getbufline() 1597 e SomeFile 1598 let buf = bufnr() 1599 e # 1600 let lines = ['aaa', 'bbb', 'ccc'] 1601 setbufline(buf, 1, lines) 1602 getbufline('#', 1, '$')->assert_equal(lines) 1603 1604 bwipe! 1605enddef 1606 1607def Test_getchangelist() 1608 new 1609 setline(1, 'some text') 1610 let changelist = bufnr()->getchangelist() 1611 getchangelist('%')->assert_equal(changelist) 1612 bwipe! 1613enddef 1614 1615def Test_getchar() 1616 while getchar(0) 1617 endwhile 1618 getchar(true)->assert_equal(0) 1619enddef 1620 1621def Test_getcompletion() 1622 set wildignore=*.vim,*~ 1623 let l = getcompletion('run', 'file', true) 1624 l->assert_equal([]) 1625 set wildignore& 1626enddef 1627 1628def Test_getreg() 1629 let lines = ['aaa', 'bbb', 'ccc'] 1630 setreg('a', lines) 1631 getreg('a', true, true)->assert_equal(lines) 1632enddef 1633 1634def Test_glob() 1635 glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim']) 1636enddef 1637 1638def Test_globpath() 1639 globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim']) 1640enddef 1641 1642def Test_has() 1643 has('eval', true)->assert_equal(1) 1644enddef 1645 1646def Test_hasmapto() 1647 hasmapto('foobar', 'i', true)->assert_equal(0) 1648 iabbrev foo foobar 1649 hasmapto('foobar', 'i', true)->assert_equal(1) 1650 iunabbrev foo 1651enddef 1652 1653def Test_index() 1654 index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3) 1655enddef 1656 1657def Test_list2str_str2list_utf8() 1658 let s = "\u3042\u3044" 1659 let l = [0x3042, 0x3044] 1660 str2list(s, true)->assert_equal(l) 1661 list2str(l, true)->assert_equal(s) 1662enddef 1663 1664def SID(): number 1665 return expand('<SID>') 1666 ->matchstr('<SNR>\zs\d\+\ze_$') 1667 ->str2nr() 1668enddef 1669 1670def Test_maparg() 1671 let lnum = str2nr(expand('<sflnum>')) 1672 map foo bar 1673 maparg('foo', '', false, true)->assert_equal(#{ 1674 lnum: lnum + 1, 1675 script: 0, 1676 mode: ' ', 1677 silent: 0, 1678 noremap: 0, 1679 lhs: 'foo', 1680 lhsraw: 'foo', 1681 nowait: 0, 1682 expr: 0, 1683 sid: SID(), 1684 rhs: 'bar', 1685 buffer: 0}) 1686 unmap foo 1687enddef 1688 1689def Test_mapcheck() 1690 iabbrev foo foobar 1691 mapcheck('foo', 'i', true)->assert_equal('foobar') 1692 iunabbrev foo 1693enddef 1694 1695def Test_nr2char() 1696 nr2char(97, true)->assert_equal('a') 1697enddef 1698 1699def Test_readdir() 1700 eval expand('sautest')->readdir({e -> e[0] !=# '.'}) 1701 eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'}) 1702enddef 1703 1704def Test_search() 1705 new 1706 setline(1, ['foo', 'bar']) 1707 let val = 0 1708 # skip expr returns boolean 1709 search('bar', 'W', 0, 0, {-> val == 1})->assert_equal(2) 1710 :1 1711 search('bar', 'W', 0, 0, {-> val == 0})->assert_equal(0) 1712 # skip expr returns number, only 0 and 1 are accepted 1713 :1 1714 search('bar', 'W', 0, 0, {-> 0})->assert_equal(2) 1715 :1 1716 search('bar', 'W', 0, 0, {-> 1})->assert_equal(0) 1717 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:') 1718 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:') 1719enddef 1720 1721def Test_searchcount() 1722 new 1723 setline(1, "foo bar") 1724 :/foo 1725 searchcount(#{recompute: true}) 1726 ->assert_equal(#{ 1727 exact_match: 1, 1728 current: 1, 1729 total: 1, 1730 maxcount: 99, 1731 incomplete: 0}) 1732 bwipe! 1733enddef 1734 1735def Test_searchdecl() 1736 searchdecl('blah', true, true)->assert_equal(1) 1737enddef 1738 1739def Test_setbufvar() 1740 setbufvar(bufnr('%'), '&syntax', 'vim') 1741 &syntax->assert_equal('vim') 1742 setbufvar(bufnr('%'), '&ts', 16) 1743 &ts->assert_equal(16) 1744 settabwinvar(1, 1, '&syntax', 'vam') 1745 &syntax->assert_equal('vam') 1746 settabwinvar(1, 1, '&ts', 15) 1747 &ts->assert_equal(15) 1748 setlocal ts=8 1749 1750 setbufvar('%', 'myvar', 123) 1751 getbufvar('%', 'myvar')->assert_equal(123) 1752enddef 1753 1754def Test_setloclist() 1755 let items = [#{filename: '/tmp/file', lnum: 1, valid: true}] 1756 let what = #{items: items} 1757 setqflist([], ' ', what) 1758 setloclist(0, [], ' ', what) 1759enddef 1760 1761def Test_setreg() 1762 setreg('a', ['aaa', 'bbb', 'ccc']) 1763 let reginfo = getreginfo('a') 1764 setreg('a', reginfo) 1765 getreginfo('a')->assert_equal(reginfo) 1766enddef 1767 1768def Test_spellsuggest() 1769 if !has('spell') 1770 MissingFeature 'spell' 1771 else 1772 spellsuggest('marrch', 1, true)->assert_equal(['March']) 1773 endif 1774enddef 1775 1776def Test_split() 1777 split(' aa bb ', '\W\+', true)->assert_equal(['', 'aa', 'bb', '']) 1778enddef 1779 1780def Test_str2nr() 1781 str2nr("1'000'000", 10, true)->assert_equal(1000000) 1782enddef 1783 1784def Test_strchars() 1785 strchars("A\u20dd", true)->assert_equal(1) 1786enddef 1787 1788def Test_submatch() 1789 let pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)' 1790 let Rep = {-> range(10)->map({_, v -> submatch(v, true)})->string()} 1791 let actual = substitute('A123456789', pat, Rep, '') 1792 let expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]" 1793 actual->assert_equal(expected) 1794enddef 1795 1796def Test_synID() 1797 new 1798 setline(1, "text") 1799 synID(1, 1, true)->assert_equal(0) 1800 bwipe! 1801enddef 1802 1803def Test_term_gettty() 1804 if !has('terminal') 1805 MissingFeature 'terminal' 1806 else 1807 let buf = Run_shell_in_terminal({}) 1808 term_gettty(buf, true)->assert_notequal('') 1809 StopShellInTerminal(buf) 1810 endif 1811enddef 1812 1813def Test_term_start() 1814 if !has('terminal') 1815 MissingFeature 'terminal' 1816 else 1817 botright new 1818 let winnr = winnr() 1819 term_start(&shell, #{curwin: true}) 1820 winnr()->assert_equal(winnr) 1821 bwipe! 1822 endif 1823enddef 1824 1825def Test_timer_paused() 1826 let id = timer_start(50, {-> 0}) 1827 timer_pause(id, true) 1828 let info = timer_info(id) 1829 info[0]['paused']->assert_equal(1) 1830 timer_stop(id) 1831enddef 1832 1833def Test_win_splitmove() 1834 split 1835 win_splitmove(1, 2, #{vertical: true, rightbelow: true}) 1836 close 1837enddef 1838 1839""""""" end of builtin functions 1840 1841def Fibonacci(n: number): number 1842 if n < 2 1843 return n 1844 else 1845 return Fibonacci(n - 1) + Fibonacci(n - 2) 1846 endif 1847enddef 1848 1849def Test_recursive_call() 1850 Fibonacci(20)->assert_equal(6765) 1851enddef 1852 1853def TreeWalk(dir: string): list<any> 1854 return readdir(dir)->map({_, val -> 1855 fnamemodify(dir .. '/' .. val, ':p')->isdirectory() 1856 ? {val: TreeWalk(dir .. '/' .. val)} 1857 : val 1858 }) 1859enddef 1860 1861def Test_closure_in_map() 1862 mkdir('XclosureDir/tdir', 'p') 1863 writefile(['111'], 'XclosureDir/file1') 1864 writefile(['222'], 'XclosureDir/file2') 1865 writefile(['333'], 'XclosureDir/tdir/file3') 1866 1867 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {'tdir': ['file3']}]) 1868 1869 delete('XclosureDir', 'rf') 1870enddef 1871 1872def Test_partial_call() 1873 let Xsetlist = function('setloclist', [0]) 1874 Xsetlist([], ' ', {'title': 'test'}) 1875 getloclist(0, {'title': 1})->assert_equal({'title': 'test'}) 1876 1877 Xsetlist = function('setloclist', [0, [], ' ']) 1878 Xsetlist({'title': 'test'}) 1879 getloclist(0, {'title': 1})->assert_equal({'title': 'test'}) 1880 1881 Xsetlist = function('setqflist') 1882 Xsetlist([], ' ', {'title': 'test'}) 1883 getqflist({'title': 1})->assert_equal({'title': 'test'}) 1884 1885 Xsetlist = function('setqflist', [[], ' ']) 1886 Xsetlist({'title': 'test'}) 1887 getqflist({'title': 1})->assert_equal({'title': 'test'}) 1888enddef 1889 1890def Test_cmd_modifier() 1891 tab echo '0' 1892 CheckDefFailure(['5tab echo 3'], 'E16:') 1893enddef 1894 1895def Test_restore_modifiers() 1896 # check that when compiling a :def function command modifiers are not messed 1897 # up. 1898 let lines =<< trim END 1899 vim9script 1900 set eventignore= 1901 autocmd QuickFixCmdPost * copen 1902 def AutocmdsDisabled() 1903 eval 0 1904 enddef 1905 func Func() 1906 noautocmd call s:AutocmdsDisabled() 1907 let g:ei_after = &eventignore 1908 endfunc 1909 Func() 1910 END 1911 CheckScriptSuccess(lines) 1912 g:ei_after->assert_equal('') 1913enddef 1914 1915def StackTop() 1916 eval 1 1917 eval 2 1918 # call not on fourth line 1919 StackBot() 1920enddef 1921 1922def StackBot() 1923 # throw an error 1924 eval [][0] 1925enddef 1926 1927def Test_callstack_def() 1928 try 1929 StackTop() 1930 catch 1931 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2') 1932 endtry 1933enddef 1934 1935 1936" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 1937