forked from aniani/vim
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 <cb@256bit.org>
This commit is contained in:
parent
325420ebe4
commit
70a11a6bf6
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -704,6 +704,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
624,
|
||||
/**/
|
||||
623,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user