diff --git a/src/cmdexpand.c b/src/cmdexpand.c
index 5cad1db..9d012ad 100644
--- a/src/cmdexpand.c
+++ b/src/cmdexpand.c
@@ -682,6 +682,98 @@
 }
 
 /*
+ * 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 @@
     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 @@
 	showtail = expand_showtail(xp);
 	if (i != EXPAND_OK)
 	    return i;
-
     }
     else
     {
@@ -789,69 +878,8 @@
 	// 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 @@
 }
 
 /*
+ * 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 @@
 	    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 @@
 	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 @@
 #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,6 +2336,31 @@
 }
 
 /*
+ * 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".
  */
     static int
@@ -2328,19 +2376,7 @@
     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
@@ -2550,6 +2586,64 @@
 }
 
 /*
+ * 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 @@
     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 @@
 	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 @@
     }
 #endif
 
-    if (did_wild_list && p_wmnu)
+    if (did_wild_list)
     {
 	if (c == K_LEFT)
 	    c = Ctrl_P;
@@ -2933,7 +2992,7 @@
     }
 
     // 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 @@
 }
 
 /*
- * 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;
 }
 
 /*
