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