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