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