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