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