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