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