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