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