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