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