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