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 final theList = [1] 1066END 1067 1068def Undo_export_script_lines() 1069 unlet g:result 1070 unlet g:localname 1071enddef 1072 1073def Test_vim9_import_export() 1074 var import_script_lines =<< trim END 1075 vim9script 1076 import {exported, Exported} from './Xexport.vim' 1077 g:imported = exported 1078 exported += 3 1079 g:imported_added = exported 1080 g:imported_func = Exported() 1081 1082 def GetExported(): string 1083 var local_dict = {ref: Exported} 1084 return local_dict.ref() 1085 enddef 1086 g:funcref_result = GetExported() 1087 1088 import {exp_name} from './Xexport.vim' 1089 g:imported_name = exp_name 1090 exp_name ..= ' Doe' 1091 g:imported_name_appended = exp_name 1092 g:imported_later = exported 1093 1094 import theList from './Xexport.vim' 1095 theList->add(2) 1096 assert_equal([1, 2], theList) 1097 END 1098 1099 writefile(import_script_lines, 'Ximport.vim') 1100 writefile(s:export_script_lines, 'Xexport.vim') 1101 1102 source Ximport.vim 1103 1104 assert_equal('bobbie', g:result) 1105 assert_equal('bob', g:localname) 1106 assert_equal(9876, g:imported) 1107 assert_equal(9879, g:imported_added) 1108 assert_equal(9879, g:imported_later) 1109 assert_equal('Exported', g:imported_func) 1110 assert_equal('Exported', g:funcref_result) 1111 assert_equal('John', g:imported_name) 1112 assert_equal('John Doe', g:imported_name_appended) 1113 assert_false(exists('g:name')) 1114 1115 Undo_export_script_lines() 1116 unlet g:imported 1117 unlet g:imported_added 1118 unlet g:imported_later 1119 unlet g:imported_func 1120 unlet g:imported_name g:imported_name_appended 1121 delete('Ximport.vim') 1122 1123 # similar, with line breaks 1124 var import_line_break_script_lines =<< trim END 1125 vim9script 1126 import { 1127 exported, 1128 Exported, 1129 } 1130 from 1131 './Xexport.vim' 1132 g:imported = exported 1133 exported += 5 1134 g:imported_added = exported 1135 g:imported_func = Exported() 1136 END 1137 writefile(import_line_break_script_lines, 'Ximport_lbr.vim') 1138 source Ximport_lbr.vim 1139 1140 assert_equal(9876, g:imported) 1141 assert_equal(9881, g:imported_added) 1142 assert_equal('Exported', g:imported_func) 1143 1144 # exported script not sourced again 1145 assert_false(exists('g:result')) 1146 unlet g:imported 1147 unlet g:imported_added 1148 unlet g:imported_func 1149 delete('Ximport_lbr.vim') 1150 1151 # import inside :def function 1152 var import_in_def_lines =<< trim END 1153 vim9script 1154 def ImportInDef() 1155 import exported from './Xexport.vim' 1156 g:imported = exported 1157 exported += 7 1158 g:imported_added = exported 1159 enddef 1160 ImportInDef() 1161 END 1162 writefile(import_in_def_lines, 'Ximport2.vim') 1163 source Ximport2.vim 1164 # TODO: this should be 9879 1165 assert_equal(9876, g:imported) 1166 assert_equal(9883, g:imported_added) 1167 unlet g:imported 1168 unlet g:imported_added 1169 delete('Ximport2.vim') 1170 1171 var import_star_as_lines =<< trim END 1172 vim9script 1173 import * as Export from './Xexport.vim' 1174 def UseExport() 1175 g:imported_def = Export.exported 1176 enddef 1177 g:imported_script = Export.exported 1178 assert_equal(1, exists('Export.exported')) 1179 assert_equal(0, exists('Export.notexported')) 1180 UseExport() 1181 END 1182 writefile(import_star_as_lines, 'Ximport.vim') 1183 source Ximport.vim 1184 assert_equal(9883, g:imported_def) 1185 assert_equal(9883, g:imported_script) 1186 1187 var import_star_as_lines_no_dot =<< trim END 1188 vim9script 1189 import * as Export from './Xexport.vim' 1190 def Func() 1191 var dummy = 1 1192 var imported = Export + dummy 1193 enddef 1194 defcompile 1195 END 1196 writefile(import_star_as_lines_no_dot, 'Ximport.vim') 1197 assert_fails('source Ximport.vim', 'E1060:', '', 2, 'Func') 1198 1199 var import_star_as_lines_dot_space =<< trim END 1200 vim9script 1201 import * as Export from './Xexport.vim' 1202 def Func() 1203 var imported = Export . exported 1204 enddef 1205 defcompile 1206 END 1207 writefile(import_star_as_lines_dot_space, 'Ximport.vim') 1208 assert_fails('source Ximport.vim', 'E1074:', '', 1, 'Func') 1209 1210 var import_star_as_duplicated =<< trim END 1211 vim9script 1212 import * as Export from './Xexport.vim' 1213 var some = 'other' 1214 import * as Export from './Xexport.vim' 1215 defcompile 1216 END 1217 writefile(import_star_as_duplicated, 'Ximport.vim') 1218 assert_fails('source Ximport.vim', 'E1073:', '', 4, 'Ximport.vim') 1219 1220 var import_star_as_lines_script_no_dot =<< trim END 1221 vim9script 1222 import * as Export from './Xexport.vim' 1223 g:imported_script = Export exported 1224 END 1225 writefile(import_star_as_lines_script_no_dot, 'Ximport.vim') 1226 assert_fails('source Ximport.vim', 'E1029:') 1227 1228 var import_star_as_lines_script_space_after_dot =<< trim END 1229 vim9script 1230 import * as Export from './Xexport.vim' 1231 g:imported_script = Export. exported 1232 END 1233 writefile(import_star_as_lines_script_space_after_dot, 'Ximport.vim') 1234 assert_fails('source Ximport.vim', 'E1074:') 1235 1236 var import_star_as_lines_missing_name =<< trim END 1237 vim9script 1238 import * as Export from './Xexport.vim' 1239 def Func() 1240 var imported = Export. 1241 enddef 1242 defcompile 1243 END 1244 writefile(import_star_as_lines_missing_name, 'Ximport.vim') 1245 assert_fails('source Ximport.vim', 'E1048:', '', 1, 'Func') 1246 1247 var import_star_as_lbr_lines =<< trim END 1248 vim9script 1249 import * 1250 as Export 1251 from 1252 './Xexport.vim' 1253 def UseExport() 1254 g:imported = Export.exported 1255 enddef 1256 UseExport() 1257 END 1258 writefile(import_star_as_lbr_lines, 'Ximport.vim') 1259 source Ximport.vim 1260 assert_equal(9883, g:imported) 1261 1262 var import_star_lines =<< trim END 1263 vim9script 1264 import * from './Xexport.vim' 1265 END 1266 writefile(import_star_lines, 'Ximport.vim') 1267 assert_fails('source Ximport.vim', 'E1045:', '', 2, 'Ximport.vim') 1268 1269 # try to import something that exists but is not exported 1270 var import_not_exported_lines =<< trim END 1271 vim9script 1272 import name from './Xexport.vim' 1273 END 1274 writefile(import_not_exported_lines, 'Ximport.vim') 1275 assert_fails('source Ximport.vim', 'E1049:', '', 2, 'Ximport.vim') 1276 1277 # try to import something that is already defined 1278 var import_already_defined =<< trim END 1279 vim9script 1280 var exported = 'something' 1281 import exported from './Xexport.vim' 1282 END 1283 writefile(import_already_defined, 'Ximport.vim') 1284 assert_fails('source Ximport.vim', 'E1054:', '', 3, 'Ximport.vim') 1285 1286 # try to import something that is already defined 1287 import_already_defined =<< trim END 1288 vim9script 1289 var exported = 'something' 1290 import * as exported from './Xexport.vim' 1291 END 1292 writefile(import_already_defined, 'Ximport.vim') 1293 assert_fails('source Ximport.vim', 'E1054:', '', 3, 'Ximport.vim') 1294 1295 # try to import something that is already defined 1296 import_already_defined =<< trim END 1297 vim9script 1298 var exported = 'something' 1299 import {exported} from './Xexport.vim' 1300 END 1301 writefile(import_already_defined, 'Ximport.vim') 1302 assert_fails('source Ximport.vim', 'E1054:', '', 3, 'Ximport.vim') 1303 1304 # try changing an imported const 1305 var import_assign_to_const =<< trim END 1306 vim9script 1307 import CONST from './Xexport.vim' 1308 def Assign() 1309 CONST = 987 1310 enddef 1311 defcompile 1312 END 1313 writefile(import_assign_to_const, 'Ximport.vim') 1314 assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign') 1315 1316 # try changing an imported final 1317 var import_assign_to_final =<< trim END 1318 vim9script 1319 import theList from './Xexport.vim' 1320 def Assign() 1321 theList = [2] 1322 enddef 1323 defcompile 1324 END 1325 writefile(import_assign_to_final, 'Ximport.vim') 1326 assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign') 1327 1328 # import a very long name, requires making a copy 1329 var import_long_name_lines =<< trim END 1330 vim9script 1331 import name012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 from './Xexport.vim' 1332 END 1333 writefile(import_long_name_lines, 'Ximport.vim') 1334 assert_fails('source Ximport.vim', 'E1048:', '', 2, 'Ximport.vim') 1335 1336 var import_no_from_lines =<< trim END 1337 vim9script 1338 import name './Xexport.vim' 1339 END 1340 writefile(import_no_from_lines, 'Ximport.vim') 1341 assert_fails('source Ximport.vim', 'E1070:', '', 2, 'Ximport.vim') 1342 1343 var import_invalid_string_lines =<< trim END 1344 vim9script 1345 import name from Xexport.vim 1346 END 1347 writefile(import_invalid_string_lines, 'Ximport.vim') 1348 assert_fails('source Ximport.vim', 'E1071:', '', 2, 'Ximport.vim') 1349 1350 var import_wrong_name_lines =<< trim END 1351 vim9script 1352 import name from './XnoExport.vim' 1353 END 1354 writefile(import_wrong_name_lines, 'Ximport.vim') 1355 assert_fails('source Ximport.vim', 'E1053:', '', 2, 'Ximport.vim') 1356 1357 var import_missing_comma_lines =<< trim END 1358 vim9script 1359 import {exported name} from './Xexport.vim' 1360 END 1361 writefile(import_missing_comma_lines, 'Ximport3.vim') 1362 assert_fails('source Ximport3.vim', 'E1046:', '', 2, 'Ximport3.vim') 1363 1364 delete('Ximport.vim') 1365 delete('Ximport3.vim') 1366 delete('Xexport.vim') 1367 1368 # Check that in a Vim9 script 'cpo' is set to the Vim default. 1369 # Flags added or removed are also applied to the restored value. 1370 set cpo=abcd 1371 var lines =<< trim END 1372 vim9script 1373 g:cpo_in_vim9script = &cpo 1374 set cpo+=f 1375 set cpo-=c 1376 g:cpo_after_vim9script = &cpo 1377 END 1378 writefile(lines, 'Xvim9_script') 1379 source Xvim9_script 1380 assert_equal('fabd', &cpo) 1381 set cpo&vim 1382 assert_equal(&cpo, g:cpo_in_vim9script) 1383 var newcpo = substitute(&cpo, 'c', '', '') .. 'f' 1384 assert_equal(newcpo, g:cpo_after_vim9script) 1385 1386 delete('Xvim9_script') 1387enddef 1388 1389def Test_import_as() 1390 var export_lines =<< trim END 1391 vim9script 1392 export var one = 1 1393 export var yes = 'yes' 1394 export var slist: list<string> 1395 END 1396 writefile(export_lines, 'XexportAs') 1397 1398 var import_lines =<< trim END 1399 vim9script 1400 var one = 'notused' 1401 var yes = 777 1402 import one as thatOne from './XexportAs' 1403 assert_equal(1, thatOne) 1404 import yes as yesYes from './XexportAs' 1405 assert_equal('yes', yesYes) 1406 END 1407 CheckScriptSuccess(import_lines) 1408 1409 import_lines =<< trim END 1410 vim9script 1411 import {one as thatOne, yes as yesYes} from './XexportAs' 1412 assert_equal(1, thatOne) 1413 assert_equal('yes', yesYes) 1414 assert_fails('echo one', 'E121:') 1415 assert_fails('echo yes', 'E121:') 1416 END 1417 CheckScriptSuccess(import_lines) 1418 1419 import_lines =<< trim END 1420 vim9script 1421 import {slist as impSlist} from './XexportAs' 1422 impSlist->add(123) 1423 END 1424 CheckScriptFailure(import_lines, 'E1012: Type mismatch; expected string but got number') 1425 1426 delete('XexportAs') 1427enddef 1428 1429func g:Trigger() 1430 source Ximport.vim 1431 return "echo 'yes'\<CR>" 1432endfunc 1433 1434def Test_import_export_expr_map() 1435 # check that :import and :export work when buffer is locked 1436 var export_lines =<< trim END 1437 vim9script 1438 export def That(): string 1439 return 'yes' 1440 enddef 1441 END 1442 writefile(export_lines, 'Xexport_that.vim') 1443 1444 var import_lines =<< trim END 1445 vim9script 1446 import That from './Xexport_that.vim' 1447 assert_equal('yes', That()) 1448 END 1449 writefile(import_lines, 'Ximport.vim') 1450 1451 nnoremap <expr> trigger g:Trigger() 1452 feedkeys('trigger', "xt") 1453 1454 delete('Xexport_that.vim') 1455 delete('Ximport.vim') 1456 nunmap trigger 1457enddef 1458 1459def Test_import_in_filetype() 1460 # check that :import works when the buffer is locked 1461 mkdir('ftplugin', 'p') 1462 var export_lines =<< trim END 1463 vim9script 1464 export var That = 'yes' 1465 END 1466 writefile(export_lines, 'ftplugin/Xexport_ft.vim') 1467 1468 var import_lines =<< trim END 1469 vim9script 1470 import That from './Xexport_ft.vim' 1471 assert_equal('yes', That) 1472 g:did_load_mytpe = 1 1473 END 1474 writefile(import_lines, 'ftplugin/qf.vim') 1475 1476 var save_rtp = &rtp 1477 &rtp = getcwd() .. ',' .. &rtp 1478 1479 filetype plugin on 1480 copen 1481 assert_equal(1, g:did_load_mytpe) 1482 1483 quit! 1484 delete('Xexport_ft.vim') 1485 delete('ftplugin', 'rf') 1486 &rtp = save_rtp 1487enddef 1488 1489def Test_use_import_in_mapping() 1490 var lines =<< trim END 1491 vim9script 1492 export def Funcx() 1493 g:result = 42 1494 enddef 1495 END 1496 writefile(lines, 'XsomeExport.vim') 1497 lines =<< trim END 1498 vim9script 1499 import Funcx from './XsomeExport.vim' 1500 nnoremap <F3> :call <sid>Funcx()<cr> 1501 END 1502 writefile(lines, 'Xmapscript.vim') 1503 1504 source Xmapscript.vim 1505 feedkeys("\<F3>", "xt") 1506 assert_equal(42, g:result) 1507 1508 unlet g:result 1509 delete('XsomeExport.vim') 1510 delete('Xmapscript.vim') 1511 nunmap <F3> 1512enddef 1513 1514def Test_vim9script_mix() 1515 var lines =<< trim END 1516 if has(g:feature) 1517 " legacy script 1518 let g:legacy = 1 1519 finish 1520 endif 1521 vim9script 1522 g:legacy = 0 1523 END 1524 g:feature = 'eval' 1525 g:legacy = -1 1526 CheckScriptSuccess(lines) 1527 assert_equal(1, g:legacy) 1528 1529 g:feature = 'noteval' 1530 g:legacy = -1 1531 CheckScriptSuccess(lines) 1532 assert_equal(0, g:legacy) 1533enddef 1534 1535def Test_vim9script_fails() 1536 CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:') 1537 CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:') 1538 CheckScriptFailure(['export var some = 123'], 'E1042:') 1539 CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1048:') 1540 CheckScriptFailure(['vim9script', 'export var g:some'], 'E1022:') 1541 CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:') 1542 1543 CheckScriptFailure(['vim9script', 'var str: string', 'str = 1234'], 'E1012:') 1544 CheckScriptFailure(['vim9script', 'const str = "asdf"', 'str = "xxx"'], 'E46:') 1545 1546 assert_fails('vim9script', 'E1038:') 1547 assert_fails('export something', 'E1043:') 1548enddef 1549 1550func Test_import_fails_without_script() 1551 CheckRunVimInTerminal 1552 1553 " call indirectly to avoid compilation error for missing functions 1554 call Run_Test_import_fails_on_command_line() 1555endfunc 1556 1557def Run_Test_import_fails_on_command_line() 1558 var export =<< trim END 1559 vim9script 1560 export def Foo(): number 1561 return 0 1562 enddef 1563 END 1564 writefile(export, 'XexportCmd.vim') 1565 1566 var buf = RunVimInTerminal('-c "import Foo from ''./XexportCmd.vim''"', { 1567 rows: 6, wait_for_ruler: 0}) 1568 WaitForAssert(() => assert_match('^E1094:', term_getline(buf, 5))) 1569 1570 delete('XexportCmd.vim') 1571 StopVimInTerminal(buf) 1572enddef 1573 1574def Test_vim9script_reload_noclear() 1575 var lines =<< trim END 1576 vim9script 1577 export var exported = 'thexport' 1578 END 1579 writefile(lines, 'XExportReload') 1580 lines =<< trim END 1581 vim9script noclear 1582 g:loadCount += 1 1583 var s:reloaded = 'init' 1584 import exported from './XExportReload' 1585 1586 def Again(): string 1587 return 'again' 1588 enddef 1589 1590 if exists('s:loaded') | finish | endif 1591 var s:loaded = true 1592 1593 var s:notReloaded = 'yes' 1594 s:reloaded = 'first' 1595 def g:Values(): list<string> 1596 return [s:reloaded, s:notReloaded, Again(), Once(), exported] 1597 enddef 1598 1599 def Once(): string 1600 return 'once' 1601 enddef 1602 END 1603 writefile(lines, 'XReloaded') 1604 g:loadCount = 0 1605 source XReloaded 1606 assert_equal(1, g:loadCount) 1607 assert_equal(['first', 'yes', 'again', 'once', 'thexport'], g:Values()) 1608 source XReloaded 1609 assert_equal(2, g:loadCount) 1610 assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values()) 1611 source XReloaded 1612 assert_equal(3, g:loadCount) 1613 assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values()) 1614 1615 delete('XReloaded') 1616 delete('XExportReload') 1617 delfunc g:Values 1618 unlet g:loadCount 1619 1620 lines =<< trim END 1621 vim9script 1622 def Inner() 1623 enddef 1624 END 1625 lines->writefile('XreloadScript.vim') 1626 source XreloadScript.vim 1627 1628 lines =<< trim END 1629 vim9script 1630 def Outer() 1631 def Inner() 1632 enddef 1633 enddef 1634 defcompile 1635 END 1636 lines->writefile('XreloadScript.vim') 1637 source XreloadScript.vim 1638 1639 delete('XreloadScript.vim') 1640enddef 1641 1642def Test_vim9script_reload_import() 1643 var lines =<< trim END 1644 vim9script 1645 const var = '' 1646 var valone = 1234 1647 def MyFunc(arg: string) 1648 valone = 5678 1649 enddef 1650 END 1651 var morelines =<< trim END 1652 var valtwo = 222 1653 export def GetValtwo(): number 1654 return valtwo 1655 enddef 1656 END 1657 writefile(lines + morelines, 'Xreload.vim') 1658 source Xreload.vim 1659 source Xreload.vim 1660 source Xreload.vim 1661 1662 var testlines =<< trim END 1663 vim9script 1664 def TheFunc() 1665 import GetValtwo from './Xreload.vim' 1666 assert_equal(222, GetValtwo()) 1667 enddef 1668 TheFunc() 1669 END 1670 writefile(testlines, 'Ximport.vim') 1671 source Ximport.vim 1672 1673 # Test that when not using "morelines" GetValtwo() and valtwo are still 1674 # defined, because import doesn't reload a script. 1675 writefile(lines, 'Xreload.vim') 1676 source Ximport.vim 1677 1678 # cannot declare a var twice 1679 lines =<< trim END 1680 vim9script 1681 var valone = 1234 1682 var valone = 5678 1683 END 1684 writefile(lines, 'Xreload.vim') 1685 assert_fails('source Xreload.vim', 'E1041:', '', 3, 'Xreload.vim') 1686 1687 delete('Xreload.vim') 1688 delete('Ximport.vim') 1689enddef 1690 1691" if a script is reloaded with a script-local variable that changed its type, a 1692" compiled function using that variable must fail. 1693def Test_script_reload_change_type() 1694 var lines =<< trim END 1695 vim9script noclear 1696 var str = 'string' 1697 def g:GetStr(): string 1698 return str .. 'xxx' 1699 enddef 1700 END 1701 writefile(lines, 'Xreload.vim') 1702 source Xreload.vim 1703 echo g:GetStr() 1704 1705 lines =<< trim END 1706 vim9script noclear 1707 var str = 1234 1708 END 1709 writefile(lines, 'Xreload.vim') 1710 source Xreload.vim 1711 assert_fails('echo g:GetStr()', 'E1150:') 1712 1713 delfunc g:GetStr 1714 delete('Xreload.vim') 1715enddef 1716 1717" Define CallFunc so that the test can be compiled 1718command CallFunc echo 'nop' 1719 1720def Test_script_reload_from_function() 1721 var lines =<< trim END 1722 vim9script 1723 1724 if exists('g:loaded') 1725 finish 1726 endif 1727 g:loaded = 1 1728 delcommand CallFunc 1729 command CallFunc Func() 1730 def Func() 1731 so XreloadFunc.vim 1732 g:didTheFunc = 1 1733 enddef 1734 END 1735 writefile(lines, 'XreloadFunc.vim') 1736 source XreloadFunc.vim 1737 CallFunc 1738 assert_equal(1, g:didTheFunc) 1739 1740 delete('XreloadFunc.vim') 1741 delcommand CallFunc 1742 unlet g:loaded 1743 unlet g:didTheFunc 1744enddef 1745 1746def Test_script_var_shadows_function() 1747 var lines =<< trim END 1748 vim9script 1749 def Func(): number 1750 return 123 1751 enddef 1752 var Func = 1 1753 END 1754 CheckScriptFailure(lines, 'E1041:', 5) 1755enddef 1756 1757def Test_script_var_shadows_command() 1758 var lines =<< trim END 1759 var undo = 1 1760 undo = 2 1761 assert_equal(2, undo) 1762 END 1763 CheckDefAndScriptSuccess(lines) 1764 1765 lines =<< trim END 1766 var undo = 1 1767 undo 1768 END 1769 CheckDefAndScriptFailure(lines, 'E1207:', 2) 1770enddef 1771 1772def s:RetSome(): string 1773 return 'some' 1774enddef 1775 1776" Not exported function that is referenced needs to be accessed by the 1777" script-local name. 1778def Test_vim9script_funcref() 1779 var sortlines =<< trim END 1780 vim9script 1781 def Compare(i1: number, i2: number): number 1782 return i2 - i1 1783 enddef 1784 1785 export def FastSort(): list<number> 1786 return range(5)->sort(Compare) 1787 enddef 1788 1789 export def GetString(arg: string): string 1790 return arg 1791 enddef 1792 END 1793 writefile(sortlines, 'Xsort.vim') 1794 1795 var lines =<< trim END 1796 vim9script 1797 import FastSort from './Xsort.vim' 1798 def Test() 1799 g:result = FastSort() 1800 enddef 1801 Test() 1802 1803 # using a function imported with "as" 1804 import * as anAlias from './Xsort.vim' 1805 assert_equal('yes', anAlias.GetString('yes')) 1806 1807 # using the function from a compiled function 1808 def TestMore(): string 1809 var s = s:anAlias.GetString('foo') 1810 return s .. anAlias.GetString('bar') 1811 enddef 1812 assert_equal('foobar', TestMore()) 1813 1814 # error when using a function that isn't exported 1815 assert_fails('anAlias.Compare(1, 2)', 'E1049:') 1816 END 1817 writefile(lines, 'Xscript.vim') 1818 1819 source Xscript.vim 1820 assert_equal([4, 3, 2, 1, 0], g:result) 1821 1822 unlet g:result 1823 delete('Xsort.vim') 1824 delete('Xscript.vim') 1825 1826 var Funcref = function('s:RetSome') 1827 assert_equal('some', Funcref()) 1828enddef 1829 1830" Check that when searching for "FilterFunc" it finds the import in the 1831" script where FastFilter() is called from, both as a string and as a direct 1832" function reference. 1833def Test_vim9script_funcref_other_script() 1834 var filterLines =<< trim END 1835 vim9script 1836 export def FilterFunc(idx: number, val: number): bool 1837 return idx % 2 == 1 1838 enddef 1839 export def FastFilter(): list<number> 1840 return range(10)->filter('FilterFunc') 1841 enddef 1842 export def FastFilterDirect(): list<number> 1843 return range(10)->filter(FilterFunc) 1844 enddef 1845 END 1846 writefile(filterLines, 'Xfilter.vim') 1847 1848 var lines =<< trim END 1849 vim9script 1850 import {FilterFunc, FastFilter, FastFilterDirect} from './Xfilter.vim' 1851 def Test() 1852 var x: list<number> = FastFilter() 1853 enddef 1854 Test() 1855 def TestDirect() 1856 var x: list<number> = FastFilterDirect() 1857 enddef 1858 TestDirect() 1859 END 1860 CheckScriptSuccess(lines) 1861 delete('Xfilter.vim') 1862enddef 1863 1864def Test_vim9script_reload_delfunc() 1865 var first_lines =<< trim END 1866 vim9script 1867 def FuncYes(): string 1868 return 'yes' 1869 enddef 1870 END 1871 var withno_lines =<< trim END 1872 def FuncNo(): string 1873 return 'no' 1874 enddef 1875 def g:DoCheck(no_exists: bool) 1876 assert_equal('yes', FuncYes()) 1877 assert_equal('no', FuncNo()) 1878 enddef 1879 END 1880 var nono_lines =<< trim END 1881 def g:DoCheck(no_exists: bool) 1882 assert_equal('yes', FuncYes()) 1883 assert_fails('FuncNo()', 'E117:', '', 2, 'DoCheck') 1884 enddef 1885 END 1886 1887 # FuncNo() is defined 1888 writefile(first_lines + withno_lines, 'Xreloaded.vim') 1889 source Xreloaded.vim 1890 g:DoCheck(true) 1891 1892 # FuncNo() is not redefined 1893 writefile(first_lines + nono_lines, 'Xreloaded.vim') 1894 source Xreloaded.vim 1895 g:DoCheck(false) 1896 1897 # FuncNo() is back 1898 writefile(first_lines + withno_lines, 'Xreloaded.vim') 1899 source Xreloaded.vim 1900 g:DoCheck(false) 1901 1902 delete('Xreloaded.vim') 1903enddef 1904 1905def Test_vim9script_reload_delvar() 1906 # write the script with a script-local variable 1907 var lines =<< trim END 1908 vim9script 1909 var name = 'string' 1910 END 1911 writefile(lines, 'XreloadVar.vim') 1912 source XreloadVar.vim 1913 1914 # now write the script using the same variable locally - works 1915 lines =<< trim END 1916 vim9script 1917 def Func() 1918 var name = 'string' 1919 enddef 1920 END 1921 writefile(lines, 'XreloadVar.vim') 1922 source XreloadVar.vim 1923 1924 delete('XreloadVar.vim') 1925enddef 1926 1927def Test_import_absolute() 1928 var import_lines = [ 1929 'vim9script', 1930 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"', 1931 'def UseExported()', 1932 ' g:imported_abs = exported', 1933 ' exported = 8888', 1934 ' g:imported_after = exported', 1935 'enddef', 1936 'UseExported()', 1937 'g:import_disassembled = execute("disass UseExported")', 1938 ] 1939 writefile(import_lines, 'Ximport_abs.vim') 1940 writefile(s:export_script_lines, 'Xexport_abs.vim') 1941 1942 source Ximport_abs.vim 1943 1944 assert_equal(9876, g:imported_abs) 1945 assert_equal(8888, g:imported_after) 1946 assert_match('<SNR>\d\+_UseExported\_s*' .. 1947 'g:imported_abs = exported\_s*' .. 1948 '0 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' .. 1949 '1 STOREG g:imported_abs\_s*' .. 1950 'exported = 8888\_s*' .. 1951 '2 PUSHNR 8888\_s*' .. 1952 '3 STORESCRIPT exported-2 in .*Xexport_abs.vim\_s*' .. 1953 'g:imported_after = exported\_s*' .. 1954 '4 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' .. 1955 '5 STOREG g:imported_after', 1956 g:import_disassembled) 1957 1958 Undo_export_script_lines() 1959 unlet g:imported_abs 1960 unlet g:import_disassembled 1961 1962 delete('Ximport_abs.vim') 1963 delete('Xexport_abs.vim') 1964enddef 1965 1966def Test_import_rtp() 1967 var import_lines = [ 1968 'vim9script', 1969 'import exported from "Xexport_rtp.vim"', 1970 'g:imported_rtp = exported', 1971 ] 1972 writefile(import_lines, 'Ximport_rtp.vim') 1973 mkdir('import', 'p') 1974 writefile(s:export_script_lines, 'import/Xexport_rtp.vim') 1975 1976 var save_rtp = &rtp 1977 &rtp = getcwd() 1978 source Ximport_rtp.vim 1979 &rtp = save_rtp 1980 1981 assert_equal(9876, g:imported_rtp) 1982 1983 Undo_export_script_lines() 1984 unlet g:imported_rtp 1985 delete('Ximport_rtp.vim') 1986 delete('import', 'rf') 1987enddef 1988 1989def Test_import_compile_error() 1990 var export_lines = [ 1991 'vim9script', 1992 'export def ExpFunc(): string', 1993 ' return notDefined', 1994 'enddef', 1995 ] 1996 writefile(export_lines, 'Xexported.vim') 1997 1998 var import_lines = [ 1999 'vim9script', 2000 'import ExpFunc from "./Xexported.vim"', 2001 'def ImpFunc()', 2002 ' echo ExpFunc()', 2003 'enddef', 2004 'defcompile', 2005 ] 2006 writefile(import_lines, 'Ximport.vim') 2007 2008 try 2009 source Ximport.vim 2010 catch /E1001/ 2011 # Error should be fore the Xexported.vim file. 2012 assert_match('E1001: Variable not found: notDefined', v:exception) 2013 assert_match('function <SNR>\d\+_ImpFunc\[1\]..<SNR>\d\+_ExpFunc, line 1', v:throwpoint) 2014 endtry 2015 2016 delete('Xexported.vim') 2017 delete('Ximport.vim') 2018enddef 2019 2020def Test_func_redefine_error() 2021 var lines = [ 2022 'vim9script', 2023 'def Func()', 2024 ' eval [][0]', 2025 'enddef', 2026 'Func()', 2027 ] 2028 writefile(lines, 'Xtestscript.vim') 2029 2030 for count in range(3) 2031 try 2032 source Xtestscript.vim 2033 catch /E684/ 2034 # function name should contain <SNR> every time 2035 assert_match('E684: list index out of range', v:exception) 2036 assert_match('function <SNR>\d\+_Func, line 1', v:throwpoint) 2037 endtry 2038 endfor 2039 2040 delete('Xtestscript.vim') 2041enddef 2042 2043def Test_func_overrules_import_fails() 2044 var export_lines =<< trim END 2045 vim9script 2046 export def Func() 2047 echo 'imported' 2048 enddef 2049 END 2050 writefile(export_lines, 'XexportedFunc.vim') 2051 2052 var lines =<< trim END 2053 vim9script 2054 import Func from './XexportedFunc.vim' 2055 def Func() 2056 echo 'local to function' 2057 enddef 2058 END 2059 CheckScriptFailure(lines, 'E1073:') 2060 2061 lines =<< trim END 2062 vim9script 2063 import Func from './XexportedFunc.vim' 2064 def Outer() 2065 def Func() 2066 echo 'local to function' 2067 enddef 2068 enddef 2069 defcompile 2070 END 2071 CheckScriptFailure(lines, 'E1073:') 2072 2073 delete('XexportedFunc.vim') 2074enddef 2075 2076def Test_func_redefine_fails() 2077 var lines =<< trim END 2078 vim9script 2079 def Func() 2080 echo 'one' 2081 enddef 2082 def Func() 2083 echo 'two' 2084 enddef 2085 END 2086 CheckScriptFailure(lines, 'E1073:') 2087 2088 lines =<< trim END 2089 vim9script 2090 def Foo(): string 2091 return 'foo' 2092 enddef 2093 def Func() 2094 var Foo = {-> 'lambda'} 2095 enddef 2096 defcompile 2097 END 2098 CheckScriptFailure(lines, 'E1073:') 2099enddef 2100 2101def Test_fixed_size_list() 2102 # will be allocated as one piece of memory, check that changes work 2103 var l = [1, 2, 3, 4] 2104 l->remove(0) 2105 l->add(5) 2106 l->insert(99, 1) 2107 assert_equal([2, 99, 3, 4, 5], l) 2108enddef 2109 2110def Test_no_insert_xit() 2111 CheckDefExecFailure(['a = 1'], 'E1100:') 2112 CheckDefExecFailure(['c = 1'], 'E1100:') 2113 CheckDefExecFailure(['i = 1'], 'E1100:') 2114 CheckDefExecFailure(['t = 1'], 'E1100:') 2115 CheckDefExecFailure(['x = 1'], 'E1100:') 2116 2117 CheckScriptFailure(['vim9script', 'a = 1'], 'E488:') 2118 CheckScriptFailure(['vim9script', 'a'], 'E1100:') 2119 CheckScriptFailure(['vim9script', 'c = 1'], 'E488:') 2120 CheckScriptFailure(['vim9script', 'c'], 'E1100:') 2121 CheckScriptFailure(['vim9script', 'i = 1'], 'E488:') 2122 CheckScriptFailure(['vim9script', 'i'], 'E1100:') 2123 CheckScriptFailure(['vim9script', 'o = 1'], 'E1100:') 2124 CheckScriptFailure(['vim9script', 'o'], 'E1100:') 2125 CheckScriptFailure(['vim9script', 't'], 'E1100:') 2126 CheckScriptFailure(['vim9script', 't = 1'], 'E1100:') 2127 CheckScriptFailure(['vim9script', 'x = 1'], 'E1100:') 2128enddef 2129 2130def IfElse(what: number): string 2131 var res = '' 2132 if what == 1 2133 res = "one" 2134 elseif what == 2 2135 res = "two" 2136 else 2137 res = "three" 2138 endif 2139 return res 2140enddef 2141 2142def Test_if_elseif_else() 2143 assert_equal('one', IfElse(1)) 2144 assert_equal('two', IfElse(2)) 2145 assert_equal('three', IfElse(3)) 2146enddef 2147 2148def Test_if_elseif_else_fails() 2149 CheckDefFailure(['elseif true'], 'E582:') 2150 CheckDefFailure(['else'], 'E581:') 2151 CheckDefFailure(['endif'], 'E580:') 2152 CheckDefFailure(['if g:abool', 'elseif xxx'], 'E1001:') 2153 CheckDefFailure(['if true', 'echo 1'], 'E171:') 2154 2155 var lines =<< trim END 2156 var s = '' 2157 if s = '' 2158 endif 2159 END 2160 CheckDefFailure(lines, 'E488:') 2161 2162 lines =<< trim END 2163 var s = '' 2164 if s == '' 2165 elseif s = '' 2166 endif 2167 END 2168 CheckDefFailure(lines, 'E488:') 2169enddef 2170 2171let g:bool_true = v:true 2172let g:bool_false = v:false 2173 2174def Test_if_const_expr() 2175 var res = false 2176 if true ? true : false 2177 res = true 2178 endif 2179 assert_equal(true, res) 2180 2181 g:glob = 2 2182 if false 2183 execute('g:glob = 3') 2184 endif 2185 assert_equal(2, g:glob) 2186 if true 2187 execute('g:glob = 3') 2188 endif 2189 assert_equal(3, g:glob) 2190 2191 res = false 2192 if g:bool_true ? true : false 2193 res = true 2194 endif 2195 assert_equal(true, res) 2196 2197 res = false 2198 if true ? g:bool_true : false 2199 res = true 2200 endif 2201 assert_equal(true, res) 2202 2203 res = false 2204 if true ? true : g:bool_false 2205 res = true 2206 endif 2207 assert_equal(true, res) 2208 2209 res = false 2210 if true ? false : true 2211 res = true 2212 endif 2213 assert_equal(false, res) 2214 2215 res = false 2216 if false ? false : true 2217 res = true 2218 endif 2219 assert_equal(true, res) 2220 2221 res = false 2222 if false ? true : false 2223 res = true 2224 endif 2225 assert_equal(false, res) 2226 2227 res = false 2228 if has('xyz') ? true : false 2229 res = true 2230 endif 2231 assert_equal(false, res) 2232 2233 res = false 2234 if true && true 2235 res = true 2236 endif 2237 assert_equal(true, res) 2238 2239 res = false 2240 if true && false 2241 res = true 2242 endif 2243 assert_equal(false, res) 2244 2245 res = false 2246 if g:bool_true && false 2247 res = true 2248 endif 2249 assert_equal(false, res) 2250 2251 res = false 2252 if true && g:bool_false 2253 res = true 2254 endif 2255 assert_equal(false, res) 2256 2257 res = false 2258 if false && false 2259 res = true 2260 endif 2261 assert_equal(false, res) 2262 2263 res = false 2264 if true || false 2265 res = true 2266 endif 2267 assert_equal(true, res) 2268 2269 res = false 2270 if g:bool_true || false 2271 res = true 2272 endif 2273 assert_equal(true, res) 2274 2275 res = false 2276 if true || g:bool_false 2277 res = true 2278 endif 2279 assert_equal(true, res) 2280 2281 res = false 2282 if false || false 2283 res = true 2284 endif 2285 assert_equal(false, res) 2286 2287 # with constant "false" expression may be invalid so long as the syntax is OK 2288 if false | eval 1 + 2 | endif 2289 if false | eval burp + 234 | endif 2290 if false | echo burp 234 'asd' | endif 2291 if false 2292 burp 2293 endif 2294enddef 2295 2296def Test_if_const_expr_fails() 2297 CheckDefFailure(['if "aaa" == "bbb'], 'E114:') 2298 CheckDefFailure(["if 'aaa' == 'bbb"], 'E115:') 2299 CheckDefFailure(["if has('aaa'"], 'E110:') 2300 CheckDefFailure(["if has('aaa') ? true false"], 'E109:') 2301enddef 2302 2303def RunNested(i: number): number 2304 var x: number = 0 2305 if i % 2 2306 if 1 2307 # comment 2308 else 2309 # comment 2310 endif 2311 x += 1 2312 else 2313 x += 1000 2314 endif 2315 return x 2316enddef 2317 2318def Test_nested_if() 2319 assert_equal(1, RunNested(1)) 2320 assert_equal(1000, RunNested(2)) 2321enddef 2322 2323def Test_execute_cmd() 2324 # missing argument is ignored 2325 execute 2326 execute # comment 2327 2328 new 2329 setline(1, 'default') 2330 execute 'setline(1, "execute-string")' 2331 assert_equal('execute-string', getline(1)) 2332 2333 execute "setline(1, 'execute-string')" 2334 assert_equal('execute-string', getline(1)) 2335 2336 var cmd1 = 'setline(1,' 2337 var cmd2 = '"execute-var")' 2338 execute cmd1 cmd2 # comment 2339 assert_equal('execute-var', getline(1)) 2340 2341 execute cmd1 cmd2 '|setline(1, "execute-var-string")' 2342 assert_equal('execute-var-string', getline(1)) 2343 2344 var cmd_first = 'call ' 2345 var cmd_last = 'setline(1, "execute-var-var")' 2346 execute cmd_first .. cmd_last 2347 assert_equal('execute-var-var', getline(1)) 2348 bwipe! 2349 2350 var n = true 2351 execute 'echomsg' (n ? '"true"' : '"no"') 2352 assert_match('^true$', Screenline(&lines)) 2353 2354 echomsg [1, 2, 3] {a: 1, b: 2} 2355 assert_match('^\[1, 2, 3\] {''a'': 1, ''b'': 2}$', Screenline(&lines)) 2356 2357 CheckDefFailure(['execute xxx'], 'E1001:', 1) 2358 CheckDefExecFailure(['execute "tabnext " .. 8'], 'E475:', 1) 2359 CheckDefFailure(['execute "cmd"# comment'], 'E488:', 1) 2360enddef 2361 2362def Test_execute_cmd_vimscript() 2363 # only checks line continuation 2364 var lines =<< trim END 2365 vim9script 2366 execute 'g:someVar' 2367 .. ' = ' .. 2368 '28' 2369 assert_equal(28, g:someVar) 2370 unlet g:someVar 2371 END 2372 CheckScriptSuccess(lines) 2373enddef 2374 2375def Test_echo_cmd() 2376 echo 'some' # comment 2377 echon 'thing' 2378 assert_match('^something$', Screenline(&lines)) 2379 2380 echo "some" # comment 2381 echon "thing" 2382 assert_match('^something$', Screenline(&lines)) 2383 2384 var str1 = 'some' 2385 var str2 = 'more' 2386 echo str1 str2 2387 assert_match('^some more$', Screenline(&lines)) 2388 2389 CheckDefFailure(['echo "xxx"# comment'], 'E488:') 2390enddef 2391 2392def Test_echomsg_cmd() 2393 echomsg 'some' 'more' # comment 2394 assert_match('^some more$', Screenline(&lines)) 2395 echo 'clear' 2396 :1messages 2397 assert_match('^some more$', Screenline(&lines)) 2398 2399 CheckDefFailure(['echomsg "xxx"# comment'], 'E488:') 2400enddef 2401 2402def Test_echomsg_cmd_vimscript() 2403 # only checks line continuation 2404 var lines =<< trim END 2405 vim9script 2406 echomsg 'here' 2407 .. ' is ' .. 2408 'a message' 2409 assert_match('^here is a message$', Screenline(&lines)) 2410 END 2411 CheckScriptSuccess(lines) 2412enddef 2413 2414def Test_echoerr_cmd() 2415 try 2416 echoerr 'something' 'wrong' # comment 2417 catch 2418 assert_match('something wrong', v:exception) 2419 endtry 2420enddef 2421 2422def Test_echoerr_cmd_vimscript() 2423 # only checks line continuation 2424 var lines =<< trim END 2425 vim9script 2426 try 2427 echoerr 'this' 2428 .. ' is ' .. 2429 'wrong' 2430 catch 2431 assert_match('this is wrong', v:exception) 2432 endtry 2433 END 2434 CheckScriptSuccess(lines) 2435enddef 2436 2437def Test_for_outside_of_function() 2438 var lines =<< trim END 2439 vim9script 2440 new 2441 for var in range(0, 3) 2442 append(line('$'), var) 2443 endfor 2444 assert_equal(['', '0', '1', '2', '3'], getline(1, '$')) 2445 bwipe! 2446 2447 var result = '' 2448 for i in [1, 2, 3] 2449 var loop = ' loop ' .. i 2450 result ..= loop 2451 endfor 2452 assert_equal(' loop 1 loop 2 loop 3', result) 2453 END 2454 writefile(lines, 'Xvim9for.vim') 2455 source Xvim9for.vim 2456 delete('Xvim9for.vim') 2457enddef 2458 2459def Test_for_loop() 2460 var lines =<< trim END 2461 var result = '' 2462 for cnt in range(7) 2463 if cnt == 4 2464 break 2465 endif 2466 if cnt == 2 2467 continue 2468 endif 2469 result ..= cnt .. '_' 2470 endfor 2471 assert_equal('0_1_3_', result) 2472 2473 var concat = '' 2474 for str in eval('["one", "two"]') 2475 concat ..= str 2476 endfor 2477 assert_equal('onetwo', concat) 2478 2479 var total = 0 2480 for nr in 2481 [1, 2, 3] 2482 total += nr 2483 endfor 2484 assert_equal(6, total) 2485 2486 total = 0 2487 for nr 2488 in [1, 2, 3] 2489 total += nr 2490 endfor 2491 assert_equal(6, total) 2492 2493 total = 0 2494 for nr 2495 in 2496 [1, 2, 3] 2497 total += nr 2498 endfor 2499 assert_equal(6, total) 2500 2501 # with type 2502 total = 0 2503 for n: number in [1, 2, 3] 2504 total += n 2505 endfor 2506 assert_equal(6, total) 2507 2508 var chars = '' 2509 for s: string in 'foobar' 2510 chars ..= s 2511 endfor 2512 assert_equal('foobar', chars) 2513 2514 chars = '' 2515 for x: string in {a: 'a', b: 'b'}->values() 2516 chars ..= x 2517 endfor 2518 assert_equal('ab', chars) 2519 2520 # unpack with type 2521 var res = '' 2522 for [n: number, s: string] in [[1, 'a'], [2, 'b']] 2523 res ..= n .. s 2524 endfor 2525 assert_equal('1a2b', res) 2526 2527 # unpack with one var 2528 var reslist = [] 2529 for [x] in [['aaa'], ['bbb']] 2530 reslist->add(x) 2531 endfor 2532 assert_equal(['aaa', 'bbb'], reslist) 2533 2534 # loop over string 2535 res = '' 2536 for c in 'aéc̀d' 2537 res ..= c .. '-' 2538 endfor 2539 assert_equal('a-é-c̀-d-', res) 2540 2541 res = '' 2542 for c in '' 2543 res ..= c .. '-' 2544 endfor 2545 assert_equal('', res) 2546 2547 res = '' 2548 for c in test_null_string() 2549 res ..= c .. '-' 2550 endfor 2551 assert_equal('', res) 2552 2553 var foo: list<dict<any>> = [ 2554 {a: 'Cat'} 2555 ] 2556 for dd in foo 2557 dd.counter = 12 2558 endfor 2559 assert_equal([{a: 'Cat', counter: 12}], foo) 2560 2561 reslist = [] 2562 for _ in range(3) 2563 reslist->add('x') 2564 endfor 2565 assert_equal(['x', 'x', 'x'], reslist) 2566 END 2567 CheckDefAndScriptSuccess(lines) 2568enddef 2569 2570def Test_for_loop_fails() 2571 CheckDefAndScriptFailure2(['for '], 'E1097:', 'E690:') 2572 CheckDefAndScriptFailure2(['for x'], 'E1097:', 'E690:') 2573 CheckDefAndScriptFailure2(['for x in'], 'E1097:', 'E15:') 2574 CheckDefAndScriptFailure(['for # in range(5)'], 'E690:') 2575 CheckDefAndScriptFailure(['for i In range(5)'], 'E690:') 2576 CheckDefAndScriptFailure2(['var x = 5', 'for x in range(5)', 'endfor'], 'E1017:', 'E1041:') 2577 CheckScriptFailure(['vim9script', 'var x = 5', 'for x in range(5)', '# comment', 'endfor'], 'E1041:', 3) 2578 CheckScriptFailure(['def Func(arg: any)', 'for arg in range(5)', 'enddef', 'defcompile'], 'E1006:') 2579 delfunc! g:Func 2580 CheckDefFailure(['for i in xxx'], 'E1001:') 2581 CheckDefFailure(['endfor'], 'E588:') 2582 CheckDefFailure(['for i in range(3)', 'echo 3'], 'E170:') 2583 2584 # wrong type detected at compile time 2585 CheckDefFailure(['for i in {a: 1}', 'echo 3', 'endfor'], 'E1177: For loop on dict not supported') 2586 2587 # wrong type detected at runtime 2588 g:adict = {a: 1} 2589 CheckDefExecFailure(['for i in g:adict', 'echo 3', 'endfor'], 'E1177: For loop on dict not supported') 2590 unlet g:adict 2591 2592 var lines =<< trim END 2593 var d: list<dict<any>> = [{a: 0}] 2594 for e in d 2595 e = {a: 0, b: ''} 2596 endfor 2597 END 2598 CheckDefAndScriptFailure2(lines, 'E1018:', 'E46:', 3) 2599 2600 lines =<< trim END 2601 for nr: number in ['foo'] 2602 endfor 2603 END 2604 CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected number but got string', 1) 2605 2606 lines =<< trim END 2607 for n : number in [1, 2] 2608 echo n 2609 endfor 2610 END 2611 CheckDefAndScriptFailure(lines, 'E1059:', 1) 2612 2613 lines =<< trim END 2614 var d: dict<number> = {a: 1, b: 2} 2615 for [k: job, v: job] in d->items() 2616 echo k v 2617 endfor 2618 END 2619 CheckDefExecAndScriptFailure(lines, 'E1012: Type mismatch; expected job but got string', 2) 2620enddef 2621 2622def Test_for_loop_script_var() 2623 # cannot use s:var in a :def function 2624 CheckDefFailure(['for s:var in range(3)', 'echo 3'], 'E1101:') 2625 2626 # can use s:var in Vim9 script, with or without s: 2627 var lines =<< trim END 2628 vim9script 2629 var total = 0 2630 for s:var in [1, 2, 3] 2631 total += s:var 2632 endfor 2633 assert_equal(6, total) 2634 2635 total = 0 2636 for var in [1, 2, 3] 2637 total += var 2638 endfor 2639 assert_equal(6, total) 2640 END 2641enddef 2642 2643def Test_for_loop_unpack() 2644 var lines =<< trim END 2645 var result = [] 2646 for [v1, v2] in [[1, 2], [3, 4]] 2647 result->add(v1) 2648 result->add(v2) 2649 endfor 2650 assert_equal([1, 2, 3, 4], result) 2651 2652 result = [] 2653 for [v1, v2; v3] in [[1, 2], [3, 4, 5, 6]] 2654 result->add(v1) 2655 result->add(v2) 2656 result->add(v3) 2657 endfor 2658 assert_equal([1, 2, [], 3, 4, [5, 6]], result) 2659 2660 result = [] 2661 for [&ts, &sw] in [[1, 2], [3, 4]] 2662 result->add(&ts) 2663 result->add(&sw) 2664 endfor 2665 assert_equal([1, 2, 3, 4], result) 2666 2667 var slist: list<string> 2668 for [$LOOPVAR, @r, v:errmsg] in [['a', 'b', 'c'], ['d', 'e', 'f']] 2669 slist->add($LOOPVAR) 2670 slist->add(@r) 2671 slist->add(v:errmsg) 2672 endfor 2673 assert_equal(['a', 'b', 'c', 'd', 'e', 'f'], slist) 2674 2675 slist = [] 2676 for [g:globalvar, b:bufvar, w:winvar, t:tabvar] in [['global', 'buf', 'win', 'tab'], ['1', '2', '3', '4']] 2677 slist->add(g:globalvar) 2678 slist->add(b:bufvar) 2679 slist->add(w:winvar) 2680 slist->add(t:tabvar) 2681 endfor 2682 assert_equal(['global', 'buf', 'win', 'tab', '1', '2', '3', '4'], slist) 2683 unlet! g:globalvar b:bufvar w:winvar t:tabvar 2684 2685 var res = [] 2686 for [_, n, _] in [[1, 2, 3], [4, 5, 6]] 2687 res->add(n) 2688 endfor 2689 assert_equal([2, 5], res) 2690 END 2691 CheckDefAndScriptSuccess(lines) 2692 2693 lines =<< trim END 2694 for [v1, v2] in [[1, 2, 3], [3, 4]] 2695 echo v1 v2 2696 endfor 2697 END 2698 CheckDefExecFailure(lines, 'E710:', 1) 2699 2700 lines =<< trim END 2701 for [v1, v2] in [[1], [3, 4]] 2702 echo v1 v2 2703 endfor 2704 END 2705 CheckDefExecFailure(lines, 'E711:', 1) 2706 2707 lines =<< trim END 2708 for [v1, v1] in [[1, 2], [3, 4]] 2709 echo v1 2710 endfor 2711 END 2712 CheckDefExecFailure(lines, 'E1017:', 1) 2713enddef 2714 2715def Test_for_loop_with_try_continue() 2716 var lines =<< trim END 2717 var looped = 0 2718 var cleanup = 0 2719 for i in range(3) 2720 looped += 1 2721 try 2722 eval [][0] 2723 catch 2724 continue 2725 finally 2726 cleanup += 1 2727 endtry 2728 endfor 2729 assert_equal(3, looped) 2730 assert_equal(3, cleanup) 2731 END 2732 CheckDefAndScriptSuccess(lines) 2733enddef 2734 2735def Test_while_loop() 2736 var result = '' 2737 var cnt = 0 2738 while cnt < 555 2739 if cnt == 3 2740 break 2741 endif 2742 cnt += 1 2743 if cnt == 2 2744 continue 2745 endif 2746 result ..= cnt .. '_' 2747 endwhile 2748 assert_equal('1_3_', result) 2749 2750 var s = '' 2751 while s == 'x' # {comment} 2752 endwhile 2753enddef 2754 2755def Test_while_loop_fails() 2756 CheckDefFailure(['while xxx'], 'E1001:') 2757 CheckDefFailure(['endwhile'], 'E588:') 2758 CheckDefFailure(['continue'], 'E586:') 2759 CheckDefFailure(['if true', 'continue'], 'E586:') 2760 CheckDefFailure(['break'], 'E587:') 2761 CheckDefFailure(['if true', 'break'], 'E587:') 2762 CheckDefFailure(['while 1', 'echo 3'], 'E170:') 2763 2764 var lines =<< trim END 2765 var s = '' 2766 while s = '' 2767 endwhile 2768 END 2769 CheckDefFailure(lines, 'E488:') 2770enddef 2771 2772def Test_interrupt_loop() 2773 var caught = false 2774 var x = 0 2775 try 2776 while 1 2777 x += 1 2778 if x == 100 2779 feedkeys("\<C-C>", 'Lt') 2780 endif 2781 endwhile 2782 catch 2783 caught = true 2784 assert_equal(100, x) 2785 endtry 2786 assert_true(caught, 'should have caught an exception') 2787 # consume the CTRL-C 2788 getchar(0) 2789enddef 2790 2791def Test_automatic_line_continuation() 2792 var mylist = [ 2793 'one', 2794 'two', 2795 'three', 2796 ] # comment 2797 assert_equal(['one', 'two', 'three'], mylist) 2798 2799 var mydict = { 2800 ['one']: 1, 2801 ['two']: 2, 2802 ['three']: 2803 3, 2804 } # comment 2805 assert_equal({one: 1, two: 2, three: 3}, mydict) 2806 mydict = { 2807 one: 1, # comment 2808 two: # comment 2809 2, # comment 2810 three: 3 # comment 2811 } 2812 assert_equal({one: 1, two: 2, three: 3}, mydict) 2813 mydict = { 2814 one: 1, 2815 two: 2816 2, 2817 three: 3 2818 } 2819 assert_equal({one: 1, two: 2, three: 3}, mydict) 2820 2821 assert_equal( 2822 ['one', 'two', 'three'], 2823 split('one two three') 2824 ) 2825enddef 2826 2827def Test_vim9_comment() 2828 CheckScriptSuccess([ 2829 'vim9script', 2830 '# something', 2831 '#something', 2832 '#{something', 2833 ]) 2834 2835 split Xfile 2836 CheckScriptSuccess([ 2837 'vim9script', 2838 'edit #something', 2839 ]) 2840 CheckScriptSuccess([ 2841 'vim9script', 2842 'edit #{something', 2843 ]) 2844 close 2845 2846 CheckScriptFailure([ 2847 'vim9script', 2848 ':# something', 2849 ], 'E488:') 2850 CheckScriptFailure([ 2851 '# something', 2852 ], 'E488:') 2853 CheckScriptFailure([ 2854 ':# something', 2855 ], 'E488:') 2856 2857 { # block start 2858 } # block end 2859 CheckDefFailure([ 2860 '{# comment', 2861 ], 'E488:') 2862 CheckDefFailure([ 2863 '{', 2864 '}# comment', 2865 ], 'E488:') 2866 2867 echo "yes" # comment 2868 CheckDefFailure([ 2869 'echo "yes"# comment', 2870 ], 'E488:') 2871 CheckScriptSuccess([ 2872 'vim9script', 2873 'echo "yes" # something', 2874 ]) 2875 CheckScriptFailure([ 2876 'vim9script', 2877 'echo "yes"# something', 2878 ], 'E121:') 2879 CheckScriptFailure([ 2880 'vim9script', 2881 'echo# something', 2882 ], 'E1144:') 2883 CheckScriptFailure([ 2884 'echo "yes" # something', 2885 ], 'E121:') 2886 2887 exe "echo" # comment 2888 CheckDefFailure([ 2889 'exe "echo"# comment', 2890 ], 'E488:') 2891 CheckScriptSuccess([ 2892 'vim9script', 2893 'exe "echo" # something', 2894 ]) 2895 CheckScriptFailure([ 2896 'vim9script', 2897 'exe "echo"# something', 2898 ], 'E121:') 2899 CheckScriptFailure([ 2900 'vim9script', 2901 'exe# something', 2902 ], 'E1144:') 2903 CheckScriptFailure([ 2904 'exe "echo" # something', 2905 ], 'E121:') 2906 2907 CheckDefFailure([ 2908 'try# comment', 2909 ' echo "yes"', 2910 'catch', 2911 'endtry', 2912 ], 'E1144:') 2913 CheckScriptFailure([ 2914 'vim9script', 2915 'try# comment', 2916 'echo "yes"', 2917 ], 'E1144:') 2918 CheckDefFailure([ 2919 'try', 2920 ' throw#comment', 2921 'catch', 2922 'endtry', 2923 ], 'E1144:') 2924 CheckDefFailure([ 2925 'try', 2926 ' throw "yes"#comment', 2927 'catch', 2928 'endtry', 2929 ], 'E488:') 2930 CheckDefFailure([ 2931 'try', 2932 ' echo "yes"', 2933 'catch# comment', 2934 'endtry', 2935 ], 'E1144:') 2936 CheckScriptFailure([ 2937 'vim9script', 2938 'try', 2939 ' echo "yes"', 2940 'catch# comment', 2941 'endtry', 2942 ], 'E1144:') 2943 CheckDefFailure([ 2944 'try', 2945 ' echo "yes"', 2946 'catch /pat/# comment', 2947 'endtry', 2948 ], 'E488:') 2949 CheckDefFailure([ 2950 'try', 2951 'echo "yes"', 2952 'catch', 2953 'endtry# comment', 2954 ], 'E1144:') 2955 CheckScriptFailure([ 2956 'vim9script', 2957 'try', 2958 ' echo "yes"', 2959 'catch', 2960 'endtry# comment', 2961 ], 'E1144:') 2962 2963 CheckScriptSuccess([ 2964 'vim9script', 2965 'hi # comment', 2966 ]) 2967 CheckScriptFailure([ 2968 'vim9script', 2969 'hi# comment', 2970 ], 'E1144:') 2971 CheckScriptSuccess([ 2972 'vim9script', 2973 'hi Search # comment', 2974 ]) 2975 CheckScriptFailure([ 2976 'vim9script', 2977 'hi Search# comment', 2978 ], 'E416:') 2979 CheckScriptSuccess([ 2980 'vim9script', 2981 'hi link This Search # comment', 2982 ]) 2983 CheckScriptFailure([ 2984 'vim9script', 2985 'hi link This That# comment', 2986 ], 'E413:') 2987 CheckScriptSuccess([ 2988 'vim9script', 2989 'hi clear This # comment', 2990 'hi clear # comment', 2991 ]) 2992 # not tested, because it doesn't give an error but a warning: 2993 # hi clear This# comment', 2994 CheckScriptFailure([ 2995 'vim9script', 2996 'hi clear# comment', 2997 ], 'E416:') 2998 2999 CheckScriptSuccess([ 3000 'vim9script', 3001 'hi Group term=bold', 3002 'match Group /todo/ # comment', 3003 ]) 3004 CheckScriptFailure([ 3005 'vim9script', 3006 'hi Group term=bold', 3007 'match Group /todo/# comment', 3008 ], 'E488:') 3009 CheckScriptSuccess([ 3010 'vim9script', 3011 'match # comment', 3012 ]) 3013 CheckScriptFailure([ 3014 'vim9script', 3015 'match# comment', 3016 ], 'E1144:') 3017 CheckScriptSuccess([ 3018 'vim9script', 3019 'match none # comment', 3020 ]) 3021 CheckScriptFailure([ 3022 'vim9script', 3023 'match none# comment', 3024 ], 'E475:') 3025 3026 CheckScriptSuccess([ 3027 'vim9script', 3028 'menutrans clear # comment', 3029 ]) 3030 CheckScriptFailure([ 3031 'vim9script', 3032 'menutrans clear# comment text', 3033 ], 'E474:') 3034 3035 CheckScriptSuccess([ 3036 'vim9script', 3037 'syntax clear # comment', 3038 ]) 3039 CheckScriptFailure([ 3040 'vim9script', 3041 'syntax clear# comment text', 3042 ], 'E28:') 3043 CheckScriptSuccess([ 3044 'vim9script', 3045 'syntax keyword Word some', 3046 'syntax clear Word # comment', 3047 ]) 3048 CheckScriptFailure([ 3049 'vim9script', 3050 'syntax keyword Word some', 3051 'syntax clear Word# comment text', 3052 ], 'E28:') 3053 3054 CheckScriptSuccess([ 3055 'vim9script', 3056 'syntax list # comment', 3057 ]) 3058 CheckScriptFailure([ 3059 'vim9script', 3060 'syntax list# comment text', 3061 ], 'E28:') 3062 3063 CheckScriptSuccess([ 3064 'vim9script', 3065 'syntax match Word /pat/ oneline # comment', 3066 ]) 3067 CheckScriptFailure([ 3068 'vim9script', 3069 'syntax match Word /pat/ oneline# comment', 3070 ], 'E475:') 3071 3072 CheckScriptSuccess([ 3073 'vim9script', 3074 'syntax keyword Word word # comm[ent', 3075 ]) 3076 CheckScriptFailure([ 3077 'vim9script', 3078 'syntax keyword Word word# comm[ent', 3079 ], 'E789:') 3080 3081 CheckScriptSuccess([ 3082 'vim9script', 3083 'syntax match Word /pat/ # comment', 3084 ]) 3085 CheckScriptFailure([ 3086 'vim9script', 3087 'syntax match Word /pat/# comment', 3088 ], 'E402:') 3089 3090 CheckScriptSuccess([ 3091 'vim9script', 3092 'syntax match Word /pat/ contains=Something # comment', 3093 ]) 3094 CheckScriptFailure([ 3095 'vim9script', 3096 'syntax match Word /pat/ contains=Something# comment', 3097 ], 'E475:') 3098 CheckScriptFailure([ 3099 'vim9script', 3100 'syntax match Word /pat/ contains= # comment', 3101 ], 'E406:') 3102 CheckScriptFailure([ 3103 'vim9script', 3104 'syntax match Word /pat/ contains=# comment', 3105 ], 'E475:') 3106 3107 CheckScriptSuccess([ 3108 'vim9script', 3109 'syntax region Word start=/pat/ end=/pat/ # comment', 3110 ]) 3111 CheckScriptFailure([ 3112 'vim9script', 3113 'syntax region Word start=/pat/ end=/pat/# comment', 3114 ], 'E402:') 3115 3116 CheckScriptSuccess([ 3117 'vim9script', 3118 'syntax sync # comment', 3119 ]) 3120 CheckScriptFailure([ 3121 'vim9script', 3122 'syntax sync# comment', 3123 ], 'E404:') 3124 CheckScriptSuccess([ 3125 'vim9script', 3126 'syntax sync ccomment # comment', 3127 ]) 3128 CheckScriptFailure([ 3129 'vim9script', 3130 'syntax sync ccomment# comment', 3131 ], 'E404:') 3132 3133 CheckScriptSuccess([ 3134 'vim9script', 3135 'syntax cluster Some contains=Word # comment', 3136 ]) 3137 CheckScriptFailure([ 3138 'vim9script', 3139 'syntax cluster Some contains=Word# comment', 3140 ], 'E475:') 3141 3142 CheckScriptSuccess([ 3143 'vim9script', 3144 'command Echo echo # comment', 3145 'command Echo # comment', 3146 'delcommand Echo', 3147 ]) 3148 CheckScriptFailure([ 3149 'vim9script', 3150 'command Echo echo# comment', 3151 'Echo', 3152 ], 'E1144:') 3153 delcommand Echo 3154 3155 var curdir = getcwd() 3156 CheckScriptSuccess([ 3157 'command Echo cd " comment', 3158 'Echo', 3159 'delcommand Echo', 3160 ]) 3161 CheckScriptSuccess([ 3162 'vim9script', 3163 'command Echo cd # comment', 3164 'Echo', 3165 'delcommand Echo', 3166 ]) 3167 CheckScriptFailure([ 3168 'vim9script', 3169 'command Echo cd " comment', 3170 'Echo', 3171 ], 'E344:') 3172 delcommand Echo 3173 chdir(curdir) 3174 3175 CheckScriptFailure([ 3176 'vim9script', 3177 'command Echo# comment', 3178 ], 'E182:') 3179 CheckScriptFailure([ 3180 'vim9script', 3181 'command Echo echo', 3182 'command Echo# comment', 3183 ], 'E182:') 3184 delcommand Echo 3185 3186 CheckScriptSuccess([ 3187 'vim9script', 3188 'function # comment', 3189 ]) 3190 CheckScriptFailure([ 3191 'vim9script', 3192 'function " comment', 3193 ], 'E129:') 3194 CheckScriptFailure([ 3195 'vim9script', 3196 'function# comment', 3197 ], 'E1144:') 3198 CheckScriptSuccess([ 3199 'vim9script', 3200 'function CheckScriptSuccess # comment', 3201 ]) 3202 CheckScriptFailure([ 3203 'vim9script', 3204 'function CheckScriptSuccess# comment', 3205 ], 'E488:') 3206 3207 CheckScriptSuccess([ 3208 'vim9script', 3209 'func g:DeleteMeA()', 3210 'endfunc', 3211 'delfunction g:DeleteMeA # comment', 3212 ]) 3213 CheckScriptFailure([ 3214 'vim9script', 3215 'func g:DeleteMeB()', 3216 'endfunc', 3217 'delfunction g:DeleteMeB# comment', 3218 ], 'E488:') 3219 3220 CheckScriptSuccess([ 3221 'vim9script', 3222 'call execute("ls") # comment', 3223 ]) 3224 CheckScriptFailure([ 3225 'vim9script', 3226 'call execute("ls")# comment', 3227 ], 'E488:') 3228 3229 CheckScriptFailure([ 3230 'def Test() " comment', 3231 'enddef', 3232 ], 'E488:') 3233 CheckScriptFailure([ 3234 'vim9script', 3235 'def Test() " comment', 3236 'enddef', 3237 ], 'E488:') 3238 3239 CheckScriptSuccess([ 3240 'func Test() " comment', 3241 'endfunc', 3242 'delfunc Test', 3243 ]) 3244 CheckScriptSuccess([ 3245 'vim9script', 3246 'func Test() " comment', 3247 'endfunc', 3248 ]) 3249 3250 CheckScriptSuccess([ 3251 'def Test() # comment', 3252 'enddef', 3253 ]) 3254 CheckScriptFailure([ 3255 'func Test() # comment', 3256 'endfunc', 3257 ], 'E488:') 3258 3259 var lines =<< trim END 3260 vim9script 3261 syn region Text 3262 \ start='foo' 3263 #\ comment 3264 \ end='bar' 3265 syn region Text start='foo' 3266 #\ comment 3267 \ end='bar' 3268 END 3269 CheckScriptSuccess(lines) 3270 3271 lines =<< trim END 3272 vim9script 3273 syn region Text 3274 \ start='foo' 3275 "\ comment 3276 \ end='bar' 3277 END 3278 CheckScriptFailure(lines, 'E399:') 3279enddef 3280 3281def Test_vim9_comment_gui() 3282 CheckCanRunGui 3283 3284 CheckScriptFailure([ 3285 'vim9script', 3286 'gui#comment' 3287 ], 'E1144:') 3288 CheckScriptFailure([ 3289 'vim9script', 3290 'gui -f#comment' 3291 ], 'E499:') 3292enddef 3293 3294def Test_vim9_comment_not_compiled() 3295 au TabEnter *.vim g:entered = 1 3296 au TabEnter *.x g:entered = 2 3297 3298 edit test.vim 3299 doautocmd TabEnter #comment 3300 assert_equal(1, g:entered) 3301 3302 doautocmd TabEnter f.x 3303 assert_equal(2, g:entered) 3304 3305 g:entered = 0 3306 doautocmd TabEnter f.x #comment 3307 assert_equal(2, g:entered) 3308 3309 assert_fails('doautocmd Syntax#comment', 'E216:') 3310 3311 au! TabEnter 3312 unlet g:entered 3313 3314 CheckScriptSuccess([ 3315 'vim9script', 3316 'g:var = 123', 3317 'b:var = 456', 3318 'w:var = 777', 3319 't:var = 888', 3320 'unlet g:var w:var # something', 3321 ]) 3322 3323 CheckScriptFailure([ 3324 'vim9script', 3325 'let var = 123', 3326 ], 'E1126: Cannot use :let in Vim9 script') 3327 3328 CheckScriptFailure([ 3329 'vim9script', 3330 'var g:var = 123', 3331 ], 'E1016: Cannot declare a global variable:') 3332 3333 CheckScriptFailure([ 3334 'vim9script', 3335 'var b:var = 123', 3336 ], 'E1016: Cannot declare a buffer variable:') 3337 3338 CheckScriptFailure([ 3339 'vim9script', 3340 'var w:var = 123', 3341 ], 'E1016: Cannot declare a window variable:') 3342 3343 CheckScriptFailure([ 3344 'vim9script', 3345 'var t:var = 123', 3346 ], 'E1016: Cannot declare a tab variable:') 3347 3348 CheckScriptFailure([ 3349 'vim9script', 3350 'var v:version = 123', 3351 ], 'E1016: Cannot declare a v: variable:') 3352 3353 CheckScriptFailure([ 3354 'vim9script', 3355 'var $VARIABLE = "text"', 3356 ], 'E1016: Cannot declare an environment variable:') 3357 3358 CheckScriptFailure([ 3359 'vim9script', 3360 'g:var = 123', 3361 'unlet g:var# comment1', 3362 ], 'E108:') 3363 3364 CheckScriptFailure([ 3365 'let g:var = 123', 3366 'unlet g:var # something', 3367 ], 'E488:') 3368 3369 CheckScriptSuccess([ 3370 'vim9script', 3371 'if 1 # comment2', 3372 ' echo "yes"', 3373 'elseif 2 #comment', 3374 ' echo "no"', 3375 'endif', 3376 ]) 3377 3378 CheckScriptFailure([ 3379 'vim9script', 3380 'if 1# comment3', 3381 ' echo "yes"', 3382 'endif', 3383 ], 'E488:') 3384 3385 CheckScriptFailure([ 3386 'vim9script', 3387 'if 0 # comment4', 3388 ' echo "yes"', 3389 'elseif 2#comment', 3390 ' echo "no"', 3391 'endif', 3392 ], 'E488:') 3393 3394 CheckScriptSuccess([ 3395 'vim9script', 3396 'var v = 1 # comment5', 3397 ]) 3398 3399 CheckScriptFailure([ 3400 'vim9script', 3401 'var v = 1# comment6', 3402 ], 'E488:') 3403 3404 CheckScriptSuccess([ 3405 'vim9script', 3406 'new' 3407 'setline(1, ["# define pat", "last"])', 3408 ':$', 3409 'dsearch /pat/ #comment', 3410 'bwipe!', 3411 ]) 3412 3413 CheckScriptFailure([ 3414 'vim9script', 3415 'new' 3416 'setline(1, ["# define pat", "last"])', 3417 ':$', 3418 'dsearch /pat/#comment', 3419 'bwipe!', 3420 ], 'E488:') 3421 3422 CheckScriptFailure([ 3423 'vim9script', 3424 'func! SomeFunc()', 3425 ], 'E477:') 3426enddef 3427 3428def Test_finish() 3429 var lines =<< trim END 3430 vim9script 3431 g:res = 'one' 3432 if v:false | finish | endif 3433 g:res = 'two' 3434 finish 3435 g:res = 'three' 3436 END 3437 writefile(lines, 'Xfinished') 3438 source Xfinished 3439 assert_equal('two', g:res) 3440 3441 unlet g:res 3442 delete('Xfinished') 3443enddef 3444 3445def Test_forward_declaration() 3446 var lines =<< trim END 3447 vim9script 3448 def GetValue(): string 3449 return theVal 3450 enddef 3451 var theVal = 'something' 3452 g:initVal = GetValue() 3453 theVal = 'else' 3454 g:laterVal = GetValue() 3455 END 3456 writefile(lines, 'Xforward') 3457 source Xforward 3458 assert_equal('something', g:initVal) 3459 assert_equal('else', g:laterVal) 3460 3461 unlet g:initVal 3462 unlet g:laterVal 3463 delete('Xforward') 3464enddef 3465 3466def Test_source_vim9_from_legacy() 3467 var vim9_lines =<< trim END 3468 vim9script 3469 var local = 'local' 3470 g:global = 'global' 3471 export var exported = 'exported' 3472 export def GetText(): string 3473 return 'text' 3474 enddef 3475 END 3476 writefile(vim9_lines, 'Xvim9_script.vim') 3477 3478 var legacy_lines =<< trim END 3479 source Xvim9_script.vim 3480 3481 call assert_false(exists('local')) 3482 call assert_false(exists('exported')) 3483 call assert_false(exists('s:exported')) 3484 call assert_equal('global', global) 3485 call assert_equal('global', g:global) 3486 3487 " imported variable becomes script-local 3488 import exported from './Xvim9_script.vim' 3489 call assert_equal('exported', s:exported) 3490 call assert_false(exists('exported')) 3491 3492 " imported function becomes script-local 3493 import GetText from './Xvim9_script.vim' 3494 call assert_equal('text', s:GetText()) 3495 call assert_false(exists('*GetText')) 3496 END 3497 writefile(legacy_lines, 'Xlegacy_script.vim') 3498 3499 source Xlegacy_script.vim 3500 assert_equal('global', g:global) 3501 unlet g:global 3502 3503 delete('Xlegacy_script.vim') 3504 delete('Xvim9_script.vim') 3505enddef 3506 3507def Test_declare_script_in_func() 3508 var lines =<< trim END 3509 vim9script 3510 func Declare() 3511 let s:local = 123 3512 endfunc 3513 Declare() 3514 assert_equal(123, local) 3515 3516 var error: string 3517 try 3518 local = 'asdf' 3519 catch 3520 error = v:exception 3521 endtry 3522 assert_match('E1012: Type mismatch; expected number but got string', error) 3523 3524 lockvar local 3525 try 3526 local = 999 3527 catch 3528 error = v:exception 3529 endtry 3530 assert_match('E741: Value is locked: local', error) 3531 END 3532 CheckScriptSuccess(lines) 3533enddef 3534 3535 3536func Test_vim9script_not_global() 3537 " check that items defined in Vim9 script are script-local, not global 3538 let vim9lines =<< trim END 3539 vim9script 3540 var name = 'local' 3541 func TheFunc() 3542 echo 'local' 3543 endfunc 3544 def DefFunc() 3545 echo 'local' 3546 enddef 3547 END 3548 call writefile(vim9lines, 'Xvim9script.vim') 3549 source Xvim9script.vim 3550 try 3551 echo g:var 3552 assert_report('did not fail') 3553 catch /E121:/ 3554 " caught 3555 endtry 3556 try 3557 call TheFunc() 3558 assert_report('did not fail') 3559 catch /E117:/ 3560 " caught 3561 endtry 3562 try 3563 call DefFunc() 3564 assert_report('did not fail') 3565 catch /E117:/ 3566 " caught 3567 endtry 3568 3569 call delete('Xvim9script.vim') 3570endfunc 3571 3572def Test_vim9_copen() 3573 # this was giving an error for setting w:quickfix_title 3574 copen 3575 quit 3576enddef 3577 3578" test using an auto-loaded function and variable 3579def Test_vim9_autoload() 3580 var lines =<< trim END 3581 vim9script 3582 def some#gettest(): string 3583 return 'test' 3584 enddef 3585 g:some#name = 'name' 3586 g:some#dict = {key: 'value'} 3587 3588 def some#varargs(a1: string, ...l: list<string>): string 3589 return a1 .. l[0] .. l[1] 3590 enddef 3591 END 3592 3593 mkdir('Xdir/autoload', 'p') 3594 writefile(lines, 'Xdir/autoload/some.vim') 3595 var save_rtp = &rtp 3596 exe 'set rtp^=' .. getcwd() .. '/Xdir' 3597 3598 assert_equal('test', g:some#gettest()) 3599 assert_equal('name', g:some#name) 3600 assert_equal('value', g:some#dict.key) 3601 g:some#other = 'other' 3602 assert_equal('other', g:some#other) 3603 3604 assert_equal('abc', some#varargs('a', 'b', 'c')) 3605 3606 # upper case script name works 3607 lines =<< trim END 3608 vim9script 3609 def Other#getOther(): string 3610 return 'other' 3611 enddef 3612 END 3613 writefile(lines, 'Xdir/autoload/Other.vim') 3614 assert_equal('other', g:Other#getOther()) 3615 3616 delete('Xdir', 'rf') 3617 &rtp = save_rtp 3618enddef 3619 3620" test using a vim9script that is auto-loaded from an autocmd 3621def Test_vim9_aucmd_autoload() 3622 var lines =<< trim END 3623 vim9script 3624 def foo#test() 3625 echomsg getreg('"') 3626 enddef 3627 END 3628 3629 mkdir('Xdir/autoload', 'p') 3630 writefile(lines, 'Xdir/autoload/foo.vim') 3631 var save_rtp = &rtp 3632 exe 'set rtp^=' .. getcwd() .. '/Xdir' 3633 augroup test 3634 autocmd TextYankPost * call foo#test() 3635 augroup END 3636 3637 normal Y 3638 3639 augroup test 3640 autocmd! 3641 augroup END 3642 delete('Xdir', 'rf') 3643 &rtp = save_rtp 3644enddef 3645 3646" This was causing a crash because suppress_errthrow wasn't reset. 3647def Test_vim9_autoload_error() 3648 var lines =<< trim END 3649 vim9script 3650 def crash#func() 3651 try 3652 for x in List() 3653 endfor 3654 catch 3655 endtry 3656 g:ok = true 3657 enddef 3658 fu List() 3659 invalid 3660 endfu 3661 try 3662 alsoinvalid 3663 catch /wontmatch/ 3664 endtry 3665 END 3666 call mkdir('Xruntime/autoload', 'p') 3667 call writefile(lines, 'Xruntime/autoload/crash.vim') 3668 3669 # run in a separate Vim to avoid the side effects of assert_fails() 3670 lines =<< trim END 3671 exe 'set rtp^=' .. getcwd() .. '/Xruntime' 3672 call crash#func() 3673 call writefile(['ok'], 'Xdidit') 3674 qall! 3675 END 3676 writefile(lines, 'Xscript') 3677 RunVim([], [], '-S Xscript') 3678 assert_equal(['ok'], readfile('Xdidit')) 3679 3680 delete('Xdidit') 3681 delete('Xscript') 3682 delete('Xruntime', 'rf') 3683 3684 lines =<< trim END 3685 vim9script 3686 var foo#bar = 'asdf' 3687 END 3688 CheckScriptFailure(lines, 'E461: Illegal variable name: foo#bar', 2) 3689enddef 3690 3691def Test_script_var_in_autocmd() 3692 # using a script variable from an autocommand, defined in a :def function in a 3693 # legacy Vim script, cannot check the variable type. 3694 var lines =<< trim END 3695 let s:counter = 1 3696 def s:Func() 3697 au! CursorHold 3698 au CursorHold * s:counter += 1 3699 enddef 3700 call s:Func() 3701 doau CursorHold 3702 call assert_equal(2, s:counter) 3703 au! CursorHold 3704 END 3705 CheckScriptSuccess(lines) 3706enddef 3707 3708def Test_error_in_autoload_script() 3709 var save_rtp = &rtp 3710 var dir = getcwd() .. '/Xruntime' 3711 &rtp = dir 3712 mkdir(dir .. '/autoload', 'p') 3713 3714 var lines =<< trim END 3715 vim9script noclear 3716 def script#autoloaded() 3717 enddef 3718 def Broken() 3719 var x: any = '' 3720 eval x != 0 3721 enddef 3722 Broken() 3723 END 3724 writefile(lines, dir .. '/autoload/script.vim') 3725 3726 lines =<< trim END 3727 vim9script 3728 def CallAutoloaded() 3729 script#autoloaded() 3730 enddef 3731 3732 function Legacy() 3733 try 3734 call s:CallAutoloaded() 3735 catch 3736 call assert_match('E1030: Using a String as a Number', v:exception) 3737 endtry 3738 endfunction 3739 3740 Legacy() 3741 END 3742 CheckScriptSuccess(lines) 3743 3744 &rtp = save_rtp 3745 delete(dir, 'rf') 3746enddef 3747 3748def Test_cmdline_win() 3749 # if the Vim syntax highlighting uses Vim9 constructs they can be used from 3750 # the command line window. 3751 mkdir('rtp/syntax', 'p') 3752 var export_lines =<< trim END 3753 vim9script 3754 export var That = 'yes' 3755 END 3756 writefile(export_lines, 'rtp/syntax/Xexport.vim') 3757 var import_lines =<< trim END 3758 vim9script 3759 import That from './Xexport.vim' 3760 END 3761 writefile(import_lines, 'rtp/syntax/vim.vim') 3762 var save_rtp = &rtp 3763 &rtp = getcwd() .. '/rtp' .. ',' .. &rtp 3764 syntax on 3765 augroup CmdWin 3766 autocmd CmdwinEnter * g:got_there = 'yes' 3767 augroup END 3768 # this will open and also close the cmdline window 3769 feedkeys('q:', 'xt') 3770 assert_equal('yes', g:got_there) 3771 3772 augroup CmdWin 3773 au! 3774 augroup END 3775 &rtp = save_rtp 3776 delete('rtp', 'rf') 3777enddef 3778 3779def Test_invalid_sid() 3780 assert_fails('func <SNR>1234_func', 'E123:') 3781 3782 if RunVim([], ['wq! Xdidit'], '+"func <SNR>1_func"') 3783 assert_equal([], readfile('Xdidit')) 3784 endif 3785 delete('Xdidit') 3786enddef 3787 3788def Test_restoring_cpo() 3789 writefile(['vim9script', 'set nocp'], 'Xsourced') 3790 writefile(['call writefile(["done"], "Xdone")', 'quit!'], 'Xclose') 3791 if RunVim([], [], '-u NONE +"set cpo+=a" -S Xsourced -S Xclose') 3792 assert_equal(['done'], readfile('Xdone')) 3793 endif 3794 delete('Xsourced') 3795 delete('Xclose') 3796 delete('Xdone') 3797 3798 writefile(['vim9script'], 'XanotherScript') 3799 set cpo=aABceFsMny> 3800 edit XanotherScript 3801 so % 3802 assert_equal('aABceFsMny>', &cpo) 3803 :1del 3804 w 3805 so % 3806 assert_equal('aABceFsMny>', &cpo) 3807 3808 delete('XanotherScript') 3809 set cpo&vim 3810enddef 3811 3812" Use :function so we can use Check commands 3813func Test_no_redraw_when_restoring_cpo() 3814 CheckScreendump 3815 CheckFeature timers 3816 3817 let lines =<< trim END 3818 vim9script 3819 def script#func() 3820 enddef 3821 END 3822 call mkdir('Xdir/autoload', 'p') 3823 call writefile(lines, 'Xdir/autoload/script.vim') 3824 3825 let lines =<< trim END 3826 vim9script 3827 set cpo+=M 3828 exe 'set rtp^=' .. getcwd() .. '/Xdir' 3829 au CmdlineEnter : ++once timer_start(0, (_) => script#func()) 3830 setline(1, 'some text') 3831 END 3832 call writefile(lines, 'XTest_redraw_cpo') 3833 let buf = RunVimInTerminal('-S XTest_redraw_cpo', {'rows': 6}) 3834 call term_sendkeys(buf, "V:") 3835 call VerifyScreenDump(buf, 'Test_vim9_no_redraw', {}) 3836 3837 " clean up 3838 call term_sendkeys(buf, "\<Esc>u") 3839 call StopVimInTerminal(buf) 3840 call delete('XTest_redraw_cpo') 3841 call delete('Xdir', 'rf') 3842endfunc 3843 3844 3845def Test_unset_any_variable() 3846 var lines =<< trim END 3847 var name: any 3848 assert_equal(0, name) 3849 END 3850 CheckDefAndScriptSuccess(lines) 3851enddef 3852 3853func Test_define_func_at_command_line() 3854 CheckRunVimInTerminal 3855 3856 " call indirectly to avoid compilation error for missing functions 3857 call Run_Test_define_func_at_command_line() 3858endfunc 3859 3860def Run_Test_define_func_at_command_line() 3861 # run in a separate Vim instance to avoid the script context 3862 var lines =<< trim END 3863 func CheckAndQuit() 3864 call assert_fails('call Afunc()', 'E117: Unknown function: Bfunc') 3865 call writefile(['errors: ' .. string(v:errors)], 'Xdidcmd') 3866 endfunc 3867 END 3868 writefile([''], 'Xdidcmd') 3869 writefile(lines, 'XcallFunc') 3870 var buf = RunVimInTerminal('-S XcallFunc', {rows: 6}) 3871 # define Afunc() on the command line 3872 term_sendkeys(buf, ":def Afunc()\<CR>Bfunc()\<CR>enddef\<CR>") 3873 term_sendkeys(buf, ":call CheckAndQuit()\<CR>") 3874 WaitForAssert(() => assert_equal(['errors: []'], readfile('Xdidcmd'))) 3875 3876 call StopVimInTerminal(buf) 3877 delete('XcallFunc') 3878 delete('Xdidcmd') 3879enddef 3880 3881def Test_script_var_scope() 3882 var lines =<< trim END 3883 vim9script 3884 if true 3885 if true 3886 var one = 'one' 3887 echo one 3888 endif 3889 echo one 3890 endif 3891 END 3892 CheckScriptFailure(lines, 'E121:', 7) 3893 3894 lines =<< trim END 3895 vim9script 3896 if true 3897 if false 3898 var one = 'one' 3899 echo one 3900 else 3901 var one = 'one' 3902 echo one 3903 endif 3904 echo one 3905 endif 3906 END 3907 CheckScriptFailure(lines, 'E121:', 10) 3908 3909 lines =<< trim END 3910 vim9script 3911 while true 3912 var one = 'one' 3913 echo one 3914 break 3915 endwhile 3916 echo one 3917 END 3918 CheckScriptFailure(lines, 'E121:', 7) 3919 3920 lines =<< trim END 3921 vim9script 3922 for i in range(1) 3923 var one = 'one' 3924 echo one 3925 endfor 3926 echo one 3927 END 3928 CheckScriptFailure(lines, 'E121:', 6) 3929 3930 lines =<< trim END 3931 vim9script 3932 { 3933 var one = 'one' 3934 assert_equal('one', one) 3935 } 3936 assert_false(exists('one')) 3937 assert_false(exists('s:one')) 3938 END 3939 CheckScriptSuccess(lines) 3940 3941 lines =<< trim END 3942 vim9script 3943 { 3944 var one = 'one' 3945 echo one 3946 } 3947 echo one 3948 END 3949 CheckScriptFailure(lines, 'E121:', 6) 3950enddef 3951 3952def Test_catch_exception_in_callback() 3953 var lines =<< trim END 3954 vim9script 3955 def Callback(...l: list<any>) 3956 try 3957 var x: string 3958 var y: string 3959 # this error should be caught with CHECKLEN 3960 [x, y] = [''] 3961 catch 3962 g:caught = 'yes' 3963 endtry 3964 enddef 3965 popup_menu('popup', {callback: Callback}) 3966 feedkeys("\r", 'xt') 3967 END 3968 CheckScriptSuccess(lines) 3969 3970 unlet g:caught 3971enddef 3972 3973def Test_no_unknown_error_after_error() 3974 if !has('unix') || !has('job') 3975 throw 'Skipped: not unix of missing +job feature' 3976 endif 3977 var lines =<< trim END 3978 vim9script 3979 var source: list<number> 3980 def Out_cb(...l: list<any>) 3981 eval [][0] 3982 enddef 3983 def Exit_cb(...l: list<any>) 3984 sleep 1m 3985 source += l 3986 enddef 3987 var myjob = job_start('echo burp', {out_cb: Out_cb, exit_cb: Exit_cb, mode: 'raw'}) 3988 while job_status(myjob) == 'run' 3989 sleep 10m 3990 endwhile 3991 # wait for Exit_cb() to be called 3992 sleep 200m 3993 END 3994 writefile(lines, 'Xdef') 3995 assert_fails('so Xdef', ['E684:', 'E1012:']) 3996 delete('Xdef') 3997enddef 3998 3999def InvokeNormal() 4000 exe "norm! :m+1\r" 4001enddef 4002 4003def Test_invoke_normal_in_visual_mode() 4004 xnoremap <F3> <Cmd>call <SID>InvokeNormal()<CR> 4005 new 4006 setline(1, ['aaa', 'bbb']) 4007 feedkeys("V\<F3>", 'xt') 4008 assert_equal(['bbb', 'aaa'], getline(1, 2)) 4009 xunmap <F3> 4010enddef 4011 4012def Test_white_space_after_command() 4013 var lines =<< trim END 4014 exit_cb: Func}) 4015 END 4016 CheckDefAndScriptFailure(lines, 'E1144:', 1) 4017 4018 lines =<< trim END 4019 e# 4020 END 4021 CheckDefAndScriptFailure(lines, 'E1144:', 1) 4022enddef 4023 4024def Test_script_var_gone_when_sourced_twice() 4025 var lines =<< trim END 4026 vim9script 4027 if exists('g:guard') 4028 finish 4029 endif 4030 g:guard = 1 4031 var name = 'thename' 4032 def g:GetName(): string 4033 return name 4034 enddef 4035 def g:SetName(arg: string) 4036 name = arg 4037 enddef 4038 END 4039 writefile(lines, 'XscriptTwice.vim') 4040 so XscriptTwice.vim 4041 assert_equal('thename', g:GetName()) 4042 g:SetName('newname') 4043 assert_equal('newname', g:GetName()) 4044 so XscriptTwice.vim 4045 assert_fails('call g:GetName()', 'E1149:') 4046 assert_fails('call g:SetName("x")', 'E1149:') 4047 4048 delfunc g:GetName 4049 delfunc g:SetName 4050 delete('XscriptTwice.vim') 4051 unlet g:guard 4052enddef 4053 4054def Test_import_gone_when_sourced_twice() 4055 var exportlines =<< trim END 4056 vim9script 4057 if exists('g:guard') 4058 finish 4059 endif 4060 g:guard = 1 4061 export var name = 'someName' 4062 END 4063 writefile(exportlines, 'XexportScript.vim') 4064 4065 var lines =<< trim END 4066 vim9script 4067 import name from './XexportScript.vim' 4068 def g:GetName(): string 4069 return name 4070 enddef 4071 END 4072 writefile(lines, 'XscriptImport.vim') 4073 so XscriptImport.vim 4074 assert_equal('someName', g:GetName()) 4075 4076 so XexportScript.vim 4077 assert_fails('call g:GetName()', 'E1149:') 4078 4079 delfunc g:GetName 4080 delete('XexportScript.vim') 4081 delete('XscriptImport.vim') 4082 unlet g:guard 4083enddef 4084 4085def Test_unsupported_commands() 4086 var lines =<< trim END 4087 ka 4088 END 4089 CheckDefFailure(lines, 'E476:') 4090 CheckScriptFailure(['vim9script'] + lines, 'E492:') 4091 4092 lines =<< trim END 4093 :1ka 4094 END 4095 CheckDefFailure(lines, 'E476:') 4096 CheckScriptFailure(['vim9script'] + lines, 'E492:') 4097 4098 lines =<< trim END 4099 t 4100 END 4101 CheckDefFailure(lines, 'E1100:') 4102 CheckScriptFailure(['vim9script'] + lines, 'E1100:') 4103 4104 lines =<< trim END 4105 x 4106 END 4107 CheckDefFailure(lines, 'E1100:') 4108 CheckScriptFailure(['vim9script'] + lines, 'E1100:') 4109 4110 lines =<< trim END 4111 xit 4112 END 4113 CheckDefFailure(lines, 'E1100:') 4114 CheckScriptFailure(['vim9script'] + lines, 'E1100:') 4115enddef 4116 4117def Test_mapping_line_number() 4118 var lines =<< trim END 4119 vim9script 4120 def g:FuncA() 4121 # Some comment 4122 FuncB(0) 4123 enddef 4124 # Some comment 4125 def FuncB( 4126 # Some comment 4127 n: number 4128 ) 4129 exe 'nno ' 4130 # Some comment 4131 .. '<F3> a' 4132 .. 'b' 4133 .. 'c' 4134 enddef 4135 END 4136 CheckScriptSuccess(lines) 4137 var res = execute('verbose nmap <F3>') 4138 assert_match('No mapping found', res) 4139 4140 g:FuncA() 4141 res = execute('verbose nmap <F3>') 4142 assert_match(' <F3> .* abc.*Last set from .*XScriptSuccess\d\+ line 11', res) 4143 4144 nunmap <F3> 4145 delfunc g:FuncA 4146enddef 4147 4148def Test_option_set() 4149 # legacy script allows for white space 4150 var lines =<< trim END 4151 set foldlevel =11 4152 call assert_equal(11, &foldlevel) 4153 END 4154 CheckScriptSuccess(lines) 4155 4156 set foldlevel 4157 set foldlevel=12 4158 assert_equal(12, &foldlevel) 4159 set foldlevel+=2 4160 assert_equal(14, &foldlevel) 4161 set foldlevel-=3 4162 assert_equal(11, &foldlevel) 4163 4164 lines =<< trim END 4165 set foldlevel =1 4166 END 4167 CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: =1') 4168 4169 lines =<< trim END 4170 set foldlevel +=1 4171 END 4172 CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: +=1') 4173 4174 lines =<< trim END 4175 set foldlevel ^=1 4176 END 4177 CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: ^=1') 4178 4179 lines =<< trim END 4180 set foldlevel -=1 4181 END 4182 CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: -=1') 4183 4184 set foldlevel& 4185enddef 4186 4187def Test_option_modifier() 4188 # legacy script allows for white space 4189 var lines =<< trim END 4190 set hlsearch & hlsearch ! 4191 call assert_equal(1, &hlsearch) 4192 END 4193 CheckScriptSuccess(lines) 4194 4195 set hlsearch 4196 set hlsearch! 4197 assert_equal(false, &hlsearch) 4198 4199 set hlsearch 4200 set hlsearch& 4201 assert_equal(false, &hlsearch) 4202 4203 lines =<< trim END 4204 set hlsearch & 4205 END 4206 CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: &') 4207 4208 lines =<< trim END 4209 set hlsearch ! 4210 END 4211 CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: !') 4212 4213 set hlsearch& 4214enddef 4215 4216" This must be called last, it may cause following :def functions to fail 4217def Test_xxx_echoerr_line_number() 4218 var lines =<< trim END 4219 echoerr 'some' 4220 .. ' error' 4221 .. ' continued' 4222 END 4223 CheckDefExecAndScriptFailure(lines, 'some error continued', 1) 4224enddef 4225 4226def ProfiledWithLambda() 4227 var n = 3 4228 echo [[1, 2], [3, 4]]->filter((_, l) => l[0] == n) 4229enddef 4230 4231def ProfiledNested() 4232 var x = 0 4233 def Nested(): any 4234 return x 4235 enddef 4236 Nested() 4237enddef 4238 4239def ProfiledNestedProfiled() 4240 var x = 0 4241 def Nested(): any 4242 return x 4243 enddef 4244 Nested() 4245enddef 4246 4247" Execute this near the end, profiling doesn't stop until Vim exists. 4248" This only tests that it works, not the profiling output. 4249def Test_xx_profile_with_lambda() 4250 CheckFeature profile 4251 4252 profile start Xprofile.log 4253 profile func ProfiledWithLambda 4254 ProfiledWithLambda() 4255 4256 profile func ProfiledNested 4257 ProfiledNested() 4258 4259 # Also profile the nested function. Use a different function, although the 4260 # contents is the same, to make sure it was not already compiled. 4261 profile func * 4262 ProfiledNestedProfiled() 4263 4264 profdel func * 4265 profile pause 4266enddef 4267 4268" Keep this last, it messes up highlighting. 4269def Test_substitute_cmd() 4270 new 4271 setline(1, 'something') 4272 :substitute(some(other( 4273 assert_equal('otherthing', getline(1)) 4274 bwipe! 4275 4276 # also when the context is Vim9 script 4277 var lines =<< trim END 4278 vim9script 4279 new 4280 setline(1, 'something') 4281 :substitute(some(other( 4282 assert_equal('otherthing', getline(1)) 4283 bwipe! 4284 END 4285 writefile(lines, 'Xvim9lines') 4286 source Xvim9lines 4287 4288 delete('Xvim9lines') 4289enddef 4290 4291" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 4292