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