changeset 28185:dcb449ae45c9 v8.2.4618

patch 8.2.4618: cmdline completion does not recognize single letter commands Commit: https://github.com/vim/vim/commit/f4f0525c34d2aa32f214155b0dadcd274ed05dd1 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Mar 24 13:08:36 2022 +0000 patch 8.2.4618: cmdline completion does not recognize single letter commands Problem: Command line completion does not recognize single letter commands. Solution: Use the condition from find_ex_command().
author Bram Moolenaar <Bram@vim.org>
date Thu, 24 Mar 2022 14:15:02 +0100
parents b67e3db70515
children 5d3592802fb9
files src/ex_docmd.c src/version.c
diffstat 2 files changed, 43 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -3421,6 +3421,38 @@ skip_option_env_lead(char_u *start)
 #endif
 
 /*
+ * Return TRUE and set "*idx" if "p" points to a one letter command.
+ * If not in Vim9 script:
+ * - The 'k' command can directly be followed by any character.
+ * - The 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
+ *	    but :sre[wind] is another command, as are :scr[iptnames],
+ *	    :scs[cope], :sim[alt], :sig[ns] and :sil[ent].
+ */
+    static int
+one_letter_cmd(char_u *p, cmdidx_T *idx)
+{
+    if (!in_vim9script())
+	return FALSE;
+    if (*p == 'k')
+    {
+	*idx = CMD_k;
+	return TRUE;
+    }
+    if (p[0] == 's'
+	    && ((p[1] == 'c' && (p[2] == NUL || (p[2] != 's' && p[2] != 'r'
+			&& (p[3] == NUL || (p[3] != 'i' && p[4] != 'p')))))
+		|| p[1] == 'g'
+		|| (p[1] == 'i' && p[2] != 'm' && p[2] != 'l' && p[2] != 'g')
+		|| p[1] == 'I'
+		|| (p[1] == 'r' && p[2] != 'e')))
+    {
+	*idx = CMD_substitute;
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
  * Find an Ex command by its name, either built-in or user.
  * Start of the name can be found at eap->cmd.
  * Sets eap->cmdidx and returns a pointer to char after the command name.
@@ -3654,30 +3686,10 @@ find_ex_command(
 
     /*
      * Isolate the command and search for it in the command table.
-     * Exceptions:
-     * - The 'k' command can directly be followed by any character.
-     *   But it is not used in Vim9 script.
-     * - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
-     *	    but :sre[wind] is another command, as are :scr[iptnames],
-     *	    :scs[cope], :sim[alt], :sig[ns] and :sil[ent].
-     * - the "d" command can directly be followed by 'l' or 'p' flag.
      */
     p = eap->cmd;
-    if (!vim9 && *p == 'k')
-    {
-	eap->cmdidx = CMD_k;
-	++p;
-    }
-    else if (!vim9
-	    && p[0] == 's'
-	    && ((p[1] == 'c' && (p[2] == NUL || (p[2] != 's' && p[2] != 'r'
-			&& (p[3] == NUL || (p[3] != 'i' && p[4] != 'p')))))
-		|| p[1] == 'g'
-		|| (p[1] == 'i' && p[2] != 'm' && p[2] != 'l' && p[2] != 'g')
-		|| p[1] == 'I'
-		|| (p[1] == 'r' && p[2] != 'e')))
-    {
-	eap->cmdidx = CMD_substitute;
+    if (one_letter_cmd(p, &eap->cmdidx))
+    {
 	++p;
     }
     else
@@ -3702,6 +3714,8 @@ find_ex_command(
 	if (p == eap->cmd && vim_strchr((char_u *)"@*!=><&~#}", *p) != NULL)
 	    ++p;
 	len = (int)(p - eap->cmd);
+	// The "d" command can directly be followed by 'l' or 'p' flag, when
+	// not in Vim9 script.
 	if (!vim9 && *eap->cmd == 'd' && (p[-1] == 'l' || p[-1] == 'p'))
 	{
 	    // Check for ":dl", ":dell", etc. to ":deletel": that's
@@ -3955,10 +3969,11 @@ excmd_get_cmdidx(char_u *cmd, int len)
 {
     cmdidx_T idx;
 
-    for (idx = (cmdidx_T)0; (int)idx < (int)CMD_SIZE;
-	    idx = (cmdidx_T)((int)idx + 1))
-	if (STRNCMP(cmdnames[(int)idx].cmd_name, cmd, (size_t)len) == 0)
-	    break;
+    if (!one_letter_cmd(cmd, &idx))
+	for (idx = (cmdidx_T)0; (int)idx < (int)CMD_SIZE;
+		idx = (cmdidx_T)((int)idx + 1))
+	    if (STRNCMP(cmdnames[(int)idx].cmd_name, cmd, (size_t)len) == 0)
+		break;
 
     return idx;
 }
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4618,
+/**/
     4617,
 /**/
     4616,