1
0
forked from aniani/vim

patch 8.2.4398: some command completion functions are too long

Problem:    Some command completion functions are too long.
Solution:   Refactor code into separate functions.  Add a few more tests.
            (Yegappan Lakshmanan, closes #9785)
This commit is contained in:
Yegappan Lakshmanan
2022-02-16 12:44:29 +00:00
committed by Bram Moolenaar
parent 34f8117dec
commit b31aec3b93
6 changed files with 491 additions and 346 deletions

View File

@@ -681,6 +681,98 @@ ExpandCleanup(expand_T *xp)
}
}
/*
* Display one line of completion matches. Multiple matches are displayed in
* each line (used by wildmode=list and CTRL-D)
* files_found - list of completion match names
* num_files - number of completion matches in "files_found"
* lines - number of output lines
* linenr - line number of matches to display
* maxlen - maximum number of characters in each line
* showtail - display only the tail of the full path of a file name
* dir_attr - highlight attribute to use for directory names
*/
static void
showmatches_oneline(
expand_T *xp,
char_u **files_found,
int num_files,
int lines,
int linenr,
int maxlen,
int showtail,
int dir_attr)
{
int i, j;
int isdir;
int lastlen;
char_u *p;
lastlen = 999;
for (j = linenr; j < num_files; j += lines)
{
if (xp->xp_context == EXPAND_TAGS_LISTFILES)
{
msg_outtrans_attr(files_found[j], HL_ATTR(HLF_D));
p = files_found[j] + STRLEN(files_found[j]) + 1;
msg_advance(maxlen + 1);
msg_puts((char *)p);
msg_advance(maxlen + 3);
msg_outtrans_long_attr(p + 2, HL_ATTR(HLF_D));
break;
}
for (i = maxlen - lastlen; --i >= 0; )
msg_putchar(' ');
if (xp->xp_context == EXPAND_FILES
|| xp->xp_context == EXPAND_SHELLCMD
|| xp->xp_context == EXPAND_BUFFERS)
{
// highlight directories
if (xp->xp_numfiles != -1)
{
char_u *halved_slash;
char_u *exp_path;
char_u *path;
// Expansion was done before and special characters
// were escaped, need to halve backslashes. Also
// $HOME has been replaced with ~/.
exp_path = expand_env_save_opt(files_found[j], TRUE);
path = exp_path != NULL ? exp_path : files_found[j];
halved_slash = backslash_halve_save(path);
isdir = mch_isdir(halved_slash != NULL ? halved_slash
: files_found[j]);
vim_free(exp_path);
if (halved_slash != path)
vim_free(halved_slash);
}
else
// Expansion was done here, file names are literal.
isdir = mch_isdir(files_found[j]);
if (showtail)
p = SHOW_FILE_TEXT(j);
else
{
home_replace(NULL, files_found[j], NameBuff, MAXPATHL,
TRUE);
p = NameBuff;
}
}
else
{
isdir = FALSE;
p = SHOW_FILE_TEXT(j);
}
lastlen = msg_outtrans_attr(p, isdir ? dir_attr : 0);
}
if (msg_col > 0) // when not wrapped around
{
msg_clr_eos();
msg_putchar('\n');
}
out_flush(); // show one line at a time
}
/*
* Show all matches for completion on the command line.
* Returns EXPAND_NOTHING when the character that triggered expansion should
@@ -692,12 +784,10 @@ showmatches(expand_T *xp, int wildmenu UNUSED)
cmdline_info_T *ccline = get_cmdline_info();
int num_files;
char_u **files_found;
int i, j, k;
int i, j;
int maxlen;
int lines;
int columns;
char_u *p;
int lastlen;
int attr;
int showtail;
@@ -709,7 +799,6 @@ showmatches(expand_T *xp, int wildmenu UNUSED)
showtail = expand_showtail(xp);
if (i != EXPAND_OK)
return i;
}
else
{
@@ -789,69 +878,8 @@ showmatches(expand_T *xp, int wildmenu UNUSED)
// list the files line by line
for (i = 0; i < lines; ++i)
{
lastlen = 999;
for (k = i; k < num_files; k += lines)
{
if (xp->xp_context == EXPAND_TAGS_LISTFILES)
{
msg_outtrans_attr(files_found[k], HL_ATTR(HLF_D));
p = files_found[k] + STRLEN(files_found[k]) + 1;
msg_advance(maxlen + 1);
msg_puts((char *)p);
msg_advance(maxlen + 3);
msg_outtrans_long_attr(p + 2, HL_ATTR(HLF_D));
break;
}
for (j = maxlen - lastlen; --j >= 0; )
msg_putchar(' ');
if (xp->xp_context == EXPAND_FILES
|| xp->xp_context == EXPAND_SHELLCMD
|| xp->xp_context == EXPAND_BUFFERS)
{
// highlight directories
if (xp->xp_numfiles != -1)
{
char_u *halved_slash;
char_u *exp_path;
char_u *path;
// Expansion was done before and special characters
// were escaped, need to halve backslashes. Also
// $HOME has been replaced with ~/.
exp_path = expand_env_save_opt(files_found[k], TRUE);
path = exp_path != NULL ? exp_path : files_found[k];
halved_slash = backslash_halve_save(path);
j = mch_isdir(halved_slash != NULL ? halved_slash
: files_found[k]);
vim_free(exp_path);
if (halved_slash != path)
vim_free(halved_slash);
}
else
// Expansion was done here, file names are literal.
j = mch_isdir(files_found[k]);
if (showtail)
p = SHOW_FILE_TEXT(k);
else
{
home_replace(NULL, files_found[k], NameBuff, MAXPATHL,
TRUE);
p = NameBuff;
}
}
else
{
j = FALSE;
p = SHOW_FILE_TEXT(k);
}
lastlen = msg_outtrans_attr(p, j ? attr : 0);
}
if (msg_col > 0) // when not wrapped around
{
msg_clr_eos();
msg_putchar('\n');
}
out_flush(); // show one line at a time
showmatches_oneline(xp, files_found, num_files, lines, i,
maxlen, showtail, attr);
if (got_int)
{
got_int = FALSE;
@@ -1333,6 +1361,73 @@ set_context_for_wildcard_arg(
}
}
/*
* Returns a pointer to the next command after a :substitute or a :& command.
* Returns NULL if there is no next command.
*/
static char_u *
find_cmd_after_substitute_cmd(char_u *arg)
{
int delim;
delim = *arg;
if (delim)
{
// skip "from" part
++arg;
arg = skip_regexp(arg, delim, magic_isset());
if (arg[0] != NUL && arg[0] == delim)
{
// skip "to" part
++arg;
while (arg[0] != NUL && arg[0] != delim)
{
if (arg[0] == '\\' && arg[1] != NUL)
++arg;
++arg;
}
if (arg[0] != NUL) // skip delimiter
++arg;
}
}
while (arg[0] && vim_strchr((char_u *)"|\"#", arg[0]) == NULL)
++arg;
if (arg[0] != NUL)
return arg;
return NULL;
}
/*
* Returns a pointer to the next command after a :isearch/:dsearch/:ilist
* :dlist/:ijump/:psearch/:djump/:isplit/:dsplit command.
* Returns NULL if there is no next command.
*/
static char_u *
find_cmd_after_isearch_cmd(char_u *arg, expand_T *xp)
{
arg = skipwhite(skipdigits(arg)); // skip count
if (*arg == '/') // Match regexp, not just whole words
{
for (++arg; *arg && *arg != '/'; arg++)
if (*arg == '\\' && arg[1] != NUL)
arg++;
if (*arg)
{
arg = skipwhite(arg + 1);
// Check for trailing illegal characters
if (*arg == NUL || vim_strchr((char_u *)"|\"\n", *arg) == NULL)
xp->xp_context = EXPAND_NOTHING;
else
return arg;
}
}
return NULL;
}
/*
* Set the completion context in 'xp' for command 'cmd' with index 'cmdidx'.
* The argument to the command is 'arg' and the argument flags is 'argt'.
@@ -1467,32 +1562,7 @@ set_context_by_cmdname(
break;
case CMD_and:
case CMD_substitute:
delim = *arg;
if (delim)
{
// skip "from" part
++arg;
arg = skip_regexp(arg, delim, magic_isset());
if (arg[0] != NUL && arg[0] == delim)
{
// skip "to" part
++arg;
while (arg[0] != NUL && arg[0] != delim)
{
if (arg[0] == '\\' && arg[1] != NUL)
++arg;
++arg;
}
if (arg[0] != NUL) // skip delimiter
++arg;
}
}
while (arg[0] && vim_strchr((char_u *)"|\"#", arg[0]) == NULL)
++arg;
if (arg[0] != NUL)
return arg;
break;
return find_cmd_after_substitute_cmd(arg);
case CMD_isearch:
case CMD_dsearch:
case CMD_ilist:
@@ -1502,26 +1572,7 @@ set_context_by_cmdname(
case CMD_djump:
case CMD_isplit:
case CMD_dsplit:
arg = skipwhite(skipdigits(arg)); // skip count
if (*arg == '/') // Match regexp, not just whole words
{
for (++arg; *arg && *arg != '/'; arg++)
if (*arg == '\\' && arg[1] != NUL)
arg++;
if (*arg)
{
arg = skipwhite(arg + 1);
// Check for trailing illegal characters
if (*arg == NUL ||
vim_strchr((char_u *)"|\"\n", *arg) == NULL)
xp->xp_context = EXPAND_NOTHING;
else
return arg;
}
}
break;
return find_cmd_after_isearch_cmd(arg, xp);
case CMD_autocmd:
return set_context_in_autocmd(xp, arg, FALSE);
case CMD_doautocmd:
@@ -1652,36 +1703,8 @@ set_context_by_cmdname(
#endif
case CMD_USER:
case CMD_USER_BUF:
if (compl != EXPAND_NOTHING)
{
// EX_XFILE: file names are handled above
if (!(argt & EX_XFILE))
{
#ifdef FEAT_MENU
if (compl == EXPAND_MENUS)
return set_context_in_menu_cmd(xp, cmd, arg, forceit);
#endif
if (compl == EXPAND_COMMANDS)
return arg;
if (compl == EXPAND_MAPPINGS)
return set_context_in_map_cmd(xp, (char_u *)"map",
arg, forceit, FALSE, FALSE, CMD_map);
// Find start of last argument.
p = arg;
while (*p)
{
if (*p == ' ')
// argument starts after a space
arg = p + 1;
else if (*p == '\\' && *(p + 1) != NUL)
++p; // skip over escaped character
MB_PTR_ADV(p);
}
xp->xp_pattern = arg;
}
xp->xp_context = compl;
}
break;
return set_context_in_user_cmdarg(cmd, arg, argt, compl, xp,
forceit);
case CMD_map: case CMD_noremap:
case CMD_nmap: case CMD_nnoremap:
@@ -2312,6 +2335,31 @@ ExpandOther(
return ret;
}
/*
* Map wild expand options to flags for expand_wildcards()
*/
static int
map_wildopts_to_ewflags(int options)
{
int flags;
flags = EW_DIR; // include directories
if (options & WILD_LIST_NOTFOUND)
flags |= EW_NOTFOUND;
if (options & WILD_ADD_SLASH)
flags |= EW_ADDSLASH;
if (options & WILD_KEEP_ALL)
flags |= EW_KEEPALL;
if (options & WILD_SILENT)
flags |= EW_SILENT;
if (options & WILD_NOERROR)
flags |= EW_NOERROR;
if (options & WILD_ALLLINKS)
flags |= EW_ALLLINKS;
return flags;
}
/*
* Do the expansion based on xp->xp_context and "pat".
*/
@@ -2328,19 +2376,7 @@ ExpandFromContext(
int flags;
char_u *tofree = NULL;
flags = EW_DIR; // include directories
if (options & WILD_LIST_NOTFOUND)
flags |= EW_NOTFOUND;
if (options & WILD_ADD_SLASH)
flags |= EW_ADDSLASH;
if (options & WILD_KEEP_ALL)
flags |= EW_KEEPALL;
if (options & WILD_SILENT)
flags |= EW_SILENT;
if (options & WILD_NOERROR)
flags |= EW_NOERROR;
if (options & WILD_ALLLINKS)
flags |= EW_ALLLINKS;
flags = map_wildopts_to_ewflags(options);
if (xp->xp_context == EXPAND_FILES
|| xp->xp_context == EXPAND_DIRECTORIES
@@ -2549,6 +2585,64 @@ ExpandGeneric(
return OK;
}
/*
* Expand shell command matches in one directory of $PATH.
*/
static void
expand_shellcmd_onedir(
char_u *buf,
char_u *s,
size_t l,
char_u *pat,
char_u ***files,
int *num_files,
int flags,
hashtab_T *ht,
garray_T *gap)
{
int ret;
int i;
hash_T hash;
hashitem_T *hi;
vim_strncpy(buf, s, l);
add_pathsep(buf);
l = STRLEN(buf);
vim_strncpy(buf + l, pat, MAXPATHL - 1 - l);
// Expand matches in one directory of $PATH.
ret = expand_wildcards(1, &buf, num_files, files, flags);
if (ret == OK)
{
if (ga_grow(gap, *num_files) == FAIL)
FreeWild(*num_files, *files);
else
{
for (i = 0; i < *num_files; ++i)
{
char_u *name = (*files)[i];
if (STRLEN(name) > l)
{
// Check if this name was already found.
hash = hash_hash(name + l);
hi = hash_lookup(ht, name + l, hash);
if (HASHITEM_EMPTY(hi))
{
// Remove the path that was prepended.
STRMOVE(name, name + l);
((char_u **)gap->ga_data)[gap->ga_len++] = name;
hash_add_item(ht, hi, name, hash);
name = NULL;
}
}
vim_free(name);
}
vim_free(*files);
}
}
}
/*
* Complete a shell command.
* Returns FAIL or OK;
@@ -2569,11 +2663,8 @@ expand_shellcmd(
size_t l;
char_u *s, *e;
int flags = flagsarg;
int ret;
int did_curdir = FALSE;
hashtab_T found_ht;
hashitem_T *hi;
hash_T hash;
buf = alloc(MAXPATHL);
if (buf == NULL)
@@ -2640,42 +2731,10 @@ expand_shellcmd(
l = e - s;
if (l > MAXPATHL - 5)
break;
vim_strncpy(buf, s, l);
add_pathsep(buf);
l = STRLEN(buf);
vim_strncpy(buf + l, pat, MAXPATHL - 1 - l);
// Expand matches in one directory of $PATH.
ret = expand_wildcards(1, &buf, num_file, file, flags);
if (ret == OK)
{
if (ga_grow(&ga, *num_file) == FAIL)
FreeWild(*num_file, *file);
else
{
for (i = 0; i < *num_file; ++i)
{
char_u *name = (*file)[i];
expand_shellcmd_onedir(buf, s, l, pat, file, num_file, flags,
&found_ht, &ga);
if (STRLEN(name) > l)
{
// Check if this name was already found.
hash = hash_hash(name + l);
hi = hash_lookup(&found_ht, name + l, hash);
if (HASHITEM_EMPTY(hi))
{
// Remove the path that was prepended.
STRMOVE(name, name + l);
((char_u **)ga.ga_data)[ga.ga_len++] = name;
hash_add_item(&found_ht, hi, name, hash);
name = NULL;
}
}
vim_free(name);
}
vim_free(*file);
}
}
if (*e != NUL)
++e;
}
@@ -2924,7 +2983,7 @@ wildmenu_translate_key(
}
#endif
if (did_wild_list && p_wmnu)
if (did_wild_list)
{
if (c == K_LEFT)
c = Ctrl_P;
@@ -2933,7 +2992,7 @@ wildmenu_translate_key(
}
// Hitting CR after "emenu Name.": complete submenu
if (xp->xp_context == EXPAND_MENUNAMES && p_wmnu
if (xp->xp_context == EXPAND_MENUNAMES
&& cclp->cmdpos > 1
&& cclp->cmdbuff[cclp->cmdpos - 1] == '.'
&& cclp->cmdbuff[cclp->cmdpos - 2] != '\\'
@@ -2957,170 +3016,188 @@ cmdline_del(cmdline_info_T *cclp, int from)
}
/*
* Handle a key pressed when wild menu is displayed
* Handle a key pressed when the wild menu for the menu names
* (EXPAND_MENUNAMES) is displayed.
*/
int
wildmenu_process_key(cmdline_info_T *cclp, int key, expand_T *xp)
static int
wildmenu_process_key_menunames(cmdline_info_T *cclp, int key, expand_T *xp)
{
int c = key;
int i;
int j;
if (!p_wmnu)
return c;
// Special translations for 'wildmenu'
if (xp->xp_context == EXPAND_MENUNAMES)
// Hitting <Down> after "emenu Name.": complete submenu
if (key == K_DOWN && cclp->cmdpos > 0
&& cclp->cmdbuff[cclp->cmdpos - 1] == '.')
{
// Hitting <Down> after "emenu Name.": complete submenu
if (c == K_DOWN && cclp->cmdpos > 0
&& cclp->cmdbuff[cclp->cmdpos - 1] == '.')
{
c = p_wc;
KeyTyped = TRUE; // in case the key was mapped
}
else if (c == K_UP)
{
// Hitting <Up>: Remove one submenu name in front of the
// cursor
int found = FALSE;
key = p_wc;
KeyTyped = TRUE; // in case the key was mapped
}
else if (key == K_UP)
{
// Hitting <Up>: Remove one submenu name in front of the
// cursor
int found = FALSE;
j = (int)(xp->xp_pattern - cclp->cmdbuff);
i = 0;
while (--j > 0)
j = (int)(xp->xp_pattern - cclp->cmdbuff);
i = 0;
while (--j > 0)
{
// check for start of menu name
if (cclp->cmdbuff[j] == ' '
&& cclp->cmdbuff[j - 1] != '\\')
{
// check for start of menu name
if (cclp->cmdbuff[j] == ' '
&& cclp->cmdbuff[j - 1] != '\\')
i = j + 1;
break;
}
// check for start of submenu name
if (cclp->cmdbuff[j] == '.'
&& cclp->cmdbuff[j - 1] != '\\')
{
if (found)
{
i = j + 1;
break;
}
// check for start of submenu name
if (cclp->cmdbuff[j] == '.'
&& cclp->cmdbuff[j - 1] != '\\')
{
if (found)
{
i = j + 1;
break;
}
else
found = TRUE;
}
else
found = TRUE;
}
if (i > 0)
cmdline_del(cclp, i);
c = p_wc;
}
if (i > 0)
cmdline_del(cclp, i);
key = p_wc;
KeyTyped = TRUE; // in case the key was mapped
xp->xp_context = EXPAND_NOTHING;
}
return key;
}
/*
* Handle a key pressed when the wild menu for file names (EXPAND_FILES) or
* directory names (EXPAND_DIRECTORIES) or shell command names
* (EXPAND_SHELLCMD) is displayed.
*/
static int
wildmenu_process_key_filenames(cmdline_info_T *cclp, int key, expand_T *xp)
{
int i;
int j;
char_u upseg[5];
upseg[0] = PATHSEP;
upseg[1] = '.';
upseg[2] = '.';
upseg[3] = PATHSEP;
upseg[4] = NUL;
if (key == K_DOWN
&& cclp->cmdpos > 0
&& cclp->cmdbuff[cclp->cmdpos - 1] == PATHSEP
&& (cclp->cmdpos < 3
|| cclp->cmdbuff[cclp->cmdpos - 2] != '.'
|| cclp->cmdbuff[cclp->cmdpos - 3] != '.'))
{
// go down a directory
key = p_wc;
KeyTyped = TRUE; // in case the key was mapped
}
else if (STRNCMP(xp->xp_pattern, upseg + 1, 3) == 0 && key == K_DOWN)
{
// If in a direct ancestor, strip off one ../ to go down
int found = FALSE;
j = cclp->cmdpos;
i = (int)(xp->xp_pattern - cclp->cmdbuff);
while (--j > i)
{
if (has_mbyte)
j -= (*mb_head_off)(cclp->cmdbuff, cclp->cmdbuff + j);
if (vim_ispathsep(cclp->cmdbuff[j]))
{
found = TRUE;
break;
}
}
if (found
&& cclp->cmdbuff[j - 1] == '.'
&& cclp->cmdbuff[j - 2] == '.'
&& (vim_ispathsep(cclp->cmdbuff[j - 3]) || j == i + 2))
{
cmdline_del(cclp, j - 2);
key = p_wc;
KeyTyped = TRUE; // in case the key was mapped
xp->xp_context = EXPAND_NOTHING;
}
}
if ((xp->xp_context == EXPAND_FILES
|| xp->xp_context == EXPAND_DIRECTORIES
|| xp->xp_context == EXPAND_SHELLCMD))
else if (key == K_UP)
{
char_u upseg[5];
// go up a directory
int found = FALSE;
upseg[0] = PATHSEP;
upseg[1] = '.';
upseg[2] = '.';
upseg[3] = PATHSEP;
upseg[4] = NUL;
if (c == K_DOWN
&& cclp->cmdpos > 0
&& cclp->cmdbuff[cclp->cmdpos - 1] == PATHSEP
&& (cclp->cmdpos < 3
|| cclp->cmdbuff[cclp->cmdpos - 2] != '.'
|| cclp->cmdbuff[cclp->cmdpos - 3] != '.'))
j = cclp->cmdpos - 1;
i = (int)(xp->xp_pattern - cclp->cmdbuff);
while (--j > i)
{
// go down a directory
c = p_wc;
KeyTyped = TRUE; // in case the key was mapped
}
else if (STRNCMP(xp->xp_pattern, upseg + 1, 3) == 0 && c == K_DOWN)
{
// If in a direct ancestor, strip off one ../ to go down
int found = FALSE;
j = cclp->cmdpos;
i = (int)(xp->xp_pattern - cclp->cmdbuff);
while (--j > i)
if (has_mbyte)
j -= (*mb_head_off)(cclp->cmdbuff, cclp->cmdbuff + j);
if (vim_ispathsep(cclp->cmdbuff[j])
# ifdef BACKSLASH_IN_FILENAME
&& vim_strchr((char_u *)" *?[{`$%#",
cclp->cmdbuff[j + 1]) == NULL
# endif
)
{
if (has_mbyte)
j -= (*mb_head_off)(cclp->cmdbuff, cclp->cmdbuff + j);
if (vim_ispathsep(cclp->cmdbuff[j]))
if (found)
{
found = TRUE;
i = j + 1;
break;
}
}
if (found
&& cclp->cmdbuff[j - 1] == '.'
&& cclp->cmdbuff[j - 2] == '.'
&& (vim_ispathsep(cclp->cmdbuff[j - 3]) || j == i + 2))
{
cmdline_del(cclp, j - 2);
c = p_wc;
KeyTyped = TRUE; // in case the key was mapped
else
found = TRUE;
}
}
else if (c == K_UP)
if (!found)
j = i;
else if (STRNCMP(cclp->cmdbuff + j, upseg, 4) == 0)
j += 4;
else if (STRNCMP(cclp->cmdbuff + j, upseg + 1, 3) == 0
&& j == i)
j += 3;
else
j = 0;
if (j > 0)
{
// go up a directory
int found = FALSE;
j = cclp->cmdpos - 1;
i = (int)(xp->xp_pattern - cclp->cmdbuff);
while (--j > i)
{
if (has_mbyte)
j -= (*mb_head_off)(cclp->cmdbuff, cclp->cmdbuff + j);
if (vim_ispathsep(cclp->cmdbuff[j])
# ifdef BACKSLASH_IN_FILENAME
&& vim_strchr((char_u *)" *?[{`$%#",
cclp->cmdbuff[j + 1]) == NULL
# endif
)
{
if (found)
{
i = j + 1;
break;
}
else
found = TRUE;
}
}
if (!found)
j = i;
else if (STRNCMP(cclp->cmdbuff + j, upseg, 4) == 0)
j += 4;
else if (STRNCMP(cclp->cmdbuff + j, upseg + 1, 3) == 0
&& j == i)
j += 3;
else
j = 0;
if (j > 0)
{
// TODO this is only for DOS/UNIX systems - need to put in
// machine-specific stuff here and in upseg init
cmdline_del(cclp, j);
put_on_cmdline(upseg + 1, 3, FALSE);
}
else if (cclp->cmdpos > i)
cmdline_del(cclp, i);
// Now complete in the new directory. Set KeyTyped in case the
// Up key came from a mapping.
c = p_wc;
KeyTyped = TRUE;
// TODO this is only for DOS/UNIX systems - need to put in
// machine-specific stuff here and in upseg init
cmdline_del(cclp, j);
put_on_cmdline(upseg + 1, 3, FALSE);
}
else if (cclp->cmdpos > i)
cmdline_del(cclp, i);
// Now complete in the new directory. Set KeyTyped in case the
// Up key came from a mapping.
key = p_wc;
KeyTyped = TRUE;
}
return c;
return key;
}
/*
* Handle a key pressed when the wild menu is displayed
*/
int
wildmenu_process_key(cmdline_info_T *cclp, int key, expand_T *xp)
{
if (xp->xp_context == EXPAND_MENUNAMES)
return wildmenu_process_key_menunames(cclp, key, xp);
else if ((xp->xp_context == EXPAND_FILES
|| xp->xp_context == EXPAND_DIRECTORIES
|| xp->xp_context == EXPAND_SHELLCMD))
return wildmenu_process_key_filenames(cclp, key, xp);
return key;
}
/*