@@ -2684,6 +2684,58 @@ ex_errmsg(char *msg, char_u *arg)
26842684 return ex_error_buf ;
26852685}
26862686
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+
26872739/*
26882740 * Parse and skip over command modifiers:
26892741 * - update eap->cmd
@@ -2770,51 +2822,51 @@ parse_command_modifiers(
27702822 switch (* p )
27712823 {
27722824 // 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 ))
27742826 break ;
27752827 cmod -> cmod_split |= WSP_ABOVE ;
27762828 continue ;
27772829
2778- case 'b' : if (checkforcmd (& eap -> cmd , "belowright" , 3 ))
2830+ case 'b' : if (checkforcmd_noparen (& eap -> cmd , "belowright" , 3 ))
27792831 {
27802832 cmod -> cmod_split |= WSP_BELOW ;
27812833 continue ;
27822834 }
2783- if (checkforcmd (& eap -> cmd , "browse" , 3 ))
2835+ if (checkforcmd_opt (& eap -> cmd , "browse" , 3 , TRUE ))
27842836 {
27852837#ifdef FEAT_BROWSE_CMD
27862838 cmod -> cmod_flags |= CMOD_BROWSE ;
27872839#endif
27882840 continue ;
27892841 }
2790- if (!checkforcmd (& eap -> cmd , "botright" , 2 ))
2842+ if (!checkforcmd_noparen (& eap -> cmd , "botright" , 2 ))
27912843 break ;
27922844 cmod -> cmod_split |= WSP_BOT ;
27932845 continue ;
27942846
2795- case 'c' : if (!checkforcmd (& eap -> cmd , "confirm" , 4 ))
2847+ case 'c' : if (!checkforcmd_opt (& eap -> cmd , "confirm" , 4 , TRUE ))
27962848 break ;
27972849#if defined(FEAT_GUI_DIALOG ) || defined(FEAT_CON_DIALOG )
27982850 cmod -> cmod_flags |= CMOD_CONFIRM ;
27992851#endif
28002852 continue ;
28012853
2802- case 'k' : if (checkforcmd (& eap -> cmd , "keepmarks" , 3 ))
2854+ case 'k' : if (checkforcmd_noparen (& eap -> cmd , "keepmarks" , 3 ))
28032855 {
28042856 cmod -> cmod_flags |= CMOD_KEEPMARKS ;
28052857 continue ;
28062858 }
2807- if (checkforcmd (& eap -> cmd , "keepalt" , 5 ))
2859+ if (checkforcmd_noparen (& eap -> cmd , "keepalt" , 5 ))
28082860 {
28092861 cmod -> cmod_flags |= CMOD_KEEPALT ;
28102862 continue ;
28112863 }
2812- if (checkforcmd (& eap -> cmd , "keeppatterns" , 5 ))
2864+ if (checkforcmd_noparen (& eap -> cmd , "keeppatterns" , 5 ))
28132865 {
28142866 cmod -> cmod_flags |= CMOD_KEEPPATTERNS ;
28152867 continue ;
28162868 }
2817- if (!checkforcmd (& eap -> cmd , "keepjumps" , 5 ))
2869+ if (!checkforcmd_noparen (& eap -> cmd , "keepjumps" , 5 ))
28182870 break ;
28192871 cmod -> cmod_flags |= CMOD_KEEPJUMPS ;
28202872 continue ;
@@ -2823,7 +2875,7 @@ parse_command_modifiers(
28232875 {
28242876 char_u * reg_pat ;
28252877
2826- if (!checkforcmd (& p , "filter" , 4 )
2878+ if (!checkforcmd_noparen (& p , "filter" , 4 )
28272879 || * p == NUL || ends_excmd (* p ))
28282880 break ;
28292881 if (* p == '!' )
@@ -2857,45 +2909,45 @@ parse_command_modifiers(
28572909 }
28582910
28592911 // ":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 )
28612913 || * p == NUL || ends_excmd (* p ))
28622914 break ;
28632915 eap -> cmd = p ;
28642916 cmod -> cmod_flags |= CMOD_HIDE ;
28652917 continue ;
28662918
2867- case 'l' : if (checkforcmd (& eap -> cmd , "lockmarks" , 3 ))
2919+ case 'l' : if (checkforcmd_noparen (& eap -> cmd , "lockmarks" , 3 ))
28682920 {
28692921 cmod -> cmod_flags |= CMOD_LOCKMARKS ;
28702922 continue ;
28712923 }
28722924
2873- if (!checkforcmd (& eap -> cmd , "leftabove" , 5 ))
2925+ if (!checkforcmd_noparen (& eap -> cmd , "leftabove" , 5 ))
28742926 break ;
28752927 cmod -> cmod_split |= WSP_ABOVE ;
28762928 continue ;
28772929
2878- case 'n' : if (checkforcmd (& eap -> cmd , "noautocmd" , 3 ))
2930+ case 'n' : if (checkforcmd_noparen (& eap -> cmd , "noautocmd" , 3 ))
28792931 {
28802932 cmod -> cmod_flags |= CMOD_NOAUTOCMD ;
28812933 continue ;
28822934 }
2883- if (!checkforcmd (& eap -> cmd , "noswapfile" , 3 ))
2935+ if (!checkforcmd_noparen (& eap -> cmd , "noswapfile" , 3 ))
28842936 break ;
28852937 cmod -> cmod_flags |= CMOD_NOSWAPFILE ;
28862938 continue ;
28872939
2888- case 'r' : if (!checkforcmd (& eap -> cmd , "rightbelow" , 6 ))
2940+ case 'r' : if (!checkforcmd_noparen (& eap -> cmd , "rightbelow" , 6 ))
28892941 break ;
28902942 cmod -> cmod_split |= WSP_BELOW ;
28912943 continue ;
28922944
2893- case 's' : if (checkforcmd (& eap -> cmd , "sandbox" , 3 ))
2945+ case 's' : if (checkforcmd_noparen (& eap -> cmd , "sandbox" , 3 ))
28942946 {
28952947 cmod -> cmod_flags |= CMOD_SANDBOX ;
28962948 continue ;
28972949 }
2898- if (!checkforcmd (& eap -> cmd , "silent" , 3 ))
2950+ if (!checkforcmd_noparen (& eap -> cmd , "silent" , 3 ))
28992951 break ;
29002952 cmod -> cmod_flags |= CMOD_SILENT ;
29012953 if (* eap -> cmd == '!' && !VIM_ISWHITE (eap -> cmd [-1 ]))
@@ -2906,7 +2958,7 @@ parse_command_modifiers(
29062958 }
29072959 continue ;
29082960
2909- case 't' : if (checkforcmd (& p , "tab" , 3 ))
2961+ case 't' : if (checkforcmd_noparen (& p , "tab" , 3 ))
29102962 {
29112963 if (!skip_only )
29122964 {
@@ -2928,22 +2980,22 @@ parse_command_modifiers(
29282980 eap -> cmd = p ;
29292981 continue ;
29302982 }
2931- if (!checkforcmd (& eap -> cmd , "topleft" , 2 ))
2983+ if (!checkforcmd_noparen (& eap -> cmd , "topleft" , 2 ))
29322984 break ;
29332985 cmod -> cmod_split |= WSP_TOP ;
29342986 continue ;
29352987
2936- case 'u' : if (!checkforcmd (& eap -> cmd , "unsilent" , 3 ))
2988+ case 'u' : if (!checkforcmd_noparen (& eap -> cmd , "unsilent" , 3 ))
29372989 break ;
29382990 cmod -> cmod_flags |= CMOD_UNSILENT ;
29392991 continue ;
29402992
2941- case 'v' : if (checkforcmd (& eap -> cmd , "vertical" , 4 ))
2993+ case 'v' : if (checkforcmd_noparen (& eap -> cmd , "vertical" , 4 ))
29422994 {
29432995 cmod -> cmod_split |= WSP_VERT ;
29442996 continue ;
29452997 }
2946- if (checkforcmd (& eap -> cmd , "vim9cmd" , 4 ))
2998+ if (checkforcmd_noparen (& eap -> cmd , "vim9cmd" , 4 ))
29472999 {
29483000 if (ends_excmd2 (p , eap -> cmd ))
29493001 {
@@ -2954,7 +3006,7 @@ parse_command_modifiers(
29543006 cmod -> cmod_flags |= CMOD_VIM9CMD ;
29553007 continue ;
29563008 }
2957- if (!checkforcmd (& p , "verbose" , 4 ))
3009+ if (!checkforcmd_noparen (& p , "verbose" , 4 ))
29583010 break ;
29593011 if (vim_isdigit (* eap -> cmd ))
29603012 cmod -> cmod_verbose = atoi ((char * )eap -> cmd );
@@ -3251,29 +3303,6 @@ parse_cmd_address(exarg_T *eap, char **errormsg, int silent)
32513303 return OK ;
32523304}
32533305
3254- /*
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-
32773306/*
32783307 * Append "cmd" to the error message in IObuff.
32793308 * Takes care of limiting the length and handling 0xa0, which would be
0 commit comments