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