xref: /vim-8.2.3635/src/cmdexpand.c (revision dfe04dbf)
1 /* vi:set ts=8 sts=4 sw=4 noet:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
5  * Do ":help uganda"  in Vim to read copying and usage conditions.
6  * Do ":help credits" in Vim to see a list of people who contributed.
7  * See README.txt for an overview of the Vim source code.
8  */
9 
10 /*
11  * cmdexpand.c: functions for command-line completion
12  */
13 
14 #include "vim.h"
15 
16 static int	cmd_showtail;	// Only show path tail in lists ?
17 
18 static void	set_expand_context(expand_T *xp);
19 static int      ExpandGeneric(expand_T *xp, regmatch_T *regmatch,
20 			      int *num_file, char_u ***file,
21 			      char_u *((*func)(expand_T *, int)), int escaped);
22 static int	ExpandFromContext(expand_T *xp, char_u *, int *, char_u ***, int);
23 static int	expand_showtail(expand_T *xp);
24 static int	expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, int flagsarg);
25 #if defined(FEAT_EVAL)
26 static int	ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file);
27 static int	ExpandUserList(expand_T *xp, int *num_file, char_u ***file);
28 #endif
29 
30     static int
31 sort_func_compare(const void *s1, const void *s2)
32 {
33     char_u *p1 = *(char_u **)s1;
34     char_u *p2 = *(char_u **)s2;
35 
36     if (*p1 != '<' && *p2 == '<') return -1;
37     if (*p1 == '<' && *p2 != '<') return 1;
38     return STRCMP(p1, p2);
39 }
40 
41     static void
42 ExpandEscape(
43     expand_T	*xp,
44     char_u	*str,
45     int		numfiles,
46     char_u	**files,
47     int		options)
48 {
49     int		i;
50     char_u	*p;
51 
52     // May change home directory back to "~"
53     if (options & WILD_HOME_REPLACE)
54 	tilde_replace(str, numfiles, files);
55 
56     if (options & WILD_ESCAPE)
57     {
58 	if (xp->xp_context == EXPAND_FILES
59 		|| xp->xp_context == EXPAND_FILES_IN_PATH
60 		|| xp->xp_context == EXPAND_SHELLCMD
61 		|| xp->xp_context == EXPAND_BUFFERS
62 		|| xp->xp_context == EXPAND_DIRECTORIES)
63 	{
64 	    // Insert a backslash into a file name before a space, \, %, #
65 	    // and wildmatch characters, except '~'.
66 	    for (i = 0; i < numfiles; ++i)
67 	    {
68 		// for ":set path=" we need to escape spaces twice
69 		if (xp->xp_backslash == XP_BS_THREE)
70 		{
71 		    p = vim_strsave_escaped(files[i], (char_u *)" ");
72 		    if (p != NULL)
73 		    {
74 			vim_free(files[i]);
75 			files[i] = p;
76 #if defined(BACKSLASH_IN_FILENAME)
77 			p = vim_strsave_escaped(files[i], (char_u *)" ");
78 			if (p != NULL)
79 			{
80 			    vim_free(files[i]);
81 			    files[i] = p;
82 			}
83 #endif
84 		    }
85 		}
86 #ifdef BACKSLASH_IN_FILENAME
87 		p = vim_strsave_fnameescape(files[i], FALSE);
88 #else
89 		p = vim_strsave_fnameescape(files[i], xp->xp_shell);
90 #endif
91 		if (p != NULL)
92 		{
93 		    vim_free(files[i]);
94 		    files[i] = p;
95 		}
96 
97 		// If 'str' starts with "\~", replace "~" at start of
98 		// files[i] with "\~".
99 		if (str[0] == '\\' && str[1] == '~' && files[i][0] == '~')
100 		    escape_fname(&files[i]);
101 	    }
102 	    xp->xp_backslash = XP_BS_NONE;
103 
104 	    // If the first file starts with a '+' escape it.  Otherwise it
105 	    // could be seen as "+cmd".
106 	    if (*files[0] == '+')
107 		escape_fname(&files[0]);
108 	}
109 	else if (xp->xp_context == EXPAND_TAGS)
110 	{
111 	    // Insert a backslash before characters in a tag name that
112 	    // would terminate the ":tag" command.
113 	    for (i = 0; i < numfiles; ++i)
114 	    {
115 		p = vim_strsave_escaped(files[i], (char_u *)"\\|\"");
116 		if (p != NULL)
117 		{
118 		    vim_free(files[i]);
119 		    files[i] = p;
120 		}
121 	    }
122 	}
123     }
124 }
125 
126 /*
127  * Return FAIL if this is not an appropriate context in which to do
128  * completion of anything, return OK if it is (even if there are no matches).
129  * For the caller, this means that the character is just passed through like a
130  * normal character (instead of being expanded).  This allows :s/^I^D etc.
131  */
132     int
133 nextwild(
134     expand_T	*xp,
135     int		type,
136     int		options,	// extra options for ExpandOne()
137     int		escape)		// if TRUE, escape the returned matches
138 {
139     cmdline_info_T	*ccline = get_cmdline_info();
140     int		i, j;
141     char_u	*p1;
142     char_u	*p2;
143     int		difflen;
144     int		v;
145 
146     if (xp->xp_numfiles == -1)
147     {
148 	set_expand_context(xp);
149 	cmd_showtail = expand_showtail(xp);
150     }
151 
152     if (xp->xp_context == EXPAND_UNSUCCESSFUL)
153     {
154 	beep_flush();
155 	return OK;  // Something illegal on command line
156     }
157     if (xp->xp_context == EXPAND_NOTHING)
158     {
159 	// Caller can use the character as a normal char instead
160 	return FAIL;
161     }
162 
163     msg_puts("...");	    // show that we are busy
164     out_flush();
165 
166     i = (int)(xp->xp_pattern - ccline->cmdbuff);
167     xp->xp_pattern_len = ccline->cmdpos - i;
168 
169     if (type == WILD_NEXT || type == WILD_PREV)
170     {
171 	// Get next/previous match for a previous expanded pattern.
172 	p2 = ExpandOne(xp, NULL, NULL, 0, type);
173     }
174     else
175     {
176 	// Translate string into pattern and expand it.
177 	if ((p1 = addstar(xp->xp_pattern, xp->xp_pattern_len,
178 						     xp->xp_context)) == NULL)
179 	    p2 = NULL;
180 	else
181 	{
182 	    int use_options = options |
183 		    WILD_HOME_REPLACE|WILD_ADD_SLASH|WILD_SILENT;
184 	    if (escape)
185 		use_options |= WILD_ESCAPE;
186 
187 	    if (p_wic)
188 		use_options += WILD_ICASE;
189 	    p2 = ExpandOne(xp, p1,
190 			 vim_strnsave(&ccline->cmdbuff[i], xp->xp_pattern_len),
191 							   use_options, type);
192 	    vim_free(p1);
193 	    // longest match: make sure it is not shorter, happens with :help
194 	    if (p2 != NULL && type == WILD_LONGEST)
195 	    {
196 		for (j = 0; j < xp->xp_pattern_len; ++j)
197 		     if (ccline->cmdbuff[i + j] == '*'
198 			     || ccline->cmdbuff[i + j] == '?')
199 			 break;
200 		if ((int)STRLEN(p2) < j)
201 		    VIM_CLEAR(p2);
202 	    }
203 	}
204     }
205 
206     if (p2 != NULL && !got_int)
207     {
208 	difflen = (int)STRLEN(p2) - xp->xp_pattern_len;
209 	if (ccline->cmdlen + difflen + 4 > ccline->cmdbufflen)
210 	{
211 	    v = realloc_cmdbuff(ccline->cmdlen + difflen + 4);
212 	    xp->xp_pattern = ccline->cmdbuff + i;
213 	}
214 	else
215 	    v = OK;
216 	if (v == OK)
217 	{
218 	    mch_memmove(&ccline->cmdbuff[ccline->cmdpos + difflen],
219 		    &ccline->cmdbuff[ccline->cmdpos],
220 		    (size_t)(ccline->cmdlen - ccline->cmdpos + 1));
221 	    mch_memmove(&ccline->cmdbuff[i], p2, STRLEN(p2));
222 	    ccline->cmdlen += difflen;
223 	    ccline->cmdpos += difflen;
224 	}
225     }
226     vim_free(p2);
227 
228     redrawcmd();
229     cursorcmd();
230 
231     // When expanding a ":map" command and no matches are found, assume that
232     // the key is supposed to be inserted literally
233     if (xp->xp_context == EXPAND_MAPPINGS && p2 == NULL)
234 	return FAIL;
235 
236     if (xp->xp_numfiles <= 0 && p2 == NULL)
237 	beep_flush();
238     else if (xp->xp_numfiles == 1)
239 	// free expanded pattern
240 	(void)ExpandOne(xp, NULL, NULL, 0, WILD_FREE);
241 
242     return OK;
243 }
244 
245 /*
246  * Do wildcard expansion on the string 'str'.
247  * Chars that should not be expanded must be preceded with a backslash.
248  * Return a pointer to allocated memory containing the new string.
249  * Return NULL for failure.
250  *
251  * "orig" is the originally expanded string, copied to allocated memory.  It
252  * should either be kept in orig_save or freed.  When "mode" is WILD_NEXT or
253  * WILD_PREV "orig" should be NULL.
254  *
255  * Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode"
256  * is WILD_EXPAND_FREE or WILD_ALL.
257  *
258  * mode = WILD_FREE:	    just free previously expanded matches
259  * mode = WILD_EXPAND_FREE: normal expansion, do not keep matches
260  * mode = WILD_EXPAND_KEEP: normal expansion, keep matches
261  * mode = WILD_NEXT:	    use next match in multiple match, wrap to first
262  * mode = WILD_PREV:	    use previous match in multiple match, wrap to first
263  * mode = WILD_ALL:	    return all matches concatenated
264  * mode = WILD_LONGEST:	    return longest matched part
265  * mode = WILD_ALL_KEEP:    get all matches, keep matches
266  *
267  * options = WILD_LIST_NOTFOUND:    list entries without a match
268  * options = WILD_HOME_REPLACE:	    do home_replace() for buffer names
269  * options = WILD_USE_NL:	    Use '\n' for WILD_ALL
270  * options = WILD_NO_BEEP:	    Don't beep for multiple matches
271  * options = WILD_ADD_SLASH:	    add a slash after directory names
272  * options = WILD_KEEP_ALL:	    don't remove 'wildignore' entries
273  * options = WILD_SILENT:	    don't print warning messages
274  * options = WILD_ESCAPE:	    put backslash before special chars
275  * options = WILD_ICASE:	    ignore case for files
276  * options = WILD_ALLLINKS;	    keep broken links
277  *
278  * The variables xp->xp_context and xp->xp_backslash must have been set!
279  */
280     char_u *
281 ExpandOne(
282     expand_T	*xp,
283     char_u	*str,
284     char_u	*orig,	    // allocated copy of original of expanded string
285     int		options,
286     int		mode)
287 {
288     char_u	*ss = NULL;
289     static int	findex;
290     static char_u *orig_save = NULL;	// kept value of orig
291     int		orig_saved = FALSE;
292     int		i;
293     long_u	len;
294     int		non_suf_match;		// number without matching suffix
295 
296     // first handle the case of using an old match
297     if (mode == WILD_NEXT || mode == WILD_PREV)
298     {
299 	if (xp->xp_numfiles > 0)
300 	{
301 	    if (mode == WILD_PREV)
302 	    {
303 		if (findex == -1)
304 		    findex = xp->xp_numfiles;
305 		--findex;
306 	    }
307 	    else    // mode == WILD_NEXT
308 		++findex;
309 
310 	    // When wrapping around, return the original string, set findex to
311 	    // -1.
312 	    if (findex < 0)
313 	    {
314 		if (orig_save == NULL)
315 		    findex = xp->xp_numfiles - 1;
316 		else
317 		    findex = -1;
318 	    }
319 	    if (findex >= xp->xp_numfiles)
320 	    {
321 		if (orig_save == NULL)
322 		    findex = 0;
323 		else
324 		    findex = -1;
325 	    }
326 #ifdef FEAT_WILDMENU
327 	    if (p_wmnu)
328 		win_redr_status_matches(xp, xp->xp_numfiles, xp->xp_files,
329 							findex, cmd_showtail);
330 #endif
331 	    if (findex == -1)
332 		return vim_strsave(orig_save);
333 	    return vim_strsave(xp->xp_files[findex]);
334 	}
335 	else
336 	    return NULL;
337     }
338 
339     // free old names
340     if (xp->xp_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST)
341     {
342 	FreeWild(xp->xp_numfiles, xp->xp_files);
343 	xp->xp_numfiles = -1;
344 	VIM_CLEAR(orig_save);
345     }
346     findex = 0;
347 
348     if (mode == WILD_FREE)	// only release file name
349 	return NULL;
350 
351     if (xp->xp_numfiles == -1)
352     {
353 	vim_free(orig_save);
354 	orig_save = orig;
355 	orig_saved = TRUE;
356 
357 	// Do the expansion.
358 	if (ExpandFromContext(xp, str, &xp->xp_numfiles, &xp->xp_files,
359 							     options) == FAIL)
360 	{
361 #ifdef FNAME_ILLEGAL
362 	    // Illegal file name has been silently skipped.  But when there
363 	    // are wildcards, the real problem is that there was no match,
364 	    // causing the pattern to be added, which has illegal characters.
365 	    if (!(options & WILD_SILENT) && (options & WILD_LIST_NOTFOUND))
366 		semsg(_(e_nomatch2), str);
367 #endif
368 	}
369 	else if (xp->xp_numfiles == 0)
370 	{
371 	    if (!(options & WILD_SILENT))
372 		semsg(_(e_nomatch2), str);
373 	}
374 	else
375 	{
376 	    // Escape the matches for use on the command line.
377 	    ExpandEscape(xp, str, xp->xp_numfiles, xp->xp_files, options);
378 
379 	    // Check for matching suffixes in file names.
380 	    if (mode != WILD_ALL && mode != WILD_ALL_KEEP
381 						      && mode != WILD_LONGEST)
382 	    {
383 		if (xp->xp_numfiles)
384 		    non_suf_match = xp->xp_numfiles;
385 		else
386 		    non_suf_match = 1;
387 		if ((xp->xp_context == EXPAND_FILES
388 			    || xp->xp_context == EXPAND_DIRECTORIES)
389 			&& xp->xp_numfiles > 1)
390 		{
391 		    // More than one match; check suffix.
392 		    // The files will have been sorted on matching suffix in
393 		    // expand_wildcards, only need to check the first two.
394 		    non_suf_match = 0;
395 		    for (i = 0; i < 2; ++i)
396 			if (match_suffix(xp->xp_files[i]))
397 			    ++non_suf_match;
398 		}
399 		if (non_suf_match != 1)
400 		{
401 		    // Can we ever get here unless it's while expanding
402 		    // interactively?  If not, we can get rid of this all
403 		    // together. Don't really want to wait for this message
404 		    // (and possibly have to hit return to continue!).
405 		    if (!(options & WILD_SILENT))
406 			emsg(_(e_toomany));
407 		    else if (!(options & WILD_NO_BEEP))
408 			beep_flush();
409 		}
410 		if (!(non_suf_match != 1 && mode == WILD_EXPAND_FREE))
411 		    ss = vim_strsave(xp->xp_files[0]);
412 	    }
413 	}
414     }
415 
416     // Find longest common part
417     if (mode == WILD_LONGEST && xp->xp_numfiles > 0)
418     {
419 	int mb_len = 1;
420 	int c0, ci;
421 
422 	for (len = 0; xp->xp_files[0][len]; len += mb_len)
423 	{
424 	    if (has_mbyte)
425 	    {
426 		mb_len = (*mb_ptr2len)(&xp->xp_files[0][len]);
427 		c0 =(* mb_ptr2char)(&xp->xp_files[0][len]);
428 	    }
429 	    else
430 		c0 = xp->xp_files[0][len];
431 	    for (i = 1; i < xp->xp_numfiles; ++i)
432 	    {
433 		if (has_mbyte)
434 		    ci =(* mb_ptr2char)(&xp->xp_files[i][len]);
435 		else
436 		    ci = xp->xp_files[i][len];
437 		if (p_fic && (xp->xp_context == EXPAND_DIRECTORIES
438 			|| xp->xp_context == EXPAND_FILES
439 			|| xp->xp_context == EXPAND_SHELLCMD
440 			|| xp->xp_context == EXPAND_BUFFERS))
441 		{
442 		    if (MB_TOLOWER(c0) != MB_TOLOWER(ci))
443 			break;
444 		}
445 		else if (c0 != ci)
446 		    break;
447 	    }
448 	    if (i < xp->xp_numfiles)
449 	    {
450 		if (!(options & WILD_NO_BEEP))
451 		    vim_beep(BO_WILD);
452 		break;
453 	    }
454 	}
455 
456 	ss = alloc(len + 1);
457 	if (ss)
458 	    vim_strncpy(ss, xp->xp_files[0], (size_t)len);
459 	findex = -1;			    // next p_wc gets first one
460     }
461 
462     // Concatenate all matching names
463     if (mode == WILD_ALL && xp->xp_numfiles > 0)
464     {
465 	len = 0;
466 	for (i = 0; i < xp->xp_numfiles; ++i)
467 	    len += (long_u)STRLEN(xp->xp_files[i]) + 1;
468 	ss = alloc(len);
469 	if (ss != NULL)
470 	{
471 	    *ss = NUL;
472 	    for (i = 0; i < xp->xp_numfiles; ++i)
473 	    {
474 		STRCAT(ss, xp->xp_files[i]);
475 		if (i != xp->xp_numfiles - 1)
476 		    STRCAT(ss, (options & WILD_USE_NL) ? "\n" : " ");
477 	    }
478 	}
479     }
480 
481     if (mode == WILD_EXPAND_FREE || mode == WILD_ALL)
482 	ExpandCleanup(xp);
483 
484     // Free "orig" if it wasn't stored in "orig_save".
485     if (!orig_saved)
486 	vim_free(orig);
487 
488     return ss;
489 }
490 
491 /*
492  * Prepare an expand structure for use.
493  */
494     void
495 ExpandInit(expand_T *xp)
496 {
497     CLEAR_POINTER(xp);
498     xp->xp_backslash = XP_BS_NONE;
499     xp->xp_numfiles = -1;
500 }
501 
502 /*
503  * Cleanup an expand structure after use.
504  */
505     void
506 ExpandCleanup(expand_T *xp)
507 {
508     if (xp->xp_numfiles >= 0)
509     {
510 	FreeWild(xp->xp_numfiles, xp->xp_files);
511 	xp->xp_numfiles = -1;
512     }
513 }
514 
515 /*
516  * Show all matches for completion on the command line.
517  * Returns EXPAND_NOTHING when the character that triggered expansion should
518  * be inserted like a normal character.
519  */
520     int
521 showmatches(expand_T *xp, int wildmenu UNUSED)
522 {
523     cmdline_info_T	*ccline = get_cmdline_info();
524 #define L_SHOWFILE(m) (showtail ? sm_gettail(files_found[m]) : files_found[m])
525     int		num_files;
526     char_u	**files_found;
527     int		i, j, k;
528     int		maxlen;
529     int		lines;
530     int		columns;
531     char_u	*p;
532     int		lastlen;
533     int		attr;
534     int		showtail;
535 
536     if (xp->xp_numfiles == -1)
537     {
538 	set_expand_context(xp);
539 	i = expand_cmdline(xp, ccline->cmdbuff, ccline->cmdpos,
540 						    &num_files, &files_found);
541 	showtail = expand_showtail(xp);
542 	if (i != EXPAND_OK)
543 	    return i;
544 
545     }
546     else
547     {
548 	num_files = xp->xp_numfiles;
549 	files_found = xp->xp_files;
550 	showtail = cmd_showtail;
551     }
552 
553 #ifdef FEAT_WILDMENU
554     if (!wildmenu)
555     {
556 #endif
557 	msg_didany = FALSE;		// lines_left will be set
558 	msg_start();			// prepare for paging
559 	msg_putchar('\n');
560 	out_flush();
561 	cmdline_row = msg_row;
562 	msg_didany = FALSE;		// lines_left will be set again
563 	msg_start();			// prepare for paging
564 #ifdef FEAT_WILDMENU
565     }
566 #endif
567 
568     if (got_int)
569 	got_int = FALSE;	// only int. the completion, not the cmd line
570 #ifdef FEAT_WILDMENU
571     else if (wildmenu)
572 	win_redr_status_matches(xp, num_files, files_found, -1, showtail);
573 #endif
574     else
575     {
576 	// find the length of the longest file name
577 	maxlen = 0;
578 	for (i = 0; i < num_files; ++i)
579 	{
580 	    if (!showtail && (xp->xp_context == EXPAND_FILES
581 			  || xp->xp_context == EXPAND_SHELLCMD
582 			  || xp->xp_context == EXPAND_BUFFERS))
583 	    {
584 		home_replace(NULL, files_found[i], NameBuff, MAXPATHL, TRUE);
585 		j = vim_strsize(NameBuff);
586 	    }
587 	    else
588 		j = vim_strsize(L_SHOWFILE(i));
589 	    if (j > maxlen)
590 		maxlen = j;
591 	}
592 
593 	if (xp->xp_context == EXPAND_TAGS_LISTFILES)
594 	    lines = num_files;
595 	else
596 	{
597 	    // compute the number of columns and lines for the listing
598 	    maxlen += 2;    // two spaces between file names
599 	    columns = ((int)Columns + 2) / maxlen;
600 	    if (columns < 1)
601 		columns = 1;
602 	    lines = (num_files + columns - 1) / columns;
603 	}
604 
605 	attr = HL_ATTR(HLF_D);	// find out highlighting for directories
606 
607 	if (xp->xp_context == EXPAND_TAGS_LISTFILES)
608 	{
609 	    msg_puts_attr(_("tagname"), HL_ATTR(HLF_T));
610 	    msg_clr_eos();
611 	    msg_advance(maxlen - 3);
612 	    msg_puts_attr(_(" kind file\n"), HL_ATTR(HLF_T));
613 	}
614 
615 	// list the files line by line
616 	for (i = 0; i < lines; ++i)
617 	{
618 	    lastlen = 999;
619 	    for (k = i; k < num_files; k += lines)
620 	    {
621 		if (xp->xp_context == EXPAND_TAGS_LISTFILES)
622 		{
623 		    msg_outtrans_attr(files_found[k], HL_ATTR(HLF_D));
624 		    p = files_found[k] + STRLEN(files_found[k]) + 1;
625 		    msg_advance(maxlen + 1);
626 		    msg_puts((char *)p);
627 		    msg_advance(maxlen + 3);
628 		    msg_outtrans_long_attr(p + 2, HL_ATTR(HLF_D));
629 		    break;
630 		}
631 		for (j = maxlen - lastlen; --j >= 0; )
632 		    msg_putchar(' ');
633 		if (xp->xp_context == EXPAND_FILES
634 					  || xp->xp_context == EXPAND_SHELLCMD
635 					  || xp->xp_context == EXPAND_BUFFERS)
636 		{
637 		    // highlight directories
638 		    if (xp->xp_numfiles != -1)
639 		    {
640 			char_u	*halved_slash;
641 			char_u	*exp_path;
642 			char_u	*path;
643 
644 			// Expansion was done before and special characters
645 			// were escaped, need to halve backslashes.  Also
646 			// $HOME has been replaced with ~/.
647 			exp_path = expand_env_save_opt(files_found[k], TRUE);
648 			path = exp_path != NULL ? exp_path : files_found[k];
649 			halved_slash = backslash_halve_save(path);
650 			j = mch_isdir(halved_slash != NULL ? halved_slash
651 							    : files_found[k]);
652 			vim_free(exp_path);
653 			if (halved_slash != path)
654 			    vim_free(halved_slash);
655 		    }
656 		    else
657 			// Expansion was done here, file names are literal.
658 			j = mch_isdir(files_found[k]);
659 		    if (showtail)
660 			p = L_SHOWFILE(k);
661 		    else
662 		    {
663 			home_replace(NULL, files_found[k], NameBuff, MAXPATHL,
664 									TRUE);
665 			p = NameBuff;
666 		    }
667 		}
668 		else
669 		{
670 		    j = FALSE;
671 		    p = L_SHOWFILE(k);
672 		}
673 		lastlen = msg_outtrans_attr(p, j ? attr : 0);
674 	    }
675 	    if (msg_col > 0)	// when not wrapped around
676 	    {
677 		msg_clr_eos();
678 		msg_putchar('\n');
679 	    }
680 	    out_flush();		    // show one line at a time
681 	    if (got_int)
682 	    {
683 		got_int = FALSE;
684 		break;
685 	    }
686 	}
687 
688 	// we redraw the command below the lines that we have just listed
689 	// This is a bit tricky, but it saves a lot of screen updating.
690 	cmdline_row = msg_row;	// will put it back later
691     }
692 
693     if (xp->xp_numfiles == -1)
694 	FreeWild(num_files, files_found);
695 
696     return EXPAND_OK;
697 }
698 
699 /*
700  * Private gettail for showmatches() (and win_redr_status_matches()):
701  * Find tail of file name path, but ignore trailing "/".
702  */
703     char_u *
704 sm_gettail(char_u *s)
705 {
706     char_u	*p;
707     char_u	*t = s;
708     int		had_sep = FALSE;
709 
710     for (p = s; *p != NUL; )
711     {
712 	if (vim_ispathsep(*p)
713 #ifdef BACKSLASH_IN_FILENAME
714 		&& !rem_backslash(p)
715 #endif
716 	   )
717 	    had_sep = TRUE;
718 	else if (had_sep)
719 	{
720 	    t = p;
721 	    had_sep = FALSE;
722 	}
723 	MB_PTR_ADV(p);
724     }
725     return t;
726 }
727 
728 /*
729  * Return TRUE if we only need to show the tail of completion matches.
730  * When not completing file names or there is a wildcard in the path FALSE is
731  * returned.
732  */
733     static int
734 expand_showtail(expand_T *xp)
735 {
736     char_u	*s;
737     char_u	*end;
738 
739     // When not completing file names a "/" may mean something different.
740     if (xp->xp_context != EXPAND_FILES
741 	    && xp->xp_context != EXPAND_SHELLCMD
742 	    && xp->xp_context != EXPAND_DIRECTORIES)
743 	return FALSE;
744 
745     end = gettail(xp->xp_pattern);
746     if (end == xp->xp_pattern)		// there is no path separator
747 	return FALSE;
748 
749     for (s = xp->xp_pattern; s < end; s++)
750     {
751 	// Skip escaped wildcards.  Only when the backslash is not a path
752 	// separator, on DOS the '*' "path\*\file" must not be skipped.
753 	if (rem_backslash(s))
754 	    ++s;
755 	else if (vim_strchr((char_u *)"*?[", *s) != NULL)
756 	    return FALSE;
757     }
758     return TRUE;
759 }
760 
761 /*
762  * Prepare a string for expansion.
763  * When expanding file names: The string will be used with expand_wildcards().
764  * Copy "fname[len]" into allocated memory and add a '*' at the end.
765  * When expanding other names: The string will be used with regcomp().  Copy
766  * the name into allocated memory and prepend "^".
767  */
768     char_u *
769 addstar(
770     char_u	*fname,
771     int		len,
772     int		context)	// EXPAND_FILES etc.
773 {
774     char_u	*retval;
775     int		i, j;
776     int		new_len;
777     char_u	*tail;
778     int		ends_in_star;
779 
780     if (context != EXPAND_FILES
781 	    && context != EXPAND_FILES_IN_PATH
782 	    && context != EXPAND_SHELLCMD
783 	    && context != EXPAND_DIRECTORIES)
784     {
785 	// Matching will be done internally (on something other than files).
786 	// So we convert the file-matching-type wildcards into our kind for
787 	// use with vim_regcomp().  First work out how long it will be:
788 
789 	// For help tags the translation is done in find_help_tags().
790 	// For a tag pattern starting with "/" no translation is needed.
791 	if (context == EXPAND_HELP
792 		|| context == EXPAND_COLORS
793 		|| context == EXPAND_COMPILER
794 		|| context == EXPAND_OWNSYNTAX
795 		|| context == EXPAND_FILETYPE
796 		|| context == EXPAND_PACKADD
797 		|| ((context == EXPAND_TAGS_LISTFILES
798 			|| context == EXPAND_TAGS)
799 		    && fname[0] == '/'))
800 	    retval = vim_strnsave(fname, len);
801 	else
802 	{
803 	    new_len = len + 2;		// +2 for '^' at start, NUL at end
804 	    for (i = 0; i < len; i++)
805 	    {
806 		if (fname[i] == '*' || fname[i] == '~')
807 		    new_len++;		// '*' needs to be replaced by ".*"
808 					// '~' needs to be replaced by "\~"
809 
810 		// Buffer names are like file names.  "." should be literal
811 		if (context == EXPAND_BUFFERS && fname[i] == '.')
812 		    new_len++;		// "." becomes "\."
813 
814 		// Custom expansion takes care of special things, match
815 		// backslashes literally (perhaps also for other types?)
816 		if ((context == EXPAND_USER_DEFINED
817 			  || context == EXPAND_USER_LIST) && fname[i] == '\\')
818 		    new_len++;		// '\' becomes "\\"
819 	    }
820 	    retval = alloc(new_len);
821 	    if (retval != NULL)
822 	    {
823 		retval[0] = '^';
824 		j = 1;
825 		for (i = 0; i < len; i++, j++)
826 		{
827 		    // Skip backslash.  But why?  At least keep it for custom
828 		    // expansion.
829 		    if (context != EXPAND_USER_DEFINED
830 			    && context != EXPAND_USER_LIST
831 			    && fname[i] == '\\'
832 			    && ++i == len)
833 			break;
834 
835 		    switch (fname[i])
836 		    {
837 			case '*':   retval[j++] = '.';
838 				    break;
839 			case '~':   retval[j++] = '\\';
840 				    break;
841 			case '?':   retval[j] = '.';
842 				    continue;
843 			case '.':   if (context == EXPAND_BUFFERS)
844 					retval[j++] = '\\';
845 				    break;
846 			case '\\':  if (context == EXPAND_USER_DEFINED
847 					    || context == EXPAND_USER_LIST)
848 					retval[j++] = '\\';
849 				    break;
850 		    }
851 		    retval[j] = fname[i];
852 		}
853 		retval[j] = NUL;
854 	    }
855 	}
856     }
857     else
858     {
859 	retval = alloc(len + 4);
860 	if (retval != NULL)
861 	{
862 	    vim_strncpy(retval, fname, len);
863 
864 	    // Don't add a star to *, ~, ~user, $var or `cmd`.
865 	    // * would become **, which walks the whole tree.
866 	    // ~ would be at the start of the file name, but not the tail.
867 	    // $ could be anywhere in the tail.
868 	    // ` could be anywhere in the file name.
869 	    // When the name ends in '$' don't add a star, remove the '$'.
870 	    tail = gettail(retval);
871 	    ends_in_star = (len > 0 && retval[len - 1] == '*');
872 #ifndef BACKSLASH_IN_FILENAME
873 	    for (i = len - 2; i >= 0; --i)
874 	    {
875 		if (retval[i] != '\\')
876 		    break;
877 		ends_in_star = !ends_in_star;
878 	    }
879 #endif
880 	    if ((*retval != '~' || tail != retval)
881 		    && !ends_in_star
882 		    && vim_strchr(tail, '$') == NULL
883 		    && vim_strchr(retval, '`') == NULL)
884 		retval[len++] = '*';
885 	    else if (len > 0 && retval[len - 1] == '$')
886 		--len;
887 	    retval[len] = NUL;
888 	}
889     }
890     return retval;
891 }
892 
893 /*
894  * Must parse the command line so far to work out what context we are in.
895  * Completion can then be done based on that context.
896  * This routine sets the variables:
897  *  xp->xp_pattern	    The start of the pattern to be expanded within
898  *				the command line (ends at the cursor).
899  *  xp->xp_context	    The type of thing to expand.  Will be one of:
900  *
901  *  EXPAND_UNSUCCESSFUL	    Used sometimes when there is something illegal on
902  *			    the command line, like an unknown command.	Caller
903  *			    should beep.
904  *  EXPAND_NOTHING	    Unrecognised context for completion, use char like
905  *			    a normal char, rather than for completion.	eg
906  *			    :s/^I/
907  *  EXPAND_COMMANDS	    Cursor is still touching the command, so complete
908  *			    it.
909  *  EXPAND_BUFFERS	    Complete file names for :buf and :sbuf commands.
910  *  EXPAND_FILES	    After command with EX_XFILE set, or after setting
911  *			    with P_EXPAND set.	eg :e ^I, :w>>^I
912  *  EXPAND_DIRECTORIES	    In some cases this is used instead of the latter
913  *			    when we know only directories are of interest.  eg
914  *			    :set dir=^I
915  *  EXPAND_SHELLCMD	    After ":!cmd", ":r !cmd"  or ":w !cmd".
916  *  EXPAND_SETTINGS	    Complete variable names.  eg :set d^I
917  *  EXPAND_BOOL_SETTINGS    Complete boolean variables only,  eg :set no^I
918  *  EXPAND_TAGS		    Complete tags from the files in p_tags.  eg :ta a^I
919  *  EXPAND_TAGS_LISTFILES   As above, but list filenames on ^D, after :tselect
920  *  EXPAND_HELP		    Complete tags from the file 'helpfile'/tags
921  *  EXPAND_EVENTS	    Complete event names
922  *  EXPAND_SYNTAX	    Complete :syntax command arguments
923  *  EXPAND_HIGHLIGHT	    Complete highlight (syntax) group names
924  *  EXPAND_AUGROUP	    Complete autocommand group names
925  *  EXPAND_USER_VARS	    Complete user defined variable names, eg :unlet a^I
926  *  EXPAND_MAPPINGS	    Complete mapping and abbreviation names,
927  *			      eg :unmap a^I , :cunab x^I
928  *  EXPAND_FUNCTIONS	    Complete internal or user defined function names,
929  *			      eg :call sub^I
930  *  EXPAND_USER_FUNC	    Complete user defined function names, eg :delf F^I
931  *  EXPAND_EXPRESSION	    Complete internal or user defined function/variable
932  *			    names in expressions, eg :while s^I
933  *  EXPAND_ENV_VARS	    Complete environment variable names
934  *  EXPAND_USER		    Complete user names
935  */
936     static void
937 set_expand_context(expand_T *xp)
938 {
939     cmdline_info_T	*ccline = get_cmdline_info();
940 
941     // only expansion for ':', '>' and '=' command-lines
942     if (ccline->cmdfirstc != ':'
943 #ifdef FEAT_EVAL
944 	    && ccline->cmdfirstc != '>' && ccline->cmdfirstc != '='
945 	    && !ccline->input_fn
946 #endif
947 	    )
948     {
949 	xp->xp_context = EXPAND_NOTHING;
950 	return;
951     }
952     set_cmd_context(xp, ccline->cmdbuff, ccline->cmdlen, ccline->cmdpos, TRUE);
953 }
954 
955 /*
956  * This is all pretty much copied from do_one_cmd(), with all the extra stuff
957  * we don't need/want deleted.	Maybe this could be done better if we didn't
958  * repeat all this stuff.  The only problem is that they may not stay
959  * perfectly compatible with each other, but then the command line syntax
960  * probably won't change that much -- webb.
961  */
962     static char_u *
963 set_one_cmd_context(
964     expand_T	*xp,
965     char_u	*buff)	    // buffer for command string
966 {
967     char_u		*p;
968     char_u		*cmd, *arg;
969     int			len = 0;
970     exarg_T		ea;
971     int			compl = EXPAND_NOTHING;
972     int			delim;
973     int			forceit = FALSE;
974     int			usefilter = FALSE;  // filter instead of file name
975 
976     ExpandInit(xp);
977     xp->xp_pattern = buff;
978     xp->xp_context = EXPAND_COMMANDS;	// Default until we get past command
979     ea.argt = 0;
980 
981     // 1. skip comment lines and leading space, colons or bars
982     for (cmd = buff; vim_strchr((char_u *)" \t:|", *cmd) != NULL; cmd++)
983 	;
984     xp->xp_pattern = cmd;
985 
986     if (*cmd == NUL)
987 	return NULL;
988     if (*cmd == '"')	    // ignore comment lines
989     {
990 	xp->xp_context = EXPAND_NOTHING;
991 	return NULL;
992     }
993 
994     // 3. Skip over the range to find the command.
995     cmd = skip_range(cmd, TRUE, &xp->xp_context);
996     xp->xp_pattern = cmd;
997     if (*cmd == NUL)
998 	return NULL;
999     if (*cmd == '"')
1000     {
1001 	xp->xp_context = EXPAND_NOTHING;
1002 	return NULL;
1003     }
1004 
1005     if (*cmd == '|' || *cmd == '\n')
1006 	return cmd + 1;			// There's another command
1007 
1008     // Isolate the command and search for it in the command table.
1009     // Exceptions:
1010     // - the 'k' command can directly be followed by any character, but
1011     //   do accept "keepmarks", "keepalt" and "keepjumps".
1012     // - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
1013     if (*cmd == 'k' && cmd[1] != 'e')
1014     {
1015 	ea.cmdidx = CMD_k;
1016 	p = cmd + 1;
1017     }
1018     else
1019     {
1020 	p = cmd;
1021 	while (ASCII_ISALPHA(*p) || *p == '*')    // Allow * wild card
1022 	    ++p;
1023 	// A user command may contain digits.
1024 	// Include "9" for "vim9*" commands; "vim9cmd" and "vim9script".
1025 	if (ASCII_ISUPPER(cmd[0]) || STRNCMP("vim9", cmd, 4) == 0)
1026 	    while (ASCII_ISALNUM(*p) || *p == '*')
1027 		++p;
1028 	// for python 3.x: ":py3*" commands completion
1029 	if (cmd[0] == 'p' && cmd[1] == 'y' && p == cmd + 2 && *p == '3')
1030 	{
1031 	    ++p;
1032 	    while (ASCII_ISALPHA(*p) || *p == '*')
1033 		++p;
1034 	}
1035 	// check for non-alpha command
1036 	if (p == cmd && vim_strchr((char_u *)"@*!=><&~#", *p) != NULL)
1037 	    ++p;
1038 	len = (int)(p - cmd);
1039 
1040 	if (len == 0)
1041 	{
1042 	    xp->xp_context = EXPAND_UNSUCCESSFUL;
1043 	    return NULL;
1044 	}
1045 
1046 	ea.cmdidx = excmd_get_cmdidx(cmd, len);
1047 
1048 	if (cmd[0] >= 'A' && cmd[0] <= 'Z')
1049 	    while (ASCII_ISALNUM(*p) || *p == '*')	// Allow * wild card
1050 		++p;
1051     }
1052 
1053     // If the cursor is touching the command, and it ends in an alphanumeric
1054     // character, complete the command name.
1055     if (*p == NUL && ASCII_ISALNUM(p[-1]))
1056 	return NULL;
1057 
1058     if (ea.cmdidx == CMD_SIZE)
1059     {
1060 	if (*cmd == 's' && vim_strchr((char_u *)"cgriI", cmd[1]) != NULL)
1061 	{
1062 	    ea.cmdidx = CMD_substitute;
1063 	    p = cmd + 1;
1064 	}
1065 	else if (cmd[0] >= 'A' && cmd[0] <= 'Z')
1066 	{
1067 	    ea.cmd = cmd;
1068 	    p = find_ucmd(&ea, p, NULL, xp, &compl);
1069 	    if (p == NULL)
1070 		ea.cmdidx = CMD_SIZE;	// ambiguous user command
1071 	}
1072     }
1073     if (ea.cmdidx == CMD_SIZE)
1074     {
1075 	// Not still touching the command and it was an illegal one
1076 	xp->xp_context = EXPAND_UNSUCCESSFUL;
1077 	return NULL;
1078     }
1079 
1080     xp->xp_context = EXPAND_NOTHING; // Default now that we're past command
1081 
1082     if (*p == '!')		    // forced commands
1083     {
1084 	forceit = TRUE;
1085 	++p;
1086     }
1087 
1088     // 6. parse arguments
1089     if (!IS_USER_CMDIDX(ea.cmdidx))
1090 	ea.argt = excmd_get_argt(ea.cmdidx);
1091 
1092     arg = skipwhite(p);
1093 
1094     // Skip over ++argopt argument
1095     if ((ea.argt & EX_ARGOPT) && *arg != NUL && STRNCMP(arg, "++", 2) == 0)
1096     {
1097 	p = arg;
1098 	while (*p && !vim_isspace(*p))
1099 	    MB_PTR_ADV(p);
1100 	arg = skipwhite(p);
1101     }
1102 
1103     if (ea.cmdidx == CMD_write || ea.cmdidx == CMD_update)
1104     {
1105 	if (*arg == '>')			// append
1106 	{
1107 	    if (*++arg == '>')
1108 		++arg;
1109 	    arg = skipwhite(arg);
1110 	}
1111 	else if (*arg == '!' && ea.cmdidx == CMD_write)	// :w !filter
1112 	{
1113 	    ++arg;
1114 	    usefilter = TRUE;
1115 	}
1116     }
1117 
1118     if (ea.cmdidx == CMD_read)
1119     {
1120 	usefilter = forceit;			// :r! filter if forced
1121 	if (*arg == '!')			// :r !filter
1122 	{
1123 	    ++arg;
1124 	    usefilter = TRUE;
1125 	}
1126     }
1127 
1128     if (ea.cmdidx == CMD_lshift || ea.cmdidx == CMD_rshift)
1129     {
1130 	while (*arg == *cmd)	    // allow any number of '>' or '<'
1131 	    ++arg;
1132 	arg = skipwhite(arg);
1133     }
1134 
1135     // Does command allow "+command"?
1136     if ((ea.argt & EX_CMDARG) && !usefilter && *arg == '+')
1137     {
1138 	// Check if we're in the +command
1139 	p = arg + 1;
1140 	arg = skip_cmd_arg(arg, FALSE);
1141 
1142 	// Still touching the command after '+'?
1143 	if (*arg == NUL)
1144 	    return p;
1145 
1146 	// Skip space(s) after +command to get to the real argument
1147 	arg = skipwhite(arg);
1148     }
1149 
1150 
1151     // Check for '|' to separate commands and '"' to start comments.
1152     // Don't do this for ":read !cmd" and ":write !cmd".
1153     if ((ea.argt & EX_TRLBAR) && !usefilter)
1154     {
1155 	p = arg;
1156 	// ":redir @" is not the start of a comment
1157 	if (ea.cmdidx == CMD_redir && p[0] == '@' && p[1] == '"')
1158 	    p += 2;
1159 	while (*p)
1160 	{
1161 	    if (*p == Ctrl_V)
1162 	    {
1163 		if (p[1] != NUL)
1164 		    ++p;
1165 	    }
1166 	    else if ( (*p == '"' && !(ea.argt & EX_NOTRLCOM))
1167 		    || *p == '|' || *p == '\n')
1168 	    {
1169 		if (*(p - 1) != '\\')
1170 		{
1171 		    if (*p == '|' || *p == '\n')
1172 			return p + 1;
1173 		    return NULL;    // It's a comment
1174 		}
1175 	    }
1176 	    MB_PTR_ADV(p);
1177 	}
1178     }
1179 
1180     if (!(ea.argt & EX_EXTRA) && *arg != NUL
1181 				  && vim_strchr((char_u *)"|\"", *arg) == NULL)
1182 	// no arguments allowed but there is something
1183 	return NULL;
1184 
1185     // Find start of last argument (argument just before cursor):
1186     p = buff;
1187     xp->xp_pattern = p;
1188     len = (int)STRLEN(buff);
1189     while (*p && p < buff + len)
1190     {
1191 	if (*p == ' ' || *p == TAB)
1192 	{
1193 	    // argument starts after a space
1194 	    xp->xp_pattern = ++p;
1195 	}
1196 	else
1197 	{
1198 	    if (*p == '\\' && *(p + 1) != NUL)
1199 		++p; // skip over escaped character
1200 	    MB_PTR_ADV(p);
1201 	}
1202     }
1203 
1204     if (ea.argt & EX_XFILE)
1205     {
1206 	int	c;
1207 	int	in_quote = FALSE;
1208 	char_u	*bow = NULL;	// Beginning of word
1209 
1210 	// Allow spaces within back-quotes to count as part of the argument
1211 	// being expanded.
1212 	xp->xp_pattern = skipwhite(arg);
1213 	p = xp->xp_pattern;
1214 	while (*p != NUL)
1215 	{
1216 	    if (has_mbyte)
1217 		c = mb_ptr2char(p);
1218 	    else
1219 		c = *p;
1220 	    if (c == '\\' && p[1] != NUL)
1221 		++p;
1222 	    else if (c == '`')
1223 	    {
1224 		if (!in_quote)
1225 		{
1226 		    xp->xp_pattern = p;
1227 		    bow = p + 1;
1228 		}
1229 		in_quote = !in_quote;
1230 	    }
1231 	    // An argument can contain just about everything, except
1232 	    // characters that end the command and white space.
1233 	    else if (c == '|' || c == '\n' || c == '"' || (VIM_ISWHITE(c)
1234 #ifdef SPACE_IN_FILENAME
1235 					&& (!(ea.argt & EX_NOSPC) || usefilter)
1236 #endif
1237 		    ))
1238 	    {
1239 		len = 0;  // avoid getting stuck when space is in 'isfname'
1240 		while (*p != NUL)
1241 		{
1242 		    if (has_mbyte)
1243 			c = mb_ptr2char(p);
1244 		    else
1245 			c = *p;
1246 		    if (c == '`' || vim_isfilec_or_wc(c))
1247 			break;
1248 		    if (has_mbyte)
1249 			len = (*mb_ptr2len)(p);
1250 		    else
1251 			len = 1;
1252 		    MB_PTR_ADV(p);
1253 		}
1254 		if (in_quote)
1255 		    bow = p;
1256 		else
1257 		    xp->xp_pattern = p;
1258 		p -= len;
1259 	    }
1260 	    MB_PTR_ADV(p);
1261 	}
1262 
1263 	// If we are still inside the quotes, and we passed a space, just
1264 	// expand from there.
1265 	if (bow != NULL && in_quote)
1266 	    xp->xp_pattern = bow;
1267 	xp->xp_context = EXPAND_FILES;
1268 
1269 	// For a shell command more chars need to be escaped.
1270 	if (usefilter || ea.cmdidx == CMD_bang || ea.cmdidx == CMD_terminal)
1271 	{
1272 #ifndef BACKSLASH_IN_FILENAME
1273 	    xp->xp_shell = TRUE;
1274 #endif
1275 	    // When still after the command name expand executables.
1276 	    if (xp->xp_pattern == skipwhite(arg))
1277 		xp->xp_context = EXPAND_SHELLCMD;
1278 	}
1279 
1280 	// Check for environment variable.
1281 	if (*xp->xp_pattern == '$')
1282 	{
1283 	    for (p = xp->xp_pattern + 1; *p != NUL; ++p)
1284 		if (!vim_isIDc(*p))
1285 		    break;
1286 	    if (*p == NUL)
1287 	    {
1288 		xp->xp_context = EXPAND_ENV_VARS;
1289 		++xp->xp_pattern;
1290 		// Avoid that the assignment uses EXPAND_FILES again.
1291 		if (compl != EXPAND_USER_DEFINED && compl != EXPAND_USER_LIST)
1292 		    compl = EXPAND_ENV_VARS;
1293 	    }
1294 	}
1295 	// Check for user names.
1296 	if (*xp->xp_pattern == '~')
1297 	{
1298 	    for (p = xp->xp_pattern + 1; *p != NUL && *p != '/'; ++p)
1299 		;
1300 	    // Complete ~user only if it partially matches a user name.
1301 	    // A full match ~user<Tab> will be replaced by user's home
1302 	    // directory i.e. something like ~user<Tab> -> /home/user/
1303 	    if (*p == NUL && p > xp->xp_pattern + 1
1304 				       && match_user(xp->xp_pattern + 1) >= 1)
1305 	    {
1306 		xp->xp_context = EXPAND_USER;
1307 		++xp->xp_pattern;
1308 	    }
1309 	}
1310     }
1311 
1312     // 6. Switch on command name.
1313     switch (ea.cmdidx)
1314     {
1315 	case CMD_find:
1316 	case CMD_sfind:
1317 	case CMD_tabfind:
1318 	    if (xp->xp_context == EXPAND_FILES)
1319 		xp->xp_context = EXPAND_FILES_IN_PATH;
1320 	    break;
1321 	case CMD_cd:
1322 	case CMD_chdir:
1323 	case CMD_tcd:
1324 	case CMD_tchdir:
1325 	case CMD_lcd:
1326 	case CMD_lchdir:
1327 	    if (xp->xp_context == EXPAND_FILES)
1328 		xp->xp_context = EXPAND_DIRECTORIES;
1329 	    break;
1330 	case CMD_help:
1331 	    xp->xp_context = EXPAND_HELP;
1332 	    xp->xp_pattern = arg;
1333 	    break;
1334 
1335 	// Command modifiers: return the argument.
1336 	// Also for commands with an argument that is a command.
1337 	case CMD_aboveleft:
1338 	case CMD_argdo:
1339 	case CMD_belowright:
1340 	case CMD_botright:
1341 	case CMD_browse:
1342 	case CMD_bufdo:
1343 	case CMD_cdo:
1344 	case CMD_cfdo:
1345 	case CMD_confirm:
1346 	case CMD_debug:
1347 	case CMD_folddoclosed:
1348 	case CMD_folddoopen:
1349 	case CMD_hide:
1350 	case CMD_keepalt:
1351 	case CMD_keepjumps:
1352 	case CMD_keepmarks:
1353 	case CMD_keeppatterns:
1354 	case CMD_ldo:
1355 	case CMD_leftabove:
1356 	case CMD_lfdo:
1357 	case CMD_lockmarks:
1358 	case CMD_noautocmd:
1359 	case CMD_noswapfile:
1360 	case CMD_rightbelow:
1361 	case CMD_sandbox:
1362 	case CMD_silent:
1363 	case CMD_tab:
1364 	case CMD_tabdo:
1365 	case CMD_topleft:
1366 	case CMD_verbose:
1367 	case CMD_vertical:
1368 	case CMD_windo:
1369 	case CMD_vim9cmd:
1370 	case CMD_legacy:
1371 	    return arg;
1372 
1373 	case CMD_filter:
1374 	    if (*arg != NUL)
1375 		arg = skip_vimgrep_pat(arg, NULL, NULL);
1376 	    if (arg == NULL || *arg == NUL)
1377 	    {
1378 		xp->xp_context = EXPAND_NOTHING;
1379 		return NULL;
1380 	    }
1381 	    return skipwhite(arg);
1382 
1383 #ifdef FEAT_SEARCH_EXTRA
1384 	case CMD_match:
1385 	    if (*arg == NUL || !ends_excmd(*arg))
1386 	    {
1387 		// also complete "None"
1388 		set_context_in_echohl_cmd(xp, arg);
1389 		arg = skipwhite(skiptowhite(arg));
1390 		if (*arg != NUL)
1391 		{
1392 		    xp->xp_context = EXPAND_NOTHING;
1393 		    arg = skip_regexp(arg + 1, *arg, magic_isset());
1394 		}
1395 	    }
1396 	    return find_nextcmd(arg);
1397 #endif
1398 
1399 	// All completion for the +cmdline_compl feature goes here.
1400 
1401 	case CMD_command:
1402 	    return set_context_in_user_cmd(xp, arg);
1403 
1404 	case CMD_delcommand:
1405 	    xp->xp_context = EXPAND_USER_COMMANDS;
1406 	    xp->xp_pattern = arg;
1407 	    break;
1408 
1409 	case CMD_global:
1410 	case CMD_vglobal:
1411 	    delim = *arg;	    // get the delimiter
1412 	    if (delim)
1413 		++arg;		    // skip delimiter if there is one
1414 
1415 	    while (arg[0] != NUL && arg[0] != delim)
1416 	    {
1417 		if (arg[0] == '\\' && arg[1] != NUL)
1418 		    ++arg;
1419 		++arg;
1420 	    }
1421 	    if (arg[0] != NUL)
1422 		return arg + 1;
1423 	    break;
1424 	case CMD_and:
1425 	case CMD_substitute:
1426 	    delim = *arg;
1427 	    if (delim)
1428 	    {
1429 		// skip "from" part
1430 		++arg;
1431 		arg = skip_regexp(arg, delim, magic_isset());
1432 	    }
1433 	    // skip "to" part
1434 	    while (arg[0] != NUL && arg[0] != delim)
1435 	    {
1436 		if (arg[0] == '\\' && arg[1] != NUL)
1437 		    ++arg;
1438 		++arg;
1439 	    }
1440 	    if (arg[0] != NUL)	// skip delimiter
1441 		++arg;
1442 	    while (arg[0] && vim_strchr((char_u *)"|\"#", arg[0]) == NULL)
1443 		++arg;
1444 	    if (arg[0] != NUL)
1445 		return arg;
1446 	    break;
1447 	case CMD_isearch:
1448 	case CMD_dsearch:
1449 	case CMD_ilist:
1450 	case CMD_dlist:
1451 	case CMD_ijump:
1452 	case CMD_psearch:
1453 	case CMD_djump:
1454 	case CMD_isplit:
1455 	case CMD_dsplit:
1456 	    arg = skipwhite(skipdigits(arg));	    // skip count
1457 	    if (*arg == '/')	// Match regexp, not just whole words
1458 	    {
1459 		for (++arg; *arg && *arg != '/'; arg++)
1460 		    if (*arg == '\\' && arg[1] != NUL)
1461 			arg++;
1462 		if (*arg)
1463 		{
1464 		    arg = skipwhite(arg + 1);
1465 
1466 		    // Check for trailing illegal characters
1467 		    if (*arg && vim_strchr((char_u *)"|\"\n", *arg) == NULL)
1468 			xp->xp_context = EXPAND_NOTHING;
1469 		    else
1470 			return arg;
1471 		}
1472 	    }
1473 	    break;
1474 
1475 	case CMD_autocmd:
1476 	    return set_context_in_autocmd(xp, arg, FALSE);
1477 	case CMD_doautocmd:
1478 	case CMD_doautoall:
1479 	    return set_context_in_autocmd(xp, arg, TRUE);
1480 	case CMD_set:
1481 	    set_context_in_set_cmd(xp, arg, 0);
1482 	    break;
1483 	case CMD_setglobal:
1484 	    set_context_in_set_cmd(xp, arg, OPT_GLOBAL);
1485 	    break;
1486 	case CMD_setlocal:
1487 	    set_context_in_set_cmd(xp, arg, OPT_LOCAL);
1488 	    break;
1489 	case CMD_tag:
1490 	case CMD_stag:
1491 	case CMD_ptag:
1492 	case CMD_ltag:
1493 	case CMD_tselect:
1494 	case CMD_stselect:
1495 	case CMD_ptselect:
1496 	case CMD_tjump:
1497 	case CMD_stjump:
1498 	case CMD_ptjump:
1499 	    if (*p_wop != NUL)
1500 		xp->xp_context = EXPAND_TAGS_LISTFILES;
1501 	    else
1502 		xp->xp_context = EXPAND_TAGS;
1503 	    xp->xp_pattern = arg;
1504 	    break;
1505 	case CMD_augroup:
1506 	    xp->xp_context = EXPAND_AUGROUP;
1507 	    xp->xp_pattern = arg;
1508 	    break;
1509 #ifdef FEAT_SYN_HL
1510 	case CMD_syntax:
1511 	    set_context_in_syntax_cmd(xp, arg);
1512 	    break;
1513 #endif
1514 #ifdef FEAT_EVAL
1515 	case CMD_final:
1516 	case CMD_const:
1517 	case CMD_let:
1518 	case CMD_var:
1519 	case CMD_if:
1520 	case CMD_elseif:
1521 	case CMD_while:
1522 	case CMD_for:
1523 	case CMD_echo:
1524 	case CMD_echon:
1525 	case CMD_execute:
1526 	case CMD_echomsg:
1527 	case CMD_echoerr:
1528 	case CMD_call:
1529 	case CMD_return:
1530 	case CMD_cexpr:
1531 	case CMD_caddexpr:
1532 	case CMD_cgetexpr:
1533 	case CMD_lexpr:
1534 	case CMD_laddexpr:
1535 	case CMD_lgetexpr:
1536 	    set_context_for_expression(xp, arg, ea.cmdidx);
1537 	    break;
1538 
1539 	case CMD_unlet:
1540 	    while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL)
1541 		arg = xp->xp_pattern + 1;
1542 
1543 	    xp->xp_context = EXPAND_USER_VARS;
1544 	    xp->xp_pattern = arg;
1545 
1546 	    if (*xp->xp_pattern == '$')
1547 	    {
1548 		xp->xp_context = EXPAND_ENV_VARS;
1549 		++xp->xp_pattern;
1550 	    }
1551 
1552 	    break;
1553 
1554 	case CMD_function:
1555 	case CMD_delfunction:
1556 	    xp->xp_context = EXPAND_USER_FUNC;
1557 	    xp->xp_pattern = arg;
1558 	    break;
1559 	case CMD_disassemble:
1560 	    set_context_in_disassemble_cmd(xp, arg);
1561 	    break;
1562 
1563 	case CMD_echohl:
1564 	    set_context_in_echohl_cmd(xp, arg);
1565 	    break;
1566 #endif
1567 	case CMD_highlight:
1568 	    set_context_in_highlight_cmd(xp, arg);
1569 	    break;
1570 #ifdef FEAT_CSCOPE
1571 	case CMD_cscope:
1572 	case CMD_lcscope:
1573 	case CMD_scscope:
1574 	    set_context_in_cscope_cmd(xp, arg, ea.cmdidx);
1575 	    break;
1576 #endif
1577 #ifdef FEAT_SIGNS
1578 	case CMD_sign:
1579 	    set_context_in_sign_cmd(xp, arg);
1580 	    break;
1581 #endif
1582 	case CMD_bdelete:
1583 	case CMD_bwipeout:
1584 	case CMD_bunload:
1585 	    while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL)
1586 		arg = xp->xp_pattern + 1;
1587 	    // FALLTHROUGH
1588 	case CMD_buffer:
1589 	case CMD_sbuffer:
1590 	case CMD_checktime:
1591 	    xp->xp_context = EXPAND_BUFFERS;
1592 	    xp->xp_pattern = arg;
1593 	    break;
1594 #ifdef FEAT_DIFF
1595 	case CMD_diffget:
1596 	case CMD_diffput:
1597 	    // If current buffer is in diff mode, complete buffer names
1598 	    // which are in diff mode, and different than current buffer.
1599 	    xp->xp_context = EXPAND_DIFF_BUFFERS;
1600 	    xp->xp_pattern = arg;
1601 	    break;
1602 #endif
1603 	case CMD_USER:
1604 	case CMD_USER_BUF:
1605 	    if (compl != EXPAND_NOTHING)
1606 	    {
1607 		// EX_XFILE: file names are handled above
1608 		if (!(ea.argt & EX_XFILE))
1609 		{
1610 #ifdef FEAT_MENU
1611 		    if (compl == EXPAND_MENUS)
1612 			return set_context_in_menu_cmd(xp, cmd, arg, forceit);
1613 #endif
1614 		    if (compl == EXPAND_COMMANDS)
1615 			return arg;
1616 		    if (compl == EXPAND_MAPPINGS)
1617 			return set_context_in_map_cmd(xp, (char_u *)"map",
1618 					 arg, forceit, FALSE, FALSE, CMD_map);
1619 		    // Find start of last argument.
1620 		    p = arg;
1621 		    while (*p)
1622 		    {
1623 			if (*p == ' ')
1624 			    // argument starts after a space
1625 			    arg = p + 1;
1626 			else if (*p == '\\' && *(p + 1) != NUL)
1627 			    ++p; // skip over escaped character
1628 			MB_PTR_ADV(p);
1629 		    }
1630 		    xp->xp_pattern = arg;
1631 		}
1632 		xp->xp_context = compl;
1633 	    }
1634 	    break;
1635 
1636 	case CMD_map:	    case CMD_noremap:
1637 	case CMD_nmap:	    case CMD_nnoremap:
1638 	case CMD_vmap:	    case CMD_vnoremap:
1639 	case CMD_omap:	    case CMD_onoremap:
1640 	case CMD_imap:	    case CMD_inoremap:
1641 	case CMD_cmap:	    case CMD_cnoremap:
1642 	case CMD_lmap:	    case CMD_lnoremap:
1643 	case CMD_smap:	    case CMD_snoremap:
1644 	case CMD_tmap:	    case CMD_tnoremap:
1645 	case CMD_xmap:	    case CMD_xnoremap:
1646 	    return set_context_in_map_cmd(xp, cmd, arg, forceit,
1647 						     FALSE, FALSE, ea.cmdidx);
1648 	case CMD_unmap:
1649 	case CMD_nunmap:
1650 	case CMD_vunmap:
1651 	case CMD_ounmap:
1652 	case CMD_iunmap:
1653 	case CMD_cunmap:
1654 	case CMD_lunmap:
1655 	case CMD_sunmap:
1656 	case CMD_tunmap:
1657 	case CMD_xunmap:
1658 	    return set_context_in_map_cmd(xp, cmd, arg, forceit,
1659 						      FALSE, TRUE, ea.cmdidx);
1660 	case CMD_mapclear:
1661 	case CMD_nmapclear:
1662 	case CMD_vmapclear:
1663 	case CMD_omapclear:
1664 	case CMD_imapclear:
1665 	case CMD_cmapclear:
1666 	case CMD_lmapclear:
1667 	case CMD_smapclear:
1668 	case CMD_tmapclear:
1669 	case CMD_xmapclear:
1670 	    xp->xp_context = EXPAND_MAPCLEAR;
1671 	    xp->xp_pattern = arg;
1672 	    break;
1673 
1674 	case CMD_abbreviate:	case CMD_noreabbrev:
1675 	case CMD_cabbrev:	case CMD_cnoreabbrev:
1676 	case CMD_iabbrev:	case CMD_inoreabbrev:
1677 	    return set_context_in_map_cmd(xp, cmd, arg, forceit,
1678 						      TRUE, FALSE, ea.cmdidx);
1679 	case CMD_unabbreviate:
1680 	case CMD_cunabbrev:
1681 	case CMD_iunabbrev:
1682 	    return set_context_in_map_cmd(xp, cmd, arg, forceit,
1683 						       TRUE, TRUE, ea.cmdidx);
1684 #ifdef FEAT_MENU
1685 	case CMD_menu:	    case CMD_noremenu:	    case CMD_unmenu:
1686 	case CMD_amenu:	    case CMD_anoremenu:	    case CMD_aunmenu:
1687 	case CMD_nmenu:	    case CMD_nnoremenu:	    case CMD_nunmenu:
1688 	case CMD_vmenu:	    case CMD_vnoremenu:	    case CMD_vunmenu:
1689 	case CMD_omenu:	    case CMD_onoremenu:	    case CMD_ounmenu:
1690 	case CMD_imenu:	    case CMD_inoremenu:	    case CMD_iunmenu:
1691 	case CMD_cmenu:	    case CMD_cnoremenu:	    case CMD_cunmenu:
1692 	case CMD_tlmenu:    case CMD_tlnoremenu:    case CMD_tlunmenu:
1693 	case CMD_tmenu:				    case CMD_tunmenu:
1694 	case CMD_popup:	    case CMD_tearoff:	    case CMD_emenu:
1695 	    return set_context_in_menu_cmd(xp, cmd, arg, forceit);
1696 #endif
1697 
1698 	case CMD_colorscheme:
1699 	    xp->xp_context = EXPAND_COLORS;
1700 	    xp->xp_pattern = arg;
1701 	    break;
1702 
1703 	case CMD_compiler:
1704 	    xp->xp_context = EXPAND_COMPILER;
1705 	    xp->xp_pattern = arg;
1706 	    break;
1707 
1708 	case CMD_ownsyntax:
1709 	    xp->xp_context = EXPAND_OWNSYNTAX;
1710 	    xp->xp_pattern = arg;
1711 	    break;
1712 
1713 	case CMD_setfiletype:
1714 	    xp->xp_context = EXPAND_FILETYPE;
1715 	    xp->xp_pattern = arg;
1716 	    break;
1717 
1718 	case CMD_packadd:
1719 	    xp->xp_context = EXPAND_PACKADD;
1720 	    xp->xp_pattern = arg;
1721 	    break;
1722 
1723 #if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
1724 	case CMD_language:
1725 	    p = skiptowhite(arg);
1726 	    if (*p == NUL)
1727 	    {
1728 		xp->xp_context = EXPAND_LANGUAGE;
1729 		xp->xp_pattern = arg;
1730 	    }
1731 	    else
1732 	    {
1733 		if ( STRNCMP(arg, "messages", p - arg) == 0
1734 		  || STRNCMP(arg, "ctype", p - arg) == 0
1735 		  || STRNCMP(arg, "time", p - arg) == 0
1736 		  || STRNCMP(arg, "collate", p - arg) == 0)
1737 		{
1738 		    xp->xp_context = EXPAND_LOCALES;
1739 		    xp->xp_pattern = skipwhite(p);
1740 		}
1741 		else
1742 		    xp->xp_context = EXPAND_NOTHING;
1743 	    }
1744 	    break;
1745 #endif
1746 #if defined(FEAT_PROFILE)
1747 	case CMD_profile:
1748 	    set_context_in_profile_cmd(xp, arg);
1749 	    break;
1750 #endif
1751 	case CMD_behave:
1752 	    xp->xp_context = EXPAND_BEHAVE;
1753 	    xp->xp_pattern = arg;
1754 	    break;
1755 
1756 	case CMD_messages:
1757 	    xp->xp_context = EXPAND_MESSAGES;
1758 	    xp->xp_pattern = arg;
1759 	    break;
1760 
1761 	case CMD_history:
1762 	    xp->xp_context = EXPAND_HISTORY;
1763 	    xp->xp_pattern = arg;
1764 	    break;
1765 #if defined(FEAT_PROFILE)
1766 	case CMD_syntime:
1767 	    xp->xp_context = EXPAND_SYNTIME;
1768 	    xp->xp_pattern = arg;
1769 	    break;
1770 #endif
1771 
1772 	case CMD_argdelete:
1773 	    while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL)
1774 		arg = xp->xp_pattern + 1;
1775 	    xp->xp_context = EXPAND_ARGLIST;
1776 	    xp->xp_pattern = arg;
1777 	    break;
1778 
1779 	default:
1780 	    break;
1781     }
1782     return NULL;
1783 }
1784 
1785     void
1786 set_cmd_context(
1787     expand_T	*xp,
1788     char_u	*str,	    // start of command line
1789     int		len,	    // length of command line (excl. NUL)
1790     int		col,	    // position of cursor
1791     int		use_ccline UNUSED) // use ccline for info
1792 {
1793 #ifdef FEAT_EVAL
1794     cmdline_info_T	*ccline = get_cmdline_info();
1795 #endif
1796     int		old_char = NUL;
1797     char_u	*nextcomm;
1798 
1799     // Avoid a UMR warning from Purify, only save the character if it has been
1800     // written before.
1801     if (col < len)
1802 	old_char = str[col];
1803     str[col] = NUL;
1804     nextcomm = str;
1805 
1806 #ifdef FEAT_EVAL
1807     if (use_ccline && ccline->cmdfirstc == '=')
1808     {
1809 	// pass CMD_SIZE because there is no real command
1810 	set_context_for_expression(xp, str, CMD_SIZE);
1811     }
1812     else if (use_ccline && ccline->input_fn)
1813     {
1814 	xp->xp_context = ccline->xp_context;
1815 	xp->xp_pattern = ccline->cmdbuff;
1816 	xp->xp_arg = ccline->xp_arg;
1817     }
1818     else
1819 #endif
1820 	while (nextcomm != NULL)
1821 	    nextcomm = set_one_cmd_context(xp, nextcomm);
1822 
1823     // Store the string here so that call_user_expand_func() can get to them
1824     // easily.
1825     xp->xp_line = str;
1826     xp->xp_col = col;
1827 
1828     str[col] = old_char;
1829 }
1830 
1831 /*
1832  * Expand the command line "str" from context "xp".
1833  * "xp" must have been set by set_cmd_context().
1834  * xp->xp_pattern points into "str", to where the text that is to be expanded
1835  * starts.
1836  * Returns EXPAND_UNSUCCESSFUL when there is something illegal before the
1837  * cursor.
1838  * Returns EXPAND_NOTHING when there is nothing to expand, might insert the
1839  * key that triggered expansion literally.
1840  * Returns EXPAND_OK otherwise.
1841  */
1842     int
1843 expand_cmdline(
1844     expand_T	*xp,
1845     char_u	*str,		// start of command line
1846     int		col,		// position of cursor
1847     int		*matchcount,	// return: nr of matches
1848     char_u	***matches)	// return: array of pointers to matches
1849 {
1850     char_u	*file_str = NULL;
1851     int		options = WILD_ADD_SLASH|WILD_SILENT;
1852 
1853     if (xp->xp_context == EXPAND_UNSUCCESSFUL)
1854     {
1855 	beep_flush();
1856 	return EXPAND_UNSUCCESSFUL;  // Something illegal on command line
1857     }
1858     if (xp->xp_context == EXPAND_NOTHING)
1859     {
1860 	// Caller can use the character as a normal char instead
1861 	return EXPAND_NOTHING;
1862     }
1863 
1864     // add star to file name, or convert to regexp if not exp. files.
1865     xp->xp_pattern_len = (int)(str + col - xp->xp_pattern);
1866     file_str = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
1867     if (file_str == NULL)
1868 	return EXPAND_UNSUCCESSFUL;
1869 
1870     if (p_wic)
1871 	options += WILD_ICASE;
1872 
1873     // find all files that match the description
1874     if (ExpandFromContext(xp, file_str, matchcount, matches, options) == FAIL)
1875     {
1876 	*matchcount = 0;
1877 	*matches = NULL;
1878     }
1879     vim_free(file_str);
1880 
1881     return EXPAND_OK;
1882 }
1883 
1884 /*
1885  * Function given to ExpandGeneric() to obtain the possible arguments of the
1886  * ":behave {mswin,xterm}" command.
1887  */
1888     static char_u *
1889 get_behave_arg(expand_T *xp UNUSED, int idx)
1890 {
1891     if (idx == 0)
1892 	return (char_u *)"mswin";
1893     if (idx == 1)
1894 	return (char_u *)"xterm";
1895     return NULL;
1896 }
1897 
1898 /*
1899  * Function given to ExpandGeneric() to obtain the possible arguments of the
1900  * ":messages {clear}" command.
1901  */
1902     static char_u *
1903 get_messages_arg(expand_T *xp UNUSED, int idx)
1904 {
1905     if (idx == 0)
1906 	return (char_u *)"clear";
1907     return NULL;
1908 }
1909 
1910     static char_u *
1911 get_mapclear_arg(expand_T *xp UNUSED, int idx)
1912 {
1913     if (idx == 0)
1914 	return (char_u *)"<buffer>";
1915     return NULL;
1916 }
1917 
1918 /*
1919  * Do the expansion based on xp->xp_context and "pat".
1920  */
1921     static int
1922 ExpandFromContext(
1923     expand_T	*xp,
1924     char_u	*pat,
1925     int		*num_file,
1926     char_u	***file,
1927     int		options)  // WILD_ flags
1928 {
1929     regmatch_T	regmatch;
1930     int		ret;
1931     int		flags;
1932     char_u	*tofree = NULL;
1933 
1934     flags = EW_DIR;	// include directories
1935     if (options & WILD_LIST_NOTFOUND)
1936 	flags |= EW_NOTFOUND;
1937     if (options & WILD_ADD_SLASH)
1938 	flags |= EW_ADDSLASH;
1939     if (options & WILD_KEEP_ALL)
1940 	flags |= EW_KEEPALL;
1941     if (options & WILD_SILENT)
1942 	flags |= EW_SILENT;
1943     if (options & WILD_NOERROR)
1944 	flags |= EW_NOERROR;
1945     if (options & WILD_ALLLINKS)
1946 	flags |= EW_ALLLINKS;
1947 
1948     if (xp->xp_context == EXPAND_FILES
1949 	    || xp->xp_context == EXPAND_DIRECTORIES
1950 	    || xp->xp_context == EXPAND_FILES_IN_PATH)
1951     {
1952 	// Expand file or directory names.
1953 	int	free_pat = FALSE;
1954 	int	i;
1955 
1956 	// for ":set path=" and ":set tags=" halve backslashes for escaped
1957 	// space
1958 	if (xp->xp_backslash != XP_BS_NONE)
1959 	{
1960 	    free_pat = TRUE;
1961 	    pat = vim_strsave(pat);
1962 	    for (i = 0; pat[i]; ++i)
1963 		if (pat[i] == '\\')
1964 		{
1965 		    if (xp->xp_backslash == XP_BS_THREE
1966 			    && pat[i + 1] == '\\'
1967 			    && pat[i + 2] == '\\'
1968 			    && pat[i + 3] == ' ')
1969 			STRMOVE(pat + i, pat + i + 3);
1970 		    if (xp->xp_backslash == XP_BS_ONE
1971 			    && pat[i + 1] == ' ')
1972 			STRMOVE(pat + i, pat + i + 1);
1973 		}
1974 	}
1975 
1976 	if (xp->xp_context == EXPAND_FILES)
1977 	    flags |= EW_FILE;
1978 	else if (xp->xp_context == EXPAND_FILES_IN_PATH)
1979 	    flags |= (EW_FILE | EW_PATH);
1980 	else
1981 	    flags = (flags | EW_DIR) & ~EW_FILE;
1982 	if (options & WILD_ICASE)
1983 	    flags |= EW_ICASE;
1984 
1985 	// Expand wildcards, supporting %:h and the like.
1986 	ret = expand_wildcards_eval(&pat, num_file, file, flags);
1987 	if (free_pat)
1988 	    vim_free(pat);
1989 #ifdef BACKSLASH_IN_FILENAME
1990 	if (p_csl[0] != NUL && (options & WILD_IGNORE_COMPLETESLASH) == 0)
1991 	{
1992 	    int	    i;
1993 
1994 	    for (i = 0; i < *num_file; ++i)
1995 	    {
1996 		char_u	*ptr = (*file)[i];
1997 
1998 		while (*ptr != NUL)
1999 		{
2000 		    if (p_csl[0] == 's' && *ptr == '\\')
2001 			*ptr = '/';
2002 		    else if (p_csl[0] == 'b' && *ptr == '/')
2003 			*ptr = '\\';
2004 		    ptr += (*mb_ptr2len)(ptr);
2005 		}
2006 	    }
2007 	}
2008 #endif
2009 	return ret;
2010     }
2011 
2012     *file = (char_u **)"";
2013     *num_file = 0;
2014     if (xp->xp_context == EXPAND_HELP)
2015     {
2016 	// With an empty argument we would get all the help tags, which is
2017 	// very slow.  Get matches for "help" instead.
2018 	if (find_help_tags(*pat == NUL ? (char_u *)"help" : pat,
2019 						 num_file, file, FALSE) == OK)
2020 	{
2021 #ifdef FEAT_MULTI_LANG
2022 	    cleanup_help_tags(*num_file, *file);
2023 #endif
2024 	    return OK;
2025 	}
2026 	return FAIL;
2027     }
2028 
2029     if (xp->xp_context == EXPAND_SHELLCMD)
2030 	return expand_shellcmd(pat, num_file, file, flags);
2031     if (xp->xp_context == EXPAND_OLD_SETTING)
2032 	return ExpandOldSetting(num_file, file);
2033     if (xp->xp_context == EXPAND_BUFFERS)
2034 	return ExpandBufnames(pat, num_file, file, options);
2035 #ifdef FEAT_DIFF
2036     if (xp->xp_context == EXPAND_DIFF_BUFFERS)
2037 	return ExpandBufnames(pat, num_file, file, options | BUF_DIFF_FILTER);
2038 #endif
2039     if (xp->xp_context == EXPAND_TAGS
2040 	    || xp->xp_context == EXPAND_TAGS_LISTFILES)
2041 	return expand_tags(xp->xp_context == EXPAND_TAGS, pat, num_file, file);
2042     if (xp->xp_context == EXPAND_COLORS)
2043     {
2044 	char *directories[] = {"colors", NULL};
2045 	return ExpandRTDir(pat, DIP_START + DIP_OPT, num_file, file,
2046 								directories);
2047     }
2048     if (xp->xp_context == EXPAND_COMPILER)
2049     {
2050 	char *directories[] = {"compiler", NULL};
2051 	return ExpandRTDir(pat, 0, num_file, file, directories);
2052     }
2053     if (xp->xp_context == EXPAND_OWNSYNTAX)
2054     {
2055 	char *directories[] = {"syntax", NULL};
2056 	return ExpandRTDir(pat, 0, num_file, file, directories);
2057     }
2058     if (xp->xp_context == EXPAND_FILETYPE)
2059     {
2060 	char *directories[] = {"syntax", "indent", "ftplugin", NULL};
2061 	return ExpandRTDir(pat, 0, num_file, file, directories);
2062     }
2063 # if defined(FEAT_EVAL)
2064     if (xp->xp_context == EXPAND_USER_LIST)
2065 	return ExpandUserList(xp, num_file, file);
2066 # endif
2067     if (xp->xp_context == EXPAND_PACKADD)
2068 	return ExpandPackAddDir(pat, num_file, file);
2069 
2070     // When expanding a function name starting with s:, match the <SNR>nr_
2071     // prefix.
2072     if ((xp->xp_context == EXPAND_USER_FUNC
2073 				       || xp->xp_context == EXPAND_DISASSEMBLE)
2074 	    && STRNCMP(pat, "^s:", 3) == 0)
2075     {
2076 	int len = (int)STRLEN(pat) + 20;
2077 
2078 	tofree = alloc(len);
2079 	vim_snprintf((char *)tofree, len, "^<SNR>\\d\\+_%s", pat + 3);
2080 	pat = tofree;
2081     }
2082 
2083     regmatch.regprog = vim_regcomp(pat, magic_isset() ? RE_MAGIC : 0);
2084     if (regmatch.regprog == NULL)
2085 	return FAIL;
2086 
2087     // set ignore-case according to p_ic, p_scs and pat
2088     regmatch.rm_ic = ignorecase(pat);
2089 
2090     if (xp->xp_context == EXPAND_SETTINGS
2091 	    || xp->xp_context == EXPAND_BOOL_SETTINGS)
2092 	ret = ExpandSettings(xp, &regmatch, num_file, file);
2093     else if (xp->xp_context == EXPAND_MAPPINGS)
2094 	ret = ExpandMappings(&regmatch, num_file, file);
2095 # if defined(FEAT_EVAL)
2096     else if (xp->xp_context == EXPAND_USER_DEFINED)
2097 	ret = ExpandUserDefined(xp, &regmatch, num_file, file);
2098 # endif
2099     else
2100     {
2101 	static struct expgen
2102 	{
2103 	    int		context;
2104 	    char_u	*((*func)(expand_T *, int));
2105 	    int		ic;
2106 	    int		escaped;
2107 	} tab[] =
2108 	{
2109 	    {EXPAND_COMMANDS, get_command_name, FALSE, TRUE},
2110 	    {EXPAND_BEHAVE, get_behave_arg, TRUE, TRUE},
2111 	    {EXPAND_MAPCLEAR, get_mapclear_arg, TRUE, TRUE},
2112 	    {EXPAND_MESSAGES, get_messages_arg, TRUE, TRUE},
2113 	    {EXPAND_HISTORY, get_history_arg, TRUE, TRUE},
2114 	    {EXPAND_USER_COMMANDS, get_user_commands, FALSE, TRUE},
2115 	    {EXPAND_USER_ADDR_TYPE, get_user_cmd_addr_type, FALSE, TRUE},
2116 	    {EXPAND_USER_CMD_FLAGS, get_user_cmd_flags, FALSE, TRUE},
2117 	    {EXPAND_USER_NARGS, get_user_cmd_nargs, FALSE, TRUE},
2118 	    {EXPAND_USER_COMPLETE, get_user_cmd_complete, FALSE, TRUE},
2119 # ifdef FEAT_EVAL
2120 	    {EXPAND_USER_VARS, get_user_var_name, FALSE, TRUE},
2121 	    {EXPAND_FUNCTIONS, get_function_name, FALSE, TRUE},
2122 	    {EXPAND_USER_FUNC, get_user_func_name, FALSE, TRUE},
2123 	    {EXPAND_DISASSEMBLE, get_disassemble_argument, FALSE, TRUE},
2124 	    {EXPAND_EXPRESSION, get_expr_name, FALSE, TRUE},
2125 # endif
2126 # ifdef FEAT_MENU
2127 	    {EXPAND_MENUS, get_menu_name, FALSE, TRUE},
2128 	    {EXPAND_MENUNAMES, get_menu_names, FALSE, TRUE},
2129 # endif
2130 # ifdef FEAT_SYN_HL
2131 	    {EXPAND_SYNTAX, get_syntax_name, TRUE, TRUE},
2132 # endif
2133 # ifdef FEAT_PROFILE
2134 	    {EXPAND_SYNTIME, get_syntime_arg, TRUE, TRUE},
2135 # endif
2136 	    {EXPAND_HIGHLIGHT, get_highlight_name, TRUE, TRUE},
2137 	    {EXPAND_EVENTS, get_event_name, TRUE, FALSE},
2138 	    {EXPAND_AUGROUP, get_augroup_name, TRUE, FALSE},
2139 # ifdef FEAT_CSCOPE
2140 	    {EXPAND_CSCOPE, get_cscope_name, TRUE, TRUE},
2141 # endif
2142 # ifdef FEAT_SIGNS
2143 	    {EXPAND_SIGN, get_sign_name, TRUE, TRUE},
2144 # endif
2145 # ifdef FEAT_PROFILE
2146 	    {EXPAND_PROFILE, get_profile_name, TRUE, TRUE},
2147 # endif
2148 # if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
2149 	    {EXPAND_LANGUAGE, get_lang_arg, TRUE, FALSE},
2150 	    {EXPAND_LOCALES, get_locales, TRUE, FALSE},
2151 # endif
2152 	    {EXPAND_ENV_VARS, get_env_name, TRUE, TRUE},
2153 	    {EXPAND_USER, get_users, TRUE, FALSE},
2154 	    {EXPAND_ARGLIST, get_arglist_name, TRUE, FALSE},
2155 	};
2156 	int	i;
2157 
2158 	// Find a context in the table and call the ExpandGeneric() with the
2159 	// right function to do the expansion.
2160 	ret = FAIL;
2161 	for (i = 0; i < (int)ARRAY_LENGTH(tab); ++i)
2162 	    if (xp->xp_context == tab[i].context)
2163 	    {
2164 		if (tab[i].ic)
2165 		    regmatch.rm_ic = TRUE;
2166 		ret = ExpandGeneric(xp, &regmatch, num_file, file,
2167 						tab[i].func, tab[i].escaped);
2168 		break;
2169 	    }
2170     }
2171 
2172     vim_regfree(regmatch.regprog);
2173     vim_free(tofree);
2174 
2175     return ret;
2176 }
2177 
2178 /*
2179  * Expand a list of names.
2180  *
2181  * Generic function for command line completion.  It calls a function to
2182  * obtain strings, one by one.	The strings are matched against a regexp
2183  * program.  Matching strings are copied into an array, which is returned.
2184  *
2185  * Returns OK when no problems encountered, FAIL for error (out of memory).
2186  */
2187     static int
2188 ExpandGeneric(
2189     expand_T	*xp,
2190     regmatch_T	*regmatch,
2191     int		*num_file,
2192     char_u	***file,
2193     char_u	*((*func)(expand_T *, int)),
2194 					  // returns a string from the list
2195     int		escaped)
2196 {
2197     int		i;
2198     int		count = 0;
2199     int		round;
2200     char_u	*str;
2201 
2202     // do this loop twice:
2203     // round == 0: count the number of matching names
2204     // round == 1: copy the matching names into allocated memory
2205     for (round = 0; round <= 1; ++round)
2206     {
2207 	for (i = 0; ; ++i)
2208 	{
2209 	    str = (*func)(xp, i);
2210 	    if (str == NULL)	    // end of list
2211 		break;
2212 	    if (*str == NUL)	    // skip empty strings
2213 		continue;
2214 
2215 	    if (vim_regexec(regmatch, str, (colnr_T)0))
2216 	    {
2217 		if (round)
2218 		{
2219 		    if (escaped)
2220 			str = vim_strsave_escaped(str, (char_u *)" \t\\.");
2221 		    else
2222 			str = vim_strsave(str);
2223 		    if (str == NULL)
2224 		    {
2225 			FreeWild(count, *file);
2226 			*num_file = 0;
2227 			*file = NULL;
2228 			return FAIL;
2229 		    }
2230 		    (*file)[count] = str;
2231 # ifdef FEAT_MENU
2232 		    if (func == get_menu_names && str != NULL)
2233 		    {
2234 			// test for separator added by get_menu_names()
2235 			str += STRLEN(str) - 1;
2236 			if (*str == '\001')
2237 			    *str = '.';
2238 		    }
2239 # endif
2240 		}
2241 		++count;
2242 	    }
2243 	}
2244 	if (round == 0)
2245 	{
2246 	    if (count == 0)
2247 		return OK;
2248 	    *file = ALLOC_MULT(char_u *, count);
2249 	    if (*file == NULL)
2250 	    {
2251 		*num_file = 0;
2252 		*file = NULL;
2253 		return FAIL;
2254 	    }
2255 	    *num_file = count;
2256 	    count = 0;
2257 	}
2258     }
2259 
2260     // Sort the results.  Keep menu's in the specified order.
2261     if (xp->xp_context != EXPAND_MENUNAMES && xp->xp_context != EXPAND_MENUS)
2262     {
2263 	if (xp->xp_context == EXPAND_EXPRESSION
2264 		|| xp->xp_context == EXPAND_FUNCTIONS
2265 		|| xp->xp_context == EXPAND_USER_FUNC
2266 		|| xp->xp_context == EXPAND_DISASSEMBLE)
2267 	    // <SNR> functions should be sorted to the end.
2268 	    qsort((void *)*file, (size_t)*num_file, sizeof(char_u *),
2269 							   sort_func_compare);
2270 	else
2271 	    sort_strings(*file, *num_file);
2272     }
2273 
2274 #if defined(FEAT_SYN_HL)
2275     // Reset the variables used for special highlight names expansion, so that
2276     // they don't show up when getting normal highlight names by ID.
2277     reset_expand_highlight();
2278 #endif
2279     return OK;
2280 }
2281 
2282 /*
2283  * Complete a shell command.
2284  * Returns FAIL or OK;
2285  */
2286     static int
2287 expand_shellcmd(
2288     char_u	*filepat,	// pattern to match with command names
2289     int		*num_file,	// return: number of matches
2290     char_u	***file,	// return: array with matches
2291     int		flagsarg)	// EW_ flags
2292 {
2293     char_u	*pat;
2294     int		i;
2295     char_u	*path = NULL;
2296     int		mustfree = FALSE;
2297     garray_T    ga;
2298     char_u	*buf;
2299     size_t	l;
2300     char_u	*s, *e;
2301     int		flags = flagsarg;
2302     int		ret;
2303     int		did_curdir = FALSE;
2304     hashtab_T	found_ht;
2305     hashitem_T	*hi;
2306     hash_T	hash;
2307 
2308     buf = alloc(MAXPATHL);
2309     if (buf == NULL)
2310 	return FAIL;
2311 
2312     // for ":set path=" and ":set tags=" halve backslashes for escaped space
2313     pat = vim_strsave(filepat);
2314     if (pat == NULL)
2315     {
2316 	vim_free(buf);
2317 	return FAIL;
2318     }
2319 
2320     for (i = 0; pat[i]; ++i)
2321 	if (pat[i] == '\\' && pat[i + 1] == ' ')
2322 	    STRMOVE(pat + i, pat + i + 1);
2323 
2324     flags |= EW_FILE | EW_EXEC | EW_SHELLCMD;
2325 
2326     if (pat[0] == '.' && (vim_ispathsep(pat[1])
2327 			       || (pat[1] == '.' && vim_ispathsep(pat[2]))))
2328 	path = (char_u *)".";
2329     else
2330     {
2331 	// For an absolute name we don't use $PATH.
2332 	if (!mch_isFullName(pat))
2333 	    path = vim_getenv((char_u *)"PATH", &mustfree);
2334 	if (path == NULL)
2335 	    path = (char_u *)"";
2336     }
2337 
2338     // Go over all directories in $PATH.  Expand matches in that directory and
2339     // collect them in "ga".  When "." is not in $PATH also expand for the
2340     // current directory, to find "subdir/cmd".
2341     ga_init2(&ga, (int)sizeof(char *), 10);
2342     hash_init(&found_ht);
2343     for (s = path; ; s = e)
2344     {
2345 # if defined(MSWIN)
2346 	e = vim_strchr(s, ';');
2347 # else
2348 	e = vim_strchr(s, ':');
2349 # endif
2350 	if (e == NULL)
2351 	    e = s + STRLEN(s);
2352 
2353 	if (*s == NUL)
2354 	{
2355 	    if (did_curdir)
2356 		break;
2357 	    // Find directories in the current directory, path is empty.
2358 	    did_curdir = TRUE;
2359 	    flags |= EW_DIR;
2360 	}
2361 	else if (STRNCMP(s, ".", (int)(e - s)) == 0)
2362 	{
2363 	    did_curdir = TRUE;
2364 	    flags |= EW_DIR;
2365 	}
2366 	else
2367 	    // Do not match directories inside a $PATH item.
2368 	    flags &= ~EW_DIR;
2369 
2370 	l = e - s;
2371 	if (l > MAXPATHL - 5)
2372 	    break;
2373 	vim_strncpy(buf, s, l);
2374 	add_pathsep(buf);
2375 	l = STRLEN(buf);
2376 	vim_strncpy(buf + l, pat, MAXPATHL - 1 - l);
2377 
2378 	// Expand matches in one directory of $PATH.
2379 	ret = expand_wildcards(1, &buf, num_file, file, flags);
2380 	if (ret == OK)
2381 	{
2382 	    if (ga_grow(&ga, *num_file) == FAIL)
2383 		FreeWild(*num_file, *file);
2384 	    else
2385 	    {
2386 		for (i = 0; i < *num_file; ++i)
2387 		{
2388 		    char_u *name = (*file)[i];
2389 
2390 		    if (STRLEN(name) > l)
2391 		    {
2392 			// Check if this name was already found.
2393 			hash = hash_hash(name + l);
2394 			hi = hash_lookup(&found_ht, name + l, hash);
2395 			if (HASHITEM_EMPTY(hi))
2396 			{
2397 			    // Remove the path that was prepended.
2398 			    STRMOVE(name, name + l);
2399 			    ((char_u **)ga.ga_data)[ga.ga_len++] = name;
2400 			    hash_add_item(&found_ht, hi, name, hash);
2401 			    name = NULL;
2402 			}
2403 		    }
2404 		    vim_free(name);
2405 		}
2406 		vim_free(*file);
2407 	    }
2408 	}
2409 	if (*e != NUL)
2410 	    ++e;
2411     }
2412     *file = ga.ga_data;
2413     *num_file = ga.ga_len;
2414 
2415     vim_free(buf);
2416     vim_free(pat);
2417     if (mustfree)
2418 	vim_free(path);
2419     hash_clear(&found_ht);
2420     return OK;
2421 }
2422 
2423 # if defined(FEAT_EVAL)
2424 /*
2425  * Call "user_expand_func()" to invoke a user defined Vim script function and
2426  * return the result (either a string, a List or NULL).
2427  */
2428     static void *
2429 call_user_expand_func(
2430     void	*(*user_expand_func)(char_u *, int, typval_T *),
2431     expand_T	*xp,
2432     int		*num_file,
2433     char_u	***file)
2434 {
2435     cmdline_info_T	*ccline = get_cmdline_info();
2436     int		keep = 0;
2437     typval_T	args[4];
2438     sctx_T	save_current_sctx = current_sctx;
2439     char_u	*pat = NULL;
2440     void	*ret;
2441 
2442     if (xp->xp_arg == NULL || xp->xp_arg[0] == '\0' || xp->xp_line == NULL)
2443 	return NULL;
2444     *num_file = 0;
2445     *file = NULL;
2446 
2447     if (ccline->cmdbuff != NULL)
2448     {
2449 	keep = ccline->cmdbuff[ccline->cmdlen];
2450 	ccline->cmdbuff[ccline->cmdlen] = 0;
2451     }
2452 
2453     pat = vim_strnsave(xp->xp_pattern, xp->xp_pattern_len);
2454 
2455     args[0].v_type = VAR_STRING;
2456     args[0].vval.v_string = pat;
2457     args[1].v_type = VAR_STRING;
2458     args[1].vval.v_string = xp->xp_line;
2459     args[2].v_type = VAR_NUMBER;
2460     args[2].vval.v_number = xp->xp_col;
2461     args[3].v_type = VAR_UNKNOWN;
2462 
2463     current_sctx = xp->xp_script_ctx;
2464 
2465     ret = user_expand_func(xp->xp_arg, 3, args);
2466 
2467     current_sctx = save_current_sctx;
2468     if (ccline->cmdbuff != NULL)
2469 	ccline->cmdbuff[ccline->cmdlen] = keep;
2470 
2471     vim_free(pat);
2472     return ret;
2473 }
2474 
2475 /*
2476  * Expand names with a function defined by the user.
2477  */
2478     static int
2479 ExpandUserDefined(
2480     expand_T	*xp,
2481     regmatch_T	*regmatch,
2482     int		*num_file,
2483     char_u	***file)
2484 {
2485     char_u	*retstr;
2486     char_u	*s;
2487     char_u	*e;
2488     int		keep;
2489     garray_T	ga;
2490     int		skip;
2491 
2492     retstr = call_user_expand_func(call_func_retstr, xp, num_file, file);
2493     if (retstr == NULL)
2494 	return FAIL;
2495 
2496     ga_init2(&ga, (int)sizeof(char *), 3);
2497     for (s = retstr; *s != NUL; s = e)
2498     {
2499 	e = vim_strchr(s, '\n');
2500 	if (e == NULL)
2501 	    e = s + STRLEN(s);
2502 	keep = *e;
2503 	*e = NUL;
2504 
2505 	skip = xp->xp_pattern[0] && vim_regexec(regmatch, s, (colnr_T)0) == 0;
2506 	*e = keep;
2507 
2508 	if (!skip)
2509 	{
2510 	    if (ga_grow(&ga, 1) == FAIL)
2511 		break;
2512 	    ((char_u **)ga.ga_data)[ga.ga_len] = vim_strnsave(s, e - s);
2513 	    ++ga.ga_len;
2514 	}
2515 
2516 	if (*e != NUL)
2517 	    ++e;
2518     }
2519     vim_free(retstr);
2520     *file = ga.ga_data;
2521     *num_file = ga.ga_len;
2522     return OK;
2523 }
2524 
2525 /*
2526  * Expand names with a list returned by a function defined by the user.
2527  */
2528     static int
2529 ExpandUserList(
2530     expand_T	*xp,
2531     int		*num_file,
2532     char_u	***file)
2533 {
2534     list_T      *retlist;
2535     listitem_T	*li;
2536     garray_T	ga;
2537 
2538     retlist = call_user_expand_func(call_func_retlist, xp, num_file, file);
2539     if (retlist == NULL)
2540 	return FAIL;
2541 
2542     ga_init2(&ga, (int)sizeof(char *), 3);
2543     // Loop over the items in the list.
2544     FOR_ALL_LIST_ITEMS(retlist, li)
2545     {
2546 	if (li->li_tv.v_type != VAR_STRING || li->li_tv.vval.v_string == NULL)
2547 	    continue;  // Skip non-string items and empty strings
2548 
2549 	if (ga_grow(&ga, 1) == FAIL)
2550 	    break;
2551 
2552 	((char_u **)ga.ga_data)[ga.ga_len] =
2553 					 vim_strsave(li->li_tv.vval.v_string);
2554 	++ga.ga_len;
2555     }
2556     list_unref(retlist);
2557 
2558     *file = ga.ga_data;
2559     *num_file = ga.ga_len;
2560     return OK;
2561 }
2562 # endif
2563 
2564 /*
2565  * Expand "file" for all comma-separated directories in "path".
2566  * Adds the matches to "ga".  Caller must init "ga".
2567  */
2568     void
2569 globpath(
2570     char_u	*path,
2571     char_u	*file,
2572     garray_T	*ga,
2573     int		expand_options)
2574 {
2575     expand_T	xpc;
2576     char_u	*buf;
2577     int		i;
2578     int		num_p;
2579     char_u	**p;
2580 
2581     buf = alloc(MAXPATHL);
2582     if (buf == NULL)
2583 	return;
2584 
2585     ExpandInit(&xpc);
2586     xpc.xp_context = EXPAND_FILES;
2587 
2588     // Loop over all entries in {path}.
2589     while (*path != NUL)
2590     {
2591 	// Copy one item of the path to buf[] and concatenate the file name.
2592 	copy_option_part(&path, buf, MAXPATHL, ",");
2593 	if (STRLEN(buf) + STRLEN(file) + 2 < MAXPATHL)
2594 	{
2595 # if defined(MSWIN)
2596 	    // Using the platform's path separator (\) makes vim incorrectly
2597 	    // treat it as an escape character, use '/' instead.
2598 	    if (*buf != NUL && !after_pathsep(buf, buf + STRLEN(buf)))
2599 		STRCAT(buf, "/");
2600 # else
2601 	    add_pathsep(buf);
2602 # endif
2603 	    STRCAT(buf, file);
2604 	    if (ExpandFromContext(&xpc, buf, &num_p, &p,
2605 			     WILD_SILENT|expand_options) != FAIL && num_p > 0)
2606 	    {
2607 		ExpandEscape(&xpc, buf, num_p, p, WILD_SILENT|expand_options);
2608 
2609 		if (ga_grow(ga, num_p) == OK)
2610 		    // take over the pointers and put them in "ga"
2611 		    for (i = 0; i < num_p; ++i)
2612 		    {
2613 			((char_u **)ga->ga_data)[ga->ga_len] = p[i];
2614 			++ga->ga_len;
2615 		    }
2616 		vim_free(p);
2617 	    }
2618 	}
2619     }
2620 
2621     vim_free(buf);
2622 }
2623 
2624 #ifdef FEAT_WILDMENU
2625 
2626 /*
2627  * Translate some keys pressed when 'wildmenu' is used.
2628  */
2629     int
2630 wildmenu_translate_key(
2631 	cmdline_info_T	*cclp,
2632 	int		key,
2633 	expand_T	*xp,
2634 	int		did_wild_list)
2635 {
2636     int c = key;
2637 
2638     if (did_wild_list && p_wmnu)
2639     {
2640 	if (c == K_LEFT)
2641 	    c = Ctrl_P;
2642 	else if (c == K_RIGHT)
2643 	    c = Ctrl_N;
2644     }
2645     // Hitting CR after "emenu Name.": complete submenu
2646     if (xp->xp_context == EXPAND_MENUNAMES && p_wmnu
2647 	    && cclp->cmdpos > 1
2648 	    && cclp->cmdbuff[cclp->cmdpos - 1] == '.'
2649 	    && cclp->cmdbuff[cclp->cmdpos - 2] != '\\'
2650 	    && (c == '\n' || c == '\r' || c == K_KENTER))
2651 	c = K_DOWN;
2652 
2653     return c;
2654 }
2655 
2656 /*
2657  * Delete characters on the command line, from "from" to the current
2658  * position.
2659  */
2660     static void
2661 cmdline_del(cmdline_info_T *cclp, int from)
2662 {
2663     mch_memmove(cclp->cmdbuff + from, cclp->cmdbuff + cclp->cmdpos,
2664 	    (size_t)(cclp->cmdlen - cclp->cmdpos + 1));
2665     cclp->cmdlen -= cclp->cmdpos - from;
2666     cclp->cmdpos = from;
2667 }
2668 
2669 /*
2670  * Handle a key pressed when wild menu is displayed
2671  */
2672     int
2673 wildmenu_process_key(cmdline_info_T *cclp, int key, expand_T *xp)
2674 {
2675     int		c = key;
2676     int		i;
2677     int		j;
2678 
2679     if (!p_wmnu)
2680 	return c;
2681 
2682     // Special translations for 'wildmenu'
2683     if (xp->xp_context == EXPAND_MENUNAMES)
2684     {
2685 	// Hitting <Down> after "emenu Name.": complete submenu
2686 	if (c == K_DOWN && cclp->cmdpos > 0
2687 		&& cclp->cmdbuff[cclp->cmdpos - 1] == '.')
2688 	{
2689 	    c = p_wc;
2690 	    KeyTyped = TRUE;  // in case the key was mapped
2691 	}
2692 	else if (c == K_UP)
2693 	{
2694 	    // Hitting <Up>: Remove one submenu name in front of the
2695 	    // cursor
2696 	    int found = FALSE;
2697 
2698 	    j = (int)(xp->xp_pattern - cclp->cmdbuff);
2699 	    i = 0;
2700 	    while (--j > 0)
2701 	    {
2702 		// check for start of menu name
2703 		if (cclp->cmdbuff[j] == ' '
2704 			&& cclp->cmdbuff[j - 1] != '\\')
2705 		{
2706 		    i = j + 1;
2707 		    break;
2708 		}
2709 		// check for start of submenu name
2710 		if (cclp->cmdbuff[j] == '.'
2711 			&& cclp->cmdbuff[j - 1] != '\\')
2712 		{
2713 		    if (found)
2714 		    {
2715 			i = j + 1;
2716 			break;
2717 		    }
2718 		    else
2719 			found = TRUE;
2720 		}
2721 	    }
2722 	    if (i > 0)
2723 		cmdline_del(cclp, i);
2724 	    c = p_wc;
2725 	    KeyTyped = TRUE;  // in case the key was mapped
2726 	    xp->xp_context = EXPAND_NOTHING;
2727 	}
2728     }
2729     if ((xp->xp_context == EXPAND_FILES
2730 		|| xp->xp_context == EXPAND_DIRECTORIES
2731 		|| xp->xp_context == EXPAND_SHELLCMD))
2732     {
2733 	char_u upseg[5];
2734 
2735 	upseg[0] = PATHSEP;
2736 	upseg[1] = '.';
2737 	upseg[2] = '.';
2738 	upseg[3] = PATHSEP;
2739 	upseg[4] = NUL;
2740 
2741 	if (c == K_DOWN
2742 		&& cclp->cmdpos > 0
2743 		&& cclp->cmdbuff[cclp->cmdpos - 1] == PATHSEP
2744 		&& (cclp->cmdpos < 3
2745 		    || cclp->cmdbuff[cclp->cmdpos - 2] != '.'
2746 		    || cclp->cmdbuff[cclp->cmdpos - 3] != '.'))
2747 	{
2748 	    // go down a directory
2749 	    c = p_wc;
2750 	    KeyTyped = TRUE;  // in case the key was mapped
2751 	}
2752 	else if (STRNCMP(xp->xp_pattern, upseg + 1, 3) == 0 && c == K_DOWN)
2753 	{
2754 	    // If in a direct ancestor, strip off one ../ to go down
2755 	    int found = FALSE;
2756 
2757 	    j = cclp->cmdpos;
2758 	    i = (int)(xp->xp_pattern - cclp->cmdbuff);
2759 	    while (--j > i)
2760 	    {
2761 		if (has_mbyte)
2762 		    j -= (*mb_head_off)(cclp->cmdbuff, cclp->cmdbuff + j);
2763 		if (vim_ispathsep(cclp->cmdbuff[j]))
2764 		{
2765 		    found = TRUE;
2766 		    break;
2767 		}
2768 	    }
2769 	    if (found
2770 		    && cclp->cmdbuff[j - 1] == '.'
2771 		    && cclp->cmdbuff[j - 2] == '.'
2772 		    && (vim_ispathsep(cclp->cmdbuff[j - 3]) || j == i + 2))
2773 	    {
2774 		cmdline_del(cclp, j - 2);
2775 		c = p_wc;
2776 		KeyTyped = TRUE;  // in case the key was mapped
2777 	    }
2778 	}
2779 	else if (c == K_UP)
2780 	{
2781 	    // go up a directory
2782 	    int found = FALSE;
2783 
2784 	    j = cclp->cmdpos - 1;
2785 	    i = (int)(xp->xp_pattern - cclp->cmdbuff);
2786 	    while (--j > i)
2787 	    {
2788 		if (has_mbyte)
2789 		    j -= (*mb_head_off)(cclp->cmdbuff, cclp->cmdbuff + j);
2790 		if (vim_ispathsep(cclp->cmdbuff[j])
2791 # ifdef BACKSLASH_IN_FILENAME
2792 			&& vim_strchr((char_u *)" *?[{`$%#",
2793 			    cclp->cmdbuff[j + 1]) == NULL
2794 # endif
2795 		   )
2796 		{
2797 		    if (found)
2798 		    {
2799 			i = j + 1;
2800 			break;
2801 		    }
2802 		    else
2803 			found = TRUE;
2804 		}
2805 	    }
2806 
2807 	    if (!found)
2808 		j = i;
2809 	    else if (STRNCMP(cclp->cmdbuff + j, upseg, 4) == 0)
2810 		j += 4;
2811 	    else if (STRNCMP(cclp->cmdbuff + j, upseg + 1, 3) == 0
2812 		    && j == i)
2813 		j += 3;
2814 	    else
2815 		j = 0;
2816 	    if (j > 0)
2817 	    {
2818 		// TODO this is only for DOS/UNIX systems - need to put in
2819 		// machine-specific stuff here and in upseg init
2820 		cmdline_del(cclp, j);
2821 		put_on_cmdline(upseg + 1, 3, FALSE);
2822 	    }
2823 	    else if (cclp->cmdpos > i)
2824 		cmdline_del(cclp, i);
2825 
2826 	    // Now complete in the new directory. Set KeyTyped in case the
2827 	    // Up key came from a mapping.
2828 	    c = p_wc;
2829 	    KeyTyped = TRUE;
2830 	}
2831     }
2832 
2833     return c;
2834 }
2835 
2836 /*
2837  * Free expanded names when finished walking through the matches
2838  */
2839     void
2840 wildmenu_cleanup(cmdline_info_T *cclp)
2841 {
2842     int skt = KeyTyped;
2843     int old_RedrawingDisabled = RedrawingDisabled;
2844 
2845     if (!p_wmnu || wild_menu_showing == 0)
2846 	return;
2847 
2848     if (cclp->input_fn)
2849 	RedrawingDisabled = 0;
2850 
2851     if (wild_menu_showing == WM_SCROLLED)
2852     {
2853 	// Entered command line, move it up
2854 	cmdline_row--;
2855 	redrawcmd();
2856     }
2857     else if (save_p_ls != -1)
2858     {
2859 	// restore 'laststatus' and 'winminheight'
2860 	p_ls = save_p_ls;
2861 	p_wmh = save_p_wmh;
2862 	last_status(FALSE);
2863 	update_screen(VALID);	// redraw the screen NOW
2864 	redrawcmd();
2865 	save_p_ls = -1;
2866     }
2867     else
2868     {
2869 	win_redraw_last_status(topframe);
2870 	redraw_statuslines();
2871     }
2872     KeyTyped = skt;
2873     wild_menu_showing = 0;
2874     if (cclp->input_fn)
2875 	RedrawingDisabled = old_RedrawingDisabled;
2876 }
2877 #endif
2878 
2879 #if defined(FEAT_EVAL) || defined(PROTO)
2880 /*
2881  * "getcompletion()" function
2882  */
2883     void
2884 f_getcompletion(typval_T *argvars, typval_T *rettv)
2885 {
2886     char_u	*pat;
2887     char_u	*type;
2888     expand_T	xpc;
2889     int		filtered = FALSE;
2890     int		options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH
2891 								| WILD_NO_BEEP;
2892 
2893     if (in_vim9script()
2894 	    && (check_for_string_arg(argvars, 0) == FAIL
2895 		|| check_for_string_arg(argvars, 1) == FAIL
2896 		|| check_for_opt_bool_arg(argvars, 2) == FAIL))
2897 	return;
2898 
2899     if (argvars[1].v_type != VAR_STRING)
2900     {
2901 	semsg(_(e_invarg2), "type must be a string");
2902 	return;
2903     }
2904     type = tv_get_string(&argvars[1]);
2905 
2906     if (argvars[2].v_type != VAR_UNKNOWN)
2907 	filtered = tv_get_bool_chk(&argvars[2], NULL);
2908 
2909     if (p_wic)
2910 	options |= WILD_ICASE;
2911 
2912     // For filtered results, 'wildignore' is used
2913     if (!filtered)
2914 	options |= WILD_KEEP_ALL;
2915 
2916     ExpandInit(&xpc);
2917     if (STRCMP(type, "cmdline") == 0)
2918     {
2919 	set_one_cmd_context(&xpc, tv_get_string(&argvars[0]));
2920 	xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
2921     }
2922     else
2923     {
2924 	xpc.xp_pattern = tv_get_string(&argvars[0]);
2925 	xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
2926 
2927 	xpc.xp_context = cmdcomplete_str_to_type(type);
2928 	if (xpc.xp_context == EXPAND_NOTHING)
2929 	{
2930 	    semsg(_(e_invarg2), type);
2931 	    return;
2932 	}
2933 
2934 # if defined(FEAT_MENU)
2935 	if (xpc.xp_context == EXPAND_MENUS)
2936 	{
2937 	    set_context_in_menu_cmd(&xpc, (char_u *)"menu", xpc.xp_pattern, FALSE);
2938 	    xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
2939 	}
2940 # endif
2941 # ifdef FEAT_CSCOPE
2942 	if (xpc.xp_context == EXPAND_CSCOPE)
2943 	{
2944 	    set_context_in_cscope_cmd(&xpc, xpc.xp_pattern, CMD_cscope);
2945 	    xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
2946 	}
2947 # endif
2948 # ifdef FEAT_SIGNS
2949 	if (xpc.xp_context == EXPAND_SIGN)
2950 	{
2951 	    set_context_in_sign_cmd(&xpc, xpc.xp_pattern);
2952 	    xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
2953 	}
2954 # endif
2955     }
2956 
2957     pat = addstar(xpc.xp_pattern, xpc.xp_pattern_len, xpc.xp_context);
2958     if ((rettv_list_alloc(rettv) != FAIL) && (pat != NULL))
2959     {
2960 	int	i;
2961 
2962 	ExpandOne(&xpc, pat, NULL, options, WILD_ALL_KEEP);
2963 
2964 	for (i = 0; i < xpc.xp_numfiles; i++)
2965 	    list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1);
2966     }
2967     vim_free(pat);
2968     ExpandCleanup(&xpc);
2969 }
2970 #endif // FEAT_EVAL
2971