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 shared.vim 8source screendump.vim 9 10def Test_range_only() 11 new 12 setline(1, ['blah', 'Blah']) 13 :/Blah/ 14 assert_equal(2, getcurpos()[1]) 15 bwipe! 16 17 # without range commands use current line 18 new 19 setline(1, ['one', 'two', 'three']) 20 :2 21 print 22 assert_equal('two', Screenline(&lines)) 23 :3 24 list 25 assert_equal('three$', Screenline(&lines)) 26 27 # missing command does not print the line 28 var lines =<< trim END 29 vim9script 30 :1| 31 assert_equal('three$', Screenline(&lines)) 32 :| 33 assert_equal('three$', Screenline(&lines)) 34 END 35 CheckScriptSuccess(lines) 36 37 bwipe! 38 39 # won't generate anything 40 if false 41 :123 42 endif 43enddef 44 45let g:alist = [7] 46let g:astring = 'text' 47let g:anumber = 123 48 49def Test_delfunction() 50 # Check function is defined in script namespace 51 CheckScriptSuccess([ 52 'vim9script', 53 'func CheckMe()', 54 ' return 123', 55 'endfunc', 56 'assert_equal(123, s:CheckMe())', 57 ]) 58 59 # Check function in script namespace cannot be deleted 60 CheckScriptFailure([ 61 'vim9script', 62 'func DeleteMe1()', 63 'endfunc', 64 'delfunction DeleteMe1', 65 ], 'E1084:') 66 CheckScriptFailure([ 67 'vim9script', 68 'func DeleteMe2()', 69 'endfunc', 70 'def DoThat()', 71 ' delfunction DeleteMe2', 72 'enddef', 73 'DoThat()', 74 ], 'E1084:') 75 CheckScriptFailure([ 76 'vim9script', 77 'def DeleteMe3()', 78 'enddef', 79 'delfunction DeleteMe3', 80 ], 'E1084:') 81 CheckScriptFailure([ 82 'vim9script', 83 'def DeleteMe4()', 84 'enddef', 85 'def DoThat()', 86 ' delfunction DeleteMe4', 87 'enddef', 88 'DoThat()', 89 ], 'E1084:') 90 91 # Check that global :def function can be replaced and deleted 92 var lines =<< trim END 93 vim9script 94 def g:Global(): string 95 return "yes" 96 enddef 97 assert_equal("yes", g:Global()) 98 def! g:Global(): string 99 return "no" 100 enddef 101 assert_equal("no", g:Global()) 102 delfunc g:Global 103 assert_false(exists('*g:Global')) 104 END 105 CheckScriptSuccess(lines) 106 107 # Check that global function can be replaced by a :def function and deleted 108 lines =<< trim END 109 vim9script 110 func g:Global() 111 return "yes" 112 endfunc 113 assert_equal("yes", g:Global()) 114 def! g:Global(): string 115 return "no" 116 enddef 117 assert_equal("no", g:Global()) 118 delfunc g:Global 119 assert_false(exists('*g:Global')) 120 END 121 CheckScriptSuccess(lines) 122 123 # Check that global :def function can be replaced by a function and deleted 124 lines =<< trim END 125 vim9script 126 def g:Global(): string 127 return "yes" 128 enddef 129 assert_equal("yes", g:Global()) 130 func! g:Global() 131 return "no" 132 endfunc 133 assert_equal("no", g:Global()) 134 delfunc g:Global 135 assert_false(exists('*g:Global')) 136 END 137 CheckScriptSuccess(lines) 138enddef 139 140def Test_wrong_type() 141 CheckDefFailure(['var name: list<nothing>'], 'E1010:') 142 CheckDefFailure(['var name: list<list<nothing>>'], 'E1010:') 143 CheckDefFailure(['var name: dict<nothing>'], 'E1010:') 144 CheckDefFailure(['var name: dict<dict<nothing>>'], 'E1010:') 145 146 CheckDefFailure(['var name: dict<number'], 'E1009:') 147 CheckDefFailure(['var name: dict<list<number>'], 'E1009:') 148 149 CheckDefFailure(['var name: ally'], 'E1010:') 150 CheckDefFailure(['var name: bram'], 'E1010:') 151 CheckDefFailure(['var name: cathy'], 'E1010:') 152 CheckDefFailure(['var name: dom'], 'E1010:') 153 CheckDefFailure(['var name: freddy'], 'E1010:') 154 CheckDefFailure(['var name: john'], 'E1010:') 155 CheckDefFailure(['var name: larry'], 'E1010:') 156 CheckDefFailure(['var name: ned'], 'E1010:') 157 CheckDefFailure(['var name: pam'], 'E1010:') 158 CheckDefFailure(['var name: sam'], 'E1010:') 159 CheckDefFailure(['var name: vim'], 'E1010:') 160 161 CheckDefFailure(['var Ref: number', 'Ref()'], 'E1085:') 162 CheckDefFailure(['var Ref: string', 'var res = Ref()'], 'E1085:') 163enddef 164 165def Test_script_wrong_type() 166 var lines =<< trim END 167 vim9script 168 var s:dict: dict<string> 169 s:dict['a'] = ['x'] 170 END 171 CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got list<string>', 3) 172enddef 173 174def Test_const() 175 CheckDefFailure(['final name = 234', 'name = 99'], 'E1018:') 176 CheckDefFailure(['final one = 234', 'var one = 99'], 'E1017:') 177 CheckDefFailure(['final list = [1, 2]', 'var list = [3, 4]'], 'E1017:') 178 CheckDefFailure(['final two'], 'E1125:') 179 CheckDefFailure(['final &option'], 'E996:') 180 181 var lines =<< trim END 182 final list = [1, 2, 3] 183 list[0] = 4 184 list->assert_equal([4, 2, 3]) 185 const other = [5, 6, 7] 186 other->assert_equal([5, 6, 7]) 187 188 var varlist = [7, 8] 189 const constlist = [1, varlist, 3] 190 varlist[0] = 77 191 # TODO: does not work yet 192 # constlist[1][1] = 88 193 var cl = constlist[1] 194 cl[1] = 88 195 constlist->assert_equal([1, [77, 88], 3]) 196 197 var vardict = {five: 5, six: 6} 198 const constdict = {one: 1, two: vardict, three: 3} 199 vardict['five'] = 55 200 # TODO: does not work yet 201 # constdict['two']['six'] = 66 202 var cd = constdict['two'] 203 cd['six'] = 66 204 constdict->assert_equal({one: 1, two: {five: 55, six: 66}, three: 3}) 205 END 206 CheckDefAndScriptSuccess(lines) 207enddef 208 209def Test_const_bang() 210 var lines =<< trim END 211 const var = 234 212 var = 99 213 END 214 CheckDefExecFailure(lines, 'E1018:', 2) 215 CheckScriptFailure(['vim9script'] + lines, 'E46:', 3) 216 217 lines =<< trim END 218 const ll = [2, 3, 4] 219 ll[0] = 99 220 END 221 CheckDefExecFailure(lines, 'E1119:', 2) 222 CheckScriptFailure(['vim9script'] + lines, 'E741:', 3) 223 224 lines =<< trim END 225 const ll = [2, 3, 4] 226 ll[3] = 99 227 END 228 CheckDefExecFailure(lines, 'E1118:', 2) 229 CheckScriptFailure(['vim9script'] + lines, 'E684:', 3) 230 231 lines =<< trim END 232 const dd = {one: 1, two: 2} 233 dd["one"] = 99 234 END 235 CheckDefExecFailure(lines, 'E1121:', 2) 236 CheckScriptFailure(['vim9script'] + lines, 'E741:', 3) 237 238 lines =<< trim END 239 const dd = {one: 1, two: 2} 240 dd["three"] = 99 241 END 242 CheckDefExecFailure(lines, 'E1120:') 243 CheckScriptFailure(['vim9script'] + lines, 'E741:', 3) 244enddef 245 246def Test_range_no_colon() 247 CheckDefFailure(['%s/a/b/'], 'E1050:') 248 CheckDefFailure(['+ s/a/b/'], 'E1050:') 249 CheckDefFailure(['- s/a/b/'], 'E1050:') 250 CheckDefFailure(['. s/a/b/'], 'E1050:') 251enddef 252 253 254def Test_block() 255 var outer = 1 256 { 257 var inner = 2 258 assert_equal(1, outer) 259 assert_equal(2, inner) 260 } 261 assert_equal(1, outer) 262 263 {|echo 'yes'|} 264enddef 265 266def Test_block_failure() 267 CheckDefFailure(['{', 'var inner = 1', '}', 'echo inner'], 'E1001:') 268 CheckDefFailure(['}'], 'E1025:') 269 CheckDefFailure(['{', 'echo 1'], 'E1026:') 270enddef 271 272def Test_block_local_vars() 273 var lines =<< trim END 274 vim9script 275 v:testing = 1 276 if true 277 var text = ['hello'] 278 def SayHello(): list<string> 279 return text 280 enddef 281 def SetText(v: string) 282 text = [v] 283 enddef 284 endif 285 286 if true 287 var text = ['again'] 288 def SayAgain(): list<string> 289 return text 290 enddef 291 endif 292 293 # test that the "text" variables are not cleaned up 294 test_garbagecollect_now() 295 296 defcompile 297 298 assert_equal(['hello'], SayHello()) 299 assert_equal(['again'], SayAgain()) 300 301 SetText('foobar') 302 assert_equal(['foobar'], SayHello()) 303 304 call writefile(['ok'], 'Xdidit') 305 qall! 306 END 307 308 # need to execute this with a separate Vim instance to avoid the current 309 # context gets garbage collected. 310 writefile(lines, 'Xscript') 311 RunVim([], [], '-S Xscript') 312 assert_equal(['ok'], readfile('Xdidit')) 313 314 delete('Xscript') 315 delete('Xdidit') 316enddef 317 318def Test_block_local_vars_with_func() 319 var lines =<< trim END 320 vim9script 321 if true 322 var foo = 'foo' 323 if true 324 var bar = 'bar' 325 def Func(): list<string> 326 return [foo, bar] 327 enddef 328 endif 329 endif 330 # function is compiled here, after blocks have finished, can still access 331 # "foo" and "bar" 332 assert_equal(['foo', 'bar'], Func()) 333 END 334 CheckScriptSuccess(lines) 335enddef 336 337func g:NoSuchFunc() 338 echo 'none' 339endfunc 340 341def Test_try_catch_throw() 342 var l = [] 343 try # comment 344 add(l, '1') 345 throw 'wrong' 346 add(l, '2') 347 catch # comment 348 add(l, v:exception) 349 finally # comment 350 add(l, '3') 351 endtry # comment 352 assert_equal(['1', 'wrong', '3'], l) 353 354 l = [] 355 try 356 try 357 add(l, '1') 358 throw 'wrong' 359 add(l, '2') 360 catch /right/ 361 add(l, v:exception) 362 endtry 363 catch /wrong/ 364 add(l, 'caught') 365 fina 366 add(l, 'finally') 367 endtry 368 assert_equal(['1', 'caught', 'finally'], l) 369 370 var n: number 371 try 372 n = l[3] 373 catch /E684:/ 374 n = 99 375 endtry 376 assert_equal(99, n) 377 378 var done = 'no' 379 if 0 380 try | catch | endtry 381 else 382 done = 'yes' 383 endif 384 assert_equal('yes', done) 385 386 done = 'no' 387 if 1 388 done = 'yes' 389 else 390 try | catch | endtry 391 done = 'never' 392 endif 393 assert_equal('yes', done) 394 395 if 1 396 else 397 try | catch /pat/ | endtry 398 try | catch /pat/ 399 endtry 400 try 401 catch /pat/ | endtry 402 try 403 catch /pat/ 404 endtry 405 endif 406 407 try 408 # string slice returns a string, not a number 409 n = g:astring[3] 410 catch /E1012:/ 411 n = 77 412 endtry 413 assert_equal(77, n) 414 415 try 416 n = l[g:astring] 417 catch /E1012:/ 418 n = 88 419 endtry 420 assert_equal(88, n) 421 422 try 423 n = s:does_not_exist 424 catch /E121:/ 425 n = 111 426 endtry 427 assert_equal(111, n) 428 429 try 430 n = g:does_not_exist 431 catch /E121:/ 432 n = 121 433 endtry 434 assert_equal(121, n) 435 436 var d = {one: 1} 437 try 438 n = d[g:astring] 439 catch /E716:/ 440 n = 222 441 endtry 442 assert_equal(222, n) 443 444 try 445 n = -g:astring 446 catch /E39:/ 447 n = 233 448 endtry 449 assert_equal(233, n) 450 451 try 452 n = +g:astring 453 catch /E1030:/ 454 n = 244 455 endtry 456 assert_equal(244, n) 457 458 try 459 n = +g:alist 460 catch /E745:/ 461 n = 255 462 endtry 463 assert_equal(255, n) 464 465 var nd: dict<any> 466 try 467 nd = {[g:alist]: 1} 468 catch /E1105:/ 469 n = 266 470 endtry 471 assert_equal(266, n) 472 473 try 474 [n] = [1, 2, 3] 475 catch /E1093:/ 476 n = 277 477 endtry 478 assert_equal(277, n) 479 480 try 481 &ts = g:astring 482 catch /E1012:/ 483 n = 288 484 endtry 485 assert_equal(288, n) 486 487 try 488 &backspace = 'asdf' 489 catch /E474:/ 490 n = 299 491 endtry 492 assert_equal(299, n) 493 494 l = [1] 495 try 496 l[3] = 3 497 catch /E684:/ 498 n = 300 499 endtry 500 assert_equal(300, n) 501 502 try 503 unlet g:does_not_exist 504 catch /E108:/ 505 n = 322 506 endtry 507 assert_equal(322, n) 508 509 try 510 d = {text: 1, [g:astring]: 2} 511 catch /E721:/ 512 n = 333 513 endtry 514 assert_equal(333, n) 515 516 try 517 l = DeletedFunc() 518 catch /E933:/ 519 n = 344 520 endtry 521 assert_equal(344, n) 522 523 try 524 echo len(v:true) 525 catch /E701:/ 526 n = 355 527 endtry 528 assert_equal(355, n) 529 530 var P = function('g:NoSuchFunc') 531 delfunc g:NoSuchFunc 532 try 533 echo P() 534 catch /E117:/ 535 n = 366 536 endtry 537 assert_equal(366, n) 538 539 try 540 echo g:NoSuchFunc() 541 catch /E117:/ 542 n = 377 543 endtry 544 assert_equal(377, n) 545 546 try 547 echo g:alist + 4 548 catch /E745:/ 549 n = 388 550 endtry 551 assert_equal(388, n) 552 553 try 554 echo 4 + g:alist 555 catch /E745:/ 556 n = 399 557 endtry 558 assert_equal(399, n) 559 560 try 561 echo g:alist.member 562 catch /E715:/ 563 n = 400 564 endtry 565 assert_equal(400, n) 566 567 try 568 echo d.member 569 catch /E716:/ 570 n = 411 571 endtry 572 assert_equal(411, n) 573 574 var counter = 0 575 for i in range(4) 576 try 577 eval [][0] 578 catch 579 endtry 580 counter += 1 581 endfor 582 assert_equal(4, counter) 583 584 # return in finally after empty catch 585 def ReturnInFinally(): number 586 try 587 finally 588 return 4 589 endtry 590 return 2 591 enddef 592 assert_equal(4, ReturnInFinally()) 593 594 var lines =<< trim END 595 vim9script 596 try 597 acos('0.5') 598 ->setline(1) 599 catch 600 g:caught = v:exception 601 endtry 602 END 603 CheckScriptSuccess(lines) 604 assert_match('E808: Number or Float required', g:caught) 605 unlet g:caught 606 607 # missing catch and/or finally 608 lines =<< trim END 609 vim9script 610 try 611 echo 'something' 612 endtry 613 END 614 CheckScriptFailure(lines, 'E1032:') 615enddef 616 617def Test_try_in_catch() 618 var lines =<< trim END 619 vim9script 620 var seq = [] 621 def DoIt() 622 try 623 seq->add('throw 1') 624 eval [][0] 625 seq->add('notreached') 626 catch 627 seq->add('catch') 628 try 629 seq->add('throw 2') 630 eval [][0] 631 seq->add('notreached') 632 catch /nothing/ 633 seq->add('notreached') 634 endtry 635 seq->add('done') 636 endtry 637 enddef 638 DoIt() 639 assert_equal(['throw 1', 'catch', 'throw 2', 'done'], seq) 640 END 641enddef 642 643def Test_error_in_catch() 644 var lines =<< trim END 645 try 646 eval [][0] 647 catch /E684:/ 648 eval [][0] 649 endtry 650 END 651 CheckDefExecFailure(lines, 'E684:', 4) 652enddef 653 654" :while at the very start of a function that :continue jumps to 655def TryContinueFunc() 656 while g:Count < 2 657 g:sequence ..= 't' 658 try 659 echoerr 'Test' 660 catch 661 g:Count += 1 662 g:sequence ..= 'c' 663 continue 664 endtry 665 g:sequence ..= 'e' 666 g:Count += 1 667 endwhile 668enddef 669 670def Test_continue_in_try_in_while() 671 g:Count = 0 672 g:sequence = '' 673 TryContinueFunc() 674 assert_equal('tctc', g:sequence) 675 unlet g:Count 676 unlet g:sequence 677enddef 678 679def Test_nocatch_return_in_try() 680 # return in try block returns normally 681 def ReturnInTry(): string 682 try 683 return '"some message"' 684 catch 685 endtry 686 return 'not reached' 687 enddef 688 exe 'echoerr ' .. ReturnInTry() 689enddef 690 691def Test_cnext_works_in_catch() 692 var lines =<< trim END 693 vim9script 694 au BufEnter * eval 1 + 2 695 writefile(['text'], 'Xfile1') 696 writefile(['text'], 'Xfile2') 697 var items = [ 698 {lnum: 1, filename: 'Xfile1', valid: true}, 699 {lnum: 1, filename: 'Xfile2', valid: true} 700 ] 701 setqflist([], ' ', {items: items}) 702 cwindow 703 704 def CnextOrCfirst() 705 # if cnext fails, cfirst is used 706 try 707 cnext 708 catch 709 cfirst 710 endtry 711 enddef 712 713 CnextOrCfirst() 714 CnextOrCfirst() 715 writefile([getqflist({idx: 0}).idx], 'Xresult') 716 qall 717 END 718 writefile(lines, 'XCatchCnext') 719 RunVim([], [], '--clean -S XCatchCnext') 720 assert_equal(['1'], readfile('Xresult')) 721 722 delete('Xfile1') 723 delete('Xfile2') 724 delete('XCatchCnext') 725 delete('Xresult') 726enddef 727 728def Test_throw_skipped() 729 if 0 730 throw dontgethere 731 endif 732enddef 733 734def Test_nocatch_throw_silenced() 735 var lines =<< trim END 736 vim9script 737 def Func() 738 throw 'error' 739 enddef 740 silent! Func() 741 END 742 writefile(lines, 'XthrowSilenced') 743 source XthrowSilenced 744 delete('XthrowSilenced') 745enddef 746 747def DeletedFunc(): list<any> 748 return ['delete me'] 749enddef 750defcompile 751delfunc DeletedFunc 752 753def ThrowFromDef() 754 throw "getout" # comment 755enddef 756 757func CatchInFunc() 758 try 759 call ThrowFromDef() 760 catch 761 let g:thrown_func = v:exception 762 endtry 763endfunc 764 765def CatchInDef() 766 try 767 ThrowFromDef() 768 catch 769 g:thrown_def = v:exception 770 endtry 771enddef 772 773def ReturnFinally(): string 774 try 775 return 'intry' 776 finall 777 g:in_finally = 'finally' 778 endtry 779 return 'end' 780enddef 781 782def Test_try_catch_nested() 783 CatchInFunc() 784 assert_equal('getout', g:thrown_func) 785 786 CatchInDef() 787 assert_equal('getout', g:thrown_def) 788 789 assert_equal('intry', ReturnFinally()) 790 assert_equal('finally', g:in_finally) 791 792 var l = [] 793 try 794 l->add('1') 795 throw 'bad' 796 l->add('x') 797 catch /bad/ 798 l->add('2') 799 try 800 l->add('3') 801 throw 'one' 802 l->add('x') 803 catch /one/ 804 l->add('4') 805 try 806 l->add('5') 807 throw 'more' 808 l->add('x') 809 catch /more/ 810 l->add('6') 811 endtry 812 endtry 813 endtry 814 assert_equal(['1', '2', '3', '4', '5', '6'], l) 815 816 l = [] 817 try 818 try 819 l->add('1') 820 throw 'foo' 821 l->add('x') 822 catch 823 l->add('2') 824 throw 'bar' 825 l->add('x') 826 finally 827 l->add('3') 828 endtry 829 l->add('x') 830 catch /bar/ 831 l->add('4') 832 endtry 833 assert_equal(['1', '2', '3', '4'], l) 834enddef 835 836def TryOne(): number 837 try 838 return 0 839 catch 840 endtry 841 return 0 842enddef 843 844def TryTwo(n: number): string 845 try 846 var x = {} 847 catch 848 endtry 849 return 'text' 850enddef 851 852def Test_try_catch_twice() 853 assert_equal('text', TryOne()->TryTwo()) 854enddef 855 856def Test_try_catch_match() 857 var seq = 'a' 858 try 859 throw 'something' 860 catch /nothing/ 861 seq ..= 'x' 862 catch /some/ 863 seq ..= 'b' 864 catch /asdf/ 865 seq ..= 'x' 866 catch ?a\?sdf? 867 seq ..= 'y' 868 finally 869 seq ..= 'c' 870 endtry 871 assert_equal('abc', seq) 872enddef 873 874def Test_try_catch_fails() 875 CheckDefFailure(['catch'], 'E603:') 876 CheckDefFailure(['try', 'echo 0', 'catch', 'catch'], 'E1033:') 877 CheckDefFailure(['try', 'echo 0', 'catch /pat'], 'E1067:') 878 CheckDefFailure(['finally'], 'E606:') 879 CheckDefFailure(['try', 'echo 0', 'finally', 'echo 1', 'finally'], 'E607:') 880 CheckDefFailure(['endtry'], 'E602:') 881 CheckDefFailure(['while 1', 'endtry'], 'E170:') 882 CheckDefFailure(['for i in range(5)', 'endtry'], 'E170:') 883 CheckDefFailure(['if 1', 'endtry'], 'E171:') 884 CheckDefFailure(['try', 'echo 1', 'endtry'], 'E1032:') 885 886 CheckDefFailure(['throw'], 'E1143:') 887 CheckDefFailure(['throw xxx'], 'E1001:') 888enddef 889 890def Try_catch_skipped() 891 var l = [] 892 try 893 finally 894 endtry 895 896 if 1 897 else 898 try 899 endtry 900 endif 901enddef 902 903" The skipped try/endtry was updating the wrong instruction. 904def Test_try_catch_skipped() 905 var instr = execute('disassemble Try_catch_skipped') 906 assert_match("NEWLIST size 0\n", instr) 907enddef 908 909 910 911def Test_throw_vimscript() 912 # only checks line continuation 913 var lines =<< trim END 914 vim9script 915 try 916 throw 'one' 917 .. 'two' 918 catch 919 assert_equal('onetwo', v:exception) 920 endtry 921 END 922 CheckScriptSuccess(lines) 923 924 lines =<< trim END 925 vim9script 926 @r = '' 927 def Func() 928 throw @r 929 enddef 930 var result = '' 931 try 932 Func() 933 catch /E1129:/ 934 result = 'caught' 935 endtry 936 assert_equal('caught', result) 937 END 938 CheckScriptSuccess(lines) 939enddef 940 941def Test_error_in_nested_function() 942 # an error in a nested :function aborts executing in the calling :def function 943 var lines =<< trim END 944 vim9script 945 def Func() 946 Error() 947 g:test_var = 1 948 enddef 949 func Error() abort 950 eval [][0] 951 endfunc 952 Func() 953 END 954 g:test_var = 0 955 CheckScriptFailure(lines, 'E684:') 956 assert_equal(0, g:test_var) 957enddef 958 959def Test_abort_after_error() 960 var lines =<< trim END 961 vim9script 962 while true 963 echo notfound 964 endwhile 965 g:gotthere = true 966 END 967 g:gotthere = false 968 CheckScriptFailure(lines, 'E121:') 969 assert_false(g:gotthere) 970 unlet g:gotthere 971enddef 972 973def Test_cexpr_vimscript() 974 # only checks line continuation 975 set errorformat=File\ %f\ line\ %l 976 var lines =<< trim END 977 vim9script 978 cexpr 'File' 979 .. ' someFile' .. 980 ' line 19' 981 assert_equal(19, getqflist()[0].lnum) 982 END 983 CheckScriptSuccess(lines) 984 set errorformat& 985enddef 986 987def Test_statusline_syntax() 988 # legacy syntax is used for 'statusline' 989 var lines =<< trim END 990 vim9script 991 func g:Status() 992 return '%{"x" is# "x"}' 993 endfunc 994 set laststatus=2 statusline=%!Status() 995 redrawstatus 996 set laststatus statusline= 997 END 998 CheckScriptSuccess(lines) 999enddef 1000 1001def Test_list_vimscript() 1002 # checks line continuation and comments 1003 var lines =<< trim END 1004 vim9script 1005 var mylist = [ 1006 'one', 1007 # comment 1008 'two', # empty line follows 1009 1010 'three', 1011 ] 1012 assert_equal(['one', 'two', 'three'], mylist) 1013 END 1014 CheckScriptSuccess(lines) 1015 1016 # check all lines from heredoc are kept 1017 lines =<< trim END 1018 # comment 1 1019 two 1020 # comment 3 1021 1022 five 1023 # comment 6 1024 END 1025 assert_equal(['# comment 1', 'two', '# comment 3', '', 'five', '# comment 6'], lines) 1026 1027 lines =<< trim END 1028 [{ 1029 a: 0}]->string()->assert_equal("[{'a': 0}]") 1030 END 1031 CheckDefAndScriptSuccess(lines) 1032enddef 1033 1034if has('channel') 1035 let someJob = test_null_job() 1036 1037 def FuncWithError() 1038 echomsg g:someJob 1039 enddef 1040 1041 func Test_convert_emsg_to_exception() 1042 try 1043 call FuncWithError() 1044 catch 1045 call assert_match('Vim:E908:', v:exception) 1046 endtry 1047 endfunc 1048endif 1049 1050let s:export_script_lines =<< trim END 1051 vim9script 1052 var name: string = 'bob' 1053 def Concat(arg: string): string 1054 return name .. arg 1055 enddef 1056 g:result = Concat('bie') 1057 g:localname = name 1058 1059 export const CONST = 1234 1060 export var exported = 9876 1061 export var exp_name = 'John' 1062 export def Exported(): string 1063 return 'Exported' 1064 enddef 1065 export def ExportedValue(): number 1066 return exported 1067 enddef 1068 export def ExportedInc() 1069 exported += 5 1070 enddef 1071 export final theList = [1] 1072END 1073 1074def Undo_export_script_lines() 1075 unlet g:result 1076 unlet g:localname 1077enddef 1078 1079def Test_vim9_import_export() 1080 var import_script_lines =<< trim END 1081 vim9script 1082 import {exported, Exported, ExportedValue} from './Xexport.vim' 1083 g:exported1 = exported 1084 exported += 3 1085 g:exported2 = exported 1086 g:exported3 = ExportedValue() 1087 1088 import ExportedInc from './Xexport.vim' 1089 ExportedInc() 1090 g:exported_i1 = exported 1091 g:exported_i2 = ExportedValue() 1092 1093 exported = 11 1094 g:exported_s1 = exported 1095 g:exported_s2 = ExportedValue() 1096 1097 g:imported_func = Exported() 1098 1099 def GetExported(): string 1100 var local_dict = {ref: Exported} 1101 return local_dict.ref() 1102 enddef 1103 g:funcref_result = GetExported() 1104 1105 var dir = './' 1106 var ext = ".vim" 1107 import {exp_name} from dir .. 'Xexport' .. ext 1108 g:imported_name = exp_name 1109 exp_name ..= ' Doe' 1110 g:imported_name_appended = exp_name 1111 g:exported_later = exported 1112 1113 import theList from './Xexport.vim' 1114 theList->add(2) 1115 assert_equal([1, 2], theList) 1116 END 1117 1118 writefile(import_script_lines, 'Ximport.vim') 1119 writefile(s:export_script_lines, 'Xexport.vim') 1120 1121 source Ximport.vim 1122 1123 assert_equal('bobbie', g:result) 1124 assert_equal('bob', g:localname) 1125 assert_equal(9876, g:exported1) 1126 assert_equal(9879, g:exported2) 1127 assert_equal(9879, g:exported3) 1128 1129 assert_equal(9884, g:exported_i1) 1130 assert_equal(9884, g:exported_i2) 1131 1132 assert_equal(11, g:exported_s1) 1133 assert_equal(11, g:exported_s2) 1134 assert_equal(11, g:exported_later) 1135 1136 assert_equal('Exported', g:imported_func) 1137 assert_equal('Exported', g:funcref_result) 1138 assert_equal('John', g:imported_name) 1139 assert_equal('John Doe', g:imported_name_appended) 1140 assert_false(exists('g:name')) 1141 1142 Undo_export_script_lines() 1143 unlet g:exported1 1144 unlet g:exported2 1145 unlet g:exported3 1146 unlet g:exported_i1 1147 unlet g:exported_i2 1148 unlet g:exported_later 1149 unlet g:imported_func 1150 unlet g:imported_name g:imported_name_appended 1151 delete('Ximport.vim') 1152 1153 # similar, with line breaks 1154 var import_line_break_script_lines =<< trim END 1155 vim9script 1156 import { 1157 exported, 1158 Exported, 1159 } 1160 from 1161 './Xexport.vim' 1162 g:exported = exported 1163 exported += 7 1164 g:exported_added = exported 1165 g:imported_func = Exported() 1166 END 1167 writefile(import_line_break_script_lines, 'Ximport_lbr.vim') 1168 source Ximport_lbr.vim 1169 1170 assert_equal(11, g:exported) 1171 assert_equal(18, g:exported_added) 1172 assert_equal('Exported', g:imported_func) 1173 1174 # exported script not sourced again 1175 assert_false(exists('g:result')) 1176 unlet g:exported 1177 unlet g:exported_added 1178 unlet g:imported_func 1179 delete('Ximport_lbr.vim') 1180 1181 var import_star_as_lines =<< trim END 1182 vim9script 1183 import * as Export from './Xexport.vim' 1184 def UseExport() 1185 g:exported_def = Export.exported 1186 enddef 1187 g:exported_script = Export.exported 1188 assert_equal(1, exists('Export.exported')) 1189 assert_equal(0, exists('Export.notexported')) 1190 UseExport() 1191 END 1192 writefile(import_star_as_lines, 'Ximport.vim') 1193 source Ximport.vim 1194 1195 assert_equal(18, g:exported_def) 1196 assert_equal(18, g:exported_script) 1197 unlet g:exported_def 1198 unlet g:exported_script 1199 1200 var import_star_as_lines_no_dot =<< trim END 1201 vim9script 1202 import * as Export from './Xexport.vim' 1203 def Func() 1204 var dummy = 1 1205 var imported = Export + dummy 1206 enddef 1207 defcompile 1208 END 1209 writefile(import_star_as_lines_no_dot, 'Ximport.vim') 1210 assert_fails('source Ximport.vim', 'E1060:', '', 2, 'Func') 1211 1212 var import_star_as_lines_dot_space =<< trim END 1213 vim9script 1214 import * as Export from './Xexport.vim' 1215 def Func() 1216 var imported = Export . exported 1217 enddef 1218 defcompile 1219 END 1220 writefile(import_star_as_lines_dot_space, 'Ximport.vim') 1221 assert_fails('source Ximport.vim', 'E1074:', '', 1, 'Func') 1222 1223 var import_star_as_duplicated =<< trim END 1224 vim9script 1225 import * as Export from './Xexport.vim' 1226 var some = 'other' 1227 import * as Export from './Xexport.vim' 1228 defcompile 1229 END 1230 writefile(import_star_as_duplicated, 'Ximport.vim') 1231 assert_fails('source Ximport.vim', 'E1073:', '', 4, 'Ximport.vim') 1232 1233 var import_star_as_lines_script_no_dot =<< trim END 1234 vim9script 1235 import * as Export from './Xexport.vim' 1236 g:imported_script = Export exported 1237 END 1238 writefile(import_star_as_lines_script_no_dot, 'Ximport.vim') 1239 assert_fails('source Ximport.vim', 'E1029:') 1240 1241 var import_star_as_lines_script_space_after_dot =<< trim END 1242 vim9script 1243 import * as Export from './Xexport.vim' 1244 g:imported_script = Export. exported 1245 END 1246 writefile(import_star_as_lines_script_space_after_dot, 'Ximport.vim') 1247 assert_fails('source Ximport.vim', 'E1074:') 1248 1249 var import_star_as_lines_missing_name =<< trim END 1250 vim9script 1251 import * as Export from './Xexport.vim' 1252 def Func() 1253 var imported = Export. 1254 enddef 1255 defcompile 1256 END 1257 writefile(import_star_as_lines_missing_name, 'Ximport.vim') 1258 assert_fails('source Ximport.vim', 'E1048:', '', 1, 'Func') 1259 1260 var import_star_as_lbr_lines =<< trim END 1261 vim9script 1262 import * 1263 as Export 1264 from 1265 './Xexport.vim' 1266 def UseExport() 1267 g:exported = Export.exported 1268 enddef 1269 UseExport() 1270 END 1271 writefile(import_star_as_lbr_lines, 'Ximport.vim') 1272 source Ximport.vim 1273 assert_equal(18, g:exported) 1274 unlet g:exported 1275 1276 var import_star_lines =<< trim END 1277 vim9script 1278 import * from './Xexport.vim' 1279 END 1280 writefile(import_star_lines, 'Ximport.vim') 1281 assert_fails('source Ximport.vim', 'E1045:', '', 2, 'Ximport.vim') 1282 1283 # try to import something that exists but is not exported 1284 var import_not_exported_lines =<< trim END 1285 vim9script 1286 import name from './Xexport.vim' 1287 END 1288 writefile(import_not_exported_lines, 'Ximport.vim') 1289 assert_fails('source Ximport.vim', 'E1049:', '', 2, 'Ximport.vim') 1290 1291 # try to import something that is already defined 1292 var import_already_defined =<< trim END 1293 vim9script 1294 var exported = 'something' 1295 import exported from './Xexport.vim' 1296 END 1297 writefile(import_already_defined, 'Ximport.vim') 1298 assert_fails('source Ximport.vim', 'E1054:', '', 3, 'Ximport.vim') 1299 1300 # try to import something that is already defined 1301 import_already_defined =<< trim END 1302 vim9script 1303 var exported = 'something' 1304 import * as exported from './Xexport.vim' 1305 END 1306 writefile(import_already_defined, 'Ximport.vim') 1307 assert_fails('source Ximport.vim', 'E1054:', '', 3, 'Ximport.vim') 1308 1309 # try to import something that is already defined 1310 import_already_defined =<< trim END 1311 vim9script 1312 var exported = 'something' 1313 import {exported} from './Xexport.vim' 1314 END 1315 writefile(import_already_defined, 'Ximport.vim') 1316 assert_fails('source Ximport.vim', 'E1054:', '', 3, 'Ximport.vim') 1317 1318 # try changing an imported const 1319 var import_assign_to_const =<< trim END 1320 vim9script 1321 import CONST from './Xexport.vim' 1322 def Assign() 1323 CONST = 987 1324 enddef 1325 defcompile 1326 END 1327 writefile(import_assign_to_const, 'Ximport.vim') 1328 assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign') 1329 1330 # try changing an imported final 1331 var import_assign_to_final =<< trim END 1332 vim9script 1333 import theList from './Xexport.vim' 1334 def Assign() 1335 theList = [2] 1336 enddef 1337 defcompile 1338 END 1339 writefile(import_assign_to_final, 'Ximport.vim') 1340 assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign') 1341 1342 # import a very long name, requires making a copy 1343 var import_long_name_lines =<< trim END 1344 vim9script 1345 import name012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 from './Xexport.vim' 1346 END 1347 writefile(import_long_name_lines, 'Ximport.vim') 1348 assert_fails('source Ximport.vim', 'E1048:', '', 2, 'Ximport.vim') 1349 1350 var import_no_from_lines =<< trim END 1351 vim9script 1352 import name './Xexport.vim' 1353 END 1354 writefile(import_no_from_lines, 'Ximport.vim') 1355 assert_fails('source Ximport.vim', 'E1070:', '', 2, 'Ximport.vim') 1356 1357 var import_invalid_string_lines =<< trim END 1358 vim9script 1359 import name from Xexport.vim 1360 END 1361 writefile(import_invalid_string_lines, 'Ximport.vim') 1362 assert_fails('source Ximport.vim', 'E121:', '', 2, 'Ximport.vim') 1363 1364 var import_wrong_name_lines =<< trim END 1365 vim9script 1366 import name from './XnoExport.vim' 1367 END 1368 writefile(import_wrong_name_lines, 'Ximport.vim') 1369 assert_fails('source Ximport.vim', 'E1053:', '', 2, 'Ximport.vim') 1370 1371 var import_missing_comma_lines =<< trim END 1372 vim9script 1373 import {exported name} from './Xexport.vim' 1374 END 1375 writefile(import_missing_comma_lines, 'Ximport3.vim') 1376 assert_fails('source Ximport3.vim', 'E1046:', '', 2, 'Ximport3.vim') 1377 1378 delete('Ximport.vim') 1379 delete('Ximport3.vim') 1380 delete('Xexport.vim') 1381 1382 # Check that in a Vim9 script 'cpo' is set to the Vim default. 1383 # Flags added or removed are also applied to the restored value. 1384 set cpo=abcd 1385 var lines =<< trim END 1386 vim9script 1387 g:cpo_in_vim9script = &cpo 1388 set cpo+=f 1389 set cpo-=c 1390 g:cpo_after_vim9script = &cpo 1391 END 1392 writefile(lines, 'Xvim9_script') 1393 source Xvim9_script 1394 assert_equal('fabd', &cpo) 1395 set cpo&vim 1396 assert_equal(&cpo, g:cpo_in_vim9script) 1397 var newcpo = substitute(&cpo, 'c', '', '') .. 'f' 1398 assert_equal(newcpo, g:cpo_after_vim9script) 1399 1400 delete('Xvim9_script') 1401enddef 1402 1403def Test_import_as() 1404 var export_lines =<< trim END 1405 vim9script 1406 export var one = 1 1407 export var yes = 'yes' 1408 export var slist: list<string> 1409 END 1410 writefile(export_lines, 'XexportAs') 1411 1412 var import_lines =<< trim END 1413 vim9script 1414 var one = 'notused' 1415 var yes = 777 1416 import one as thatOne from './XexportAs' 1417 assert_equal(1, thatOne) 1418 import yes as yesYes from './XexportAs' 1419 assert_equal('yes', yesYes) 1420 END 1421 CheckScriptSuccess(import_lines) 1422 1423 import_lines =<< trim END 1424 vim9script 1425 import {one as thatOne, yes as yesYes} from './XexportAs' 1426 assert_equal(1, thatOne) 1427 assert_equal('yes', yesYes) 1428 assert_fails('echo one', 'E121:') 1429 assert_fails('echo yes', 'E121:') 1430 END 1431 CheckScriptSuccess(import_lines) 1432 1433 import_lines =<< trim END 1434 vim9script 1435 import {slist as impSlist} from './XexportAs' 1436 impSlist->add(123) 1437 END 1438 CheckScriptFailure(import_lines, 'E1012: Type mismatch; expected string but got number') 1439 1440 delete('XexportAs') 1441enddef 1442 1443func g:Trigger() 1444 source Ximport.vim 1445 return "echo 'yes'\<CR>" 1446endfunc 1447 1448def Test_import_export_expr_map() 1449 # check that :import and :export work when buffer is locked 1450 var export_lines =<< trim END 1451 vim9script 1452 export def That(): string 1453 return 'yes' 1454 enddef 1455 END 1456 writefile(export_lines, 'Xexport_that.vim') 1457 1458 var import_lines =<< trim END 1459 vim9script 1460 import That from './Xexport_that.vim' 1461 assert_equal('yes', That()) 1462 END 1463 writefile(import_lines, 'Ximport.vim') 1464 1465 nnoremap <expr> trigger g:Trigger() 1466 feedkeys('trigger', "xt") 1467 1468 delete('Xexport_that.vim') 1469 delete('Ximport.vim') 1470 nunmap trigger 1471enddef 1472 1473def Test_import_in_filetype() 1474 # check that :import works when the buffer is locked 1475 mkdir('ftplugin', 'p') 1476 var export_lines =<< trim END 1477 vim9script 1478 export var That = 'yes' 1479 END 1480 writefile(export_lines, 'ftplugin/Xexport_ft.vim') 1481 1482 var import_lines =<< trim END 1483 vim9script 1484 import That from './Xexport_ft.vim' 1485 assert_equal('yes', That) 1486 g:did_load_mytpe = 1 1487 END 1488 writefile(import_lines, 'ftplugin/qf.vim') 1489 1490 var save_rtp = &rtp 1491 &rtp = getcwd() .. ',' .. &rtp 1492 1493 filetype plugin on 1494 copen 1495 assert_equal(1, g:did_load_mytpe) 1496 1497 quit! 1498 delete('Xexport_ft.vim') 1499 delete('ftplugin', 'rf') 1500 &rtp = save_rtp 1501enddef 1502 1503def Test_use_import_in_mapping() 1504 var lines =<< trim END 1505 vim9script 1506 export def Funcx() 1507 g:result = 42 1508 enddef 1509 END 1510 writefile(lines, 'XsomeExport.vim') 1511 lines =<< trim END 1512 vim9script 1513 import Funcx from './XsomeExport.vim' 1514 nnoremap <F3> :call <sid>Funcx()<cr> 1515 END 1516 writefile(lines, 'Xmapscript.vim') 1517 1518 source Xmapscript.vim 1519 feedkeys("\<F3>", "xt") 1520 assert_equal(42, g:result) 1521 1522 unlet g:result 1523 delete('XsomeExport.vim') 1524 delete('Xmapscript.vim') 1525 nunmap <F3> 1526enddef 1527 1528def Test_vim9script_mix() 1529 var lines =<< trim END 1530 if has(g:feature) 1531 " legacy script 1532 let g:legacy = 1 1533 finish 1534 endif 1535 vim9script 1536 g:legacy = 0 1537 END 1538 g:feature = 'eval' 1539 g:legacy = -1 1540 CheckScriptSuccess(lines) 1541 assert_equal(1, g:legacy) 1542 1543 g:feature = 'noteval' 1544 g:legacy = -1 1545 CheckScriptSuccess(lines) 1546 assert_equal(0, g:legacy) 1547enddef 1548 1549def Test_vim9script_fails() 1550 CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:') 1551 CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:') 1552 CheckScriptFailure(['export var some = 123'], 'E1042:') 1553 CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1048:') 1554 CheckScriptFailure(['vim9script', 'export var g:some'], 'E1022:') 1555 CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:') 1556 1557 CheckScriptFailure(['vim9script', 'var str: string', 'str = 1234'], 'E1012:') 1558 CheckScriptFailure(['vim9script', 'const str = "asdf"', 'str = "xxx"'], 'E46:') 1559 1560 assert_fails('vim9script', 'E1038:') 1561 assert_fails('export something', 'E1043:') 1562enddef 1563 1564func Test_import_fails_without_script() 1565 CheckRunVimInTerminal 1566 1567 " call indirectly to avoid compilation error for missing functions 1568 call Run_Test_import_fails_on_command_line() 1569endfunc 1570 1571def Run_Test_import_fails_on_command_line() 1572 var export =<< trim END 1573 vim9script 1574 export def Foo(): number 1575 return 0 1576 enddef 1577 END 1578 writefile(export, 'XexportCmd.vim') 1579 1580 var buf = RunVimInTerminal('-c "import Foo from ''./XexportCmd.vim''"', { 1581 rows: 6, wait_for_ruler: 0}) 1582 WaitForAssert(() => assert_match('^E1094:', term_getline(buf, 5))) 1583 1584 delete('XexportCmd.vim') 1585 StopVimInTerminal(buf) 1586enddef 1587 1588def Test_vim9script_reload_noclear() 1589 var lines =<< trim END 1590 vim9script 1591 export var exported = 'thexport' 1592 END 1593 writefile(lines, 'XExportReload') 1594 lines =<< trim END 1595 vim9script noclear 1596 g:loadCount += 1 1597 var s:reloaded = 'init' 1598 import exported from './XExportReload' 1599 1600 def Again(): string 1601 return 'again' 1602 enddef 1603 1604 if exists('s:loaded') | finish | endif 1605 var s:loaded = true 1606 1607 var s:notReloaded = 'yes' 1608 s:reloaded = 'first' 1609 def g:Values(): list<string> 1610 return [s:reloaded, s:notReloaded, Again(), Once(), exported] 1611 enddef 1612 1613 def Once(): string 1614 return 'once' 1615 enddef 1616 END 1617 writefile(lines, 'XReloaded') 1618 g:loadCount = 0 1619 source XReloaded 1620 assert_equal(1, g:loadCount) 1621 assert_equal(['first', 'yes', 'again', 'once', 'thexport'], g:Values()) 1622 source XReloaded 1623 assert_equal(2, g:loadCount) 1624 assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values()) 1625 source XReloaded 1626 assert_equal(3, g:loadCount) 1627 assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values()) 1628 1629 delete('XReloaded') 1630 delete('XExportReload') 1631 delfunc g:Values 1632 unlet g:loadCount 1633 1634 lines =<< trim END 1635 vim9script 1636 def Inner() 1637 enddef 1638 END 1639 lines->writefile('XreloadScript.vim') 1640 source XreloadScript.vim 1641 1642 lines =<< trim END 1643 vim9script 1644 def Outer() 1645 def Inner() 1646 enddef 1647 enddef 1648 defcompile 1649 END 1650 lines->writefile('XreloadScript.vim') 1651 source XreloadScript.vim 1652 1653 delete('XreloadScript.vim') 1654enddef 1655 1656def Test_vim9script_reload_import() 1657 var lines =<< trim END 1658 vim9script 1659 const var = '' 1660 var valone = 1234 1661 def MyFunc(arg: string) 1662 valone = 5678 1663 enddef 1664 END 1665 var morelines =<< trim END 1666 var valtwo = 222 1667 export def GetValtwo(): number 1668 return valtwo 1669 enddef 1670 END 1671 writefile(lines + morelines, 'Xreload.vim') 1672 source Xreload.vim 1673 source Xreload.vim 1674 source Xreload.vim 1675 1676 # cannot declare a var twice 1677 lines =<< trim END 1678 vim9script 1679 var valone = 1234 1680 var valone = 5678 1681 END 1682 writefile(lines, 'Xreload.vim') 1683 assert_fails('source Xreload.vim', 'E1041:', '', 3, 'Xreload.vim') 1684 1685 delete('Xreload.vim') 1686 delete('Ximport.vim') 1687enddef 1688 1689" if a script is reloaded with a script-local variable that changed its type, a 1690" compiled function using that variable must fail. 1691def Test_script_reload_change_type() 1692 var lines =<< trim END 1693 vim9script noclear 1694 var str = 'string' 1695 def g:GetStr(): string 1696 return str .. 'xxx' 1697 enddef 1698 END 1699 writefile(lines, 'Xreload.vim') 1700 source Xreload.vim 1701 echo g:GetStr() 1702 1703 lines =<< trim END 1704 vim9script noclear 1705 var str = 1234 1706 END 1707 writefile(lines, 'Xreload.vim') 1708 source Xreload.vim 1709 assert_fails('echo g:GetStr()', 'E1150:') 1710 1711 delfunc g:GetStr 1712 delete('Xreload.vim') 1713enddef 1714 1715" Define CallFunc so that the test can be compiled 1716command CallFunc echo 'nop' 1717 1718def Test_script_reload_from_function() 1719 var lines =<< trim END 1720 vim9script 1721 1722 if exists('g:loaded') 1723 finish 1724 endif 1725 g:loaded = 1 1726 delcommand CallFunc 1727 command CallFunc Func() 1728 def Func() 1729 so XreloadFunc.vim 1730 g:didTheFunc = 1 1731 enddef 1732 END 1733 writefile(lines, 'XreloadFunc.vim') 1734 source XreloadFunc.vim 1735 CallFunc 1736 assert_equal(1, g:didTheFunc) 1737 1738 delete('XreloadFunc.vim') 1739 delcommand CallFunc 1740 unlet g:loaded 1741 unlet g:didTheFunc 1742enddef 1743 1744def Test_script_var_shadows_function() 1745 var lines =<< trim END 1746 vim9script 1747 def Func(): number 1748 return 123 1749 enddef 1750 var Func = 1 1751 END 1752 CheckScriptFailure(lines, 'E1041:', 5) 1753enddef 1754 1755def Test_script_var_shadows_command() 1756 var lines =<< trim END 1757 var undo = 1 1758 undo = 2 1759 assert_equal(2, undo) 1760 END 1761 CheckDefAndScriptSuccess(lines) 1762 1763 lines =<< trim END 1764 var undo = 1 1765 undo 1766 END 1767 CheckDefAndScriptFailure(lines, 'E1207:', 2) 1768enddef 1769 1770def s:RetSome(): string 1771 return 'some' 1772enddef 1773 1774" Not exported function that is referenced needs to be accessed by the 1775" script-local name. 1776def Test_vim9script_funcref() 1777 var sortlines =<< trim END 1778 vim9script 1779 def Compare(i1: number, i2: number): number 1780 return i2 - i1 1781 enddef 1782 1783 export def FastSort(): list<number> 1784 return range(5)->sort(Compare) 1785 enddef 1786 1787 export def GetString(arg: string): string 1788 return arg 1789 enddef 1790 END 1791 writefile(sortlines, 'Xsort.vim') 1792 1793 var lines =<< trim END 1794 vim9script 1795 import FastSort from './Xsort.vim' 1796 def Test() 1797 g:result = FastSort() 1798 enddef 1799 Test() 1800 1801 # using a function imported with "as" 1802 import * as anAlias from './Xsort.vim' 1803 assert_equal('yes', anAlias.GetString('yes')) 1804 1805 # using the function from a compiled function 1806 def TestMore(): string 1807 var s = s:anAlias.GetString('foo') 1808 return s .. anAlias.GetString('bar') 1809 enddef 1810 assert_equal('foobar', TestMore()) 1811 1812 # error when using a function that isn't exported 1813 assert_fails('anAlias.Compare(1, 2)', 'E1049:') 1814 END 1815 writefile(lines, 'Xscript.vim') 1816 1817 source Xscript.vim 1818 assert_equal([4, 3, 2, 1, 0], g:result) 1819 1820 unlet g:result 1821 delete('Xsort.vim') 1822 delete('Xscript.vim') 1823 1824 var Funcref = function('s:RetSome') 1825 assert_equal('some', Funcref()) 1826enddef 1827 1828" Check that when searching for "FilterFunc" it finds the import in the 1829" script where FastFilter() is called from, both as a string and as a direct 1830" function reference. 1831def Test_vim9script_funcref_other_script() 1832 var filterLines =<< trim END 1833 vim9script 1834 export def FilterFunc(idx: number, val: number): bool 1835 return idx % 2 == 1 1836 enddef 1837 export def FastFilter(): list<number> 1838 return range(10)->filter('FilterFunc') 1839 enddef 1840 export def FastFilterDirect(): list<number> 1841 return range(10)->filter(FilterFunc) 1842 enddef 1843 END 1844 writefile(filterLines, 'Xfilter.vim') 1845 1846 var lines =<< trim END 1847 vim9script 1848 import {FilterFunc, FastFilter, FastFilterDirect} from './Xfilter.vim' 1849 def Test() 1850 var x: list<number> = FastFilter() 1851 enddef 1852 Test() 1853 def TestDirect() 1854 var x: list<number> = FastFilterDirect() 1855 enddef 1856 TestDirect() 1857 END 1858 CheckScriptSuccess(lines) 1859 delete('Xfilter.vim') 1860enddef 1861 1862def Test_vim9script_reload_delfunc() 1863 var first_lines =<< trim END 1864 vim9script 1865 def FuncYes(): string 1866 return 'yes' 1867 enddef 1868 END 1869 var withno_lines =<< trim END 1870 def FuncNo(): string 1871 return 'no' 1872 enddef 1873 def g:DoCheck(no_exists: bool) 1874 assert_equal('yes', FuncYes()) 1875 assert_equal('no', FuncNo()) 1876 enddef 1877 END 1878 var nono_lines =<< trim END 1879 def g:DoCheck(no_exists: bool) 1880 assert_equal('yes', FuncYes()) 1881 assert_fails('FuncNo()', 'E117:', '', 2, 'DoCheck') 1882 enddef 1883 END 1884 1885 # FuncNo() is defined 1886 writefile(first_lines + withno_lines, 'Xreloaded.vim') 1887 source Xreloaded.vim 1888 g:DoCheck(true) 1889 1890 # FuncNo() is not redefined 1891 writefile(first_lines + nono_lines, 'Xreloaded.vim') 1892 source Xreloaded.vim 1893 g:DoCheck(false) 1894 1895 # FuncNo() is back 1896 writefile(first_lines + withno_lines, 'Xreloaded.vim') 1897 source Xreloaded.vim 1898 g:DoCheck(false) 1899 1900 delete('Xreloaded.vim') 1901enddef 1902 1903def Test_vim9script_reload_delvar() 1904 # write the script with a script-local variable 1905 var lines =<< trim END 1906 vim9script 1907 var name = 'string' 1908 END 1909 writefile(lines, 'XreloadVar.vim') 1910 source XreloadVar.vim 1911 1912 # now write the script using the same variable locally - works 1913 lines =<< trim END 1914 vim9script 1915 def Func() 1916 var name = 'string' 1917 enddef 1918 END 1919 writefile(lines, 'XreloadVar.vim') 1920 source XreloadVar.vim 1921 1922 delete('XreloadVar.vim') 1923enddef 1924 1925def Test_import_absolute() 1926 var import_lines = [ 1927 'vim9script', 1928 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"', 1929 'def UseExported()', 1930 ' g:imported_abs = exported', 1931 ' exported = 8888', 1932 ' g:imported_after = exported', 1933 'enddef', 1934 'UseExported()', 1935 'g:import_disassembled = execute("disass UseExported")', 1936 ] 1937 writefile(import_lines, 'Ximport_abs.vim') 1938 writefile(s:export_script_lines, 'Xexport_abs.vim') 1939 1940 source Ximport_abs.vim 1941 1942 assert_equal(9876, g:imported_abs) 1943 assert_equal(8888, g:imported_after) 1944 assert_match('<SNR>\d\+_UseExported\_s*' .. 1945 'g:imported_abs = exported\_s*' .. 1946 '0 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' .. 1947 '1 STOREG g:imported_abs\_s*' .. 1948 'exported = 8888\_s*' .. 1949 '2 PUSHNR 8888\_s*' .. 1950 '3 STORESCRIPT exported-2 in .*Xexport_abs.vim\_s*' .. 1951 'g:imported_after = exported\_s*' .. 1952 '4 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' .. 1953 '5 STOREG g:imported_after', 1954 g:import_disassembled) 1955 1956 Undo_export_script_lines() 1957 unlet g:imported_abs 1958 unlet g:import_disassembled 1959 1960 delete('Ximport_abs.vim') 1961 delete('Xexport_abs.vim') 1962enddef 1963 1964def Test_import_rtp() 1965 var import_lines = [ 1966 'vim9script', 1967 'import exported from "Xexport_rtp.vim"', 1968 'g:imported_rtp = exported', 1969 ] 1970 writefile(import_lines, 'Ximport_rtp.vim') 1971 mkdir('import', 'p') 1972 writefile(s:export_script_lines, 'import/Xexport_rtp.vim') 1973 1974 var save_rtp = &rtp 1975 &rtp = getcwd() 1976 source Ximport_rtp.vim 1977 &rtp = save_rtp 1978 1979 assert_equal(9876, g:imported_rtp) 1980 1981 Undo_export_script_lines() 1982 unlet g:imported_rtp 1983 delete('Ximport_rtp.vim') 1984 delete('import', 'rf') 1985enddef 1986 1987def Test_import_compile_error() 1988 var export_lines = [ 1989 'vim9script', 1990 'export def ExpFunc(): string', 1991 ' return notDefined', 1992 'enddef', 1993 ] 1994 writefile(export_lines, 'Xexported.vim') 1995 1996 var import_lines = [ 1997 'vim9script', 1998 'import ExpFunc from "./Xexported.vim"', 1999 'def ImpFunc()', 2000 ' echo ExpFunc()', 2001 'enddef', 2002 'defcompile', 2003 ] 2004 writefile(import_lines, 'Ximport.vim') 2005 2006 try 2007 source Ximport.vim 2008 catch /E1001/ 2009 # Error should be fore the Xexported.vim file. 2010 assert_match('E1001: Variable not found: notDefined', v:exception) 2011 assert_match('function <SNR>\d\+_ImpFunc\[1\]..<SNR>\d\+_ExpFunc, line 1', v:throwpoint) 2012 endtry 2013 2014 delete('Xexported.vim') 2015 delete('Ximport.vim') 2016enddef 2017 2018def Test_func_redefine_error() 2019 var lines = [ 2020 'vim9script', 2021 'def Func()', 2022 ' eval [][0]', 2023 'enddef', 2024 'Func()', 2025 ] 2026 writefile(lines, 'Xtestscript.vim') 2027 2028 for count in range(3) 2029 try 2030 source Xtestscript.vim 2031 catch /E684/ 2032 # function name should contain <SNR> every time 2033 assert_match('E684: list index out of range', v:exception) 2034 assert_match('function <SNR>\d\+_Func, line 1', v:throwpoint) 2035 endtry 2036 endfor 2037 2038 delete('Xtestscript.vim') 2039enddef 2040 2041def Test_func_overrules_import_fails() 2042 var export_lines =<< trim END 2043 vim9script 2044 export def Func() 2045 echo 'imported' 2046 enddef 2047 END 2048 writefile(export_lines, 'XexportedFunc.vim') 2049 2050 var lines =<< trim END 2051 vim9script 2052 import Func from './XexportedFunc.vim' 2053 def Func() 2054 echo 'local to function' 2055 enddef 2056 END 2057 CheckScriptFailure(lines, 'E1073:') 2058 2059 lines =<< trim END 2060 vim9script 2061 import Func from './XexportedFunc.vim' 2062 def Outer() 2063 def Func() 2064 echo 'local to function' 2065 enddef 2066 enddef 2067 defcompile 2068 END 2069 CheckScriptFailure(lines, 'E1073:') 2070 2071 delete('XexportedFunc.vim') 2072enddef 2073 2074def Test_func_redefine_fails() 2075 var lines =<< trim END 2076 vim9script 2077 def Func() 2078 echo 'one' 2079 enddef 2080 def Func() 2081 echo 'two' 2082 enddef 2083 END 2084 CheckScriptFailure(lines, 'E1073:') 2085 2086 lines =<< trim END 2087 vim9script 2088 def Foo(): string 2089 return 'foo' 2090 enddef 2091 def Func() 2092 var Foo = {-> 'lambda'} 2093 enddef 2094 defcompile 2095 END 2096 CheckScriptFailure(lines, 'E1073:') 2097enddef 2098 2099def Test_fixed_size_list() 2100 # will be allocated as one piece of memory, check that changes work 2101 var l = [1, 2, 3, 4] 2102 l->remove(0) 2103 l->add(5) 2104 l->insert(99, 1) 2105 assert_equal([2, 99, 3, 4, 5], l) 2106enddef 2107 2108def Test_no_insert_xit() 2109 CheckDefExecFailure(['a = 1'], 'E1100:') 2110 CheckDefExecFailure(['c = 1'], 'E1100:') 2111 CheckDefExecFailure(['i = 1'], 'E1100:') 2112 CheckDefExecFailure(['t = 1'], 'E1100:') 2113 CheckDefExecFailure(['x = 1'], 'E1100:') 2114 2115 CheckScriptFailure(['vim9script', 'a = 1'], 'E488:') 2116 CheckScriptFailure(['vim9script', 'a'], 'E1100:') 2117 CheckScriptFailure(['vim9script', 'c = 1'], 'E488:') 2118 CheckScriptFailure(['vim9script', 'c'], 'E1100:') 2119 CheckScriptFailure(['vim9script', 'i = 1'], 'E488:') 2120 CheckScriptFailure(['vim9script', 'i'], 'E1100:') 2121 CheckScriptFailure(['vim9script', 'o = 1'], 'E1100:') 2122 CheckScriptFailure(['vim9script', 'o'], 'E1100:') 2123 CheckScriptFailure(['vim9script', 't'], 'E1100:') 2124 CheckScriptFailure(['vim9script', 't = 1'], 'E1100:') 2125 CheckScriptFailure(['vim9script', 'x = 1'], 'E1100:') 2126enddef 2127 2128def IfElse(what: number): string 2129 var res = '' 2130 if what == 1 2131 res = "one" 2132 elseif what == 2 2133 res = "two" 2134 else 2135 res = "three" 2136 endif 2137 return res 2138enddef 2139 2140def Test_if_elseif_else() 2141 assert_equal('one', IfElse(1)) 2142 assert_equal('two', IfElse(2)) 2143 assert_equal('three', IfElse(3)) 2144enddef 2145 2146def Test_if_elseif_else_fails() 2147 CheckDefFailure(['elseif true'], 'E582:') 2148 CheckDefFailure(['else'], 'E581:') 2149 CheckDefFailure(['endif'], 'E580:') 2150 CheckDefFailure(['if g:abool', 'elseif xxx'], 'E1001:') 2151 CheckDefFailure(['if true', 'echo 1'], 'E171:') 2152 2153 var lines =<< trim END 2154 var s = '' 2155 if s = '' 2156 endif 2157 END 2158 CheckDefFailure(lines, 'E488:') 2159 2160 lines =<< trim END 2161 var s = '' 2162 if s == '' 2163 elseif s = '' 2164 endif 2165 END 2166 CheckDefFailure(lines, 'E488:') 2167enddef 2168 2169let g:bool_true = v:true 2170let g:bool_false = v:false 2171 2172def Test_if_const_expr() 2173 var res = false 2174 if true ? true : false 2175 res = true 2176 endif 2177 assert_equal(true, res) 2178 2179 g:glob = 2 2180 if false 2181 execute('g:glob = 3') 2182 endif 2183 assert_equal(2, g:glob) 2184 if true 2185 execute('g:glob = 3') 2186 endif 2187 assert_equal(3, g:glob) 2188 2189 res = false 2190 if g:bool_true ? true : false 2191 res = true 2192 endif 2193 assert_equal(true, res) 2194 2195 res = false 2196 if true ? g:bool_true : false 2197 res = true 2198 endif 2199 assert_equal(true, res) 2200 2201 res = false 2202 if true ? true : g:bool_false 2203 res = true 2204 endif 2205 assert_equal(true, res) 2206 2207 res = false 2208 if true ? false : true 2209 res = true 2210 endif 2211 assert_equal(false, res) 2212 2213 res = false 2214 if false ? false : true 2215 res = true 2216 endif 2217 assert_equal(true, res) 2218 2219 res = false 2220 if false ? true : false 2221 res = true 2222 endif 2223 assert_equal(false, res) 2224 2225 res = false 2226 if has('xyz') ? true : false 2227 res = true 2228 endif 2229 assert_equal(false, res) 2230 2231 res = false 2232 if true && true 2233 res = true 2234 endif 2235 assert_equal(true, res) 2236 2237 res = false 2238 if true && false 2239 res = true 2240 endif 2241 assert_equal(false, res) 2242 2243 res = false 2244 if g:bool_true && false 2245 res = true 2246 endif 2247 assert_equal(false, res) 2248 2249 res = false 2250 if true && g:bool_false 2251 res = true 2252 endif 2253 assert_equal(false, res) 2254 2255 res = false 2256 if false && false 2257 res = true 2258 endif 2259 assert_equal(false, res) 2260 2261 res = false 2262 if true || false 2263 res = true 2264 endif 2265 assert_equal(true, res) 2266 2267 res = false 2268 if g:bool_true || false 2269 res = true 2270 endif 2271 assert_equal(true, res) 2272 2273 res = false 2274 if true || g:bool_false 2275 res = true 2276 endif 2277 assert_equal(true, res) 2278 2279 res = false 2280 if false || false 2281 res = true 2282 endif 2283 assert_equal(false, res) 2284 2285 # with constant "false" expression may be invalid so long as the syntax is OK 2286 if false | eval 1 + 2 | endif 2287 if false | eval burp + 234 | endif 2288 if false | echo burp 234 'asd' | endif 2289 if false 2290 burp 2291 endif 2292enddef 2293 2294def Test_if_const_expr_fails() 2295 CheckDefFailure(['if "aaa" == "bbb'], 'E114:') 2296 CheckDefFailure(["if 'aaa' == 'bbb"], 'E115:') 2297 CheckDefFailure(["if has('aaa'"], 'E110:') 2298 CheckDefFailure(["if has('aaa') ? true false"], 'E109:') 2299enddef 2300 2301def RunNested(i: number): number 2302 var x: number = 0 2303 if i % 2 2304 if 1 2305 # comment 2306 else 2307 # comment 2308 endif 2309 x += 1 2310 else 2311 x += 1000 2312 endif 2313 return x 2314enddef 2315 2316def Test_nested_if() 2317 assert_equal(1, RunNested(1)) 2318 assert_equal(1000, RunNested(2)) 2319enddef 2320 2321def Test_execute_cmd() 2322 # missing argument is ignored 2323 execute 2324 execute # comment 2325 2326 new 2327 setline(1, 'default') 2328 execute 'setline(1, "execute-string")' 2329 assert_equal('execute-string', getline(1)) 2330 2331 execute "setline(1, 'execute-string')" 2332 assert_equal('execute-string', getline(1)) 2333 2334 var cmd1 = 'setline(1,' 2335 var cmd2 = '"execute-var")' 2336 execute cmd1 cmd2 # comment 2337 assert_equal('execute-var', getline(1)) 2338 2339 execute cmd1 cmd2 '|setline(1, "execute-var-string")' 2340 assert_equal('execute-var-string', getline(1)) 2341 2342 var cmd_first = 'call ' 2343 var cmd_last = 'setline(1, "execute-var-var")' 2344 execute cmd_first .. cmd_last 2345 assert_equal('execute-var-var', getline(1)) 2346 bwipe! 2347 2348 var n = true 2349 execute 'echomsg' (n ? '"true"' : '"no"') 2350 assert_match('^true$', Screenline(&lines)) 2351 2352 echomsg [1, 2, 3] {a: 1, b: 2} 2353 assert_match('^\[1, 2, 3\] {''a'': 1, ''b'': 2}$', Screenline(&lines)) 2354 2355 CheckDefFailure(['execute xxx'], 'E1001:', 1) 2356 CheckDefExecFailure(['execute "tabnext " .. 8'], 'E475:', 1) 2357 CheckDefFailure(['execute "cmd"# comment'], 'E488:', 1) 2358enddef 2359 2360def Test_execute_cmd_vimscript() 2361 # only checks line continuation 2362 var lines =<< trim END 2363 vim9script 2364 execute 'g:someVar' 2365 .. ' = ' .. 2366 '28' 2367 assert_equal(28, g:someVar) 2368 unlet g:someVar 2369 END 2370 CheckScriptSuccess(lines) 2371enddef 2372 2373def Test_echo_cmd() 2374 echo 'some' # comment 2375 echon 'thing' 2376 assert_match('^something$', Screenline(&lines)) 2377 2378 echo "some" # comment 2379 echon "thing" 2380 assert_match('^something$', Screenline(&lines)) 2381 2382 var str1 = 'some' 2383 var str2 = 'more' 2384 echo str1 str2 2385 assert_match('^some more$', Screenline(&lines)) 2386 2387 CheckDefFailure(['echo "xxx"# comment'], 'E488:') 2388enddef 2389 2390def Test_echomsg_cmd() 2391 echomsg 'some' 'more' # comment 2392 assert_match('^some more$', Screenline(&lines)) 2393 echo 'clear' 2394 :1messages 2395 assert_match('^some more$', Screenline(&lines)) 2396 2397 CheckDefFailure(['echomsg "xxx"# comment'], 'E488:') 2398enddef 2399 2400def Test_echomsg_cmd_vimscript() 2401 # only checks line continuation 2402 var lines =<< trim END 2403 vim9script 2404 echomsg 'here' 2405 .. ' is ' .. 2406 'a message' 2407 assert_match('^here is a message$', Screenline(&lines)) 2408 END 2409 CheckScriptSuccess(lines) 2410enddef 2411 2412def Test_echoerr_cmd() 2413 try 2414 echoerr 'something' 'wrong' # comment 2415 catch 2416 assert_match('something wrong', v:exception) 2417 endtry 2418enddef 2419 2420def Test_echoerr_cmd_vimscript() 2421 # only checks line continuation 2422 var lines =<< trim END 2423 vim9script 2424 try 2425 echoerr 'this' 2426 .. ' is ' .. 2427 'wrong' 2428 catch 2429 assert_match('this is wrong', v:exception) 2430 endtry 2431 END 2432 CheckScriptSuccess(lines) 2433enddef 2434 2435def Test_for_outside_of_function() 2436 var lines =<< trim END 2437 vim9script 2438 new 2439 for var in range(0, 3) 2440 append(line('$'), var) 2441 endfor 2442 assert_equal(['', '0', '1', '2', '3'], getline(1, '$')) 2443 bwipe! 2444 2445 var result = '' 2446 for i in [1, 2, 3] 2447 var loop = ' loop ' .. i 2448 result ..= loop 2449 endfor 2450 assert_equal(' loop 1 loop 2 loop 3', result) 2451 END 2452 writefile(lines, 'Xvim9for.vim') 2453 source Xvim9for.vim 2454 delete('Xvim9for.vim') 2455enddef 2456 2457def Test_for_loop() 2458 var lines =<< trim END 2459 var result = '' 2460 for cnt in range(7) 2461 if cnt == 4 2462 break 2463 endif 2464 if cnt == 2 2465 continue 2466 endif 2467 result ..= cnt .. '_' 2468 endfor 2469 assert_equal('0_1_3_', result) 2470 2471 var concat = '' 2472 for str in eval('["one", "two"]') 2473 concat ..= str 2474 endfor 2475 assert_equal('onetwo', concat) 2476 2477 var total = 0 2478 for nr in 2479 [1, 2, 3] 2480 total += nr 2481 endfor 2482 assert_equal(6, total) 2483 2484 total = 0 2485 for nr 2486 in [1, 2, 3] 2487 total += nr 2488 endfor 2489 assert_equal(6, total) 2490 2491 total = 0 2492 for nr 2493 in 2494 [1, 2, 3] 2495 total += nr 2496 endfor 2497 assert_equal(6, total) 2498 2499 # with type 2500 total = 0 2501 for n: number in [1, 2, 3] 2502 total += n 2503 endfor 2504 assert_equal(6, total) 2505 2506 var chars = '' 2507 for s: string in 'foobar' 2508 chars ..= s 2509 endfor 2510 assert_equal('foobar', chars) 2511 2512 chars = '' 2513 for x: string in {a: 'a', b: 'b'}->values() 2514 chars ..= x 2515 endfor 2516 assert_equal('ab', chars) 2517 2518 # unpack with type 2519 var res = '' 2520 for [n: number, s: string] in [[1, 'a'], [2, 'b']] 2521 res ..= n .. s 2522 endfor 2523 assert_equal('1a2b', res) 2524 2525 # unpack with one var 2526 var reslist = [] 2527 for [x] in [['aaa'], ['bbb']] 2528 reslist->add(x) 2529 endfor 2530 assert_equal(['aaa', 'bbb'], reslist) 2531 2532 # loop over string 2533 res = '' 2534 for c in 'aéc̀d' 2535 res ..= c .. '-' 2536 endfor 2537 assert_equal('a-é-c̀-d-', res) 2538 2539 res = '' 2540 for c in '' 2541 res ..= c .. '-' 2542 endfor 2543 assert_equal('', res) 2544 2545 res = '' 2546 for c in test_null_string() 2547 res ..= c .. '-' 2548 endfor 2549 assert_equal('', res) 2550 2551 var foo: list<dict<any>> = [ 2552 {a: 'Cat'} 2553 ] 2554 for dd in foo 2555 dd.counter = 12 2556 endfor 2557 assert_equal([{a: 'Cat', counter: 12}], foo) 2558 2559 reslist = [] 2560 for _ in range(3) 2561 reslist->add('x') 2562 endfor 2563 assert_equal(['x', 'x', 'x'], reslist) 2564 END 2565 CheckDefAndScriptSuccess(lines) 2566enddef 2567 2568def Test_for_loop_fails() 2569 CheckDefAndScriptFailure2(['for '], 'E1097:', 'E690:') 2570 CheckDefAndScriptFailure2(['for x'], 'E1097:', 'E690:') 2571 CheckDefAndScriptFailure2(['for x in'], 'E1097:', 'E15:') 2572 CheckDefAndScriptFailure(['for # in range(5)'], 'E690:') 2573 CheckDefAndScriptFailure(['for i In range(5)'], 'E690:') 2574 CheckDefAndScriptFailure2(['var x = 5', 'for x in range(5)', 'endfor'], 'E1017:', 'E1041:') 2575 CheckScriptFailure(['vim9script', 'var x = 5', 'for x in range(5)', '# comment', 'endfor'], 'E1041:', 3) 2576 CheckScriptFailure(['def Func(arg: any)', 'for arg in range(5)', 'enddef', 'defcompile'], 'E1006:') 2577 delfunc! g:Func 2578 CheckDefFailure(['for i in xxx'], 'E1001:') 2579 CheckDefFailure(['endfor'], 'E588:') 2580 CheckDefFailure(['for i in range(3)', 'echo 3'], 'E170:') 2581 2582 # wrong type detected at compile time 2583 CheckDefFailure(['for i in {a: 1}', 'echo 3', 'endfor'], 'E1177: For loop on dict not supported') 2584 2585 # wrong type detected at runtime 2586 g:adict = {a: 1} 2587 CheckDefExecFailure(['for i in g:adict', 'echo 3', 'endfor'], 'E1177: For loop on dict not supported') 2588 unlet g:adict 2589 2590 var lines =<< trim END 2591 var d: list<dict<any>> = [{a: 0}] 2592 for e in d 2593 e = {a: 0, b: ''} 2594 endfor 2595 END 2596 CheckDefAndScriptFailure2(lines, 'E1018:', 'E46:', 3) 2597 2598 lines =<< trim END 2599 for nr: number in ['foo'] 2600 endfor 2601 END 2602 CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected number but got string', 1) 2603 2604 lines =<< trim END 2605 for n : number in [1, 2] 2606 echo n 2607 endfor 2608 END 2609 CheckDefAndScriptFailure(lines, 'E1059:', 1) 2610 2611 lines =<< trim END 2612 var d: dict<number> = {a: 1, b: 2} 2613 for [k: job, v: job] in d->items() 2614 echo k v 2615 endfor 2616 END 2617 CheckDefExecAndScriptFailure(lines, 'E1012: Type mismatch; expected job but got string', 2) 2618enddef 2619 2620def Test_for_loop_script_var() 2621 # cannot use s:var in a :def function 2622 CheckDefFailure(['for s:var in range(3)', 'echo 3'], 'E1101:') 2623 2624 # can use s:var in Vim9 script, with or without s: 2625 var lines =<< trim END 2626 vim9script 2627 var total = 0 2628 for s:var in [1, 2, 3] 2629 total += s:var 2630 endfor 2631 assert_equal(6, total) 2632 2633 total = 0 2634 for var in [1, 2, 3] 2635 total += var 2636 endfor 2637 assert_equal(6, total) 2638 END 2639enddef 2640 2641def Test_for_loop_unpack() 2642 var lines =<< trim END 2643 var result = [] 2644 for [v1, v2] in [[1, 2], [3, 4]] 2645 result->add(v1) 2646 result->add(v2) 2647 endfor 2648 assert_equal([1, 2, 3, 4], result) 2649 2650 result = [] 2651 for [v1, v2; v3] in [[1, 2], [3, 4, 5, 6]] 2652 result->add(v1) 2653 result->add(v2) 2654 result->add(v3) 2655 endfor 2656 assert_equal([1, 2, [], 3, 4, [5, 6]], result) 2657 2658 result = [] 2659 for [&ts, &sw] in [[1, 2], [3, 4]] 2660 result->add(&ts) 2661 result->add(&sw) 2662 endfor 2663 assert_equal([1, 2, 3, 4], result) 2664 2665 var slist: list<string> 2666 for [$LOOPVAR, @r, v:errmsg] in [['a', 'b', 'c'], ['d', 'e', 'f']] 2667 slist->add($LOOPVAR) 2668 slist->add(@r) 2669 slist->add(v:errmsg) 2670 endfor 2671 assert_equal(['a', 'b', 'c', 'd', 'e', 'f'], slist) 2672 2673 slist = [] 2674 for [g:globalvar, b:bufvar, w:winvar, t:tabvar] in [['global', 'buf', 'win', 'tab'], ['1', '2', '3', '4']] 2675 slist->add(g:globalvar) 2676 slist->add(b:bufvar) 2677 slist->add(w:winvar) 2678 slist->add(t:tabvar) 2679 endfor 2680 assert_equal(['global', 'buf', 'win', 'tab', '1', '2', '3', '4'], slist) 2681 unlet! g:globalvar b:bufvar w:winvar t:tabvar 2682 2683 var res = [] 2684 for [_, n, _] in [[1, 2, 3], [4, 5, 6]] 2685 res->add(n) 2686 endfor 2687 assert_equal([2, 5], res) 2688 END 2689 CheckDefAndScriptSuccess(lines) 2690 2691 lines =<< trim END 2692 for [v1, v2] in [[1, 2, 3], [3, 4]] 2693 echo v1 v2 2694 endfor 2695 END 2696 CheckDefExecFailure(lines, 'E710:', 1) 2697 2698 lines =<< trim END 2699 for [v1, v2] in [[1], [3, 4]] 2700 echo v1 v2 2701 endfor 2702 END 2703 CheckDefExecFailure(lines, 'E711:', 1) 2704 2705 lines =<< trim END 2706 for [v1, v1] in [[1, 2], [3, 4]] 2707 echo v1 2708 endfor 2709 END 2710 CheckDefExecFailure(lines, 'E1017:', 1) 2711enddef 2712 2713def Test_for_loop_with_try_continue() 2714 var lines =<< trim END 2715 var looped = 0 2716 var cleanup = 0 2717 for i in range(3) 2718 looped += 1 2719 try 2720 eval [][0] 2721 catch 2722 continue 2723 finally 2724 cleanup += 1 2725 endtry 2726 endfor 2727 assert_equal(3, looped) 2728 assert_equal(3, cleanup) 2729 END 2730 CheckDefAndScriptSuccess(lines) 2731enddef 2732 2733def Test_while_loop() 2734 var result = '' 2735 var cnt = 0 2736 while cnt < 555 2737 if cnt == 3 2738 break 2739 endif 2740 cnt += 1 2741 if cnt == 2 2742 continue 2743 endif 2744 result ..= cnt .. '_' 2745 endwhile 2746 assert_equal('1_3_', result) 2747 2748 var s = '' 2749 while s == 'x' # {comment} 2750 endwhile 2751enddef 2752 2753def Test_while_loop_fails() 2754 CheckDefFailure(['while xxx'], 'E1001:') 2755 CheckDefFailure(['endwhile'], 'E588:') 2756 CheckDefFailure(['continue'], 'E586:') 2757 CheckDefFailure(['if true', 'continue'], 'E586:') 2758 CheckDefFailure(['break'], 'E587:') 2759 CheckDefFailure(['if true', 'break'], 'E587:') 2760 CheckDefFailure(['while 1', 'echo 3'], 'E170:') 2761 2762 var lines =<< trim END 2763 var s = '' 2764 while s = '' 2765 endwhile 2766 END 2767 CheckDefFailure(lines, 'E488:') 2768enddef 2769 2770def Test_interrupt_loop() 2771 var caught = false 2772 var x = 0 2773 try 2774 while 1 2775 x += 1 2776 if x == 100 2777 feedkeys("\<C-C>", 'Lt') 2778 endif 2779 endwhile 2780 catch 2781 caught = true 2782 assert_equal(100, x) 2783 endtry 2784 assert_true(caught, 'should have caught an exception') 2785 # consume the CTRL-C 2786 getchar(0) 2787enddef 2788 2789def Test_automatic_line_continuation() 2790 var mylist = [ 2791 'one', 2792 'two', 2793 'three', 2794 ] # comment 2795 assert_equal(['one', 'two', 'three'], mylist) 2796 2797 var mydict = { 2798 ['one']: 1, 2799 ['two']: 2, 2800 ['three']: 2801 3, 2802 } # comment 2803 assert_equal({one: 1, two: 2, three: 3}, mydict) 2804 mydict = { 2805 one: 1, # comment 2806 two: # comment 2807 2, # comment 2808 three: 3 # comment 2809 } 2810 assert_equal({one: 1, two: 2, three: 3}, mydict) 2811 mydict = { 2812 one: 1, 2813 two: 2814 2, 2815 three: 3 2816 } 2817 assert_equal({one: 1, two: 2, three: 3}, mydict) 2818 2819 assert_equal( 2820 ['one', 'two', 'three'], 2821 split('one two three') 2822 ) 2823enddef 2824 2825def Test_vim9_comment() 2826 CheckScriptSuccess([ 2827 'vim9script', 2828 '# something', 2829 '#something', 2830 '#{something', 2831 ]) 2832 2833 split Xfile 2834 CheckScriptSuccess([ 2835 'vim9script', 2836 'edit #something', 2837 ]) 2838 CheckScriptSuccess([ 2839 'vim9script', 2840 'edit #{something', 2841 ]) 2842 close 2843 2844 CheckScriptFailure([ 2845 'vim9script', 2846 ':# something', 2847 ], 'E488:') 2848 CheckScriptFailure([ 2849 '# something', 2850 ], 'E488:') 2851 CheckScriptFailure([ 2852 ':# something', 2853 ], 'E488:') 2854 2855 { # block start 2856 } # block end 2857 CheckDefFailure([ 2858 '{# comment', 2859 ], 'E488:') 2860 CheckDefFailure([ 2861 '{', 2862 '}# comment', 2863 ], 'E488:') 2864 2865 echo "yes" # comment 2866 CheckDefFailure([ 2867 'echo "yes"# comment', 2868 ], 'E488:') 2869 CheckScriptSuccess([ 2870 'vim9script', 2871 'echo "yes" # something', 2872 ]) 2873 CheckScriptFailure([ 2874 'vim9script', 2875 'echo "yes"# something', 2876 ], 'E121:') 2877 CheckScriptFailure([ 2878 'vim9script', 2879 'echo# something', 2880 ], 'E1144:') 2881 CheckScriptFailure([ 2882 'echo "yes" # something', 2883 ], 'E121:') 2884 2885 exe "echo" # comment 2886 CheckDefFailure([ 2887 'exe "echo"# comment', 2888 ], 'E488:') 2889 CheckScriptSuccess([ 2890 'vim9script', 2891 'exe "echo" # something', 2892 ]) 2893 CheckScriptFailure([ 2894 'vim9script', 2895 'exe "echo"# something', 2896 ], 'E121:') 2897 CheckScriptFailure([ 2898 'vim9script', 2899 'exe# something', 2900 ], 'E1144:') 2901 CheckScriptFailure([ 2902 'exe "echo" # something', 2903 ], 'E121:') 2904 2905 CheckDefFailure([ 2906 'try# comment', 2907 ' echo "yes"', 2908 'catch', 2909 'endtry', 2910 ], 'E1144:') 2911 CheckScriptFailure([ 2912 'vim9script', 2913 'try# comment', 2914 'echo "yes"', 2915 ], 'E1144:') 2916 CheckDefFailure([ 2917 'try', 2918 ' throw#comment', 2919 'catch', 2920 'endtry', 2921 ], 'E1144:') 2922 CheckDefFailure([ 2923 'try', 2924 ' throw "yes"#comment', 2925 'catch', 2926 'endtry', 2927 ], 'E488:') 2928 CheckDefFailure([ 2929 'try', 2930 ' echo "yes"', 2931 'catch# comment', 2932 'endtry', 2933 ], 'E1144:') 2934 CheckScriptFailure([ 2935 'vim9script', 2936 'try', 2937 ' echo "yes"', 2938 'catch# comment', 2939 'endtry', 2940 ], 'E1144:') 2941 CheckDefFailure([ 2942 'try', 2943 ' echo "yes"', 2944 'catch /pat/# comment', 2945 'endtry', 2946 ], 'E488:') 2947 CheckDefFailure([ 2948 'try', 2949 'echo "yes"', 2950 'catch', 2951 'endtry# comment', 2952 ], 'E1144:') 2953 CheckScriptFailure([ 2954 'vim9script', 2955 'try', 2956 ' echo "yes"', 2957 'catch', 2958 'endtry# comment', 2959 ], 'E1144:') 2960 2961 CheckScriptSuccess([ 2962 'vim9script', 2963 'hi # comment', 2964 ]) 2965 CheckScriptFailure([ 2966 'vim9script', 2967 'hi# comment', 2968 ], 'E1144:') 2969 CheckScriptSuccess([ 2970 'vim9script', 2971 'hi Search # comment', 2972 ]) 2973 CheckScriptFailure([ 2974 'vim9script', 2975 'hi Search# comment', 2976 ], 'E416:') 2977 CheckScriptSuccess([ 2978 'vim9script', 2979 'hi link This Search # comment', 2980 ]) 2981 CheckScriptFailure([ 2982 'vim9script', 2983 'hi link This That# comment', 2984 ], 'E413:') 2985 CheckScriptSuccess([ 2986 'vim9script', 2987 'hi clear This # comment', 2988 'hi clear # comment', 2989 ]) 2990 # not tested, because it doesn't give an error but a warning: 2991 # hi clear This# comment', 2992 CheckScriptFailure([ 2993 'vim9script', 2994 'hi clear# comment', 2995 ], 'E416:') 2996 2997 CheckScriptSuccess([ 2998 'vim9script', 2999 'hi Group term=bold', 3000 'match Group /todo/ # comment', 3001 ]) 3002 CheckScriptFailure([ 3003 'vim9script', 3004 'hi Group term=bold', 3005 'match Group /todo/# comment', 3006 ], 'E488:') 3007 CheckScriptSuccess([ 3008 'vim9script', 3009 'match # comment', 3010 ]) 3011 CheckScriptFailure([ 3012 'vim9script', 3013 'match# comment', 3014 ], 'E1144:') 3015 CheckScriptSuccess([ 3016 'vim9script', 3017 'match none # comment', 3018 ]) 3019 CheckScriptFailure([ 3020 'vim9script', 3021 'match none# comment', 3022 ], 'E475:') 3023 3024 CheckScriptSuccess([ 3025 'vim9script', 3026 'menutrans clear # comment', 3027 ]) 3028 CheckScriptFailure([ 3029 'vim9script', 3030 'menutrans clear# comment text', 3031 ], 'E474:') 3032 3033 CheckScriptSuccess([ 3034 'vim9script', 3035 'syntax clear # comment', 3036 ]) 3037 CheckScriptFailure([ 3038 'vim9script', 3039 'syntax clear# comment text', 3040 ], 'E28:') 3041 CheckScriptSuccess([ 3042 'vim9script', 3043 'syntax keyword Word some', 3044 'syntax clear Word # comment', 3045 ]) 3046 CheckScriptFailure([ 3047 'vim9script', 3048 'syntax keyword Word some', 3049 'syntax clear Word# comment text', 3050 ], 'E28:') 3051 3052 CheckScriptSuccess([ 3053 'vim9script', 3054 'syntax list # comment', 3055 ]) 3056 CheckScriptFailure([ 3057 'vim9script', 3058 'syntax list# comment text', 3059 ], 'E28:') 3060 3061 CheckScriptSuccess([ 3062 'vim9script', 3063 'syntax match Word /pat/ oneline # comment', 3064 ]) 3065 CheckScriptFailure([ 3066 'vim9script', 3067 'syntax match Word /pat/ oneline# comment', 3068 ], 'E475:') 3069 3070 CheckScriptSuccess([ 3071 'vim9script', 3072 'syntax keyword Word word # comm[ent', 3073 ]) 3074 CheckScriptFailure([ 3075 'vim9script', 3076 'syntax keyword Word word# comm[ent', 3077 ], 'E789:') 3078 3079 CheckScriptSuccess([ 3080 'vim9script', 3081 'syntax match Word /pat/ # comment', 3082 ]) 3083 CheckScriptFailure([ 3084 'vim9script', 3085 'syntax match Word /pat/# comment', 3086 ], 'E402:') 3087 3088 CheckScriptSuccess([ 3089 'vim9script', 3090 'syntax match Word /pat/ contains=Something # comment', 3091 ]) 3092 CheckScriptFailure([ 3093 'vim9script', 3094 'syntax match Word /pat/ contains=Something# comment', 3095 ], 'E475:') 3096 CheckScriptFailure([ 3097 'vim9script', 3098 'syntax match Word /pat/ contains= # comment', 3099 ], 'E406:') 3100 CheckScriptFailure([ 3101 'vim9script', 3102 'syntax match Word /pat/ contains=# comment', 3103 ], 'E475:') 3104 3105 CheckScriptSuccess([ 3106 'vim9script', 3107 'syntax region Word start=/pat/ end=/pat/ # comment', 3108 ]) 3109 CheckScriptFailure([ 3110 'vim9script', 3111 'syntax region Word start=/pat/ end=/pat/# comment', 3112 ], 'E402:') 3113 3114 CheckScriptSuccess([ 3115 'vim9script', 3116 'syntax sync # comment', 3117 ]) 3118 CheckScriptFailure([ 3119 'vim9script', 3120 'syntax sync# comment', 3121 ], 'E404:') 3122 CheckScriptSuccess([ 3123 'vim9script', 3124 'syntax sync ccomment # comment', 3125 ]) 3126 CheckScriptFailure([ 3127 'vim9script', 3128 'syntax sync ccomment# comment', 3129 ], 'E404:') 3130 3131 CheckScriptSuccess([ 3132 'vim9script', 3133 'syntax cluster Some contains=Word # comment', 3134 ]) 3135 CheckScriptFailure([ 3136 'vim9script', 3137 'syntax cluster Some contains=Word# comment', 3138 ], 'E475:') 3139 3140 CheckScriptSuccess([ 3141 'vim9script', 3142 'command Echo echo # comment', 3143 'command Echo # comment', 3144 'delcommand Echo', 3145 ]) 3146 CheckScriptFailure([ 3147 'vim9script', 3148 'command Echo echo# comment', 3149 'Echo', 3150 ], 'E1144:') 3151 delcommand Echo 3152 3153 var curdir = getcwd() 3154 CheckScriptSuccess([ 3155 'command Echo cd " comment', 3156 'Echo', 3157 'delcommand Echo', 3158 ]) 3159 CheckScriptSuccess([ 3160 'vim9script', 3161 'command Echo cd # comment', 3162 'Echo', 3163 'delcommand Echo', 3164 ]) 3165 CheckScriptFailure([ 3166 'vim9script', 3167 'command Echo cd " comment', 3168 'Echo', 3169 ], 'E344:') 3170 delcommand Echo 3171 chdir(curdir) 3172 3173 CheckScriptFailure([ 3174 'vim9script', 3175 'command Echo# comment', 3176 ], 'E182:') 3177 CheckScriptFailure([ 3178 'vim9script', 3179 'command Echo echo', 3180 'command Echo# comment', 3181 ], 'E182:') 3182 delcommand Echo 3183 3184 CheckScriptSuccess([ 3185 'vim9script', 3186 'function # comment', 3187 ]) 3188 CheckScriptFailure([ 3189 'vim9script', 3190 'function " comment', 3191 ], 'E129:') 3192 CheckScriptFailure([ 3193 'vim9script', 3194 'function# comment', 3195 ], 'E1144:') 3196 CheckScriptSuccess([ 3197 'vim9script', 3198 'function CheckScriptSuccess # comment', 3199 ]) 3200 CheckScriptFailure([ 3201 'vim9script', 3202 'function CheckScriptSuccess# comment', 3203 ], 'E488:') 3204 3205 CheckScriptSuccess([ 3206 'vim9script', 3207 'func g:DeleteMeA()', 3208 'endfunc', 3209 'delfunction g:DeleteMeA # comment', 3210 ]) 3211 CheckScriptFailure([ 3212 'vim9script', 3213 'func g:DeleteMeB()', 3214 'endfunc', 3215 'delfunction g:DeleteMeB# comment', 3216 ], 'E488:') 3217 3218 CheckScriptSuccess([ 3219 'vim9script', 3220 'call execute("ls") # comment', 3221 ]) 3222 CheckScriptFailure([ 3223 'vim9script', 3224 'call execute("ls")# comment', 3225 ], 'E488:') 3226 3227 CheckScriptFailure([ 3228 'def Test() " comment', 3229 'enddef', 3230 ], 'E488:') 3231 CheckScriptFailure([ 3232 'vim9script', 3233 'def Test() " comment', 3234 'enddef', 3235 ], 'E488:') 3236 3237 CheckScriptSuccess([ 3238 'func Test() " comment', 3239 'endfunc', 3240 'delfunc Test', 3241 ]) 3242 CheckScriptSuccess([ 3243 'vim9script', 3244 'func Test() " comment', 3245 'endfunc', 3246 ]) 3247 3248 CheckScriptSuccess([ 3249 'def Test() # comment', 3250 'enddef', 3251 ]) 3252 CheckScriptFailure([ 3253 'func Test() # comment', 3254 'endfunc', 3255 ], 'E488:') 3256 3257 var lines =<< trim END 3258 vim9script 3259 syn region Text 3260 \ start='foo' 3261 #\ comment 3262 \ end='bar' 3263 syn region Text start='foo' 3264 #\ comment 3265 \ end='bar' 3266 END 3267 CheckScriptSuccess(lines) 3268 3269 lines =<< trim END 3270 vim9script 3271 syn region Text 3272 \ start='foo' 3273 "\ comment 3274 \ end='bar' 3275 END 3276 CheckScriptFailure(lines, 'E399:') 3277enddef 3278 3279def Test_vim9_comment_gui() 3280 CheckCanRunGui 3281 3282 CheckScriptFailure([ 3283 'vim9script', 3284 'gui#comment' 3285 ], 'E1144:') 3286 CheckScriptFailure([ 3287 'vim9script', 3288 'gui -f#comment' 3289 ], 'E499:') 3290enddef 3291 3292def Test_vim9_comment_not_compiled() 3293 au TabEnter *.vim g:entered = 1 3294 au TabEnter *.x g:entered = 2 3295 3296 edit test.vim 3297 doautocmd TabEnter #comment 3298 assert_equal(1, g:entered) 3299 3300 doautocmd TabEnter f.x 3301 assert_equal(2, g:entered) 3302 3303 g:entered = 0 3304 doautocmd TabEnter f.x #comment 3305 assert_equal(2, g:entered) 3306 3307 assert_fails('doautocmd Syntax#comment', 'E216:') 3308 3309 au! TabEnter 3310 unlet g:entered 3311 3312 CheckScriptSuccess([ 3313 'vim9script', 3314 'g:var = 123', 3315 'b:var = 456', 3316 'w:var = 777', 3317 't:var = 888', 3318 'unlet g:var w:var # something', 3319 ]) 3320 3321 CheckScriptFailure([ 3322 'vim9script', 3323 'let var = 123', 3324 ], 'E1126: Cannot use :let in Vim9 script') 3325 3326 CheckScriptFailure([ 3327 'vim9script', 3328 'var g:var = 123', 3329 ], 'E1016: Cannot declare a global variable:') 3330 3331 CheckScriptFailure([ 3332 'vim9script', 3333 'var b:var = 123', 3334 ], 'E1016: Cannot declare a buffer variable:') 3335 3336 CheckScriptFailure([ 3337 'vim9script', 3338 'var w:var = 123', 3339 ], 'E1016: Cannot declare a window variable:') 3340 3341 CheckScriptFailure([ 3342 'vim9script', 3343 'var t:var = 123', 3344 ], 'E1016: Cannot declare a tab variable:') 3345 3346 CheckScriptFailure([ 3347 'vim9script', 3348 'var v:version = 123', 3349 ], 'E1016: Cannot declare a v: variable:') 3350 3351 CheckScriptFailure([ 3352 'vim9script', 3353 'var $VARIABLE = "text"', 3354 ], 'E1016: Cannot declare an environment variable:') 3355 3356 CheckScriptFailure([ 3357 'vim9script', 3358 'g:var = 123', 3359 'unlet g:var# comment1', 3360 ], 'E108:') 3361 3362 CheckScriptFailure([ 3363 'let g:var = 123', 3364 'unlet g:var # something', 3365 ], 'E488:') 3366 3367 CheckScriptSuccess([ 3368 'vim9script', 3369 'if 1 # comment2', 3370 ' echo "yes"', 3371 'elseif 2 #comment', 3372 ' echo "no"', 3373 'endif', 3374 ]) 3375 3376 CheckScriptFailure([ 3377 'vim9script', 3378 'if 1# comment3', 3379 ' echo "yes"', 3380 'endif', 3381 ], 'E488:') 3382 3383 CheckScriptFailure([ 3384 'vim9script', 3385 'if 0 # comment4', 3386 ' echo "yes"', 3387 'elseif 2#comment', 3388 ' echo "no"', 3389 'endif', 3390 ], 'E488:') 3391 3392 CheckScriptSuccess([ 3393 'vim9script', 3394 'var v = 1 # comment5', 3395 ]) 3396 3397 CheckScriptFailure([ 3398 'vim9script', 3399 'var v = 1# comment6', 3400 ], 'E488:') 3401 3402 CheckScriptSuccess([ 3403 'vim9script', 3404 'new' 3405 'setline(1, ["# define pat", "last"])', 3406 ':$', 3407 'dsearch /pat/ #comment', 3408 'bwipe!', 3409 ]) 3410 3411 CheckScriptFailure([ 3412 'vim9script', 3413 'new' 3414 'setline(1, ["# define pat", "last"])', 3415 ':$', 3416 'dsearch /pat/#comment', 3417 'bwipe!', 3418 ], 'E488:') 3419 3420 CheckScriptFailure([ 3421 'vim9script', 3422 'func! SomeFunc()', 3423 ], 'E477:') 3424enddef 3425 3426def Test_finish() 3427 var lines =<< trim END 3428 vim9script 3429 g:res = 'one' 3430 if v:false | finish | endif 3431 g:res = 'two' 3432 finish 3433 g:res = 'three' 3434 END 3435 writefile(lines, 'Xfinished') 3436 source Xfinished 3437 assert_equal('two', g:res) 3438 3439 unlet g:res 3440 delete('Xfinished') 3441enddef 3442 3443def Test_forward_declaration() 3444 var lines =<< trim END 3445 vim9script 3446 def GetValue(): string 3447 return theVal 3448 enddef 3449 var theVal = 'something' 3450 g:initVal = GetValue() 3451 theVal = 'else' 3452 g:laterVal = GetValue() 3453 END 3454 writefile(lines, 'Xforward') 3455 source Xforward 3456 assert_equal('something', g:initVal) 3457 assert_equal('else', g:laterVal) 3458 3459 unlet g:initVal 3460 unlet g:laterVal 3461 delete('Xforward') 3462enddef 3463 3464def Test_source_vim9_from_legacy() 3465 var vim9_lines =<< trim END 3466 vim9script 3467 var local = 'local' 3468 g:global = 'global' 3469 export var exported = 'exported' 3470 export def GetText(): string 3471 return 'text' 3472 enddef 3473 END 3474 writefile(vim9_lines, 'Xvim9_script.vim') 3475 3476 var legacy_lines =<< trim END 3477 source Xvim9_script.vim 3478 3479 call assert_false(exists('local')) 3480 call assert_false(exists('exported')) 3481 call assert_false(exists('s:exported')) 3482 call assert_equal('global', global) 3483 call assert_equal('global', g:global) 3484 3485 " imported variable becomes script-local 3486 import exported from './Xvim9_script.vim' 3487 call assert_equal('exported', s:exported) 3488 call assert_false(exists('exported')) 3489 3490 " imported function becomes script-local 3491 import GetText from './Xvim9_script.vim' 3492 call assert_equal('text', s:GetText()) 3493 call assert_false(exists('*GetText')) 3494 END 3495 writefile(legacy_lines, 'Xlegacy_script.vim') 3496 3497 source Xlegacy_script.vim 3498 assert_equal('global', g:global) 3499 unlet g:global 3500 3501 delete('Xlegacy_script.vim') 3502 delete('Xvim9_script.vim') 3503enddef 3504 3505def Test_declare_script_in_func() 3506 var lines =<< trim END 3507 vim9script 3508 func Declare() 3509 let s:local = 123 3510 endfunc 3511 Declare() 3512 assert_equal(123, local) 3513 3514 var error: string 3515 try 3516 local = 'asdf' 3517 catch 3518 error = v:exception 3519 endtry 3520 assert_match('E1012: Type mismatch; expected number but got string', error) 3521 3522 lockvar local 3523 try 3524 local = 999 3525 catch 3526 error = v:exception 3527 endtry 3528 assert_match('E741: Value is locked: local', error) 3529 END 3530 CheckScriptSuccess(lines) 3531enddef 3532 3533 3534func Test_vim9script_not_global() 3535 " check that items defined in Vim9 script are script-local, not global 3536 let vim9lines =<< trim END 3537 vim9script 3538 var name = 'local' 3539 func TheFunc() 3540 echo 'local' 3541 endfunc 3542 def DefFunc() 3543 echo 'local' 3544 enddef 3545 END 3546 call writefile(vim9lines, 'Xvim9script.vim') 3547 source Xvim9script.vim 3548 try 3549 echo g:var 3550 assert_report('did not fail') 3551 catch /E121:/ 3552 " caught 3553 endtry 3554 try 3555 call TheFunc() 3556 assert_report('did not fail') 3557 catch /E117:/ 3558 " caught 3559 endtry 3560 try 3561 call DefFunc() 3562 assert_report('did not fail') 3563 catch /E117:/ 3564 " caught 3565 endtry 3566 3567 call delete('Xvim9script.vim') 3568endfunc 3569 3570def Test_vim9_copen() 3571 # this was giving an error for setting w:quickfix_title 3572 copen 3573 quit 3574enddef 3575 3576" test using an auto-loaded function and variable 3577def Test_vim9_autoload() 3578 var lines =<< trim END 3579 vim9script 3580 def some#gettest(): string 3581 return 'test' 3582 enddef 3583 g:some#name = 'name' 3584 g:some#dict = {key: 'value'} 3585 3586 def some#varargs(a1: string, ...l: list<string>): string 3587 return a1 .. l[0] .. l[1] 3588 enddef 3589 END 3590 3591 mkdir('Xdir/autoload', 'p') 3592 writefile(lines, 'Xdir/autoload/some.vim') 3593 var save_rtp = &rtp 3594 exe 'set rtp^=' .. getcwd() .. '/Xdir' 3595 3596 assert_equal('test', g:some#gettest()) 3597 assert_equal('name', g:some#name) 3598 assert_equal('value', g:some#dict.key) 3599 g:some#other = 'other' 3600 assert_equal('other', g:some#other) 3601 3602 assert_equal('abc', some#varargs('a', 'b', 'c')) 3603 3604 # upper case script name works 3605 lines =<< trim END 3606 vim9script 3607 def Other#getOther(): string 3608 return 'other' 3609 enddef 3610 END 3611 writefile(lines, 'Xdir/autoload/Other.vim') 3612 assert_equal('other', g:Other#getOther()) 3613 3614 delete('Xdir', 'rf') 3615 &rtp = save_rtp 3616enddef 3617 3618" test using a vim9script that is auto-loaded from an autocmd 3619def Test_vim9_aucmd_autoload() 3620 var lines =<< trim END 3621 vim9script 3622 def foo#test() 3623 echomsg getreg('"') 3624 enddef 3625 END 3626 3627 mkdir('Xdir/autoload', 'p') 3628 writefile(lines, 'Xdir/autoload/foo.vim') 3629 var save_rtp = &rtp 3630 exe 'set rtp^=' .. getcwd() .. '/Xdir' 3631 augroup test 3632 autocmd TextYankPost * call foo#test() 3633 augroup END 3634 3635 normal Y 3636 3637 augroup test 3638 autocmd! 3639 augroup END 3640 delete('Xdir', 'rf') 3641 &rtp = save_rtp 3642enddef 3643 3644" This was causing a crash because suppress_errthrow wasn't reset. 3645def Test_vim9_autoload_error() 3646 var lines =<< trim END 3647 vim9script 3648 def crash#func() 3649 try 3650 for x in List() 3651 endfor 3652 catch 3653 endtry 3654 g:ok = true 3655 enddef 3656 fu List() 3657 invalid 3658 endfu 3659 try 3660 alsoinvalid 3661 catch /wontmatch/ 3662 endtry 3663 END 3664 call mkdir('Xruntime/autoload', 'p') 3665 call writefile(lines, 'Xruntime/autoload/crash.vim') 3666 3667 # run in a separate Vim to avoid the side effects of assert_fails() 3668 lines =<< trim END 3669 exe 'set rtp^=' .. getcwd() .. '/Xruntime' 3670 call crash#func() 3671 call writefile(['ok'], 'Xdidit') 3672 qall! 3673 END 3674 writefile(lines, 'Xscript') 3675 RunVim([], [], '-S Xscript') 3676 assert_equal(['ok'], readfile('Xdidit')) 3677 3678 delete('Xdidit') 3679 delete('Xscript') 3680 delete('Xruntime', 'rf') 3681 3682 lines =<< trim END 3683 vim9script 3684 var foo#bar = 'asdf' 3685 END 3686 CheckScriptFailure(lines, 'E461: Illegal variable name: foo#bar', 2) 3687enddef 3688 3689def Test_script_var_in_autocmd() 3690 # using a script variable from an autocommand, defined in a :def function in a 3691 # legacy Vim script, cannot check the variable type. 3692 var lines =<< trim END 3693 let s:counter = 1 3694 def s:Func() 3695 au! CursorHold 3696 au CursorHold * s:counter += 1 3697 enddef 3698 call s:Func() 3699 doau CursorHold 3700 call assert_equal(2, s:counter) 3701 au! CursorHold 3702 END 3703 CheckScriptSuccess(lines) 3704enddef 3705 3706def Test_error_in_autoload_script() 3707 var save_rtp = &rtp 3708 var dir = getcwd() .. '/Xruntime' 3709 &rtp = dir 3710 mkdir(dir .. '/autoload', 'p') 3711 3712 var lines =<< trim END 3713 vim9script noclear 3714 def script#autoloaded() 3715 enddef 3716 def Broken() 3717 var x: any = '' 3718 eval x != 0 3719 enddef 3720 Broken() 3721 END 3722 writefile(lines, dir .. '/autoload/script.vim') 3723 3724 lines =<< trim END 3725 vim9script 3726 def CallAutoloaded() 3727 script#autoloaded() 3728 enddef 3729 3730 function Legacy() 3731 try 3732 call s:CallAutoloaded() 3733 catch 3734 call assert_match('E1030: Using a String as a Number', v:exception) 3735 endtry 3736 endfunction 3737 3738 Legacy() 3739 END 3740 CheckScriptSuccess(lines) 3741 3742 &rtp = save_rtp 3743 delete(dir, 'rf') 3744enddef 3745 3746def Test_cmdline_win() 3747 # if the Vim syntax highlighting uses Vim9 constructs they can be used from 3748 # the command line window. 3749 mkdir('rtp/syntax', 'p') 3750 var export_lines =<< trim END 3751 vim9script 3752 export var That = 'yes' 3753 END 3754 writefile(export_lines, 'rtp/syntax/Xexport.vim') 3755 var import_lines =<< trim END 3756 vim9script 3757 import That from './Xexport.vim' 3758 END 3759 writefile(import_lines, 'rtp/syntax/vim.vim') 3760 var save_rtp = &rtp 3761 &rtp = getcwd() .. '/rtp' .. ',' .. &rtp 3762 syntax on 3763 augroup CmdWin 3764 autocmd CmdwinEnter * g:got_there = 'yes' 3765 augroup END 3766 # this will open and also close the cmdline window 3767 feedkeys('q:', 'xt') 3768 assert_equal('yes', g:got_there) 3769 3770 augroup CmdWin 3771 au! 3772 augroup END 3773 &rtp = save_rtp 3774 delete('rtp', 'rf') 3775enddef 3776 3777def Test_invalid_sid() 3778 assert_fails('func <SNR>1234_func', 'E123:') 3779 3780 if RunVim([], ['wq! Xdidit'], '+"func <SNR>1_func"') 3781 assert_equal([], readfile('Xdidit')) 3782 endif 3783 delete('Xdidit') 3784enddef 3785 3786def Test_restoring_cpo() 3787 writefile(['vim9script', 'set nocp'], 'Xsourced') 3788 writefile(['call writefile(["done"], "Xdone")', 'quit!'], 'Xclose') 3789 if RunVim([], [], '-u NONE +"set cpo+=a" -S Xsourced -S Xclose') 3790 assert_equal(['done'], readfile('Xdone')) 3791 endif 3792 delete('Xsourced') 3793 delete('Xclose') 3794 delete('Xdone') 3795 3796 writefile(['vim9script'], 'XanotherScript') 3797 set cpo=aABceFsMny> 3798 edit XanotherScript 3799 so % 3800 assert_equal('aABceFsMny>', &cpo) 3801 :1del 3802 w 3803 so % 3804 assert_equal('aABceFsMny>', &cpo) 3805 3806 delete('XanotherScript') 3807 set cpo&vim 3808enddef 3809 3810" Use :function so we can use Check commands 3811func Test_no_redraw_when_restoring_cpo() 3812 CheckScreendump 3813 CheckFeature timers 3814 3815 let lines =<< trim END 3816 vim9script 3817 def script#func() 3818 enddef 3819 END 3820 call mkdir('Xdir/autoload', 'p') 3821 call writefile(lines, 'Xdir/autoload/script.vim') 3822 3823 let lines =<< trim END 3824 vim9script 3825 set cpo+=M 3826 exe 'set rtp^=' .. getcwd() .. '/Xdir' 3827 au CmdlineEnter : ++once timer_start(0, (_) => script#func()) 3828 setline(1, 'some text') 3829 END 3830 call writefile(lines, 'XTest_redraw_cpo') 3831 let buf = RunVimInTerminal('-S XTest_redraw_cpo', {'rows': 6}) 3832 call term_sendkeys(buf, "V:") 3833 call VerifyScreenDump(buf, 'Test_vim9_no_redraw', {}) 3834 3835 " clean up 3836 call term_sendkeys(buf, "\<Esc>u") 3837 call StopVimInTerminal(buf) 3838 call delete('XTest_redraw_cpo') 3839 call delete('Xdir', 'rf') 3840endfunc 3841 3842 3843def Test_unset_any_variable() 3844 var lines =<< trim END 3845 var name: any 3846 assert_equal(0, name) 3847 END 3848 CheckDefAndScriptSuccess(lines) 3849enddef 3850 3851func Test_define_func_at_command_line() 3852 CheckRunVimInTerminal 3853 3854 " call indirectly to avoid compilation error for missing functions 3855 call Run_Test_define_func_at_command_line() 3856endfunc 3857 3858def Run_Test_define_func_at_command_line() 3859 # run in a separate Vim instance to avoid the script context 3860 var lines =<< trim END 3861 func CheckAndQuit() 3862 call assert_fails('call Afunc()', 'E117: Unknown function: Bfunc') 3863 call writefile(['errors: ' .. string(v:errors)], 'Xdidcmd') 3864 endfunc 3865 END 3866 writefile([''], 'Xdidcmd') 3867 writefile(lines, 'XcallFunc') 3868 var buf = RunVimInTerminal('-S XcallFunc', {rows: 6}) 3869 # define Afunc() on the command line 3870 term_sendkeys(buf, ":def Afunc()\<CR>Bfunc()\<CR>enddef\<CR>") 3871 term_sendkeys(buf, ":call CheckAndQuit()\<CR>") 3872 WaitForAssert(() => assert_equal(['errors: []'], readfile('Xdidcmd'))) 3873 3874 call StopVimInTerminal(buf) 3875 delete('XcallFunc') 3876 delete('Xdidcmd') 3877enddef 3878 3879def Test_script_var_scope() 3880 var lines =<< trim END 3881 vim9script 3882 if true 3883 if true 3884 var one = 'one' 3885 echo one 3886 endif 3887 echo one 3888 endif 3889 END 3890 CheckScriptFailure(lines, 'E121:', 7) 3891 3892 lines =<< trim END 3893 vim9script 3894 if true 3895 if false 3896 var one = 'one' 3897 echo one 3898 else 3899 var one = 'one' 3900 echo one 3901 endif 3902 echo one 3903 endif 3904 END 3905 CheckScriptFailure(lines, 'E121:', 10) 3906 3907 lines =<< trim END 3908 vim9script 3909 while true 3910 var one = 'one' 3911 echo one 3912 break 3913 endwhile 3914 echo one 3915 END 3916 CheckScriptFailure(lines, 'E121:', 7) 3917 3918 lines =<< trim END 3919 vim9script 3920 for i in range(1) 3921 var one = 'one' 3922 echo one 3923 endfor 3924 echo one 3925 END 3926 CheckScriptFailure(lines, 'E121:', 6) 3927 3928 lines =<< trim END 3929 vim9script 3930 { 3931 var one = 'one' 3932 assert_equal('one', one) 3933 } 3934 assert_false(exists('one')) 3935 assert_false(exists('s:one')) 3936 END 3937 CheckScriptSuccess(lines) 3938 3939 lines =<< trim END 3940 vim9script 3941 { 3942 var one = 'one' 3943 echo one 3944 } 3945 echo one 3946 END 3947 CheckScriptFailure(lines, 'E121:', 6) 3948enddef 3949 3950def Test_catch_exception_in_callback() 3951 var lines =<< trim END 3952 vim9script 3953 def Callback(...l: list<any>) 3954 try 3955 var x: string 3956 var y: string 3957 # this error should be caught with CHECKLEN 3958 [x, y] = [''] 3959 catch 3960 g:caught = 'yes' 3961 endtry 3962 enddef 3963 popup_menu('popup', {callback: Callback}) 3964 feedkeys("\r", 'xt') 3965 END 3966 CheckScriptSuccess(lines) 3967 3968 unlet g:caught 3969enddef 3970 3971def Test_no_unknown_error_after_error() 3972 if !has('unix') || !has('job') 3973 throw 'Skipped: not unix of missing +job feature' 3974 endif 3975 var lines =<< trim END 3976 vim9script 3977 var source: list<number> 3978 def Out_cb(...l: list<any>) 3979 eval [][0] 3980 enddef 3981 def Exit_cb(...l: list<any>) 3982 sleep 1m 3983 source += l 3984 enddef 3985 var myjob = job_start('echo burp', {out_cb: Out_cb, exit_cb: Exit_cb, mode: 'raw'}) 3986 while job_status(myjob) == 'run' 3987 sleep 10m 3988 endwhile 3989 # wait for Exit_cb() to be called 3990 sleep 200m 3991 END 3992 writefile(lines, 'Xdef') 3993 assert_fails('so Xdef', ['E684:', 'E1012:']) 3994 delete('Xdef') 3995enddef 3996 3997def InvokeNormal() 3998 exe "norm! :m+1\r" 3999enddef 4000 4001def Test_invoke_normal_in_visual_mode() 4002 xnoremap <F3> <Cmd>call <SID>InvokeNormal()<CR> 4003 new 4004 setline(1, ['aaa', 'bbb']) 4005 feedkeys("V\<F3>", 'xt') 4006 assert_equal(['bbb', 'aaa'], getline(1, 2)) 4007 xunmap <F3> 4008enddef 4009 4010def Test_white_space_after_command() 4011 var lines =<< trim END 4012 exit_cb: Func}) 4013 END 4014 CheckDefAndScriptFailure(lines, 'E1144:', 1) 4015 4016 lines =<< trim END 4017 e# 4018 END 4019 CheckDefAndScriptFailure(lines, 'E1144:', 1) 4020enddef 4021 4022def Test_script_var_gone_when_sourced_twice() 4023 var lines =<< trim END 4024 vim9script 4025 if exists('g:guard') 4026 finish 4027 endif 4028 g:guard = 1 4029 var name = 'thename' 4030 def g:GetName(): string 4031 return name 4032 enddef 4033 def g:SetName(arg: string) 4034 name = arg 4035 enddef 4036 END 4037 writefile(lines, 'XscriptTwice.vim') 4038 so XscriptTwice.vim 4039 assert_equal('thename', g:GetName()) 4040 g:SetName('newname') 4041 assert_equal('newname', g:GetName()) 4042 so XscriptTwice.vim 4043 assert_fails('call g:GetName()', 'E1149:') 4044 assert_fails('call g:SetName("x")', 'E1149:') 4045 4046 delfunc g:GetName 4047 delfunc g:SetName 4048 delete('XscriptTwice.vim') 4049 unlet g:guard 4050enddef 4051 4052def Test_import_gone_when_sourced_twice() 4053 var exportlines =<< trim END 4054 vim9script 4055 if exists('g:guard') 4056 finish 4057 endif 4058 g:guard = 1 4059 export var name = 'someName' 4060 END 4061 writefile(exportlines, 'XexportScript.vim') 4062 4063 var lines =<< trim END 4064 vim9script 4065 import name from './XexportScript.vim' 4066 def g:GetName(): string 4067 return name 4068 enddef 4069 END 4070 writefile(lines, 'XscriptImport.vim') 4071 so XscriptImport.vim 4072 assert_equal('someName', g:GetName()) 4073 4074 so XexportScript.vim 4075 assert_fails('call g:GetName()', 'E1149:') 4076 4077 delfunc g:GetName 4078 delete('XexportScript.vim') 4079 delete('XscriptImport.vim') 4080 unlet g:guard 4081enddef 4082 4083def Test_unsupported_commands() 4084 var lines =<< trim END 4085 ka 4086 END 4087 CheckDefFailure(lines, 'E476:') 4088 CheckScriptFailure(['vim9script'] + lines, 'E492:') 4089 4090 lines =<< trim END 4091 :1ka 4092 END 4093 CheckDefFailure(lines, 'E476:') 4094 CheckScriptFailure(['vim9script'] + lines, 'E492:') 4095 4096 lines =<< trim END 4097 t 4098 END 4099 CheckDefFailure(lines, 'E1100:') 4100 CheckScriptFailure(['vim9script'] + lines, 'E1100:') 4101 4102 lines =<< trim END 4103 x 4104 END 4105 CheckDefFailure(lines, 'E1100:') 4106 CheckScriptFailure(['vim9script'] + lines, 'E1100:') 4107 4108 lines =<< trim END 4109 xit 4110 END 4111 CheckDefFailure(lines, 'E1100:') 4112 CheckScriptFailure(['vim9script'] + lines, 'E1100:') 4113enddef 4114 4115def Test_mapping_line_number() 4116 var lines =<< trim END 4117 vim9script 4118 def g:FuncA() 4119 # Some comment 4120 FuncB(0) 4121 enddef 4122 # Some comment 4123 def FuncB( 4124 # Some comment 4125 n: number 4126 ) 4127 exe 'nno ' 4128 # Some comment 4129 .. '<F3> a' 4130 .. 'b' 4131 .. 'c' 4132 enddef 4133 END 4134 CheckScriptSuccess(lines) 4135 var res = execute('verbose nmap <F3>') 4136 assert_match('No mapping found', res) 4137 4138 g:FuncA() 4139 res = execute('verbose nmap <F3>') 4140 assert_match(' <F3> .* abc.*Last set from .*XScriptSuccess\d\+ line 11', res) 4141 4142 nunmap <F3> 4143 delfunc g:FuncA 4144enddef 4145 4146def Test_option_set() 4147 # legacy script allows for white space 4148 var lines =<< trim END 4149 set foldlevel =11 4150 call assert_equal(11, &foldlevel) 4151 END 4152 CheckScriptSuccess(lines) 4153 4154 set foldlevel 4155 set foldlevel=12 4156 assert_equal(12, &foldlevel) 4157 set foldlevel+=2 4158 assert_equal(14, &foldlevel) 4159 set foldlevel-=3 4160 assert_equal(11, &foldlevel) 4161 4162 lines =<< trim END 4163 set foldlevel =1 4164 END 4165 CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: =1') 4166 4167 lines =<< trim END 4168 set foldlevel +=1 4169 END 4170 CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: +=1') 4171 4172 lines =<< trim END 4173 set foldlevel ^=1 4174 END 4175 CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: ^=1') 4176 4177 lines =<< trim END 4178 set foldlevel -=1 4179 END 4180 CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: -=1') 4181 4182 set foldlevel& 4183enddef 4184 4185def Test_option_modifier() 4186 # legacy script allows for white space 4187 var lines =<< trim END 4188 set hlsearch & hlsearch ! 4189 call assert_equal(1, &hlsearch) 4190 END 4191 CheckScriptSuccess(lines) 4192 4193 set hlsearch 4194 set hlsearch! 4195 assert_equal(false, &hlsearch) 4196 4197 set hlsearch 4198 set hlsearch& 4199 assert_equal(false, &hlsearch) 4200 4201 lines =<< trim END 4202 set hlsearch & 4203 END 4204 CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: &') 4205 4206 lines =<< trim END 4207 set hlsearch ! 4208 END 4209 CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: !') 4210 4211 set hlsearch& 4212enddef 4213 4214" This must be called last, it may cause following :def functions to fail 4215def Test_xxx_echoerr_line_number() 4216 var lines =<< trim END 4217 echoerr 'some' 4218 .. ' error' 4219 .. ' continued' 4220 END 4221 CheckDefExecAndScriptFailure(lines, 'some error continued', 1) 4222enddef 4223 4224def ProfiledWithLambda() 4225 var n = 3 4226 echo [[1, 2], [3, 4]]->filter((_, l) => l[0] == n) 4227enddef 4228 4229def ProfiledNested() 4230 var x = 0 4231 def Nested(): any 4232 return x 4233 enddef 4234 Nested() 4235enddef 4236 4237def ProfiledNestedProfiled() 4238 var x = 0 4239 def Nested(): any 4240 return x 4241 enddef 4242 Nested() 4243enddef 4244 4245" Execute this near the end, profiling doesn't stop until Vim exists. 4246" This only tests that it works, not the profiling output. 4247def Test_xx_profile_with_lambda() 4248 CheckFeature profile 4249 4250 profile start Xprofile.log 4251 profile func ProfiledWithLambda 4252 ProfiledWithLambda() 4253 4254 profile func ProfiledNested 4255 ProfiledNested() 4256 4257 # Also profile the nested function. Use a different function, although the 4258 # contents is the same, to make sure it was not already compiled. 4259 profile func * 4260 ProfiledNestedProfiled() 4261 4262 profdel func * 4263 profile pause 4264enddef 4265 4266" Keep this last, it messes up highlighting. 4267def Test_substitute_cmd() 4268 new 4269 setline(1, 'something') 4270 :substitute(some(other( 4271 assert_equal('otherthing', getline(1)) 4272 bwipe! 4273 4274 # also when the context is Vim9 script 4275 var lines =<< trim END 4276 vim9script 4277 new 4278 setline(1, 'something') 4279 :substitute(some(other( 4280 assert_equal('otherthing', getline(1)) 4281 bwipe! 4282 END 4283 writefile(lines, 'Xvim9lines') 4284 source Xvim9lines 4285 4286 delete('Xvim9lines') 4287enddef 4288 4289" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 4290