1" Test various aspects of the Vim script language. 2" Most of this was formerly in test49.vim (developed by Servatius Brandt 3" <[email protected]>) 4 5source check.vim 6source shared.vim 7source script_util.vim 8 9"------------------------------------------------------------------------------- 10" Test environment {{{1 11"------------------------------------------------------------------------------- 12 13" Append a message to the "messages" file 14func Xout(text) 15 split messages 16 $put =a:text 17 wq 18endfunc 19 20com! -nargs=1 Xout call Xout(<args>) 21 22" Create a new instance of Vim and run the commands in 'test' and then 'verify' 23" The commands in 'test' are expected to store the test results in the Xtest.out 24" file. If the test passes successfully, then Xtest.out should be empty. 25func RunInNewVim(test, verify) 26 let init =<< trim END 27 set cpo-=C " support line-continuation in sourced script 28 source script_util.vim 29 XpathINIT 30 XloopINIT 31 END 32 let cleanup =<< trim END 33 call writefile(v:errors, 'Xtest.out') 34 qall 35 END 36 call writefile(init, 'Xtest.vim') 37 call writefile(a:test, 'Xtest.vim', 'a') 38 call writefile(a:verify, 'Xverify.vim') 39 call writefile(cleanup, 'Xverify.vim', 'a') 40 call RunVim([], [], "-S Xtest.vim -S Xverify.vim") 41 call assert_equal([], readfile('Xtest.out')) 42 call delete('Xtest.out') 43 call delete('Xtest.vim') 44 call delete('Xverify.vim') 45endfunc 46 47"------------------------------------------------------------------------------- 48" Test 1: :endwhile in function {{{1 49" 50" Detect if a broken loop is (incorrectly) reactivated by the 51" :endwhile. Use a :return to prevent an endless loop, and make 52" this test first to get a meaningful result on an error before other 53" tests will hang. 54"------------------------------------------------------------------------------- 55 56func T1_F() 57 Xpath 'a' 58 let first = 1 59 while 1 60 Xpath 'b' 61 if first 62 Xpath 'c' 63 let first = 0 64 break 65 else 66 Xpath 'd' 67 return 68 endif 69 endwhile 70endfunc 71 72func T1_G() 73 Xpath 'h' 74 let first = 1 75 while 1 76 Xpath 'i' 77 if first 78 Xpath 'j' 79 let first = 0 80 break 81 else 82 Xpath 'k' 83 return 84 endif 85 if 1 " unmatched :if 86 endwhile 87endfunc 88 89func Test_endwhile_function() 90 XpathINIT 91 call T1_F() 92 Xpath 'F' 93 94 try 95 call T1_G() 96 catch 97 " Catch missing :endif 98 call assert_true(v:exception =~ 'E171') 99 Xpath 'x' 100 endtry 101 Xpath 'G' 102 103 call assert_equal('abcFhijxG', g:Xpath) 104endfunc 105 106"------------------------------------------------------------------------------- 107" Test 2: :endwhile in script {{{1 108" 109" Detect if a broken loop is (incorrectly) reactivated by the 110" :endwhile. Use a :finish to prevent an endless loop, and place 111" this test before others that might hang to get a meaningful result 112" on an error. 113" 114" This test executes the bodies of the functions T1_F and T1_G from 115" the previous test as script files (:return replaced by :finish). 116"------------------------------------------------------------------------------- 117 118func Test_endwhile_script() 119 XpathINIT 120 ExecAsScript T1_F 121 Xpath 'F' 122 call DeleteTheScript() 123 124 try 125 ExecAsScript T1_G 126 catch 127 " Catch missing :endif 128 call assert_true(v:exception =~ 'E171') 129 Xpath 'x' 130 endtry 131 Xpath 'G' 132 call DeleteTheScript() 133 134 call assert_equal('abcFhijxG', g:Xpath) 135endfunc 136 137"------------------------------------------------------------------------------- 138" Test 3: :if, :elseif, :while, :continue, :break {{{1 139"------------------------------------------------------------------------------- 140 141func Test_if_while() 142 XpathINIT 143 if 1 144 Xpath 'a' 145 let loops = 3 146 while loops > -1 " main loop: loops == 3, 2, 1 (which breaks) 147 if loops <= 0 148 let break_err = 1 149 let loops = -1 150 else 151 Xpath 'b' . loops 152 endif 153 if (loops == 2) 154 while loops == 2 " dummy loop 155 Xpath 'c' . loops 156 let loops = loops - 1 157 continue " stop dummy loop 158 Xpath 'd' . loops 159 endwhile 160 continue " continue main loop 161 Xpath 'e' . loops 162 elseif (loops == 1) 163 let p = 1 164 while p " dummy loop 165 Xpath 'f' . loops 166 let p = 0 167 break " break dummy loop 168 Xpath 'g' . loops 169 endwhile 170 Xpath 'h' . loops 171 unlet p 172 break " break main loop 173 Xpath 'i' . loops 174 endif 175 if (loops > 0) 176 Xpath 'j' . loops 177 endif 178 while loops == 3 " dummy loop 179 let loops = loops - 1 180 endwhile " end dummy loop 181 endwhile " end main loop 182 Xpath 'k' 183 else 184 Xpath 'l' 185 endif 186 Xpath 'm' 187 if exists("break_err") 188 Xpath 'm' 189 unlet break_err 190 endif 191 192 unlet loops 193 194 call assert_equal('ab3j3b2c2b1f1h1km', g:Xpath) 195endfunc 196 197"------------------------------------------------------------------------------- 198" Test 4: :return {{{1 199"------------------------------------------------------------------------------- 200 201func T4_F() 202 if 1 203 Xpath 'a' 204 let loops = 3 205 while loops > 0 " 3: 2: 1: 206 Xpath 'b' . loops 207 if (loops == 2) 208 Xpath 'c' . loops 209 return 210 Xpath 'd' . loops 211 endif 212 Xpath 'e' . loops 213 let loops = loops - 1 214 endwhile 215 Xpath 'f' 216 else 217 Xpath 'g' 218 endif 219endfunc 220 221func Test_return() 222 XpathINIT 223 call T4_F() 224 Xpath '4' 225 226 call assert_equal('ab3e3b2c24', g:Xpath) 227endfunc 228 229 230"------------------------------------------------------------------------------- 231" Test 5: :finish {{{1 232" 233" This test executes the body of the function T4_F from the previous 234" test as a script file (:return replaced by :finish). 235"------------------------------------------------------------------------------- 236 237func Test_finish() 238 XpathINIT 239 ExecAsScript T4_F 240 Xpath '5' 241 call DeleteTheScript() 242 243 call assert_equal('ab3e3b2c25', g:Xpath) 244endfunc 245 246 247 248"------------------------------------------------------------------------------- 249" Test 6: Defining functions in :while loops {{{1 250" 251" Functions can be defined inside other functions. An inner function 252" gets defined when the outer function is executed. Functions may 253" also be defined inside while loops. Expressions in braces for 254" defining the function name are allowed. 255" 256" The functions are defined when sourcing the script, only the 257" resulting path is checked in the test function. 258"------------------------------------------------------------------------------- 259 260XpathINIT 261 262" The command CALL collects the argument of all its invocations in "calls" 263" when used from a function (that is, when the global variable "calls" needs 264" the "g:" prefix). This is to check that the function code is skipped when 265" the function is defined. For inner functions, do so only if the outer 266" function is not being executed. 267" 268let calls = "" 269com! -nargs=1 CALL 270 \ if !exists("calls") && !exists("outer") | 271 \ let g:calls = g:calls . <args> | 272 \ endif 273 274let i = 0 275while i < 3 276 let i = i + 1 277 if i == 1 278 Xpath 'a' 279 function! F1(arg) 280 CALL a:arg 281 let outer = 1 282 283 let j = 0 284 while j < 1 285 Xpath 'b' 286 let j = j + 1 287 function! G1(arg) 288 CALL a:arg 289 endfunction 290 Xpath 'c' 291 endwhile 292 endfunction 293 Xpath 'd' 294 295 continue 296 endif 297 298 Xpath 'e' . i 299 function! F{i}(i, arg) 300 CALL a:arg 301 let outer = 1 302 303 if a:i == 3 304 Xpath 'f' 305 endif 306 let k = 0 307 while k < 3 308 Xpath 'g' . k 309 let k = k + 1 310 function! G{a:i}{k}(arg) 311 CALL a:arg 312 endfunction 313 Xpath 'h' . k 314 endwhile 315 endfunction 316 Xpath 'i' 317 318endwhile 319 320if exists("*G1") 321 Xpath 'j' 322endif 323if exists("*F1") 324 call F1("F1") 325 if exists("*G1") 326 call G1("G1") 327 endif 328endif 329 330if exists("G21") || exists("G22") || exists("G23") 331 Xpath 'k' 332endif 333if exists("*F2") 334 call F2(2, "F2") 335 if exists("*G21") 336 call G21("G21") 337 endif 338 if exists("*G22") 339 call G22("G22") 340 endif 341 if exists("*G23") 342 call G23("G23") 343 endif 344endif 345 346if exists("G31") || exists("G32") || exists("G33") 347 Xpath 'l' 348endif 349if exists("*F3") 350 call F3(3, "F3") 351 if exists("*G31") 352 call G31("G31") 353 endif 354 if exists("*G32") 355 call G32("G32") 356 endif 357 if exists("*G33") 358 call G33("G33") 359 endif 360endif 361 362Xpath 'm' 363 364let g:test6_result = g:Xpath 365let g:test6_calls = calls 366 367unlet calls 368delfunction F1 369delfunction G1 370delfunction F2 371delfunction G21 372delfunction G22 373delfunction G23 374delfunction G31 375delfunction G32 376delfunction G33 377 378func Test_defining_functions() 379 call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result) 380 call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls) 381endfunc 382 383"------------------------------------------------------------------------------- 384" Test 7: Continuing on errors outside functions {{{1 385" 386" On an error outside a function, the script processing continues 387" at the line following the outermost :endif or :endwhile. When not 388" inside an :if or :while, the script processing continues at the next 389" line. 390"------------------------------------------------------------------------------- 391 392XpathINIT 393 394if 1 395 Xpath 'a' 396 while 1 397 Xpath 'b' 398 asdf 399 Xpath 'c' 400 break 401 endwhile | Xpath 'd' 402 Xpath 'e' 403endif | Xpath 'f' 404Xpath 'g' 405 406while 1 407 Xpath 'h' 408 if 1 409 Xpath 'i' 410 asdf 411 Xpath 'j' 412 endif | Xpath 'k' 413 Xpath 'l' 414 break 415endwhile | Xpath 'm' 416Xpath 'n' 417 418asdf 419Xpath 'o' 420 421asdf | Xpath 'p' 422Xpath 'q' 423 424let g:test7_result = g:Xpath 425 426func Test_error_in_script() 427 call assert_equal('abghinoq', g:test7_result) 428endfunc 429 430"------------------------------------------------------------------------------- 431" Test 8: Aborting and continuing on errors inside functions {{{1 432" 433" On an error inside a function without the "abort" attribute, the 434" script processing continues at the next line (unless the error was 435" in a :return command). On an error inside a function with the 436" "abort" attribute, the function is aborted and the script processing 437" continues after the function call; the value -1 is returned then. 438"------------------------------------------------------------------------------- 439 440XpathINIT 441 442func T8_F() 443 if 1 444 Xpath 'a' 445 while 1 446 Xpath 'b' 447 asdf 448 Xpath 'c' 449 asdf | Xpath 'd' 450 Xpath 'e' 451 break 452 endwhile 453 Xpath 'f' 454 endif | Xpath 'g' 455 Xpath 'h' 456 457 while 1 458 Xpath 'i' 459 if 1 460 Xpath 'j' 461 asdf 462 Xpath 'k' 463 asdf | Xpath 'l' 464 Xpath 'm' 465 endif 466 Xpath 'n' 467 break 468 endwhile | Xpath 'o' 469 Xpath 'p' 470 471 return novar " returns (default return value 0) 472 Xpath 'q' 473 return 1 " not reached 474endfunc 475 476func T8_G() abort 477 if 1 478 Xpath 'r' 479 while 1 480 Xpath 's' 481 asdf " returns -1 482 Xpath 't' 483 break 484 endwhile 485 Xpath 'v' 486 endif | Xpath 'w' 487 Xpath 'x' 488 489 return -4 " not reached 490endfunc 491 492func T8_H() abort 493 while 1 494 Xpath 'A' 495 if 1 496 Xpath 'B' 497 asdf " returns -1 498 Xpath 'C' 499 endif 500 Xpath 'D' 501 break 502 endwhile | Xpath 'E' 503 Xpath 'F' 504 505 return -4 " not reached 506endfunc 507 508" Aborted functions (T8_G and T8_H) return -1. 509let g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H() 510Xpath 'X' 511let g:test8_result = g:Xpath 512 513func Test_error_in_function() 514 call assert_equal(13, g:test8_sum) 515 call assert_equal('abcefghijkmnoprsABX', g:test8_result) 516 517 delfunction T8_F 518 delfunction T8_G 519 delfunction T8_H 520endfunc 521 522 523"------------------------------------------------------------------------------- 524" Test 9: Continuing after aborted functions {{{1 525" 526" When a function with the "abort" attribute is aborted due to an 527" error, the next function back in the call hierarchy without an 528" "abort" attribute continues; the value -1 is returned then. 529"------------------------------------------------------------------------------- 530 531XpathINIT 532 533func F() abort 534 Xpath 'a' 535 let result = G() " not aborted 536 Xpath 'b' 537 if result != 2 538 Xpath 'c' 539 endif 540 return 1 541endfunc 542 543func G() " no abort attribute 544 Xpath 'd' 545 if H() != -1 " aborted 546 Xpath 'e' 547 endif 548 Xpath 'f' 549 return 2 550endfunc 551 552func H() abort 553 Xpath 'g' 554 call I() " aborted 555 Xpath 'h' 556 return 4 557endfunc 558 559func I() abort 560 Xpath 'i' 561 asdf " error 562 Xpath 'j' 563 return 8 564endfunc 565 566if F() != 1 567 Xpath 'k' 568endif 569 570let g:test9_result = g:Xpath 571 572delfunction F 573delfunction G 574delfunction H 575delfunction I 576 577func Test_func_abort() 578 call assert_equal('adgifb', g:test9_result) 579endfunc 580 581 582"------------------------------------------------------------------------------- 583" Test 10: :if, :elseif, :while argument parsing {{{1 584" 585" A '"' or '|' in an argument expression must not be mixed up with 586" a comment or a next command after a bar. Parsing errors should 587" be recognized. 588"------------------------------------------------------------------------------- 589 590XpathINIT 591 592func MSG(enr, emsg) 593 let english = v:lang == "C" || v:lang =~ '^[Ee]n' 594 if a:enr == "" 595 Xout "TODO: Add message number for:" a:emsg 596 let v:errmsg = ":" . v:errmsg 597 endif 598 let match = 1 599 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg) 600 let match = 0 601 if v:errmsg == "" 602 Xout "Message missing." 603 else 604 let v:errmsg = v:errmsg->escape('"') 605 Xout "Unexpected message:" v:errmsg 606 endif 607 endif 608 return match 609endfunc 610 611if 1 || strlen("\"") | Xpath 'a' 612 Xpath 'b' 613endif 614Xpath 'c' 615 616if 0 617elseif 1 || strlen("\"") | Xpath 'd' 618 Xpath 'e' 619endif 620Xpath 'f' 621 622while 1 || strlen("\"") | Xpath 'g' 623 Xpath 'h' 624 break 625endwhile 626Xpath 'i' 627 628let v:errmsg = "" 629if 1 ||| strlen("\"") | Xpath 'j' 630 Xpath 'k' 631endif 632Xpath 'l' 633if !MSG('E15', "Invalid expression") 634 Xpath 'm' 635endif 636 637let v:errmsg = "" 638if 0 639elseif 1 ||| strlen("\"") | Xpath 'n' 640 Xpath 'o' 641endif 642Xpath 'p' 643if !MSG('E15', "Invalid expression") 644 Xpath 'q' 645endif 646 647let v:errmsg = "" 648while 1 ||| strlen("\"") | Xpath 'r' 649 Xpath 's' 650 break 651endwhile 652Xpath 't' 653if !MSG('E15', "Invalid expression") 654 Xpath 'u' 655endif 656 657let g:test10_result = g:Xpath 658delfunction MSG 659 660func Test_expr_parsing() 661 call assert_equal('abcdefghilpt', g:test10_result) 662endfunc 663 664 665"------------------------------------------------------------------------------- 666" Test 11: :if, :elseif, :while argument evaluation after abort {{{1 667" 668" When code is skipped over due to an error, the boolean argument to 669" an :if, :elseif, or :while must not be evaluated. 670"------------------------------------------------------------------------------- 671 672XpathINIT 673 674let calls = 0 675 676func P(num) 677 let g:calls = g:calls + a:num " side effect on call 678 return 0 679endfunc 680 681if 1 682 Xpath 'a' 683 asdf " error 684 Xpath 'b' 685 if P(1) " should not be called 686 Xpath 'c' 687 elseif !P(2) " should not be called 688 Xpath 'd' 689 else 690 Xpath 'e' 691 endif 692 Xpath 'f' 693 while P(4) " should not be called 694 Xpath 'g' 695 endwhile 696 Xpath 'h' 697endif 698Xpath 'x' 699 700let g:test11_calls = calls 701let g:test11_result = g:Xpath 702 703unlet calls 704delfunction P 705 706func Test_arg_abort() 707 call assert_equal(0, g:test11_calls) 708 call assert_equal('ax', g:test11_result) 709endfunc 710 711 712"------------------------------------------------------------------------------- 713" Test 12: Expressions in braces in skipped code {{{1 714" 715" In code skipped over due to an error or inactive conditional, 716" an expression in braces as part of a variable or function name 717" should not be evaluated. 718"------------------------------------------------------------------------------- 719 720XpathINIT 721 722function! NULL() 723 Xpath 'a' 724 return 0 725endfunction 726 727function! ZERO() 728 Xpath 'b' 729 return 0 730endfunction 731 732function! F0() 733 Xpath 'c' 734endfunction 735 736function! F1(arg) 737 Xpath 'e' 738endfunction 739 740let V0 = 1 741 742Xpath 'f' 743echo 0 ? F{NULL() + V{ZERO()}}() : 1 744 745Xpath 'g' 746if 0 747 Xpath 'h' 748 call F{NULL() + V{ZERO()}}() 749endif 750 751Xpath 'i' 752if 1 753 asdf " error 754 Xpath 'j' 755 call F1(F{NULL() + V{ZERO()}}()) 756endif 757 758Xpath 'k' 759if 1 760 asdf " error 761 Xpath 'l' 762 call F{NULL() + V{ZERO()}}() 763endif 764 765let g:test12_result = g:Xpath 766 767func Test_braces_skipped() 768 call assert_equal('fgik', g:test12_result) 769endfunc 770 771 772"------------------------------------------------------------------------------- 773" Test 13: Failure in argument evaluation for :while {{{1 774" 775" A failure in the expression evaluation for the condition of a :while 776" causes the whole :while loop until the matching :endwhile being 777" ignored. Continuation is at the next following line. 778"------------------------------------------------------------------------------- 779 780XpathINIT 781 782Xpath 'a' 783while asdf 784 Xpath 'b' 785 while 1 786 Xpath 'c' 787 break 788 endwhile 789 Xpath 'd' 790 break 791endwhile 792Xpath 'e' 793 794while asdf | Xpath 'f' | endwhile | Xpath 'g' 795Xpath 'h' 796let g:test13_result = g:Xpath 797 798func Test_while_fail() 799 call assert_equal('aeh', g:test13_result) 800endfunc 801 802 803"------------------------------------------------------------------------------- 804" Test 14: Failure in argument evaluation for :if {{{1 805" 806" A failure in the expression evaluation for the condition of an :if 807" does not cause the corresponding :else or :endif being matched to 808" a previous :if/:elseif. Neither of both branches of the failed :if 809" are executed. 810"------------------------------------------------------------------------------- 811 812XpathINIT 813 814function! F() 815 Xpath 'a' 816 let x = 0 817 if x " false 818 Xpath 'b' 819 elseif !x " always true 820 Xpath 'c' 821 let x = 1 822 if g:boolvar " possibly undefined 823 Xpath 'd' 824 else 825 Xpath 'e' 826 endif 827 Xpath 'f' 828 elseif x " never executed 829 Xpath 'g' 830 endif 831 Xpath 'h' 832endfunction 833 834let boolvar = 1 835call F() 836Xpath '-' 837 838unlet boolvar 839call F() 840let g:test14_result = g:Xpath 841 842delfunction F 843 844func Test_if_fail() 845 call assert_equal('acdfh-acfh', g:test14_result) 846endfunc 847 848 849"------------------------------------------------------------------------------- 850" Test 15: Failure in argument evaluation for :if (bar) {{{1 851" 852" Like previous test, except that the failing :if ... | ... | :endif 853" is in a single line. 854"------------------------------------------------------------------------------- 855 856XpathINIT 857 858function! F() 859 Xpath 'a' 860 let x = 0 861 if x " false 862 Xpath 'b' 863 elseif !x " always true 864 Xpath 'c' 865 let x = 1 866 if g:boolvar | Xpath 'd' | else | Xpath 'e' | endif 867 Xpath 'f' 868 elseif x " never executed 869 Xpath 'g' 870 endif 871 Xpath 'h' 872endfunction 873 874let boolvar = 1 875call F() 876Xpath '-' 877 878unlet boolvar 879call F() 880let g:test15_result = g:Xpath 881 882delfunction F 883 884func Test_if_bar_fail() 885 call assert_equal('acdfh-acfh', g:test15_result) 886endfunc 887 888"------------------------------------------------------------------------------- 889" Test 16: Double :else or :elseif after :else {{{1 890" 891" Multiple :elses or an :elseif after an :else are forbidden. 892"------------------------------------------------------------------------------- 893 894func T16_F() abort 895 if 0 896 Xpath 'a' 897 else 898 Xpath 'b' 899 else " aborts function 900 Xpath 'c' 901 endif 902 Xpath 'd' 903endfunc 904 905func T16_G() abort 906 if 0 907 Xpath 'a' 908 else 909 Xpath 'b' 910 elseif 1 " aborts function 911 Xpath 'c' 912 else 913 Xpath 'd' 914 endif 915 Xpath 'e' 916endfunc 917 918func T16_H() abort 919 if 0 920 Xpath 'a' 921 elseif 0 922 Xpath 'b' 923 else 924 Xpath 'c' 925 else " aborts function 926 Xpath 'd' 927 endif 928 Xpath 'e' 929endfunc 930 931func T16_I() abort 932 if 0 933 Xpath 'a' 934 elseif 0 935 Xpath 'b' 936 else 937 Xpath 'c' 938 elseif 1 " aborts function 939 Xpath 'd' 940 else 941 Xpath 'e' 942 endif 943 Xpath 'f' 944endfunc 945 946func Test_Multi_Else() 947 XpathINIT 948 try 949 call T16_F() 950 catch /E583:/ 951 Xpath 'e' 952 endtry 953 call assert_equal('be', g:Xpath) 954 955 XpathINIT 956 try 957 call T16_G() 958 catch /E584:/ 959 Xpath 'f' 960 endtry 961 call assert_equal('bf', g:Xpath) 962 963 XpathINIT 964 try 965 call T16_H() 966 catch /E583:/ 967 Xpath 'f' 968 endtry 969 call assert_equal('cf', g:Xpath) 970 971 XpathINIT 972 try 973 call T16_I() 974 catch /E584:/ 975 Xpath 'g' 976 endtry 977 call assert_equal('cg', g:Xpath) 978endfunc 979 980"------------------------------------------------------------------------------- 981" Test 17: Nesting of unmatched :if or :endif inside a :while {{{1 982" 983" The :while/:endwhile takes precedence in nesting over an unclosed 984" :if or an unopened :endif. 985"------------------------------------------------------------------------------- 986 987" While loops inside a function are continued on error. 988func T17_F() 989 let loops = 3 990 while loops > 0 991 let loops -= 1 992 Xpath 'a' . loops 993 if (loops == 1) 994 Xpath 'b' . loops 995 continue 996 elseif (loops == 0) 997 Xpath 'c' . loops 998 break 999 elseif 1 1000 Xpath 'd' . loops 1001 " endif missing! 1002 endwhile " :endwhile after :if 1 1003 Xpath 'e' 1004endfunc 1005 1006func T17_G() 1007 let loops = 2 1008 while loops > 0 1009 let loops -= 1 1010 Xpath 'a' . loops 1011 if 0 1012 Xpath 'b' . loops 1013 " endif missing 1014 endwhile " :endwhile after :if 0 1015endfunc 1016 1017func T17_H() 1018 let loops = 2 1019 while loops > 0 1020 let loops -= 1 1021 Xpath 'a' . loops 1022 " if missing! 1023 endif " :endif without :if in while 1024 Xpath 'b' . loops 1025 endwhile 1026endfunc 1027 1028" Error continuation outside a function is at the outermost :endwhile or :endif. 1029XpathINIT 1030let v:errmsg = '' 1031let loops = 2 1032while loops > 0 1033 let loops -= 1 1034 Xpath 'a' . loops 1035 if 0 1036 Xpath 'b' . loops 1037 " endif missing! Following :endwhile fails. 1038endwhile | Xpath 'c' 1039Xpath 'd' 1040call assert_match('E171:', v:errmsg) 1041call assert_equal('a1d', g:Xpath) 1042 1043func Test_unmatched_if_in_while() 1044 XpathINIT 1045 call assert_fails('call T17_F()', 'E171:') 1046 call assert_equal('a2d2a1b1a0c0e', g:Xpath) 1047 1048 XpathINIT 1049 call assert_fails('call T17_G()', 'E171:') 1050 call assert_equal('a1a0', g:Xpath) 1051 1052 XpathINIT 1053 call assert_fails('call T17_H()', 'E580:') 1054 call assert_equal('a1b1a0b0', g:Xpath) 1055endfunc 1056 1057"------------------------------------------------------------------------------- 1058" Test 18: Interrupt (Ctrl-C pressed) {{{1 1059" 1060" On an interrupt, the script processing is terminated immediately. 1061"------------------------------------------------------------------------------- 1062 1063func Test_interrupt_while_if() 1064 let test =<< trim [CODE] 1065 try 1066 if 1 1067 Xpath 'a' 1068 while 1 1069 Xpath 'b' 1070 if 1 1071 Xpath 'c' 1072 call interrupt() 1073 call assert_report('should not get here') 1074 break 1075 finish 1076 endif | call assert_report('should not get here') 1077 call assert_report('should not get here') 1078 endwhile | call assert_report('should not get here') 1079 call assert_report('should not get here') 1080 endif | call assert_report('should not get here') 1081 call assert_report('should not get here') 1082 catch /^Vim:Interrupt$/ 1083 Xpath 'd' 1084 endtry | Xpath 'e' 1085 Xpath 'f' 1086 [CODE] 1087 let verify =<< trim [CODE] 1088 call assert_equal('abcdef', g:Xpath) 1089 [CODE] 1090 call RunInNewVim(test, verify) 1091endfunc 1092 1093func Test_interrupt_try() 1094 let test =<< trim [CODE] 1095 try 1096 try 1097 Xpath 'a' 1098 call interrupt() 1099 call assert_report('should not get here') 1100 endtry | call assert_report('should not get here') 1101 call assert_report('should not get here') 1102 catch /^Vim:Interrupt$/ 1103 Xpath 'b' 1104 endtry | Xpath 'c' 1105 Xpath 'd' 1106 [CODE] 1107 let verify =<< trim [CODE] 1108 call assert_equal('abcd', g:Xpath) 1109 [CODE] 1110 call RunInNewVim(test, verify) 1111endfunc 1112 1113func Test_interrupt_func_while_if() 1114 let test =<< trim [CODE] 1115 func F() 1116 if 1 1117 Xpath 'a' 1118 while 1 1119 Xpath 'b' 1120 if 1 1121 Xpath 'c' 1122 call interrupt() 1123 call assert_report('should not get here') 1124 break 1125 return 1126 endif | call assert_report('should not get here') 1127 call assert_report('should not get here') 1128 endwhile | call assert_report('should not get here') 1129 call assert_report('should not get here') 1130 endif | call assert_report('should not get here') 1131 call assert_report('should not get here') 1132 endfunc 1133 1134 Xpath 'd' 1135 try 1136 call F() | call assert_report('should not get here') 1137 catch /^Vim:Interrupt$/ 1138 Xpath 'e' 1139 endtry | Xpath 'f' 1140 Xpath 'g' 1141 [CODE] 1142 let verify =<< trim [CODE] 1143 call assert_equal('dabcefg', g:Xpath) 1144 [CODE] 1145 call RunInNewVim(test, verify) 1146endfunc 1147 1148func Test_interrupt_func_try() 1149 let test =<< trim [CODE] 1150 func G() 1151 try 1152 Xpath 'a' 1153 call interrupt() 1154 call assert_report('should not get here') 1155 endtry | call assert_report('should not get here') 1156 call assert_report('should not get here') 1157 endfunc 1158 1159 Xpath 'b' 1160 try 1161 call G() | call assert_report('should not get here') 1162 catch /^Vim:Interrupt$/ 1163 Xpath 'c' 1164 endtry | Xpath 'd' 1165 Xpath 'e' 1166 [CODE] 1167 let verify =<< trim [CODE] 1168 call assert_equal('bacde', g:Xpath) 1169 [CODE] 1170 call RunInNewVim(test, verify) 1171endfunc 1172 1173"------------------------------------------------------------------------------- 1174" Test 19: Aborting on errors inside :try/:endtry {{{1 1175" 1176" An error in a command dynamically enclosed in a :try/:endtry region 1177" aborts script processing immediately. It does not matter whether 1178" the failing command is outside or inside a function and whether a 1179" function has an "abort" attribute. 1180"------------------------------------------------------------------------------- 1181 1182func Test_try_error_abort_1() 1183 let test =<< trim [CODE] 1184 func F() abort 1185 Xpath 'a' 1186 asdf 1187 call assert_report('should not get here') 1188 endfunc 1189 1190 try 1191 Xpath 'b' 1192 call F() 1193 call assert_report('should not get here') 1194 endtry | call assert_report('should not get here') 1195 call assert_report('should not get here') 1196 [CODE] 1197 let verify =<< trim [CODE] 1198 call assert_equal('ba', g:Xpath) 1199 [CODE] 1200 call RunInNewVim(test, verify) 1201endfunc 1202 1203func Test_try_error_abort_2() 1204 let test =<< trim [CODE] 1205 func G() 1206 Xpath 'a' 1207 asdf 1208 call assert_report('should not get here') 1209 endfunc 1210 1211 try 1212 Xpath 'b' 1213 call G() 1214 call assert_report('should not get here') 1215 endtry | call assert_report('should not get here') 1216 call assert_report('should not get here') 1217 [CODE] 1218 let verify =<< trim [CODE] 1219 call assert_equal('ba', g:Xpath) 1220 [CODE] 1221 call RunInNewVim(test, verify) 1222endfunc 1223 1224func Test_try_error_abort_3() 1225 let test =<< trim [CODE] 1226 try 1227 Xpath 'a' 1228 asdf 1229 call assert_report('should not get here') 1230 endtry | call assert_report('should not get here') 1231 call assert_report('should not get here') 1232 [CODE] 1233 let verify =<< trim [CODE] 1234 call assert_equal('a', g:Xpath) 1235 [CODE] 1236 call RunInNewVim(test, verify) 1237endfunc 1238 1239func Test_try_error_abort_4() 1240 let test =<< trim [CODE] 1241 if 1 1242 try 1243 Xpath 'a' 1244 asdf 1245 call assert_report('should not get here') 1246 endtry | call assert_report('should not get here') 1247 endif | call assert_report('should not get here') 1248 call assert_report('should not get here') 1249 [CODE] 1250 let verify =<< trim [CODE] 1251 call assert_equal('a', g:Xpath) 1252 [CODE] 1253 call RunInNewVim(test, verify) 1254endfunc 1255 1256func Test_try_error_abort_5() 1257 let test =<< trim [CODE] 1258 let p = 1 1259 while p 1260 let p = 0 1261 try 1262 Xpath 'a' 1263 asdf 1264 call assert_report('should not get here') 1265 endtry | call assert_report('should not get here') 1266 endwhile | call assert_report('should not get here') 1267 call assert_report('should not get here') 1268 [CODE] 1269 let verify =<< trim [CODE] 1270 call assert_equal('a', g:Xpath) 1271 [CODE] 1272 call RunInNewVim(test, verify) 1273endfunc 1274 1275func Test_try_error_abort_6() 1276 let test =<< trim [CODE] 1277 let p = 1 1278 Xpath 'a' 1279 while p 1280 Xpath 'b' 1281 let p = 0 1282 try 1283 Xpath 'c' 1284 endwhile | call assert_report('should not get here') 1285 call assert_report('should not get here') 1286 [CODE] 1287 let verify =<< trim [CODE] 1288 call assert_equal('abc', g:Xpath) 1289 [CODE] 1290 call RunInNewVim(test, verify) 1291endfunc 1292 1293"------------------------------------------------------------------------------- 1294" Test 20: Aborting on errors after :try/:endtry {{{1 1295" 1296" When an error occurs after the last active :try/:endtry region has 1297" been left, termination behavior is as if no :try/:endtry has been 1298" seen. 1299"------------------------------------------------------------------------------- 1300 1301func Test_error_after_try_1() 1302 let test =<< trim [CODE] 1303 let p = 1 1304 while p 1305 let p = 0 1306 Xpath 'a' 1307 try 1308 Xpath 'b' 1309 endtry 1310 asdf 1311 call assert_report('should not get here') 1312 endwhile | call assert_report('should not get here') 1313 Xpath 'c' 1314 [CODE] 1315 let verify =<< trim [CODE] 1316 call assert_equal('abc', g:Xpath) 1317 [CODE] 1318 call RunInNewVim(test, verify) 1319endfunc 1320 1321func Test_error_after_try_2() 1322 let test =<< trim [CODE] 1323 while 1 1324 try 1325 Xpath 'a' 1326 break 1327 call assert_report('should not get here') 1328 endtry 1329 endwhile 1330 Xpath 'b' 1331 asdf 1332 Xpath 'c' 1333 [CODE] 1334 let verify =<< trim [CODE] 1335 call assert_equal('abc', g:Xpath) 1336 [CODE] 1337 call RunInNewVim(test, verify) 1338endfunc 1339 1340func Test_error_after_try_3() 1341 let test =<< trim [CODE] 1342 while 1 1343 try 1344 Xpath 'a' 1345 break 1346 call assert_report('should not get here') 1347 finally 1348 Xpath 'b' 1349 endtry 1350 endwhile 1351 Xpath 'c' 1352 asdf 1353 Xpath 'd' 1354 [CODE] 1355 let verify =<< trim [CODE] 1356 call assert_equal('abcd', g:Xpath) 1357 [CODE] 1358 call RunInNewVim(test, verify) 1359endfunc 1360 1361func Test_error_after_try_4() 1362 let test =<< trim [CODE] 1363 while 1 1364 try 1365 Xpath 'a' 1366 finally 1367 Xpath 'b' 1368 break 1369 call assert_report('should not get here') 1370 endtry 1371 endwhile 1372 Xpath 'c' 1373 asdf 1374 Xpath 'd' 1375 [CODE] 1376 let verify =<< trim [CODE] 1377 call assert_equal('abcd', g:Xpath) 1378 [CODE] 1379 call RunInNewVim(test, verify) 1380endfunc 1381 1382func Test_error_after_try_5() 1383 let test =<< trim [CODE] 1384 let p = 1 1385 while p 1386 let p = 0 1387 try 1388 Xpath 'a' 1389 continue 1390 call assert_report('should not get here') 1391 endtry 1392 endwhile 1393 Xpath 'b' 1394 asdf 1395 Xpath 'c' 1396 [CODE] 1397 let verify =<< trim [CODE] 1398 call assert_equal('abc', g:Xpath) 1399 [CODE] 1400 call RunInNewVim(test, verify) 1401endfunc 1402 1403func Test_error_after_try_6() 1404 let test =<< trim [CODE] 1405 let p = 1 1406 while p 1407 let p = 0 1408 try 1409 Xpath 'a' 1410 continue 1411 call assert_report('should not get here') 1412 finally 1413 Xpath 'b' 1414 endtry 1415 endwhile 1416 Xpath 'c' 1417 asdf 1418 Xpath 'd' 1419 [CODE] 1420 let verify =<< trim [CODE] 1421 call assert_equal('abcd', g:Xpath) 1422 [CODE] 1423 call RunInNewVim(test, verify) 1424endfunc 1425 1426func Test_error_after_try_7() 1427 let test =<< trim [CODE] 1428 let p = 1 1429 while p 1430 let p = 0 1431 try 1432 Xpath 'a' 1433 finally 1434 Xpath 'b' 1435 continue 1436 call assert_report('should not get here') 1437 endtry 1438 endwhile 1439 Xpath 'c' 1440 asdf 1441 Xpath 'd' 1442 [CODE] 1443 let verify =<< trim [CODE] 1444 call assert_equal('abcd', g:Xpath) 1445 [CODE] 1446 call RunInNewVim(test, verify) 1447endfunc 1448 1449"------------------------------------------------------------------------------- 1450" Test 21: :finally for :try after :continue/:break/:return/:finish {{{1 1451" 1452" If a :try conditional stays inactive due to a preceding :continue, 1453" :break, :return, or :finish, its :finally clause should not be 1454" executed. 1455"------------------------------------------------------------------------------- 1456 1457func Test_finally_after_loop_ctrl_statement() 1458 let test =<< trim [CODE] 1459 func F() 1460 let loops = 2 1461 while loops > 0 1462 XloopNEXT 1463 let loops = loops - 1 1464 try 1465 if loops == 1 1466 Xloop 'a' 1467 continue 1468 call assert_report('should not get here') 1469 elseif loops == 0 1470 Xloop 'b' 1471 break 1472 call assert_report('should not get here') 1473 endif 1474 1475 try " inactive 1476 call assert_report('should not get here') 1477 finally 1478 call assert_report('should not get here') 1479 endtry 1480 finally 1481 Xloop 'c' 1482 endtry 1483 call assert_report('should not get here') 1484 endwhile 1485 1486 try 1487 Xpath 'd' 1488 return 1489 call assert_report('should not get here') 1490 try " inactive 1491 call assert_report('should not get here') 1492 finally 1493 call assert_report('should not get here') 1494 endtry 1495 finally 1496 Xpath 'e' 1497 endtry 1498 call assert_report('should not get here') 1499 endfunc 1500 1501 try 1502 Xpath 'f' 1503 call F() 1504 Xpath 'g' 1505 finish 1506 call assert_report('should not get here') 1507 try " inactive 1508 call assert_report('should not get here') 1509 finally 1510 call assert_report('should not get here') 1511 endtry 1512 finally 1513 Xpath 'h' 1514 endtry 1515 call assert_report('should not get here') 1516 [CODE] 1517 let verify =<< trim [CODE] 1518 call assert_equal('fa2c2b3c3degh', g:Xpath) 1519 [CODE] 1520 call RunInNewVim(test, verify) 1521endfunc 1522 1523"------------------------------------------------------------------------------- 1524" Test 22: :finally for a :try after an error/interrupt/:throw {{{1 1525" 1526" If a :try conditional stays inactive due to a preceding error or 1527" interrupt or :throw, its :finally clause should not be executed. 1528"------------------------------------------------------------------------------- 1529 1530func Test_finally_after_error_in_func() 1531 let test =<< trim [CODE] 1532 func Error() 1533 try 1534 Xpath 'b' 1535 asdf " aborting error, triggering error exception 1536 call assert_report('should not get here') 1537 endtry 1538 call assert_report('should not get here') 1539 endfunc 1540 1541 Xpath 'a' 1542 call Error() 1543 call assert_report('should not get here') 1544 1545 if 1 " not active due to error 1546 try " not active since :if inactive 1547 call assert_report('should not get here') 1548 finally 1549 call assert_report('should not get here') 1550 endtry 1551 endif 1552 1553 try " not active due to error 1554 call assert_report('should not get here') 1555 finally 1556 call assert_report('should not get here') 1557 endtry 1558 [CODE] 1559 let verify =<< trim [CODE] 1560 call assert_equal('ab', g:Xpath) 1561 [CODE] 1562 call RunInNewVim(test, verify) 1563endfunc 1564 1565func Test_finally_after_interrupt() 1566 let test =<< trim [CODE] 1567 func Interrupt() 1568 try 1569 Xpath 'a' 1570 call interrupt() " triggering interrupt exception 1571 call assert_report('should not get here') 1572 endtry 1573 endfunc 1574 1575 Xpath 'b' 1576 try 1577 call Interrupt() 1578 catch /^Vim:Interrupt$/ 1579 Xpath 'c' 1580 finish 1581 endtry 1582 call assert_report('should not get here') 1583 1584 if 1 " not active due to interrupt 1585 try " not active since :if inactive 1586 call assert_report('should not get here') 1587 finally 1588 call assert_report('should not get here') 1589 endtry 1590 endif 1591 1592 try " not active due to interrupt 1593 call assert_report('should not get here') 1594 finally 1595 call assert_report('should not get here') 1596 endtry 1597 [CODE] 1598 let verify =<< trim [CODE] 1599 call assert_equal('bac', g:Xpath) 1600 [CODE] 1601 call RunInNewVim(test, verify) 1602endfunc 1603 1604func Test_finally_after_throw() 1605 let test =<< trim [CODE] 1606 func Throw() 1607 Xpath 'a' 1608 throw 'xyz' 1609 endfunc 1610 1611 Xpath 'b' 1612 call Throw() 1613 call assert_report('should not get here') 1614 1615 if 1 " not active due to :throw 1616 try " not active since :if inactive 1617 call assert_report('should not get here') 1618 finally 1619 call assert_report('should not get here') 1620 endtry 1621 endif 1622 1623 try " not active due to :throw 1624 call assert_report('should not get here') 1625 finally 1626 call assert_report('should not get here') 1627 endtry 1628 [CODE] 1629 let verify =<< trim [CODE] 1630 call assert_equal('ba', g:Xpath) 1631 [CODE] 1632 call RunInNewVim(test, verify) 1633endfunc 1634 1635"------------------------------------------------------------------------------- 1636" Test 23: :catch clauses for a :try after a :throw {{{1 1637" 1638" If a :try conditional stays inactive due to a preceding :throw, 1639" none of its :catch clauses should be executed. 1640"------------------------------------------------------------------------------- 1641 1642func Test_catch_after_throw() 1643 let test =<< trim [CODE] 1644 try 1645 Xpath 'a' 1646 throw "xyz" 1647 call assert_report('should not get here') 1648 1649 if 1 " not active due to :throw 1650 try " not active since :if inactive 1651 call assert_report('should not get here') 1652 catch /xyz/ 1653 call assert_report('should not get here') 1654 endtry 1655 endif 1656 catch /xyz/ 1657 Xpath 'b' 1658 endtry 1659 1660 Xpath 'c' 1661 throw "abc" 1662 call assert_report('should not get here') 1663 1664 try " not active due to :throw 1665 call assert_report('should not get here') 1666 catch /abc/ 1667 call assert_report('should not get here') 1668 endtry 1669 [CODE] 1670 let verify =<< trim [CODE] 1671 call assert_equal('abc', g:Xpath) 1672 [CODE] 1673 call RunInNewVim(test, verify) 1674endfunc 1675 1676"------------------------------------------------------------------------------- 1677" Test 24: :endtry for a :try after a :throw {{{1 1678" 1679" If a :try conditional stays inactive due to a preceding :throw, 1680" its :endtry should not rethrow the exception to the next surrounding 1681" active :try conditional. 1682"------------------------------------------------------------------------------- 1683 1684func Test_endtry_after_throw() 1685 let test =<< trim [CODE] 1686 try " try 1 1687 try " try 2 1688 Xpath 'a' 1689 throw "xyz" " makes try 2 inactive 1690 call assert_report('should not get here') 1691 1692 try " try 3 1693 call assert_report('should not get here') 1694 endtry " no rethrow to try 1 1695 catch /xyz/ " should catch although try 2 inactive 1696 Xpath 'b' 1697 endtry 1698 catch /xyz/ " try 1 active, but exception already caught 1699 call assert_report('should not get here') 1700 endtry 1701 Xpath 'c' 1702 [CODE] 1703 let verify =<< trim [CODE] 1704 call assert_equal('abc', g:Xpath) 1705 [CODE] 1706 call RunInNewVim(test, verify) 1707endfunc 1708 1709"------------------------------------------------------------------------------- 1710" Test 27: Executing :finally clauses after :return {{{1 1711" 1712" For a :return command dynamically enclosed in a :try/:endtry region, 1713" :finally clauses are executed and the called function is ended. 1714"------------------------------------------------------------------------------- 1715 1716func T27_F() 1717 try 1718 Xpath 'a' 1719 try 1720 Xpath 'b' 1721 return 1722 call assert_report('should not get here') 1723 finally 1724 Xpath 'c' 1725 endtry 1726 Xpath 'd' 1727 finally 1728 Xpath 'e' 1729 endtry 1730 call assert_report('should not get here') 1731endfunc 1732 1733func T27_G() 1734 try 1735 Xpath 'f' 1736 return 1737 call assert_report('should not get here') 1738 finally 1739 Xpath 'g' 1740 call T27_F() 1741 Xpath 'h' 1742 endtry 1743 call assert_report('should not get here') 1744endfunc 1745 1746func T27_H() 1747 try 1748 Xpath 'i' 1749 call T27_G() 1750 Xpath 'j' 1751 finally 1752 Xpath 'k' 1753 return 1754 call assert_report('should not get here') 1755 endtry 1756 call assert_report('should not get here') 1757endfunction 1758 1759func Test_finally_after_return() 1760 XpathINIT 1761 try 1762 Xpath 'l' 1763 call T27_H() 1764 Xpath 'm' 1765 finally 1766 Xpath 'n' 1767 endtry 1768 call assert_equal('lifgabcehjkmn', g:Xpath) 1769endfunc 1770 1771"------------------------------------------------------------------------------- 1772" Test 28: Executing :finally clauses after :finish {{{1 1773" 1774" For a :finish command dynamically enclosed in a :try/:endtry region, 1775" :finally clauses are executed and the sourced file is finished. 1776" 1777" This test executes the bodies of the functions F, G, and H from the 1778" previous test as script files (:return replaced by :finish). 1779"------------------------------------------------------------------------------- 1780 1781func Test_finally_after_finish() 1782 XpathINIT 1783 1784 let scriptF = MakeScript("T27_F") 1785 let scriptG = MakeScript("T27_G", scriptF) 1786 let scriptH = MakeScript("T27_H", scriptG) 1787 1788 try 1789 Xpath 'A' 1790 exec "source" scriptH 1791 Xpath 'B' 1792 finally 1793 Xpath 'C' 1794 endtry 1795 Xpath 'D' 1796 call assert_equal('AifgabcehjkBCD', g:Xpath) 1797 call delete(scriptF) 1798 call delete(scriptG) 1799 call delete(scriptH) 1800endfunc 1801 1802"------------------------------------------------------------------------------- 1803" Test 29: Executing :finally clauses on errors {{{1 1804" 1805" After an error in a command dynamically enclosed in a :try/:endtry 1806" region, :finally clauses are executed and the script processing is 1807" terminated. 1808"------------------------------------------------------------------------------- 1809 1810func Test_finally_after_error_1() 1811 let test =<< trim [CODE] 1812 func F() 1813 while 1 1814 try 1815 Xpath 'a' 1816 while 1 1817 try 1818 Xpath 'b' 1819 asdf " error 1820 call assert_report('should not get here') 1821 finally 1822 Xpath 'c' 1823 endtry | call assert_report('should not get here') 1824 call assert_report('should not get here') 1825 break 1826 endwhile 1827 call assert_report('should not get here') 1828 finally 1829 Xpath 'd' 1830 endtry | call assert_report('should not get here') 1831 call assert_report('should not get here') 1832 break 1833 endwhile 1834 call assert_report('should not get here') 1835 endfunc 1836 1837 while 1 1838 try 1839 Xpath 'e' 1840 while 1 1841 call F() 1842 call assert_report('should not get here') 1843 break 1844 endwhile | call assert_report('should not get here') 1845 call assert_report('should not get here') 1846 finally 1847 Xpath 'f' 1848 endtry | call assert_report('should not get here') 1849 endwhile | call assert_report('should not get here') 1850 call assert_report('should not get here') 1851 [CODE] 1852 let verify =<< trim [CODE] 1853 call assert_equal('eabcdf', g:Xpath) 1854 [CODE] 1855 call RunInNewVim(test, verify) 1856endfunc 1857 1858func Test_finally_after_error_2() 1859 let test =<< trim [CODE] 1860 func G() abort 1861 if 1 1862 try 1863 Xpath 'a' 1864 asdf " error 1865 call assert_report('should not get here') 1866 finally 1867 Xpath 'b' 1868 endtry | Xpath 'c' 1869 endif | Xpath 'd' 1870 call assert_report('should not get here') 1871 endfunc 1872 1873 if 1 1874 try 1875 Xpath 'e' 1876 call G() 1877 call assert_report('should not get here') 1878 finally 1879 Xpath 'f' 1880 endtry | call assert_report('should not get here') 1881 endif | call assert_report('should not get here') 1882 call assert_report('should not get here') 1883 [CODE] 1884 let verify =<< trim [CODE] 1885 call assert_equal('eabf', g:Xpath) 1886 [CODE] 1887 call RunInNewVim(test, verify) 1888endfunc 1889 1890"------------------------------------------------------------------------------- 1891" Test 30: Executing :finally clauses on interrupt {{{1 1892" 1893" After an interrupt in a command dynamically enclosed in 1894" a :try/:endtry region, :finally clauses are executed and the 1895" script processing is terminated. 1896"------------------------------------------------------------------------------- 1897 1898func Test_finally_on_interrupt() 1899 let test =<< trim [CODE] 1900 func F() 1901 try 1902 Xloop 'a' 1903 call interrupt() 1904 call assert_report('should not get here') 1905 finally 1906 Xloop 'b' 1907 endtry 1908 call assert_report('should not get here') 1909 endfunc 1910 1911 try 1912 try 1913 Xpath 'c' 1914 try 1915 Xpath 'd' 1916 call interrupt() 1917 call assert_report('should not get here') 1918 finally 1919 Xpath 'e' 1920 try 1921 Xpath 'f' 1922 try 1923 Xpath 'g' 1924 finally 1925 Xpath 'h' 1926 try 1927 Xpath 'i' 1928 call interrupt() 1929 call assert_report('should not get here') 1930 endtry 1931 call assert_report('should not get here') 1932 endtry 1933 call assert_report('should not get here') 1934 endtry 1935 call assert_report('should not get here') 1936 endtry 1937 call assert_report('should not get here') 1938 finally 1939 Xpath 'j' 1940 try 1941 Xpath 'k' 1942 call F() 1943 call assert_report('should not get here') 1944 finally 1945 Xpath 'l' 1946 try 1947 Xpath 'm' 1948 XloopNEXT 1949 ExecAsScript F 1950 call assert_report('should not get here') 1951 finally 1952 Xpath 'n' 1953 endtry 1954 call assert_report('should not get here') 1955 endtry 1956 call assert_report('should not get here') 1957 endtry 1958 call assert_report('should not get here') 1959 catch /^Vim:Interrupt$/ 1960 Xpath 'o' 1961 endtry 1962 [CODE] 1963 let verify =<< trim [CODE] 1964 call assert_equal('cdefghijka1b1lma2b2no', g:Xpath) 1965 [CODE] 1966 call RunInNewVim(test, verify) 1967endfunc 1968 1969"------------------------------------------------------------------------------- 1970" Test 31: Executing :finally clauses after :throw {{{1 1971" 1972" After a :throw dynamically enclosed in a :try/:endtry region, 1973" :finally clauses are executed and the script processing is 1974" terminated. 1975"------------------------------------------------------------------------------- 1976 1977func Test_finally_after_throw_2() 1978 let test =<< trim [CODE] 1979 func F() 1980 try 1981 Xloop 'a' 1982 throw "exception" 1983 call assert_report('should not get here') 1984 finally 1985 Xloop 'b' 1986 endtry 1987 call assert_report('should not get here') 1988 endfunc 1989 1990 try 1991 Xpath 'c' 1992 try 1993 Xpath 'd' 1994 throw "exception" 1995 call assert_report('should not get here') 1996 finally 1997 Xpath 'e' 1998 try 1999 Xpath 'f' 2000 try 2001 Xpath 'g' 2002 finally 2003 Xpath 'h' 2004 try 2005 Xpath 'i' 2006 throw "exception" 2007 call assert_report('should not get here') 2008 endtry 2009 call assert_report('should not get here') 2010 endtry 2011 call assert_report('should not get here') 2012 endtry 2013 call assert_report('should not get here') 2014 endtry 2015 call assert_report('should not get here') 2016 finally 2017 Xpath 'j' 2018 try 2019 Xpath 'k' 2020 call F() 2021 call assert_report('should not get here') 2022 finally 2023 Xpath 'l' 2024 try 2025 Xpath 'm' 2026 XloopNEXT 2027 ExecAsScript F 2028 call assert_report('should not get here') 2029 finally 2030 Xpath 'n' 2031 endtry 2032 call assert_report('should not get here') 2033 endtry 2034 call assert_report('should not get here') 2035 endtry 2036 call assert_report('should not get here') 2037 [CODE] 2038 let verify =<< trim [CODE] 2039 call assert_equal('cdefghijka1b1lma2b2n', g:Xpath) 2040 [CODE] 2041 call RunInNewVim(test, verify) 2042endfunc 2043 2044"------------------------------------------------------------------------------- 2045" Test 34: :finally reason discarded by :continue {{{1 2046" 2047" When a :finally clause is executed due to a :continue, :break, 2048" :return, :finish, error, interrupt or :throw, the jump reason is 2049" discarded by a :continue in the finally clause. 2050"------------------------------------------------------------------------------- 2051 2052func Test_finally_after_continue() 2053 let test =<< trim [CODE] 2054 func C(jump) 2055 XloopNEXT 2056 let loop = 0 2057 while loop < 2 2058 let loop = loop + 1 2059 if loop == 1 2060 try 2061 if a:jump == "continue" 2062 continue 2063 elseif a:jump == "break" 2064 break 2065 elseif a:jump == "return" || a:jump == "finish" 2066 return 2067 elseif a:jump == "error" 2068 asdf 2069 elseif a:jump == "interrupt" 2070 call interrupt() 2071 let dummy = 0 2072 elseif a:jump == "throw" 2073 throw "abc" 2074 endif 2075 finally 2076 continue " discards jump that caused the :finally 2077 call assert_report('should not get here') 2078 endtry 2079 call assert_report('should not get here') 2080 elseif loop == 2 2081 Xloop 'a' 2082 endif 2083 endwhile 2084 endfunc 2085 2086 call C("continue") 2087 Xpath 'b' 2088 call C("break") 2089 Xpath 'c' 2090 call C("return") 2091 Xpath 'd' 2092 let g:jump = "finish" 2093 ExecAsScript C 2094 unlet g:jump 2095 Xpath 'e' 2096 try 2097 call C("error") 2098 Xpath 'f' 2099 finally 2100 Xpath 'g' 2101 try 2102 call C("interrupt") 2103 Xpath 'h' 2104 finally 2105 Xpath 'i' 2106 call C("throw") 2107 Xpath 'j' 2108 endtry 2109 endtry 2110 Xpath 'k' 2111 [CODE] 2112 let verify =<< trim [CODE] 2113 call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath) 2114 [CODE] 2115 call RunInNewVim(test, verify) 2116endfunc 2117 2118"------------------------------------------------------------------------------- 2119" Test 35: :finally reason discarded by :break {{{1 2120" 2121" When a :finally clause is executed due to a :continue, :break, 2122" :return, :finish, error, interrupt or :throw, the jump reason is 2123" discarded by a :break in the finally clause. 2124"------------------------------------------------------------------------------- 2125 2126func Test_finally_discard_by_break() 2127 let test =<< trim [CODE] 2128 func B(jump) 2129 XloopNEXT 2130 let loop = 0 2131 while loop < 2 2132 let loop = loop + 1 2133 if loop == 1 2134 try 2135 if a:jump == "continue" 2136 continue 2137 elseif a:jump == "break" 2138 break 2139 elseif a:jump == "return" || a:jump == "finish" 2140 return 2141 elseif a:jump == "error" 2142 asdf 2143 elseif a:jump == "interrupt" 2144 call interrupt() 2145 let dummy = 0 2146 elseif a:jump == "throw" 2147 throw "abc" 2148 endif 2149 finally 2150 break " discards jump that caused the :finally 2151 call assert_report('should not get here') 2152 endtry 2153 elseif loop == 2 2154 call assert_report('should not get here') 2155 endif 2156 endwhile 2157 Xloop 'a' 2158 endfunc 2159 2160 call B("continue") 2161 Xpath 'b' 2162 call B("break") 2163 Xpath 'c' 2164 call B("return") 2165 Xpath 'd' 2166 let g:jump = "finish" 2167 ExecAsScript B 2168 unlet g:jump 2169 Xpath 'e' 2170 try 2171 call B("error") 2172 Xpath 'f' 2173 finally 2174 Xpath 'g' 2175 try 2176 call B("interrupt") 2177 Xpath 'h' 2178 finally 2179 Xpath 'i' 2180 call B("throw") 2181 Xpath 'j' 2182 endtry 2183 endtry 2184 Xpath 'k' 2185 [CODE] 2186 let verify =<< trim [CODE] 2187 call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath) 2188 [CODE] 2189 call RunInNewVim(test, verify) 2190endfunc 2191 2192"------------------------------------------------------------------------------- 2193" Test 36: :finally reason discarded by :return {{{1 2194" 2195" When a :finally clause is executed due to a :continue, :break, 2196" :return, :finish, error, interrupt or :throw, the jump reason is 2197" discarded by a :return in the finally clause. 2198"------------------------------------------------------------------------------- 2199 2200func Test_finally_discard_by_return() 2201 let test =<< trim [CODE] 2202 func R(jump, retval) abort 2203 let loop = 0 2204 while loop < 2 2205 let loop = loop + 1 2206 if loop == 1 2207 try 2208 if a:jump == "continue" 2209 continue 2210 elseif a:jump == "break" 2211 break 2212 elseif a:jump == "return" 2213 return 2214 elseif a:jump == "error" 2215 asdf 2216 elseif a:jump == "interrupt" 2217 call interrupt() 2218 let dummy = 0 2219 elseif a:jump == "throw" 2220 throw "abc" 2221 endif 2222 finally 2223 return a:retval " discards jump that caused the :finally 2224 call assert_report('should not get here') 2225 endtry 2226 elseif loop == 2 2227 call assert_report('should not get here') 2228 endif 2229 endwhile 2230 call assert_report('should not get here') 2231 endfunc 2232 2233 let sum = -R("continue", -8) 2234 Xpath 'a' 2235 let sum = sum - R("break", -16) 2236 Xpath 'b' 2237 let sum = sum - R("return", -32) 2238 Xpath 'c' 2239 try 2240 let sum = sum - R("error", -64) 2241 Xpath 'd' 2242 finally 2243 Xpath 'e' 2244 try 2245 let sum = sum - R("interrupt", -128) 2246 Xpath 'f' 2247 finally 2248 Xpath 'g' 2249 let sum = sum - R("throw", -256) 2250 Xpath 'h' 2251 endtry 2252 endtry 2253 Xpath 'i' 2254 2255 let expected = 8 + 16 + 32 + 64 + 128 + 256 2256 call assert_equal(sum, expected) 2257 [CODE] 2258 let verify =<< trim [CODE] 2259 call assert_equal('abcdefghi', g:Xpath) 2260 [CODE] 2261 call RunInNewVim(test, verify) 2262endfunc 2263 2264"------------------------------------------------------------------------------- 2265" Test 37: :finally reason discarded by :finish {{{1 2266" 2267" When a :finally clause is executed due to a :continue, :break, 2268" :return, :finish, error, interrupt or :throw, the jump reason is 2269" discarded by a :finish in the finally clause. 2270"------------------------------------------------------------------------------- 2271 2272func Test_finally_discard_by_finish() 2273 let test =<< trim [CODE] 2274 func F(jump) " not executed as function, transformed to a script 2275 let loop = 0 2276 while loop < 2 2277 let loop = loop + 1 2278 if loop == 1 2279 try 2280 if a:jump == "continue" 2281 continue 2282 elseif a:jump == "break" 2283 break 2284 elseif a:jump == "finish" 2285 finish 2286 elseif a:jump == "error" 2287 asdf 2288 elseif a:jump == "interrupt" 2289 call interrupt() 2290 let dummy = 0 2291 elseif a:jump == "throw" 2292 throw "abc" 2293 endif 2294 finally 2295 finish " discards jump that caused the :finally 2296 call assert_report('should not get here') 2297 endtry 2298 elseif loop == 2 2299 call assert_report('should not get here') 2300 endif 2301 endwhile 2302 call assert_report('should not get here') 2303 endfunc 2304 2305 let scriptF = MakeScript("F") 2306 delfunction F 2307 2308 let g:jump = "continue" 2309 exec "source" scriptF 2310 Xpath 'a' 2311 let g:jump = "break" 2312 exec "source" scriptF 2313 Xpath 'b' 2314 let g:jump = "finish" 2315 exec "source" scriptF 2316 Xpath 'c' 2317 try 2318 let g:jump = "error" 2319 exec "source" scriptF 2320 Xpath 'd' 2321 finally 2322 Xpath 'e' 2323 try 2324 let g:jump = "interrupt" 2325 exec "source" scriptF 2326 Xpath 'f' 2327 finally 2328 Xpath 'g' 2329 try 2330 let g:jump = "throw" 2331 exec "source" scriptF 2332 Xpath 'h' 2333 finally 2334 Xpath 'i' 2335 endtry 2336 endtry 2337 endtry 2338 unlet g:jump 2339 call delete(scriptF) 2340 [CODE] 2341 let verify =<< trim [CODE] 2342 call assert_equal('abcdefghi', g:Xpath) 2343 [CODE] 2344 call RunInNewVim(test, verify) 2345endfunc 2346 2347"------------------------------------------------------------------------------- 2348" Test 38: :finally reason discarded by an error {{{1 2349" 2350" When a :finally clause is executed due to a :continue, :break, 2351" :return, :finish, error, interrupt or :throw, the jump reason is 2352" discarded by an error in the finally clause. 2353"------------------------------------------------------------------------------- 2354 2355func Test_finally_discard_by_error() 2356 let test =<< trim [CODE] 2357 func E(jump) 2358 let loop = 0 2359 while loop < 2 2360 let loop = loop + 1 2361 if loop == 1 2362 try 2363 if a:jump == "continue" 2364 continue 2365 elseif a:jump == "break" 2366 break 2367 elseif a:jump == "return" || a:jump == "finish" 2368 return 2369 elseif a:jump == "error" 2370 asdf 2371 elseif a:jump == "interrupt" 2372 call interrupt() 2373 let dummy = 0 2374 elseif a:jump == "throw" 2375 throw "abc" 2376 endif 2377 finally 2378 asdf " error; discards jump that caused the :finally 2379 endtry 2380 elseif loop == 2 2381 call assert_report('should not get here') 2382 endif 2383 endwhile 2384 call assert_report('should not get here') 2385 endfunc 2386 2387 try 2388 Xpath 'a' 2389 call E("continue") 2390 call assert_report('should not get here') 2391 finally 2392 try 2393 Xpath 'b' 2394 call E("break") 2395 call assert_report('should not get here') 2396 finally 2397 try 2398 Xpath 'c' 2399 call E("return") 2400 call assert_report('should not get here') 2401 finally 2402 try 2403 Xpath 'd' 2404 let g:jump = "finish" 2405 ExecAsScript E 2406 call assert_report('should not get here') 2407 finally 2408 unlet g:jump 2409 try 2410 Xpath 'e' 2411 call E("error") 2412 call assert_report('should not get here') 2413 finally 2414 try 2415 Xpath 'f' 2416 call E("interrupt") 2417 call assert_report('should not get here') 2418 finally 2419 try 2420 Xpath 'g' 2421 call E("throw") 2422 call assert_report('should not get here') 2423 finally 2424 Xpath 'h' 2425 delfunction E 2426 endtry 2427 endtry 2428 endtry 2429 endtry 2430 endtry 2431 endtry 2432 endtry 2433 call assert_report('should not get here') 2434 [CODE] 2435 let verify =<< trim [CODE] 2436 call assert_equal('abcdefgh', g:Xpath) 2437 [CODE] 2438 call RunInNewVim(test, verify) 2439endfunc 2440 2441"------------------------------------------------------------------------------- 2442" Test 39: :finally reason discarded by an interrupt {{{1 2443" 2444" When a :finally clause is executed due to a :continue, :break, 2445" :return, :finish, error, interrupt or :throw, the jump reason is 2446" discarded by an interrupt in the finally clause. 2447"------------------------------------------------------------------------------- 2448 2449func Test_finally_discarded_by_interrupt() 2450 let test =<< trim [CODE] 2451 func I(jump) 2452 let loop = 0 2453 while loop < 2 2454 let loop = loop + 1 2455 if loop == 1 2456 try 2457 if a:jump == "continue" 2458 continue 2459 elseif a:jump == "break" 2460 break 2461 elseif a:jump == "return" || a:jump == "finish" 2462 return 2463 elseif a:jump == "error" 2464 asdf 2465 elseif a:jump == "interrupt" 2466 call interrupt() 2467 let dummy = 0 2468 elseif a:jump == "throw" 2469 throw "abc" 2470 endif 2471 finally 2472 call interrupt() 2473 let dummy = 0 2474 endtry 2475 elseif loop == 2 2476 call assert_report('should not get here') 2477 endif 2478 endwhile 2479 call assert_report('should not get here') 2480 endfunc 2481 2482 try 2483 try 2484 Xpath 'a' 2485 call I("continue") 2486 call assert_report('should not get here') 2487 finally 2488 try 2489 Xpath 'b' 2490 call I("break") 2491 call assert_report('should not get here') 2492 finally 2493 try 2494 Xpath 'c' 2495 call I("return") 2496 call assert_report('should not get here') 2497 finally 2498 try 2499 Xpath 'd' 2500 let g:jump = "finish" 2501 ExecAsScript I 2502 call assert_report('should not get here') 2503 finally 2504 unlet g:jump 2505 try 2506 Xpath 'e' 2507 call I("error") 2508 call assert_report('should not get here') 2509 finally 2510 try 2511 Xpath 'f' 2512 call I("interrupt") 2513 call assert_report('should not get here') 2514 finally 2515 try 2516 Xpath 'g' 2517 call I("throw") 2518 call assert_report('should not get here') 2519 finally 2520 Xpath 'h' 2521 delfunction I 2522 endtry 2523 endtry 2524 endtry 2525 endtry 2526 endtry 2527 endtry 2528 endtry 2529 call assert_report('should not get here') 2530 catch /^Vim:Interrupt$/ 2531 Xpath 'A' 2532 endtry 2533 [CODE] 2534 let verify =<< trim [CODE] 2535 call assert_equal('abcdefghA', g:Xpath) 2536 [CODE] 2537 call RunInNewVim(test, verify) 2538endfunc 2539 2540"------------------------------------------------------------------------------- 2541" Test 40: :finally reason discarded by :throw {{{1 2542" 2543" When a :finally clause is executed due to a :continue, :break, 2544" :return, :finish, error, interrupt or :throw, the jump reason is 2545" discarded by a :throw in the finally clause. 2546"------------------------------------------------------------------------------- 2547 2548func Test_finally_discard_by_throw() 2549 let test =<< trim [CODE] 2550 func T(jump) 2551 let loop = 0 2552 while loop < 2 2553 let loop = loop + 1 2554 if loop == 1 2555 try 2556 if a:jump == "continue" 2557 continue 2558 elseif a:jump == "break" 2559 break 2560 elseif a:jump == "return" || a:jump == "finish" 2561 return 2562 elseif a:jump == "error" 2563 asdf 2564 elseif a:jump == "interrupt" 2565 call interrupt() 2566 let dummy = 0 2567 elseif a:jump == "throw" 2568 throw "abc" 2569 endif 2570 finally 2571 throw "xyz" " discards jump that caused the :finally 2572 endtry 2573 elseif loop == 2 2574 call assert_report('should not get here') 2575 endif 2576 endwhile 2577 call assert_report('should not get here') 2578 endfunc 2579 2580 try 2581 Xpath 'a' 2582 call T("continue") 2583 call assert_report('should not get here') 2584 finally 2585 try 2586 Xpath 'b' 2587 call T("break") 2588 call assert_report('should not get here') 2589 finally 2590 try 2591 Xpath 'c' 2592 call T("return") 2593 call assert_report('should not get here') 2594 finally 2595 try 2596 Xpath 'd' 2597 let g:jump = "finish" 2598 ExecAsScript T 2599 call assert_report('should not get here') 2600 finally 2601 unlet g:jump 2602 try 2603 Xpath 'e' 2604 call T("error") 2605 call assert_report('should not get here') 2606 finally 2607 try 2608 Xpath 'f' 2609 call T("interrupt") 2610 call assert_report('should not get here') 2611 finally 2612 try 2613 Xpath 'g' 2614 call T("throw") 2615 call assert_report('should not get here') 2616 finally 2617 Xpath 'h' 2618 delfunction T 2619 endtry 2620 endtry 2621 endtry 2622 endtry 2623 endtry 2624 endtry 2625 endtry 2626 call assert_report('should not get here') 2627 [CODE] 2628 let verify =<< trim [CODE] 2629 call assert_equal('abcdefgh', g:Xpath) 2630 [CODE] 2631 call RunInNewVim(test, verify) 2632endfunc 2633 2634"------------------------------------------------------------------------------- 2635" Test 49: Throwing exceptions across functions {{{1 2636" 2637" When an exception is thrown but not caught inside a function, the 2638" caller is checked for a matching :catch clause. 2639"------------------------------------------------------------------------------- 2640 2641func T49_C() 2642 try 2643 Xpath 'a' 2644 throw "arrgh" 2645 call assert_report('should not get here') 2646 catch /arrgh/ 2647 Xpath 'b' 2648 endtry 2649 Xpath 'c' 2650endfunc 2651 2652func T49_T1() 2653 XloopNEXT 2654 try 2655 Xloop 'd' 2656 throw "arrgh" 2657 call assert_report('should not get here') 2658 finally 2659 Xloop 'e' 2660 endtry 2661 Xloop 'f' 2662endfunc 2663 2664func T49_T2() 2665 try 2666 Xpath 'g' 2667 call T49_T1() 2668 call assert_report('should not get here') 2669 finally 2670 Xpath 'h' 2671 endtry 2672 call assert_report('should not get here') 2673endfunc 2674 2675func Test_throw_exception_across_funcs() 2676 XpathINIT 2677 XloopINIT 2678 try 2679 Xpath 'i' 2680 call T49_C() " throw and catch 2681 Xpath 'j' 2682 catch /.*/ 2683 call assert_report('should not get here') 2684 endtry 2685 2686 try 2687 Xpath 'k' 2688 call T49_T1() " throw, one level 2689 call assert_report('should not get here') 2690 catch /arrgh/ 2691 Xpath 'l' 2692 catch /.*/ 2693 call assert_report('should not get here') 2694 endtry 2695 2696 try 2697 Xpath 'm' 2698 call T49_T2() " throw, two levels 2699 call assert_report('should not get here') 2700 catch /arrgh/ 2701 Xpath 'n' 2702 catch /.*/ 2703 call assert_report('should not get here') 2704 endtry 2705 Xpath 'o' 2706 2707 call assert_equal('iabcjkd2e2lmgd3e3hno', g:Xpath) 2708endfunc 2709 2710"------------------------------------------------------------------------------- 2711" Test 50: Throwing exceptions across script files {{{1 2712" 2713" When an exception is thrown but not caught inside a script file, 2714" the sourcing script or function is checked for a matching :catch 2715" clause. 2716" 2717" This test executes the bodies of the functions C, T1, and T2 from 2718" the previous test as script files (:return replaced by :finish). 2719"------------------------------------------------------------------------------- 2720 2721func T50_F() 2722 try 2723 Xpath 'A' 2724 exec "source" g:scriptC 2725 Xpath 'B' 2726 catch /.*/ 2727 call assert_report('should not get here') 2728 endtry 2729 2730 try 2731 Xpath 'C' 2732 exec "source" g:scriptT1 2733 call assert_report('should not get here') 2734 catch /arrgh/ 2735 Xpath 'D' 2736 catch /.*/ 2737 call assert_report('should not get here') 2738 endtry 2739endfunc 2740 2741func Test_throw_across_script() 2742 XpathINIT 2743 XloopINIT 2744 let g:scriptC = MakeScript("T49_C") 2745 let g:scriptT1 = MakeScript("T49_T1") 2746 let scriptT2 = MakeScript("T49_T2", g:scriptT1) 2747 2748 try 2749 Xpath 'E' 2750 call T50_F() 2751 Xpath 'F' 2752 exec "source" scriptT2 2753 call assert_report('should not get here') 2754 catch /arrgh/ 2755 Xpath 'G' 2756 catch /.*/ 2757 call assert_report('should not get here') 2758 endtry 2759 Xpath 'H' 2760 call assert_equal('EAabcBCd2e2DFgd3e3hGH', g:Xpath) 2761 2762 call delete(g:scriptC) 2763 call delete(g:scriptT1) 2764 call delete(scriptT2) 2765 unlet g:scriptC g:scriptT1 scriptT2 2766endfunc 2767 2768"------------------------------------------------------------------------------- 2769" Test 52: Uncaught exceptions {{{1 2770" 2771" When an exception is thrown but not caught, an error message is 2772" displayed when the script is terminated. In case of an interrupt 2773" or error exception, the normal interrupt or error message(s) are 2774" displayed. 2775"------------------------------------------------------------------------------- 2776 2777func Test_uncaught_exception_1() 2778 CheckEnglish 2779 2780 let test =<< trim [CODE] 2781 Xpath 'a' 2782 throw "arrgh" 2783 call assert_report('should not get here')` 2784 [CODE] 2785 let verify =<< trim [CODE] 2786 call assert_equal('E605: Exception not caught: arrgh', v:errmsg) 2787 call assert_equal('a', g:Xpath) 2788 [CODE] 2789 call RunInNewVim(test, verify) 2790endfunc 2791 2792func Test_uncaught_exception_2() 2793 CheckEnglish 2794 2795 let test =<< trim [CODE] 2796 try 2797 Xpath 'a' 2798 throw "oops" 2799 call assert_report('should not get here')` 2800 catch /arrgh/ 2801 call assert_report('should not get here')` 2802 endtry 2803 call assert_report('should not get here')` 2804 [CODE] 2805 let verify =<< trim [CODE] 2806 call assert_equal('E605: Exception not caught: oops', v:errmsg) 2807 call assert_equal('a', g:Xpath) 2808 [CODE] 2809 call RunInNewVim(test, verify) 2810endfunc 2811 2812func Test_uncaught_exception_3() 2813 CheckEnglish 2814 2815 let test =<< trim [CODE] 2816 func T() 2817 Xpath 'c' 2818 throw "brrr" 2819 call assert_report('should not get here')` 2820 endfunc 2821 2822 try 2823 Xpath 'a' 2824 throw "arrgh" 2825 call assert_report('should not get here')` 2826 catch /.*/ 2827 Xpath 'b' 2828 call T() 2829 call assert_report('should not get here')` 2830 endtry 2831 call assert_report('should not get here')` 2832 [CODE] 2833 let verify =<< trim [CODE] 2834 call assert_equal('E605: Exception not caught: brrr', v:errmsg) 2835 call assert_equal('abc', g:Xpath) 2836 [CODE] 2837 call RunInNewVim(test, verify) 2838endfunc 2839 2840func Test_uncaught_exception_4() 2841 CheckEnglish 2842 2843 let test =<< trim [CODE] 2844 try 2845 Xpath 'a' 2846 throw "arrgh" 2847 call assert_report('should not get here')` 2848 finally 2849 Xpath 'b' 2850 throw "brrr" 2851 call assert_report('should not get here')` 2852 endtry 2853 call assert_report('should not get here')` 2854 [CODE] 2855 let verify =<< trim [CODE] 2856 call assert_equal('E605: Exception not caught: brrr', v:errmsg) 2857 call assert_equal('ab', g:Xpath) 2858 [CODE] 2859 call RunInNewVim(test, verify) 2860endfunc 2861 2862func Test_uncaught_exception_5() 2863 CheckEnglish 2864 2865 " Need to catch and handle interrupt, otherwise the test will wait for the 2866 " user to press <Enter> to continue 2867 let test =<< trim [CODE] 2868 try 2869 try 2870 Xpath 'a' 2871 call interrupt() 2872 call assert_report('should not get here') 2873 endtry 2874 call assert_report('should not get here') 2875 catch /^Vim:Interrupt$/ 2876 Xpath 'b' 2877 endtry 2878 [CODE] 2879 let verify =<< trim [CODE] 2880 call assert_equal('ab', g:Xpath) 2881 [CODE] 2882 call RunInNewVim(test, verify) 2883endfunc 2884 2885func Test_uncaught_exception_6() 2886 CheckEnglish 2887 2888 let test =<< trim [CODE] 2889 try 2890 Xpath 'a' 2891 let x = novar " error E121; exception: E121 2892 catch /E15:/ " should not catch 2893 call assert_report('should not get here') 2894 endtry 2895 call assert_report('should not get here') 2896 [CODE] 2897 let verify =<< trim [CODE] 2898 call assert_equal('a', g:Xpath) 2899 call assert_equal('E121: Undefined variable: novar', v:errmsg) 2900 [CODE] 2901 call RunInNewVim(test, verify) 2902endfunc 2903 2904func Test_uncaught_exception_7() 2905 CheckEnglish 2906 2907 let test =<< trim [CODE] 2908 try 2909 Xpath 'a' 2910 " error E108/E488; exception: E488 2911 unlet novar # 2912 catch /E108:/ " should not catch 2913 call assert_report('should not get here') 2914 endtry 2915 call assert_report('should not get here') 2916 [CODE] 2917 let verify =<< trim [CODE] 2918 call assert_equal('a', g:Xpath) 2919 call assert_equal('E488: Trailing characters: #', v:errmsg) 2920 [CODE] 2921 call RunInNewVim(test, verify) 2922endfunc 2923 2924"------------------------------------------------------------------------------- 2925" Test 53: Nesting errors: :endif/:else/:elseif {{{1 2926" 2927" For nesting errors of :if conditionals the correct error messages 2928" should be given. 2929"------------------------------------------------------------------------------- 2930 2931func Test_nested_if_else_errors() 2932 CheckEnglish 2933 2934 " :endif without :if 2935 let code =<< trim END 2936 endif 2937 END 2938 call writefile(code, 'Xtest') 2939 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if') 2940 2941 " :endif without :if 2942 let code =<< trim END 2943 while 1 2944 endif 2945 endwhile 2946 END 2947 call writefile(code, 'Xtest') 2948 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if') 2949 2950 " :endif without :if 2951 let code =<< trim END 2952 try 2953 finally 2954 endif 2955 endtry 2956 END 2957 call writefile(code, 'Xtest') 2958 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if') 2959 2960 " :endif without :if 2961 let code =<< trim END 2962 try 2963 endif 2964 endtry 2965 END 2966 call writefile(code, 'Xtest') 2967 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if') 2968 2969 " :endif without :if 2970 let code =<< trim END 2971 try 2972 throw "a" 2973 catch /a/ 2974 endif 2975 endtry 2976 END 2977 call writefile(code, 'Xtest') 2978 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if') 2979 2980 " :else without :if 2981 let code =<< trim END 2982 else 2983 END 2984 call writefile(code, 'Xtest') 2985 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if') 2986 2987 " :else without :if 2988 let code =<< trim END 2989 while 1 2990 else 2991 endwhile 2992 END 2993 call writefile(code, 'Xtest') 2994 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if') 2995 2996 " :else without :if 2997 let code =<< trim END 2998 try 2999 finally 3000 else 3001 endtry 3002 END 3003 call writefile(code, 'Xtest') 3004 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if') 3005 3006 " :else without :if 3007 let code =<< trim END 3008 try 3009 else 3010 endtry 3011 END 3012 call writefile(code, 'Xtest') 3013 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if') 3014 3015 " :else without :if 3016 let code =<< trim END 3017 try 3018 throw "a" 3019 catch /a/ 3020 else 3021 endtry 3022 END 3023 call writefile(code, 'Xtest') 3024 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if') 3025 3026 " :elseif without :if 3027 let code =<< trim END 3028 elseif 3029 END 3030 call writefile(code, 'Xtest') 3031 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if') 3032 3033 " :elseif without :if 3034 let code =<< trim END 3035 while 1 3036 elseif 3037 endwhile 3038 END 3039 call writefile(code, 'Xtest') 3040 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if') 3041 3042 " :elseif without :if 3043 let code =<< trim END 3044 try 3045 finally 3046 elseif 3047 endtry 3048 END 3049 call writefile(code, 'Xtest') 3050 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if') 3051 3052 " :elseif without :if 3053 let code =<< trim END 3054 try 3055 elseif 3056 endtry 3057 END 3058 call writefile(code, 'Xtest') 3059 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if') 3060 3061 " :elseif without :if 3062 let code =<< trim END 3063 try 3064 throw "a" 3065 catch /a/ 3066 elseif 3067 endtry 3068 END 3069 call writefile(code, 'Xtest') 3070 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if') 3071 3072 " multiple :else 3073 let code =<< trim END 3074 if 1 3075 else 3076 else 3077 endif 3078 END 3079 call writefile(code, 'Xtest') 3080 call AssertException(['source Xtest'], 'Vim(else):E583: multiple :else') 3081 3082 " :elseif after :else 3083 let code =<< trim END 3084 if 1 3085 else 3086 elseif 1 3087 endif 3088 END 3089 call writefile(code, 'Xtest') 3090 call AssertException(['source Xtest'], 'Vim(elseif):E584: :elseif after :else') 3091 3092 call delete('Xtest') 3093endfunc 3094 3095"------------------------------------------------------------------------------- 3096" Test 54: Nesting errors: :while/:endwhile {{{1 3097" 3098" For nesting errors of :while conditionals the correct error messages 3099" should be given. 3100" 3101" This test reuses the function MESSAGES() from the previous test. 3102" This functions checks the messages in g:msgfile. 3103"------------------------------------------------------------------------------- 3104 3105func Test_nested_while_error() 3106 CheckEnglish 3107 3108 " :endwhile without :while 3109 let code =<< trim END 3110 endwhile 3111 END 3112 call writefile(code, 'Xtest') 3113 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3114 3115 " :endwhile without :while 3116 let code =<< trim END 3117 if 1 3118 endwhile 3119 endif 3120 END 3121 call writefile(code, 'Xtest') 3122 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3123 3124 " Missing :endif 3125 let code =<< trim END 3126 while 1 3127 if 1 3128 endwhile 3129 END 3130 call writefile(code, 'Xtest') 3131 call AssertException(['source Xtest'], 'Vim(endwhile):E171: Missing :endif') 3132 3133 " :endwhile without :while 3134 let code =<< trim END 3135 try 3136 finally 3137 endwhile 3138 endtry 3139 END 3140 call writefile(code, 'Xtest') 3141 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3142 3143 " Missing :endtry 3144 let code =<< trim END 3145 while 1 3146 try 3147 finally 3148 endwhile 3149 END 3150 call writefile(code, 'Xtest') 3151 call AssertException(['source Xtest'], 'Vim(endwhile):E600: Missing :endtry') 3152 3153 " Missing :endtry 3154 let code =<< trim END 3155 while 1 3156 if 1 3157 try 3158 finally 3159 endwhile 3160 END 3161 call writefile(code, 'Xtest') 3162 call AssertException(['source Xtest'], 'Vim(endwhile):E600: Missing :endtry') 3163 3164 " Missing :endif 3165 let code =<< trim END 3166 while 1 3167 try 3168 finally 3169 if 1 3170 endwhile 3171 END 3172 call writefile(code, 'Xtest') 3173 call AssertException(['source Xtest'], 'Vim(endwhile):E171: Missing :endif') 3174 3175 " :endwhile without :while 3176 let code =<< trim END 3177 try 3178 endwhile 3179 endtry 3180 END 3181 call writefile(code, 'Xtest') 3182 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3183 3184 " :endwhile without :while 3185 let code =<< trim END 3186 while 1 3187 try 3188 endwhile 3189 endtry 3190 endwhile 3191 END 3192 call writefile(code, 'Xtest') 3193 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3194 3195 " :endwhile without :while 3196 let code =<< trim END 3197 try 3198 throw "a" 3199 catch /a/ 3200 endwhile 3201 endtry 3202 END 3203 call writefile(code, 'Xtest') 3204 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3205 3206 " :endwhile without :while 3207 let code =<< trim END 3208 while 1 3209 try 3210 throw "a" 3211 catch /a/ 3212 endwhile 3213 endtry 3214 endwhile 3215 END 3216 call writefile(code, 'Xtest') 3217 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3218 3219 call delete('Xtest') 3220endfunc 3221 3222"------------------------------------------------------------------------------- 3223" Test 55: Nesting errors: :continue/:break {{{1 3224" 3225" For nesting errors of :continue and :break commands the correct 3226" error messages should be given. 3227" 3228" This test reuses the function MESSAGES() from the previous test. 3229" This functions checks the messages in g:msgfile. 3230"------------------------------------------------------------------------------- 3231 3232func Test_nested_cont_break_error() 3233 CheckEnglish 3234 3235 " :continue without :while 3236 let code =<< trim END 3237 continue 3238 END 3239 call writefile(code, 'Xtest') 3240 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for') 3241 3242 " :continue without :while 3243 let code =<< trim END 3244 if 1 3245 continue 3246 endif 3247 END 3248 call writefile(code, 'Xtest') 3249 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for') 3250 3251 " :continue without :while 3252 let code =<< trim END 3253 try 3254 finally 3255 continue 3256 endtry 3257 END 3258 call writefile(code, 'Xtest') 3259 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for') 3260 3261 " :continue without :while 3262 let code =<< trim END 3263 try 3264 continue 3265 endtry 3266 END 3267 call writefile(code, 'Xtest') 3268 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for') 3269 3270 " :continue without :while 3271 let code =<< trim END 3272 try 3273 throw "a" 3274 catch /a/ 3275 continue 3276 endtry 3277 END 3278 call writefile(code, 'Xtest') 3279 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for') 3280 3281 " :break without :while 3282 let code =<< trim END 3283 break 3284 END 3285 call writefile(code, 'Xtest') 3286 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for') 3287 3288 " :break without :while 3289 let code =<< trim END 3290 if 1 3291 break 3292 endif 3293 END 3294 call writefile(code, 'Xtest') 3295 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for') 3296 3297 " :break without :while 3298 let code =<< trim END 3299 try 3300 finally 3301 break 3302 endtry 3303 END 3304 call writefile(code, 'Xtest') 3305 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for') 3306 3307 " :break without :while 3308 let code =<< trim END 3309 try 3310 break 3311 endtry 3312 END 3313 call writefile(code, 'Xtest') 3314 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for') 3315 3316 " :break without :while 3317 let code =<< trim END 3318 try 3319 throw "a" 3320 catch /a/ 3321 break 3322 endtry 3323 END 3324 call writefile(code, 'Xtest') 3325 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for') 3326 3327 call delete('Xtest') 3328endfunc 3329 3330"------------------------------------------------------------------------------- 3331" Test 56: Nesting errors: :endtry {{{1 3332" 3333" For nesting errors of :try conditionals the correct error messages 3334" should be given. 3335" 3336" This test reuses the function MESSAGES() from the previous test. 3337" This functions checks the messages in g:msgfile. 3338"------------------------------------------------------------------------------- 3339 3340func Test_nested_endtry_error() 3341 CheckEnglish 3342 3343 " :endtry without :try 3344 let code =<< trim END 3345 endtry 3346 END 3347 call writefile(code, 'Xtest') 3348 call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try') 3349 3350 " :endtry without :try 3351 let code =<< trim END 3352 if 1 3353 endtry 3354 endif 3355 END 3356 call writefile(code, 'Xtest') 3357 call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try') 3358 3359 " :endtry without :try 3360 let code =<< trim END 3361 while 1 3362 endtry 3363 endwhile 3364 END 3365 call writefile(code, 'Xtest') 3366 call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try') 3367 3368 " Missing :endif 3369 let code =<< trim END 3370 try 3371 if 1 3372 endtry 3373 END 3374 call writefile(code, 'Xtest') 3375 call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif') 3376 3377 " Missing :endwhile 3378 let code =<< trim END 3379 try 3380 while 1 3381 endtry 3382 END 3383 call writefile(code, 'Xtest') 3384 call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile') 3385 3386 " Missing :endif 3387 let code =<< trim END 3388 try 3389 finally 3390 if 1 3391 endtry 3392 END 3393 call writefile(code, 'Xtest') 3394 call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif') 3395 3396 " Missing :endwhile 3397 let code =<< trim END 3398 try 3399 finally 3400 while 1 3401 endtry 3402 END 3403 call writefile(code, 'Xtest') 3404 call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile') 3405 3406 " Missing :endif 3407 let code =<< trim END 3408 try 3409 throw "a" 3410 catch /a/ 3411 if 1 3412 endtry 3413 END 3414 call writefile(code, 'Xtest') 3415 call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif') 3416 3417 " Missing :endwhile 3418 let code =<< trim END 3419 try 3420 throw "a" 3421 catch /a/ 3422 while 1 3423 endtry 3424 END 3425 call writefile(code, 'Xtest') 3426 call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile') 3427 3428 call delete('Xtest') 3429endfunc 3430 3431"------------------------------------------------------------------------------- 3432" Test 57: v:exception and v:throwpoint for user exceptions {{{1 3433" 3434" v:exception evaluates to the value of the exception that was caught 3435" most recently and is not finished. (A caught exception is finished 3436" when the next ":catch", ":finally", or ":endtry" is reached.) 3437" v:throwpoint evaluates to the script/function name and line number 3438" where that exception has been thrown. 3439"------------------------------------------------------------------------------- 3440 3441func Test_user_exception_info() 3442 CheckEnglish 3443 3444 XpathINIT 3445 XloopINIT 3446 3447 func FuncException() 3448 let g:exception = v:exception 3449 endfunc 3450 3451 func FuncThrowpoint() 3452 let g:throwpoint = v:throwpoint 3453 endfunc 3454 3455 let scriptException = MakeScript("FuncException") 3456 let scriptThrowPoint = MakeScript("FuncThrowpoint") 3457 3458 command! CmdException let g:exception = v:exception 3459 command! CmdThrowpoint let g:throwpoint = v:throwpoint 3460 3461 func T(arg, line) 3462 if a:line == 2 3463 throw a:arg " in line 2 3464 elseif a:line == 4 3465 throw a:arg " in line 4 3466 elseif a:line == 6 3467 throw a:arg " in line 6 3468 elseif a:line == 8 3469 throw a:arg " in line 8 3470 endif 3471 endfunc 3472 3473 func G(arg, line) 3474 call T(a:arg, a:line) 3475 endfunc 3476 3477 func F(arg, line) 3478 call G(a:arg, a:line) 3479 endfunc 3480 3481 let scriptT = MakeScript("T") 3482 let scriptG = MakeScript("G", scriptT) 3483 let scriptF = MakeScript("F", scriptG) 3484 3485 try 3486 Xpath 'a' 3487 call F("oops", 2) 3488 catch /.*/ 3489 Xpath 'b' 3490 let exception = v:exception 3491 let throwpoint = v:throwpoint 3492 call assert_equal("oops", v:exception) 3493 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3494 call assert_match('\<2\>', v:throwpoint) 3495 3496 exec "let exception = v:exception" 3497 exec "let throwpoint = v:throwpoint" 3498 call assert_equal("oops", v:exception) 3499 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3500 call assert_match('\<2\>', v:throwpoint) 3501 3502 CmdException 3503 CmdThrowpoint 3504 call assert_equal("oops", v:exception) 3505 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3506 call assert_match('\<2\>', v:throwpoint) 3507 3508 call FuncException() 3509 call FuncThrowpoint() 3510 call assert_equal("oops", v:exception) 3511 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3512 call assert_match('\<2\>', v:throwpoint) 3513 3514 exec "source" scriptException 3515 exec "source" scriptThrowPoint 3516 call assert_equal("oops", v:exception) 3517 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3518 call assert_match('\<2\>', v:throwpoint) 3519 3520 try 3521 Xpath 'c' 3522 call G("arrgh", 4) 3523 catch /.*/ 3524 Xpath 'd' 3525 let exception = v:exception 3526 let throwpoint = v:throwpoint 3527 call assert_equal("arrgh", v:exception) 3528 call assert_match('\<G\[1]\.\.T\>', v:throwpoint) 3529 call assert_match('\<4\>', v:throwpoint) 3530 3531 try 3532 Xpath 'e' 3533 let g:arg = "autsch" 3534 let g:line = 6 3535 exec "source" scriptF 3536 catch /.*/ 3537 Xpath 'f' 3538 let exception = v:exception 3539 let throwpoint = v:throwpoint 3540 call assert_equal("autsch", v:exception) 3541 call assert_match(fnamemodify(scriptT, ':t'), v:throwpoint) 3542 call assert_match('\<6\>', v:throwpoint) 3543 finally 3544 Xpath 'g' 3545 let exception = v:exception 3546 let throwpoint = v:throwpoint 3547 call assert_equal("arrgh", v:exception) 3548 call assert_match('\<G\[1]\.\.T\>', v:throwpoint) 3549 call assert_match('\<4\>', v:throwpoint) 3550 try 3551 Xpath 'h' 3552 let g:arg = "brrrr" 3553 let g:line = 8 3554 exec "source" scriptG 3555 catch /.*/ 3556 Xpath 'i' 3557 let exception = v:exception 3558 let throwpoint = v:throwpoint 3559 " Resolve scriptT for matching it against v:throwpoint. 3560 call assert_equal("brrrr", v:exception) 3561 call assert_match(fnamemodify(scriptT, ':t'), v:throwpoint) 3562 call assert_match('\<8\>', v:throwpoint) 3563 finally 3564 Xpath 'j' 3565 let exception = v:exception 3566 let throwpoint = v:throwpoint 3567 call assert_equal("arrgh", v:exception) 3568 call assert_match('\<G\[1]\.\.T\>', v:throwpoint) 3569 call assert_match('\<4\>', v:throwpoint) 3570 endtry 3571 Xpath 'k' 3572 let exception = v:exception 3573 let throwpoint = v:throwpoint 3574 call assert_equal("arrgh", v:exception) 3575 call assert_match('\<G\[1]\.\.T\>', v:throwpoint) 3576 call assert_match('\<4\>', v:throwpoint) 3577 endtry 3578 Xpath 'l' 3579 let exception = v:exception 3580 let throwpoint = v:throwpoint 3581 call assert_equal("arrgh", v:exception) 3582 call assert_match('\<G\[1]\.\.T\>', v:throwpoint) 3583 call assert_match('\<4\>', v:throwpoint) 3584 finally 3585 Xpath 'm' 3586 let exception = v:exception 3587 let throwpoint = v:throwpoint 3588 call assert_equal("oops", v:exception) 3589 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3590 call assert_match('\<2\>', v:throwpoint) 3591 endtry 3592 Xpath 'n' 3593 let exception = v:exception 3594 let throwpoint = v:throwpoint 3595 call assert_equal("oops", v:exception) 3596 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3597 call assert_match('\<2\>', v:throwpoint) 3598 finally 3599 Xpath 'o' 3600 let exception = v:exception 3601 let throwpoint = v:throwpoint 3602 call assert_equal("", v:exception) 3603 call assert_match('^$', v:throwpoint) 3604 call assert_match('^$', v:throwpoint) 3605 endtry 3606 3607 call assert_equal('abcdefghijklmno', g:Xpath) 3608 3609 unlet exception throwpoint 3610 delfunction FuncException 3611 delfunction FuncThrowpoint 3612 call delete(scriptException) 3613 call delete(scriptThrowPoint) 3614 unlet scriptException scriptThrowPoint 3615 delcommand CmdException 3616 delcommand CmdThrowpoint 3617 delfunction T 3618 delfunction G 3619 delfunction F 3620 call delete(scriptT) 3621 call delete(scriptG) 3622 call delete(scriptF) 3623 unlet scriptT scriptG scriptF 3624endfunc 3625 3626"------------------------------------------------------------------------------- 3627" 3628" Test 58: v:exception and v:throwpoint for error/interrupt exceptions {{{1 3629" 3630" v:exception and v:throwpoint work also for error and interrupt 3631" exceptions. 3632"------------------------------------------------------------------------------- 3633 3634func Test_execption_info_for_error() 3635 CheckEnglish 3636 3637 let test =<< trim [CODE] 3638 func T(line) 3639 if a:line == 2 3640 delfunction T " error (function in use) in line 2 3641 elseif a:line == 4 3642 call interrupt() 3643 endif 3644 endfunc 3645 3646 while 1 3647 try 3648 Xpath 'a' 3649 call T(2) 3650 call assert_report('should not get here') 3651 catch /.*/ 3652 Xpath 'b' 3653 if v:exception !~ 'Vim(delfunction):' 3654 call assert_report('should not get here') 3655 endif 3656 if v:throwpoint !~ '\<T\>' 3657 call assert_report('should not get here') 3658 endif 3659 if v:throwpoint !~ '\<2\>' 3660 call assert_report('should not get here') 3661 endif 3662 finally 3663 Xpath 'c' 3664 if v:exception != "" 3665 call assert_report('should not get here') 3666 endif 3667 if v:throwpoint != "" 3668 call assert_report('should not get here') 3669 endif 3670 break 3671 endtry 3672 endwhile 3673 3674 Xpath 'd' 3675 if v:exception != "" 3676 call assert_report('should not get here') 3677 endif 3678 if v:throwpoint != "" 3679 call assert_report('should not get here') 3680 endif 3681 3682 while 1 3683 try 3684 Xpath 'e' 3685 call T(4) 3686 call assert_report('should not get here') 3687 catch /.*/ 3688 Xpath 'f' 3689 if v:exception != 'Vim:Interrupt' 3690 call assert_report('should not get here') 3691 endif 3692 if v:throwpoint !~ 'function T' 3693 call assert_report('should not get here') 3694 endif 3695 if v:throwpoint !~ '\<4\>' 3696 call assert_report('should not get here') 3697 endif 3698 finally 3699 Xpath 'g' 3700 if v:exception != "" 3701 call assert_report('should not get here') 3702 endif 3703 if v:throwpoint != "" 3704 call assert_report('should not get here') 3705 endif 3706 break 3707 endtry 3708 endwhile 3709 3710 Xpath 'h' 3711 if v:exception != "" 3712 call assert_report('should not get here') 3713 endif 3714 if v:throwpoint != "" 3715 call assert_report('should not get here') 3716 endif 3717 [CODE] 3718 let verify =<< trim [CODE] 3719 call assert_equal('abcdefgh', g:Xpath) 3720 [CODE] 3721 call RunInNewVim(test, verify) 3722endfunc 3723 3724"------------------------------------------------------------------------------- 3725" 3726" Test 59: v:exception and v:throwpoint when discarding exceptions {{{1 3727" 3728" When a :catch clause is left by a ":break" etc or an error or 3729" interrupt exception, v:exception and v:throwpoint are reset. They 3730" are not affected by an exception that is discarded before being 3731" caught. 3732"------------------------------------------------------------------------------- 3733func Test_exception_info_on_discard() 3734 CheckEnglish 3735 3736 let test =<< trim [CODE] 3737 let sfile = expand("<sfile>") 3738 3739 while 1 3740 try 3741 throw "x1" 3742 catch /.*/ 3743 break 3744 endtry 3745 endwhile 3746 call assert_equal('', v:exception) 3747 call assert_equal('', v:throwpoint) 3748 3749 while 1 3750 try 3751 throw "x2" 3752 catch /.*/ 3753 break 3754 finally 3755 call assert_equal('', v:exception) 3756 call assert_equal('', v:throwpoint) 3757 endtry 3758 break 3759 endwhile 3760 call assert_equal('', v:exception) 3761 call assert_equal('', v:throwpoint) 3762 3763 while 1 3764 try 3765 let errcaught = 0 3766 try 3767 try 3768 throw "x3" 3769 catch /.*/ 3770 let lnum = expand("<sflnum>") 3771 asdf 3772 endtry 3773 catch /.*/ 3774 let errcaught = 1 3775 call assert_match('Vim:E492: Not an editor command:', v:exception) 3776 call assert_match('line ' .. (lnum + 1), v:throwpoint) 3777 endtry 3778 finally 3779 call assert_equal(1, errcaught) 3780 break 3781 endtry 3782 endwhile 3783 call assert_equal('', v:exception) 3784 call assert_equal('', v:throwpoint) 3785 3786 Xpath 'a' 3787 3788 while 1 3789 try 3790 let intcaught = 0 3791 try 3792 try 3793 throw "x4" 3794 catch /.*/ 3795 let lnum = expand("<sflnum>") 3796 call interrupt() 3797 endtry 3798 catch /.*/ 3799 let intcaught = 1 3800 call assert_match('Vim:Interrupt', v:exception) 3801 call assert_match('line ' .. (lnum + 1), v:throwpoint) 3802 endtry 3803 finally 3804 call assert_equal(1, intcaught) 3805 break 3806 endtry 3807 endwhile 3808 call assert_equal('', v:exception) 3809 call assert_equal('', v:throwpoint) 3810 3811 Xpath 'b' 3812 3813 while 1 3814 try 3815 let errcaught = 0 3816 try 3817 try 3818 if 1 3819 let lnum = expand("<sflnum>") 3820 throw "x5" 3821 " missing endif 3822 catch /.*/ 3823 call assert_report('should not get here') 3824 endtry 3825 catch /.*/ 3826 let errcaught = 1 3827 call assert_match('Vim(catch):E171: Missing :endif:', v:exception) 3828 call assert_match('line ' .. (lnum + 3), v:throwpoint) 3829 endtry 3830 finally 3831 call assert_equal(1, errcaught) 3832 break 3833 endtry 3834 endwhile 3835 call assert_equal('', v:exception) 3836 call assert_equal('', v:throwpoint) 3837 3838 Xpath 'c' 3839 3840 try 3841 while 1 3842 try 3843 throw "x6" 3844 finally 3845 break 3846 endtry 3847 break 3848 endwhile 3849 catch /.*/ 3850 call assert_report('should not get here') 3851 endtry 3852 call assert_equal('', v:exception) 3853 call assert_equal('', v:throwpoint) 3854 3855 try 3856 while 1 3857 try 3858 throw "x7" 3859 finally 3860 break 3861 endtry 3862 break 3863 endwhile 3864 catch /.*/ 3865 call assert_report('should not get here') 3866 finally 3867 call assert_equal('', v:exception) 3868 call assert_equal('', v:throwpoint) 3869 endtry 3870 call assert_equal('', v:exception) 3871 call assert_equal('', v:throwpoint) 3872 3873 while 1 3874 try 3875 let errcaught = 0 3876 try 3877 try 3878 throw "x8" 3879 finally 3880 let lnum = expand("<sflnum>") 3881 asdf 3882 endtry 3883 catch /.*/ 3884 let errcaught = 1 3885 call assert_match('Vim:E492: Not an editor command:', v:exception) 3886 call assert_match('line ' .. (lnum + 1), v:throwpoint) 3887 endtry 3888 finally 3889 call assert_equal(1, errcaught) 3890 break 3891 endtry 3892 endwhile 3893 call assert_equal('', v:exception) 3894 call assert_equal('', v:throwpoint) 3895 3896 Xpath 'd' 3897 3898 while 1 3899 try 3900 let intcaught = 0 3901 try 3902 try 3903 throw "x9" 3904 finally 3905 let lnum = expand("<sflnum>") 3906 call interrupt() 3907 endtry 3908 catch /.*/ 3909 let intcaught = 1 3910 call assert_match('Vim:Interrupt', v:exception) 3911 call assert_match('line ' .. (lnum + 1), v:throwpoint) 3912 endtry 3913 finally 3914 call assert_equal(1, intcaught) 3915 break 3916 endtry 3917 endwhile 3918 call assert_equal('', v:exception) 3919 call assert_equal('', v:throwpoint) 3920 3921 Xpath 'e' 3922 3923 while 1 3924 try 3925 let errcaught = 0 3926 try 3927 try 3928 if 1 3929 let lnum = expand("<sflnum>") 3930 throw "x10" 3931 " missing endif 3932 finally 3933 call assert_equal('', v:exception) 3934 call assert_equal('', v:throwpoint) 3935 endtry 3936 catch /.*/ 3937 let errcaught = 1 3938 call assert_match('Vim(finally):E171: Missing :endif:', v:exception) 3939 call assert_match('line ' .. (lnum + 3), v:throwpoint) 3940 endtry 3941 finally 3942 call assert_equal(1, errcaught) 3943 break 3944 endtry 3945 endwhile 3946 call assert_equal('', v:exception) 3947 call assert_equal('', v:throwpoint) 3948 3949 Xpath 'f' 3950 3951 while 1 3952 try 3953 let errcaught = 0 3954 try 3955 try 3956 if 1 3957 let lnum = expand("<sflnum>") 3958 throw "x11" 3959 " missing endif 3960 endtry 3961 catch /.*/ 3962 let errcaught = 1 3963 call assert_match('Vim(endtry):E171: Missing :endif:', v:exception) 3964 call assert_match('line ' .. (lnum + 3), v:throwpoint) 3965 endtry 3966 finally 3967 call assert_equal(1, errcaught) 3968 break 3969 endtry 3970 endwhile 3971 call assert_equal('', v:exception) 3972 call assert_equal('', v:throwpoint) 3973 3974 Xpath 'g' 3975 [CODE] 3976 let verify =<< trim [CODE] 3977 call assert_equal('abcdefg', g:Xpath) 3978 [CODE] 3979 call RunInNewVim(test, verify) 3980endfunc 3981 3982"------------------------------------------------------------------------------- 3983" 3984" Test 60: (Re)throwing v:exception; :echoerr. {{{1 3985" 3986" A user exception can be rethrown after catching by throwing 3987" v:exception. An error or interrupt exception cannot be rethrown 3988" because Vim exceptions cannot be faked. A Vim exception using the 3989" value of v:exception can, however, be triggered by the :echoerr 3990" command. 3991"------------------------------------------------------------------------------- 3992 3993func Test_rethrow_exception_1() 3994 XpathINIT 3995 try 3996 try 3997 Xpath 'a' 3998 throw "oops" 3999 catch /oops/ 4000 Xpath 'b' 4001 throw v:exception " rethrow user exception 4002 catch /.*/ 4003 call assert_report('should not get here') 4004 endtry 4005 catch /^oops$/ " catches rethrown user exception 4006 Xpath 'c' 4007 catch /.*/ 4008 call assert_report('should not get here') 4009 endtry 4010 call assert_equal('abc', g:Xpath) 4011endfunc 4012 4013func Test_rethrow_exception_2() 4014 XpathINIT 4015 try 4016 let caught = 0 4017 try 4018 Xpath 'a' 4019 write /n/o/n/w/r/i/t/a/b/l/e/_/f/i/l/e 4020 call assert_report('should not get here') 4021 catch /^Vim(write):/ 4022 let caught = 1 4023 throw v:exception " throw error: cannot fake Vim exception 4024 catch /.*/ 4025 call assert_report('should not get here') 4026 finally 4027 Xpath 'b' 4028 call assert_equal(1, caught) 4029 endtry 4030 catch /^Vim(throw):/ " catches throw error 4031 let caught = caught + 1 4032 catch /.*/ 4033 call assert_report('should not get here') 4034 finally 4035 Xpath 'c' 4036 call assert_equal(2, caught) 4037 endtry 4038 call assert_equal('abc', g:Xpath) 4039endfunc 4040 4041func Test_rethrow_exception_3() 4042 XpathINIT 4043 try 4044 let caught = 0 4045 try 4046 Xpath 'a' 4047 asdf 4048 catch /^Vim/ " catch error exception 4049 let caught = 1 4050 " Trigger Vim error exception with value specified after :echoerr 4051 let value = substitute(v:exception, '^Vim\((.*)\)\=:', '', "") 4052 echoerr value 4053 catch /.*/ 4054 call assert_report('should not get here') 4055 finally 4056 Xpath 'b' 4057 call assert_equal(1, caught) 4058 endtry 4059 catch /^Vim(echoerr):/ 4060 let caught = caught + 1 4061 call assert_match(value, v:exception) 4062 catch /.*/ 4063 call assert_report('should not get here') 4064 finally 4065 Xpath 'c' 4066 call assert_equal(2, caught) 4067 endtry 4068 call assert_equal('abc', g:Xpath) 4069endfunc 4070 4071func Test_rethrow_exception_3() 4072 XpathINIT 4073 try 4074 let errcaught = 0 4075 try 4076 Xpath 'a' 4077 let intcaught = 0 4078 call interrupt() 4079 catch /^Vim:/ " catch interrupt exception 4080 let intcaught = 1 4081 " Trigger Vim error exception with value specified after :echoerr 4082 echoerr substitute(v:exception, '^Vim\((.*)\)\=:', '', "") 4083 catch /.*/ 4084 call assert_report('should not get here') 4085 finally 4086 Xpath 'b' 4087 call assert_equal(1, intcaught) 4088 endtry 4089 catch /^Vim(echoerr):/ 4090 let errcaught = 1 4091 call assert_match('Interrupt', v:exception) 4092 finally 4093 Xpath 'c' 4094 call assert_equal(1, errcaught) 4095 endtry 4096 call assert_equal('abc', g:Xpath) 4097endfunc 4098 4099"------------------------------------------------------------------------------- 4100" Test 61: Catching interrupt exceptions {{{1 4101" 4102" When an interrupt occurs inside a :try/:endtry region, an 4103" interrupt exception is thrown and can be caught. Its value is 4104" "Vim:Interrupt". If the interrupt occurs after an error or a :throw 4105" but before a matching :catch is reached, all following :catches of 4106" that try block are ignored, but the interrupt exception can be 4107" caught by the next surrounding try conditional. An interrupt is 4108" ignored when there is a previous interrupt that has not been caught 4109" or causes a :finally clause to be executed. 4110"------------------------------------------------------------------------------- 4111 4112func Test_catch_intr_exception() 4113 let test =<< trim [CODE] 4114 while 1 4115 try 4116 try 4117 Xpath 'a' 4118 call interrupt() 4119 call assert_report('should not get here') 4120 catch /^Vim:Interrupt$/ 4121 Xpath 'b' 4122 finally 4123 Xpath 'c' 4124 endtry 4125 catch /.*/ 4126 call assert_report('should not get here') 4127 finally 4128 Xpath 'd' 4129 break 4130 endtry 4131 endwhile 4132 4133 while 1 4134 try 4135 try 4136 try 4137 Xpath 'e' 4138 asdf 4139 call assert_report('should not get here') 4140 catch /do_not_catch/ 4141 call assert_report('should not get here') 4142 catch /.*/ 4143 Xpath 'f' 4144 call interrupt() 4145 call assert_report('should not get here') 4146 catch /.*/ 4147 call assert_report('should not get here') 4148 finally 4149 Xpath 'g' 4150 call interrupt() 4151 call assert_report('should not get here') 4152 endtry 4153 catch /^Vim:Interrupt$/ 4154 Xpath 'h' 4155 finally 4156 Xpath 'i' 4157 endtry 4158 catch /.*/ 4159 call assert_report('should not get here') 4160 finally 4161 Xpath 'j' 4162 break 4163 endtry 4164 endwhile 4165 4166 while 1 4167 try 4168 try 4169 try 4170 Xpath 'k' 4171 throw "x" 4172 call assert_report('should not get here') 4173 catch /do_not_catch/ 4174 call assert_report('should not get here') 4175 catch /x/ 4176 Xpath 'l' 4177 call interrupt() 4178 call assert_report('should not get here') 4179 catch /.*/ 4180 call assert_report('should not get here') 4181 endtry 4182 catch /^Vim:Interrupt$/ 4183 Xpath 'm' 4184 finally 4185 Xpath 'n' 4186 endtry 4187 catch /.*/ 4188 call assert_report('should not get here') 4189 finally 4190 Xpath 'o' 4191 break 4192 endtry 4193 endwhile 4194 4195 while 1 4196 try 4197 try 4198 Xpath 'p' 4199 call interrupt() 4200 call assert_report('should not get here') 4201 catch /do_not_catch/ 4202 call interrupt() 4203 call assert_report('should not get here') 4204 catch /^Vim:Interrupt$/ 4205 Xpath 'q' 4206 finally 4207 Xpath 'r' 4208 endtry 4209 catch /.*/ 4210 call assert_report('should not get here') 4211 finally 4212 Xpath 's' 4213 break 4214 endtry 4215 endwhile 4216 4217 Xpath 't' 4218 [CODE] 4219 let verify =<< trim [CODE] 4220 call assert_equal('abcdefghijklmnopqrst', g:Xpath) 4221 [CODE] 4222 call RunInNewVim(test, verify) 4223endfunc 4224 4225"------------------------------------------------------------------------------- 4226" Test 62: Catching error exceptions {{{1 4227" 4228" An error inside a :try/:endtry region is converted to an exception 4229" and can be caught. The error exception has a "Vim(cmdname):" prefix 4230" where cmdname is the name of the failing command, or a "Vim:" prefix 4231" if no command name is known. The "Vim" prefixes cannot be faked. 4232"------------------------------------------------------------------------------- 4233 4234func Test_catch_err_exception_1() 4235 XpathINIT 4236 while 1 4237 try 4238 try 4239 let caught = 0 4240 unlet novar 4241 catch /^Vim(unlet):/ 4242 Xpath 'a' 4243 let caught = 1 4244 let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "") 4245 finally 4246 Xpath 'b' 4247 call assert_equal(1, caught) 4248 call assert_match('E108: No such variable: "novar"', v:errmsg) 4249 endtry 4250 catch /.*/ 4251 call assert_report('should not get here') 4252 finally 4253 Xpath 'c' 4254 break 4255 endtry 4256 call assert_report('should not get here') 4257 endwhile 4258 call assert_equal('abc', g:Xpath) 4259endfunc 4260 4261func Test_catch_err_exception_2() 4262 XpathINIT 4263 while 1 4264 try 4265 try 4266 let caught = 0 4267 throw novar " error in :throw 4268 catch /^Vim(throw):/ 4269 Xpath 'a' 4270 let caught = 1 4271 let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "") 4272 finally 4273 Xpath 'b' 4274 call assert_equal(1, caught) 4275 call assert_match('E121: Undefined variable: novar', v:errmsg) 4276 endtry 4277 catch /.*/ 4278 call assert_report('should not get here') 4279 finally 4280 Xpath 'c' 4281 break 4282 endtry 4283 call assert_report('should not get here') 4284 endwhile 4285 call assert_equal('abc', g:Xpath) 4286endfunc 4287 4288func Test_catch_err_exception_3() 4289 XpathINIT 4290 while 1 4291 try 4292 try 4293 let caught = 0 4294 throw "Vim:faked" " error: cannot fake Vim exception 4295 catch /^Vim(throw):/ 4296 Xpath 'a' 4297 let caught = 1 4298 let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "") 4299 finally 4300 Xpath 'b' 4301 call assert_equal(1, caught) 4302 call assert_match("E608: Cannot :throw exceptions with 'Vim' prefix", 4303 \ v:errmsg) 4304 endtry 4305 catch /.*/ 4306 call assert_report('should not get here') 4307 finally 4308 Xpath 'c' 4309 break 4310 endtry 4311 call assert_report('should not get here') 4312 endwhile 4313 call assert_equal('abc', g:Xpath) 4314endfunc 4315 4316func Test_catch_err_exception_4() 4317 XpathINIT 4318 func F() 4319 while 1 4320 " Missing :endwhile 4321 endfunc 4322 4323 while 1 4324 try 4325 try 4326 let caught = 0 4327 call F() 4328 catch /^Vim(endfunction):/ 4329 Xpath 'a' 4330 let caught = 1 4331 let v:errmsg = substitute(v:exception, '^Vim(endfunction):', '', "") 4332 finally 4333 Xpath 'b' 4334 call assert_equal(1, caught) 4335 call assert_match("E170: Missing :endwhile", v:errmsg) 4336 endtry 4337 catch /.*/ 4338 call assert_report('should not get here') 4339 finally 4340 Xpath 'c' 4341 break 4342 endtry 4343 call assert_report('should not get here') 4344 endwhile 4345 call assert_equal('abc', g:Xpath) 4346 delfunc F 4347endfunc 4348 4349func Test_catch_err_exception_5() 4350 XpathINIT 4351 func F() 4352 while 1 4353 " Missing :endwhile 4354 endfunc 4355 4356 while 1 4357 try 4358 try 4359 let caught = 0 4360 ExecAsScript F 4361 catch /^Vim:/ 4362 Xpath 'a' 4363 let caught = 1 4364 let v:errmsg = substitute(v:exception, '^Vim:', '', "") 4365 finally 4366 Xpath 'b' 4367 call assert_equal(1, caught) 4368 call assert_match("E170: Missing :endwhile", v:errmsg) 4369 endtry 4370 catch /.*/ 4371 call assert_report('should not get here') 4372 finally 4373 Xpath 'c' 4374 break 4375 endtry 4376 call assert_report('should not get here') 4377 endwhile 4378 call assert_equal('abc', g:Xpath) 4379 delfunc F 4380endfunc 4381 4382func Test_catch_err_exception_6() 4383 XpathINIT 4384 func G() 4385 call G() 4386 endfunc 4387 4388 while 1 4389 try 4390 let mfd_save = &mfd 4391 set mfd=3 4392 try 4393 let caught = 0 4394 call G() 4395 catch /^Vim(call):/ 4396 Xpath 'a' 4397 let caught = 1 4398 let v:errmsg = substitute(v:exception, '^Vim(call):', '', "") 4399 finally 4400 Xpath 'b' 4401 call assert_equal(1, caught) 4402 call assert_match("E132: Function call depth is higher than 'maxfuncdepth'", v:errmsg) 4403 endtry 4404 catch /.*/ 4405 call assert_report('should not get here') 4406 finally 4407 Xpath 'c' 4408 let &mfd = mfd_save 4409 break 4410 endtry 4411 call assert_report('should not get here') 4412 endwhile 4413 call assert_equal('abc', g:Xpath) 4414 delfunc G 4415endfunc 4416 4417func Test_catch_err_exception_7() 4418 XpathINIT 4419 func H() 4420 return H() 4421 endfunc 4422 4423 while 1 4424 try 4425 let mfd_save = &mfd 4426 set mfd=3 4427 try 4428 let caught = 0 4429 call H() 4430 catch /^Vim(return):/ 4431 Xpath 'a' 4432 let caught = 1 4433 let v:errmsg = substitute(v:exception, '^Vim(return):', '', "") 4434 finally 4435 Xpath 'b' 4436 call assert_equal(1, caught) 4437 call assert_match("E132: Function call depth is higher than 'maxfuncdepth'", v:errmsg) 4438 endtry 4439 catch /.*/ 4440 call assert_report('should not get here') 4441 finally 4442 Xpath 'c' 4443 let &mfd = mfd_save 4444 break " discard error for $VIMNOERRTHROW 4445 endtry 4446 call assert_report('should not get here') 4447 endwhile 4448 4449 call assert_equal('abc', g:Xpath) 4450 delfunc H 4451endfunc 4452 4453"------------------------------------------------------------------------------- 4454" Test 63: Suppressing error exceptions by :silent!. {{{1 4455" 4456" A :silent! command inside a :try/:endtry region suppresses the 4457" conversion of errors to an exception and the immediate abortion on 4458" error. When the commands executed by the :silent! themselves open 4459" a new :try/:endtry region, conversion of errors to exception and 4460" immediate abortion is switched on again - until the next :silent! 4461" etc. The :silent! has the effect of setting v:errmsg to the error 4462" message text (without displaying it) and continuing with the next 4463" script line. 4464" 4465" When a command triggering autocommands is executed by :silent! 4466" inside a :try/:endtry, the autocommand execution is not suppressed 4467" on error. 4468" 4469" This test reuses the function MSG() from the previous test. 4470"------------------------------------------------------------------------------- 4471 4472func Test_silent_exception() 4473 XpathINIT 4474 XloopINIT 4475 let g:taken = "" 4476 4477 func S(n) abort 4478 XloopNEXT 4479 let g:taken = g:taken . "E" . a:n 4480 let v:errmsg = "" 4481 exec "asdf" . a:n 4482 4483 " Check that ":silent!" continues: 4484 Xloop 'a' 4485 4486 " Check that ":silent!" sets "v:errmsg": 4487 call assert_match("E492: Not an editor command", v:errmsg) 4488 endfunc 4489 4490 func Foo() 4491 while 1 4492 try 4493 try 4494 let caught = 0 4495 " This is not silent: 4496 call S(3) 4497 catch /^Vim:/ 4498 Xpath 'b' 4499 let caught = 1 4500 let errmsg3 = substitute(v:exception, '^Vim:', '', "") 4501 silent! call S(4) 4502 finally 4503 call assert_equal(1, caught) 4504 Xpath 'c' 4505 call assert_match("E492: Not an editor command", errmsg3) 4506 silent! call S(5) 4507 " Break out of try conditionals that cover ":silent!". This also 4508 " discards the aborting error when $VIMNOERRTHROW is non-zero. 4509 break 4510 endtry 4511 catch /.*/ 4512 call assert_report('should not get here') 4513 endtry 4514 endwhile 4515 " This is a double ":silent!" (see caller). 4516 silent! call S(6) 4517 endfunc 4518 4519 func Bar() 4520 try 4521 silent! call S(2) 4522 silent! execute "call Foo() | call S(7)" 4523 silent! call S(8) 4524 endtry " normal end of try cond that covers ":silent!" 4525 " This has a ":silent!" from the caller: 4526 call S(9) 4527 endfunc 4528 4529 silent! call S(1) 4530 silent! call Bar() 4531 silent! call S(10) 4532 4533 call assert_equal("E1E2E3E4E5E6E7E8E9E10", g:taken) 4534 4535 augroup TMP 4536 au! 4537 autocmd BufWritePost * Xpath 'd' 4538 augroup END 4539 4540 Xpath 'e' 4541 silent! write /i/m/p/o/s/s/i/b/l/e 4542 Xpath 'f' 4543 4544 call assert_equal('a2a3ba5ca6a7a8a9a10a11edf', g:Xpath) 4545 4546 augroup TMP 4547 au! 4548 augroup END 4549 augroup! TMP 4550 delfunction S 4551 delfunction Foo 4552 delfunction Bar 4553endfunc 4554 4555"------------------------------------------------------------------------------- 4556" Test 64: Error exceptions after error, interrupt or :throw {{{1 4557" 4558" When an error occurs after an interrupt or a :throw but before 4559" a matching :catch is reached, all following :catches of that try 4560" block are ignored, but the error exception can be caught by the next 4561" surrounding try conditional. Any previous error exception is 4562" discarded. An error is ignored when there is a previous error that 4563" has not been caught. 4564"------------------------------------------------------------------------------- 4565 4566func Test_exception_after_error_1() 4567 XpathINIT 4568 while 1 4569 try 4570 try 4571 Xpath 'a' 4572 let caught = 0 4573 while 1 4574 if 1 4575 " Missing :endif 4576 endwhile " throw error exception 4577 catch /^Vim(/ 4578 Xpath 'b' 4579 let caught = 1 4580 finally 4581 Xpath 'c' 4582 call assert_equal(1, caught) 4583 endtry 4584 catch /.*/ 4585 call assert_report('should not get here') 4586 finally 4587 Xpath 'd' 4588 break 4589 endtry 4590 call assert_report('should not get here') 4591 endwhile 4592 call assert_equal('abcd', g:Xpath) 4593endfunc 4594 4595func Test_exception_after_error_2() 4596 XpathINIT 4597 while 1 4598 try 4599 try 4600 Xpath 'a' 4601 let caught = 0 4602 try 4603 if 1 4604 " Missing :endif 4605 catch /.*/ " throw error exception 4606 call assert_report('should not get here') 4607 catch /.*/ 4608 call assert_report('should not get here') 4609 endtry 4610 catch /^Vim(/ 4611 Xpath 'b' 4612 let caught = 1 4613 finally 4614 Xpath 'c' 4615 call assert_equal(1, caught) 4616 endtry 4617 catch /.*/ 4618 call assert_report('should not get here') 4619 finally 4620 Xpath 'd' 4621 break 4622 endtry 4623 call assert_report('should not get here') 4624 endwhile 4625 call assert_equal('abcd', g:Xpath) 4626endfunc 4627 4628func Test_exception_after_error_3() 4629 XpathINIT 4630 while 1 4631 try 4632 try 4633 let caught = 0 4634 try 4635 Xpath 'a' 4636 call interrupt() 4637 catch /do_not_catch/ 4638 call assert_report('should not get here') 4639 if 1 4640 " Missing :endif 4641 catch /.*/ " throw error exception 4642 call assert_report('should not get here') 4643 catch /.*/ 4644 call assert_report('should not get here') 4645 endtry 4646 catch /^Vim(/ 4647 Xpath 'b' 4648 let caught = 1 4649 finally 4650 Xpath 'c' 4651 call assert_equal(1, caught) 4652 endtry 4653 catch /.*/ 4654 call assert_report('should not get here') 4655 finally 4656 Xpath 'd' 4657 break 4658 endtry 4659 call assert_report('should not get here') 4660 endwhile 4661 call assert_equal('abcd', g:Xpath) 4662endfunc 4663 4664func Test_exception_after_error_4() 4665 XpathINIT 4666 while 1 4667 try 4668 try 4669 let caught = 0 4670 try 4671 Xpath 'a' 4672 throw "x" 4673 catch /do_not_catch/ 4674 call assert_report('should not get here') 4675 if 1 4676 " Missing :endif 4677 catch /x/ " throw error exception 4678 call assert_report('should not get here') 4679 catch /.*/ 4680 call assert_report('should not get here') 4681 endtry 4682 catch /^Vim(/ 4683 Xpath 'b' 4684 let caught = 1 4685 finally 4686 Xpath 'c' 4687 call assert_equal(1, caught) 4688 endtry 4689 catch /.*/ 4690 call assert_report('should not get here') 4691 finally 4692 Xpath 'd' 4693 break 4694 endtry 4695 call assert_report('should not get here') 4696 endwhile 4697 call assert_equal('abcd', g:Xpath) 4698endfunc 4699 4700func Test_exception_after_error_5() 4701 XpathINIT 4702 while 1 4703 try 4704 try 4705 let caught = 0 4706 Xpath 'a' 4707 endif " :endif without :if; throw error exception 4708 if 1 4709 " Missing :endif 4710 catch /do_not_catch/ " ignore new error 4711 call assert_report('should not get here') 4712 catch /^Vim(endif):/ 4713 Xpath 'b' 4714 let caught = 1 4715 catch /^Vim(/ 4716 call assert_report('should not get here') 4717 finally 4718 Xpath 'c' 4719 call assert_equal(1, caught) 4720 endtry 4721 catch /.*/ 4722 call assert_report('should not get here') 4723 finally 4724 Xpath 'd' 4725 break 4726 endtry 4727 call assert_report('should not get here') 4728 endwhile 4729 call assert_equal('abcd', g:Xpath) 4730endfunc 4731 4732"------------------------------------------------------------------------------- 4733" Test 65: Errors in the /pattern/ argument of a :catch {{{1 4734" 4735" On an error in the /pattern/ argument of a :catch, the :catch does 4736" not match. Any following :catches of the same :try/:endtry don't 4737" match either. Finally clauses are executed. 4738"------------------------------------------------------------------------------- 4739 4740func Test_catch_pattern_error() 4741 CheckEnglish 4742 XpathINIT 4743 4744 try 4745 try 4746 Xpath 'a' 4747 throw "oops" 4748 catch /^oops$/ 4749 Xpath 'b' 4750 catch /\)/ " not checked; exception has already been caught 4751 call assert_report('should not get here') 4752 endtry 4753 Xpath 'c' 4754 catch /.*/ 4755 call assert_report('should not get here') 4756 endtry 4757 call assert_equal('abc', g:Xpath) 4758 4759 XpathINIT 4760 func F() 4761 try 4762 try 4763 try 4764 Xpath 'a' 4765 throw "ab" 4766 catch /abc/ " does not catch 4767 call assert_report('should not get here') 4768 catch /\)/ " error; discards exception 4769 call assert_report('should not get here') 4770 catch /.*/ " not checked 4771 call assert_report('should not get here') 4772 finally 4773 Xpath 'b' 4774 endtry 4775 call assert_report('should not get here') 4776 catch /^ab$/ " checked, but original exception is discarded 4777 call assert_report('should not get here') 4778 catch /^Vim(catch):/ 4779 Xpath 'c' 4780 call assert_match('Vim(catch):E475: Invalid argument:', v:exception) 4781 finally 4782 Xpath 'd' 4783 endtry 4784 Xpath 'e' 4785 catch /.*/ 4786 call assert_report('should not get here') 4787 endtry 4788 Xpath 'f' 4789 endfunc 4790 4791 call F() 4792 call assert_equal('abcdef', g:Xpath) 4793 4794 delfunc F 4795endfunc 4796 4797"------------------------------------------------------------------------------- 4798" Test 66: Stop range :call on error, interrupt, or :throw {{{1 4799" 4800" When a function which is multiply called for a range since it 4801" doesn't handle the range itself has an error in a command 4802" dynamically enclosed by :try/:endtry or gets an interrupt or 4803" executes a :throw, no more calls for the remaining lines in the 4804" range are made. On an error in a command not dynamically enclosed 4805" by :try/:endtry, the function is executed again for the remaining 4806" lines in the range. 4807"------------------------------------------------------------------------------- 4808 4809func Test_stop_range_on_error() 4810 let test =<< trim [CODE] 4811 let file = tempname() 4812 exec "edit" file 4813 call setline(1, ['line 1', 'line 2', 'line 3']) 4814 let taken = "" 4815 let expected = "G1EF1E(1)F1E(2)F1E(3)G2EF2E(1)G3IF3I(1)G4TF4T(1)G5AF5A(1)" 4816 4817 func F(reason, n) abort 4818 let g:taken = g:taken .. "F" .. a:n .. 4819 \ substitute(a:reason, '\(\l\).*', '\u\1', "") .. 4820 \ "(" .. line(".") .. ")" 4821 4822 if a:reason == "error" 4823 asdf 4824 elseif a:reason == "interrupt" 4825 call interrupt() 4826 elseif a:reason == "throw" 4827 throw "xyz" 4828 elseif a:reason == "aborting error" 4829 XloopNEXT 4830 call assert_equal(g:taken, g:expected) 4831 try 4832 bwipeout! 4833 call delete(g:file) 4834 asdf 4835 endtry 4836 endif 4837 endfunc 4838 4839 func G(reason, n) 4840 let g:taken = g:taken .. "G" .. a:n .. 4841 \ substitute(a:reason, '\(\l\).*', '\u\1', "") 4842 1,3call F(a:reason, a:n) 4843 endfunc 4844 4845 Xpath 'a' 4846 call G("error", 1) 4847 try 4848 Xpath 'b' 4849 try 4850 call G("error", 2) 4851 call assert_report('should not get here') 4852 finally 4853 Xpath 'c' 4854 try 4855 call G("interrupt", 3) 4856 call assert_report('should not get here') 4857 finally 4858 Xpath 'd' 4859 try 4860 call G("throw", 4) 4861 call assert_report('should not get here') 4862 endtry 4863 endtry 4864 endtry 4865 catch /xyz/ 4866 Xpath 'e' 4867 catch /.*/ 4868 call assert_report('should not get here') 4869 endtry 4870 Xpath 'f' 4871 call G("aborting error", 5) 4872 call assert_report('should not get here') 4873 [CODE] 4874 let verify =<< trim [CODE] 4875 call assert_equal('abcdef', g:Xpath) 4876 [CODE] 4877 call RunInNewVim(test, verify) 4878endfunc 4879 4880"------------------------------------------------------------------------------- 4881" Test 67: :throw across :call command {{{1 4882" 4883" On a call command, an exception might be thrown when evaluating the 4884" function name, during evaluation of the arguments, or when the 4885" function is being executed. The exception can be caught by the 4886" caller. 4887"------------------------------------------------------------------------------- 4888 4889func THROW(x, n) 4890 if a:n == 1 4891 Xpath 'A' 4892 elseif a:n == 2 4893 Xpath 'B' 4894 elseif a:n == 3 4895 Xpath 'C' 4896 endif 4897 throw a:x 4898endfunc 4899 4900func NAME(x, n) 4901 if a:n == 1 4902 call assert_report('should not get here') 4903 elseif a:n == 2 4904 Xpath 'D' 4905 elseif a:n == 3 4906 Xpath 'E' 4907 elseif a:n == 4 4908 Xpath 'F' 4909 endif 4910 return a:x 4911endfunc 4912 4913func ARG(x, n) 4914 if a:n == 1 4915 call assert_report('should not get here') 4916 elseif a:n == 2 4917 call assert_report('should not get here') 4918 elseif a:n == 3 4919 Xpath 'G' 4920 elseif a:n == 4 4921 Xpath 'I' 4922 endif 4923 return a:x 4924endfunc 4925 4926func Test_throw_across_call_cmd() 4927 XpathINIT 4928 4929 func F(x, n) 4930 if a:n == 2 4931 call assert_report('should not get here') 4932 elseif a:n == 4 4933 Xpath 'a' 4934 endif 4935 endfunc 4936 4937 while 1 4938 try 4939 let v:errmsg = "" 4940 4941 while 1 4942 try 4943 Xpath 'b' 4944 call {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1) 4945 call assert_report('should not get here') 4946 catch /^name$/ 4947 Xpath 'c' 4948 catch /.*/ 4949 call assert_report('should not get here') 4950 finally 4951 call assert_equal("", v:errmsg) 4952 let v:errmsg = "" 4953 break 4954 endtry 4955 endwhile 4956 4957 while 1 4958 try 4959 Xpath 'd' 4960 call {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2) 4961 call assert_report('should not get here') 4962 catch /^arg$/ 4963 Xpath 'e' 4964 catch /.*/ 4965 call assert_report('should not get here') 4966 finally 4967 call assert_equal("", v:errmsg) 4968 let v:errmsg = "" 4969 break 4970 endtry 4971 endwhile 4972 4973 while 1 4974 try 4975 Xpath 'f' 4976 call {NAME("THROW", 3)}(ARG("call", 3), 3) 4977 call assert_report('should not get here') 4978 catch /^call$/ 4979 Xpath 'g' 4980 catch /^0$/ " default return value 4981 call assert_report('should not get here') 4982 catch /.*/ 4983 call assert_report('should not get here') 4984 finally 4985 call assert_equal("", v:errmsg) 4986 let v:errmsg = "" 4987 break 4988 endtry 4989 endwhile 4990 4991 while 1 4992 try 4993 Xpath 'h' 4994 call {NAME("F", 4)}(ARG(4711, 4), 4) 4995 Xpath 'i' 4996 catch /.*/ 4997 call assert_report('should not get here') 4998 finally 4999 call assert_equal("", v:errmsg) 5000 let v:errmsg = "" 5001 break 5002 endtry 5003 endwhile 5004 5005 catch /^0$/ " default return value 5006 call assert_report('should not get here') 5007 catch /.*/ 5008 call assert_report('should not get here') 5009 finally 5010 call assert_equal("", v:errmsg) 5011 let v:errmsg = "" 5012 break 5013 endtry 5014 endwhile 5015 5016 call assert_equal('bAcdDBefEGCghFIai', g:Xpath) 5017 delfunction F 5018endfunc 5019 5020"------------------------------------------------------------------------------- 5021" Test 68: :throw across function calls in expressions {{{1 5022" 5023" On a function call within an expression, an exception might be 5024" thrown when evaluating the function name, during evaluation of the 5025" arguments, or when the function is being executed. The exception 5026" can be caught by the caller. 5027" 5028" This test reuses the functions THROW(), NAME(), and ARG() from the 5029" previous test. 5030"------------------------------------------------------------------------------- 5031 5032func Test_throw_across_call_expr() 5033 XpathINIT 5034 5035 func F(x, n) 5036 if a:n == 2 5037 call assert_report('should not get here') 5038 elseif a:n == 4 5039 Xpath 'a' 5040 endif 5041 return a:x 5042 endfunction 5043 5044 while 1 5045 try 5046 let error = 0 5047 let v:errmsg = "" 5048 5049 while 1 5050 try 5051 Xpath 'b' 5052 let var1 = {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1) 5053 call assert_report('should not get here') 5054 catch /^name$/ 5055 Xpath 'c' 5056 catch /.*/ 5057 call assert_report('should not get here') 5058 finally 5059 call assert_equal("", v:errmsg) 5060 let v:errmsg = "" 5061 break 5062 endtry 5063 endwhile 5064 call assert_true(!exists('var1')) 5065 5066 while 1 5067 try 5068 Xpath 'd' 5069 let var2 = {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2) 5070 call assert_report('should not get here') 5071 catch /^arg$/ 5072 Xpath 'e' 5073 catch /.*/ 5074 call assert_report('should not get here') 5075 finally 5076 call assert_equal("", v:errmsg) 5077 let v:errmsg = "" 5078 break 5079 endtry 5080 endwhile 5081 call assert_true(!exists('var2')) 5082 5083 while 1 5084 try 5085 Xpath 'f' 5086 let var3 = {NAME("THROW", 3)}(ARG("call", 3), 3) 5087 call assert_report('should not get here') 5088 catch /^call$/ 5089 Xpath 'g' 5090 catch /^0$/ " default return value 5091 call assert_report('should not get here') 5092 catch /.*/ 5093 call assert_report('should not get here') 5094 finally 5095 call assert_equal("", v:errmsg) 5096 let v:errmsg = "" 5097 break 5098 endtry 5099 endwhile 5100 call assert_true(!exists('var3')) 5101 5102 while 1 5103 try 5104 Xpath 'h' 5105 let var4 = {NAME("F", 4)}(ARG(4711, 4), 4) 5106 Xpath 'i' 5107 catch /.*/ 5108 call assert_report('should not get here') 5109 finally 5110 call assert_equal("", v:errmsg) 5111 let v:errmsg = "" 5112 break 5113 endtry 5114 endwhile 5115 call assert_true(exists('var4') && var4 == 4711) 5116 5117 catch /^0$/ " default return value 5118 call assert_report('should not get here') 5119 catch /.*/ 5120 call assert_report('should not get here') 5121 finally 5122 call assert_equal("", v:errmsg) 5123 break 5124 endtry 5125 endwhile 5126 5127 call assert_equal('bAcdDBefEGCghFIai', g:Xpath) 5128 delfunc F 5129endfunc 5130 5131"------------------------------------------------------------------------------- 5132" Test 76: Errors, interrupts, :throw during expression evaluation {{{1 5133" 5134" When a function call made during expression evaluation is aborted 5135" due to an error inside a :try/:endtry region or due to an interrupt 5136" or a :throw, the expression evaluation is aborted as well. No 5137" message is displayed for the cancelled expression evaluation. On an 5138" error not inside :try/:endtry, the expression evaluation continues. 5139"------------------------------------------------------------------------------- 5140 5141func Test_expr_eval_error() 5142 let test =<< trim [CODE] 5143 let taken = "" 5144 5145 func ERR(n) 5146 let g:taken = g:taken .. "E" .. a:n 5147 asdf 5148 endfunc 5149 5150 func ERRabort(n) abort 5151 let g:taken = g:taken .. "A" .. a:n 5152 asdf 5153 endfunc " returns -1; may cause follow-up msg for illegal var/func name 5154 5155 func WRAP(n, arg) 5156 let g:taken = g:taken .. "W" .. a:n 5157 let g:saved_errmsg = v:errmsg 5158 return arg 5159 endfunc 5160 5161 func INT(n) 5162 let g:taken = g:taken .. "I" .. a:n 5163 call interrupt() 5164 endfunc 5165 5166 func THR(n) 5167 let g:taken = g:taken .. "T" .. a:n 5168 throw "should not be caught" 5169 endfunc 5170 5171 func CONT(n) 5172 let g:taken = g:taken .. "C" .. a:n 5173 endfunc 5174 5175 func MSG(n) 5176 let g:taken = g:taken .. "M" .. a:n 5177 let errmsg = (a:n >= 37 && a:n <= 44) ? g:saved_errmsg : v:errmsg 5178 let msgptn = (a:n >= 10 && a:n <= 27) ? "^$" : "asdf" 5179 call assert_match(msgptn, errmsg) 5180 let v:errmsg = "" 5181 let g:saved_errmsg = "" 5182 endfunc 5183 5184 let v:errmsg = "" 5185 5186 try 5187 let t = 1 5188 while t <= 9 5189 Xloop 'a' 5190 try 5191 if t == 1 5192 let v{ERR(t) + CONT(t)} = 0 5193 elseif t == 2 5194 let v{ERR(t) + CONT(t)} 5195 elseif t == 3 5196 let var = exists('v{ERR(t) + CONT(t)}') 5197 elseif t == 4 5198 unlet v{ERR(t) + CONT(t)} 5199 elseif t == 5 5200 function F{ERR(t) + CONT(t)}() 5201 endfunction 5202 elseif t == 6 5203 function F{ERR(t) + CONT(t)} 5204 elseif t == 7 5205 let var = exists('*F{ERR(t) + CONT(t)}') 5206 elseif t == 8 5207 delfunction F{ERR(t) + CONT(t)} 5208 elseif t == 9 5209 let var = ERR(t) + CONT(t) 5210 endif 5211 catch /asdf/ 5212 " v:errmsg is not set when the error message is converted to an 5213 " exception. Set it to the original error message. 5214 let v:errmsg = substitute(v:exception, '^Vim:', '', "") 5215 catch /^Vim\((\a\+)\)\=:/ 5216 " An error exception has been thrown after the original error. 5217 let v:errmsg = "" 5218 finally 5219 call MSG(t) 5220 let t = t + 1 5221 XloopNEXT 5222 continue " discard an aborting error 5223 endtry 5224 endwhile 5225 catch /.*/ 5226 call assert_report('should not get here') 5227 endtry 5228 5229 try 5230 let t = 10 5231 while t <= 18 5232 Xloop 'b' 5233 try 5234 if t == 10 5235 let v{INT(t) + CONT(t)} = 0 5236 elseif t == 11 5237 let v{INT(t) + CONT(t)} 5238 elseif t == 12 5239 let var = exists('v{INT(t) + CONT(t)}') 5240 elseif t == 13 5241 unlet v{INT(t) + CONT(t)} 5242 elseif t == 14 5243 function F{INT(t) + CONT(t)}() 5244 endfunction 5245 elseif t == 15 5246 function F{INT(t) + CONT(t)} 5247 elseif t == 16 5248 let var = exists('*F{INT(t) + CONT(t)}') 5249 elseif t == 17 5250 delfunction F{INT(t) + CONT(t)} 5251 elseif t == 18 5252 let var = INT(t) + CONT(t) 5253 endif 5254 catch /^Vim\((\a\+)\)\=:\(Interrupt\)\@!/ 5255 " An error exception has been triggered after the interrupt. 5256 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") 5257 finally 5258 call MSG(t) 5259 let t = t + 1 5260 XloopNEXT 5261 continue " discard interrupt 5262 endtry 5263 endwhile 5264 catch /.*/ 5265 call assert_report('should not get here') 5266 endtry 5267 5268 try 5269 let t = 19 5270 while t <= 27 5271 Xloop 'c' 5272 try 5273 if t == 19 5274 let v{THR(t) + CONT(t)} = 0 5275 elseif t == 20 5276 let v{THR(t) + CONT(t)} 5277 elseif t == 21 5278 let var = exists('v{THR(t) + CONT(t)}') 5279 elseif t == 22 5280 unlet v{THR(t) + CONT(t)} 5281 elseif t == 23 5282 function F{THR(t) + CONT(t)}() 5283 endfunction 5284 elseif t == 24 5285 function F{THR(t) + CONT(t)} 5286 elseif t == 25 5287 let var = exists('*F{THR(t) + CONT(t)}') 5288 elseif t == 26 5289 delfunction F{THR(t) + CONT(t)} 5290 elseif t == 27 5291 let var = THR(t) + CONT(t) 5292 endif 5293 catch /^Vim\((\a\+)\)\=:/ 5294 " An error exception has been triggered after the :throw. 5295 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") 5296 finally 5297 call MSG(t) 5298 let t = t + 1 5299 XloopNEXT 5300 continue " discard exception 5301 endtry 5302 endwhile 5303 catch /.*/ 5304 call assert_report('should not get here') 5305 endtry 5306 5307 let v{ERR(28) + CONT(28)} = 0 5308 call MSG(28) 5309 let v{ERR(29) + CONT(29)} 5310 call MSG(29) 5311 let var = exists('v{ERR(30) + CONT(30)}') 5312 call MSG(30) 5313 unlet v{ERR(31) + CONT(31)} 5314 call MSG(31) 5315 function F{ERR(32) + CONT(32)}() 5316 endfunction 5317 call MSG(32) 5318 function F{ERR(33) + CONT(33)} 5319 call MSG(33) 5320 let var = exists('*F{ERR(34) + CONT(34)}') 5321 call MSG(34) 5322 delfunction F{ERR(35) + CONT(35)} 5323 call MSG(35) 5324 let var = ERR(36) + CONT(36) 5325 call MSG(36) 5326 5327 let saved_errmsg = "" 5328 5329 let v{WRAP(37, ERRabort(37)) + CONT(37)} = 0 5330 call MSG(37) 5331 let v{WRAP(38, ERRabort(38)) + CONT(38)} 5332 call MSG(38) 5333 let var = exists('v{WRAP(39, ERRabort(39)) + CONT(39)}') 5334 call MSG(39) 5335 unlet v{WRAP(40, ERRabort(40)) + CONT(40)} 5336 call MSG(40) 5337 function F{WRAP(41, ERRabort(41)) + CONT(41)}() 5338 endfunction 5339 call MSG(41) 5340 function F{WRAP(42, ERRabort(42)) + CONT(42)} 5341 call MSG(42) 5342 let var = exists('*F{WRAP(43, ERRabort(43)) + CONT(43)}') 5343 call MSG(43) 5344 delfunction F{WRAP(44, ERRabort(44)) + CONT(44)} 5345 call MSG(44) 5346 let var = ERRabort(45) + CONT(45) 5347 call MSG(45) 5348 Xpath 'd' 5349 5350 let expected = "" 5351 \ .. "E1M1E2M2E3M3E4M4E5M5E6M6E7M7E8M8E9M9" 5352 \ .. "I10M10I11M11I12M12I13M13I14M14I15M15I16M16I17M17I18M18" 5353 \ .. "T19M19T20M20T21M21T22M22T23M23T24M24T25M25T26M26T27M27" 5354 \ .. "E28C28M28E29C29M29E30C30M30E31C31M31E32C32M32E33C33M33" 5355 \ .. "E34C34M34E35C35M35E36C36M36" 5356 \ .. "A37W37C37M37A38W38C38M38A39W39C39M39A40W40C40M40A41W41C41M41" 5357 \ .. "A42W42C42M42A43W43C43M43A44W44C44M44A45C45M45" 5358 call assert_equal(expected, taken) 5359 [CODE] 5360 let verify =<< trim [CODE] 5361 let expected = "a1a2a3a4a5a6a7a8a9" 5362 \ .. "b10b11b12b13b14b15b16b17b18" 5363 \ .. "c19c20c21c22c23c24c25c26c27d" 5364 call assert_equal(expected, g:Xpath) 5365 [CODE] 5366 call RunInNewVim(test, verify) 5367endfunc 5368 5369"------------------------------------------------------------------------------- 5370" Test 77: Errors, interrupts, :throw in name{brace-expression} {{{1 5371" 5372" When a function call made during evaluation of an expression in 5373" braces as part of a function name after ":function" is aborted due 5374" to an error inside a :try/:endtry region or due to an interrupt or 5375" a :throw, the expression evaluation is aborted as well, and the 5376" function definition is ignored, skipping all commands to the 5377" ":endfunction". On an error not inside :try/:endtry, the expression 5378" evaluation continues and the function gets defined, and can be 5379" called and deleted. 5380"------------------------------------------------------------------------------- 5381func Test_brace_expr_error() 5382 let test =<< trim [CODE] 5383 func ERR() abort 5384 Xloop 'a' 5385 asdf 5386 endfunc " returns -1 5387 5388 func OK() 5389 Xloop 'b' 5390 let v:errmsg = "" 5391 return 0 5392 endfunc 5393 5394 let v:errmsg = "" 5395 5396 Xpath 'c' 5397 func F{1 + ERR() + OK()}(arg) 5398 " F0 should be defined. 5399 if exists("a:arg") && a:arg == "calling" 5400 Xpath 'd' 5401 else 5402 call assert_report('should not get here') 5403 endif 5404 endfunction 5405 call assert_equal("", v:errmsg) 5406 XloopNEXT 5407 5408 Xpath 'e' 5409 call F{1 + ERR() + OK()}("calling") 5410 call assert_equal("", v:errmsg) 5411 XloopNEXT 5412 5413 Xpath 'f' 5414 delfunction F{1 + ERR() + OK()} 5415 call assert_equal("", v:errmsg) 5416 XloopNEXT 5417 5418 try 5419 while 1 5420 try 5421 Xpath 'g' 5422 func G{1 + ERR() + OK()}(arg) 5423 " G0 should not be defined, and the function body should be 5424 " skipped. 5425 call assert_report('should not get here') 5426 " Use an unmatched ":finally" to check whether the body is 5427 " skipped when an error occurs in ERR(). This works whether or 5428 " not the exception is converted to an exception. 5429 finally 5430 call assert_report('should not get here') 5431 endtry 5432 try 5433 call assert_report('should not get here') 5434 endfunction 5435 5436 call assert_report('should not get here') 5437 catch /asdf/ 5438 " Jumped to when the function is not defined and the body is 5439 " skipped. 5440 Xpath 'h' 5441 catch /.*/ 5442 call assert_report('should not get here') 5443 finally 5444 Xpath 'i' 5445 break 5446 endtry " jumped to when the body is not skipped 5447 endwhile 5448 catch /.*/ 5449 call assert_report('should not get here') 5450 endtry 5451 [CODE] 5452 let verify =<< trim [CODE] 5453 call assert_equal('ca1b1ea2b2dfa3b3ga4hi', g:Xpath) 5454 [CODE] 5455 call RunInNewVim(test, verify) 5456endfunc 5457 5458"------------------------------------------------------------------------------- 5459" Test 78: Messages on parsing errors in expression evaluation {{{1 5460" 5461" When an expression evaluation detects a parsing error, an error 5462" message is given and converted to an exception, and the expression 5463" evaluation is aborted. 5464"------------------------------------------------------------------------------- 5465func Test_expr_eval_error_msg() 5466 CheckEnglish 5467 5468 let test =<< trim [CODE] 5469 let taken = "" 5470 5471 func F(n) 5472 let g:taken = g:taken . "F" . a:n 5473 endfunc 5474 5475 func MSG(n, enr, emsg) 5476 let g:taken = g:taken . "M" . a:n 5477 call assert_match('^' .. a:enr .. ':', v:errmsg) 5478 call assert_match(a:emsg, v:errmsg) 5479 endfunc 5480 5481 func CONT(n) 5482 let g:taken = g:taken . "C" . a:n 5483 endfunc 5484 5485 let v:errmsg = "" 5486 try 5487 let t = 1 5488 while t <= 14 5489 let g:taken = g:taken . "T" . t 5490 let v:errmsg = "" 5491 try 5492 if t == 1 5493 let v{novar + CONT(t)} = 0 5494 elseif t == 2 5495 let v{novar + CONT(t)} 5496 elseif t == 3 5497 let var = exists('v{novar + CONT(t)}') 5498 elseif t == 4 5499 unlet v{novar + CONT(t)} 5500 elseif t == 5 5501 function F{novar + CONT(t)}() 5502 endfunction 5503 elseif t == 6 5504 function F{novar + CONT(t)} 5505 elseif t == 7 5506 let var = exists('*F{novar + CONT(t)}') 5507 elseif t == 8 5508 delfunction F{novar + CONT(t)} 5509 elseif t == 9 5510 echo novar + CONT(t) 5511 elseif t == 10 5512 echo v{novar + CONT(t)} 5513 elseif t == 11 5514 echo F{novar + CONT(t)} 5515 elseif t == 12 5516 let var = novar + CONT(t) 5517 elseif t == 13 5518 let var = v{novar + CONT(t)} 5519 elseif t == 14 5520 let var = F{novar + CONT(t)}() 5521 endif 5522 catch /^Vim\((\a\+)\)\=:/ 5523 Xloop 'a' 5524 " v:errmsg is not set when the error message is converted to an 5525 " exception. Set it to the original error message. 5526 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") 5527 finally 5528 Xloop 'b' 5529 if t <= 8 && t != 3 && t != 7 5530 call MSG(t, 'E475', 'Invalid argument\>') 5531 else 5532 call MSG(t, 'E121', "Undefined variable") 5533 endif 5534 let t = t + 1 5535 XloopNEXT 5536 continue " discard an aborting error 5537 endtry 5538 endwhile 5539 catch /.*/ 5540 call assert_report('should not get here') 5541 endtry 5542 5543 func T(n, expr, enr, emsg) 5544 try 5545 let g:taken = g:taken . "T" . a:n 5546 let v:errmsg = "" 5547 try 5548 execute "let var = " . a:expr 5549 catch /^Vim\((\a\+)\)\=:/ 5550 Xloop 'c' 5551 " v:errmsg is not set when the error message is converted to an 5552 " exception. Set it to the original error message. 5553 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") 5554 finally 5555 Xloop 'd' 5556 call MSG(a:n, a:enr, a:emsg) 5557 XloopNEXT 5558 " Discard an aborting error: 5559 return 5560 endtry 5561 catch /.*/ 5562 call assert_report('should not get here') 5563 endtry 5564 endfunc 5565 5566 call T(15, 'Nofunc() + CONT(15)', 'E117', "Unknown function") 5567 call T(16, 'F(1 2 + CONT(16))', 'E116', "Invalid arguments") 5568 call T(17, 'F(1, 2) + CONT(17)', 'E118', "Too many arguments") 5569 call T(18, 'F() + CONT(18)', 'E119', "Not enough arguments") 5570 call T(19, '{(1} + CONT(19)', 'E110', "Missing ')'") 5571 call T(20, '("abc"[1) + CONT(20)', 'E111', "Missing ']'") 5572 call T(21, '(1 +) + CONT(21)', 'E15', "Invalid expression") 5573 call T(22, '1 2 + CONT(22)', 'E15', "Invalid expression") 5574 call T(23, '(1 ? 2) + CONT(23)', 'E109', "Missing ':' after '?'") 5575 call T(24, '("abc) + CONT(24)', 'E114', "Missing quote") 5576 call T(25, "('abc) + CONT(25)", 'E115', "Missing quote") 5577 call T(26, '& + CONT(26)', 'E112', "Option name missing") 5578 call T(27, '&asdf + CONT(27)', 'E113', "Unknown option") 5579 5580 let expected = "" 5581 \ .. "T1M1T2M2T3M3T4M4T5M5T6M6T7M7T8M8T9M9T10M10T11M11T12M12T13M13T14M14" 5582 \ .. "T15M15T16M16T17M17T18M18T19M19T20M20T21M21T22M22T23M23T24M24T25M25" 5583 \ .. "T26M26T27M27" 5584 5585 call assert_equal(expected, taken) 5586 [CODE] 5587 let verify =<< trim [CODE] 5588 let expected = "a1b1a2b2a3b3a4b4a5b5a6b6a7b7a8b8a9b9a10b10a11b11a12b12" 5589 \ .. "a13b13a14b14c15d15c16d16c17d17c18d18c19d19c20d20" 5590 \ .. "c21d21c22d22c23d23c24d24c25d25c26d26c27d27" 5591 call assert_equal(expected, g:Xpath) 5592 [CODE] 5593 call RunInNewVim(test, verify) 5594endfunc 5595 5596"------------------------------------------------------------------------------- 5597" Test 79: Throwing one of several errors for the same command {{{1 5598" 5599" When several errors appear in a row (for instance during expression 5600" evaluation), the first as the most specific one is used when 5601" throwing an error exception. If, however, a syntax error is 5602" detected afterwards, this one is used for the error exception. 5603" On a syntax error, the next command is not executed, on a normal 5604" error, however, it is (relevant only in a function without the 5605" "abort" flag). v:errmsg is not set. 5606" 5607" If throwing error exceptions is configured off, v:errmsg is always 5608" set to the latest error message, that is, to the more general 5609" message or the syntax error, respectively. 5610"------------------------------------------------------------------------------- 5611func Test_throw_multi_error() 5612 CheckEnglish 5613 5614 let test =<< trim [CODE] 5615 func NEXT(cmd) 5616 exec a:cmd . " | Xloop 'a'" 5617 endfun 5618 5619 call NEXT('echo novar') " (checks nextcmd) 5620 XloopNEXT 5621 call NEXT('let novar #') " (skips nextcmd) 5622 XloopNEXT 5623 call NEXT('unlet novar #') " (skips nextcmd) 5624 XloopNEXT 5625 call NEXT('let {novar}') " (skips nextcmd) 5626 XloopNEXT 5627 call NEXT('unlet{ novar}') " (skips nextcmd) 5628 5629 call assert_equal('a1', g:Xpath) 5630 XpathINIT 5631 XloopINIT 5632 5633 func EXEC(cmd) 5634 exec a:cmd 5635 endfunc 5636 5637 try 5638 while 1 " dummy loop 5639 try 5640 let v:errmsg = "" 5641 call EXEC('echo novar') " normal error 5642 catch /^Vim\((\a\+)\)\=:/ 5643 Xpath 'b' 5644 call assert_match('E121: Undefined variable: novar', v:exception) 5645 finally 5646 Xpath 'c' 5647 call assert_equal("", v:errmsg) 5648 break 5649 endtry 5650 endwhile 5651 5652 Xpath 'd' 5653 let cmd = "let" 5654 while cmd != "" 5655 try 5656 let v:errmsg = "" 5657 call EXEC(cmd . ' novar #') " normal plus syntax error 5658 catch /^Vim\((\a\+)\)\=:/ 5659 Xloop 'e' 5660 call assert_match('E488: Trailing characters', v:exception) 5661 finally 5662 Xloop 'f' 5663 call assert_equal("", v:errmsg) 5664 if cmd == "let" 5665 let cmd = "unlet" 5666 else 5667 let cmd = "" 5668 endif 5669 XloopNEXT 5670 continue 5671 endtry 5672 endwhile 5673 5674 Xpath 'g' 5675 let cmd = "let" 5676 while cmd != "" 5677 try 5678 let v:errmsg = "" 5679 call EXEC(cmd . ' {novar}') " normal plus syntax error 5680 catch /^Vim\((\a\+)\)\=:/ 5681 Xloop 'h' 5682 call assert_match('E475: Invalid argument: {novar}', v:exception) 5683 finally 5684 Xloop 'i' 5685 call assert_equal("", v:errmsg) 5686 if cmd == "let" 5687 let cmd = "unlet" 5688 else 5689 let cmd = "" 5690 endif 5691 XloopNEXT 5692 continue 5693 endtry 5694 endwhile 5695 catch /.*/ 5696 call assert_report('should not get here') 5697 endtry 5698 Xpath 'j' 5699 [CODE] 5700 let verify =<< trim [CODE] 5701 call assert_equal('bcde1f1e2f2gh3i3h4i4j', g:Xpath) 5702 [CODE] 5703 call RunInNewVim(test, verify) 5704endfunc 5705 5706"------------------------------------------------------------------------------- 5707" Test 80: Syntax error in expression for illegal :elseif {{{1 5708" 5709" If there is a syntax error in the expression after an illegal 5710" :elseif, an error message is given (or an error exception thrown) 5711" for the illegal :elseif rather than the expression error. 5712"------------------------------------------------------------------------------- 5713func Test_if_syntax_error() 5714 CheckEnglish 5715 5716 let test =<< trim [CODE] 5717 let v:errmsg = "" 5718 if 0 5719 else 5720 elseif 1 ||| 2 5721 endif 5722 Xpath 'a' 5723 call assert_match('E584: :elseif after :else', v:errmsg) 5724 5725 let v:errmsg = "" 5726 if 1 5727 else 5728 elseif 1 ||| 2 5729 endif 5730 Xpath 'b' 5731 call assert_match('E584: :elseif after :else', v:errmsg) 5732 5733 let v:errmsg = "" 5734 elseif 1 ||| 2 5735 Xpath 'c' 5736 call assert_match('E582: :elseif without :if', v:errmsg) 5737 5738 let v:errmsg = "" 5739 while 1 5740 elseif 1 ||| 2 5741 endwhile 5742 Xpath 'd' 5743 call assert_match('E582: :elseif without :if', v:errmsg) 5744 5745 while 1 5746 try 5747 try 5748 let v:errmsg = "" 5749 if 0 5750 else 5751 elseif 1 ||| 2 5752 endif 5753 catch /^Vim\((\a\+)\)\=:/ 5754 Xpath 'e' 5755 call assert_match('E584: :elseif after :else', v:exception) 5756 finally 5757 Xpath 'f' 5758 call assert_equal("", v:errmsg) 5759 endtry 5760 catch /.*/ 5761 call assert_report('should not get here') 5762 finally 5763 Xpath 'g' 5764 break 5765 endtry 5766 endwhile 5767 5768 while 1 5769 try 5770 try 5771 let v:errmsg = "" 5772 if 1 5773 else 5774 elseif 1 ||| 2 5775 endif 5776 catch /^Vim\((\a\+)\)\=:/ 5777 Xpath 'h' 5778 call assert_match('E584: :elseif after :else', v:exception) 5779 finally 5780 Xpath 'i' 5781 call assert_equal("", v:errmsg) 5782 endtry 5783 catch /.*/ 5784 call assert_report('should not get here') 5785 finally 5786 Xpath 'j' 5787 break 5788 endtry 5789 endwhile 5790 5791 while 1 5792 try 5793 try 5794 let v:errmsg = "" 5795 elseif 1 ||| 2 5796 catch /^Vim\((\a\+)\)\=:/ 5797 Xpath 'k' 5798 call assert_match('E582: :elseif without :if', v:exception) 5799 finally 5800 Xpath 'l' 5801 call assert_equal("", v:errmsg) 5802 endtry 5803 catch /.*/ 5804 call assert_report('should not get here') 5805 finally 5806 Xpath 'm' 5807 break 5808 endtry 5809 endwhile 5810 5811 while 1 5812 try 5813 try 5814 let v:errmsg = "" 5815 while 1 5816 elseif 1 ||| 2 5817 endwhile 5818 catch /^Vim\((\a\+)\)\=:/ 5819 Xpath 'n' 5820 call assert_match('E582: :elseif without :if', v:exception) 5821 finally 5822 Xpath 'o' 5823 call assert_equal("", v:errmsg) 5824 endtry 5825 catch /.*/ 5826 call assert_report('should not get here') 5827 finally 5828 Xpath 'p' 5829 break 5830 endtry 5831 endwhile 5832 Xpath 'q' 5833 [CODE] 5834 let verify =<< trim [CODE] 5835 call assert_equal('abcdefghijklmnopq', g:Xpath) 5836 [CODE] 5837 call RunInNewVim(test, verify) 5838endfunc 5839 5840"------------------------------------------------------------------------------- 5841" Test 81: Discarding exceptions after an error or interrupt {{{1 5842" 5843" When an exception is thrown from inside a :try conditional without 5844" :catch and :finally clauses and an error or interrupt occurs before 5845" the :endtry is reached, the exception is discarded. 5846"------------------------------------------------------------------------------- 5847 5848func Test_discard_exception_after_error_1() 5849 let test =<< trim [CODE] 5850 try 5851 Xpath 'a' 5852 try 5853 Xpath 'b' 5854 throw "arrgh" 5855 call assert_report('should not get here') 5856 if 1 5857 call assert_report('should not get here') 5858 " error after :throw: missing :endif 5859 endtry 5860 call assert_report('should not get here') 5861 catch /arrgh/ 5862 call assert_report('should not get here') 5863 endtry 5864 call assert_report('should not get here') 5865 [CODE] 5866 let verify =<< trim [CODE] 5867 call assert_equal('ab', g:Xpath) 5868 [CODE] 5869 call RunInNewVim(test, verify) 5870endfunc 5871 5872" TODO: Need to interrupt the code before the endtry is invoked 5873func Disable_Test_discard_exception_after_error_2() 5874 let test =<< trim [CODE] 5875 try 5876 Xpath 'a' 5877 try 5878 Xpath 'b' 5879 throw "arrgh" 5880 call interrupt() " FIXME: throw is not interrupted here 5881 call assert_report('should not get here') 5882 endtry 5883 call assert_report('should not get here') 5884 catch /arrgh/ 5885 call assert_report('should not get here') 5886 endtry 5887 call assert_report('should not get here') 5888 [CODE] 5889 let verify =<< trim [CODE] 5890 call assert_equal('ab', g:Xpath) 5891 [CODE] 5892 call RunInNewVim(test, verify) 5893endfunc 5894 5895"------------------------------------------------------------------------------- 5896" Test 82: Ignoring :catch clauses after an error or interrupt {{{1 5897" 5898" When an exception is thrown and an error or interrupt occurs before 5899" the matching :catch clause is reached, the exception is discarded 5900" and the :catch clause is ignored (also for the error or interrupt 5901" exception being thrown then). 5902"------------------------------------------------------------------------------- 5903 5904func Test_ignore_catch_after_error_1() 5905 let test =<< trim [CODE] 5906 try 5907 try 5908 Xpath 'a' 5909 throw "arrgh" 5910 call assert_report('should not get here') 5911 if 1 5912 call assert_report('should not get here') 5913 " error after :throw: missing :endif 5914 catch /.*/ 5915 call assert_report('should not get here') 5916 catch /.*/ 5917 call assert_report('should not get here') 5918 endtry 5919 call assert_report('should not get here') 5920 catch /arrgh/ 5921 call assert_report('should not get here') 5922 endtry 5923 call assert_report('should not get here') 5924 [CODE] 5925 let verify =<< trim [CODE] 5926 call assert_equal('a', g:Xpath) 5927 [CODE] 5928 call RunInNewVim(test, verify) 5929endfunc 5930 5931func Test_ignore_catch_after_error_2() 5932 let test =<< trim [CODE] 5933 func E() 5934 try 5935 try 5936 Xpath 'a' 5937 throw "arrgh" 5938 call assert_report('should not get here') 5939 if 1 5940 call assert_report('should not get here') 5941 " error after :throw: missing :endif 5942 catch /.*/ 5943 call assert_report('should not get here') 5944 catch /.*/ 5945 call assert_report('should not get here') 5946 endtry 5947 call assert_report('should not get here') 5948 catch /arrgh/ 5949 call assert_report('should not get here') 5950 endtry 5951 endfunc 5952 5953 call E() 5954 call assert_report('should not get here') 5955 [CODE] 5956 let verify =<< trim [CODE] 5957 call assert_equal('a', g:Xpath) 5958 [CODE] 5959 call RunInNewVim(test, verify) 5960endfunc 5961 5962" TODO: Need to interrupt the code right before the catch is invoked 5963func FIXME_Test_ignore_catch_after_intr_1() 5964 let test =<< trim [CODE] 5965 try 5966 try 5967 Xpath 'a' 5968 throw "arrgh" 5969 call assert_report('should not get here') 5970 catch /.*/ " TODO: Need to interrupt before this catch is 5971 call interrupt() " invoked 5972 call assert_report('should not get here') 5973 catch /.*/ 5974 call assert_report('should not get here') 5975 endtry 5976 call assert_report('should not get here') 5977 catch /arrgh/ 5978 call assert_report('should not get here') 5979 endtry 5980 call assert_report('should not get here') 5981 [CODE] 5982 let verify =<< trim [CODE] 5983 call assert_equal('a', g:Xpath) 5984 [CODE] 5985 call RunInNewVim(test, verify) 5986endfunc 5987 5988" TODO: Need to interrupt the code right before the catch is invoked 5989func FIXME_Test_ignore_catch_after_intr_2() 5990 let test =<< trim [CODE] 5991 func I() 5992 try 5993 try 5994 Xpath 'a' 5995 throw "arrgh" 5996 call assert_report('should not get here') 5997 catch /.*/ " TODO: Need to interrupt before this catch is 5998 " invoked 5999 call interrupt() 6000 call assert_report('should not get here') 6001 catch /.*/ 6002 call assert_report('should not get here') 6003 endtry 6004 call assert_report('should not get here') 6005 catch /arrgh/ 6006 call assert_report('should not get here') 6007 endtry 6008 endfunc 6009 6010 call I() 6011 call assert_report('should not get here') 6012 [CODE] 6013 let verify =<< trim [CODE] 6014 call assert_equal('a', g:Xpath) 6015 [CODE] 6016 call RunInNewVim(test, verify) 6017endfunc 6018 6019"------------------------------------------------------------------------------- 6020" Test 83: Executing :finally clauses after an error or interrupt {{{1 6021" 6022" When an exception is thrown and an error or interrupt occurs before 6023" the :finally of the innermost :try is reached, the exception is 6024" discarded and the :finally clause is executed. 6025"------------------------------------------------------------------------------- 6026 6027func Test_finally_after_error() 6028 let test =<< trim [CODE] 6029 try 6030 Xpath 'a' 6031 try 6032 Xpath 'b' 6033 throw "arrgh" 6034 call assert_report('should not get here') 6035 if 1 6036 call assert_report('should not get here') 6037 " error after :throw: missing :endif 6038 finally 6039 Xpath 'c' 6040 endtry 6041 call assert_report('should not get here') 6042 catch /arrgh/ 6043 call assert_report('should not get here') 6044 endtry 6045 call assert_report('should not get here') 6046 [CODE] 6047 let verify =<< trim [CODE] 6048 call assert_equal('abc', g:Xpath) 6049 [CODE] 6050 call RunInNewVim(test, verify) 6051endfunc 6052 6053" TODO: Need to interrupt the code right before the finally is invoked 6054func FIXME_Test_finally_after_intr() 6055 let test =<< trim [CODE] 6056 try 6057 Xpath 'a' 6058 try 6059 Xpath 'b' 6060 throw "arrgh" 6061 call assert_report('should not get here') 6062 finally " TODO: Need to interrupt before the finally is invoked 6063 Xpath 'c' 6064 endtry 6065 call assert_report('should not get here') 6066 catch /arrgh/ 6067 call assert_report('should not get here') 6068 endtry 6069 call assert_report('should not get here') 6070 [CODE] 6071 let verify =<< trim [CODE] 6072 call assert_equal('abc', g:Xpath) 6073 [CODE] 6074 call RunInNewVim(test, verify) 6075endfunc 6076 6077"------------------------------------------------------------------------------- 6078" Test 84: Exceptions in autocommand sequences. {{{1 6079" 6080" When an exception occurs in a sequence of autocommands for 6081" a specific event, the rest of the sequence is not executed. The 6082" command that triggered the autocommand execution aborts, and the 6083" exception is propagated to the caller. 6084" 6085" For the FuncUndefined event under a function call expression or 6086" :call command, the function is not executed, even when it has 6087" been defined by the autocommands before the exception occurred. 6088"------------------------------------------------------------------------------- 6089 6090func Test_autocmd_exception() 6091 let test =<< trim [CODE] 6092 func INT() 6093 call interrupt() 6094 endfunc 6095 6096 aug TMP 6097 autocmd! 6098 6099 autocmd User x1 Xpath 'a' 6100 autocmd User x1 throw "x1" 6101 autocmd User x1 call assert_report('should not get here') 6102 6103 autocmd User x2 Xpath 'b' 6104 autocmd User x2 asdf 6105 autocmd User x2 call assert_report('should not get here') 6106 6107 autocmd User x3 Xpath 'c' 6108 autocmd User x3 call INT() 6109 autocmd User x3 call assert_report('should not get here') 6110 6111 autocmd FuncUndefined U1 func U1() 6112 autocmd FuncUndefined U1 call assert_report('should not get here') 6113 autocmd FuncUndefined U1 endfunc 6114 autocmd FuncUndefined U1 Xpath 'd' 6115 autocmd FuncUndefined U1 throw "U1" 6116 autocmd FuncUndefined U1 call assert_report('should not get here') 6117 6118 autocmd FuncUndefined U2 func U2() 6119 autocmd FuncUndefined U2 call assert_report('should not get here') 6120 autocmd FuncUndefined U2 endfunc 6121 autocmd FuncUndefined U2 Xpath 'e' 6122 autocmd FuncUndefined U2 ASDF 6123 autocmd FuncUndefined U2 call assert_report('should not get here') 6124 6125 autocmd FuncUndefined U3 func U3() 6126 autocmd FuncUndefined U3 call assert_report('should not get here') 6127 autocmd FuncUndefined U3 endfunc 6128 autocmd FuncUndefined U3 Xpath 'f' 6129 autocmd FuncUndefined U3 call INT() 6130 autocmd FuncUndefined U3 call assert_report('should not get here') 6131 aug END 6132 6133 try 6134 try 6135 Xpath 'g' 6136 doautocmd User x1 6137 catch /x1/ 6138 Xpath 'h' 6139 endtry 6140 6141 while 1 6142 try 6143 Xpath 'i' 6144 doautocmd User x2 6145 catch /asdf/ 6146 Xpath 'j' 6147 finally 6148 Xpath 'k' 6149 break 6150 endtry 6151 endwhile 6152 6153 while 1 6154 try 6155 Xpath 'l' 6156 doautocmd User x3 6157 catch /Vim:Interrupt/ 6158 Xpath 'm' 6159 finally 6160 Xpath 'n' 6161 " ... but break loop for caught interrupt exception, 6162 " or discard interrupt and break loop if $VIMNOINTTHROW 6163 break 6164 endtry 6165 endwhile 6166 6167 if exists("*U1") | delfunction U1 | endif 6168 if exists("*U2") | delfunction U2 | endif 6169 if exists("*U3") | delfunction U3 | endif 6170 6171 try 6172 Xpath 'o' 6173 call U1() 6174 catch /U1/ 6175 Xpath 'p' 6176 endtry 6177 6178 while 1 6179 try 6180 Xpath 'q' 6181 call U2() 6182 catch /ASDF/ 6183 Xpath 'r' 6184 finally 6185 Xpath 's' 6186 " ... but break loop for caught error exception, 6187 " or discard error and break loop if $VIMNOERRTHROW 6188 break 6189 endtry 6190 endwhile 6191 6192 while 1 6193 try 6194 Xpath 't' 6195 call U3() 6196 catch /Vim:Interrupt/ 6197 Xpath 'u' 6198 finally 6199 Xpath 'v' 6200 " ... but break loop for caught interrupt exception, 6201 " or discard interrupt and break loop if $VIMNOINTTHROW 6202 break 6203 endtry 6204 endwhile 6205 catch /.*/ 6206 call assert_report('should not get here') 6207 endtry 6208 Xpath 'w' 6209 [CODE] 6210 let verify =<< trim [CODE] 6211 call assert_equal('gahibjklcmnodpqerstfuvw', g:Xpath) 6212 [CODE] 6213 call RunInNewVim(test, verify) 6214endfunc 6215 6216"------------------------------------------------------------------------------- 6217" Test 85: Error exceptions in autocommands for I/O command events {{{1 6218" 6219" When an I/O command is inside :try/:endtry, autocommands to be 6220" executed after it should be skipped on an error (exception) in the 6221" command itself or in autocommands to be executed before the command. 6222" In the latter case, the I/O command should not be executed either. 6223" Example 1: BufWritePre, :write, BufWritePost 6224" Example 2: FileReadPre, :read, FileReadPost. 6225"------------------------------------------------------------------------------- 6226 6227func Test_autocmd_error_io_exception() 6228 let test =<< trim [CODE] 6229 " Remove the autocommands for the events specified as arguments in all used 6230 " autogroups. 6231 func Delete_autocommands(...) 6232 let augfile = tempname() 6233 while 1 6234 try 6235 exec "redir >" . augfile 6236 aug 6237 redir END 6238 exec "edit" augfile 6239 g/^$/d 6240 norm G$ 6241 let wrap = "w" 6242 while search('\%( \|^\)\@<=.\{-}\%( \)\@=', wrap) > 0 6243 let wrap = "W" 6244 exec "norm y/ \n" 6245 let argno = 1 6246 while argno <= a:0 6247 exec "au!" escape(@", " ") a:{argno} 6248 let argno = argno + 1 6249 endwhile 6250 endwhile 6251 catch /.*/ 6252 finally 6253 bwipeout! 6254 call delete(augfile) 6255 break 6256 endtry 6257 endwhile 6258 endfunc 6259 6260 call Delete_autocommands("BufWritePre", "BufWritePost") 6261 6262 while 1 6263 try 6264 try 6265 let post = 0 6266 aug TMP 6267 au! BufWritePost * let post = 1 6268 aug END 6269 write /n/o/n/e/x/i/s/t/e/n/t 6270 catch /^Vim(write):/ 6271 Xpath 'a' 6272 call assert_match("E212: Can't open file for writing", v:exception) 6273 finally 6274 Xpath 'b' 6275 call assert_equal(0, post) 6276 au! TMP 6277 aug! TMP 6278 endtry 6279 catch /.*/ 6280 call assert_report('should not get here') 6281 finally 6282 Xpath 'c' 6283 break 6284 endtry 6285 endwhile 6286 6287 while 1 6288 try 6289 try 6290 let post = 0 6291 aug TMP 6292 au! BufWritePre * asdf 6293 au! BufWritePost * let post = 1 6294 aug END 6295 let tmpfile = tempname() 6296 exec "write" tmpfile 6297 catch /^Vim\((write)\)\=:/ 6298 Xpath 'd' 6299 call assert_match('E492: Not an editor command', v:exception) 6300 finally 6301 Xpath 'e' 6302 if filereadable(tmpfile) 6303 call assert_report('should not get here') 6304 endif 6305 call assert_equal(0, post) 6306 au! TMP 6307 aug! TMP 6308 endtry 6309 catch /.*/ 6310 call assert_report('should not get here') 6311 finally 6312 Xpath 'f' 6313 break 6314 endtry 6315 endwhile 6316 6317 call delete(tmpfile) 6318 6319 call Delete_autocommands("BufWritePre", "BufWritePost", 6320 \ "BufReadPre", "BufReadPost", "FileReadPre", "FileReadPost") 6321 6322 while 1 6323 try 6324 try 6325 let post = 0 6326 aug TMP 6327 au! FileReadPost * let post = 1 6328 aug END 6329 let caught = 0 6330 read /n/o/n/e/x/i/s/t/e/n/t 6331 catch /^Vim(read):/ 6332 Xpath 'g' 6333 call assert_match("E484: Can't open file", v:exception) 6334 finally 6335 Xpath 'h' 6336 call assert_equal(0, post) 6337 au! TMP 6338 aug! TMP 6339 endtry 6340 catch /.*/ 6341 call assert_report('should not get here') 6342 finally 6343 Xpath 'i' 6344 break 6345 endtry 6346 endwhile 6347 6348 while 1 6349 try 6350 let infile = tempname() 6351 let tmpfile = tempname() 6352 call writefile(["XYZ"], infile) 6353 exec "edit" tmpfile 6354 try 6355 Xpath 'j' 6356 try 6357 let post = 0 6358 aug TMP 6359 au! FileReadPre * asdf 6360 au! FileReadPost * let post = 1 6361 aug END 6362 exec "0read" infile 6363 catch /^Vim\((read)\)\=:/ 6364 Xpath 'k' 6365 call assert_match('E492: Not an editor command', v:exception) 6366 finally 6367 Xpath 'l' 6368 if getline("1") == "XYZ" 6369 call assert_report('should not get here') 6370 endif 6371 call assert_equal(0, post) 6372 au! TMP 6373 aug! TMP 6374 endtry 6375 finally 6376 Xpath 'm' 6377 bwipeout! 6378 endtry 6379 catch /.*/ 6380 call assert_report('should not get here') 6381 finally 6382 Xpath 'n' 6383 break 6384 endtry 6385 endwhile 6386 6387 call delete(infile) 6388 call delete(tmpfile) 6389 [CODE] 6390 let verify =<< trim [CODE] 6391 call assert_equal('abcdefghijklmn', g:Xpath) 6392 [CODE] 6393 call RunInNewVim(test, verify) 6394endfunc 6395 6396"------------------------------------------------------------------------------- 6397" Test 87 using (expr) ? funcref : funcref {{{1 6398" 6399" Vim needs to correctly parse the funcref and even when it does 6400" not execute the funcref, it needs to consume the trailing () 6401"------------------------------------------------------------------------------- 6402 6403func Add2(x1, x2) 6404 return a:x1 + a:x2 6405endfu 6406 6407func GetStr() 6408 return "abcdefghijklmnopqrstuvwxyp" 6409endfu 6410 6411func Test_funcref_with_condexpr() 6412 call assert_equal(5, function('Add2')(2,3)) 6413 6414 call assert_equal(3, 1 ? function('Add2')(1,2) : function('Add2')(2,3)) 6415 call assert_equal(5, 0 ? function('Add2')(1,2) : function('Add2')(2,3)) 6416 " Make sure, GetStr() still works. 6417 call assert_equal('abcdefghijk', GetStr()[0:10]) 6418endfunc 6419 6420" Test 90: Recognizing {} in variable name. {{{1 6421"------------------------------------------------------------------------------- 6422 6423func Test_curlies() 6424 let s:var = 66 6425 let ns = 's' 6426 call assert_equal(66, {ns}:var) 6427 6428 let g:a = {} 6429 let g:b = 't' 6430 let g:a[g:b] = 77 6431 call assert_equal(77, g:a['t']) 6432endfunc 6433 6434"------------------------------------------------------------------------------- 6435" Test 91: using type(). {{{1 6436"------------------------------------------------------------------------------- 6437 6438func Test_type() 6439 call assert_equal(0, type(0)) 6440 call assert_equal(1, type("")) 6441 call assert_equal(2, type(function("tr"))) 6442 call assert_equal(2, type(function("tr", [8]))) 6443 call assert_equal(3, type([])) 6444 call assert_equal(4, type({})) 6445 if has('float') 6446 call assert_equal(5, type(0.0)) 6447 endif 6448 call assert_equal(6, type(v:false)) 6449 call assert_equal(6, type(v:true)) 6450 call assert_equal(7, type(v:none)) 6451 call assert_equal(7, type(v:null)) 6452 call assert_equal(8, v:t_job) 6453 call assert_equal(9, v:t_channel) 6454 call assert_equal(v:t_number, type(0)) 6455 call assert_equal(v:t_string, type("")) 6456 call assert_equal(v:t_func, type(function("tr"))) 6457 call assert_equal(v:t_func, type(function("tr", [8]))) 6458 call assert_equal(v:t_list, type([])) 6459 call assert_equal(v:t_dict, type({})) 6460 if has('float') 6461 call assert_equal(v:t_float, type(0.0)) 6462 endif 6463 call assert_equal(v:t_bool, type(v:false)) 6464 call assert_equal(v:t_bool, type(v:true)) 6465 call assert_equal(v:t_none, type(v:none)) 6466 call assert_equal(v:t_none, type(v:null)) 6467 call assert_equal(v:t_string, type(test_null_string())) 6468 call assert_equal(v:t_func, type(test_null_function())) 6469 call assert_equal(v:t_func, type(test_null_partial())) 6470 call assert_equal(v:t_list, type(test_null_list())) 6471 call assert_equal(v:t_dict, type(test_null_dict())) 6472 if has('job') 6473 call assert_equal(v:t_job, type(test_null_job())) 6474 endif 6475 if has('channel') 6476 call assert_equal(v:t_channel, type(test_null_channel())) 6477 endif 6478 call assert_equal(v:t_blob, type(test_null_blob())) 6479 6480 call assert_fails("call type(test_void())", 'E685:') 6481 call assert_fails("call type(test_unknown())", 'E685:') 6482 6483 call assert_equal(0, 0 + v:false) 6484 call assert_equal(1, 0 + v:true) 6485 call assert_equal(0, 0 + v:none) 6486 call assert_equal(0, 0 + v:null) 6487 6488 call assert_equal('v:false', '' . v:false) 6489 call assert_equal('v:true', '' . v:true) 6490 call assert_equal('v:none', '' . v:none) 6491 call assert_equal('v:null', '' . v:null) 6492 6493 call assert_true(v:false == 0) 6494 call assert_false(v:false != 0) 6495 call assert_true(v:true == 1) 6496 call assert_false(v:true != 1) 6497 call assert_false(v:true == v:false) 6498 call assert_true(v:true != v:false) 6499 6500 call assert_true(v:null == 0) 6501 call assert_false(v:null != 0) 6502 call assert_true(v:none == 0) 6503 call assert_false(v:none != 0) 6504 6505 call assert_true(v:false is v:false) 6506 call assert_true(v:true is v:true) 6507 call assert_true(v:none is v:none) 6508 call assert_true(v:null is v:null) 6509 6510 call assert_false(v:false isnot v:false) 6511 call assert_false(v:true isnot v:true) 6512 call assert_false(v:none isnot v:none) 6513 call assert_false(v:null isnot v:null) 6514 6515 call assert_false(v:false is 0) 6516 call assert_false(v:true is 1) 6517 call assert_false(v:true is v:false) 6518 call assert_false(v:none is 0) 6519 call assert_false(v:null is 0) 6520 call assert_false(v:null is v:none) 6521 6522 call assert_true(v:false isnot 0) 6523 call assert_true(v:true isnot 1) 6524 call assert_true(v:true isnot v:false) 6525 call assert_true(v:none isnot 0) 6526 call assert_true(v:null isnot 0) 6527 call assert_true(v:null isnot v:none) 6528 6529 call assert_equal(v:false, eval(string(v:false))) 6530 call assert_equal(v:true, eval(string(v:true))) 6531 call assert_equal(v:none, eval(string(v:none))) 6532 call assert_equal(v:null, eval(string(v:null))) 6533 6534 call assert_equal(v:false, copy(v:false)) 6535 call assert_equal(v:true, copy(v:true)) 6536 call assert_equal(v:none, copy(v:none)) 6537 call assert_equal(v:null, copy(v:null)) 6538 6539 call assert_equal([v:false], deepcopy([v:false])) 6540 call assert_equal([v:true], deepcopy([v:true])) 6541 call assert_equal([v:none], deepcopy([v:none])) 6542 call assert_equal([v:null], deepcopy([v:null])) 6543 6544 call assert_true(empty(v:false)) 6545 call assert_false(empty(v:true)) 6546 call assert_true(empty(v:null)) 6547 call assert_true(empty(v:none)) 6548 6549 func ChangeYourMind() 6550 try 6551 return v:true 6552 finally 6553 return 'something else' 6554 endtry 6555 endfunc 6556 6557 call ChangeYourMind() 6558endfunc 6559 6560"------------------------------------------------------------------------------- 6561" Test 92: skipping code {{{1 6562"------------------------------------------------------------------------------- 6563 6564func Test_skip() 6565 let Fn = function('Test_type') 6566 call assert_false(0 && Fn[1]) 6567 call assert_false(0 && string(Fn)) 6568 call assert_false(0 && len(Fn)) 6569 let l = [] 6570 call assert_false(0 && l[1]) 6571 call assert_false(0 && string(l)) 6572 call assert_false(0 && len(l)) 6573 let f = 1.0 6574 call assert_false(0 && f[1]) 6575 call assert_false(0 && string(f)) 6576 call assert_false(0 && len(f)) 6577 let sp = v:null 6578 call assert_false(0 && sp[1]) 6579 call assert_false(0 && string(sp)) 6580 call assert_false(0 && len(sp)) 6581 6582endfunc 6583 6584"------------------------------------------------------------------------------- 6585" Test 93: :echo and string() {{{1 6586"------------------------------------------------------------------------------- 6587 6588func Test_echo_and_string() 6589 " String 6590 let a = 'foo bar' 6591 redir => result 6592 echo a 6593 echo string(a) 6594 redir END 6595 let l = split(result, "\n") 6596 call assert_equal(["foo bar", 6597 \ "'foo bar'"], l) 6598 6599 " Float 6600 if has('float') 6601 let a = -1.2e0 6602 redir => result 6603 echo a 6604 echo string(a) 6605 redir END 6606 let l = split(result, "\n") 6607 call assert_equal(["-1.2", 6608 \ "-1.2"], l) 6609 endif 6610 6611 " Funcref 6612 redir => result 6613 echo function('string') 6614 echo string(function('string')) 6615 redir END 6616 let l = split(result, "\n") 6617 call assert_equal(["string", 6618 \ "function('string')"], l) 6619 6620 " Recursive dictionary 6621 let a = {} 6622 let a["a"] = a 6623 redir => result 6624 echo a 6625 echo string(a) 6626 redir END 6627 let l = split(result, "\n") 6628 call assert_equal(["{'a': {...}}", 6629 \ "{'a': {...}}"], l) 6630 6631 " Recursive list 6632 let a = [0] 6633 let a[0] = a 6634 redir => result 6635 echo a 6636 echo string(a) 6637 redir END 6638 let l = split(result, "\n") 6639 call assert_equal(["[[...]]", 6640 \ "[[...]]"], l) 6641 6642 " Empty dictionaries in a list 6643 let a = {} 6644 redir => result 6645 echo [a, a, a] 6646 echo string([a, a, a]) 6647 redir END 6648 let l = split(result, "\n") 6649 call assert_equal(["[{}, {}, {}]", 6650 \ "[{}, {}, {}]"], l) 6651 6652 " Empty dictionaries in a dictionary 6653 let a = {} 6654 let b = {"a": a, "b": a} 6655 redir => result 6656 echo b 6657 echo string(b) 6658 redir END 6659 let l = split(result, "\n") 6660 call assert_equal(["{'a': {}, 'b': {}}", 6661 \ "{'a': {}, 'b': {}}"], l) 6662 6663 " Empty lists in a list 6664 let a = [] 6665 redir => result 6666 echo [a, a, a] 6667 echo string([a, a, a]) 6668 redir END 6669 let l = split(result, "\n") 6670 call assert_equal(["[[], [], []]", 6671 \ "[[], [], []]"], l) 6672 6673 " Empty lists in a dictionary 6674 let a = [] 6675 let b = {"a": a, "b": a} 6676 redir => result 6677 echo b 6678 echo string(b) 6679 redir END 6680 let l = split(result, "\n") 6681 call assert_equal(["{'a': [], 'b': []}", 6682 \ "{'a': [], 'b': []}"], l) 6683 6684 " Dictionaries in a list 6685 let a = {"one": "yes", "two": "yes", "three": "yes"} 6686 redir => result 6687 echo [a, a, a] 6688 echo string([a, a, a]) 6689 redir END 6690 let l = split(result, "\n") 6691 call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...}, {...}]", 6692 \ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}]"], l) 6693 6694 " Dictionaries in a dictionary 6695 let a = {"one": "yes", "two": "yes", "three": "yes"} 6696 let b = {"a": a, "b": a} 6697 redir => result 6698 echo b 6699 echo string(b) 6700 redir END 6701 let l = split(result, "\n") 6702 call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {...}}", 6703 \ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l) 6704 6705 " Lists in a list 6706 let a = [1, 2, 3] 6707 redir => result 6708 echo [a, a, a] 6709 echo string([a, a, a]) 6710 redir END 6711 let l = split(result, "\n") 6712 call assert_equal(["[[1, 2, 3], [...], [...]]", 6713 \ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l) 6714 6715 " Lists in a dictionary 6716 let a = [1, 2, 3] 6717 let b = {"a": a, "b": a} 6718 redir => result 6719 echo b 6720 echo string(b) 6721 redir END 6722 let l = split(result, "\n") 6723 call assert_equal(["{'a': [1, 2, 3], 'b': [...]}", 6724 \ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l) 6725 6726 call assert_fails('echo &:', 'E112:') 6727 call assert_fails('echo &g:', 'E112:') 6728 call assert_fails('echo &l:', 'E112:') 6729 6730endfunc 6731 6732"------------------------------------------------------------------------------- 6733" Test 94: 64-bit Numbers {{{1 6734"------------------------------------------------------------------------------- 6735 6736func Test_num64() 6737 call assert_notequal( 4294967296, 0) 6738 call assert_notequal(-4294967296, 0) 6739 call assert_equal( 4294967296, 0xFFFFffff + 1) 6740 call assert_equal(-4294967296, -0xFFFFffff - 1) 6741 6742 call assert_equal( 9223372036854775807, 1 / 0) 6743 call assert_equal(-9223372036854775807, -1 / 0) 6744 call assert_equal(-9223372036854775807 - 1, 0 / 0) 6745 6746 if has('float') 6747 call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150)) 6748 call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150)) 6749 endif 6750 6751 let rng = range(0xFFFFffff, 0x100000001) 6752 call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng) 6753 call assert_equal(0x100000001, max(rng)) 6754 call assert_equal(0xFFFFffff, min(rng)) 6755 call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N')) 6756endfunc 6757 6758"------------------------------------------------------------------------------- 6759" Test 95: lines of :append, :change, :insert {{{1 6760"------------------------------------------------------------------------------- 6761 6762function! DefineFunction(name, body) 6763 let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n") 6764 exec func 6765endfunction 6766 6767func Test_script_lines() 6768 " :append 6769 try 6770 call DefineFunction('T_Append', [ 6771 \ 'append', 6772 \ 'py <<EOS', 6773 \ '.', 6774 \ ]) 6775 catch 6776 call assert_report("Can't define function") 6777 endtry 6778 try 6779 call DefineFunction('T_Append', [ 6780 \ 'append', 6781 \ 'abc', 6782 \ ]) 6783 call assert_report("Shouldn't be able to define function") 6784 catch 6785 call assert_exception('Vim(function):E126: Missing :endfunction') 6786 endtry 6787 6788 " :change 6789 try 6790 call DefineFunction('T_Change', [ 6791 \ 'change', 6792 \ 'py <<EOS', 6793 \ '.', 6794 \ ]) 6795 catch 6796 call assert_report("Can't define function") 6797 endtry 6798 try 6799 call DefineFunction('T_Change', [ 6800 \ 'change', 6801 \ 'abc', 6802 \ ]) 6803 call assert_report("Shouldn't be able to define function") 6804 catch 6805 call assert_exception('Vim(function):E126: Missing :endfunction') 6806 endtry 6807 6808 " :insert 6809 try 6810 call DefineFunction('T_Insert', [ 6811 \ 'insert', 6812 \ 'py <<EOS', 6813 \ '.', 6814 \ ]) 6815 catch 6816 call assert_report("Can't define function") 6817 endtry 6818 try 6819 call DefineFunction('T_Insert', [ 6820 \ 'insert', 6821 \ 'abc', 6822 \ ]) 6823 call assert_report("Shouldn't be able to define function") 6824 catch 6825 call assert_exception('Vim(function):E126: Missing :endfunction') 6826 endtry 6827endfunc 6828 6829"------------------------------------------------------------------------------- 6830" Test 96: line continuation {{{1 6831" 6832" Undefined behavior was detected by ubsan with line continuation 6833" after an empty line. 6834"------------------------------------------------------------------------------- 6835func Test_script_emty_line_continuation() 6836 6837 \ 6838endfunc 6839 6840"------------------------------------------------------------------------------- 6841" Test 97: bitwise functions {{{1 6842"------------------------------------------------------------------------------- 6843func Test_bitwise_functions() 6844 " and 6845 call assert_equal(127, and(127, 127)) 6846 call assert_equal(16, and(127, 16)) 6847 eval 127->and(16)->assert_equal(16) 6848 call assert_equal(0, and(127, 128)) 6849 call assert_fails("call and([], 1)", 'E745:') 6850 call assert_fails("call and({}, 1)", 'E728:') 6851 if has('float') 6852 call assert_fails("call and(1.0, 1)", 'E805:') 6853 call assert_fails("call and(1, 1.0)", 'E805:') 6854 endif 6855 call assert_fails("call and(1, [])", 'E745:') 6856 call assert_fails("call and(1, {})", 'E728:') 6857 " or 6858 call assert_equal(23, or(16, 7)) 6859 call assert_equal(15, or(8, 7)) 6860 eval 8->or(7)->assert_equal(15) 6861 call assert_equal(123, or(0, 123)) 6862 call assert_fails("call or([], 1)", 'E745:') 6863 call assert_fails("call or({}, 1)", 'E728:') 6864 if has('float') 6865 call assert_fails("call or(1.0, 1)", 'E805:') 6866 call assert_fails("call or(1, 1.0)", 'E805:') 6867 endif 6868 call assert_fails("call or(1, [])", 'E745:') 6869 call assert_fails("call or(1, {})", 'E728:') 6870 " xor 6871 call assert_equal(0, xor(127, 127)) 6872 call assert_equal(111, xor(127, 16)) 6873 eval 127->xor(16)->assert_equal(111) 6874 call assert_equal(255, xor(127, 128)) 6875 if has('float') 6876 call assert_fails("call xor(1.0, 1)", 'E805:') 6877 call assert_fails("call xor(1, 1.0)", 'E805:') 6878 endif 6879 call assert_fails("call xor([], 1)", 'E745:') 6880 call assert_fails("call xor({}, 1)", 'E728:') 6881 call assert_fails("call xor(1, [])", 'E745:') 6882 call assert_fails("call xor(1, {})", 'E728:') 6883 " invert 6884 call assert_equal(65408, and(invert(127), 65535)) 6885 eval 127->invert()->and(65535)->assert_equal(65408) 6886 call assert_equal(65519, and(invert(16), 65535)) 6887 call assert_equal(65407, and(invert(128), 65535)) 6888 if has('float') 6889 call assert_fails("call invert(1.0)", 'E805:') 6890 endif 6891 call assert_fails("call invert([])", 'E745:') 6892 call assert_fails("call invert({})", 'E728:') 6893endfunc 6894 6895" Test using bang after user command {{{1 6896func Test_user_command_with_bang() 6897 command -bang Nieuw let nieuw = 1 6898 Ni! 6899 call assert_equal(1, nieuw) 6900 unlet nieuw 6901 delcommand Nieuw 6902endfunc 6903 6904func Test_script_expand_sfile() 6905 let lines =<< trim END 6906 func s:snr() 6907 return expand('<sfile>') 6908 endfunc 6909 let g:result = s:snr() 6910 END 6911 call writefile(lines, 'Xexpand') 6912 source Xexpand 6913 call assert_match('<SNR>\d\+_snr', g:result) 6914 source Xexpand 6915 call assert_match('<SNR>\d\+_snr', g:result) 6916 6917 call delete('Xexpand') 6918 unlet g:result 6919endfunc 6920 6921func Test_compound_assignment_operators() 6922 " Test for number 6923 let x = 1 6924 let x += 10 6925 call assert_equal(11, x) 6926 let x -= 5 6927 call assert_equal(6, x) 6928 let x *= 4 6929 call assert_equal(24, x) 6930 let x /= 3 6931 call assert_equal(8, x) 6932 let x %= 3 6933 call assert_equal(2, x) 6934 let x .= 'n' 6935 call assert_equal('2n', x) 6936 6937 " Test special cases: division or modulus with 0. 6938 let x = 1 6939 let x /= 0 6940 call assert_equal(0x7FFFFFFFFFFFFFFF, x) 6941 6942 let x = -1 6943 let x /= 0 6944 call assert_equal(-0x7FFFFFFFFFFFFFFF, x) 6945 6946 let x = 0 6947 let x /= 0 6948 call assert_equal(-0x7FFFFFFFFFFFFFFF - 1, x) 6949 6950 let x = 1 6951 let x %= 0 6952 call assert_equal(0, x) 6953 6954 let x = -1 6955 let x %= 0 6956 call assert_equal(0, x) 6957 6958 let x = 0 6959 let x %= 0 6960 call assert_equal(0, x) 6961 6962 " Test for string 6963 let x = 'str' 6964 let x .= 'ing' 6965 call assert_equal('string', x) 6966 let x += 1 6967 call assert_equal(1, x) 6968 6969 if has('float') 6970 " Test for float 6971 let x -= 1.5 6972 call assert_equal(-0.5, x) 6973 let x = 0.5 6974 let x += 4.5 6975 call assert_equal(5.0, x) 6976 let x -= 1.5 6977 call assert_equal(3.5, x) 6978 let x *= 3.0 6979 call assert_equal(10.5, x) 6980 let x /= 2.5 6981 call assert_equal(4.2, x) 6982 call assert_fails('let x %= 0.5', 'E734') 6983 call assert_fails('let x .= "f"', 'E734') 6984 let x = !3.14 6985 call assert_equal(0.0, x) 6986 6987 " integer and float operations 6988 let x = 1 6989 let x *= 2.1 6990 call assert_equal(2.1, x) 6991 let x = 1 6992 let x /= 0.25 6993 call assert_equal(4.0, x) 6994 let x = 1 6995 call assert_fails('let x %= 0.25', 'E734:') 6996 let x = 1 6997 call assert_fails('let x .= 0.25', 'E734:') 6998 let x = 1.0 6999 call assert_fails('let x += [1.1]', 'E734:') 7000 endif 7001 7002 " Test for environment variable 7003 let $FOO = 1 7004 call assert_fails('let $FOO += 1', 'E734') 7005 call assert_fails('let $FOO -= 1', 'E734') 7006 call assert_fails('let $FOO *= 1', 'E734') 7007 call assert_fails('let $FOO /= 1', 'E734') 7008 call assert_fails('let $FOO %= 1', 'E734') 7009 let $FOO .= 's' 7010 call assert_equal('1s', $FOO) 7011 unlet $FOO 7012 7013 " Test for option variable (type: number) 7014 let &scrolljump = 1 7015 let &scrolljump += 5 7016 call assert_equal(6, &scrolljump) 7017 let &scrolljump -= 2 7018 call assert_equal(4, &scrolljump) 7019 let &scrolljump *= 3 7020 call assert_equal(12, &scrolljump) 7021 let &scrolljump /= 2 7022 call assert_equal(6, &scrolljump) 7023 let &scrolljump %= 5 7024 call assert_equal(1, &scrolljump) 7025 call assert_fails('let &scrolljump .= "j"', 'E734') 7026 set scrolljump&vim 7027 7028 " Test for register 7029 let @/ = 1 7030 call assert_fails('let @/ += 1', 'E734') 7031 call assert_fails('let @/ -= 1', 'E734') 7032 call assert_fails('let @/ *= 1', 'E734') 7033 call assert_fails('let @/ /= 1', 'E734') 7034 call assert_fails('let @/ %= 1', 'E734') 7035 let @/ .= 's' 7036 call assert_equal('1s', @/) 7037 let @/ = '' 7038endfunc 7039 7040func Test_unlet_env() 7041 let $TESTVAR = 'yes' 7042 call assert_equal('yes', $TESTVAR) 7043 call assert_fails('lockvar $TESTVAR', 'E940') 7044 call assert_fails('unlockvar $TESTVAR', 'E940') 7045 call assert_equal('yes', $TESTVAR) 7046 if 0 7047 unlet $TESTVAR 7048 endif 7049 call assert_equal('yes', $TESTVAR) 7050 unlet $TESTVAR 7051 call assert_equal('', $TESTVAR) 7052endfunc 7053 7054func Test_refcount() 7055 " Immediate values 7056 call assert_equal(-1, test_refcount(1)) 7057 call assert_equal(-1, test_refcount('s')) 7058 call assert_equal(-1, test_refcount(v:true)) 7059 call assert_equal(0, test_refcount([])) 7060 call assert_equal(0, test_refcount({})) 7061 call assert_equal(0, test_refcount(0zff)) 7062 call assert_equal(0, test_refcount({-> line('.')})) 7063 if has('float') 7064 call assert_equal(-1, test_refcount(0.1)) 7065 endif 7066 if has('job') 7067 call assert_equal(0, test_refcount(job_start([&shell, &shellcmdflag, 'echo .']))) 7068 endif 7069 7070 " No refcount types 7071 let x = 1 7072 call assert_equal(-1, test_refcount(x)) 7073 let x = 's' 7074 call assert_equal(-1, test_refcount(x)) 7075 let x = v:true 7076 call assert_equal(-1, test_refcount(x)) 7077 if has('float') 7078 let x = 0.1 7079 call assert_equal(-1, test_refcount(x)) 7080 endif 7081 7082 " Check refcount 7083 let x = [] 7084 call assert_equal(1, test_refcount(x)) 7085 7086 let x = {} 7087 call assert_equal(1, x->test_refcount()) 7088 7089 let x = 0zff 7090 call assert_equal(1, test_refcount(x)) 7091 7092 let X = {-> line('.')} 7093 call assert_equal(1, test_refcount(X)) 7094 let Y = X 7095 call assert_equal(2, test_refcount(X)) 7096 7097 if has('job') 7098 let job = job_start([&shell, &shellcmdflag, 'echo .']) 7099 call assert_equal(1, test_refcount(job)) 7100 call assert_equal(1, test_refcount(job_getchannel(job))) 7101 call assert_equal(1, test_refcount(job)) 7102 endif 7103 7104 " Function arguments, copying and unassigning 7105 func ExprCheck(x, i) 7106 let i = a:i + 1 7107 call assert_equal(i, test_refcount(a:x)) 7108 let Y = a:x 7109 call assert_equal(i + 1, test_refcount(a:x)) 7110 call assert_equal(test_refcount(a:x), test_refcount(Y)) 7111 let Y = 0 7112 call assert_equal(i, test_refcount(a:x)) 7113 endfunc 7114 call ExprCheck([], 0) 7115 call ExprCheck({}, 0) 7116 call ExprCheck(0zff, 0) 7117 call ExprCheck({-> line('.')}, 0) 7118 if has('job') 7119 call ExprCheck(job, 1) 7120 call ExprCheck(job_getchannel(job), 1) 7121 call job_stop(job) 7122 endif 7123 delfunc ExprCheck 7124 7125 " Regarding function 7126 func Func(x) abort 7127 call assert_equal(2, test_refcount(function('Func'))) 7128 call assert_equal(0, test_refcount(funcref('Func'))) 7129 endfunc 7130 call assert_equal(1, test_refcount(function('Func'))) 7131 call assert_equal(0, test_refcount(function('Func', [1]))) 7132 call assert_equal(0, test_refcount(funcref('Func'))) 7133 call assert_equal(0, test_refcount(funcref('Func', [1]))) 7134 let X = function('Func') 7135 let Y = X 7136 call assert_equal(1, test_refcount(X)) 7137 let X = function('Func', [1]) 7138 let Y = X 7139 call assert_equal(2, test_refcount(X)) 7140 let X = funcref('Func') 7141 let Y = X 7142 call assert_equal(2, test_refcount(X)) 7143 let X = funcref('Func', [1]) 7144 let Y = X 7145 call assert_equal(2, test_refcount(X)) 7146 unlet X 7147 unlet Y 7148 call Func(1) 7149 delfunc Func 7150 7151 " Function with dict 7152 func DictFunc() dict 7153 call assert_equal(3, test_refcount(self)) 7154 endfunc 7155 let d = {'Func': function('DictFunc')} 7156 call assert_equal(1, test_refcount(d)) 7157 call assert_equal(0, test_refcount(d.Func)) 7158 call d.Func() 7159 unlet d 7160 delfunc DictFunc 7161endfunc 7162 7163" Test for missing :endif, :endfor, :endwhile and :endtry {{{1 7164func Test_missing_end() 7165 call writefile(['if 2 > 1', 'echo ">"'], 'Xscript') 7166 call assert_fails('source Xscript', 'E171:') 7167 call writefile(['for i in range(5)', 'echo i'], 'Xscript') 7168 call assert_fails('source Xscript', 'E170:') 7169 call writefile(['while v:true', 'echo "."'], 'Xscript') 7170 call assert_fails('source Xscript', 'E170:') 7171 call writefile(['try', 'echo "."'], 'Xscript') 7172 call assert_fails('source Xscript', 'E600:') 7173 call delete('Xscript') 7174 7175 " Using endfor with :while 7176 let caught_e732 = 0 7177 try 7178 while v:true 7179 endfor 7180 catch /E732:/ 7181 let caught_e732 = 1 7182 endtry 7183 call assert_equal(1, caught_e732) 7184 7185 " Using endwhile with :for 7186 let caught_e733 = 0 7187 try 7188 for i in range(1) 7189 endwhile 7190 catch /E733:/ 7191 let caught_e733 = 1 7192 endtry 7193 call assert_equal(1, caught_e733) 7194 7195 " Using endfunc with :if 7196 call assert_fails('exe "if 1 | endfunc | endif"', 'E193:') 7197 7198 " Missing 'in' in a :for statement 7199 call assert_fails('for i range(1) | endfor', 'E690:') 7200 7201 " Incorrect number of variables in for 7202 call assert_fails('for [i,] in range(3) | endfor', 'E475:') 7203endfunc 7204 7205" Test for deep nesting of if/for/while/try statements {{{1 7206func Test_deep_nest() 7207 CheckRunVimInTerminal 7208 7209 let lines =<< trim [SCRIPT] 7210 " Deep nesting of if ... endif 7211 func Test1() 7212 let @a = join(repeat(['if v:true'], 51), "\n") 7213 let @a ..= "\n" 7214 let @a ..= join(repeat(['endif'], 51), "\n") 7215 @a 7216 let @a = '' 7217 endfunc 7218 7219 " Deep nesting of for ... endfor 7220 func Test2() 7221 let @a = join(repeat(['for i in [1]'], 51), "\n") 7222 let @a ..= "\n" 7223 let @a ..= join(repeat(['endfor'], 51), "\n") 7224 @a 7225 let @a = '' 7226 endfunc 7227 7228 " Deep nesting of while ... endwhile 7229 func Test3() 7230 let @a = join(repeat(['while v:true'], 51), "\n") 7231 let @a ..= "\n" 7232 let @a ..= join(repeat(['endwhile'], 51), "\n") 7233 @a 7234 let @a = '' 7235 endfunc 7236 7237 " Deep nesting of try ... endtry 7238 func Test4() 7239 let @a = join(repeat(['try'], 51), "\n") 7240 let @a ..= "\necho v:true\n" 7241 let @a ..= join(repeat(['endtry'], 51), "\n") 7242 @a 7243 let @a = '' 7244 endfunc 7245 7246 " Deep nesting of function ... endfunction 7247 func Test5() 7248 let @a = join(repeat(['function X()'], 51), "\n") 7249 let @a ..= "\necho v:true\n" 7250 let @a ..= join(repeat(['endfunction'], 51), "\n") 7251 @a 7252 let @a = '' 7253 endfunc 7254 [SCRIPT] 7255 call writefile(lines, 'Xscript') 7256 7257 let buf = RunVimInTerminal('-S Xscript', {'rows': 6}) 7258 7259 " Deep nesting of if ... endif 7260 call term_sendkeys(buf, ":call Test1()\n") 7261 call TermWait(buf) 7262 call WaitForAssert({-> assert_match('^E579:', term_getline(buf, 5))}) 7263 7264 " Deep nesting of for ... endfor 7265 call term_sendkeys(buf, ":call Test2()\n") 7266 call TermWait(buf) 7267 call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))}) 7268 7269 " Deep nesting of while ... endwhile 7270 call term_sendkeys(buf, ":call Test3()\n") 7271 call TermWait(buf) 7272 call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))}) 7273 7274 " Deep nesting of try ... endtry 7275 call term_sendkeys(buf, ":call Test4()\n") 7276 call TermWait(buf) 7277 call WaitForAssert({-> assert_match('^E601:', term_getline(buf, 5))}) 7278 7279 " Deep nesting of function ... endfunction 7280 call term_sendkeys(buf, ":call Test5()\n") 7281 call TermWait(buf) 7282 call WaitForAssert({-> assert_match('^E1058:', term_getline(buf, 4))}) 7283 call term_sendkeys(buf, "\<C-C>\n") 7284 call TermWait(buf) 7285 7286 "let l = '' 7287 "for i in range(1, 6) 7288 " let l ..= term_getline(buf, i) . "\n" 7289 "endfor 7290 "call assert_report(l) 7291 7292 call StopVimInTerminal(buf) 7293 call delete('Xscript') 7294endfunc 7295 7296" Test for errors in converting to float from various types {{{1 7297func Test_float_conversion_errors() 7298 if has('float') 7299 call assert_fails('let x = 4.0 % 2.0', 'E804') 7300 call assert_fails('echo 1.1[0]', 'E806') 7301 call assert_fails('echo sort([function("min"), 1], "f")', 'E891:') 7302 call assert_fails('echo 3.2 == "vim"', 'E892:') 7303 call assert_fails('echo sort([[], 1], "f")', 'E893:') 7304 call assert_fails('echo sort([{}, 1], "f")', 'E894:') 7305 call assert_fails('echo 3.2 == v:true', 'E362:') 7306 call assert_fails('echo 3.2 == v:none', 'E907:') 7307 endif 7308endfunc 7309 7310" invalid function names {{{1 7311func Test_invalid_function_names() 7312 " function name not starting with capital 7313 let caught_e128 = 0 7314 try 7315 func! g:test() 7316 echo "test" 7317 endfunc 7318 catch /E128:/ 7319 let caught_e128 = 1 7320 endtry 7321 call assert_equal(1, caught_e128) 7322 7323 " function name includes a colon 7324 let caught_e884 = 0 7325 try 7326 func! b:test() 7327 echo "test" 7328 endfunc 7329 catch /E884:/ 7330 let caught_e884 = 1 7331 endtry 7332 call assert_equal(1, caught_e884) 7333 7334 " function name folowed by # 7335 let caught_e128 = 0 7336 try 7337 func! test2() "# 7338 echo "test2" 7339 endfunc 7340 catch /E128:/ 7341 let caught_e128 = 1 7342 endtry 7343 call assert_equal(1, caught_e128) 7344 7345 " function name starting with/without "g:", buffer-local funcref. 7346 function! g:Foo(n) 7347 return 'called Foo(' . a:n . ')' 7348 endfunction 7349 let b:my_func = function('Foo') 7350 call assert_equal('called Foo(1)', b:my_func(1)) 7351 call assert_equal('called Foo(2)', g:Foo(2)) 7352 call assert_equal('called Foo(3)', Foo(3)) 7353 delfunc g:Foo 7354 7355 " script-local function used in Funcref must exist. 7356 let lines =<< trim END 7357 func s:Testje() 7358 return "foo" 7359 endfunc 7360 let Bar = function('s:Testje') 7361 call assert_equal(0, exists('s:Testje')) 7362 call assert_equal(1, exists('*s:Testje')) 7363 call assert_equal(1, exists('Bar')) 7364 call assert_equal(1, exists('*Bar')) 7365 END 7366 call writefile(lines, 'Xscript') 7367 source Xscript 7368 call delete('Xscript') 7369endfunc 7370 7371" substring and variable name {{{1 7372func Test_substring_var() 7373 let str = 'abcdef' 7374 let n = 3 7375 call assert_equal('def', str[n:]) 7376 call assert_equal('abcd', str[:n]) 7377 call assert_equal('d', str[n:n]) 7378 unlet n 7379 let nn = 3 7380 call assert_equal('def', str[nn:]) 7381 call assert_equal('abcd', str[:nn]) 7382 call assert_equal('d', str[nn:nn]) 7383 unlet nn 7384 let b:nn = 4 7385 call assert_equal('ef', str[b:nn:]) 7386 call assert_equal('abcde', str[:b:nn]) 7387 call assert_equal('e', str[b:nn:b:nn]) 7388 unlet b:nn 7389endfunc 7390 7391" Test using s: with a typed command {{{1 7392func Test_typed_script_var() 7393 CheckRunVimInTerminal 7394 7395 let buf = RunVimInTerminal('', {'rows': 6}) 7396 7397 " Deep nesting of if ... endif 7398 call term_sendkeys(buf, ":echo get(s:, 'foo', 'x')\n") 7399 call TermWait(buf) 7400 call WaitForAssert({-> assert_match('^E116:', term_getline(buf, 5))}) 7401 7402 call StopVimInTerminal(buf) 7403endfunc 7404 7405"------------------------------------------------------------------------------- 7406" Modelines {{{1 7407" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 7408"------------------------------------------------------------------------------- 7409