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