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