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