1" Test various aspects of the Vim9 script language. 2 3source check.vim 4source term_util.vim 5source view_util.vim 6source vim9.vim 7source screendump.vim 8 9func Test_def_basic() 10 def SomeFunc(): string 11 return 'yes' 12 enddef 13 call SomeFunc()->assert_equal('yes') 14endfunc 15 16func Test_compiling_error() 17 " use a terminal to see the whole error message 18 CheckRunVimInTerminal 19 20 call TestCompilingError() 21endfunc 22 23def TestCompilingError() 24 var lines =<< trim END 25 vim9script 26 def Fails() 27 echo nothing 28 enddef 29 defcompile 30 END 31 call writefile(lines, 'XTest_compile_error') 32 var buf = RunVimInTerminal('-S XTest_compile_error', 33 #{rows: 10, wait_for_ruler: 0}) 34 var text = '' 35 for loop in range(100) 36 text = '' 37 for i in range(1, 9) 38 text ..= term_getline(buf, i) 39 endfor 40 if text =~ 'Error detected' 41 break 42 endif 43 sleep 20m 44 endfor 45 assert_match('Error detected while compiling command line.*Fails.*Variable not found: nothing', text) 46 47 # clean up 48 call StopVimInTerminal(buf) 49 call delete('XTest_compile_error') 50enddef 51 52def ReturnString(): string 53 return 'string' 54enddef 55 56def ReturnNumber(): number 57 return 123 58enddef 59 60let g:notNumber = 'string' 61 62def ReturnGlobal(): number 63 return g:notNumber 64enddef 65 66def Test_return_something() 67 ReturnString()->assert_equal('string') 68 ReturnNumber()->assert_equal(123) 69 assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal') 70enddef 71 72def Test_missing_return() 73 CheckDefFailure(['def Missing(): number', 74 ' if g:cond', 75 ' echo "no return"', 76 ' else', 77 ' return 0', 78 ' endif' 79 'enddef'], 'E1027:') 80 CheckDefFailure(['def Missing(): number', 81 ' if g:cond', 82 ' return 1', 83 ' else', 84 ' echo "no return"', 85 ' endif' 86 'enddef'], 'E1027:') 87 CheckDefFailure(['def Missing(): number', 88 ' if g:cond', 89 ' return 1', 90 ' else', 91 ' return 2', 92 ' endif' 93 ' return 3' 94 'enddef'], 'E1095:') 95enddef 96 97def Test_return_bool() 98 var lines =<< trim END 99 vim9script 100 def MenuFilter(id: number, key: string): bool 101 return popup_filter_menu(id, key) 102 enddef 103 def YesnoFilter(id: number, key: string): bool 104 return popup_filter_yesno(id, key) 105 enddef 106 defcompile 107 END 108 CheckScriptSuccess(lines) 109enddef 110 111let s:nothing = 0 112def ReturnNothing() 113 s:nothing = 1 114 if true 115 return 116 endif 117 s:nothing = 2 118enddef 119 120def Test_return_nothing() 121 ReturnNothing() 122 s:nothing->assert_equal(1) 123enddef 124 125func Increment() 126 let g:counter += 1 127endfunc 128 129def Test_call_ufunc_count() 130 g:counter = 1 131 Increment() 132 Increment() 133 Increment() 134 # works with and without :call 135 g:counter->assert_equal(4) 136 eval g:counter->assert_equal(4) 137 unlet g:counter 138enddef 139 140def MyVarargs(arg: string, ...rest: list<string>): string 141 var res = arg 142 for s in rest 143 res ..= ',' .. s 144 endfor 145 return res 146enddef 147 148def Test_call_varargs() 149 MyVarargs('one')->assert_equal('one') 150 MyVarargs('one', 'two')->assert_equal('one,two') 151 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three') 152enddef 153 154def MyDefaultArgs(name = 'string'): string 155 return name 156enddef 157 158def MyDefaultSecond(name: string, second: bool = true): string 159 return second ? name : 'none' 160enddef 161 162def Test_call_default_args() 163 MyDefaultArgs()->assert_equal('string') 164 MyDefaultArgs('one')->assert_equal('one') 165 assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args') 166 167 MyDefaultSecond('test')->assert_equal('test') 168 MyDefaultSecond('test', true)->assert_equal('test') 169 MyDefaultSecond('test', false)->assert_equal('none') 170 171 CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:') 172 CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string') 173enddef 174 175def Test_nested_function() 176 def Nested(arg: string): string 177 return 'nested ' .. arg 178 enddef 179 Nested('function')->assert_equal('nested function') 180 181 CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:') 182 CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:') 183 184 CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:') 185 CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:') 186 CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:') 187 188 CheckDefFailure([ 189 'def Outer()', 190 ' def Inner()', 191 ' # comment', 192 ' enddef', 193 ' def Inner()', 194 ' enddef', 195 'enddef'], 'E1073:') 196 CheckDefFailure([ 197 'def Outer()', 198 ' def Inner()', 199 ' # comment', 200 ' enddef', 201 ' def! Inner()', 202 ' enddef', 203 'enddef'], 'E1117:') 204enddef 205 206func Test_call_default_args_from_func() 207 call MyDefaultArgs()->assert_equal('string') 208 call MyDefaultArgs('one')->assert_equal('one') 209 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func') 210endfunc 211 212def Test_nested_global_function() 213 var lines =<< trim END 214 vim9script 215 def Outer() 216 def g:Inner(): string 217 return 'inner' 218 enddef 219 enddef 220 defcompile 221 Outer() 222 g:Inner()->assert_equal('inner') 223 delfunc g:Inner 224 Outer() 225 g:Inner()->assert_equal('inner') 226 delfunc g:Inner 227 Outer() 228 g:Inner()->assert_equal('inner') 229 delfunc g:Inner 230 END 231 CheckScriptSuccess(lines) 232 233 lines =<< trim END 234 vim9script 235 def Outer() 236 def g:Inner(): string 237 return 'inner' 238 enddef 239 enddef 240 defcompile 241 Outer() 242 Outer() 243 END 244 CheckScriptFailure(lines, "E122:") 245 246 lines =<< trim END 247 vim9script 248 def Func() 249 echo 'script' 250 enddef 251 def Outer() 252 def Func() 253 echo 'inner' 254 enddef 255 enddef 256 defcompile 257 END 258 CheckScriptFailure(lines, "E1073:") 259enddef 260 261def Test_global_local_function() 262 var lines =<< trim END 263 vim9script 264 def g:Func(): string 265 return 'global' 266 enddef 267 def Func(): string 268 return 'local' 269 enddef 270 g:Func()->assert_equal('global') 271 Func()->assert_equal('local') 272 END 273 CheckScriptSuccess(lines) 274 275 lines =<< trim END 276 vim9script 277 def g:Funcy() 278 echo 'funcy' 279 enddef 280 s:Funcy() 281 END 282 CheckScriptFailure(lines, 'E117:') 283enddef 284 285def Test_local_function_shadows_global() 286 var lines =<< trim END 287 vim9script 288 def g:Gfunc(): string 289 return 'global' 290 enddef 291 def AnotherFunc(): number 292 var Gfunc = function('len') 293 return Gfunc('testing') 294 enddef 295 g:Gfunc()->assert_equal('global') 296 AnotherFunc()->assert_equal(7) 297 delfunc g:Gfunc 298 END 299 CheckScriptSuccess(lines) 300 301 lines =<< trim END 302 vim9script 303 def g:Func(): string 304 return 'global' 305 enddef 306 def AnotherFunc() 307 g:Func = function('len') 308 enddef 309 AnotherFunc() 310 END 311 CheckScriptFailure(lines, 'E705:') 312 delfunc g:Func 313enddef 314 315func TakesOneArg(arg) 316 echo a:arg 317endfunc 318 319def Test_call_wrong_args() 320 CheckDefFailure(['TakesOneArg()'], 'E119:') 321 CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:') 322 CheckDefFailure(['bufnr(xxx)'], 'E1001:') 323 CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:') 324 325 var lines =<< trim END 326 vim9script 327 def Func(s: string) 328 echo s 329 enddef 330 Func([]) 331 END 332 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5) 333 334 lines =<< trim END 335 vim9script 336 def FuncOne(nr: number) 337 echo nr 338 enddef 339 def FuncTwo() 340 FuncOne() 341 enddef 342 defcompile 343 END 344 writefile(lines, 'Xscript') 345 var didCatch = false 346 try 347 source Xscript 348 catch 349 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception) 350 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint) 351 didCatch = true 352 endtry 353 assert_true(didCatch) 354 355 lines =<< trim END 356 vim9script 357 def FuncOne(nr: number) 358 echo nr 359 enddef 360 def FuncTwo() 361 FuncOne(1, 2) 362 enddef 363 defcompile 364 END 365 writefile(lines, 'Xscript') 366 didCatch = false 367 try 368 source Xscript 369 catch 370 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception) 371 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint) 372 didCatch = true 373 endtry 374 assert_true(didCatch) 375 376 delete('Xscript') 377enddef 378 379" Default arg and varargs 380def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string 381 var res = one .. ',' .. two 382 for s in rest 383 res ..= ',' .. s 384 endfor 385 return res 386enddef 387 388def Test_call_def_varargs() 389 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs') 390 MyDefVarargs('one')->assert_equal('one,foo') 391 MyDefVarargs('one', 'two')->assert_equal('one,two') 392 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three') 393 CheckDefFailure(['MyDefVarargs("one", 22)'], 394 'E1013: Argument 2: type mismatch, expected string but got number') 395 CheckDefFailure(['MyDefVarargs("one", "two", 123)'], 396 'E1013: Argument 3: type mismatch, expected string but got number') 397 398 var lines =<< trim END 399 vim9script 400 def Func(...l: list<string>) 401 echo l 402 enddef 403 Func('a', 'b', 'c') 404 END 405 CheckScriptSuccess(lines) 406 407 lines =<< trim END 408 vim9script 409 def Func(...l: list<string>) 410 echo l 411 enddef 412 Func() 413 END 414 CheckScriptSuccess(lines) 415 416 lines =<< trim END 417 vim9script 418 def Func(...l: any) 419 echo l 420 enddef 421 Func(0) 422 END 423 CheckScriptSuccess(lines) 424 425 lines =<< trim END 426 vim9script 427 def Func(..._l: list<string>) 428 echo _l 429 enddef 430 Func('a', 'b', 'c') 431 END 432 CheckScriptSuccess(lines) 433 434 lines =<< trim END 435 vim9script 436 def Func(...l: list<string>) 437 echo l 438 enddef 439 Func(1, 2, 3) 440 END 441 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch') 442 443 lines =<< trim END 444 vim9script 445 def Func(...l: list<string>) 446 echo l 447 enddef 448 Func('a', 9) 449 END 450 CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch') 451 452 lines =<< trim END 453 vim9script 454 def Func(...l: list<string>) 455 echo l 456 enddef 457 Func(1, 'a') 458 END 459 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch') 460enddef 461 462let s:value = '' 463 464def FuncOneDefArg(opt = 'text') 465 s:value = opt 466enddef 467 468def FuncTwoDefArg(nr = 123, opt = 'text'): string 469 return nr .. opt 470enddef 471 472def FuncVarargs(...arg: list<string>): string 473 return join(arg, ',') 474enddef 475 476def Test_func_type_varargs() 477 var RefDefArg: func(?string) 478 RefDefArg = FuncOneDefArg 479 RefDefArg() 480 s:value->assert_equal('text') 481 RefDefArg('some') 482 s:value->assert_equal('some') 483 484 var RefDef2Arg: func(?number, ?string): string 485 RefDef2Arg = FuncTwoDefArg 486 RefDef2Arg()->assert_equal('123text') 487 RefDef2Arg(99)->assert_equal('99text') 488 RefDef2Arg(77, 'some')->assert_equal('77some') 489 490 CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:') 491 CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:') 492 493 var RefVarargs: func(...list<string>): string 494 RefVarargs = FuncVarargs 495 RefVarargs()->assert_equal('') 496 RefVarargs('one')->assert_equal('one') 497 RefVarargs('one', 'two')->assert_equal('one,two') 498 499 CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:') 500 CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:') 501enddef 502 503" Only varargs 504def MyVarargsOnly(...args: list<string>): string 505 return join(args, ',') 506enddef 507 508def Test_call_varargs_only() 509 MyVarargsOnly()->assert_equal('') 510 MyVarargsOnly('one')->assert_equal('one') 511 MyVarargsOnly('one', 'two')->assert_equal('one,two') 512 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number') 513 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number') 514enddef 515 516def Test_using_var_as_arg() 517 writefile(['def Func(x: number)', 'var x = 234', 'enddef', 'defcompile'], 'Xdef') 518 assert_fails('so Xdef', 'E1006:', '', 1, 'Func') 519 delete('Xdef') 520enddef 521 522def DictArg(arg: dict<string>) 523 arg['key'] = 'value' 524enddef 525 526def ListArg(arg: list<string>) 527 arg[0] = 'value' 528enddef 529 530def Test_assign_to_argument() 531 # works for dict and list 532 var d: dict<string> = {} 533 DictArg(d) 534 d['key']->assert_equal('value') 535 var l: list<string> = [] 536 ListArg(l) 537 l[0]->assert_equal('value') 538 539 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:') 540enddef 541 542" These argument names are reserved in legacy functions. 543def WithReservedNames(firstline: string, lastline: string): string 544 return firstline .. lastline 545enddef 546 547def Test_argument_names() 548 assert_equal('OK', WithReservedNames('O', 'K')) 549enddef 550 551def Test_call_func_defined_later() 552 g:DefinedLater('one')->assert_equal('one') 553 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later') 554enddef 555 556func DefinedLater(arg) 557 return a:arg 558endfunc 559 560def Test_call_funcref() 561 g:SomeFunc('abc')->assert_equal(3) 562 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call 563 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref') 564 565 var lines =<< trim END 566 vim9script 567 def RetNumber(): number 568 return 123 569 enddef 570 var Funcref: func: number = function('RetNumber') 571 Funcref()->assert_equal(123) 572 END 573 CheckScriptSuccess(lines) 574 575 lines =<< trim END 576 vim9script 577 def RetNumber(): number 578 return 123 579 enddef 580 def Bar(F: func: number): number 581 return F() 582 enddef 583 var Funcref = function('RetNumber') 584 Bar(Funcref)->assert_equal(123) 585 END 586 CheckScriptSuccess(lines) 587 588 lines =<< trim END 589 vim9script 590 def UseNumber(nr: number) 591 echo nr 592 enddef 593 var Funcref: func(number) = function('UseNumber') 594 Funcref(123) 595 END 596 CheckScriptSuccess(lines) 597 598 lines =<< trim END 599 vim9script 600 def UseNumber(nr: number) 601 echo nr 602 enddef 603 var Funcref: func(string) = function('UseNumber') 604 END 605 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)') 606 607 lines =<< trim END 608 vim9script 609 def EchoNr(nr = 34) 610 g:echo = nr 611 enddef 612 var Funcref: func(?number) = function('EchoNr') 613 Funcref() 614 g:echo->assert_equal(34) 615 Funcref(123) 616 g:echo->assert_equal(123) 617 END 618 CheckScriptSuccess(lines) 619 620 lines =<< trim END 621 vim9script 622 def EchoList(...l: list<number>) 623 g:echo = l 624 enddef 625 var Funcref: func(...list<number>) = function('EchoList') 626 Funcref() 627 g:echo->assert_equal([]) 628 Funcref(1, 2, 3) 629 g:echo->assert_equal([1, 2, 3]) 630 END 631 CheckScriptSuccess(lines) 632 633 lines =<< trim END 634 vim9script 635 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number 636 g:optarg = opt 637 g:listarg = l 638 return nr 639 enddef 640 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar') 641 Funcref(10)->assert_equal(10) 642 g:optarg->assert_equal(12) 643 g:listarg->assert_equal([]) 644 645 Funcref(11, 22)->assert_equal(11) 646 g:optarg->assert_equal(22) 647 g:listarg->assert_equal([]) 648 649 Funcref(17, 18, 1, 2, 3)->assert_equal(17) 650 g:optarg->assert_equal(18) 651 g:listarg->assert_equal([1, 2, 3]) 652 END 653 CheckScriptSuccess(lines) 654enddef 655 656let SomeFunc = function('len') 657let NotAFunc = 'text' 658 659def CombineFuncrefTypes() 660 # same arguments, different return type 661 var Ref1: func(bool): string 662 var Ref2: func(bool): number 663 var Ref3: func(bool): any 664 Ref3 = g:cond ? Ref1 : Ref2 665 666 # different number of arguments 667 var Refa1: func(bool): number 668 var Refa2: func(bool, number): number 669 var Refa3: func: number 670 Refa3 = g:cond ? Refa1 : Refa2 671 672 # different argument types 673 var Refb1: func(bool, string): number 674 var Refb2: func(string, number): number 675 var Refb3: func(any, any): number 676 Refb3 = g:cond ? Refb1 : Refb2 677enddef 678 679def FuncWithForwardCall() 680 return g:DefinedEvenLater("yes") 681enddef 682 683def DefinedEvenLater(arg: string): string 684 return arg 685enddef 686 687def Test_error_in_nested_function() 688 # Error in called function requires unwinding the call stack. 689 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall') 690enddef 691 692def Test_return_type_wrong() 693 CheckScriptFailure([ 694 'def Func(): number', 695 'return "a"', 696 'enddef', 697 'defcompile'], 'expected number but got string') 698 CheckScriptFailure([ 699 'def Func(): string', 700 'return 1', 701 'enddef', 702 'defcompile'], 'expected string but got number') 703 CheckScriptFailure([ 704 'def Func(): void', 705 'return "a"', 706 'enddef', 707 'defcompile'], 708 'E1096: Returning a value in a function without a return type') 709 CheckScriptFailure([ 710 'def Func()', 711 'return "a"', 712 'enddef', 713 'defcompile'], 714 'E1096: Returning a value in a function without a return type') 715 716 CheckScriptFailure([ 717 'def Func(): number', 718 'return', 719 'enddef', 720 'defcompile'], 'E1003:') 721 722 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:') 723 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:') 724 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:') 725 726 CheckScriptFailure([ 727 'vim9script', 728 'def FuncB()', 729 ' return 123', 730 'enddef', 731 'def FuncA()', 732 ' FuncB()', 733 'enddef', 734 'defcompile'], 'E1096:') 735enddef 736 737def Test_arg_type_wrong() 738 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>') 739 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...') 740 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:') 741 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:') 742enddef 743 744def Test_vim9script_call() 745 var lines =<< trim END 746 vim9script 747 var name = '' 748 def MyFunc(arg: string) 749 name = arg 750 enddef 751 MyFunc('foobar') 752 name->assert_equal('foobar') 753 754 var str = 'barfoo' 755 str->MyFunc() 756 name->assert_equal('barfoo') 757 758 g:value = 'value' 759 g:value->MyFunc() 760 name->assert_equal('value') 761 762 var listvar = [] 763 def ListFunc(arg: list<number>) 764 listvar = arg 765 enddef 766 [1, 2, 3]->ListFunc() 767 listvar->assert_equal([1, 2, 3]) 768 769 var dictvar = {} 770 def DictFunc(arg: dict<number>) 771 dictvar = arg 772 enddef 773 {'a': 1, 'b': 2}->DictFunc() 774 dictvar->assert_equal(#{a: 1, b: 2}) 775 def CompiledDict() 776 {'a': 3, 'b': 4}->DictFunc() 777 enddef 778 CompiledDict() 779 dictvar->assert_equal(#{a: 3, b: 4}) 780 781 #{a: 3, b: 4}->DictFunc() 782 dictvar->assert_equal(#{a: 3, b: 4}) 783 784 ('text')->MyFunc() 785 name->assert_equal('text') 786 ("some")->MyFunc() 787 name->assert_equal('some') 788 789 # line starting with single quote is not a mark 790 # line starting with double quote can be a method call 791 'asdfasdf'->MyFunc() 792 name->assert_equal('asdfasdf') 793 "xyz"->MyFunc() 794 name->assert_equal('xyz') 795 796 def UseString() 797 'xyork'->MyFunc() 798 enddef 799 UseString() 800 name->assert_equal('xyork') 801 802 def UseString2() 803 "knife"->MyFunc() 804 enddef 805 UseString2() 806 name->assert_equal('knife') 807 808 # prepending a colon makes it a mark 809 new 810 setline(1, ['aaa', 'bbb', 'ccc']) 811 normal! 3Gmt1G 812 :'t 813 getcurpos()[1]->assert_equal(3) 814 bwipe! 815 816 MyFunc( 817 'continued' 818 ) 819 assert_equal('continued', 820 name 821 ) 822 823 call MyFunc( 824 'more' 825 .. 826 'lines' 827 ) 828 assert_equal( 829 'morelines', 830 name) 831 END 832 writefile(lines, 'Xcall.vim') 833 source Xcall.vim 834 delete('Xcall.vim') 835enddef 836 837def Test_vim9script_call_fail_decl() 838 var lines =<< trim END 839 vim9script 840 var name = '' 841 def MyFunc(arg: string) 842 var name = 123 843 enddef 844 defcompile 845 END 846 CheckScriptFailure(lines, 'E1054:') 847enddef 848 849def Test_vim9script_call_fail_type() 850 var lines =<< trim END 851 vim9script 852 def MyFunc(arg: string) 853 echo arg 854 enddef 855 MyFunc(1234) 856 END 857 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number') 858enddef 859 860def Test_vim9script_call_fail_const() 861 var lines =<< trim END 862 vim9script 863 const var = '' 864 def MyFunc(arg: string) 865 var = 'asdf' 866 enddef 867 defcompile 868 END 869 writefile(lines, 'Xcall_const.vim') 870 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc') 871 delete('Xcall_const.vim') 872enddef 873 874" Test that inside :function a Python function can be defined, :def is not 875" recognized. 876func Test_function_python() 877 CheckFeature python3 878 let py = 'python3' 879 execute py "<< EOF" 880def do_something(): 881 return 1 882EOF 883endfunc 884 885def Test_delfunc() 886 var lines =<< trim END 887 vim9script 888 def g:GoneSoon() 889 echo 'hello' 890 enddef 891 892 def CallGoneSoon() 893 GoneSoon() 894 enddef 895 defcompile 896 897 delfunc g:GoneSoon 898 CallGoneSoon() 899 END 900 writefile(lines, 'XToDelFunc') 901 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon') 902 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon') 903 904 delete('XToDelFunc') 905enddef 906 907def Test_redef_failure() 908 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef') 909 so Xdef 910 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef') 911 so Xdef 912 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef') 913 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0') 914 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef') 915 so Xdef 916 delete('Xdef') 917 918 g:Func0()->assert_equal(0) 919 g:Func1()->assert_equal('Func1') 920 g:Func2()->assert_equal('Func2') 921 922 delfunc! Func0 923 delfunc! Func1 924 delfunc! Func2 925enddef 926 927def Test_vim9script_func() 928 var lines =<< trim END 929 vim9script 930 func Func(arg) 931 echo a:arg 932 endfunc 933 Func('text') 934 END 935 writefile(lines, 'XVim9Func') 936 so XVim9Func 937 938 delete('XVim9Func') 939enddef 940 941let s:funcResult = 0 942 943def FuncNoArgNoRet() 944 s:funcResult = 11 945enddef 946 947def FuncNoArgRetNumber(): number 948 s:funcResult = 22 949 return 1234 950enddef 951 952def FuncNoArgRetString(): string 953 s:funcResult = 45 954 return 'text' 955enddef 956 957def FuncOneArgNoRet(arg: number) 958 s:funcResult = arg 959enddef 960 961def FuncOneArgRetNumber(arg: number): number 962 s:funcResult = arg 963 return arg 964enddef 965 966def FuncTwoArgNoRet(one: bool, two: number) 967 s:funcResult = two 968enddef 969 970def FuncOneArgRetString(arg: string): string 971 return arg 972enddef 973 974def FuncOneArgRetAny(arg: any): any 975 return arg 976enddef 977 978def Test_func_type() 979 var Ref1: func() 980 s:funcResult = 0 981 Ref1 = FuncNoArgNoRet 982 Ref1() 983 s:funcResult->assert_equal(11) 984 985 var Ref2: func 986 s:funcResult = 0 987 Ref2 = FuncNoArgNoRet 988 Ref2() 989 s:funcResult->assert_equal(11) 990 991 s:funcResult = 0 992 Ref2 = FuncOneArgNoRet 993 Ref2(12) 994 s:funcResult->assert_equal(12) 995 996 s:funcResult = 0 997 Ref2 = FuncNoArgRetNumber 998 Ref2()->assert_equal(1234) 999 s:funcResult->assert_equal(22) 1000 1001 s:funcResult = 0 1002 Ref2 = FuncOneArgRetNumber 1003 Ref2(13)->assert_equal(13) 1004 s:funcResult->assert_equal(13) 1005enddef 1006 1007def Test_repeat_return_type() 1008 var res = 0 1009 for n in repeat([1], 3) 1010 res += n 1011 endfor 1012 res->assert_equal(3) 1013 1014 res = 0 1015 for n in add([1, 2], 3) 1016 res += n 1017 endfor 1018 res->assert_equal(6) 1019enddef 1020 1021def Test_argv_return_type() 1022 next fileone filetwo 1023 var res = '' 1024 for name in argv() 1025 res ..= name 1026 endfor 1027 res->assert_equal('fileonefiletwo') 1028enddef 1029 1030def Test_func_type_part() 1031 var RefVoid: func: void 1032 RefVoid = FuncNoArgNoRet 1033 RefVoid = FuncOneArgNoRet 1034 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number') 1035 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string') 1036 1037 var RefAny: func(): any 1038 RefAny = FuncNoArgRetNumber 1039 RefAny = FuncNoArgRetString 1040 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()') 1041 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)') 1042 1043 var RefAnyNoArgs: func: any = RefAny 1044 1045 var RefNr: func: number 1046 RefNr = FuncNoArgRetNumber 1047 RefNr = FuncOneArgRetNumber 1048 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()') 1049 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string') 1050 1051 var RefStr: func: string 1052 RefStr = FuncNoArgRetString 1053 RefStr = FuncOneArgRetString 1054 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()') 1055 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number') 1056enddef 1057 1058def Test_func_type_fails() 1059 CheckDefFailure(['var ref1: func()'], 'E704:') 1060 1061 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number') 1062 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)') 1063 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number') 1064 CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)') 1065 CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)') 1066 CheckDefFailure(['var Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(...bool) but got func(bool, number)') 1067 1068 CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:') 1069 CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:') 1070 CheckDefFailure(['var RefWrong: func(bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool)'], 'E1005:') 1071 CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:') 1072enddef 1073 1074def Test_func_return_type() 1075 var nr: number 1076 nr = FuncNoArgRetNumber() 1077 nr->assert_equal(1234) 1078 1079 nr = FuncOneArgRetAny(122) 1080 nr->assert_equal(122) 1081 1082 var str: string 1083 str = FuncOneArgRetAny('yes') 1084 str->assert_equal('yes') 1085 1086 CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number') 1087enddef 1088 1089def Test_func_common_type() 1090 def FuncOne(n: number): number 1091 return n 1092 enddef 1093 def FuncTwo(s: string): number 1094 return len(s) 1095 enddef 1096 def FuncThree(n: number, s: string): number 1097 return n + len(s) 1098 enddef 1099 var list = [FuncOne, FuncTwo, FuncThree] 1100 assert_equal(8, list[0](8)) 1101 assert_equal(4, list[1]('word')) 1102 assert_equal(7, list[2](3, 'word')) 1103enddef 1104 1105def MultiLine( 1106 arg1: string, 1107 arg2 = 1234, 1108 ...rest: list<string> 1109 ): string 1110 return arg1 .. arg2 .. join(rest, '-') 1111enddef 1112 1113def MultiLineComment( 1114 arg1: string, # comment 1115 arg2 = 1234, # comment 1116 ...rest: list<string> # comment 1117 ): string # comment 1118 return arg1 .. arg2 .. join(rest, '-') 1119enddef 1120 1121def Test_multiline() 1122 MultiLine('text')->assert_equal('text1234') 1123 MultiLine('text', 777)->assert_equal('text777') 1124 MultiLine('text', 777, 'one')->assert_equal('text777one') 1125 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two') 1126enddef 1127 1128func Test_multiline_not_vim9() 1129 call MultiLine('text')->assert_equal('text1234') 1130 call MultiLine('text', 777)->assert_equal('text777') 1131 call MultiLine('text', 777, 'one')->assert_equal('text777one') 1132 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two') 1133endfunc 1134 1135 1136" When using CheckScriptFailure() for the below test, E1010 is generated instead 1137" of E1056. 1138func Test_E1056_1059() 1139 let caught_1056 = 0 1140 try 1141 def F(): 1142 return 1 1143 enddef 1144 catch /E1056:/ 1145 let caught_1056 = 1 1146 endtry 1147 eval caught_1056->assert_equal(1) 1148 1149 let caught_1059 = 0 1150 try 1151 def F5(items : list) 1152 echo 'a' 1153 enddef 1154 catch /E1059:/ 1155 let caught_1059 = 1 1156 endtry 1157 eval caught_1059->assert_equal(1) 1158endfunc 1159 1160func DelMe() 1161 echo 'DelMe' 1162endfunc 1163 1164def Test_error_reporting() 1165 # comment lines at the start of the function 1166 var lines =<< trim END 1167 " comment 1168 def Func() 1169 # comment 1170 # comment 1171 invalid 1172 enddef 1173 defcompile 1174 END 1175 writefile(lines, 'Xdef') 1176 try 1177 source Xdef 1178 assert_report('should have failed') 1179 catch /E476:/ 1180 v:exception->assert_match('Invalid command: invalid') 1181 v:throwpoint->assert_match(', line 3$') 1182 endtry 1183 1184 # comment lines after the start of the function 1185 lines =<< trim END 1186 " comment 1187 def Func() 1188 var x = 1234 1189 # comment 1190 # comment 1191 invalid 1192 enddef 1193 defcompile 1194 END 1195 writefile(lines, 'Xdef') 1196 try 1197 source Xdef 1198 assert_report('should have failed') 1199 catch /E476:/ 1200 v:exception->assert_match('Invalid command: invalid') 1201 v:throwpoint->assert_match(', line 4$') 1202 endtry 1203 1204 lines =<< trim END 1205 vim9script 1206 def Func() 1207 var db = #{foo: 1, bar: 2} 1208 # comment 1209 var x = db.asdf 1210 enddef 1211 defcompile 1212 Func() 1213 END 1214 writefile(lines, 'Xdef') 1215 try 1216 source Xdef 1217 assert_report('should have failed') 1218 catch /E716:/ 1219 v:throwpoint->assert_match('_Func, line 3$') 1220 endtry 1221 1222 delete('Xdef') 1223enddef 1224 1225def Test_deleted_function() 1226 CheckDefExecFailure([ 1227 'var RefMe: func = function("g:DelMe")', 1228 'delfunc g:DelMe', 1229 'echo RefMe()'], 'E117:') 1230enddef 1231 1232def Test_unknown_function() 1233 CheckDefExecFailure([ 1234 'var Ref: func = function("NotExist")', 1235 'delfunc g:NotExist'], 'E700:') 1236enddef 1237 1238def RefFunc(Ref: func(string): string): string 1239 return Ref('more') 1240enddef 1241 1242def Test_closure_simple() 1243 var local = 'some ' 1244 RefFunc({s -> local .. s})->assert_equal('some more') 1245enddef 1246 1247def MakeRef() 1248 var local = 'some ' 1249 g:Ref = {s -> local .. s} 1250enddef 1251 1252def Test_closure_ref_after_return() 1253 MakeRef() 1254 g:Ref('thing')->assert_equal('some thing') 1255 unlet g:Ref 1256enddef 1257 1258def MakeTwoRefs() 1259 var local = ['some'] 1260 g:Extend = {s -> local->add(s)} 1261 g:Read = {-> local} 1262enddef 1263 1264def Test_closure_two_refs() 1265 MakeTwoRefs() 1266 join(g:Read(), ' ')->assert_equal('some') 1267 g:Extend('more') 1268 join(g:Read(), ' ')->assert_equal('some more') 1269 g:Extend('even') 1270 join(g:Read(), ' ')->assert_equal('some more even') 1271 1272 unlet g:Extend 1273 unlet g:Read 1274enddef 1275 1276def ReadRef(Ref: func(): list<string>): string 1277 return join(Ref(), ' ') 1278enddef 1279 1280def ExtendRef(Ref: func(string): list<string>, add: string) 1281 Ref(add) 1282enddef 1283 1284def Test_closure_two_indirect_refs() 1285 MakeTwoRefs() 1286 ReadRef(g:Read)->assert_equal('some') 1287 ExtendRef(g:Extend, 'more') 1288 ReadRef(g:Read)->assert_equal('some more') 1289 ExtendRef(g:Extend, 'even') 1290 ReadRef(g:Read)->assert_equal('some more even') 1291 1292 unlet g:Extend 1293 unlet g:Read 1294enddef 1295 1296def MakeArgRefs(theArg: string) 1297 var local = 'loc_val' 1298 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s} 1299enddef 1300 1301def MakeArgRefsVarargs(theArg: string, ...rest: list<string>) 1302 var local = 'the_loc' 1303 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)} 1304enddef 1305 1306def Test_closure_using_argument() 1307 MakeArgRefs('arg_val') 1308 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val') 1309 1310 MakeArgRefsVarargs('arg_val', 'one', 'two') 1311 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two') 1312 1313 unlet g:UseArg 1314 unlet g:UseVararg 1315enddef 1316 1317def MakeGetAndAppendRefs() 1318 var local = 'a' 1319 1320 def Append(arg: string) 1321 local ..= arg 1322 enddef 1323 g:Append = Append 1324 1325 def Get(): string 1326 return local 1327 enddef 1328 g:Get = Get 1329enddef 1330 1331def Test_closure_append_get() 1332 MakeGetAndAppendRefs() 1333 g:Get()->assert_equal('a') 1334 g:Append('-b') 1335 g:Get()->assert_equal('a-b') 1336 g:Append('-c') 1337 g:Get()->assert_equal('a-b-c') 1338 1339 unlet g:Append 1340 unlet g:Get 1341enddef 1342 1343def Test_nested_closure() 1344 var local = 'text' 1345 def Closure(arg: string): string 1346 return local .. arg 1347 enddef 1348 Closure('!!!')->assert_equal('text!!!') 1349enddef 1350 1351func GetResult(Ref) 1352 return a:Ref('some') 1353endfunc 1354 1355def Test_call_closure_not_compiled() 1356 var text = 'text' 1357 g:Ref = {s -> s .. text} 1358 GetResult(g:Ref)->assert_equal('sometext') 1359enddef 1360 1361def Test_double_closure_fails() 1362 var lines =<< trim END 1363 vim9script 1364 def Func() 1365 var name = 0 1366 for i in range(2) 1367 timer_start(0, {-> name}) 1368 endfor 1369 enddef 1370 Func() 1371 END 1372 CheckScriptSuccess(lines) 1373enddef 1374 1375def Test_nested_closure_used() 1376 var lines =<< trim END 1377 vim9script 1378 def Func() 1379 var x = 'hello' 1380 var Closure = {-> x} 1381 g:Myclosure = {-> Closure()} 1382 enddef 1383 Func() 1384 assert_equal('hello', g:Myclosure()) 1385 END 1386 CheckScriptSuccess(lines) 1387enddef 1388 1389def Test_nested_closure_fails() 1390 var lines =<< trim END 1391 vim9script 1392 def FuncA() 1393 FuncB(0) 1394 enddef 1395 def FuncB(n: number): list<string> 1396 return map([0], {_, v -> n}) 1397 enddef 1398 FuncA() 1399 END 1400 CheckScriptFailure(lines, 'E1012:') 1401enddef 1402 1403def Test_nested_lambda() 1404 var lines =<< trim END 1405 vim9script 1406 def Func() 1407 var x = 4 1408 var Lambda1 = {-> 7} 1409 var Lambda2 = {-> [Lambda1(), x]} 1410 var res = Lambda2() 1411 assert_equal([7, 4], res) 1412 enddef 1413 Func() 1414 END 1415 CheckScriptSuccess(lines) 1416enddef 1417 1418def Line_continuation_in_def(dir: string = ''): string 1419 var path: string = empty(dir) 1420 \ ? 'empty' 1421 \ : 'full' 1422 return path 1423enddef 1424 1425def Test_line_continuation_in_def() 1426 Line_continuation_in_def('.')->assert_equal('full') 1427enddef 1428 1429def Line_continuation_in_lambda(): list<string> 1430 var x = range(97, 100) 1431 ->map({_, v -> nr2char(v) 1432 ->toupper()}) 1433 ->reverse() 1434 return x 1435enddef 1436 1437def Test_line_continuation_in_lambda() 1438 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A']) 1439enddef 1440 1441func Test_silent_echo() 1442 CheckScreendump 1443 1444 let lines =<< trim END 1445 vim9script 1446 def EchoNothing() 1447 silent echo '' 1448 enddef 1449 defcompile 1450 END 1451 call writefile(lines, 'XTest_silent_echo') 1452 1453 " Check that the balloon shows up after a mouse move 1454 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6}) 1455 call term_sendkeys(buf, ":abc") 1456 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {}) 1457 1458 " clean up 1459 call StopVimInTerminal(buf) 1460 call delete('XTest_silent_echo') 1461endfunc 1462 1463def Fibonacci(n: number): number 1464 if n < 2 1465 return n 1466 else 1467 return Fibonacci(n - 1) + Fibonacci(n - 2) 1468 endif 1469enddef 1470 1471def Test_recursive_call() 1472 Fibonacci(20)->assert_equal(6765) 1473enddef 1474 1475def TreeWalk(dir: string): list<any> 1476 return readdir(dir)->map({_, val -> 1477 fnamemodify(dir .. '/' .. val, ':p')->isdirectory() 1478 ? {val: TreeWalk(dir .. '/' .. val)} 1479 : val 1480 }) 1481enddef 1482 1483def Test_closure_in_map() 1484 mkdir('XclosureDir/tdir', 'p') 1485 writefile(['111'], 'XclosureDir/file1') 1486 writefile(['222'], 'XclosureDir/file2') 1487 writefile(['333'], 'XclosureDir/tdir/file3') 1488 1489 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {'tdir': ['file3']}]) 1490 1491 delete('XclosureDir', 'rf') 1492enddef 1493 1494def Test_invalid_function_name() 1495 var lines =<< trim END 1496 vim9script 1497 def s: list<string> 1498 END 1499 CheckScriptFailure(lines, 'E129:') 1500 1501 lines =<< trim END 1502 vim9script 1503 def g: list<string> 1504 END 1505 CheckScriptFailure(lines, 'E129:') 1506 1507 lines =<< trim END 1508 vim9script 1509 def <SID>: list<string> 1510 END 1511 CheckScriptFailure(lines, 'E884:') 1512 1513 lines =<< trim END 1514 vim9script 1515 def F list<string> 1516 END 1517 CheckScriptFailure(lines, 'E488:') 1518enddef 1519 1520def Test_partial_call() 1521 var Xsetlist = function('setloclist', [0]) 1522 Xsetlist([], ' ', {'title': 'test'}) 1523 getloclist(0, {'title': 1})->assert_equal({'title': 'test'}) 1524 1525 Xsetlist = function('setloclist', [0, [], ' ']) 1526 Xsetlist({'title': 'test'}) 1527 getloclist(0, {'title': 1})->assert_equal({'title': 'test'}) 1528 1529 Xsetlist = function('setqflist') 1530 Xsetlist([], ' ', {'title': 'test'}) 1531 getqflist({'title': 1})->assert_equal({'title': 'test'}) 1532 1533 Xsetlist = function('setqflist', [[], ' ']) 1534 Xsetlist({'title': 'test'}) 1535 getqflist({'title': 1})->assert_equal({'title': 'test'}) 1536 1537 var Len: func: number = function('len', ['word']) 1538 assert_equal(4, Len()) 1539enddef 1540 1541def Test_cmd_modifier() 1542 tab echo '0' 1543 CheckDefFailure(['5tab echo 3'], 'E16:') 1544enddef 1545 1546def Test_restore_modifiers() 1547 # check that when compiling a :def function command modifiers are not messed 1548 # up. 1549 var lines =<< trim END 1550 vim9script 1551 set eventignore= 1552 autocmd QuickFixCmdPost * copen 1553 def AutocmdsDisabled() 1554 eval 0 1555 enddef 1556 func Func() 1557 noautocmd call s:AutocmdsDisabled() 1558 let g:ei_after = &eventignore 1559 endfunc 1560 Func() 1561 END 1562 CheckScriptSuccess(lines) 1563 g:ei_after->assert_equal('') 1564enddef 1565 1566def StackTop() 1567 eval 1 1568 eval 2 1569 # call not on fourth line 1570 StackBot() 1571enddef 1572 1573def StackBot() 1574 # throw an error 1575 eval [][0] 1576enddef 1577 1578def Test_callstack_def() 1579 try 1580 StackTop() 1581 catch 1582 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2') 1583 endtry 1584enddef 1585 1586" Re-using spot for variable used in block 1587def Test_block_scoped_var() 1588 var lines =<< trim END 1589 vim9script 1590 def Func() 1591 var x = ['a', 'b', 'c'] 1592 if 1 1593 var y = 'x' 1594 map(x, {-> y}) 1595 endif 1596 var z = x 1597 assert_equal(['x', 'x', 'x'], z) 1598 enddef 1599 Func() 1600 END 1601 CheckScriptSuccess(lines) 1602enddef 1603 1604 1605" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 1606