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