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