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