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 var 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 var 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 var 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 var lines =<< trim END 237 vim9script 238 def g:Gfunc(): string 239 return 'global' 240 enddef 241 def AnotherFunc(): number 242 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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(['var RefWrong: func(string?)'], 'E1010:') 447 CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:') 448 449 var 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(['var RefWrong: func(...list<string>, string)'], 'E110:') 456 CheckDefFailure(['var 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)', 'var 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 var d: dict<string> = {} 489 DictArg(d) 490 d['key']->assert_equal('value') 491 var 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 var lines =<< trim END 522 vim9script 523 def RetNumber(): number 524 return 123 525 enddef 526 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var Ref1: func(bool): string 618 var Ref2: func(bool): number 619 var Ref3: func(bool): any 620 Ref3 = g:cond ? Ref1 : Ref2 621 622 # different number of arguments 623 var Refa1: func(bool): number 624 var Refa2: func(bool, number): number 625 var Refa3: func: number 626 Refa3 = g:cond ? Refa1 : Refa2 627 628 # different argument types 629 var Refb1: func(bool, string): number 630 var Refb2: func(string, number): number 631 var 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 var lines =<< trim END 702 vim9script 703 var name = '' 704 def MyFunc(arg: string) 705 name = arg 706 enddef 707 MyFunc('foobar') 708 name->assert_equal('foobar') 709 710 var str = 'barfoo' 711 str->MyFunc() 712 name->assert_equal('barfoo') 713 714 g:value = 'value' 715 g:value->MyFunc() 716 name->assert_equal('value') 717 718 var 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 var 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 name->assert_equal('text') 742 ("some")->MyFunc() 743 name->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 name->assert_equal('asdfasdf') 749 "xyz"->MyFunc() 750 name->assert_equal('xyz') 751 752 def UseString() 753 'xyork'->MyFunc() 754 enddef 755 UseString() 756 name->assert_equal('xyork') 757 758 def UseString2() 759 "knife"->MyFunc() 760 enddef 761 UseString2() 762 name->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 name 777 ) 778 779 call MyFunc( 780 'more' 781 .. 782 'lines' 783 ) 784 assert_equal( 785 'morelines', 786 name) 787 END 788 writefile(lines, 'Xcall.vim') 789 source Xcall.vim 790 delete('Xcall.vim') 791enddef 792 793def Test_vim9script_call_fail_decl() 794 var lines =<< trim END 795 vim9script 796 var name = '' 797 def MyFunc(arg: string) 798 var name = 123 799 enddef 800 defcompile 801 END 802 CheckScriptFailure(lines, 'E1054:') 803enddef 804 805def Test_vim9script_call_fail_type() 806 var 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 var 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 var 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 var 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 var Ref1: func() 996 s:funcResult = 0 997 Ref1 = FuncNoArgNoRet 998 Ref1() 999 s:funcResult->assert_equal(11) 1000 1001 var 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 var 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 var res = '' 1040 for name in argv() 1041 res ..= name 1042 endfor 1043 res->assert_equal('fileonefiletwo') 1044enddef 1045 1046def Test_func_type_part() 1047 var RefVoid: func: void 1048 RefVoid = FuncNoArgNoRet 1049 RefVoid = FuncOneArgNoRet 1050 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number') 1051 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string') 1052 1053 var RefAny: func(): any 1054 RefAny = FuncNoArgRetNumber 1055 RefAny = FuncNoArgRetString 1056 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()') 1057 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)') 1058 1059 var RefNr: func: number 1060 RefNr = FuncNoArgRetNumber 1061 RefNr = FuncOneArgRetNumber 1062 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()') 1063 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string') 1064 1065 var RefStr: func: string 1066 RefStr = FuncNoArgRetString 1067 RefStr = FuncOneArgRetString 1068 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()') 1069 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number') 1070enddef 1071 1072def Test_func_type_fails() 1073 CheckDefFailure(['var ref1: func()'], 'E704:') 1074 1075 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number') 1076 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)') 1077 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number') 1078 CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)') 1079 CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)') 1080 CheckDefFailure(['var Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(...bool) but got func(bool, number)') 1081 1082 CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:') 1083 CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:') 1084 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:') 1085 CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:') 1086enddef 1087 1088def Test_func_return_type() 1089 var nr: number 1090 nr = FuncNoArgRetNumber() 1091 nr->assert_equal(1234) 1092 1093 nr = FuncOneArgRetAny(122) 1094 nr->assert_equal(122) 1095 1096 var str: string 1097 str = FuncOneArgRetAny('yes') 1098 str->assert_equal('yes') 1099 1100 CheckDefFailure(['var 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 var 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 var 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 var db = #{foo: 1, bar: 2} 1206 # comment 1207 var 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 'var RefMe: func = function("g:DelMe")', 1226 'delfunc g:DelMe', 1227 'echo RefMe()'], 'E117:') 1228enddef 1229 1230def Test_unknown_function() 1231 CheckDefExecFailure([ 1232 'var 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 var local = 'some ' 1242 RefFunc({s -> local .. s})->assert_equal('some more') 1243enddef 1244 1245def MakeRef() 1246 var 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 var 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 var local = 'loc_val' 1296 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s} 1297enddef 1298 1299def MakeArgRefsVarargs(theArg: string, ...rest: list<string>) 1300 var 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 var 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 var 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 var text = 'text' 1355 g:Ref = {s -> s .. text} 1356 GetResult(g:Ref)->assert_equal('sometext') 1357enddef 1358 1359def Test_double_closure_fails() 1360 var lines =<< trim END 1361 vim9script 1362 def Func() 1363 var name = 0 1364 for i in range(2) 1365 timer_start(0, {-> name}) 1366 endfor 1367 enddef 1368 Func() 1369 END 1370 CheckScriptSuccess(lines) 1371enddef 1372 1373def Test_nested_closure_fails() 1374 var lines =<< trim END 1375 vim9script 1376 def FuncA() 1377 FuncB(0) 1378 enddef 1379 def FuncB(n: number): list<string> 1380 return map([0], {_, v -> n}) 1381 enddef 1382 FuncA() 1383 END 1384 CheckScriptFailure(lines, 'E1012:') 1385enddef 1386 1387def Test_nested_lambda() 1388 var lines =<< trim END 1389 vim9script 1390 def Func() 1391 var x = 4 1392 var Lambda1 = {-> 7} 1393 var Lambda2 = {-> [Lambda1(), x]} 1394 var res = Lambda2() 1395 assert_equal([7, 4], res) 1396 enddef 1397 Func() 1398 END 1399 CheckScriptSuccess(lines) 1400enddef 1401 1402def Test_sort_return_type() 1403 var res: list<number> 1404 res = [1, 2, 3]->sort() 1405enddef 1406 1407def Test_sort_argument() 1408 var res = ['b', 'a', 'c']->sort('i') 1409 res->assert_equal(['a', 'b', 'c']) 1410enddef 1411 1412def Test_getqflist_return_type() 1413 var l = getqflist() 1414 l->assert_equal([]) 1415 1416 var d = getqflist(#{items: 0}) 1417 d->assert_equal(#{items: []}) 1418enddef 1419 1420def Test_getloclist_return_type() 1421 var l = getloclist(1) 1422 l->assert_equal([]) 1423 1424 var d = getloclist(1, #{items: 0}) 1425 d->assert_equal(#{items: []}) 1426enddef 1427 1428def Test_copy_return_type() 1429 var l = copy([1, 2, 3]) 1430 var res = 0 1431 for n in l 1432 res += n 1433 endfor 1434 res->assert_equal(6) 1435 1436 var dl = deepcopy([1, 2, 3]) 1437 res = 0 1438 for n in dl 1439 res += n 1440 endfor 1441 res->assert_equal(6) 1442 1443 dl = deepcopy([1, 2, 3], true) 1444enddef 1445 1446def Test_extend_return_type() 1447 var l = extend([1, 2], [3]) 1448 var res = 0 1449 for n in l 1450 res += n 1451 endfor 1452 res->assert_equal(6) 1453enddef 1454 1455def Test_garbagecollect() 1456 garbagecollect(true) 1457enddef 1458 1459def Test_insert_return_type() 1460 var l = insert([2, 1], 3) 1461 var res = 0 1462 for n in l 1463 res += n 1464 endfor 1465 res->assert_equal(6) 1466enddef 1467 1468def Test_keys_return_type() 1469 const var: list<string> = #{a: 1, b: 2}->keys() 1470 var->assert_equal(['a', 'b']) 1471enddef 1472 1473def Test_reverse_return_type() 1474 var l = reverse([1, 2, 3]) 1475 var res = 0 1476 for n in l 1477 res += n 1478 endfor 1479 res->assert_equal(6) 1480enddef 1481 1482def Test_remove_return_type() 1483 var l = remove(#{one: [1, 2], two: [3, 4]}, 'one') 1484 var res = 0 1485 for n in l 1486 res += n 1487 endfor 1488 res->assert_equal(3) 1489enddef 1490 1491def Test_filter_return_type() 1492 var l = filter([1, 2, 3], {-> 1}) 1493 var res = 0 1494 for n in l 1495 res += n 1496 endfor 1497 res->assert_equal(6) 1498enddef 1499 1500def Test_bufnr() 1501 var buf = bufnr() 1502 bufnr('%')->assert_equal(buf) 1503 1504 buf = bufnr('Xdummy', true) 1505 buf->assert_notequal(-1) 1506 exe 'bwipe! ' .. buf 1507enddef 1508 1509def Test_col() 1510 new 1511 setline(1, 'asdf') 1512 col([1, '$'])->assert_equal(5) 1513enddef 1514 1515def Test_char2nr() 1516 char2nr('あ', true)->assert_equal(12354) 1517enddef 1518 1519def Test_getreg_return_type() 1520 var s1: string = getreg('"') 1521 var s2: string = getreg('"', 1) 1522 var s3: list<string> = getreg('"', 1, 1) 1523enddef 1524 1525def Wrong_dict_key_type(items: list<number>): list<number> 1526 return filter(items, {_, val -> get({val: 1}, 'x')}) 1527enddef 1528 1529def Test_wrong_dict_key_type() 1530 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1012:') 1531enddef 1532 1533def Line_continuation_in_def(dir: string = ''): string 1534 var path: string = empty(dir) 1535 \ ? 'empty' 1536 \ : 'full' 1537 return path 1538enddef 1539 1540def Test_line_continuation_in_def() 1541 Line_continuation_in_def('.')->assert_equal('full') 1542enddef 1543 1544def Line_continuation_in_lambda(): list<string> 1545 var x = range(97, 100) 1546 ->map({_, v -> nr2char(v) 1547 ->toupper()}) 1548 ->reverse() 1549 return x 1550enddef 1551 1552def Test_line_continuation_in_lambda() 1553 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A']) 1554enddef 1555 1556func Test_silent_echo() 1557 CheckScreendump 1558 1559 let lines =<< trim END 1560 vim9script 1561 def EchoNothing() 1562 silent echo '' 1563 enddef 1564 defcompile 1565 END 1566 call writefile(lines, 'XTest_silent_echo') 1567 1568 " Check that the balloon shows up after a mouse move 1569 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6}) 1570 call term_sendkeys(buf, ":abc") 1571 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {}) 1572 1573 " clean up 1574 call StopVimInTerminal(buf) 1575 call delete('XTest_silent_echo') 1576endfunc 1577 1578""""""" builtin functions that behave differently in Vim9 1579 1580def Test_bufname() 1581 split SomeFile 1582 bufname('%')->assert_equal('SomeFile') 1583 edit OtherFile 1584 bufname('#')->assert_equal('SomeFile') 1585 close 1586enddef 1587 1588def Test_bufwinid() 1589 var origwin = win_getid() 1590 below split SomeFile 1591 var SomeFileID = win_getid() 1592 below split OtherFile 1593 below split SomeFile 1594 bufwinid('SomeFile')->assert_equal(SomeFileID) 1595 1596 win_gotoid(origwin) 1597 only 1598 bwipe SomeFile 1599 bwipe OtherFile 1600enddef 1601 1602def Test_count() 1603 count('ABC ABC ABC', 'b', true)->assert_equal(3) 1604 count('ABC ABC ABC', 'b', false)->assert_equal(0) 1605enddef 1606 1607def Test_expand() 1608 split SomeFile 1609 expand('%', true, true)->assert_equal(['SomeFile']) 1610 close 1611enddef 1612 1613def Test_getbufinfo() 1614 var bufinfo = getbufinfo(bufnr()) 1615 getbufinfo('%')->assert_equal(bufinfo) 1616 1617 edit Xtestfile1 1618 hide edit Xtestfile2 1619 hide enew 1620 getbufinfo(#{bufloaded: true, buflisted: true, bufmodified: false}) 1621 ->len()->assert_equal(3) 1622 bwipe Xtestfile1 Xtestfile2 1623enddef 1624 1625def Test_getbufline() 1626 e SomeFile 1627 var buf = bufnr() 1628 e # 1629 var lines = ['aaa', 'bbb', 'ccc'] 1630 setbufline(buf, 1, lines) 1631 getbufline('#', 1, '$')->assert_equal(lines) 1632 1633 bwipe! 1634enddef 1635 1636def Test_getchangelist() 1637 new 1638 setline(1, 'some text') 1639 var changelist = bufnr()->getchangelist() 1640 getchangelist('%')->assert_equal(changelist) 1641 bwipe! 1642enddef 1643 1644def Test_getchar() 1645 while getchar(0) 1646 endwhile 1647 getchar(true)->assert_equal(0) 1648enddef 1649 1650def Test_getcompletion() 1651 set wildignore=*.vim,*~ 1652 var l = getcompletion('run', 'file', true) 1653 l->assert_equal([]) 1654 set wildignore& 1655enddef 1656 1657def Test_getreg() 1658 var lines = ['aaa', 'bbb', 'ccc'] 1659 setreg('a', lines) 1660 getreg('a', true, true)->assert_equal(lines) 1661enddef 1662 1663def Test_glob() 1664 glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim']) 1665enddef 1666 1667def Test_globpath() 1668 globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim']) 1669enddef 1670 1671def Test_has() 1672 has('eval', true)->assert_equal(1) 1673enddef 1674 1675def Test_hasmapto() 1676 hasmapto('foobar', 'i', true)->assert_equal(0) 1677 iabbrev foo foobar 1678 hasmapto('foobar', 'i', true)->assert_equal(1) 1679 iunabbrev foo 1680enddef 1681 1682def Test_index() 1683 index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3) 1684enddef 1685 1686def Test_list2str_str2list_utf8() 1687 var s = "\u3042\u3044" 1688 var l = [0x3042, 0x3044] 1689 str2list(s, true)->assert_equal(l) 1690 list2str(l, true)->assert_equal(s) 1691enddef 1692 1693def SID(): number 1694 return expand('<SID>') 1695 ->matchstr('<SNR>\zs\d\+\ze_$') 1696 ->str2nr() 1697enddef 1698 1699def Test_maparg() 1700 var lnum = str2nr(expand('<sflnum>')) 1701 map foo bar 1702 maparg('foo', '', false, true)->assert_equal(#{ 1703 lnum: lnum + 1, 1704 script: 0, 1705 mode: ' ', 1706 silent: 0, 1707 noremap: 0, 1708 lhs: 'foo', 1709 lhsraw: 'foo', 1710 nowait: 0, 1711 expr: 0, 1712 sid: SID(), 1713 rhs: 'bar', 1714 buffer: 0}) 1715 unmap foo 1716enddef 1717 1718def Test_mapcheck() 1719 iabbrev foo foobar 1720 mapcheck('foo', 'i', true)->assert_equal('foobar') 1721 iunabbrev foo 1722enddef 1723 1724def Test_maparg_mapset() 1725 nnoremap <F3> :echo "hit F3"<CR> 1726 var mapsave = maparg('<F3>', 'n', false, true) 1727 mapset('n', false, mapsave) 1728 1729 nunmap <F3> 1730enddef 1731 1732def Test_nr2char() 1733 nr2char(97, true)->assert_equal('a') 1734enddef 1735 1736def Test_readdir() 1737 eval expand('sautest')->readdir({e -> e[0] !=# '.'}) 1738 eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'}) 1739enddef 1740 1741def Test_search() 1742 new 1743 setline(1, ['foo', 'bar']) 1744 var val = 0 1745 # skip expr returns boolean 1746 search('bar', 'W', 0, 0, {-> val == 1})->assert_equal(2) 1747 :1 1748 search('bar', 'W', 0, 0, {-> val == 0})->assert_equal(0) 1749 # skip expr returns number, only 0 and 1 are accepted 1750 :1 1751 search('bar', 'W', 0, 0, {-> 0})->assert_equal(2) 1752 :1 1753 search('bar', 'W', 0, 0, {-> 1})->assert_equal(0) 1754 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:') 1755 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:') 1756enddef 1757 1758def Test_searchcount() 1759 new 1760 setline(1, "foo bar") 1761 :/foo 1762 searchcount(#{recompute: true}) 1763 ->assert_equal(#{ 1764 exact_match: 1, 1765 current: 1, 1766 total: 1, 1767 maxcount: 99, 1768 incomplete: 0}) 1769 bwipe! 1770enddef 1771 1772def Test_searchdecl() 1773 searchdecl('blah', true, true)->assert_equal(1) 1774enddef 1775 1776def Test_setbufvar() 1777 setbufvar(bufnr('%'), '&syntax', 'vim') 1778 &syntax->assert_equal('vim') 1779 setbufvar(bufnr('%'), '&ts', 16) 1780 &ts->assert_equal(16) 1781 settabwinvar(1, 1, '&syntax', 'vam') 1782 &syntax->assert_equal('vam') 1783 settabwinvar(1, 1, '&ts', 15) 1784 &ts->assert_equal(15) 1785 setlocal ts=8 1786 1787 setbufvar('%', 'myvar', 123) 1788 getbufvar('%', 'myvar')->assert_equal(123) 1789enddef 1790 1791def Test_setloclist() 1792 var items = [#{filename: '/tmp/file', lnum: 1, valid: true}] 1793 var what = #{items: items} 1794 setqflist([], ' ', what) 1795 setloclist(0, [], ' ', what) 1796enddef 1797 1798def Test_setreg() 1799 setreg('a', ['aaa', 'bbb', 'ccc']) 1800 var reginfo = getreginfo('a') 1801 setreg('a', reginfo) 1802 getreginfo('a')->assert_equal(reginfo) 1803enddef 1804 1805def Test_spellsuggest() 1806 if !has('spell') 1807 MissingFeature 'spell' 1808 else 1809 spellsuggest('marrch', 1, true)->assert_equal(['March']) 1810 endif 1811enddef 1812 1813def Test_split() 1814 split(' aa bb ', '\W\+', true)->assert_equal(['', 'aa', 'bb', '']) 1815enddef 1816 1817def Test_str2nr() 1818 str2nr("1'000'000", 10, true)->assert_equal(1000000) 1819enddef 1820 1821def Test_strchars() 1822 strchars("A\u20dd", true)->assert_equal(1) 1823enddef 1824 1825def Test_submatch() 1826 var pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)' 1827 var Rep = {-> range(10)->map({_, v -> submatch(v, true)})->string()} 1828 var actual = substitute('A123456789', pat, Rep, '') 1829 var expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]" 1830 actual->assert_equal(expected) 1831enddef 1832 1833def Test_synID() 1834 new 1835 setline(1, "text") 1836 synID(1, 1, true)->assert_equal(0) 1837 bwipe! 1838enddef 1839 1840def Test_term_gettty() 1841 if !has('terminal') 1842 MissingFeature 'terminal' 1843 else 1844 var buf = Run_shell_in_terminal({}) 1845 term_gettty(buf, true)->assert_notequal('') 1846 StopShellInTerminal(buf) 1847 endif 1848enddef 1849 1850def Test_term_start() 1851 if !has('terminal') 1852 MissingFeature 'terminal' 1853 else 1854 botright new 1855 var winnr = winnr() 1856 term_start(&shell, #{curwin: true}) 1857 winnr()->assert_equal(winnr) 1858 bwipe! 1859 endif 1860enddef 1861 1862def Test_timer_paused() 1863 var id = timer_start(50, {-> 0}) 1864 timer_pause(id, true) 1865 var info = timer_info(id) 1866 info[0]['paused']->assert_equal(1) 1867 timer_stop(id) 1868enddef 1869 1870def Test_win_splitmove() 1871 split 1872 win_splitmove(1, 2, #{vertical: true, rightbelow: true}) 1873 close 1874enddef 1875 1876""""""" end of builtin functions 1877 1878def Fibonacci(n: number): number 1879 if n < 2 1880 return n 1881 else 1882 return Fibonacci(n - 1) + Fibonacci(n - 2) 1883 endif 1884enddef 1885 1886def Test_recursive_call() 1887 Fibonacci(20)->assert_equal(6765) 1888enddef 1889 1890def TreeWalk(dir: string): list<any> 1891 return readdir(dir)->map({_, val -> 1892 fnamemodify(dir .. '/' .. val, ':p')->isdirectory() 1893 ? {val: TreeWalk(dir .. '/' .. val)} 1894 : val 1895 }) 1896enddef 1897 1898def Test_closure_in_map() 1899 mkdir('XclosureDir/tdir', 'p') 1900 writefile(['111'], 'XclosureDir/file1') 1901 writefile(['222'], 'XclosureDir/file2') 1902 writefile(['333'], 'XclosureDir/tdir/file3') 1903 1904 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {'tdir': ['file3']}]) 1905 1906 delete('XclosureDir', 'rf') 1907enddef 1908 1909def Test_partial_call() 1910 var Xsetlist = function('setloclist', [0]) 1911 Xsetlist([], ' ', {'title': 'test'}) 1912 getloclist(0, {'title': 1})->assert_equal({'title': 'test'}) 1913 1914 Xsetlist = function('setloclist', [0, [], ' ']) 1915 Xsetlist({'title': 'test'}) 1916 getloclist(0, {'title': 1})->assert_equal({'title': 'test'}) 1917 1918 Xsetlist = function('setqflist') 1919 Xsetlist([], ' ', {'title': 'test'}) 1920 getqflist({'title': 1})->assert_equal({'title': 'test'}) 1921 1922 Xsetlist = function('setqflist', [[], ' ']) 1923 Xsetlist({'title': 'test'}) 1924 getqflist({'title': 1})->assert_equal({'title': 'test'}) 1925enddef 1926 1927def Test_cmd_modifier() 1928 tab echo '0' 1929 CheckDefFailure(['5tab echo 3'], 'E16:') 1930enddef 1931 1932def Test_restore_modifiers() 1933 # check that when compiling a :def function command modifiers are not messed 1934 # up. 1935 var lines =<< trim END 1936 vim9script 1937 set eventignore= 1938 autocmd QuickFixCmdPost * copen 1939 def AutocmdsDisabled() 1940 eval 0 1941 enddef 1942 func Func() 1943 noautocmd call s:AutocmdsDisabled() 1944 let g:ei_after = &eventignore 1945 endfunc 1946 Func() 1947 END 1948 CheckScriptSuccess(lines) 1949 g:ei_after->assert_equal('') 1950enddef 1951 1952def StackTop() 1953 eval 1 1954 eval 2 1955 # call not on fourth line 1956 StackBot() 1957enddef 1958 1959def StackBot() 1960 # throw an error 1961 eval [][0] 1962enddef 1963 1964def Test_callstack_def() 1965 try 1966 StackTop() 1967 catch 1968 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2') 1969 endtry 1970enddef 1971 1972 1973" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 1974