Mercurial > vim
comparison src/ex_docmd.c @ 24254:0868ac82ef18 v8.2.2668
patch 8.2.2668: Vim9: omitting "call" for "confirm()" does not give an error
Commit: https://github.com/vim/vim/commit/f49a1fcdb952ca270f108fcc27bb8ad6922e0807
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Mar 27 22:20:21 2021 +0100
patch 8.2.2668: Vim9: omitting "call" for "confirm()" does not give an error
Problem: Vim9: omitting "call" for "confirm()" does not give an error.
Solution: Do not recognize a modifier followed by "(".
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 27 Mar 2021 22:30:02 +0100 |
parents | a2e6029d354e |
children | b471a413d36a |
comparison
equal
deleted
inserted
replaced
24253:5fdc41e253e7 | 24254:0868ac82ef18 |
---|---|
2683 vim_snprintf(ex_error_buf, MSG_BUF_LEN, _(msg), arg); | 2683 vim_snprintf(ex_error_buf, MSG_BUF_LEN, _(msg), arg); |
2684 return ex_error_buf; | 2684 return ex_error_buf; |
2685 } | 2685 } |
2686 | 2686 |
2687 /* | 2687 /* |
2688 * Check for an Ex command with optional tail. | |
2689 * If there is a match advance "pp" to the argument and return TRUE. | |
2690 * If "noparen" is TRUE do not recognize the command followed by "(". | |
2691 */ | |
2692 static int | |
2693 checkforcmd_opt( | |
2694 char_u **pp, // start of command | |
2695 char *cmd, // name of command | |
2696 int len, // required length | |
2697 int noparen) | |
2698 { | |
2699 int i; | |
2700 | |
2701 for (i = 0; cmd[i] != NUL; ++i) | |
2702 if (((char_u *)cmd)[i] != (*pp)[i]) | |
2703 break; | |
2704 if (i >= len && !isalpha((*pp)[i]) | |
2705 && (*pp)[i] != '_' && (!noparen || (*pp)[i] != '(')) | |
2706 { | |
2707 *pp = skipwhite(*pp + i); | |
2708 return TRUE; | |
2709 } | |
2710 return FALSE; | |
2711 } | |
2712 | |
2713 /* | |
2714 * Check for an Ex command with optional tail. | |
2715 * If there is a match advance "pp" to the argument and return TRUE. | |
2716 */ | |
2717 int | |
2718 checkforcmd( | |
2719 char_u **pp, // start of command | |
2720 char *cmd, // name of command | |
2721 int len) // required length | |
2722 { | |
2723 return checkforcmd_opt(pp, cmd, len, FALSE); | |
2724 } | |
2725 | |
2726 /* | |
2727 * Check for an Ex command with optional tail, not followed by "(". | |
2728 * If there is a match advance "pp" to the argument and return TRUE. | |
2729 */ | |
2730 static int | |
2731 checkforcmd_noparen( | |
2732 char_u **pp, // start of command | |
2733 char *cmd, // name of command | |
2734 int len) // required length | |
2735 { | |
2736 return checkforcmd_opt(pp, cmd, len, TRUE); | |
2737 } | |
2738 | |
2739 /* | |
2688 * Parse and skip over command modifiers: | 2740 * Parse and skip over command modifiers: |
2689 * - update eap->cmd | 2741 * - update eap->cmd |
2690 * - store flags in "cmod". | 2742 * - store flags in "cmod". |
2691 * - Set ex_pressedreturn for an empty command line. | 2743 * - Set ex_pressedreturn for an empty command line. |
2692 * When "skip_only" is TRUE the global variables are not changed, except for | 2744 * When "skip_only" is TRUE the global variables are not changed, except for |
2768 } | 2820 } |
2769 | 2821 |
2770 switch (*p) | 2822 switch (*p) |
2771 { | 2823 { |
2772 // When adding an entry, also modify cmd_exists(). | 2824 // When adding an entry, also modify cmd_exists(). |
2773 case 'a': if (!checkforcmd(&eap->cmd, "aboveleft", 3)) | 2825 case 'a': if (!checkforcmd_noparen(&eap->cmd, "aboveleft", 3)) |
2774 break; | 2826 break; |
2775 cmod->cmod_split |= WSP_ABOVE; | 2827 cmod->cmod_split |= WSP_ABOVE; |
2776 continue; | 2828 continue; |
2777 | 2829 |
2778 case 'b': if (checkforcmd(&eap->cmd, "belowright", 3)) | 2830 case 'b': if (checkforcmd_noparen(&eap->cmd, "belowright", 3)) |
2779 { | 2831 { |
2780 cmod->cmod_split |= WSP_BELOW; | 2832 cmod->cmod_split |= WSP_BELOW; |
2781 continue; | 2833 continue; |
2782 } | 2834 } |
2783 if (checkforcmd(&eap->cmd, "browse", 3)) | 2835 if (checkforcmd_opt(&eap->cmd, "browse", 3, TRUE)) |
2784 { | 2836 { |
2785 #ifdef FEAT_BROWSE_CMD | 2837 #ifdef FEAT_BROWSE_CMD |
2786 cmod->cmod_flags |= CMOD_BROWSE; | 2838 cmod->cmod_flags |= CMOD_BROWSE; |
2787 #endif | 2839 #endif |
2788 continue; | 2840 continue; |
2789 } | 2841 } |
2790 if (!checkforcmd(&eap->cmd, "botright", 2)) | 2842 if (!checkforcmd_noparen(&eap->cmd, "botright", 2)) |
2791 break; | 2843 break; |
2792 cmod->cmod_split |= WSP_BOT; | 2844 cmod->cmod_split |= WSP_BOT; |
2793 continue; | 2845 continue; |
2794 | 2846 |
2795 case 'c': if (!checkforcmd(&eap->cmd, "confirm", 4)) | 2847 case 'c': if (!checkforcmd_opt(&eap->cmd, "confirm", 4, TRUE)) |
2796 break; | 2848 break; |
2797 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) | 2849 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) |
2798 cmod->cmod_flags |= CMOD_CONFIRM; | 2850 cmod->cmod_flags |= CMOD_CONFIRM; |
2799 #endif | 2851 #endif |
2800 continue; | 2852 continue; |
2801 | 2853 |
2802 case 'k': if (checkforcmd(&eap->cmd, "keepmarks", 3)) | 2854 case 'k': if (checkforcmd_noparen(&eap->cmd, "keepmarks", 3)) |
2803 { | 2855 { |
2804 cmod->cmod_flags |= CMOD_KEEPMARKS; | 2856 cmod->cmod_flags |= CMOD_KEEPMARKS; |
2805 continue; | 2857 continue; |
2806 } | 2858 } |
2807 if (checkforcmd(&eap->cmd, "keepalt", 5)) | 2859 if (checkforcmd_noparen(&eap->cmd, "keepalt", 5)) |
2808 { | 2860 { |
2809 cmod->cmod_flags |= CMOD_KEEPALT; | 2861 cmod->cmod_flags |= CMOD_KEEPALT; |
2810 continue; | 2862 continue; |
2811 } | 2863 } |
2812 if (checkforcmd(&eap->cmd, "keeppatterns", 5)) | 2864 if (checkforcmd_noparen(&eap->cmd, "keeppatterns", 5)) |
2813 { | 2865 { |
2814 cmod->cmod_flags |= CMOD_KEEPPATTERNS; | 2866 cmod->cmod_flags |= CMOD_KEEPPATTERNS; |
2815 continue; | 2867 continue; |
2816 } | 2868 } |
2817 if (!checkforcmd(&eap->cmd, "keepjumps", 5)) | 2869 if (!checkforcmd_noparen(&eap->cmd, "keepjumps", 5)) |
2818 break; | 2870 break; |
2819 cmod->cmod_flags |= CMOD_KEEPJUMPS; | 2871 cmod->cmod_flags |= CMOD_KEEPJUMPS; |
2820 continue; | 2872 continue; |
2821 | 2873 |
2822 case 'f': // only accept ":filter {pat} cmd" | 2874 case 'f': // only accept ":filter {pat} cmd" |
2823 { | 2875 { |
2824 char_u *reg_pat; | 2876 char_u *reg_pat; |
2825 | 2877 |
2826 if (!checkforcmd(&p, "filter", 4) | 2878 if (!checkforcmd_noparen(&p, "filter", 4) |
2827 || *p == NUL || ends_excmd(*p)) | 2879 || *p == NUL || ends_excmd(*p)) |
2828 break; | 2880 break; |
2829 if (*p == '!') | 2881 if (*p == '!') |
2830 { | 2882 { |
2831 cmod->cmod_filter_force = TRUE; | 2883 cmod->cmod_filter_force = TRUE; |
2855 eap->cmd = p; | 2907 eap->cmd = p; |
2856 continue; | 2908 continue; |
2857 } | 2909 } |
2858 | 2910 |
2859 // ":hide" and ":hide | cmd" are not modifiers | 2911 // ":hide" and ":hide | cmd" are not modifiers |
2860 case 'h': if (p != eap->cmd || !checkforcmd(&p, "hide", 3) | 2912 case 'h': if (p != eap->cmd || !checkforcmd_noparen(&p, "hide", 3) |
2861 || *p == NUL || ends_excmd(*p)) | 2913 || *p == NUL || ends_excmd(*p)) |
2862 break; | 2914 break; |
2863 eap->cmd = p; | 2915 eap->cmd = p; |
2864 cmod->cmod_flags |= CMOD_HIDE; | 2916 cmod->cmod_flags |= CMOD_HIDE; |
2865 continue; | 2917 continue; |
2866 | 2918 |
2867 case 'l': if (checkforcmd(&eap->cmd, "lockmarks", 3)) | 2919 case 'l': if (checkforcmd_noparen(&eap->cmd, "lockmarks", 3)) |
2868 { | 2920 { |
2869 cmod->cmod_flags |= CMOD_LOCKMARKS; | 2921 cmod->cmod_flags |= CMOD_LOCKMARKS; |
2870 continue; | 2922 continue; |
2871 } | 2923 } |
2872 | 2924 |
2873 if (!checkforcmd(&eap->cmd, "leftabove", 5)) | 2925 if (!checkforcmd_noparen(&eap->cmd, "leftabove", 5)) |
2874 break; | 2926 break; |
2875 cmod->cmod_split |= WSP_ABOVE; | 2927 cmod->cmod_split |= WSP_ABOVE; |
2876 continue; | 2928 continue; |
2877 | 2929 |
2878 case 'n': if (checkforcmd(&eap->cmd, "noautocmd", 3)) | 2930 case 'n': if (checkforcmd_noparen(&eap->cmd, "noautocmd", 3)) |
2879 { | 2931 { |
2880 cmod->cmod_flags |= CMOD_NOAUTOCMD; | 2932 cmod->cmod_flags |= CMOD_NOAUTOCMD; |
2881 continue; | 2933 continue; |
2882 } | 2934 } |
2883 if (!checkforcmd(&eap->cmd, "noswapfile", 3)) | 2935 if (!checkforcmd_noparen(&eap->cmd, "noswapfile", 3)) |
2884 break; | 2936 break; |
2885 cmod->cmod_flags |= CMOD_NOSWAPFILE; | 2937 cmod->cmod_flags |= CMOD_NOSWAPFILE; |
2886 continue; | 2938 continue; |
2887 | 2939 |
2888 case 'r': if (!checkforcmd(&eap->cmd, "rightbelow", 6)) | 2940 case 'r': if (!checkforcmd_noparen(&eap->cmd, "rightbelow", 6)) |
2889 break; | 2941 break; |
2890 cmod->cmod_split |= WSP_BELOW; | 2942 cmod->cmod_split |= WSP_BELOW; |
2891 continue; | 2943 continue; |
2892 | 2944 |
2893 case 's': if (checkforcmd(&eap->cmd, "sandbox", 3)) | 2945 case 's': if (checkforcmd_noparen(&eap->cmd, "sandbox", 3)) |
2894 { | 2946 { |
2895 cmod->cmod_flags |= CMOD_SANDBOX; | 2947 cmod->cmod_flags |= CMOD_SANDBOX; |
2896 continue; | 2948 continue; |
2897 } | 2949 } |
2898 if (!checkforcmd(&eap->cmd, "silent", 3)) | 2950 if (!checkforcmd_noparen(&eap->cmd, "silent", 3)) |
2899 break; | 2951 break; |
2900 cmod->cmod_flags |= CMOD_SILENT; | 2952 cmod->cmod_flags |= CMOD_SILENT; |
2901 if (*eap->cmd == '!' && !VIM_ISWHITE(eap->cmd[-1])) | 2953 if (*eap->cmd == '!' && !VIM_ISWHITE(eap->cmd[-1])) |
2902 { | 2954 { |
2903 // ":silent!", but not "silent !cmd" | 2955 // ":silent!", but not "silent !cmd" |
2904 eap->cmd = skipwhite(eap->cmd + 1); | 2956 eap->cmd = skipwhite(eap->cmd + 1); |
2905 cmod->cmod_flags |= CMOD_ERRSILENT; | 2957 cmod->cmod_flags |= CMOD_ERRSILENT; |
2906 } | 2958 } |
2907 continue; | 2959 continue; |
2908 | 2960 |
2909 case 't': if (checkforcmd(&p, "tab", 3)) | 2961 case 't': if (checkforcmd_noparen(&p, "tab", 3)) |
2910 { | 2962 { |
2911 if (!skip_only) | 2963 if (!skip_only) |
2912 { | 2964 { |
2913 long tabnr = get_address(eap, &eap->cmd, | 2965 long tabnr = get_address(eap, &eap->cmd, |
2914 ADDR_TABS, eap->skip, | 2966 ADDR_TABS, eap->skip, |
2926 } | 2978 } |
2927 } | 2979 } |
2928 eap->cmd = p; | 2980 eap->cmd = p; |
2929 continue; | 2981 continue; |
2930 } | 2982 } |
2931 if (!checkforcmd(&eap->cmd, "topleft", 2)) | 2983 if (!checkforcmd_noparen(&eap->cmd, "topleft", 2)) |
2932 break; | 2984 break; |
2933 cmod->cmod_split |= WSP_TOP; | 2985 cmod->cmod_split |= WSP_TOP; |
2934 continue; | 2986 continue; |
2935 | 2987 |
2936 case 'u': if (!checkforcmd(&eap->cmd, "unsilent", 3)) | 2988 case 'u': if (!checkforcmd_noparen(&eap->cmd, "unsilent", 3)) |
2937 break; | 2989 break; |
2938 cmod->cmod_flags |= CMOD_UNSILENT; | 2990 cmod->cmod_flags |= CMOD_UNSILENT; |
2939 continue; | 2991 continue; |
2940 | 2992 |
2941 case 'v': if (checkforcmd(&eap->cmd, "vertical", 4)) | 2993 case 'v': if (checkforcmd_noparen(&eap->cmd, "vertical", 4)) |
2942 { | 2994 { |
2943 cmod->cmod_split |= WSP_VERT; | 2995 cmod->cmod_split |= WSP_VERT; |
2944 continue; | 2996 continue; |
2945 } | 2997 } |
2946 if (checkforcmd(&eap->cmd, "vim9cmd", 4)) | 2998 if (checkforcmd_noparen(&eap->cmd, "vim9cmd", 4)) |
2947 { | 2999 { |
2948 if (ends_excmd2(p, eap->cmd)) | 3000 if (ends_excmd2(p, eap->cmd)) |
2949 { | 3001 { |
2950 *errormsg = | 3002 *errormsg = |
2951 _(e_vim9cmd_must_be_followed_by_command); | 3003 _(e_vim9cmd_must_be_followed_by_command); |
2952 return FAIL; | 3004 return FAIL; |
2953 } | 3005 } |
2954 cmod->cmod_flags |= CMOD_VIM9CMD; | 3006 cmod->cmod_flags |= CMOD_VIM9CMD; |
2955 continue; | 3007 continue; |
2956 } | 3008 } |
2957 if (!checkforcmd(&p, "verbose", 4)) | 3009 if (!checkforcmd_noparen(&p, "verbose", 4)) |
2958 break; | 3010 break; |
2959 if (vim_isdigit(*eap->cmd)) | 3011 if (vim_isdigit(*eap->cmd)) |
2960 cmod->cmod_verbose = atoi((char *)eap->cmd); | 3012 cmod->cmod_verbose = atoi((char *)eap->cmd); |
2961 else | 3013 else |
2962 cmod->cmod_verbose = 1; | 3014 cmod->cmod_verbose = 1; |
3250 } | 3302 } |
3251 return OK; | 3303 return OK; |
3252 } | 3304 } |
3253 | 3305 |
3254 /* | 3306 /* |
3255 * Check for an Ex command with optional tail. | |
3256 * If there is a match advance "pp" to the argument and return TRUE. | |
3257 */ | |
3258 int | |
3259 checkforcmd( | |
3260 char_u **pp, // start of command | |
3261 char *cmd, // name of command | |
3262 int len) // required length | |
3263 { | |
3264 int i; | |
3265 | |
3266 for (i = 0; cmd[i] != NUL; ++i) | |
3267 if (((char_u *)cmd)[i] != (*pp)[i]) | |
3268 break; | |
3269 if (i >= len && !isalpha((*pp)[i]) && (*pp)[i] != '_') | |
3270 { | |
3271 *pp = skipwhite(*pp + i); | |
3272 return TRUE; | |
3273 } | |
3274 return FALSE; | |
3275 } | |
3276 | |
3277 /* | |
3278 * Append "cmd" to the error message in IObuff. | 3307 * Append "cmd" to the error message in IObuff. |
3279 * Takes care of limiting the length and handling 0xa0, which would be | 3308 * Takes care of limiting the length and handling 0xa0, which would be |
3280 * invisible otherwise. | 3309 * invisible otherwise. |
3281 */ | 3310 */ |
3282 static void | 3311 static void |