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