patch 9.1.0624: ex command modifiers not found

Commit: 
https://github.com/vim/vim/commit/70a11a6bf69f477844470ce59958b686024d2a41
Author: Christian Brabandt <c...@256bit.org>
Date:   Fri Jul 26 19:13:55 2024 +0200

    patch 9.1.0624: ex command modifiers not found
    
    Problem:  ex command modifiers are not found
              (Ingo Karkat, after v9.1.0352)
    Solution: partly revert patch v9.1.0352, ignore :{ and :}
              when expanding ex commands
    
    The issue is, that the :keepmarks command can be abbreviated to :kee or
    :keep or :keepm but not to e.g. :ke (because that would be the :exe
    command :k with register e).
    
    This basically means, we need `:kee` sorted before `:keepalt` but at the
    same time `:keepmarks` sorted after the `:keepalt` command in the
    cmdmod_info_tab table. Due to this, the binary search may not work
    correctly, so let's revert that part of patch v9.1.0352.
    
    fixes: #15305
    closes: #15336
    
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index e6200ed70..2a5930154 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -19,10 +19,6 @@ static int   ex_pressedreturn = FALSE;
 # define ex_hardcopy   ex_ni
 #endif
 
-#if defined(FEAT_EVAL) || defined(PROTO)
-static int cmp_cmdmod_info(const void *a, const void *b);
-#endif
-
 #ifdef FEAT_EVAL
 static char_u  *do_one_cmd(char_u **, int, cstack_T *, char_u 
*(*fgetline)(int, void *, int, getline_opt_T), void *cookie);
 #else
@@ -4050,16 +4046,6 @@ static cmdmod_info_T cmdmod_info_tab[] = {
     {"vim9cmd", 4, FALSE}
 };     // cmdmod_info_tab
 
-// compare two cmdmod_info_T structs by case sensitive name with length
-    static int
-cmp_cmdmod_info(const void *a, const void *b)
-{
-    cmdmod_info_T *cm1 = (cmdmod_info_T *)a;
-    cmdmod_info_T *cm2 = (cmdmod_info_T *)b;
-
-    return STRNCMP(cm1->name, cm2->name, cm2->minlen);
-}
-
 /*
  * Return length of a command modifier (including optional count).
  * Return zero when it's not a modifier.
@@ -4067,36 +4053,20 @@ cmp_cmdmod_info(const void *a, const void *b)
     int
 modifier_len(char_u *cmd)
 {
+    int                i, j;
     char_u     *p = cmd;
-    cmdmod_info_T      target;
-    cmdmod_info_T      *entry;
 
     if (VIM_ISDIGIT(*cmd))
        p = skipwhite(skipdigits(cmd + 1));
-
-    // only lowercase characters can match
-    if (!ASCII_ISLOWER(*p))
-       return 0;
-
-    target.name = (char *)p;
-    target.minlen = 0;         // not used, see cmp_cmdmod_info()
-    target.has_count = FALSE;
-
-    entry = (cmdmod_info_T *)bsearch(&target, &cmdmod_info_tab, 
ARRAY_LENGTH(cmdmod_info_tab), sizeof(cmdmod_info_tab[0]), cmp_cmdmod_info);
-    if (entry != NULL)
+    for (i = 0; i < (int)ARRAY_LENGTH(cmdmod_info_tab); ++i)
     {
-       int i;
-
-       for (i = entry->minlen; p[i] != NUL; ++i)
-       {
-           if (p[i] != entry->name[i])
+       for (j = 0; p[j] != NUL; ++j)
+           if (p[j] != cmdmod_info_tab[i].name[j])
                break;
-       }
-
-       if (!ASCII_ISALPHA(p[i]) && i >= entry->minlen && (p == cmd || 
entry->has_count))
-           return i + (int)(p - cmd);
+       if (!ASCII_ISALPHA(p[j]) && j >= cmdmod_info_tab[i].minlen
+                                       && (p == cmd || 
cmdmod_info_tab[i].has_count))
+           return j + (int)(p - cmd);
     }
-
     return 0;
 }
 
@@ -4110,33 +4080,18 @@ cmd_exists(char_u *name)
 {
     exarg_T    ea;
     int                full = FALSE;
+    int                i;
+    int                j;
     char_u     *p;
 
-    // only lowercase characters can match
-    if (ASCII_ISLOWER(*name))
+    // Check command modifiers.
+    for (i = 0; i < (int)ARRAY_LENGTH(cmdmod_info_tab); ++i)
     {
-       cmdmod_info_T   target;
-       cmdmod_info_T   *entry;
-
-       target.name = (char *)name;
-       target.minlen = 0;              // not used, see cmp_cmdmod_info()
-       target.has_count = FALSE;
-
-       // Check command modifiers.
-       entry = (cmdmod_info_T *)bsearch(&target, &cmdmod_info_tab, 
ARRAY_LENGTH(cmdmod_info_tab), sizeof(cmdmod_info_tab[0]), cmp_cmdmod_info);
-       if (entry != NULL)
-       {
-           int i;
-
-           for (i = entry->minlen; name[i] != NUL; ++i)
-           {
-               if (name[i] != entry->name[i])
-                   break;
-           }
-
-           if (name[i] == NUL && i >= entry->minlen)
-               return (entry->name[i] == NUL ? 2 : 1);
-       }
+       for (j = 0; name[j] != NUL; ++j)
+           if (name[j] != cmdmod_info_tab[i].name[j])
+               break;
+       if (name[j] == NUL && j >= cmdmod_info_tab[i].minlen)
+           return (cmdmod_info_tab[i].name[j] == NUL ? 2 : 1);
     }
 
     // Check built-in commands and user defined commands.
@@ -5993,6 +5948,10 @@ get_command_name(expand_T *xp UNUSED, int idx)
 {
     if (idx >= (int)CMD_SIZE)
        return expand_user_command_name(idx);
+    // the following are no real commands
+    if (STRNCMP(cmdnames[idx].cmd_name, "{", 1) == 0 ||
+        STRNCMP(cmdnames[idx].cmd_name, "}", 1) == 0)
+       return (char_u *)"";
     return cmdnames[idx].cmd_name;
 }
 
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index f83d67334..3f6918a8c 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -3870,4 +3870,25 @@ func Test_term_option()
   let &cpo = _cpo
 endfunc
 
+func Test_ex_command_completion()
+  " required for :*
+  set cpo+=*
+  let list = filter(getcompletion('', 'command'), 'exists(":" . v:val) == 0')
+  " :++ and :-- are only valid in Vim9 Script context, so they can be ignored
+  call assert_equal(['++', '--'], sort(list))
+  call assert_equal(1, exists(':k'))
+  call assert_equal(0, exists(':ke'))
+  call assert_equal(1, exists(':kee'))
+  call assert_equal(1, exists(':keep'))
+  call assert_equal(1, exists(':keepm'))
+  call assert_equal(1, exists(':keepma'))
+  call assert_equal(1, exists(':keepmar'))
+  call assert_equal(1, exists(':keepmark'))
+  call assert_equal(2, exists(':keepmarks'))
+  call assert_equal(2, exists(':keepalt'))
+  call assert_equal(2, exists(':keepjumps'))
+  call assert_equal(2, exists(':keeppatterns'))
+  set cpo-=*
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index e16ad291a..0dadd19b1 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    624,
 /**/
     623,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1sXOlX-00CfbL-Gs%40256bit.org.

Raspunde prin e-mail lui