summaryrefslogtreecommitdiffstats
path: root/src/cmdexpand.c
diff options
context:
space:
mode:
authorYegappan Lakshmanan <yegappan@yahoo.com>2022-02-16 12:44:29 +0000
committerBram Moolenaar <Bram@vim.org>2022-02-16 12:44:29 +0000
commitb31aec3b9387ed12677dca09069c3ae98c6c7447 (patch)
tree5855230aa79d06471234f4d7627cb8a3003f77a3 /src/cmdexpand.c
parent34f8117dec685ace52cd9e578e2729db278163fc (diff)
patch 8.2.4398: some command completion functions are too longv8.2.4398
Problem: Some command completion functions are too long. Solution: Refactor code into separate functions. Add a few more tests. (Yegappan Lakshmanan, closes #9785)
Diffstat (limited to 'src/cmdexpand.c')
-rw-r--r--src/cmdexpand.c727
1 files changed, 402 insertions, 325 deletions
diff --git a/src/cmdexpand.c b/src/cmdexpand.c
index 5cad1db2d7..9d012ad4b5 100644
--- a/src/cmdexpand.c
+++ b/src/cmdexpand.c
@@ -682,6 +682,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
* be inserted like a normal character.
@@ -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;
@@ -1334,6 +1362,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'.
* For user-defined commands and for environment variables, 'compl' has the
@@ -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:
@@ -2313,20 +2336,12 @@ ExpandOther(
}
/*
- * Do the expansion based on xp->xp_context and "pat".
+ * Map wild expand options to flags for expand_wildcards()
*/
static int
-ExpandFromContext(
- expand_T *xp,
- char_u *pat,
- int *num_file,
- char_u ***file,
- int options) // WILD_ flags
+map_wildopts_to_ewflags(int options)
{
- regmatch_T regmatch;
- int ret;
int flags;
- char_u *tofree = NULL;
flags = EW_DIR; // include directories
if (options & WILD_LIST_NOTFOUND)
@@ -2342,6 +2357,27 @@ ExpandFromContext(
if (options & WILD_ALLLINKS)
flags |= EW_ALLLINKS;
+ return flags;
+}
+
+/*
+ * Do the expansion based on xp->xp_context and "pat".
+ */
+ static int
+ExpandFromContext(
+ expand_T *xp,
+ char_u *pat,
+ int *num_file,
+ char_u ***file,
+ int options) // WILD_ flags
+{
+ regmatch_T regmatch;
+ int ret;
+ int flags;
+ char_u *tofree = NULL;
+
+ flags = map_wildopts_to_ewflags(options);
+
if (xp->xp_context == EXPAND_FILES
|| xp->xp_context == EXPAND_DIRECTORIES
|| xp->xp_context == EXPAND_FILES_IN_PATH)
@@ -2550,6 +2586,64 @@ ExpandGeneric(
}
/*
+ * 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];
- 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);
- }
- }
+ expand_shellcmd_onedir(buf, s, l, pat, file, num_file, flags,
+ &found_ht, &ga);
+
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] != '\\')
+ {
+ i = j + 1;
+ break;
+ }
+ // check for start of submenu name
+ if (cclp->cmdbuff[j] == '.'
+ && cclp->cmdbuff[j - 1] != '\\')
{
- // check for start of menu 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;
- KeyTyped = TRUE; // in case the key was mapped
- xp->xp_context = EXPAND_NOTHING;
}
+ if (i > 0)
+ cmdline_del(cclp, i);
+ 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))
- {
- char_u upseg[5];
- upseg[0] = PATHSEP;
- upseg[1] = '.';
- upseg[2] = '.';
- upseg[3] = PATHSEP;
- upseg[4] = NUL;
+ return key;
+}
- 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] != '.'))
- {
- // 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;
+/*
+ * 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];
- 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))
+ 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]))
{
- cmdline_del(cclp, j - 2);
- c = p_wc;
- KeyTyped = TRUE; // in case the key was mapped
+ found = TRUE;
+ break;
}
}
- else if (c == K_UP)
+ if (found
+ && cclp->cmdbuff[j - 1] == '.'
+ && cclp->cmdbuff[j - 2] == '.'
+ && (vim_ispathsep(cclp->cmdbuff[j - 3]) || j == i + 2))
{
- // go up a directory
- int found = FALSE;
+ cmdline_del(cclp, j - 2);
+ key = p_wc;
+ KeyTyped = TRUE; // in case the key was mapped
+ }
+ }
+ else if (key == K_UP)
+ {
+ // 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])
+ 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
+ && vim_strchr((char_u *)" *?[{`$%#",
+ cclp->cmdbuff[j + 1]) == NULL
# endif
- )
+ )
+ {
+ if (found)
{
- if (found)
- {
- i = j + 1;
- break;
- }
- else
- found = TRUE;
+ 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;
+ 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.
+ 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;
}
/*