xref: /vim-8.2.3635/src/ex_getln.c (revision 94688b8a)
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  * ex_getln.c: Functions for entering and editing an Ex command line.
12  */
13 
14 #include "vim.h"
15 
16 #ifndef MAX
17 # define MAX(x,y) ((x) > (y) ? (x) : (y))
18 #endif
19 
20 /*
21  * Variables shared between getcmdline(), redrawcmdline() and others.
22  * These need to be saved when using CTRL-R |, that's why they are in a
23  * structure.
24  */
25 struct cmdline_info
26 {
27     char_u	*cmdbuff;	/* pointer to command line buffer */
28     int		cmdbufflen;	/* length of cmdbuff */
29     int		cmdlen;		/* number of chars in command line */
30     int		cmdpos;		/* current cursor position */
31     int		cmdspos;	/* cursor column on screen */
32     int		cmdfirstc;	/* ':', '/', '?', '=', '>' or NUL */
33     int		cmdindent;	/* number of spaces before cmdline */
34     char_u	*cmdprompt;	/* message in front of cmdline */
35     int		cmdattr;	/* attributes for prompt */
36     int		overstrike;	/* Typing mode on the command line.  Shared by
37 				   getcmdline() and put_on_cmdline(). */
38     expand_T	*xpc;		/* struct being used for expansion, xp_pattern
39 				   may point into cmdbuff */
40     int		xp_context;	/* type of expansion */
41 # ifdef FEAT_EVAL
42     char_u	*xp_arg;	/* user-defined expansion arg */
43     int		input_fn;	/* when TRUE Invoked for input() function */
44 # endif
45 };
46 
47 // The current cmdline_info.  It is initialized in getcmdline() and after that
48 // used by other functions.  When invoking getcmdline() recursively it needs
49 // to be saved with save_cmdline() and restored with restore_cmdline().
50 static struct cmdline_info ccline;
51 
52 static int	cmd_showtail;	/* Only show path tail in lists ? */
53 
54 #ifdef FEAT_EVAL
55 static int	new_cmdpos;	/* position set by set_cmdline_pos() */
56 #endif
57 
58 static int	extra_char = NUL;  /* extra character to display when redrawing
59 				    * the command line */
60 static int	extra_char_shift;
61 
62 #ifdef FEAT_CMDHIST
63 typedef struct hist_entry
64 {
65     int		hisnum;		/* identifying number */
66     int		viminfo;	/* when TRUE hisstr comes from viminfo */
67     char_u	*hisstr;	/* actual entry, separator char after the NUL */
68     time_t	time_set;	/* when it was typed, zero if unknown */
69 } histentry_T;
70 
71 static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL};
72 static int	hisidx[HIST_COUNT] = {-1, -1, -1, -1, -1};  /* lastused entry */
73 static int	hisnum[HIST_COUNT] = {0, 0, 0, 0, 0};
74 		    /* identifying (unique) number of newest history entry */
75 static int	hislen = 0;		/* actual length of history tables */
76 
77 static int	hist_char2type(int c);
78 #endif
79 
80 #ifdef FEAT_RIGHTLEFT
81 static int	cmd_hkmap = 0;	/* Hebrew mapping during command line */
82 #endif
83 
84 #ifdef FEAT_FKMAP
85 static int	cmd_fkmap = 0;	/* Farsi mapping during command line */
86 #endif
87 
88 static char_u	*getcmdline_int(int firstc, long count, int indent, int init_ccline);
89 static int	cmdline_charsize(int idx);
90 static void	set_cmdspos(void);
91 static void	set_cmdspos_cursor(void);
92 static void	correct_cmdspos(int idx, int cells);
93 static void	alloc_cmdbuff(int len);
94 static int	realloc_cmdbuff(int len);
95 static void	draw_cmdline(int start, int len);
96 static void	save_cmdline(struct cmdline_info *ccp);
97 static void	restore_cmdline(struct cmdline_info *ccp);
98 static int	cmdline_paste(int regname, int literally, int remcr);
99 #ifdef FEAT_WILDMENU
100 static void	cmdline_del(int from);
101 #endif
102 static void	redrawcmdprompt(void);
103 static void	cursorcmd(void);
104 static int	ccheck_abbr(int);
105 static int	nextwild(expand_T *xp, int type, int options, int escape);
106 static void	escape_fname(char_u **pp);
107 static int	showmatches(expand_T *xp, int wildmenu);
108 static void	set_expand_context(expand_T *xp);
109 static int	ExpandFromContext(expand_T *xp, char_u *, int *, char_u ***, int);
110 static int	expand_showtail(expand_T *xp);
111 #ifdef FEAT_CMDL_COMPL
112 static int	expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, int flagsarg);
113 static int	ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file, char *dirname[]);
114 static int	ExpandPackAddDir(char_u *pat, int *num_file, char_u ***file);
115 # ifdef FEAT_CMDHIST
116 static char_u	*get_history_arg(expand_T *xp, int idx);
117 # endif
118 # if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
119 static int	ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file);
120 static int	ExpandUserList(expand_T *xp, int *num_file, char_u ***file);
121 # endif
122 #endif
123 #ifdef FEAT_CMDHIST
124 static void	clear_hist_entry(histentry_T *hisptr);
125 #endif
126 
127 #ifdef FEAT_CMDWIN
128 static int	open_cmdwin(void);
129 #endif
130 
131 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
132 static int
133 #ifdef __BORLANDC__
134 _RTLENTRYF
135 #endif
136 sort_func_compare(const void *s1, const void *s2);
137 #endif
138 
139 
140     static void
141 trigger_cmd_autocmd(int typechar, int evt)
142 {
143     char_u	typestr[2];
144 
145     typestr[0] = typechar;
146     typestr[1] = NUL;
147     apply_autocmds(evt, typestr, typestr, FALSE, curbuf);
148 }
149 
150 /*
151  * Abandon the command line.
152  */
153     static void
154 abandon_cmdline(void)
155 {
156     VIM_CLEAR(ccline.cmdbuff);
157     if (msg_scrolled == 0)
158 	compute_cmdrow();
159     msg("");
160     redraw_cmdline = TRUE;
161 }
162 
163 #ifdef FEAT_SEARCH_EXTRA
164 /*
165  * Guess that the pattern matches everything.  Only finds specific cases, such
166  * as a trailing \|, which can happen while typing a pattern.
167  */
168     static int
169 empty_pattern(char_u *p)
170 {
171     size_t n = STRLEN(p);
172 
173     /* remove trailing \v and the like */
174     while (n >= 2 && p[n - 2] == '\\'
175 			  && vim_strchr((char_u *)"mMvVcCZ", p[n - 1]) != NULL)
176 	n -= 2;
177     return n == 0 || (n >= 2 && p[n - 2] == '\\' && p[n - 1] == '|');
178 }
179 
180 // Struct to store the viewstate during 'incsearch' highlighting.
181 typedef struct {
182     colnr_T	vs_curswant;
183     colnr_T	vs_leftcol;
184     linenr_T	vs_topline;
185 # ifdef FEAT_DIFF
186     int		vs_topfill;
187 # endif
188     linenr_T	vs_botline;
189     linenr_T	vs_empty_rows;
190 } viewstate_T;
191 
192     static void
193 save_viewstate(viewstate_T *vs)
194 {
195     vs->vs_curswant = curwin->w_curswant;
196     vs->vs_leftcol = curwin->w_leftcol;
197     vs->vs_topline = curwin->w_topline;
198 # ifdef FEAT_DIFF
199     vs->vs_topfill = curwin->w_topfill;
200 # endif
201     vs->vs_botline = curwin->w_botline;
202     vs->vs_empty_rows = curwin->w_empty_rows;
203 }
204 
205     static void
206 restore_viewstate(viewstate_T *vs)
207 {
208     curwin->w_curswant = vs->vs_curswant;
209     curwin->w_leftcol = vs->vs_leftcol;
210     curwin->w_topline = vs->vs_topline;
211 # ifdef FEAT_DIFF
212     curwin->w_topfill = vs->vs_topfill;
213 # endif
214     curwin->w_botline = vs->vs_botline;
215     curwin->w_empty_rows = vs->vs_empty_rows;
216 }
217 
218 // Struct to store the state of 'incsearch' highlighting.
219 typedef struct {
220     pos_T	search_start;	// where 'incsearch' starts searching
221     pos_T       save_cursor;
222     viewstate_T	init_viewstate;
223     viewstate_T	old_viewstate;
224     pos_T       match_start;
225     pos_T       match_end;
226     int		did_incsearch;
227     int		incsearch_postponed;
228     int		magic_save;
229 } incsearch_state_T;
230 
231     static void
232 init_incsearch_state(incsearch_state_T *is_state)
233 {
234     is_state->match_start = curwin->w_cursor;
235     is_state->did_incsearch = FALSE;
236     is_state->incsearch_postponed = FALSE;
237     is_state->magic_save = p_magic;
238     CLEAR_POS(&is_state->match_end);
239     is_state->save_cursor = curwin->w_cursor;  // may be restored later
240     is_state->search_start = curwin->w_cursor;
241     save_viewstate(&is_state->init_viewstate);
242     save_viewstate(&is_state->old_viewstate);
243 }
244 
245 /*
246  * First move cursor to end of match, then to the start.  This
247  * moves the whole match onto the screen when 'nowrap' is set.
248  */
249     static void
250 set_search_match(pos_T *t)
251 {
252     t->lnum += search_match_lines;
253     t->col = search_match_endcol;
254     if (t->lnum > curbuf->b_ml.ml_line_count)
255     {
256 	t->lnum = curbuf->b_ml.ml_line_count;
257 	coladvance((colnr_T)MAXCOL);
258     }
259 }
260 
261 /*
262  * Return TRUE when 'incsearch' highlighting is to be done.
263  * Sets search_first_line and search_last_line to the address range.
264  * May change the last search pattern.
265  */
266     static int
267 do_incsearch_highlighting(int firstc, incsearch_state_T *is_state,
268 						     int *skiplen, int *patlen)
269 {
270     char_u	*cmd;
271     cmdmod_T	save_cmdmod = cmdmod;
272     char_u	*p;
273     int		delim_optional = FALSE;
274     int		delim;
275     char_u	*end;
276     char	*dummy;
277     exarg_T	ea;
278     pos_T	save_cursor;
279     int		use_last_pat;
280 
281     *skiplen = 0;
282     *patlen = ccline.cmdlen;
283 
284     if (!p_is || cmd_silent)
285 	return FALSE;
286 
287     // by default search all lines
288     search_first_line = 0;
289     search_last_line = MAXLNUM;
290 
291     if (firstc == '/' || firstc == '?')
292 	return TRUE;
293     if (firstc != ':')
294 	return FALSE;
295 
296     vim_memset(&ea, 0, sizeof(ea));
297     ea.line1 = 1;
298     ea.line2 = 1;
299     ea.cmd = ccline.cmdbuff;
300     ea.addr_type = ADDR_LINES;
301 
302     parse_command_modifiers(&ea, &dummy, TRUE);
303     cmdmod = save_cmdmod;
304 
305     cmd = skip_range(ea.cmd, NULL);
306     if (vim_strchr((char_u *)"sgvl", *cmd) == NULL)
307 	return FALSE;
308 
309     // Skip over "substitute" to find the pattern separator.
310     for (p = cmd; ASCII_ISALPHA(*p); ++p)
311 	;
312     if (*skipwhite(p) == NUL)
313 	return FALSE;
314 
315     if (STRNCMP(cmd, "substitute", p - cmd) == 0
316 	    || STRNCMP(cmd, "smagic", p - cmd) == 0
317 	    || STRNCMP(cmd, "snomagic", MAX(p - cmd, 3)) == 0
318 	    || STRNCMP(cmd, "vglobal", p - cmd) == 0)
319     {
320 	if (*cmd == 's' && cmd[1] == 'm')
321 	    p_magic = TRUE;
322 	else if (*cmd == 's' && cmd[1] == 'n')
323 	    p_magic = FALSE;
324     }
325     else if (STRNCMP(cmd, "sort", MAX(p - cmd, 3)) == 0)
326     {
327 	// skip over flags
328 	while (ASCII_ISALPHA(*(p = skipwhite(p))))
329 	    ++p;
330 	if (*p == NUL)
331 	    return FALSE;
332     }
333     else if (STRNCMP(cmd, "vimgrep", MAX(p - cmd, 3)) == 0
334 	|| STRNCMP(cmd, "vimgrepadd", MAX(p - cmd, 8)) == 0
335 	|| STRNCMP(cmd, "lvimgrep", MAX(p - cmd, 2)) == 0
336 	|| STRNCMP(cmd, "lvimgrepadd", MAX(p - cmd, 9)) == 0
337 	|| STRNCMP(cmd, "global", p - cmd) == 0)
338     {
339 	// skip over "!"
340 	if (*p == '!')
341 	{
342 	    p++;
343 	    if (*skipwhite(p) == NUL)
344 		return FALSE;
345 	}
346 	if (*cmd != 'g')
347 	    delim_optional = TRUE;
348     }
349     else
350 	return FALSE;
351 
352     p = skipwhite(p);
353     delim = (delim_optional && vim_isIDc(*p)) ? ' ' : *p++;
354     end = skip_regexp(p, delim, p_magic, NULL);
355 
356     use_last_pat = end == p && *end == delim;
357 
358     if (end == p && !use_last_pat)
359 	return FALSE;
360 
361     // Don't do 'hlsearch' highlighting if the pattern matches everything.
362     if (!use_last_pat)
363     {
364 	char c = *end;
365 	int  empty;
366 
367 	*end = NUL;
368 	empty = empty_pattern(p);
369 	*end = c;
370 	if (empty)
371 	    return FALSE;
372     }
373 
374     // found a non-empty pattern or //
375     *skiplen = (int)(p - ccline.cmdbuff);
376     *patlen = (int)(end - p);
377 
378     // parse the address range
379     save_cursor = curwin->w_cursor;
380     curwin->w_cursor = is_state->search_start;
381     parse_cmd_address(&ea, &dummy, TRUE);
382     if (ea.addr_count > 0)
383     {
384 	// Allow for reverse match.
385 	if (ea.line2 < ea.line1)
386 	{
387 	    search_first_line = ea.line2;
388 	    search_last_line = ea.line1;
389 	}
390 	else
391 	{
392 	    search_first_line = ea.line1;
393 	    search_last_line = ea.line2;
394 	}
395     }
396     else if (cmd[0] == 's' && cmd[1] != 'o')
397     {
398 	// :s defaults to the current line
399 	search_first_line = curwin->w_cursor.lnum;
400 	search_last_line = curwin->w_cursor.lnum;
401     }
402 
403     curwin->w_cursor = save_cursor;
404     return TRUE;
405 }
406 
407     static void
408 finish_incsearch_highlighting(
409 	int gotesc,
410 	incsearch_state_T *is_state,
411 	int call_update_screen)
412 {
413     if (is_state->did_incsearch)
414     {
415 	is_state->did_incsearch = FALSE;
416 	if (gotesc)
417 	    curwin->w_cursor = is_state->save_cursor;
418 	else
419 	{
420 	    if (!EQUAL_POS(is_state->save_cursor, is_state->search_start))
421 	    {
422 		// put the '" mark at the original position
423 		curwin->w_cursor = is_state->save_cursor;
424 		setpcmark();
425 	    }
426 	    curwin->w_cursor = is_state->search_start;
427 	}
428 	restore_viewstate(&is_state->old_viewstate);
429 	highlight_match = FALSE;
430 
431 	// by default search all lines
432 	search_first_line = 0;
433 	search_last_line = MAXLNUM;
434 
435 	p_magic = is_state->magic_save;
436 
437 	validate_cursor();	/* needed for TAB */
438 	redraw_all_later(SOME_VALID);
439 	if (call_update_screen)
440 	    update_screen(SOME_VALID);
441     }
442 }
443 
444 /*
445  * Do 'incsearch' highlighting if desired.
446  */
447     static void
448 may_do_incsearch_highlighting(
449 	int		    firstc,
450 	long		    count,
451 	incsearch_state_T   *is_state)
452 {
453     int		skiplen, patlen;
454     int		found;  // do_search() result
455     pos_T	end_pos;
456 #ifdef FEAT_RELTIME
457     proftime_T	tm;
458 #endif
459     int		next_char;
460     int		use_last_pat;
461 
462     // Parsing range may already set the last search pattern.
463     // NOTE: must call restore_last_search_pattern() before returning!
464     save_last_search_pattern();
465 
466     if (!do_incsearch_highlighting(firstc, is_state, &skiplen, &patlen))
467     {
468 	restore_last_search_pattern();
469 	finish_incsearch_highlighting(FALSE, is_state, TRUE);
470 	return;
471     }
472 
473     // If there is a character waiting, search and redraw later.
474     if (char_avail())
475     {
476 	restore_last_search_pattern();
477 	is_state->incsearch_postponed = TRUE;
478 	return;
479     }
480     is_state->incsearch_postponed = FALSE;
481 
482     if (search_first_line == 0)
483 	// start at the original cursor position
484 	curwin->w_cursor = is_state->search_start;
485     else if (search_first_line > curbuf->b_ml.ml_line_count)
486     {
487 	// start after the last line
488 	curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
489 	curwin->w_cursor.col = MAXCOL;
490     }
491     else
492     {
493 	// start at the first line in the range
494 	curwin->w_cursor.lnum = search_first_line;
495 	curwin->w_cursor.col = 0;
496     }
497 
498     // Use the previous pattern for ":s//".
499     next_char = ccline.cmdbuff[skiplen + patlen];
500     use_last_pat = patlen == 0 && skiplen > 0
501 				   && ccline.cmdbuff[skiplen - 1] == next_char;
502 
503     // If there is no pattern, don't do anything.
504     if (patlen == 0 && !use_last_pat)
505     {
506 	found = 0;
507 	set_no_hlsearch(TRUE); // turn off previous highlight
508 	redraw_all_later(SOME_VALID);
509     }
510     else
511     {
512 	int search_flags = SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK;
513 
514 	cursor_off();	// so the user knows we're busy
515 	out_flush();
516 	++emsg_off;	// so it doesn't beep if bad expr
517 #ifdef FEAT_RELTIME
518 	// Set the time limit to half a second.
519 	profile_setlimit(500L, &tm);
520 #endif
521 	if (!p_hls)
522 	    search_flags += SEARCH_KEEP;
523 	if (search_first_line != 0)
524 	    search_flags += SEARCH_START;
525 	ccline.cmdbuff[skiplen + patlen] = NUL;
526 	found = do_search(NULL, firstc == ':' ? '/' : firstc,
527 				 ccline.cmdbuff + skiplen, count, search_flags,
528 #ifdef FEAT_RELTIME
529 		&tm, NULL
530 #else
531 		NULL, NULL
532 #endif
533 		);
534 	ccline.cmdbuff[skiplen + patlen] = next_char;
535 	--emsg_off;
536 
537 	if (curwin->w_cursor.lnum < search_first_line
538 		|| curwin->w_cursor.lnum > search_last_line)
539 	{
540 	    // match outside of address range
541 	    found = 0;
542 	    curwin->w_cursor = is_state->search_start;
543 	}
544 
545 	// if interrupted while searching, behave like it failed
546 	if (got_int)
547 	{
548 	    (void)vpeekc();	// remove <C-C> from input stream
549 	    got_int = FALSE;	// don't abandon the command line
550 	    found = 0;
551 	}
552 	else if (char_avail())
553 	    // cancelled searching because a char was typed
554 	    is_state->incsearch_postponed = TRUE;
555     }
556     if (found != 0)
557 	highlight_match = TRUE;		// highlight position
558     else
559 	highlight_match = FALSE;	// remove highlight
560 
561     // First restore the old curwin values, so the screen is positioned in the
562     // same way as the actual search command.
563     restore_viewstate(&is_state->old_viewstate);
564     changed_cline_bef_curs();
565     update_topline();
566 
567     if (found != 0)
568     {
569 	pos_T	    save_pos = curwin->w_cursor;
570 
571 	is_state->match_start = curwin->w_cursor;
572 	set_search_match(&curwin->w_cursor);
573 	validate_cursor();
574 	end_pos = curwin->w_cursor;
575 	is_state->match_end = end_pos;
576 	curwin->w_cursor = save_pos;
577     }
578     else
579 	end_pos = curwin->w_cursor; // shutup gcc 4
580 
581     // Disable 'hlsearch' highlighting if the pattern matches everything.
582     // Avoids a flash when typing "foo\|".
583     if (!use_last_pat)
584     {
585 	next_char = ccline.cmdbuff[skiplen + patlen];
586 	ccline.cmdbuff[skiplen + patlen] = NUL;
587 	if (empty_pattern(ccline.cmdbuff) && !no_hlsearch)
588 	{
589 	    redraw_all_later(SOME_VALID);
590 	    set_no_hlsearch(TRUE);
591 	}
592 	ccline.cmdbuff[skiplen + patlen] = next_char;
593     }
594 
595     validate_cursor();
596     // May redraw the status line to show the cursor position.
597     if (p_ru && curwin->w_status_height > 0)
598 	curwin->w_redr_status = TRUE;
599 
600     update_screen(SOME_VALID);
601     restore_last_search_pattern();
602 
603     // Leave it at the end to make CTRL-R CTRL-W work.  But not when beyond the
604     // end of the pattern, e.g. for ":s/pat/".
605     if (ccline.cmdbuff[skiplen + patlen] != NUL)
606 	curwin->w_cursor = is_state->search_start;
607     else if (found != 0)
608 	curwin->w_cursor = end_pos;
609 
610     msg_starthere();
611     redrawcmdline();
612     is_state->did_incsearch = TRUE;
613 }
614 
615 /*
616  * May adjust 'incsearch' highlighting for typing CTRL-G and CTRL-T, go to next
617  * or previous match.
618  * Returns FAIL when jumping to cmdline_not_changed;
619  */
620     static int
621 may_adjust_incsearch_highlighting(
622 	int			firstc,
623 	long			count,
624 	incsearch_state_T	*is_state,
625 	int			c)
626 {
627     int	    skiplen, patlen;
628     pos_T   t;
629     char_u  *pat;
630     int	    search_flags = SEARCH_NOOF;
631     int	    i;
632     int	    save;
633 
634     // Parsing range may already set the last search pattern.
635     // NOTE: must call restore_last_search_pattern() before returning!
636     save_last_search_pattern();
637 
638     if (!do_incsearch_highlighting(firstc, is_state, &skiplen, &patlen))
639     {
640 	restore_last_search_pattern();
641 	return OK;
642     }
643     if (patlen == 0 && ccline.cmdbuff[skiplen] == NUL)
644     {
645 	restore_last_search_pattern();
646 	return FAIL;
647     }
648 
649     if (firstc == ccline.cmdbuff[skiplen])
650     {
651 	pat = last_search_pattern();
652 	skiplen = 0;
653 	patlen = (int)STRLEN(pat);
654     }
655     else
656 	pat = ccline.cmdbuff + skiplen;
657 
658     cursor_off();
659     out_flush();
660     if (c == Ctrl_G)
661     {
662 	t = is_state->match_end;
663 	if (LT_POS(is_state->match_start, is_state->match_end))
664 	    // Start searching at the end of the match not at the beginning of
665 	    // the next column.
666 	    (void)decl(&t);
667 	search_flags += SEARCH_COL;
668     }
669     else
670 	t = is_state->match_start;
671     if (!p_hls)
672 	search_flags += SEARCH_KEEP;
673     ++emsg_off;
674     save = pat[patlen];
675     pat[patlen] = NUL;
676     i = searchit(curwin, curbuf, &t, NULL,
677 		 c == Ctrl_G ? FORWARD : BACKWARD,
678 		 pat, count, search_flags,
679 		 RE_SEARCH, 0, NULL, NULL);
680     --emsg_off;
681     pat[patlen] = save;
682     if (i)
683     {
684 	is_state->search_start = is_state->match_start;
685 	is_state->match_end = t;
686 	is_state->match_start = t;
687 	if (c == Ctrl_T && firstc != '?')
688 	{
689 	    // Move just before the current match, so that when nv_search
690 	    // finishes the cursor will be put back on the match.
691 	    is_state->search_start = t;
692 	    (void)decl(&is_state->search_start);
693 	}
694 	else if (c == Ctrl_G && firstc == '?')
695 	{
696 	    // Move just after the current match, so that when nv_search
697 	    // finishes the cursor will be put back on the match.
698 	    is_state->search_start = t;
699 	    (void)incl(&is_state->search_start);
700 	}
701 	if (LT_POS(t, is_state->search_start) && c == Ctrl_G)
702 	{
703 	    // wrap around
704 	    is_state->search_start = t;
705 	    if (firstc == '?')
706 		(void)incl(&is_state->search_start);
707 	    else
708 		(void)decl(&is_state->search_start);
709 	}
710 
711 	set_search_match(&is_state->match_end);
712 	curwin->w_cursor = is_state->match_start;
713 	changed_cline_bef_curs();
714 	update_topline();
715 	validate_cursor();
716 	highlight_match = TRUE;
717 	save_viewstate(&is_state->old_viewstate);
718 	update_screen(NOT_VALID);
719 	redrawcmdline();
720     }
721     else
722 	vim_beep(BO_ERROR);
723     restore_last_search_pattern();
724     return FAIL;
725 }
726 
727 /*
728  * When CTRL-L typed: add character from the match to the pattern.
729  * May set "*c" to the added character.
730  * Return OK when jumping to cmdline_not_changed.
731  */
732     static int
733 may_add_char_to_search(int firstc, int *c, incsearch_state_T *is_state)
734 {
735     int		skiplen, patlen;
736 
737     // Parsing range may already set the last search pattern.
738     // NOTE: must call restore_last_search_pattern() before returning!
739     save_last_search_pattern();
740 
741     if (!do_incsearch_highlighting(firstc, is_state, &skiplen, &patlen))
742     {
743 	restore_last_search_pattern();
744 	return FAIL;
745     }
746     restore_last_search_pattern();
747 
748     // Add a character from under the cursor for 'incsearch'.
749     if (is_state->did_incsearch)
750     {
751 	curwin->w_cursor = is_state->match_end;
752 	if (!EQUAL_POS(curwin->w_cursor, is_state->search_start))
753 	{
754 	    *c = gchar_cursor();
755 
756 	    // If 'ignorecase' and 'smartcase' are set and the
757 	    // command line has no uppercase characters, convert
758 	    // the character to lowercase.
759 	    if (p_ic && p_scs && !pat_has_uppercase(ccline.cmdbuff + skiplen))
760 		*c = MB_TOLOWER(*c);
761 	    if (*c != NUL)
762 	    {
763 		if (*c == firstc || vim_strchr((char_u *)(
764 				   p_magic ? "\\~^$.*[" : "\\^$"), *c) != NULL)
765 		{
766 		    // put a backslash before special characters
767 		    stuffcharReadbuff(*c);
768 		    *c = '\\';
769 		}
770 		// add any composing characters
771 		if (mb_char2len(*c) != mb_ptr2len(ml_get_cursor()))
772 		{
773 		    int save_c = *c;
774 
775 		    while (mb_char2len(*c) != mb_ptr2len(ml_get_cursor()))
776 		    {
777 			curwin->w_cursor.col += mb_char2len(*c);
778 			*c = gchar_cursor();
779 			stuffcharReadbuff(*c);
780 		    }
781 		    *c = save_c;
782 		}
783 		return FAIL;
784 	    }
785 	}
786     }
787     return OK;
788 }
789 #endif
790 
791     void
792 cmdline_init(void)
793 {
794     vim_memset(&ccline, 0, sizeof(struct cmdline_info));
795 }
796 
797 /*
798  * getcmdline() - accept a command line starting with firstc.
799  *
800  * firstc == ':'	    get ":" command line.
801  * firstc == '/' or '?'	    get search pattern
802  * firstc == '='	    get expression
803  * firstc == '@'	    get text for input() function
804  * firstc == '>'	    get text for debug mode
805  * firstc == NUL	    get text for :insert command
806  * firstc == -1		    like NUL, and break on CTRL-C
807  *
808  * The line is collected in ccline.cmdbuff, which is reallocated to fit the
809  * command line.
810  *
811  * Careful: getcmdline() can be called recursively!
812  *
813  * Return pointer to allocated string if there is a commandline, NULL
814  * otherwise.
815  */
816     char_u *
817 getcmdline(
818     int		firstc,
819     long	count,		// only used for incremental search
820     int		indent)		// indent for inside conditionals
821 {
822     return getcmdline_int(firstc, count, indent, TRUE);
823 }
824 
825     static char_u *
826 getcmdline_int(
827     int		firstc,
828     long	count UNUSED,	// only used for incremental search
829     int		indent,		// indent for inside conditionals
830     int		init_ccline)	// clear ccline first
831 {
832     int		c;
833     int		i;
834     int		j;
835     int		gotesc = FALSE;		/* TRUE when <ESC> just typed */
836     int		do_abbr;		/* when TRUE check for abbr. */
837 #ifdef FEAT_CMDHIST
838     char_u	*lookfor = NULL;	/* string to match */
839     int		hiscnt;			/* current history line in use */
840     int		histype;		/* history type to be used */
841 #endif
842 #ifdef FEAT_SEARCH_EXTRA
843     incsearch_state_T	is_state;
844 #endif
845     int		did_wild_list = FALSE;	/* did wild_list() recently */
846     int		wim_index = 0;		/* index in wim_flags[] */
847     int		res;
848     int		save_msg_scroll = msg_scroll;
849     int		save_State = State;	/* remember State when called */
850     int		some_key_typed = FALSE;	/* one of the keys was typed */
851 #ifdef FEAT_MOUSE
852     /* mouse drag and release events are ignored, unless they are
853      * preceded with a mouse down event */
854     int		ignore_drag_release = TRUE;
855 #endif
856 #ifdef FEAT_EVAL
857     int		break_ctrl_c = FALSE;
858 #endif
859     expand_T	xpc;
860     long	*b_im_ptr = NULL;
861     struct cmdline_info save_ccline;
862     int		did_save_ccline = FALSE;
863     int		cmdline_type;
864 
865     if (ccline.cmdbuff != NULL)
866     {
867 	// Being called recursively.  Since ccline is global, we need to save
868 	// the current buffer and restore it when returning.
869 	save_cmdline(&save_ccline);
870 	did_save_ccline = TRUE;
871     }
872     if (init_ccline)
873 	vim_memset(&ccline, 0, sizeof(struct cmdline_info));
874 
875 #ifdef FEAT_EVAL
876     if (firstc == -1)
877     {
878 	firstc = NUL;
879 	break_ctrl_c = TRUE;
880     }
881 #endif
882 #ifdef FEAT_RIGHTLEFT
883     /* start without Hebrew mapping for a command line */
884     if (firstc == ':' || firstc == '=' || firstc == '>')
885 	cmd_hkmap = 0;
886 #endif
887 
888     ccline.overstrike = FALSE;		    /* always start in insert mode */
889 
890 #ifdef FEAT_SEARCH_EXTRA
891     init_incsearch_state(&is_state);
892 #endif
893 
894     /*
895      * set some variables for redrawcmd()
896      */
897     ccline.cmdfirstc = (firstc == '@' ? 0 : firstc);
898     ccline.cmdindent = (firstc > 0 ? indent : 0);
899 
900     /* alloc initial ccline.cmdbuff */
901     alloc_cmdbuff(exmode_active ? 250 : indent + 1);
902     if (ccline.cmdbuff == NULL)
903 	goto theend;	// out of memory
904     ccline.cmdlen = ccline.cmdpos = 0;
905     ccline.cmdbuff[0] = NUL;
906     sb_text_start_cmdline();
907 
908     /* autoindent for :insert and :append */
909     if (firstc <= 0)
910     {
911 	vim_memset(ccline.cmdbuff, ' ', indent);
912 	ccline.cmdbuff[indent] = NUL;
913 	ccline.cmdpos = indent;
914 	ccline.cmdspos = indent;
915 	ccline.cmdlen = indent;
916     }
917 
918     ExpandInit(&xpc);
919     ccline.xpc = &xpc;
920 
921 #ifdef FEAT_RIGHTLEFT
922     if (curwin->w_p_rl && *curwin->w_p_rlc == 's'
923 					  && (firstc == '/' || firstc == '?'))
924 	cmdmsg_rl = TRUE;
925     else
926 	cmdmsg_rl = FALSE;
927 #endif
928 
929     redir_off = TRUE;		/* don't redirect the typed command */
930     if (!cmd_silent)
931     {
932 	i = msg_scrolled;
933 	msg_scrolled = 0;		/* avoid wait_return message */
934 	gotocmdline(TRUE);
935 	msg_scrolled += i;
936 	redrawcmdprompt();		/* draw prompt or indent */
937 	set_cmdspos();
938     }
939     xpc.xp_context = EXPAND_NOTHING;
940     xpc.xp_backslash = XP_BS_NONE;
941 #ifndef BACKSLASH_IN_FILENAME
942     xpc.xp_shell = FALSE;
943 #endif
944 
945 #if defined(FEAT_EVAL)
946     if (ccline.input_fn)
947     {
948 	xpc.xp_context = ccline.xp_context;
949 	xpc.xp_pattern = ccline.cmdbuff;
950 # if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)
951 	xpc.xp_arg = ccline.xp_arg;
952 # endif
953     }
954 #endif
955 
956     /*
957      * Avoid scrolling when called by a recursive do_cmdline(), e.g. when
958      * doing ":@0" when register 0 doesn't contain a CR.
959      */
960     msg_scroll = FALSE;
961 
962     State = CMDLINE;
963 
964     if (firstc == '/' || firstc == '?' || firstc == '@')
965     {
966 	/* Use ":lmap" mappings for search pattern and input(). */
967 	if (curbuf->b_p_imsearch == B_IMODE_USE_INSERT)
968 	    b_im_ptr = &curbuf->b_p_iminsert;
969 	else
970 	    b_im_ptr = &curbuf->b_p_imsearch;
971 	if (*b_im_ptr == B_IMODE_LMAP)
972 	    State |= LANGMAP;
973 #ifdef HAVE_INPUT_METHOD
974 	im_set_active(*b_im_ptr == B_IMODE_IM);
975 #endif
976     }
977 #ifdef HAVE_INPUT_METHOD
978     else if (p_imcmdline)
979 	im_set_active(TRUE);
980 #endif
981 
982 #ifdef FEAT_MOUSE
983     setmouse();
984 #endif
985 #ifdef CURSOR_SHAPE
986     ui_cursor_shape();		/* may show different cursor shape */
987 #endif
988 
989     /* When inside an autocommand for writing "exiting" may be set and
990      * terminal mode set to cooked.  Need to set raw mode here then. */
991     settmode(TMODE_RAW);
992 
993     /* Trigger CmdlineEnter autocommands. */
994     cmdline_type = firstc == NUL ? '-' : firstc;
995     trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINEENTER);
996 
997 #ifdef FEAT_CMDHIST
998     init_history();
999     hiscnt = hislen;		/* set hiscnt to impossible history value */
1000     histype = hist_char2type(firstc);
1001 #endif
1002 
1003 #ifdef FEAT_DIGRAPHS
1004     do_digraph(-1);		/* init digraph typeahead */
1005 #endif
1006 
1007     /* If something above caused an error, reset the flags, we do want to type
1008      * and execute commands. Display may be messed up a bit. */
1009     if (did_emsg)
1010 	redrawcmd();
1011     did_emsg = FALSE;
1012     got_int = FALSE;
1013 
1014     /*
1015      * Collect the command string, handling editing keys.
1016      */
1017     for (;;)
1018     {
1019 	redir_off = TRUE;	/* Don't redirect the typed command.
1020 				   Repeated, because a ":redir" inside
1021 				   completion may switch it on. */
1022 #ifdef USE_ON_FLY_SCROLL
1023 	dont_scroll = FALSE;	/* allow scrolling here */
1024 #endif
1025 	quit_more = FALSE;	/* reset after CTRL-D which had a more-prompt */
1026 
1027 	did_emsg = FALSE;	/* There can't really be a reason why an error
1028 				   that occurs while typing a command should
1029 				   cause the command not to be executed. */
1030 
1031 	cursorcmd();		/* set the cursor on the right spot */
1032 
1033 	/* Get a character.  Ignore K_IGNORE and K_NOP, they should not do
1034 	 * anything, such as stop completion. */
1035 	do
1036 	{
1037 	    c = safe_vgetc();
1038 	} while (c == K_IGNORE || c == K_NOP);
1039 
1040 	if (KeyTyped)
1041 	{
1042 	    some_key_typed = TRUE;
1043 #ifdef FEAT_RIGHTLEFT
1044 	    if (cmd_hkmap)
1045 		c = hkmap(c);
1046 # ifdef FEAT_FKMAP
1047 	    if (cmd_fkmap)
1048 		c = cmdl_fkmap(c);
1049 # endif
1050 	    if (cmdmsg_rl && !KeyStuffed)
1051 	    {
1052 		/* Invert horizontal movements and operations.  Only when
1053 		 * typed by the user directly, not when the result of a
1054 		 * mapping. */
1055 		switch (c)
1056 		{
1057 		    case K_RIGHT:   c = K_LEFT; break;
1058 		    case K_S_RIGHT: c = K_S_LEFT; break;
1059 		    case K_C_RIGHT: c = K_C_LEFT; break;
1060 		    case K_LEFT:    c = K_RIGHT; break;
1061 		    case K_S_LEFT:  c = K_S_RIGHT; break;
1062 		    case K_C_LEFT:  c = K_C_RIGHT; break;
1063 		}
1064 	    }
1065 #endif
1066 	}
1067 
1068 	/*
1069 	 * Ignore got_int when CTRL-C was typed here.
1070 	 * Don't ignore it in :global, we really need to break then, e.g., for
1071 	 * ":g/pat/normal /pat" (without the <CR>).
1072 	 * Don't ignore it for the input() function.
1073 	 */
1074 	if ((c == Ctrl_C
1075 #ifdef UNIX
1076 		|| c == intr_char
1077 #endif
1078 				)
1079 #if defined(FEAT_EVAL) || defined(FEAT_CRYPT)
1080 		&& firstc != '@'
1081 #endif
1082 #ifdef FEAT_EVAL
1083 		&& !break_ctrl_c
1084 #endif
1085 		&& !global_busy)
1086 	    got_int = FALSE;
1087 
1088 #ifdef FEAT_CMDHIST
1089 	/* free old command line when finished moving around in the history
1090 	 * list */
1091 	if (lookfor != NULL
1092 		&& c != K_S_DOWN && c != K_S_UP
1093 		&& c != K_DOWN && c != K_UP
1094 		&& c != K_PAGEDOWN && c != K_PAGEUP
1095 		&& c != K_KPAGEDOWN && c != K_KPAGEUP
1096 		&& c != K_LEFT && c != K_RIGHT
1097 		&& (xpc.xp_numfiles > 0 || (c != Ctrl_P && c != Ctrl_N)))
1098 	    VIM_CLEAR(lookfor);
1099 #endif
1100 
1101 	/*
1102 	 * When there are matching completions to select <S-Tab> works like
1103 	 * CTRL-P (unless 'wc' is <S-Tab>).
1104 	 */
1105 	if (c != p_wc && c == K_S_TAB && xpc.xp_numfiles > 0)
1106 	    c = Ctrl_P;
1107 
1108 #ifdef FEAT_WILDMENU
1109 	/* Special translations for 'wildmenu' */
1110 	if (did_wild_list && p_wmnu)
1111 	{
1112 	    if (c == K_LEFT)
1113 		c = Ctrl_P;
1114 	    else if (c == K_RIGHT)
1115 		c = Ctrl_N;
1116 	}
1117 	/* Hitting CR after "emenu Name.": complete submenu */
1118 	if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu
1119 		&& ccline.cmdpos > 1
1120 		&& ccline.cmdbuff[ccline.cmdpos - 1] == '.'
1121 		&& ccline.cmdbuff[ccline.cmdpos - 2] != '\\'
1122 		&& (c == '\n' || c == '\r' || c == K_KENTER))
1123 	    c = K_DOWN;
1124 #endif
1125 
1126 	/* free expanded names when finished walking through matches */
1127 	if (xpc.xp_numfiles != -1
1128 		&& !(c == p_wc && KeyTyped) && c != p_wcm
1129 		&& c != Ctrl_N && c != Ctrl_P && c != Ctrl_A
1130 		&& c != Ctrl_L)
1131 	{
1132 	    (void)ExpandOne(&xpc, NULL, NULL, 0, WILD_FREE);
1133 	    did_wild_list = FALSE;
1134 #ifdef FEAT_WILDMENU
1135 	    if (!p_wmnu || (c != K_UP && c != K_DOWN))
1136 #endif
1137 		xpc.xp_context = EXPAND_NOTHING;
1138 	    wim_index = 0;
1139 #ifdef FEAT_WILDMENU
1140 	    if (p_wmnu && wild_menu_showing != 0)
1141 	    {
1142 		int skt = KeyTyped;
1143 		int old_RedrawingDisabled = RedrawingDisabled;
1144 
1145 		if (ccline.input_fn)
1146 		    RedrawingDisabled = 0;
1147 
1148 		if (wild_menu_showing == WM_SCROLLED)
1149 		{
1150 		    /* Entered command line, move it up */
1151 		    cmdline_row--;
1152 		    redrawcmd();
1153 		}
1154 		else if (save_p_ls != -1)
1155 		{
1156 		    /* restore 'laststatus' and 'winminheight' */
1157 		    p_ls = save_p_ls;
1158 		    p_wmh = save_p_wmh;
1159 		    last_status(FALSE);
1160 		    update_screen(VALID);	/* redraw the screen NOW */
1161 		    redrawcmd();
1162 		    save_p_ls = -1;
1163 		}
1164 		else
1165 		{
1166 		    win_redraw_last_status(topframe);
1167 		    redraw_statuslines();
1168 		}
1169 		KeyTyped = skt;
1170 		wild_menu_showing = 0;
1171 		if (ccline.input_fn)
1172 		    RedrawingDisabled = old_RedrawingDisabled;
1173 	    }
1174 #endif
1175 	}
1176 
1177 #ifdef FEAT_WILDMENU
1178 	/* Special translations for 'wildmenu' */
1179 	if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu)
1180 	{
1181 	    /* Hitting <Down> after "emenu Name.": complete submenu */
1182 	    if (c == K_DOWN && ccline.cmdpos > 0
1183 				  && ccline.cmdbuff[ccline.cmdpos - 1] == '.')
1184 		c = p_wc;
1185 	    else if (c == K_UP)
1186 	    {
1187 		/* Hitting <Up>: Remove one submenu name in front of the
1188 		 * cursor */
1189 		int found = FALSE;
1190 
1191 		j = (int)(xpc.xp_pattern - ccline.cmdbuff);
1192 		i = 0;
1193 		while (--j > 0)
1194 		{
1195 		    /* check for start of menu name */
1196 		    if (ccline.cmdbuff[j] == ' '
1197 			    && ccline.cmdbuff[j - 1] != '\\')
1198 		    {
1199 			i = j + 1;
1200 			break;
1201 		    }
1202 		    /* check for start of submenu name */
1203 		    if (ccline.cmdbuff[j] == '.'
1204 			    && ccline.cmdbuff[j - 1] != '\\')
1205 		    {
1206 			if (found)
1207 			{
1208 			    i = j + 1;
1209 			    break;
1210 			}
1211 			else
1212 			    found = TRUE;
1213 		    }
1214 		}
1215 		if (i > 0)
1216 		    cmdline_del(i);
1217 		c = p_wc;
1218 		xpc.xp_context = EXPAND_NOTHING;
1219 	    }
1220 	}
1221 	if ((xpc.xp_context == EXPAND_FILES
1222 			      || xpc.xp_context == EXPAND_DIRECTORIES
1223 			      || xpc.xp_context == EXPAND_SHELLCMD) && p_wmnu)
1224 	{
1225 	    char_u upseg[5];
1226 
1227 	    upseg[0] = PATHSEP;
1228 	    upseg[1] = '.';
1229 	    upseg[2] = '.';
1230 	    upseg[3] = PATHSEP;
1231 	    upseg[4] = NUL;
1232 
1233 	    if (c == K_DOWN
1234 		    && ccline.cmdpos > 0
1235 		    && ccline.cmdbuff[ccline.cmdpos - 1] == PATHSEP
1236 		    && (ccline.cmdpos < 3
1237 			|| ccline.cmdbuff[ccline.cmdpos - 2] != '.'
1238 			|| ccline.cmdbuff[ccline.cmdpos - 3] != '.'))
1239 	    {
1240 		/* go down a directory */
1241 		c = p_wc;
1242 	    }
1243 	    else if (STRNCMP(xpc.xp_pattern, upseg + 1, 3) == 0 && c == K_DOWN)
1244 	    {
1245 		/* If in a direct ancestor, strip off one ../ to go down */
1246 		int found = FALSE;
1247 
1248 		j = ccline.cmdpos;
1249 		i = (int)(xpc.xp_pattern - ccline.cmdbuff);
1250 		while (--j > i)
1251 		{
1252 		    if (has_mbyte)
1253 			j -= (*mb_head_off)(ccline.cmdbuff, ccline.cmdbuff + j);
1254 		    if (vim_ispathsep(ccline.cmdbuff[j]))
1255 		    {
1256 			found = TRUE;
1257 			break;
1258 		    }
1259 		}
1260 		if (found
1261 			&& ccline.cmdbuff[j - 1] == '.'
1262 			&& ccline.cmdbuff[j - 2] == '.'
1263 			&& (vim_ispathsep(ccline.cmdbuff[j - 3]) || j == i + 2))
1264 		{
1265 		    cmdline_del(j - 2);
1266 		    c = p_wc;
1267 		}
1268 	    }
1269 	    else if (c == K_UP)
1270 	    {
1271 		/* go up a directory */
1272 		int found = FALSE;
1273 
1274 		j = ccline.cmdpos - 1;
1275 		i = (int)(xpc.xp_pattern - ccline.cmdbuff);
1276 		while (--j > i)
1277 		{
1278 		    if (has_mbyte)
1279 			j -= (*mb_head_off)(ccline.cmdbuff, ccline.cmdbuff + j);
1280 		    if (vim_ispathsep(ccline.cmdbuff[j])
1281 #ifdef BACKSLASH_IN_FILENAME
1282 			    && vim_strchr((char_u *)" *?[{`$%#",
1283 				ccline.cmdbuff[j + 1]) == NULL
1284 #endif
1285 		       )
1286 		    {
1287 			if (found)
1288 			{
1289 			    i = j + 1;
1290 			    break;
1291 			}
1292 			else
1293 			    found = TRUE;
1294 		    }
1295 		}
1296 
1297 		if (!found)
1298 		    j = i;
1299 		else if (STRNCMP(ccline.cmdbuff + j, upseg, 4) == 0)
1300 		    j += 4;
1301 		else if (STRNCMP(ccline.cmdbuff + j, upseg + 1, 3) == 0
1302 			     && j == i)
1303 		    j += 3;
1304 		else
1305 		    j = 0;
1306 		if (j > 0)
1307 		{
1308 		    /* TODO this is only for DOS/UNIX systems - need to put in
1309 		     * machine-specific stuff here and in upseg init */
1310 		    cmdline_del(j);
1311 		    put_on_cmdline(upseg + 1, 3, FALSE);
1312 		}
1313 		else if (ccline.cmdpos > i)
1314 		    cmdline_del(i);
1315 
1316 		/* Now complete in the new directory. Set KeyTyped in case the
1317 		 * Up key came from a mapping. */
1318 		c = p_wc;
1319 		KeyTyped = TRUE;
1320 	    }
1321 	}
1322 
1323 #endif	/* FEAT_WILDMENU */
1324 
1325 	/* CTRL-\ CTRL-N goes to Normal mode, CTRL-\ CTRL-G goes to Insert
1326 	 * mode when 'insertmode' is set, CTRL-\ e prompts for an expression. */
1327 	if (c == Ctrl_BSL)
1328 	{
1329 	    ++no_mapping;
1330 	    ++allow_keys;
1331 	    c = plain_vgetc();
1332 	    --no_mapping;
1333 	    --allow_keys;
1334 	    /* CTRL-\ e doesn't work when obtaining an expression, unless it
1335 	     * is in a mapping. */
1336 	    if (c != Ctrl_N && c != Ctrl_G && (c != 'e'
1337 				    || (ccline.cmdfirstc == '=' && KeyTyped)
1338 #ifdef FEAT_EVAL
1339 				    || cmdline_star > 0
1340 #endif
1341 				    ))
1342 	    {
1343 		vungetc(c);
1344 		c = Ctrl_BSL;
1345 	    }
1346 #ifdef FEAT_EVAL
1347 	    else if (c == 'e')
1348 	    {
1349 		char_u	*p = NULL;
1350 		int	len;
1351 
1352 		/*
1353 		 * Replace the command line with the result of an expression.
1354 		 * Need to save and restore the current command line, to be
1355 		 * able to enter a new one...
1356 		 */
1357 		if (ccline.cmdpos == ccline.cmdlen)
1358 		    new_cmdpos = 99999;	/* keep it at the end */
1359 		else
1360 		    new_cmdpos = ccline.cmdpos;
1361 
1362 		c = get_expr_register();
1363 		if (c == '=')
1364 		{
1365 		    /* Need to save and restore ccline.  And set "textlock"
1366 		     * to avoid nasty things like going to another buffer when
1367 		     * evaluating an expression. */
1368 		    ++textlock;
1369 		    p = get_expr_line();
1370 		    --textlock;
1371 
1372 		    if (p != NULL)
1373 		    {
1374 			len = (int)STRLEN(p);
1375 			if (realloc_cmdbuff(len + 1) == OK)
1376 			{
1377 			    ccline.cmdlen = len;
1378 			    STRCPY(ccline.cmdbuff, p);
1379 			    vim_free(p);
1380 
1381 			    /* Restore the cursor or use the position set with
1382 			     * set_cmdline_pos(). */
1383 			    if (new_cmdpos > ccline.cmdlen)
1384 				ccline.cmdpos = ccline.cmdlen;
1385 			    else
1386 				ccline.cmdpos = new_cmdpos;
1387 
1388 			    KeyTyped = FALSE;	/* Don't do p_wc completion. */
1389 			    redrawcmd();
1390 			    goto cmdline_changed;
1391 			}
1392 			vim_free(p);
1393 		    }
1394 		}
1395 		beep_flush();
1396 		got_int = FALSE;	/* don't abandon the command line */
1397 		did_emsg = FALSE;
1398 		emsg_on_display = FALSE;
1399 		redrawcmd();
1400 		goto cmdline_not_changed;
1401 	    }
1402 #endif
1403 	    else
1404 	    {
1405 		if (c == Ctrl_G && p_im && restart_edit == 0)
1406 		    restart_edit = 'a';
1407 		gotesc = TRUE;	/* will free ccline.cmdbuff after putting it
1408 				   in history */
1409 		goto returncmd;	/* back to Normal mode */
1410 	    }
1411 	}
1412 
1413 #ifdef FEAT_CMDWIN
1414 	if (c == cedit_key || c == K_CMDWIN)
1415 	{
1416 	    if (ex_normal_busy == 0 && got_int == FALSE)
1417 	    {
1418 		/*
1419 		 * Open a window to edit the command line (and history).
1420 		 */
1421 		c = open_cmdwin();
1422 		some_key_typed = TRUE;
1423 	    }
1424 	}
1425 # ifdef FEAT_DIGRAPHS
1426 	else
1427 # endif
1428 #endif
1429 #ifdef FEAT_DIGRAPHS
1430 	    c = do_digraph(c);
1431 #endif
1432 
1433 	if (c == '\n' || c == '\r' || c == K_KENTER || (c == ESC
1434 			&& (!KeyTyped || vim_strchr(p_cpo, CPO_ESC) != NULL)))
1435 	{
1436 	    /* In Ex mode a backslash escapes a newline. */
1437 	    if (exmode_active
1438 		    && c != ESC
1439 		    && ccline.cmdpos == ccline.cmdlen
1440 		    && ccline.cmdpos > 0
1441 		    && ccline.cmdbuff[ccline.cmdpos - 1] == '\\')
1442 	    {
1443 		if (c == K_KENTER)
1444 		    c = '\n';
1445 	    }
1446 	    else
1447 	    {
1448 		gotesc = FALSE;	/* Might have typed ESC previously, don't
1449 				       truncate the cmdline now. */
1450 		if (ccheck_abbr(c + ABBR_OFF))
1451 		    goto cmdline_changed;
1452 		if (!cmd_silent)
1453 		{
1454 		    windgoto(msg_row, 0);
1455 		    out_flush();
1456 		}
1457 		break;
1458 	    }
1459 	}
1460 
1461 	/*
1462 	 * Completion for 'wildchar' or 'wildcharm' key.
1463 	 * - hitting <ESC> twice means: abandon command line.
1464 	 * - wildcard expansion is only done when the 'wildchar' key is really
1465 	 *   typed, not when it comes from a macro
1466 	 */
1467 	if ((c == p_wc && !gotesc && KeyTyped) || c == p_wcm)
1468 	{
1469 	    if (xpc.xp_numfiles > 0)   /* typed p_wc at least twice */
1470 	    {
1471 		/* if 'wildmode' contains "list" may still need to list */
1472 		if (xpc.xp_numfiles > 1
1473 			&& !did_wild_list
1474 			&& (wim_flags[wim_index] & WIM_LIST))
1475 		{
1476 		    (void)showmatches(&xpc, FALSE);
1477 		    redrawcmd();
1478 		    did_wild_list = TRUE;
1479 		}
1480 		if (wim_flags[wim_index] & WIM_LONGEST)
1481 		    res = nextwild(&xpc, WILD_LONGEST, WILD_NO_BEEP,
1482 							       firstc != '@');
1483 		else if (wim_flags[wim_index] & WIM_FULL)
1484 		    res = nextwild(&xpc, WILD_NEXT, WILD_NO_BEEP,
1485 							       firstc != '@');
1486 		else
1487 		    res = OK;	    /* don't insert 'wildchar' now */
1488 	    }
1489 	    else		    /* typed p_wc first time */
1490 	    {
1491 		wim_index = 0;
1492 		j = ccline.cmdpos;
1493 		/* if 'wildmode' first contains "longest", get longest
1494 		 * common part */
1495 		if (wim_flags[0] & WIM_LONGEST)
1496 		    res = nextwild(&xpc, WILD_LONGEST, WILD_NO_BEEP,
1497 							       firstc != '@');
1498 		else
1499 		    res = nextwild(&xpc, WILD_EXPAND_KEEP, WILD_NO_BEEP,
1500 							       firstc != '@');
1501 
1502 		/* if interrupted while completing, behave like it failed */
1503 		if (got_int)
1504 		{
1505 		    (void)vpeekc();	/* remove <C-C> from input stream */
1506 		    got_int = FALSE;	/* don't abandon the command line */
1507 		    (void)ExpandOne(&xpc, NULL, NULL, 0, WILD_FREE);
1508 #ifdef FEAT_WILDMENU
1509 		    xpc.xp_context = EXPAND_NOTHING;
1510 #endif
1511 		    goto cmdline_changed;
1512 		}
1513 
1514 		/* when more than one match, and 'wildmode' first contains
1515 		 * "list", or no change and 'wildmode' contains "longest,list",
1516 		 * list all matches */
1517 		if (res == OK && xpc.xp_numfiles > 1)
1518 		{
1519 		    /* a "longest" that didn't do anything is skipped (but not
1520 		     * "list:longest") */
1521 		    if (wim_flags[0] == WIM_LONGEST && ccline.cmdpos == j)
1522 			wim_index = 1;
1523 		    if ((wim_flags[wim_index] & WIM_LIST)
1524 #ifdef FEAT_WILDMENU
1525 			    || (p_wmnu && (wim_flags[wim_index] & WIM_FULL) != 0)
1526 #endif
1527 			    )
1528 		    {
1529 			if (!(wim_flags[0] & WIM_LONGEST))
1530 			{
1531 #ifdef FEAT_WILDMENU
1532 			    int p_wmnu_save = p_wmnu;
1533 			    p_wmnu = 0;
1534 #endif
1535 			    /* remove match */
1536 			    nextwild(&xpc, WILD_PREV, 0, firstc != '@');
1537 #ifdef FEAT_WILDMENU
1538 			    p_wmnu = p_wmnu_save;
1539 #endif
1540 			}
1541 #ifdef FEAT_WILDMENU
1542 			(void)showmatches(&xpc, p_wmnu
1543 				&& ((wim_flags[wim_index] & WIM_LIST) == 0));
1544 #else
1545 			(void)showmatches(&xpc, FALSE);
1546 #endif
1547 			redrawcmd();
1548 			did_wild_list = TRUE;
1549 			if (wim_flags[wim_index] & WIM_LONGEST)
1550 			    nextwild(&xpc, WILD_LONGEST, WILD_NO_BEEP,
1551 							       firstc != '@');
1552 			else if (wim_flags[wim_index] & WIM_FULL)
1553 			    nextwild(&xpc, WILD_NEXT, WILD_NO_BEEP,
1554 							       firstc != '@');
1555 		    }
1556 		    else
1557 			vim_beep(BO_WILD);
1558 		}
1559 #ifdef FEAT_WILDMENU
1560 		else if (xpc.xp_numfiles == -1)
1561 		    xpc.xp_context = EXPAND_NOTHING;
1562 #endif
1563 	    }
1564 	    if (wim_index < 3)
1565 		++wim_index;
1566 	    if (c == ESC)
1567 		gotesc = TRUE;
1568 	    if (res == OK)
1569 		goto cmdline_changed;
1570 	}
1571 
1572 	gotesc = FALSE;
1573 
1574 	/* <S-Tab> goes to last match, in a clumsy way */
1575 	if (c == K_S_TAB && KeyTyped)
1576 	{
1577 	    if (nextwild(&xpc, WILD_EXPAND_KEEP, 0, firstc != '@') == OK
1578 		    && nextwild(&xpc, WILD_PREV, 0, firstc != '@') == OK
1579 		    && nextwild(&xpc, WILD_PREV, 0, firstc != '@') == OK)
1580 		goto cmdline_changed;
1581 	}
1582 
1583 	if (c == NUL || c == K_ZERO)	    /* NUL is stored as NL */
1584 	    c = NL;
1585 
1586 	do_abbr = TRUE;		/* default: check for abbreviation */
1587 
1588 	/*
1589 	 * Big switch for a typed command line character.
1590 	 */
1591 	switch (c)
1592 	{
1593 	case K_BS:
1594 	case Ctrl_H:
1595 	case K_DEL:
1596 	case K_KDEL:
1597 	case Ctrl_W:
1598 #ifdef FEAT_FKMAP
1599 		if (cmd_fkmap && c == K_BS)
1600 		    c = K_DEL;
1601 #endif
1602 		if (c == K_KDEL)
1603 		    c = K_DEL;
1604 
1605 		/*
1606 		 * delete current character is the same as backspace on next
1607 		 * character, except at end of line
1608 		 */
1609 		if (c == K_DEL && ccline.cmdpos != ccline.cmdlen)
1610 		    ++ccline.cmdpos;
1611 		if (has_mbyte && c == K_DEL)
1612 		    ccline.cmdpos += mb_off_next(ccline.cmdbuff,
1613 					      ccline.cmdbuff + ccline.cmdpos);
1614 		if (ccline.cmdpos > 0)
1615 		{
1616 		    char_u *p;
1617 
1618 		    j = ccline.cmdpos;
1619 		    p = ccline.cmdbuff + j;
1620 		    if (has_mbyte)
1621 		    {
1622 			p = mb_prevptr(ccline.cmdbuff, p);
1623 			if (c == Ctrl_W)
1624 			{
1625 			    while (p > ccline.cmdbuff && vim_isspace(*p))
1626 				p = mb_prevptr(ccline.cmdbuff, p);
1627 			    i = mb_get_class(p);
1628 			    while (p > ccline.cmdbuff && mb_get_class(p) == i)
1629 				p = mb_prevptr(ccline.cmdbuff, p);
1630 			    if (mb_get_class(p) != i)
1631 				p += (*mb_ptr2len)(p);
1632 			}
1633 		    }
1634 		    else if (c == Ctrl_W)
1635 		    {
1636 			while (p > ccline.cmdbuff && vim_isspace(p[-1]))
1637 			    --p;
1638 			i = vim_iswordc(p[-1]);
1639 			while (p > ccline.cmdbuff && !vim_isspace(p[-1])
1640 				&& vim_iswordc(p[-1]) == i)
1641 			    --p;
1642 		    }
1643 		    else
1644 			--p;
1645 		    ccline.cmdpos = (int)(p - ccline.cmdbuff);
1646 		    ccline.cmdlen -= j - ccline.cmdpos;
1647 		    i = ccline.cmdpos;
1648 		    while (i < ccline.cmdlen)
1649 			ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
1650 
1651 		    /* Truncate at the end, required for multi-byte chars. */
1652 		    ccline.cmdbuff[ccline.cmdlen] = NUL;
1653 #ifdef FEAT_SEARCH_EXTRA
1654 		    if (ccline.cmdlen == 0)
1655 		    {
1656 			is_state.search_start = is_state.save_cursor;
1657 			/* save view settings, so that the screen
1658 			 * won't be restored at the wrong position */
1659 			is_state.old_viewstate = is_state.init_viewstate;
1660 		    }
1661 #endif
1662 		    redrawcmd();
1663 		}
1664 		else if (ccline.cmdlen == 0 && c != Ctrl_W
1665 				   && ccline.cmdprompt == NULL && indent == 0)
1666 		{
1667 		    /* In ex and debug mode it doesn't make sense to return. */
1668 		    if (exmode_active
1669 #ifdef FEAT_EVAL
1670 			    || ccline.cmdfirstc == '>'
1671 #endif
1672 			    )
1673 			goto cmdline_not_changed;
1674 
1675 		    VIM_CLEAR(ccline.cmdbuff);	/* no commandline to return */
1676 		    if (!cmd_silent)
1677 		    {
1678 #ifdef FEAT_RIGHTLEFT
1679 			if (cmdmsg_rl)
1680 			    msg_col = Columns;
1681 			else
1682 #endif
1683 			    msg_col = 0;
1684 			msg_putchar(' ');		/* delete ':' */
1685 		    }
1686 #ifdef FEAT_SEARCH_EXTRA
1687 		    if (ccline.cmdlen == 0)
1688 			is_state.search_start = is_state.save_cursor;
1689 #endif
1690 		    redraw_cmdline = TRUE;
1691 		    goto returncmd;		/* back to cmd mode */
1692 		}
1693 		goto cmdline_changed;
1694 
1695 	case K_INS:
1696 	case K_KINS:
1697 #ifdef FEAT_FKMAP
1698 		/* if Farsi mode set, we are in reverse insert mode -
1699 		   Do not change the mode */
1700 		if (cmd_fkmap)
1701 		    beep_flush();
1702 		else
1703 #endif
1704 		ccline.overstrike = !ccline.overstrike;
1705 #ifdef CURSOR_SHAPE
1706 		ui_cursor_shape();	/* may show different cursor shape */
1707 #endif
1708 		goto cmdline_not_changed;
1709 
1710 	case Ctrl_HAT:
1711 		if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE))
1712 		{
1713 		    /* ":lmap" mappings exists, toggle use of mappings. */
1714 		    State ^= LANGMAP;
1715 #ifdef HAVE_INPUT_METHOD
1716 		    im_set_active(FALSE);	/* Disable input method */
1717 #endif
1718 		    if (b_im_ptr != NULL)
1719 		    {
1720 			if (State & LANGMAP)
1721 			    *b_im_ptr = B_IMODE_LMAP;
1722 			else
1723 			    *b_im_ptr = B_IMODE_NONE;
1724 		    }
1725 		}
1726 #ifdef HAVE_INPUT_METHOD
1727 		else
1728 		{
1729 		    /* There are no ":lmap" mappings, toggle IM.  When
1730 		     * 'imdisable' is set don't try getting the status, it's
1731 		     * always off. */
1732 		    if ((p_imdisable && b_im_ptr != NULL)
1733 			    ? *b_im_ptr == B_IMODE_IM : im_get_status())
1734 		    {
1735 			im_set_active(FALSE);	/* Disable input method */
1736 			if (b_im_ptr != NULL)
1737 			    *b_im_ptr = B_IMODE_NONE;
1738 		    }
1739 		    else
1740 		    {
1741 			im_set_active(TRUE);	/* Enable input method */
1742 			if (b_im_ptr != NULL)
1743 			    *b_im_ptr = B_IMODE_IM;
1744 		    }
1745 		}
1746 #endif
1747 		if (b_im_ptr != NULL)
1748 		{
1749 		    if (b_im_ptr == &curbuf->b_p_iminsert)
1750 			set_iminsert_global();
1751 		    else
1752 			set_imsearch_global();
1753 		}
1754 #ifdef CURSOR_SHAPE
1755 		ui_cursor_shape();	/* may show different cursor shape */
1756 #endif
1757 #if defined(FEAT_KEYMAP)
1758 		/* Show/unshow value of 'keymap' in status lines later. */
1759 		status_redraw_curbuf();
1760 #endif
1761 		goto cmdline_not_changed;
1762 
1763 /*	case '@':   only in very old vi */
1764 	case Ctrl_U:
1765 		/* delete all characters left of the cursor */
1766 		j = ccline.cmdpos;
1767 		ccline.cmdlen -= j;
1768 		i = ccline.cmdpos = 0;
1769 		while (i < ccline.cmdlen)
1770 		    ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
1771 		/* Truncate at the end, required for multi-byte chars. */
1772 		ccline.cmdbuff[ccline.cmdlen] = NUL;
1773 #ifdef FEAT_SEARCH_EXTRA
1774 		if (ccline.cmdlen == 0)
1775 		    is_state.search_start = is_state.save_cursor;
1776 #endif
1777 		redrawcmd();
1778 		goto cmdline_changed;
1779 
1780 #ifdef FEAT_CLIPBOARD
1781 	case Ctrl_Y:
1782 		/* Copy the modeless selection, if there is one. */
1783 		if (clip_star.state != SELECT_CLEARED)
1784 		{
1785 		    if (clip_star.state == SELECT_DONE)
1786 			clip_copy_modeless_selection(TRUE);
1787 		    goto cmdline_not_changed;
1788 		}
1789 		break;
1790 #endif
1791 
1792 	case ESC:	/* get here if p_wc != ESC or when ESC typed twice */
1793 	case Ctrl_C:
1794 		/* In exmode it doesn't make sense to return.  Except when
1795 		 * ":normal" runs out of characters. */
1796 		if (exmode_active
1797 			       && (ex_normal_busy == 0 || typebuf.tb_len > 0))
1798 		    goto cmdline_not_changed;
1799 
1800 		gotesc = TRUE;		/* will free ccline.cmdbuff after
1801 					   putting it in history */
1802 		goto returncmd;		/* back to cmd mode */
1803 
1804 	case Ctrl_R:			/* insert register */
1805 #ifdef USE_ON_FLY_SCROLL
1806 		dont_scroll = TRUE;	/* disallow scrolling here */
1807 #endif
1808 		putcmdline('"', TRUE);
1809 		++no_mapping;
1810 		i = c = plain_vgetc();	/* CTRL-R <char> */
1811 		if (i == Ctrl_O)
1812 		    i = Ctrl_R;		/* CTRL-R CTRL-O == CTRL-R CTRL-R */
1813 		if (i == Ctrl_R)
1814 		    c = plain_vgetc();	/* CTRL-R CTRL-R <char> */
1815 		extra_char = NUL;
1816 		--no_mapping;
1817 #ifdef FEAT_EVAL
1818 		/*
1819 		 * Insert the result of an expression.
1820 		 * Need to save the current command line, to be able to enter
1821 		 * a new one...
1822 		 */
1823 		new_cmdpos = -1;
1824 		if (c == '=')
1825 		{
1826 		    if (ccline.cmdfirstc == '='  // can't do this recursively
1827 			    || cmdline_star > 0) // or when typing a password
1828 		    {
1829 			beep_flush();
1830 			c = ESC;
1831 		    }
1832 		    else
1833 			c = get_expr_register();
1834 		}
1835 #endif
1836 		if (c != ESC)	    /* use ESC to cancel inserting register */
1837 		{
1838 		    cmdline_paste(c, i == Ctrl_R, FALSE);
1839 
1840 #ifdef FEAT_EVAL
1841 		    /* When there was a serious error abort getting the
1842 		     * command line. */
1843 		    if (aborting())
1844 		    {
1845 			gotesc = TRUE;  /* will free ccline.cmdbuff after
1846 					   putting it in history */
1847 			goto returncmd; /* back to cmd mode */
1848 		    }
1849 #endif
1850 		    KeyTyped = FALSE;	/* Don't do p_wc completion. */
1851 #ifdef FEAT_EVAL
1852 		    if (new_cmdpos >= 0)
1853 		    {
1854 			/* set_cmdline_pos() was used */
1855 			if (new_cmdpos > ccline.cmdlen)
1856 			    ccline.cmdpos = ccline.cmdlen;
1857 			else
1858 			    ccline.cmdpos = new_cmdpos;
1859 		    }
1860 #endif
1861 		}
1862 		redrawcmd();
1863 		goto cmdline_changed;
1864 
1865 	case Ctrl_D:
1866 		if (showmatches(&xpc, FALSE) == EXPAND_NOTHING)
1867 		    break;	/* Use ^D as normal char instead */
1868 
1869 		redrawcmd();
1870 		continue;	/* don't do incremental search now */
1871 
1872 	case K_RIGHT:
1873 	case K_S_RIGHT:
1874 	case K_C_RIGHT:
1875 		do
1876 		{
1877 		    if (ccline.cmdpos >= ccline.cmdlen)
1878 			break;
1879 		    i = cmdline_charsize(ccline.cmdpos);
1880 		    if (KeyTyped && ccline.cmdspos + i >= Columns * Rows)
1881 			break;
1882 		    ccline.cmdspos += i;
1883 		    if (has_mbyte)
1884 			ccline.cmdpos += (*mb_ptr2len)(ccline.cmdbuff
1885 							     + ccline.cmdpos);
1886 		    else
1887 			++ccline.cmdpos;
1888 		}
1889 		while ((c == K_S_RIGHT || c == K_C_RIGHT
1890 			       || (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)))
1891 			&& ccline.cmdbuff[ccline.cmdpos] != ' ');
1892 		if (has_mbyte)
1893 		    set_cmdspos_cursor();
1894 		goto cmdline_not_changed;
1895 
1896 	case K_LEFT:
1897 	case K_S_LEFT:
1898 	case K_C_LEFT:
1899 		if (ccline.cmdpos == 0)
1900 		    goto cmdline_not_changed;
1901 		do
1902 		{
1903 		    --ccline.cmdpos;
1904 		    if (has_mbyte)	/* move to first byte of char */
1905 			ccline.cmdpos -= (*mb_head_off)(ccline.cmdbuff,
1906 					      ccline.cmdbuff + ccline.cmdpos);
1907 		    ccline.cmdspos -= cmdline_charsize(ccline.cmdpos);
1908 		}
1909 		while (ccline.cmdpos > 0
1910 			&& (c == K_S_LEFT || c == K_C_LEFT
1911 			       || (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)))
1912 			&& ccline.cmdbuff[ccline.cmdpos - 1] != ' ');
1913 		if (has_mbyte)
1914 		    set_cmdspos_cursor();
1915 		goto cmdline_not_changed;
1916 
1917 	case K_IGNORE:
1918 		/* Ignore mouse event or open_cmdwin() result. */
1919 		goto cmdline_not_changed;
1920 
1921 #ifdef FEAT_GUI_W32
1922 	    /* On Win32 ignore <M-F4>, we get it when closing the window was
1923 	     * cancelled. */
1924 	case K_F4:
1925 	    if (mod_mask == MOD_MASK_ALT)
1926 	    {
1927 		redrawcmd();	    /* somehow the cmdline is cleared */
1928 		goto cmdline_not_changed;
1929 	    }
1930 	    break;
1931 #endif
1932 
1933 #ifdef FEAT_MOUSE
1934 	case K_MIDDLEDRAG:
1935 	case K_MIDDLERELEASE:
1936 		goto cmdline_not_changed;	/* Ignore mouse */
1937 
1938 	case K_MIDDLEMOUSE:
1939 # ifdef FEAT_GUI
1940 		/* When GUI is active, also paste when 'mouse' is empty */
1941 		if (!gui.in_use)
1942 # endif
1943 		    if (!mouse_has(MOUSE_COMMAND))
1944 			goto cmdline_not_changed;   /* Ignore mouse */
1945 # ifdef FEAT_CLIPBOARD
1946 		if (clip_star.available)
1947 		    cmdline_paste('*', TRUE, TRUE);
1948 		else
1949 # endif
1950 		    cmdline_paste(0, TRUE, TRUE);
1951 		redrawcmd();
1952 		goto cmdline_changed;
1953 
1954 # ifdef FEAT_DND
1955 	case K_DROP:
1956 		cmdline_paste('~', TRUE, FALSE);
1957 		redrawcmd();
1958 		goto cmdline_changed;
1959 # endif
1960 
1961 	case K_LEFTDRAG:
1962 	case K_LEFTRELEASE:
1963 	case K_RIGHTDRAG:
1964 	case K_RIGHTRELEASE:
1965 		/* Ignore drag and release events when the button-down wasn't
1966 		 * seen before. */
1967 		if (ignore_drag_release)
1968 		    goto cmdline_not_changed;
1969 		/* FALLTHROUGH */
1970 	case K_LEFTMOUSE:
1971 	case K_RIGHTMOUSE:
1972 		if (c == K_LEFTRELEASE || c == K_RIGHTRELEASE)
1973 		    ignore_drag_release = TRUE;
1974 		else
1975 		    ignore_drag_release = FALSE;
1976 # ifdef FEAT_GUI
1977 		/* When GUI is active, also move when 'mouse' is empty */
1978 		if (!gui.in_use)
1979 # endif
1980 		    if (!mouse_has(MOUSE_COMMAND))
1981 			goto cmdline_not_changed;   /* Ignore mouse */
1982 # ifdef FEAT_CLIPBOARD
1983 		if (mouse_row < cmdline_row && clip_star.available)
1984 		{
1985 		    int	    button, is_click, is_drag;
1986 
1987 		    /*
1988 		     * Handle modeless selection.
1989 		     */
1990 		    button = get_mouse_button(KEY2TERMCAP1(c),
1991 							 &is_click, &is_drag);
1992 		    if (mouse_model_popup() && button == MOUSE_LEFT
1993 					       && (mod_mask & MOD_MASK_SHIFT))
1994 		    {
1995 			/* Translate shift-left to right button. */
1996 			button = MOUSE_RIGHT;
1997 			mod_mask &= ~MOD_MASK_SHIFT;
1998 		    }
1999 		    clip_modeless(button, is_click, is_drag);
2000 		    goto cmdline_not_changed;
2001 		}
2002 # endif
2003 
2004 		set_cmdspos();
2005 		for (ccline.cmdpos = 0; ccline.cmdpos < ccline.cmdlen;
2006 							      ++ccline.cmdpos)
2007 		{
2008 		    i = cmdline_charsize(ccline.cmdpos);
2009 		    if (mouse_row <= cmdline_row + ccline.cmdspos / Columns
2010 				  && mouse_col < ccline.cmdspos % Columns + i)
2011 			break;
2012 		    if (has_mbyte)
2013 		    {
2014 			/* Count ">" for double-wide char that doesn't fit. */
2015 			correct_cmdspos(ccline.cmdpos, i);
2016 			ccline.cmdpos += (*mb_ptr2len)(ccline.cmdbuff
2017 							 + ccline.cmdpos) - 1;
2018 		    }
2019 		    ccline.cmdspos += i;
2020 		}
2021 		goto cmdline_not_changed;
2022 
2023 	/* Mouse scroll wheel: ignored here */
2024 	case K_MOUSEDOWN:
2025 	case K_MOUSEUP:
2026 	case K_MOUSELEFT:
2027 	case K_MOUSERIGHT:
2028 	/* Alternate buttons ignored here */
2029 	case K_X1MOUSE:
2030 	case K_X1DRAG:
2031 	case K_X1RELEASE:
2032 	case K_X2MOUSE:
2033 	case K_X2DRAG:
2034 	case K_X2RELEASE:
2035 	case K_MOUSEMOVE:
2036 		goto cmdline_not_changed;
2037 
2038 #endif	/* FEAT_MOUSE */
2039 
2040 #ifdef FEAT_GUI
2041 	case K_LEFTMOUSE_NM:	/* mousefocus click, ignored */
2042 	case K_LEFTRELEASE_NM:
2043 		goto cmdline_not_changed;
2044 
2045 	case K_VER_SCROLLBAR:
2046 		if (msg_scrolled == 0)
2047 		{
2048 		    gui_do_scroll();
2049 		    redrawcmd();
2050 		}
2051 		goto cmdline_not_changed;
2052 
2053 	case K_HOR_SCROLLBAR:
2054 		if (msg_scrolled == 0)
2055 		{
2056 		    gui_do_horiz_scroll(scrollbar_value, FALSE);
2057 		    redrawcmd();
2058 		}
2059 		goto cmdline_not_changed;
2060 #endif
2061 #ifdef FEAT_GUI_TABLINE
2062 	case K_TABLINE:
2063 	case K_TABMENU:
2064 		/* Don't want to change any tabs here.  Make sure the same tab
2065 		 * is still selected. */
2066 		if (gui_use_tabline())
2067 		    gui_mch_set_curtab(tabpage_index(curtab));
2068 		goto cmdline_not_changed;
2069 #endif
2070 
2071 	case K_SELECT:	    /* end of Select mode mapping - ignore */
2072 		goto cmdline_not_changed;
2073 
2074 	case Ctrl_B:	    /* begin of command line */
2075 	case K_HOME:
2076 	case K_KHOME:
2077 	case K_S_HOME:
2078 	case K_C_HOME:
2079 		ccline.cmdpos = 0;
2080 		set_cmdspos();
2081 		goto cmdline_not_changed;
2082 
2083 	case Ctrl_E:	    /* end of command line */
2084 	case K_END:
2085 	case K_KEND:
2086 	case K_S_END:
2087 	case K_C_END:
2088 		ccline.cmdpos = ccline.cmdlen;
2089 		set_cmdspos_cursor();
2090 		goto cmdline_not_changed;
2091 
2092 	case Ctrl_A:	    /* all matches */
2093 		if (nextwild(&xpc, WILD_ALL, 0, firstc != '@') == FAIL)
2094 		    break;
2095 		goto cmdline_changed;
2096 
2097 	case Ctrl_L:
2098 #ifdef FEAT_SEARCH_EXTRA
2099 		if (may_add_char_to_search(firstc, &c, &is_state) == OK)
2100 		    goto cmdline_not_changed;
2101 #endif
2102 
2103 		/* completion: longest common part */
2104 		if (nextwild(&xpc, WILD_LONGEST, 0, firstc != '@') == FAIL)
2105 		    break;
2106 		goto cmdline_changed;
2107 
2108 	case Ctrl_N:	    /* next match */
2109 	case Ctrl_P:	    /* previous match */
2110 		if (xpc.xp_numfiles > 0)
2111 		{
2112 		    if (nextwild(&xpc, (c == Ctrl_P) ? WILD_PREV : WILD_NEXT,
2113 						    0, firstc != '@') == FAIL)
2114 			break;
2115 		    goto cmdline_not_changed;
2116 		}
2117 #ifdef FEAT_CMDHIST
2118 		/* FALLTHROUGH */
2119 	case K_UP:
2120 	case K_DOWN:
2121 	case K_S_UP:
2122 	case K_S_DOWN:
2123 	case K_PAGEUP:
2124 	case K_KPAGEUP:
2125 	case K_PAGEDOWN:
2126 	case K_KPAGEDOWN:
2127 		if (hislen == 0 || firstc == NUL)	/* no history */
2128 		    goto cmdline_not_changed;
2129 
2130 		i = hiscnt;
2131 
2132 		/* save current command string so it can be restored later */
2133 		if (lookfor == NULL)
2134 		{
2135 		    if ((lookfor = vim_strsave(ccline.cmdbuff)) == NULL)
2136 			goto cmdline_not_changed;
2137 		    lookfor[ccline.cmdpos] = NUL;
2138 		}
2139 
2140 		j = (int)STRLEN(lookfor);
2141 		for (;;)
2142 		{
2143 		    /* one step backwards */
2144 		    if (c == K_UP|| c == K_S_UP || c == Ctrl_P
2145 			    || c == K_PAGEUP || c == K_KPAGEUP)
2146 		    {
2147 			if (hiscnt == hislen)	/* first time */
2148 			    hiscnt = hisidx[histype];
2149 			else if (hiscnt == 0 && hisidx[histype] != hislen - 1)
2150 			    hiscnt = hislen - 1;
2151 			else if (hiscnt != hisidx[histype] + 1)
2152 			    --hiscnt;
2153 			else			/* at top of list */
2154 			{
2155 			    hiscnt = i;
2156 			    break;
2157 			}
2158 		    }
2159 		    else    /* one step forwards */
2160 		    {
2161 			/* on last entry, clear the line */
2162 			if (hiscnt == hisidx[histype])
2163 			{
2164 			    hiscnt = hislen;
2165 			    break;
2166 			}
2167 
2168 			/* not on a history line, nothing to do */
2169 			if (hiscnt == hislen)
2170 			    break;
2171 			if (hiscnt == hislen - 1)   /* wrap around */
2172 			    hiscnt = 0;
2173 			else
2174 			    ++hiscnt;
2175 		    }
2176 		    if (hiscnt < 0 || history[histype][hiscnt].hisstr == NULL)
2177 		    {
2178 			hiscnt = i;
2179 			break;
2180 		    }
2181 		    if ((c != K_UP && c != K_DOWN)
2182 			    || hiscnt == i
2183 			    || STRNCMP(history[histype][hiscnt].hisstr,
2184 						    lookfor, (size_t)j) == 0)
2185 			break;
2186 		}
2187 
2188 		if (hiscnt != i)	/* jumped to other entry */
2189 		{
2190 		    char_u	*p;
2191 		    int		len;
2192 		    int		old_firstc;
2193 
2194 		    VIM_CLEAR(ccline.cmdbuff);
2195 		    xpc.xp_context = EXPAND_NOTHING;
2196 		    if (hiscnt == hislen)
2197 			p = lookfor;	/* back to the old one */
2198 		    else
2199 			p = history[histype][hiscnt].hisstr;
2200 
2201 		    if (histype == HIST_SEARCH
2202 			    && p != lookfor
2203 			    && (old_firstc = p[STRLEN(p) + 1]) != firstc)
2204 		    {
2205 			/* Correct for the separator character used when
2206 			 * adding the history entry vs the one used now.
2207 			 * First loop: count length.
2208 			 * Second loop: copy the characters. */
2209 			for (i = 0; i <= 1; ++i)
2210 			{
2211 			    len = 0;
2212 			    for (j = 0; p[j] != NUL; ++j)
2213 			    {
2214 				/* Replace old sep with new sep, unless it is
2215 				 * escaped. */
2216 				if (p[j] == old_firstc
2217 					      && (j == 0 || p[j - 1] != '\\'))
2218 				{
2219 				    if (i > 0)
2220 					ccline.cmdbuff[len] = firstc;
2221 				}
2222 				else
2223 				{
2224 				    /* Escape new sep, unless it is already
2225 				     * escaped. */
2226 				    if (p[j] == firstc
2227 					      && (j == 0 || p[j - 1] != '\\'))
2228 				    {
2229 					if (i > 0)
2230 					    ccline.cmdbuff[len] = '\\';
2231 					++len;
2232 				    }
2233 				    if (i > 0)
2234 					ccline.cmdbuff[len] = p[j];
2235 				}
2236 				++len;
2237 			    }
2238 			    if (i == 0)
2239 			    {
2240 				alloc_cmdbuff(len);
2241 				if (ccline.cmdbuff == NULL)
2242 				    goto returncmd;
2243 			    }
2244 			}
2245 			ccline.cmdbuff[len] = NUL;
2246 		    }
2247 		    else
2248 		    {
2249 			alloc_cmdbuff((int)STRLEN(p));
2250 			if (ccline.cmdbuff == NULL)
2251 			    goto returncmd;
2252 			STRCPY(ccline.cmdbuff, p);
2253 		    }
2254 
2255 		    ccline.cmdpos = ccline.cmdlen = (int)STRLEN(ccline.cmdbuff);
2256 		    redrawcmd();
2257 		    goto cmdline_changed;
2258 		}
2259 		beep_flush();
2260 #endif
2261 		goto cmdline_not_changed;
2262 
2263 #ifdef FEAT_SEARCH_EXTRA
2264 	case Ctrl_G:	    /* next match */
2265 	case Ctrl_T:	    /* previous match */
2266 		if (may_adjust_incsearch_highlighting(
2267 					  firstc, count, &is_state, c) == FAIL)
2268 		    goto cmdline_not_changed;
2269 		break;
2270 #endif
2271 
2272 	case Ctrl_V:
2273 	case Ctrl_Q:
2274 #ifdef FEAT_MOUSE
2275 		ignore_drag_release = TRUE;
2276 #endif
2277 		putcmdline('^', TRUE);
2278 		c = get_literal();	    /* get next (two) character(s) */
2279 		do_abbr = FALSE;	    /* don't do abbreviation now */
2280 		extra_char = NUL;
2281 		/* may need to remove ^ when composing char was typed */
2282 		if (enc_utf8 && utf_iscomposing(c) && !cmd_silent)
2283 		{
2284 		    draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
2285 		    msg_putchar(' ');
2286 		    cursorcmd();
2287 		}
2288 		break;
2289 
2290 #ifdef FEAT_DIGRAPHS
2291 	case Ctrl_K:
2292 #ifdef FEAT_MOUSE
2293 		ignore_drag_release = TRUE;
2294 #endif
2295 		putcmdline('?', TRUE);
2296 #ifdef USE_ON_FLY_SCROLL
2297 		dont_scroll = TRUE;	    /* disallow scrolling here */
2298 #endif
2299 		c = get_digraph(TRUE);
2300 		extra_char = NUL;
2301 		if (c != NUL)
2302 		    break;
2303 
2304 		redrawcmd();
2305 		goto cmdline_not_changed;
2306 #endif /* FEAT_DIGRAPHS */
2307 
2308 #ifdef FEAT_RIGHTLEFT
2309 	case Ctrl__:	    /* CTRL-_: switch language mode */
2310 		if (!p_ari)
2311 		    break;
2312 # ifdef FEAT_FKMAP
2313 		if (p_altkeymap)
2314 		{
2315 		    cmd_fkmap = !cmd_fkmap;
2316 		    if (cmd_fkmap)	/* in Farsi always in Insert mode */
2317 			ccline.overstrike = FALSE;
2318 		}
2319 		else			    /* Hebrew is default */
2320 # endif
2321 		    cmd_hkmap = !cmd_hkmap;
2322 		goto cmdline_not_changed;
2323 #endif
2324 
2325 	case K_PS:
2326 		bracketed_paste(PASTE_CMDLINE, FALSE, NULL);
2327 		goto cmdline_changed;
2328 
2329 	default:
2330 #ifdef UNIX
2331 		if (c == intr_char)
2332 		{
2333 		    gotesc = TRUE;	/* will free ccline.cmdbuff after
2334 					   putting it in history */
2335 		    goto returncmd;	/* back to Normal mode */
2336 		}
2337 #endif
2338 		/*
2339 		 * Normal character with no special meaning.  Just set mod_mask
2340 		 * to 0x0 so that typing Shift-Space in the GUI doesn't enter
2341 		 * the string <S-Space>.  This should only happen after ^V.
2342 		 */
2343 		if (!IS_SPECIAL(c))
2344 		    mod_mask = 0x0;
2345 		break;
2346 	}
2347 	/*
2348 	 * End of switch on command line character.
2349 	 * We come here if we have a normal character.
2350 	 */
2351 
2352 	if (do_abbr && (IS_SPECIAL(c) || !vim_iswordc(c))
2353 		&& (ccheck_abbr(
2354 			// Add ABBR_OFF for characters above 0x100, this is
2355 			// what check_abbr() expects.
2356 				(has_mbyte && c >= 0x100) ? (c + ABBR_OFF) : c)
2357 		    || c == Ctrl_RSB))
2358 	    goto cmdline_changed;
2359 
2360 	/*
2361 	 * put the character in the command line
2362 	 */
2363 	if (IS_SPECIAL(c) || mod_mask != 0)
2364 	    put_on_cmdline(get_special_key_name(c, mod_mask), -1, TRUE);
2365 	else
2366 	{
2367 	    if (has_mbyte)
2368 	    {
2369 		j = (*mb_char2bytes)(c, IObuff);
2370 		IObuff[j] = NUL;	/* exclude composing chars */
2371 		put_on_cmdline(IObuff, j, TRUE);
2372 	    }
2373 	    else
2374 	    {
2375 		IObuff[0] = c;
2376 		put_on_cmdline(IObuff, 1, TRUE);
2377 	    }
2378 	}
2379 	goto cmdline_changed;
2380 
2381 /*
2382  * This part implements incremental searches for "/" and "?"
2383  * Jump to cmdline_not_changed when a character has been read but the command
2384  * line did not change. Then we only search and redraw if something changed in
2385  * the past.
2386  * Jump to cmdline_changed when the command line did change.
2387  * (Sorry for the goto's, I know it is ugly).
2388  */
2389 cmdline_not_changed:
2390 #ifdef FEAT_SEARCH_EXTRA
2391 	if (!is_state.incsearch_postponed)
2392 	    continue;
2393 #endif
2394 
2395 cmdline_changed:
2396 	/* Trigger CmdlineChanged autocommands. */
2397 	trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINECHANGED);
2398 
2399 #ifdef FEAT_SEARCH_EXTRA
2400 	may_do_incsearch_highlighting(firstc, count, &is_state);
2401 #endif
2402 
2403 #ifdef FEAT_RIGHTLEFT
2404 	if (cmdmsg_rl
2405 # ifdef FEAT_ARABIC
2406 		|| (p_arshape && !p_tbidi && enc_utf8)
2407 # endif
2408 		)
2409 	    /* Always redraw the whole command line to fix shaping and
2410 	     * right-left typing.  Not efficient, but it works.
2411 	     * Do it only when there are no characters left to read
2412 	     * to avoid useless intermediate redraws. */
2413 	    if (vpeekc() == NUL)
2414 		redrawcmd();
2415 #endif
2416     }
2417 
2418 returncmd:
2419 
2420 #ifdef FEAT_RIGHTLEFT
2421     cmdmsg_rl = FALSE;
2422 #endif
2423 
2424 #ifdef FEAT_FKMAP
2425     cmd_fkmap = 0;
2426 #endif
2427 
2428     ExpandCleanup(&xpc);
2429     ccline.xpc = NULL;
2430 
2431 #ifdef FEAT_SEARCH_EXTRA
2432     finish_incsearch_highlighting(gotesc, &is_state, FALSE);
2433 #endif
2434 
2435     if (ccline.cmdbuff != NULL)
2436     {
2437 	/*
2438 	 * Put line in history buffer (":" and "=" only when it was typed).
2439 	 */
2440 #ifdef FEAT_CMDHIST
2441 	if (ccline.cmdlen && firstc != NUL
2442 		&& (some_key_typed || histype == HIST_SEARCH))
2443 	{
2444 	    add_to_history(histype, ccline.cmdbuff, TRUE,
2445 				       histype == HIST_SEARCH ? firstc : NUL);
2446 	    if (firstc == ':')
2447 	    {
2448 		vim_free(new_last_cmdline);
2449 		new_last_cmdline = vim_strsave(ccline.cmdbuff);
2450 	    }
2451 	}
2452 #endif
2453 
2454 	if (gotesc)
2455 	    abandon_cmdline();
2456     }
2457 
2458     /*
2459      * If the screen was shifted up, redraw the whole screen (later).
2460      * If the line is too long, clear it, so ruler and shown command do
2461      * not get printed in the middle of it.
2462      */
2463     msg_check();
2464     msg_scroll = save_msg_scroll;
2465     redir_off = FALSE;
2466 
2467     /* When the command line was typed, no need for a wait-return prompt. */
2468     if (some_key_typed)
2469 	need_wait_return = FALSE;
2470 
2471     /* Trigger CmdlineLeave autocommands. */
2472     trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINELEAVE);
2473 
2474     State = save_State;
2475 #ifdef HAVE_INPUT_METHOD
2476     if (b_im_ptr != NULL && *b_im_ptr != B_IMODE_LMAP)
2477 	im_save_status(b_im_ptr);
2478     im_set_active(FALSE);
2479 #endif
2480 #ifdef FEAT_MOUSE
2481     setmouse();
2482 #endif
2483 #ifdef CURSOR_SHAPE
2484     ui_cursor_shape();		/* may show different cursor shape */
2485 #endif
2486     sb_text_end_cmdline();
2487 
2488 theend:
2489     {
2490 	char_u *p = ccline.cmdbuff;
2491 
2492 	if (did_save_ccline)
2493 	    restore_cmdline(&save_ccline);
2494 	else
2495 	    ccline.cmdbuff = NULL;
2496 	return p;
2497     }
2498 }
2499 
2500 #if (defined(FEAT_CRYPT) || defined(FEAT_EVAL)) || defined(PROTO)
2501 /*
2502  * Get a command line with a prompt.
2503  * This is prepared to be called recursively from getcmdline() (e.g. by
2504  * f_input() when evaluating an expression from CTRL-R =).
2505  * Returns the command line in allocated memory, or NULL.
2506  */
2507     char_u *
2508 getcmdline_prompt(
2509     int		firstc,
2510     char_u	*prompt,	/* command line prompt */
2511     int		attr,		/* attributes for prompt */
2512     int		xp_context,	/* type of expansion */
2513     char_u	*xp_arg)	/* user-defined expansion argument */
2514 {
2515     char_u		*s;
2516     struct cmdline_info	save_ccline;
2517     int			did_save_ccline = FALSE;
2518     int			msg_col_save = msg_col;
2519     int			msg_silent_save = msg_silent;
2520 
2521     if (ccline.cmdbuff != NULL)
2522     {
2523 	// Save the values of the current cmdline and restore them below.
2524 	save_cmdline(&save_ccline);
2525 	did_save_ccline = TRUE;
2526     }
2527 
2528     vim_memset(&ccline, 0, sizeof(struct cmdline_info));
2529     ccline.cmdprompt = prompt;
2530     ccline.cmdattr = attr;
2531 # ifdef FEAT_EVAL
2532     ccline.xp_context = xp_context;
2533     ccline.xp_arg = xp_arg;
2534     ccline.input_fn = (firstc == '@');
2535 # endif
2536     msg_silent = 0;
2537     s = getcmdline_int(firstc, 1L, 0, FALSE);
2538 
2539     if (did_save_ccline)
2540 	restore_cmdline(&save_ccline);
2541 
2542     msg_silent = msg_silent_save;
2543     /* Restore msg_col, the prompt from input() may have changed it.
2544      * But only if called recursively and the commandline is therefore being
2545      * restored to an old one; if not, the input() prompt stays on the screen,
2546      * so we need its modified msg_col left intact. */
2547     if (ccline.cmdbuff != NULL)
2548 	msg_col = msg_col_save;
2549 
2550     return s;
2551 }
2552 #endif
2553 
2554 /*
2555  * Return TRUE when the text must not be changed and we can't switch to
2556  * another window or buffer.  Used when editing the command line, evaluating
2557  * 'balloonexpr', etc.
2558  */
2559     int
2560 text_locked(void)
2561 {
2562 #ifdef FEAT_CMDWIN
2563     if (cmdwin_type != 0)
2564 	return TRUE;
2565 #endif
2566     return textlock != 0;
2567 }
2568 
2569 /*
2570  * Give an error message for a command that isn't allowed while the cmdline
2571  * window is open or editing the cmdline in another way.
2572  */
2573     void
2574 text_locked_msg(void)
2575 {
2576     emsg(_(get_text_locked_msg()));
2577 }
2578 
2579     char *
2580 get_text_locked_msg(void)
2581 {
2582 #ifdef FEAT_CMDWIN
2583     if (cmdwin_type != 0)
2584 	return e_cmdwin;
2585 #endif
2586     return e_secure;
2587 }
2588 
2589 /*
2590  * Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is
2591  * and give an error message.
2592  */
2593     int
2594 curbuf_locked(void)
2595 {
2596     if (curbuf_lock > 0)
2597     {
2598 	emsg(_("E788: Not allowed to edit another buffer now"));
2599 	return TRUE;
2600     }
2601     return allbuf_locked();
2602 }
2603 
2604 /*
2605  * Check if "allbuf_lock" is set and return TRUE when it is and give an error
2606  * message.
2607  */
2608     int
2609 allbuf_locked(void)
2610 {
2611     if (allbuf_lock > 0)
2612     {
2613 	emsg(_("E811: Not allowed to change buffer information now"));
2614 	return TRUE;
2615     }
2616     return FALSE;
2617 }
2618 
2619     static int
2620 cmdline_charsize(int idx)
2621 {
2622 #if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
2623     if (cmdline_star > 0)	    /* showing '*', always 1 position */
2624 	return 1;
2625 #endif
2626     return ptr2cells(ccline.cmdbuff + idx);
2627 }
2628 
2629 /*
2630  * Compute the offset of the cursor on the command line for the prompt and
2631  * indent.
2632  */
2633     static void
2634 set_cmdspos(void)
2635 {
2636     if (ccline.cmdfirstc != NUL)
2637 	ccline.cmdspos = 1 + ccline.cmdindent;
2638     else
2639 	ccline.cmdspos = 0 + ccline.cmdindent;
2640 }
2641 
2642 /*
2643  * Compute the screen position for the cursor on the command line.
2644  */
2645     static void
2646 set_cmdspos_cursor(void)
2647 {
2648     int		i, m, c;
2649 
2650     set_cmdspos();
2651     if (KeyTyped)
2652     {
2653 	m = Columns * Rows;
2654 	if (m < 0)	/* overflow, Columns or Rows at weird value */
2655 	    m = MAXCOL;
2656     }
2657     else
2658 	m = MAXCOL;
2659     for (i = 0; i < ccline.cmdlen && i < ccline.cmdpos; ++i)
2660     {
2661 	c = cmdline_charsize(i);
2662 	/* Count ">" for double-wide multi-byte char that doesn't fit. */
2663 	if (has_mbyte)
2664 	    correct_cmdspos(i, c);
2665 	/* If the cmdline doesn't fit, show cursor on last visible char.
2666 	 * Don't move the cursor itself, so we can still append. */
2667 	if ((ccline.cmdspos += c) >= m)
2668 	{
2669 	    ccline.cmdspos -= c;
2670 	    break;
2671 	}
2672 	if (has_mbyte)
2673 	    i += (*mb_ptr2len)(ccline.cmdbuff + i) - 1;
2674     }
2675 }
2676 
2677 /*
2678  * Check if the character at "idx", which is "cells" wide, is a multi-byte
2679  * character that doesn't fit, so that a ">" must be displayed.
2680  */
2681     static void
2682 correct_cmdspos(int idx, int cells)
2683 {
2684     if ((*mb_ptr2len)(ccline.cmdbuff + idx) > 1
2685 		&& (*mb_ptr2cells)(ccline.cmdbuff + idx) > 1
2686 		&& ccline.cmdspos % Columns + cells > Columns)
2687 	ccline.cmdspos++;
2688 }
2689 
2690 /*
2691  * Get an Ex command line for the ":" command.
2692  */
2693     char_u *
2694 getexline(
2695     int		c,		/* normally ':', NUL for ":append" */
2696     void	*cookie UNUSED,
2697     int		indent)		/* indent for inside conditionals */
2698 {
2699     /* When executing a register, remove ':' that's in front of each line. */
2700     if (exec_from_reg && vpeekc() == ':')
2701 	(void)vgetc();
2702     return getcmdline(c, 1L, indent);
2703 }
2704 
2705 /*
2706  * Get an Ex command line for Ex mode.
2707  * In Ex mode we only use the OS supplied line editing features and no
2708  * mappings or abbreviations.
2709  * Returns a string in allocated memory or NULL.
2710  */
2711     char_u *
2712 getexmodeline(
2713     int		promptc,	/* normally ':', NUL for ":append" and '?' for
2714 				   :s prompt */
2715     void	*cookie UNUSED,
2716     int		indent)		/* indent for inside conditionals */
2717 {
2718     garray_T	line_ga;
2719     char_u	*pend;
2720     int		startcol = 0;
2721     int		c1 = 0;
2722     int		escaped = FALSE;	/* CTRL-V typed */
2723     int		vcol = 0;
2724     char_u	*p;
2725     int		prev_char;
2726     int		len;
2727 
2728     /* Switch cursor on now.  This avoids that it happens after the "\n", which
2729      * confuses the system function that computes tabstops. */
2730     cursor_on();
2731 
2732     /* always start in column 0; write a newline if necessary */
2733     compute_cmdrow();
2734     if ((msg_col || msg_didout) && promptc != '?')
2735 	msg_putchar('\n');
2736     if (promptc == ':')
2737     {
2738 	/* indent that is only displayed, not in the line itself */
2739 	if (p_prompt)
2740 	    msg_putchar(':');
2741 	while (indent-- > 0)
2742 	    msg_putchar(' ');
2743 	startcol = msg_col;
2744     }
2745 
2746     ga_init2(&line_ga, 1, 30);
2747 
2748     /* autoindent for :insert and :append is in the line itself */
2749     if (promptc <= 0)
2750     {
2751 	vcol = indent;
2752 	while (indent >= 8)
2753 	{
2754 	    ga_append(&line_ga, TAB);
2755 	    msg_puts("        ");
2756 	    indent -= 8;
2757 	}
2758 	while (indent-- > 0)
2759 	{
2760 	    ga_append(&line_ga, ' ');
2761 	    msg_putchar(' ');
2762 	}
2763     }
2764     ++no_mapping;
2765     ++allow_keys;
2766 
2767     /*
2768      * Get the line, one character at a time.
2769      */
2770     got_int = FALSE;
2771     while (!got_int)
2772     {
2773 	long    sw;
2774 	char_u *s;
2775 
2776 	if (ga_grow(&line_ga, 40) == FAIL)
2777 	    break;
2778 
2779 	/*
2780 	 * Get one character at a time.
2781 	 */
2782 	prev_char = c1;
2783 
2784 	/* Check for a ":normal" command and no more characters left. */
2785 	if (ex_normal_busy > 0 && typebuf.tb_len == 0)
2786 	    c1 = '\n';
2787 	else
2788 	    c1 = vgetc();
2789 
2790 	/*
2791 	 * Handle line editing.
2792 	 * Previously this was left to the system, putting the terminal in
2793 	 * cooked mode, but then CTRL-D and CTRL-T can't be used properly.
2794 	 */
2795 	if (got_int)
2796 	{
2797 	    msg_putchar('\n');
2798 	    break;
2799 	}
2800 
2801 	if (c1 == K_PS)
2802 	{
2803 	    bracketed_paste(PASTE_EX, FALSE, &line_ga);
2804 	    goto redraw;
2805 	}
2806 
2807 	if (!escaped)
2808 	{
2809 	    /* CR typed means "enter", which is NL */
2810 	    if (c1 == '\r')
2811 		c1 = '\n';
2812 
2813 	    if (c1 == BS || c1 == K_BS
2814 			  || c1 == DEL || c1 == K_DEL || c1 == K_KDEL)
2815 	    {
2816 		if (line_ga.ga_len > 0)
2817 		{
2818 		    if (has_mbyte)
2819 		    {
2820 			p = (char_u *)line_ga.ga_data;
2821 			p[line_ga.ga_len] = NUL;
2822 			len = (*mb_head_off)(p, p + line_ga.ga_len - 1) + 1;
2823 			line_ga.ga_len -= len;
2824 		    }
2825 		    else
2826 			--line_ga.ga_len;
2827 		    goto redraw;
2828 		}
2829 		continue;
2830 	    }
2831 
2832 	    if (c1 == Ctrl_U)
2833 	    {
2834 		msg_col = startcol;
2835 		msg_clr_eos();
2836 		line_ga.ga_len = 0;
2837 		goto redraw;
2838 	    }
2839 
2840 	    if (c1 == Ctrl_T)
2841 	    {
2842 		sw = get_sw_value(curbuf);
2843 		p = (char_u *)line_ga.ga_data;
2844 		p[line_ga.ga_len] = NUL;
2845 		indent = get_indent_str(p, 8, FALSE);
2846 		indent += sw - indent % sw;
2847 add_indent:
2848 		while (get_indent_str(p, 8, FALSE) < indent)
2849 		{
2850 		    (void)ga_grow(&line_ga, 2);  /* one more for the NUL */
2851 		    p = (char_u *)line_ga.ga_data;
2852 		    s = skipwhite(p);
2853 		    mch_memmove(s + 1, s, line_ga.ga_len - (s - p) + 1);
2854 		    *s = ' ';
2855 		    ++line_ga.ga_len;
2856 		}
2857 redraw:
2858 		/* redraw the line */
2859 		msg_col = startcol;
2860 		vcol = 0;
2861 		p = (char_u *)line_ga.ga_data;
2862 		p[line_ga.ga_len] = NUL;
2863 		while (p < (char_u *)line_ga.ga_data + line_ga.ga_len)
2864 		{
2865 		    if (*p == TAB)
2866 		    {
2867 			do
2868 			{
2869 			    msg_putchar(' ');
2870 			} while (++vcol % 8);
2871 			++p;
2872 		    }
2873 		    else
2874 		    {
2875 			len = MB_PTR2LEN(p);
2876 			msg_outtrans_len(p, len);
2877 			vcol += ptr2cells(p);
2878 			p += len;
2879 		    }
2880 		}
2881 		msg_clr_eos();
2882 		windgoto(msg_row, msg_col);
2883 		continue;
2884 	    }
2885 
2886 	    if (c1 == Ctrl_D)
2887 	    {
2888 		/* Delete one shiftwidth. */
2889 		p = (char_u *)line_ga.ga_data;
2890 		if (prev_char == '0' || prev_char == '^')
2891 		{
2892 		    if (prev_char == '^')
2893 			ex_keep_indent = TRUE;
2894 		    indent = 0;
2895 		    p[--line_ga.ga_len] = NUL;
2896 		}
2897 		else
2898 		{
2899 		    p[line_ga.ga_len] = NUL;
2900 		    indent = get_indent_str(p, 8, FALSE);
2901 		    if (indent > 0)
2902 		    {
2903 			--indent;
2904 			indent -= indent % get_sw_value(curbuf);
2905 		    }
2906 		}
2907 		while (get_indent_str(p, 8, FALSE) > indent)
2908 		{
2909 		    s = skipwhite(p);
2910 		    mch_memmove(s - 1, s, line_ga.ga_len - (s - p) + 1);
2911 		    --line_ga.ga_len;
2912 		}
2913 		goto add_indent;
2914 	    }
2915 
2916 	    if (c1 == Ctrl_V || c1 == Ctrl_Q)
2917 	    {
2918 		escaped = TRUE;
2919 		continue;
2920 	    }
2921 
2922 	    /* Ignore special key codes: mouse movement, K_IGNORE, etc. */
2923 	    if (IS_SPECIAL(c1))
2924 		continue;
2925 	}
2926 
2927 	if (IS_SPECIAL(c1))
2928 	    c1 = '?';
2929 	if (has_mbyte)
2930 	    len = (*mb_char2bytes)(c1,
2931 				  (char_u *)line_ga.ga_data + line_ga.ga_len);
2932 	else
2933 	{
2934 	    len = 1;
2935 	    ((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
2936 	}
2937 	if (c1 == '\n')
2938 	    msg_putchar('\n');
2939 	else if (c1 == TAB)
2940 	{
2941 	    /* Don't use chartabsize(), 'ts' can be different */
2942 	    do
2943 	    {
2944 		msg_putchar(' ');
2945 	    } while (++vcol % 8);
2946 	}
2947 	else
2948 	{
2949 	    msg_outtrans_len(
2950 		     ((char_u *)line_ga.ga_data) + line_ga.ga_len, len);
2951 	    vcol += char2cells(c1);
2952 	}
2953 	line_ga.ga_len += len;
2954 	escaped = FALSE;
2955 
2956 	windgoto(msg_row, msg_col);
2957 	pend = (char_u *)(line_ga.ga_data) + line_ga.ga_len;
2958 
2959 	/* We are done when a NL is entered, but not when it comes after an
2960 	 * odd number of backslashes, that results in a NUL. */
2961 	if (line_ga.ga_len > 0 && pend[-1] == '\n')
2962 	{
2963 	    int bcount = 0;
2964 
2965 	    while (line_ga.ga_len - 2 >= bcount && pend[-2 - bcount] == '\\')
2966 		++bcount;
2967 
2968 	    if (bcount > 0)
2969 	    {
2970 		/* Halve the number of backslashes: "\NL" -> "NUL", "\\NL" ->
2971 		 * "\NL", etc. */
2972 		line_ga.ga_len -= (bcount + 1) / 2;
2973 		pend -= (bcount + 1) / 2;
2974 		pend[-1] = '\n';
2975 	    }
2976 
2977 	    if ((bcount & 1) == 0)
2978 	    {
2979 		--line_ga.ga_len;
2980 		--pend;
2981 		*pend = NUL;
2982 		break;
2983 	    }
2984 	}
2985     }
2986 
2987     --no_mapping;
2988     --allow_keys;
2989 
2990     /* make following messages go to the next line */
2991     msg_didout = FALSE;
2992     msg_col = 0;
2993     if (msg_row < Rows - 1)
2994 	++msg_row;
2995     emsg_on_display = FALSE;		/* don't want ui_delay() */
2996 
2997     if (got_int)
2998 	ga_clear(&line_ga);
2999 
3000     return (char_u *)line_ga.ga_data;
3001 }
3002 
3003 # if defined(MCH_CURSOR_SHAPE) || defined(FEAT_GUI) \
3004 	|| defined(FEAT_MOUSESHAPE) || defined(PROTO)
3005 /*
3006  * Return TRUE if ccline.overstrike is on.
3007  */
3008     int
3009 cmdline_overstrike(void)
3010 {
3011     return ccline.overstrike;
3012 }
3013 
3014 /*
3015  * Return TRUE if the cursor is at the end of the cmdline.
3016  */
3017     int
3018 cmdline_at_end(void)
3019 {
3020     return (ccline.cmdpos >= ccline.cmdlen);
3021 }
3022 #endif
3023 
3024 #if (defined(FEAT_XIM) && (defined(FEAT_GUI_GTK))) || defined(PROTO)
3025 /*
3026  * Return the virtual column number at the current cursor position.
3027  * This is used by the IM code to obtain the start of the preedit string.
3028  */
3029     colnr_T
3030 cmdline_getvcol_cursor(void)
3031 {
3032     if (ccline.cmdbuff == NULL || ccline.cmdpos > ccline.cmdlen)
3033 	return MAXCOL;
3034 
3035     if (has_mbyte)
3036     {
3037 	colnr_T	col;
3038 	int	i = 0;
3039 
3040 	for (col = 0; i < ccline.cmdpos; ++col)
3041 	    i += (*mb_ptr2len)(ccline.cmdbuff + i);
3042 
3043 	return col;
3044     }
3045     else
3046 	return ccline.cmdpos;
3047 }
3048 #endif
3049 
3050 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
3051 /*
3052  * If part of the command line is an IM preedit string, redraw it with
3053  * IM feedback attributes.  The cursor position is restored after drawing.
3054  */
3055     static void
3056 redrawcmd_preedit(void)
3057 {
3058     if ((State & CMDLINE)
3059 	    && xic != NULL
3060 	    /* && im_get_status()  doesn't work when using SCIM */
3061 	    && !p_imdisable
3062 	    && im_is_preediting())
3063     {
3064 	int	cmdpos = 0;
3065 	int	cmdspos;
3066 	int	old_row;
3067 	int	old_col;
3068 	colnr_T	col;
3069 
3070 	old_row = msg_row;
3071 	old_col = msg_col;
3072 	cmdspos = ((ccline.cmdfirstc != NUL) ? 1 : 0) + ccline.cmdindent;
3073 
3074 	if (has_mbyte)
3075 	{
3076 	    for (col = 0; col < preedit_start_col
3077 			  && cmdpos < ccline.cmdlen; ++col)
3078 	    {
3079 		cmdspos += (*mb_ptr2cells)(ccline.cmdbuff + cmdpos);
3080 		cmdpos  += (*mb_ptr2len)(ccline.cmdbuff + cmdpos);
3081 	    }
3082 	}
3083 	else
3084 	{
3085 	    cmdspos += preedit_start_col;
3086 	    cmdpos  += preedit_start_col;
3087 	}
3088 
3089 	msg_row = cmdline_row + (cmdspos / (int)Columns);
3090 	msg_col = cmdspos % (int)Columns;
3091 	if (msg_row >= Rows)
3092 	    msg_row = Rows - 1;
3093 
3094 	for (col = 0; cmdpos < ccline.cmdlen; ++col)
3095 	{
3096 	    int char_len;
3097 	    int char_attr;
3098 
3099 	    char_attr = im_get_feedback_attr(col);
3100 	    if (char_attr < 0)
3101 		break; /* end of preedit string */
3102 
3103 	    if (has_mbyte)
3104 		char_len = (*mb_ptr2len)(ccline.cmdbuff + cmdpos);
3105 	    else
3106 		char_len = 1;
3107 
3108 	    msg_outtrans_len_attr(ccline.cmdbuff + cmdpos, char_len, char_attr);
3109 	    cmdpos += char_len;
3110 	}
3111 
3112 	msg_row = old_row;
3113 	msg_col = old_col;
3114     }
3115 }
3116 #endif /* FEAT_XIM && FEAT_GUI_GTK */
3117 
3118 /*
3119  * Allocate a new command line buffer.
3120  * Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
3121  */
3122     static void
3123 alloc_cmdbuff(int len)
3124 {
3125     /*
3126      * give some extra space to avoid having to allocate all the time
3127      */
3128     if (len < 80)
3129 	len = 100;
3130     else
3131 	len += 20;
3132 
3133     ccline.cmdbuff = alloc(len);    /* caller should check for out-of-memory */
3134     ccline.cmdbufflen = len;
3135 }
3136 
3137 /*
3138  * Re-allocate the command line to length len + something extra.
3139  * return FAIL for failure, OK otherwise
3140  */
3141     static int
3142 realloc_cmdbuff(int len)
3143 {
3144     char_u	*p;
3145 
3146     if (len < ccline.cmdbufflen)
3147 	return OK;			/* no need to resize */
3148 
3149     p = ccline.cmdbuff;
3150     alloc_cmdbuff(len);			/* will get some more */
3151     if (ccline.cmdbuff == NULL)		/* out of memory */
3152     {
3153 	ccline.cmdbuff = p;		/* keep the old one */
3154 	return FAIL;
3155     }
3156     /* There isn't always a NUL after the command, but it may need to be
3157      * there, thus copy up to the NUL and add a NUL. */
3158     mch_memmove(ccline.cmdbuff, p, (size_t)ccline.cmdlen);
3159     ccline.cmdbuff[ccline.cmdlen] = NUL;
3160     vim_free(p);
3161 
3162     if (ccline.xpc != NULL
3163 	    && ccline.xpc->xp_pattern != NULL
3164 	    && ccline.xpc->xp_context != EXPAND_NOTHING
3165 	    && ccline.xpc->xp_context != EXPAND_UNSUCCESSFUL)
3166     {
3167 	int i = (int)(ccline.xpc->xp_pattern - p);
3168 
3169 	/* If xp_pattern points inside the old cmdbuff it needs to be adjusted
3170 	 * to point into the newly allocated memory. */
3171 	if (i >= 0 && i <= ccline.cmdlen)
3172 	    ccline.xpc->xp_pattern = ccline.cmdbuff + i;
3173     }
3174 
3175     return OK;
3176 }
3177 
3178 #if defined(FEAT_ARABIC) || defined(PROTO)
3179 static char_u	*arshape_buf = NULL;
3180 
3181 # if defined(EXITFREE) || defined(PROTO)
3182     void
3183 free_cmdline_buf(void)
3184 {
3185     vim_free(arshape_buf);
3186 }
3187 # endif
3188 #endif
3189 
3190 /*
3191  * Draw part of the cmdline at the current cursor position.  But draw stars
3192  * when cmdline_star is TRUE.
3193  */
3194     static void
3195 draw_cmdline(int start, int len)
3196 {
3197 #if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
3198     int		i;
3199 
3200     if (cmdline_star > 0)
3201 	for (i = 0; i < len; ++i)
3202 	{
3203 	    msg_putchar('*');
3204 	    if (has_mbyte)
3205 		i += (*mb_ptr2len)(ccline.cmdbuff + start + i) - 1;
3206 	}
3207     else
3208 #endif
3209 #ifdef FEAT_ARABIC
3210 	if (p_arshape && !p_tbidi && enc_utf8 && len > 0)
3211     {
3212 	static int	buflen = 0;
3213 	char_u		*p;
3214 	int		j;
3215 	int		newlen = 0;
3216 	int		mb_l;
3217 	int		pc, pc1 = 0;
3218 	int		prev_c = 0;
3219 	int		prev_c1 = 0;
3220 	int		u8c;
3221 	int		u8cc[MAX_MCO];
3222 	int		nc = 0;
3223 
3224 	/*
3225 	 * Do arabic shaping into a temporary buffer.  This is very
3226 	 * inefficient!
3227 	 */
3228 	if (len * 2 + 2 > buflen)
3229 	{
3230 	    /* Re-allocate the buffer.  We keep it around to avoid a lot of
3231 	     * alloc()/free() calls. */
3232 	    vim_free(arshape_buf);
3233 	    buflen = len * 2 + 2;
3234 	    arshape_buf = alloc(buflen);
3235 	    if (arshape_buf == NULL)
3236 		return;	/* out of memory */
3237 	}
3238 
3239 	if (utf_iscomposing(utf_ptr2char(ccline.cmdbuff + start)))
3240 	{
3241 	    /* Prepend a space to draw the leading composing char on. */
3242 	    arshape_buf[0] = ' ';
3243 	    newlen = 1;
3244 	}
3245 
3246 	for (j = start; j < start + len; j += mb_l)
3247 	{
3248 	    p = ccline.cmdbuff + j;
3249 	    u8c = utfc_ptr2char_len(p, u8cc, start + len - j);
3250 	    mb_l = utfc_ptr2len_len(p, start + len - j);
3251 	    if (ARABIC_CHAR(u8c))
3252 	    {
3253 		/* Do Arabic shaping. */
3254 		if (cmdmsg_rl)
3255 		{
3256 		    /* displaying from right to left */
3257 		    pc = prev_c;
3258 		    pc1 = prev_c1;
3259 		    prev_c1 = u8cc[0];
3260 		    if (j + mb_l >= start + len)
3261 			nc = NUL;
3262 		    else
3263 			nc = utf_ptr2char(p + mb_l);
3264 		}
3265 		else
3266 		{
3267 		    /* displaying from left to right */
3268 		    if (j + mb_l >= start + len)
3269 			pc = NUL;
3270 		    else
3271 		    {
3272 			int	pcc[MAX_MCO];
3273 
3274 			pc = utfc_ptr2char_len(p + mb_l, pcc,
3275 						      start + len - j - mb_l);
3276 			pc1 = pcc[0];
3277 		    }
3278 		    nc = prev_c;
3279 		}
3280 		prev_c = u8c;
3281 
3282 		u8c = arabic_shape(u8c, NULL, &u8cc[0], pc, pc1, nc);
3283 
3284 		newlen += (*mb_char2bytes)(u8c, arshape_buf + newlen);
3285 		if (u8cc[0] != 0)
3286 		{
3287 		    newlen += (*mb_char2bytes)(u8cc[0], arshape_buf + newlen);
3288 		    if (u8cc[1] != 0)
3289 			newlen += (*mb_char2bytes)(u8cc[1],
3290 							arshape_buf + newlen);
3291 		}
3292 	    }
3293 	    else
3294 	    {
3295 		prev_c = u8c;
3296 		mch_memmove(arshape_buf + newlen, p, mb_l);
3297 		newlen += mb_l;
3298 	    }
3299 	}
3300 
3301 	msg_outtrans_len(arshape_buf, newlen);
3302     }
3303     else
3304 #endif
3305 	msg_outtrans_len(ccline.cmdbuff + start, len);
3306 }
3307 
3308 /*
3309  * Put a character on the command line.  Shifts the following text to the
3310  * right when "shift" is TRUE.  Used for CTRL-V, CTRL-K, etc.
3311  * "c" must be printable (fit in one display cell)!
3312  */
3313     void
3314 putcmdline(int c, int shift)
3315 {
3316     if (cmd_silent)
3317 	return;
3318     msg_no_more = TRUE;
3319     msg_putchar(c);
3320     if (shift)
3321 	draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
3322     msg_no_more = FALSE;
3323     cursorcmd();
3324     extra_char = c;
3325     extra_char_shift = shift;
3326 }
3327 
3328 /*
3329  * Undo a putcmdline(c, FALSE).
3330  */
3331     void
3332 unputcmdline(void)
3333 {
3334     if (cmd_silent)
3335 	return;
3336     msg_no_more = TRUE;
3337     if (ccline.cmdlen == ccline.cmdpos)
3338 	msg_putchar(' ');
3339     else if (has_mbyte)
3340 	draw_cmdline(ccline.cmdpos,
3341 			       (*mb_ptr2len)(ccline.cmdbuff + ccline.cmdpos));
3342     else
3343 	draw_cmdline(ccline.cmdpos, 1);
3344     msg_no_more = FALSE;
3345     cursorcmd();
3346     extra_char = NUL;
3347 }
3348 
3349 /*
3350  * Put the given string, of the given length, onto the command line.
3351  * If len is -1, then STRLEN() is used to calculate the length.
3352  * If 'redraw' is TRUE then the new part of the command line, and the remaining
3353  * part will be redrawn, otherwise it will not.  If this function is called
3354  * twice in a row, then 'redraw' should be FALSE and redrawcmd() should be
3355  * called afterwards.
3356  */
3357     int
3358 put_on_cmdline(char_u *str, int len, int redraw)
3359 {
3360     int		retval;
3361     int		i;
3362     int		m;
3363     int		c;
3364 
3365     if (len < 0)
3366 	len = (int)STRLEN(str);
3367 
3368     /* Check if ccline.cmdbuff needs to be longer */
3369     if (ccline.cmdlen + len + 1 >= ccline.cmdbufflen)
3370 	retval = realloc_cmdbuff(ccline.cmdlen + len + 1);
3371     else
3372 	retval = OK;
3373     if (retval == OK)
3374     {
3375 	if (!ccline.overstrike)
3376 	{
3377 	    mch_memmove(ccline.cmdbuff + ccline.cmdpos + len,
3378 					       ccline.cmdbuff + ccline.cmdpos,
3379 				     (size_t)(ccline.cmdlen - ccline.cmdpos));
3380 	    ccline.cmdlen += len;
3381 	}
3382 	else
3383 	{
3384 	    if (has_mbyte)
3385 	    {
3386 		/* Count nr of characters in the new string. */
3387 		m = 0;
3388 		for (i = 0; i < len; i += (*mb_ptr2len)(str + i))
3389 		    ++m;
3390 		/* Count nr of bytes in cmdline that are overwritten by these
3391 		 * characters. */
3392 		for (i = ccline.cmdpos; i < ccline.cmdlen && m > 0;
3393 				 i += (*mb_ptr2len)(ccline.cmdbuff + i))
3394 		    --m;
3395 		if (i < ccline.cmdlen)
3396 		{
3397 		    mch_memmove(ccline.cmdbuff + ccline.cmdpos + len,
3398 			    ccline.cmdbuff + i, (size_t)(ccline.cmdlen - i));
3399 		    ccline.cmdlen += ccline.cmdpos + len - i;
3400 		}
3401 		else
3402 		    ccline.cmdlen = ccline.cmdpos + len;
3403 	    }
3404 	    else if (ccline.cmdpos + len > ccline.cmdlen)
3405 		ccline.cmdlen = ccline.cmdpos + len;
3406 	}
3407 	mch_memmove(ccline.cmdbuff + ccline.cmdpos, str, (size_t)len);
3408 	ccline.cmdbuff[ccline.cmdlen] = NUL;
3409 
3410 	if (enc_utf8)
3411 	{
3412 	    /* When the inserted text starts with a composing character,
3413 	     * backup to the character before it.  There could be two of them.
3414 	     */
3415 	    i = 0;
3416 	    c = utf_ptr2char(ccline.cmdbuff + ccline.cmdpos);
3417 	    while (ccline.cmdpos > 0 && utf_iscomposing(c))
3418 	    {
3419 		i = (*mb_head_off)(ccline.cmdbuff,
3420 				      ccline.cmdbuff + ccline.cmdpos - 1) + 1;
3421 		ccline.cmdpos -= i;
3422 		len += i;
3423 		c = utf_ptr2char(ccline.cmdbuff + ccline.cmdpos);
3424 	    }
3425 #ifdef FEAT_ARABIC
3426 	    if (i == 0 && ccline.cmdpos > 0 && arabic_maycombine(c))
3427 	    {
3428 		/* Check the previous character for Arabic combining pair. */
3429 		i = (*mb_head_off)(ccline.cmdbuff,
3430 				      ccline.cmdbuff + ccline.cmdpos - 1) + 1;
3431 		if (arabic_combine(utf_ptr2char(ccline.cmdbuff
3432 						     + ccline.cmdpos - i), c))
3433 		{
3434 		    ccline.cmdpos -= i;
3435 		    len += i;
3436 		}
3437 		else
3438 		    i = 0;
3439 	    }
3440 #endif
3441 	    if (i != 0)
3442 	    {
3443 		/* Also backup the cursor position. */
3444 		i = ptr2cells(ccline.cmdbuff + ccline.cmdpos);
3445 		ccline.cmdspos -= i;
3446 		msg_col -= i;
3447 		if (msg_col < 0)
3448 		{
3449 		    msg_col += Columns;
3450 		    --msg_row;
3451 		}
3452 	    }
3453 	}
3454 
3455 	if (redraw && !cmd_silent)
3456 	{
3457 	    msg_no_more = TRUE;
3458 	    i = cmdline_row;
3459 	    cursorcmd();
3460 	    draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
3461 	    /* Avoid clearing the rest of the line too often. */
3462 	    if (cmdline_row != i || ccline.overstrike)
3463 		msg_clr_eos();
3464 	    msg_no_more = FALSE;
3465 	}
3466 #ifdef FEAT_FKMAP
3467 	/*
3468 	 * If we are in Farsi command mode, the character input must be in
3469 	 * Insert mode. So do not advance the cmdpos.
3470 	 */
3471 	if (!cmd_fkmap)
3472 #endif
3473 	{
3474 	    if (KeyTyped)
3475 	    {
3476 		m = Columns * Rows;
3477 		if (m < 0)	/* overflow, Columns or Rows at weird value */
3478 		    m = MAXCOL;
3479 	    }
3480 	    else
3481 		m = MAXCOL;
3482 	    for (i = 0; i < len; ++i)
3483 	    {
3484 		c = cmdline_charsize(ccline.cmdpos);
3485 		/* count ">" for a double-wide char that doesn't fit. */
3486 		if (has_mbyte)
3487 		    correct_cmdspos(ccline.cmdpos, c);
3488 		/* Stop cursor at the end of the screen, but do increment the
3489 		 * insert position, so that entering a very long command
3490 		 * works, even though you can't see it. */
3491 		if (ccline.cmdspos + c < m)
3492 		    ccline.cmdspos += c;
3493 
3494 		if (has_mbyte)
3495 		{
3496 		    c = (*mb_ptr2len)(ccline.cmdbuff + ccline.cmdpos) - 1;
3497 		    if (c > len - i - 1)
3498 			c = len - i - 1;
3499 		    ccline.cmdpos += c;
3500 		    i += c;
3501 		}
3502 		++ccline.cmdpos;
3503 	    }
3504 	}
3505     }
3506     if (redraw)
3507 	msg_check();
3508     return retval;
3509 }
3510 
3511 static struct cmdline_info  prev_ccline;
3512 static int		    prev_ccline_used = FALSE;
3513 
3514 /*
3515  * Save ccline, because obtaining the "=" register may execute "normal :cmd"
3516  * and overwrite it.  But get_cmdline_str() may need it, thus make it
3517  * available globally in prev_ccline.
3518  */
3519     static void
3520 save_cmdline(struct cmdline_info *ccp)
3521 {
3522     if (!prev_ccline_used)
3523     {
3524 	vim_memset(&prev_ccline, 0, sizeof(struct cmdline_info));
3525 	prev_ccline_used = TRUE;
3526     }
3527     *ccp = prev_ccline;
3528     prev_ccline = ccline;
3529     ccline.cmdbuff = NULL;  // signal that ccline is not in use
3530 }
3531 
3532 /*
3533  * Restore ccline after it has been saved with save_cmdline().
3534  */
3535     static void
3536 restore_cmdline(struct cmdline_info *ccp)
3537 {
3538     ccline = prev_ccline;
3539     prev_ccline = *ccp;
3540 }
3541 
3542 /*
3543  * Paste a yank register into the command line.
3544  * Used by CTRL-R command in command-line mode.
3545  * insert_reg() can't be used here, because special characters from the
3546  * register contents will be interpreted as commands.
3547  *
3548  * Return FAIL for failure, OK otherwise.
3549  */
3550     static int
3551 cmdline_paste(
3552     int regname,
3553     int literally,	/* Insert text literally instead of "as typed" */
3554     int remcr)		/* remove trailing CR */
3555 {
3556     long		i;
3557     char_u		*arg;
3558     char_u		*p;
3559     int			allocated;
3560 
3561     /* check for valid regname; also accept special characters for CTRL-R in
3562      * the command line */
3563     if (regname != Ctrl_F && regname != Ctrl_P && regname != Ctrl_W
3564 	    && regname != Ctrl_A && regname != Ctrl_L
3565 	    && !valid_yank_reg(regname, FALSE))
3566 	return FAIL;
3567 
3568     /* A register containing CTRL-R can cause an endless loop.  Allow using
3569      * CTRL-C to break the loop. */
3570     line_breakcheck();
3571     if (got_int)
3572 	return FAIL;
3573 
3574 #ifdef FEAT_CLIPBOARD
3575     regname = may_get_selection(regname);
3576 #endif
3577 
3578     // Need to  set "textlock" to avoid nasty things like going to another
3579     // buffer when evaluating an expression.
3580     ++textlock;
3581     i = get_spec_reg(regname, &arg, &allocated, TRUE);
3582     --textlock;
3583 
3584     if (i)
3585     {
3586 	/* Got the value of a special register in "arg". */
3587 	if (arg == NULL)
3588 	    return FAIL;
3589 
3590 	/* When 'incsearch' is set and CTRL-R CTRL-W used: skip the duplicate
3591 	 * part of the word. */
3592 	p = arg;
3593 	if (p_is && regname == Ctrl_W)
3594 	{
3595 	    char_u  *w;
3596 	    int	    len;
3597 
3598 	    /* Locate start of last word in the cmd buffer. */
3599 	    for (w = ccline.cmdbuff + ccline.cmdpos; w > ccline.cmdbuff; )
3600 	    {
3601 		if (has_mbyte)
3602 		{
3603 		    len = (*mb_head_off)(ccline.cmdbuff, w - 1) + 1;
3604 		    if (!vim_iswordc(mb_ptr2char(w - len)))
3605 			break;
3606 		    w -= len;
3607 		}
3608 		else
3609 		{
3610 		    if (!vim_iswordc(w[-1]))
3611 			break;
3612 		    --w;
3613 		}
3614 	    }
3615 	    len = (int)((ccline.cmdbuff + ccline.cmdpos) - w);
3616 	    if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0)
3617 		p += len;
3618 	}
3619 
3620 	cmdline_paste_str(p, literally);
3621 	if (allocated)
3622 	    vim_free(arg);
3623 	return OK;
3624     }
3625 
3626     return cmdline_paste_reg(regname, literally, remcr);
3627 }
3628 
3629 /*
3630  * Put a string on the command line.
3631  * When "literally" is TRUE, insert literally.
3632  * When "literally" is FALSE, insert as typed, but don't leave the command
3633  * line.
3634  */
3635     void
3636 cmdline_paste_str(char_u *s, int literally)
3637 {
3638     int		c, cv;
3639 
3640     if (literally)
3641 	put_on_cmdline(s, -1, TRUE);
3642     else
3643 	while (*s != NUL)
3644 	{
3645 	    cv = *s;
3646 	    if (cv == Ctrl_V && s[1])
3647 		++s;
3648 	    if (has_mbyte)
3649 		c = mb_cptr2char_adv(&s);
3650 	    else
3651 		c = *s++;
3652 	    if (cv == Ctrl_V || c == ESC || c == Ctrl_C
3653 		    || c == CAR || c == NL || c == Ctrl_L
3654 #ifdef UNIX
3655 		    || c == intr_char
3656 #endif
3657 		    || (c == Ctrl_BSL && *s == Ctrl_N))
3658 		stuffcharReadbuff(Ctrl_V);
3659 	    stuffcharReadbuff(c);
3660 	}
3661 }
3662 
3663 #ifdef FEAT_WILDMENU
3664 /*
3665  * Delete characters on the command line, from "from" to the current
3666  * position.
3667  */
3668     static void
3669 cmdline_del(int from)
3670 {
3671     mch_memmove(ccline.cmdbuff + from, ccline.cmdbuff + ccline.cmdpos,
3672 	    (size_t)(ccline.cmdlen - ccline.cmdpos + 1));
3673     ccline.cmdlen -= ccline.cmdpos - from;
3674     ccline.cmdpos = from;
3675 }
3676 #endif
3677 
3678 /*
3679  * This function is called when the screen size changes and with incremental
3680  * search and in other situations where the command line may have been
3681  * overwritten.
3682  */
3683     void
3684 redrawcmdline(void)
3685 {
3686     redrawcmdline_ex(TRUE);
3687 }
3688 
3689     void
3690 redrawcmdline_ex(int do_compute_cmdrow)
3691 {
3692     if (cmd_silent)
3693 	return;
3694     need_wait_return = FALSE;
3695     if (do_compute_cmdrow)
3696 	compute_cmdrow();
3697     redrawcmd();
3698     cursorcmd();
3699 }
3700 
3701     static void
3702 redrawcmdprompt(void)
3703 {
3704     int		i;
3705 
3706     if (cmd_silent)
3707 	return;
3708     if (ccline.cmdfirstc != NUL)
3709 	msg_putchar(ccline.cmdfirstc);
3710     if (ccline.cmdprompt != NULL)
3711     {
3712 	msg_puts_attr((char *)ccline.cmdprompt, ccline.cmdattr);
3713 	ccline.cmdindent = msg_col + (msg_row - cmdline_row) * Columns;
3714 	/* do the reverse of set_cmdspos() */
3715 	if (ccline.cmdfirstc != NUL)
3716 	    --ccline.cmdindent;
3717     }
3718     else
3719 	for (i = ccline.cmdindent; i > 0; --i)
3720 	    msg_putchar(' ');
3721 }
3722 
3723 /*
3724  * Redraw what is currently on the command line.
3725  */
3726     void
3727 redrawcmd(void)
3728 {
3729     if (cmd_silent)
3730 	return;
3731 
3732     /* when 'incsearch' is set there may be no command line while redrawing */
3733     if (ccline.cmdbuff == NULL)
3734     {
3735 	windgoto(cmdline_row, 0);
3736 	msg_clr_eos();
3737 	return;
3738     }
3739 
3740     msg_start();
3741     redrawcmdprompt();
3742 
3743     /* Don't use more prompt, truncate the cmdline if it doesn't fit. */
3744     msg_no_more = TRUE;
3745     draw_cmdline(0, ccline.cmdlen);
3746     msg_clr_eos();
3747     msg_no_more = FALSE;
3748 
3749     set_cmdspos_cursor();
3750     if (extra_char != NUL)
3751 	putcmdline(extra_char, extra_char_shift);
3752 
3753     /*
3754      * An emsg() before may have set msg_scroll. This is used in normal mode,
3755      * in cmdline mode we can reset them now.
3756      */
3757     msg_scroll = FALSE;		/* next message overwrites cmdline */
3758 
3759     /* Typing ':' at the more prompt may set skip_redraw.  We don't want this
3760      * in cmdline mode */
3761     skip_redraw = FALSE;
3762 }
3763 
3764     void
3765 compute_cmdrow(void)
3766 {
3767     if (exmode_active || msg_scrolled != 0)
3768 	cmdline_row = Rows - 1;
3769     else
3770 	cmdline_row = W_WINROW(lastwin) + lastwin->w_height
3771 						    + lastwin->w_status_height;
3772 }
3773 
3774     static void
3775 cursorcmd(void)
3776 {
3777     if (cmd_silent)
3778 	return;
3779 
3780 #ifdef FEAT_RIGHTLEFT
3781     if (cmdmsg_rl)
3782     {
3783 	msg_row = cmdline_row  + (ccline.cmdspos / (int)(Columns - 1));
3784 	msg_col = (int)Columns - (ccline.cmdspos % (int)(Columns - 1)) - 1;
3785 	if (msg_row <= 0)
3786 	    msg_row = Rows - 1;
3787     }
3788     else
3789 #endif
3790     {
3791 	msg_row = cmdline_row + (ccline.cmdspos / (int)Columns);
3792 	msg_col = ccline.cmdspos % (int)Columns;
3793 	if (msg_row >= Rows)
3794 	    msg_row = Rows - 1;
3795     }
3796 
3797     windgoto(msg_row, msg_col);
3798 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
3799     if (p_imst == IM_ON_THE_SPOT)
3800 	redrawcmd_preedit();
3801 #endif
3802 #ifdef MCH_CURSOR_SHAPE
3803     mch_update_cursor();
3804 #endif
3805 }
3806 
3807     void
3808 gotocmdline(int clr)
3809 {
3810     msg_start();
3811 #ifdef FEAT_RIGHTLEFT
3812     if (cmdmsg_rl)
3813 	msg_col = Columns - 1;
3814     else
3815 #endif
3816 	msg_col = 0;	    /* always start in column 0 */
3817     if (clr)		    /* clear the bottom line(s) */
3818 	msg_clr_eos();	    /* will reset clear_cmdline */
3819     windgoto(cmdline_row, 0);
3820 }
3821 
3822 /*
3823  * Check the word in front of the cursor for an abbreviation.
3824  * Called when the non-id character "c" has been entered.
3825  * When an abbreviation is recognized it is removed from the text with
3826  * backspaces and the replacement string is inserted, followed by "c".
3827  */
3828     static int
3829 ccheck_abbr(int c)
3830 {
3831     int spos = 0;
3832 
3833     if (p_paste || no_abbr)	    /* no abbreviations or in paste mode */
3834 	return FALSE;
3835 
3836     /* Do not consider '<,'> be part of the mapping, skip leading whitespace.
3837      * Actually accepts any mark. */
3838     while (VIM_ISWHITE(ccline.cmdbuff[spos]) && spos < ccline.cmdlen)
3839 	spos++;
3840     if (ccline.cmdlen - spos > 5
3841 	    && ccline.cmdbuff[spos] == '\''
3842 	    && ccline.cmdbuff[spos + 2] == ','
3843 	    && ccline.cmdbuff[spos + 3] == '\'')
3844 	spos += 5;
3845     else
3846 	/* check abbreviation from the beginning of the commandline */
3847 	spos = 0;
3848 
3849     return check_abbr(c, ccline.cmdbuff, ccline.cmdpos, spos);
3850 }
3851 
3852 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
3853     static int
3854 #ifdef __BORLANDC__
3855 _RTLENTRYF
3856 #endif
3857 sort_func_compare(const void *s1, const void *s2)
3858 {
3859     char_u *p1 = *(char_u **)s1;
3860     char_u *p2 = *(char_u **)s2;
3861 
3862     if (*p1 != '<' && *p2 == '<') return -1;
3863     if (*p1 == '<' && *p2 != '<') return 1;
3864     return STRCMP(p1, p2);
3865 }
3866 #endif
3867 
3868 /*
3869  * Return FAIL if this is not an appropriate context in which to do
3870  * completion of anything, return OK if it is (even if there are no matches).
3871  * For the caller, this means that the character is just passed through like a
3872  * normal character (instead of being expanded).  This allows :s/^I^D etc.
3873  */
3874     static int
3875 nextwild(
3876     expand_T	*xp,
3877     int		type,
3878     int		options,	/* extra options for ExpandOne() */
3879     int		escape)		/* if TRUE, escape the returned matches */
3880 {
3881     int		i, j;
3882     char_u	*p1;
3883     char_u	*p2;
3884     int		difflen;
3885     int		v;
3886 
3887     if (xp->xp_numfiles == -1)
3888     {
3889 	set_expand_context(xp);
3890 	cmd_showtail = expand_showtail(xp);
3891     }
3892 
3893     if (xp->xp_context == EXPAND_UNSUCCESSFUL)
3894     {
3895 	beep_flush();
3896 	return OK;  /* Something illegal on command line */
3897     }
3898     if (xp->xp_context == EXPAND_NOTHING)
3899     {
3900 	/* Caller can use the character as a normal char instead */
3901 	return FAIL;
3902     }
3903 
3904     msg_puts("...");	    /* show that we are busy */
3905     out_flush();
3906 
3907     i = (int)(xp->xp_pattern - ccline.cmdbuff);
3908     xp->xp_pattern_len = ccline.cmdpos - i;
3909 
3910     if (type == WILD_NEXT || type == WILD_PREV)
3911     {
3912 	/*
3913 	 * Get next/previous match for a previous expanded pattern.
3914 	 */
3915 	p2 = ExpandOne(xp, NULL, NULL, 0, type);
3916     }
3917     else
3918     {
3919 	/*
3920 	 * Translate string into pattern and expand it.
3921 	 */
3922 	if ((p1 = addstar(xp->xp_pattern, xp->xp_pattern_len,
3923 						     xp->xp_context)) == NULL)
3924 	    p2 = NULL;
3925 	else
3926 	{
3927 	    int use_options = options |
3928 		    WILD_HOME_REPLACE|WILD_ADD_SLASH|WILD_SILENT;
3929 	    if (escape)
3930 		use_options |= WILD_ESCAPE;
3931 
3932 	    if (p_wic)
3933 		use_options += WILD_ICASE;
3934 	    p2 = ExpandOne(xp, p1,
3935 			 vim_strnsave(&ccline.cmdbuff[i], xp->xp_pattern_len),
3936 							   use_options, type);
3937 	    vim_free(p1);
3938 	    /* longest match: make sure it is not shorter, happens with :help */
3939 	    if (p2 != NULL && type == WILD_LONGEST)
3940 	    {
3941 		for (j = 0; j < xp->xp_pattern_len; ++j)
3942 		     if (ccline.cmdbuff[i + j] == '*'
3943 			     || ccline.cmdbuff[i + j] == '?')
3944 			 break;
3945 		if ((int)STRLEN(p2) < j)
3946 		    VIM_CLEAR(p2);
3947 	    }
3948 	}
3949     }
3950 
3951     if (p2 != NULL && !got_int)
3952     {
3953 	difflen = (int)STRLEN(p2) - xp->xp_pattern_len;
3954 	if (ccline.cmdlen + difflen + 4 > ccline.cmdbufflen)
3955 	{
3956 	    v = realloc_cmdbuff(ccline.cmdlen + difflen + 4);
3957 	    xp->xp_pattern = ccline.cmdbuff + i;
3958 	}
3959 	else
3960 	    v = OK;
3961 	if (v == OK)
3962 	{
3963 	    mch_memmove(&ccline.cmdbuff[ccline.cmdpos + difflen],
3964 		    &ccline.cmdbuff[ccline.cmdpos],
3965 		    (size_t)(ccline.cmdlen - ccline.cmdpos + 1));
3966 	    mch_memmove(&ccline.cmdbuff[i], p2, STRLEN(p2));
3967 	    ccline.cmdlen += difflen;
3968 	    ccline.cmdpos += difflen;
3969 	}
3970     }
3971     vim_free(p2);
3972 
3973     redrawcmd();
3974     cursorcmd();
3975 
3976     /* When expanding a ":map" command and no matches are found, assume that
3977      * the key is supposed to be inserted literally */
3978     if (xp->xp_context == EXPAND_MAPPINGS && p2 == NULL)
3979 	return FAIL;
3980 
3981     if (xp->xp_numfiles <= 0 && p2 == NULL)
3982 	beep_flush();
3983     else if (xp->xp_numfiles == 1)
3984 	/* free expanded pattern */
3985 	(void)ExpandOne(xp, NULL, NULL, 0, WILD_FREE);
3986 
3987     return OK;
3988 }
3989 
3990 /*
3991  * Do wildcard expansion on the string 'str'.
3992  * Chars that should not be expanded must be preceded with a backslash.
3993  * Return a pointer to allocated memory containing the new string.
3994  * Return NULL for failure.
3995  *
3996  * "orig" is the originally expanded string, copied to allocated memory.  It
3997  * should either be kept in orig_save or freed.  When "mode" is WILD_NEXT or
3998  * WILD_PREV "orig" should be NULL.
3999  *
4000  * Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode"
4001  * is WILD_EXPAND_FREE or WILD_ALL.
4002  *
4003  * mode = WILD_FREE:	    just free previously expanded matches
4004  * mode = WILD_EXPAND_FREE: normal expansion, do not keep matches
4005  * mode = WILD_EXPAND_KEEP: normal expansion, keep matches
4006  * mode = WILD_NEXT:	    use next match in multiple match, wrap to first
4007  * mode = WILD_PREV:	    use previous match in multiple match, wrap to first
4008  * mode = WILD_ALL:	    return all matches concatenated
4009  * mode = WILD_LONGEST:	    return longest matched part
4010  * mode = WILD_ALL_KEEP:    get all matches, keep matches
4011  *
4012  * options = WILD_LIST_NOTFOUND:    list entries without a match
4013  * options = WILD_HOME_REPLACE:	    do home_replace() for buffer names
4014  * options = WILD_USE_NL:	    Use '\n' for WILD_ALL
4015  * options = WILD_NO_BEEP:	    Don't beep for multiple matches
4016  * options = WILD_ADD_SLASH:	    add a slash after directory names
4017  * options = WILD_KEEP_ALL:	    don't remove 'wildignore' entries
4018  * options = WILD_SILENT:	    don't print warning messages
4019  * options = WILD_ESCAPE:	    put backslash before special chars
4020  * options = WILD_ICASE:	    ignore case for files
4021  *
4022  * The variables xp->xp_context and xp->xp_backslash must have been set!
4023  */
4024     char_u *
4025 ExpandOne(
4026     expand_T	*xp,
4027     char_u	*str,
4028     char_u	*orig,	    /* allocated copy of original of expanded string */
4029     int		options,
4030     int		mode)
4031 {
4032     char_u	*ss = NULL;
4033     static int	findex;
4034     static char_u *orig_save = NULL;	/* kept value of orig */
4035     int		orig_saved = FALSE;
4036     int		i;
4037     long_u	len;
4038     int		non_suf_match;		/* number without matching suffix */
4039 
4040     /*
4041      * first handle the case of using an old match
4042      */
4043     if (mode == WILD_NEXT || mode == WILD_PREV)
4044     {
4045 	if (xp->xp_numfiles > 0)
4046 	{
4047 	    if (mode == WILD_PREV)
4048 	    {
4049 		if (findex == -1)
4050 		    findex = xp->xp_numfiles;
4051 		--findex;
4052 	    }
4053 	    else    /* mode == WILD_NEXT */
4054 		++findex;
4055 
4056 	    /*
4057 	     * When wrapping around, return the original string, set findex to
4058 	     * -1.
4059 	     */
4060 	    if (findex < 0)
4061 	    {
4062 		if (orig_save == NULL)
4063 		    findex = xp->xp_numfiles - 1;
4064 		else
4065 		    findex = -1;
4066 	    }
4067 	    if (findex >= xp->xp_numfiles)
4068 	    {
4069 		if (orig_save == NULL)
4070 		    findex = 0;
4071 		else
4072 		    findex = -1;
4073 	    }
4074 #ifdef FEAT_WILDMENU
4075 	    if (p_wmnu)
4076 		win_redr_status_matches(xp, xp->xp_numfiles, xp->xp_files,
4077 							findex, cmd_showtail);
4078 #endif
4079 	    if (findex == -1)
4080 		return vim_strsave(orig_save);
4081 	    return vim_strsave(xp->xp_files[findex]);
4082 	}
4083 	else
4084 	    return NULL;
4085     }
4086 
4087     /* free old names */
4088     if (xp->xp_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST)
4089     {
4090 	FreeWild(xp->xp_numfiles, xp->xp_files);
4091 	xp->xp_numfiles = -1;
4092 	VIM_CLEAR(orig_save);
4093     }
4094     findex = 0;
4095 
4096     if (mode == WILD_FREE)	/* only release file name */
4097 	return NULL;
4098 
4099     if (xp->xp_numfiles == -1)
4100     {
4101 	vim_free(orig_save);
4102 	orig_save = orig;
4103 	orig_saved = TRUE;
4104 
4105 	/*
4106 	 * Do the expansion.
4107 	 */
4108 	if (ExpandFromContext(xp, str, &xp->xp_numfiles, &xp->xp_files,
4109 							     options) == FAIL)
4110 	{
4111 #ifdef FNAME_ILLEGAL
4112 	    /* Illegal file name has been silently skipped.  But when there
4113 	     * are wildcards, the real problem is that there was no match,
4114 	     * causing the pattern to be added, which has illegal characters.
4115 	     */
4116 	    if (!(options & WILD_SILENT) && (options & WILD_LIST_NOTFOUND))
4117 		semsg(_(e_nomatch2), str);
4118 #endif
4119 	}
4120 	else if (xp->xp_numfiles == 0)
4121 	{
4122 	    if (!(options & WILD_SILENT))
4123 		semsg(_(e_nomatch2), str);
4124 	}
4125 	else
4126 	{
4127 	    /* Escape the matches for use on the command line. */
4128 	    ExpandEscape(xp, str, xp->xp_numfiles, xp->xp_files, options);
4129 
4130 	    /*
4131 	     * Check for matching suffixes in file names.
4132 	     */
4133 	    if (mode != WILD_ALL && mode != WILD_ALL_KEEP
4134 						      && mode != WILD_LONGEST)
4135 	    {
4136 		if (xp->xp_numfiles)
4137 		    non_suf_match = xp->xp_numfiles;
4138 		else
4139 		    non_suf_match = 1;
4140 		if ((xp->xp_context == EXPAND_FILES
4141 			    || xp->xp_context == EXPAND_DIRECTORIES)
4142 			&& xp->xp_numfiles > 1)
4143 		{
4144 		    /*
4145 		     * More than one match; check suffix.
4146 		     * The files will have been sorted on matching suffix in
4147 		     * expand_wildcards, only need to check the first two.
4148 		     */
4149 		    non_suf_match = 0;
4150 		    for (i = 0; i < 2; ++i)
4151 			if (match_suffix(xp->xp_files[i]))
4152 			    ++non_suf_match;
4153 		}
4154 		if (non_suf_match != 1)
4155 		{
4156 		    /* Can we ever get here unless it's while expanding
4157 		     * interactively?  If not, we can get rid of this all
4158 		     * together. Don't really want to wait for this message
4159 		     * (and possibly have to hit return to continue!).
4160 		     */
4161 		    if (!(options & WILD_SILENT))
4162 			emsg(_(e_toomany));
4163 		    else if (!(options & WILD_NO_BEEP))
4164 			beep_flush();
4165 		}
4166 		if (!(non_suf_match != 1 && mode == WILD_EXPAND_FREE))
4167 		    ss = vim_strsave(xp->xp_files[0]);
4168 	    }
4169 	}
4170     }
4171 
4172     /* Find longest common part */
4173     if (mode == WILD_LONGEST && xp->xp_numfiles > 0)
4174     {
4175 	int mb_len = 1;
4176 	int c0, ci;
4177 
4178 	for (len = 0; xp->xp_files[0][len]; len += mb_len)
4179 	{
4180 	    if (has_mbyte)
4181 	    {
4182 		mb_len = (*mb_ptr2len)(&xp->xp_files[0][len]);
4183 		c0 =(* mb_ptr2char)(&xp->xp_files[0][len]);
4184 	    }
4185 	    else
4186 		c0 = xp->xp_files[0][len];
4187 	    for (i = 1; i < xp->xp_numfiles; ++i)
4188 	    {
4189 		if (has_mbyte)
4190 		    ci =(* mb_ptr2char)(&xp->xp_files[i][len]);
4191 		else
4192 		    ci = xp->xp_files[i][len];
4193 		if (p_fic && (xp->xp_context == EXPAND_DIRECTORIES
4194 			|| xp->xp_context == EXPAND_FILES
4195 			|| xp->xp_context == EXPAND_SHELLCMD
4196 			|| xp->xp_context == EXPAND_BUFFERS))
4197 		{
4198 		    if (MB_TOLOWER(c0) != MB_TOLOWER(ci))
4199 			break;
4200 		}
4201 		else if (c0 != ci)
4202 		    break;
4203 	    }
4204 	    if (i < xp->xp_numfiles)
4205 	    {
4206 		if (!(options & WILD_NO_BEEP))
4207 		    vim_beep(BO_WILD);
4208 		break;
4209 	    }
4210 	}
4211 
4212 	ss = alloc((unsigned)len + 1);
4213 	if (ss)
4214 	    vim_strncpy(ss, xp->xp_files[0], (size_t)len);
4215 	findex = -1;			    /* next p_wc gets first one */
4216     }
4217 
4218     /* Concatenate all matching names */
4219     if (mode == WILD_ALL && xp->xp_numfiles > 0)
4220     {
4221 	len = 0;
4222 	for (i = 0; i < xp->xp_numfiles; ++i)
4223 	    len += (long_u)STRLEN(xp->xp_files[i]) + 1;
4224 	ss = lalloc(len, TRUE);
4225 	if (ss != NULL)
4226 	{
4227 	    *ss = NUL;
4228 	    for (i = 0; i < xp->xp_numfiles; ++i)
4229 	    {
4230 		STRCAT(ss, xp->xp_files[i]);
4231 		if (i != xp->xp_numfiles - 1)
4232 		    STRCAT(ss, (options & WILD_USE_NL) ? "\n" : " ");
4233 	    }
4234 	}
4235     }
4236 
4237     if (mode == WILD_EXPAND_FREE || mode == WILD_ALL)
4238 	ExpandCleanup(xp);
4239 
4240     /* Free "orig" if it wasn't stored in "orig_save". */
4241     if (!orig_saved)
4242 	vim_free(orig);
4243 
4244     return ss;
4245 }
4246 
4247 /*
4248  * Prepare an expand structure for use.
4249  */
4250     void
4251 ExpandInit(expand_T *xp)
4252 {
4253     xp->xp_pattern = NULL;
4254     xp->xp_pattern_len = 0;
4255     xp->xp_backslash = XP_BS_NONE;
4256 #ifndef BACKSLASH_IN_FILENAME
4257     xp->xp_shell = FALSE;
4258 #endif
4259     xp->xp_numfiles = -1;
4260     xp->xp_files = NULL;
4261 #if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
4262     xp->xp_arg = NULL;
4263 #endif
4264     xp->xp_line = NULL;
4265 }
4266 
4267 /*
4268  * Cleanup an expand structure after use.
4269  */
4270     void
4271 ExpandCleanup(expand_T *xp)
4272 {
4273     if (xp->xp_numfiles >= 0)
4274     {
4275 	FreeWild(xp->xp_numfiles, xp->xp_files);
4276 	xp->xp_numfiles = -1;
4277     }
4278 }
4279 
4280     void
4281 ExpandEscape(
4282     expand_T	*xp,
4283     char_u	*str,
4284     int		numfiles,
4285     char_u	**files,
4286     int		options)
4287 {
4288     int		i;
4289     char_u	*p;
4290 
4291     /*
4292      * May change home directory back to "~"
4293      */
4294     if (options & WILD_HOME_REPLACE)
4295 	tilde_replace(str, numfiles, files);
4296 
4297     if (options & WILD_ESCAPE)
4298     {
4299 	if (xp->xp_context == EXPAND_FILES
4300 		|| xp->xp_context == EXPAND_FILES_IN_PATH
4301 		|| xp->xp_context == EXPAND_SHELLCMD
4302 		|| xp->xp_context == EXPAND_BUFFERS
4303 		|| xp->xp_context == EXPAND_DIRECTORIES)
4304 	{
4305 	    /*
4306 	     * Insert a backslash into a file name before a space, \, %, #
4307 	     * and wildmatch characters, except '~'.
4308 	     */
4309 	    for (i = 0; i < numfiles; ++i)
4310 	    {
4311 		/* for ":set path=" we need to escape spaces twice */
4312 		if (xp->xp_backslash == XP_BS_THREE)
4313 		{
4314 		    p = vim_strsave_escaped(files[i], (char_u *)" ");
4315 		    if (p != NULL)
4316 		    {
4317 			vim_free(files[i]);
4318 			files[i] = p;
4319 #if defined(BACKSLASH_IN_FILENAME)
4320 			p = vim_strsave_escaped(files[i], (char_u *)" ");
4321 			if (p != NULL)
4322 			{
4323 			    vim_free(files[i]);
4324 			    files[i] = p;
4325 			}
4326 #endif
4327 		    }
4328 		}
4329 #ifdef BACKSLASH_IN_FILENAME
4330 		p = vim_strsave_fnameescape(files[i], FALSE);
4331 #else
4332 		p = vim_strsave_fnameescape(files[i], xp->xp_shell);
4333 #endif
4334 		if (p != NULL)
4335 		{
4336 		    vim_free(files[i]);
4337 		    files[i] = p;
4338 		}
4339 
4340 		/* If 'str' starts with "\~", replace "~" at start of
4341 		 * files[i] with "\~". */
4342 		if (str[0] == '\\' && str[1] == '~' && files[i][0] == '~')
4343 		    escape_fname(&files[i]);
4344 	    }
4345 	    xp->xp_backslash = XP_BS_NONE;
4346 
4347 	    /* If the first file starts with a '+' escape it.  Otherwise it
4348 	     * could be seen as "+cmd". */
4349 	    if (*files[0] == '+')
4350 		escape_fname(&files[0]);
4351 	}
4352 	else if (xp->xp_context == EXPAND_TAGS)
4353 	{
4354 	    /*
4355 	     * Insert a backslash before characters in a tag name that
4356 	     * would terminate the ":tag" command.
4357 	     */
4358 	    for (i = 0; i < numfiles; ++i)
4359 	    {
4360 		p = vim_strsave_escaped(files[i], (char_u *)"\\|\"");
4361 		if (p != NULL)
4362 		{
4363 		    vim_free(files[i]);
4364 		    files[i] = p;
4365 		}
4366 	    }
4367 	}
4368     }
4369 }
4370 
4371 /*
4372  * Escape special characters in "fname" for when used as a file name argument
4373  * after a Vim command, or, when "shell" is non-zero, a shell command.
4374  * Returns the result in allocated memory.
4375  */
4376     char_u *
4377 vim_strsave_fnameescape(char_u *fname, int shell)
4378 {
4379     char_u	*p;
4380 #ifdef BACKSLASH_IN_FILENAME
4381     char_u	buf[20];
4382     int		j = 0;
4383 
4384     /* Don't escape '[', '{' and '!' if they are in 'isfname'. */
4385     for (p = PATH_ESC_CHARS; *p != NUL; ++p)
4386 	if ((*p != '[' && *p != '{' && *p != '!') || !vim_isfilec(*p))
4387 	    buf[j++] = *p;
4388     buf[j] = NUL;
4389     p = vim_strsave_escaped(fname, buf);
4390 #else
4391     p = vim_strsave_escaped(fname, shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS);
4392     if (shell && csh_like_shell() && p != NULL)
4393     {
4394 	char_u	    *s;
4395 
4396 	/* For csh and similar shells need to put two backslashes before '!'.
4397 	 * One is taken by Vim, one by the shell. */
4398 	s = vim_strsave_escaped(p, (char_u *)"!");
4399 	vim_free(p);
4400 	p = s;
4401     }
4402 #endif
4403 
4404     /* '>' and '+' are special at the start of some commands, e.g. ":edit" and
4405      * ":write".  "cd -" has a special meaning. */
4406     if (p != NULL && (*p == '>' || *p == '+' || (*p == '-' && p[1] == NUL)))
4407 	escape_fname(&p);
4408 
4409     return p;
4410 }
4411 
4412 /*
4413  * Put a backslash before the file name in "pp", which is in allocated memory.
4414  */
4415     static void
4416 escape_fname(char_u **pp)
4417 {
4418     char_u	*p;
4419 
4420     p = alloc((unsigned)(STRLEN(*pp) + 2));
4421     if (p != NULL)
4422     {
4423 	p[0] = '\\';
4424 	STRCPY(p + 1, *pp);
4425 	vim_free(*pp);
4426 	*pp = p;
4427     }
4428 }
4429 
4430 /*
4431  * For each file name in files[num_files]:
4432  * If 'orig_pat' starts with "~/", replace the home directory with "~".
4433  */
4434     void
4435 tilde_replace(
4436     char_u  *orig_pat,
4437     int	    num_files,
4438     char_u  **files)
4439 {
4440     int	    i;
4441     char_u  *p;
4442 
4443     if (orig_pat[0] == '~' && vim_ispathsep(orig_pat[1]))
4444     {
4445 	for (i = 0; i < num_files; ++i)
4446 	{
4447 	    p = home_replace_save(NULL, files[i]);
4448 	    if (p != NULL)
4449 	    {
4450 		vim_free(files[i]);
4451 		files[i] = p;
4452 	    }
4453 	}
4454     }
4455 }
4456 
4457 /*
4458  * Show all matches for completion on the command line.
4459  * Returns EXPAND_NOTHING when the character that triggered expansion should
4460  * be inserted like a normal character.
4461  */
4462     static int
4463 showmatches(expand_T *xp, int wildmenu UNUSED)
4464 {
4465 #define L_SHOWFILE(m) (showtail ? sm_gettail(files_found[m]) : files_found[m])
4466     int		num_files;
4467     char_u	**files_found;
4468     int		i, j, k;
4469     int		maxlen;
4470     int		lines;
4471     int		columns;
4472     char_u	*p;
4473     int		lastlen;
4474     int		attr;
4475     int		showtail;
4476 
4477     if (xp->xp_numfiles == -1)
4478     {
4479 	set_expand_context(xp);
4480 	i = expand_cmdline(xp, ccline.cmdbuff, ccline.cmdpos,
4481 						    &num_files, &files_found);
4482 	showtail = expand_showtail(xp);
4483 	if (i != EXPAND_OK)
4484 	    return i;
4485 
4486     }
4487     else
4488     {
4489 	num_files = xp->xp_numfiles;
4490 	files_found = xp->xp_files;
4491 	showtail = cmd_showtail;
4492     }
4493 
4494 #ifdef FEAT_WILDMENU
4495     if (!wildmenu)
4496     {
4497 #endif
4498 	msg_didany = FALSE;		/* lines_left will be set */
4499 	msg_start();			/* prepare for paging */
4500 	msg_putchar('\n');
4501 	out_flush();
4502 	cmdline_row = msg_row;
4503 	msg_didany = FALSE;		/* lines_left will be set again */
4504 	msg_start();			/* prepare for paging */
4505 #ifdef FEAT_WILDMENU
4506     }
4507 #endif
4508 
4509     if (got_int)
4510 	got_int = FALSE;	/* only int. the completion, not the cmd line */
4511 #ifdef FEAT_WILDMENU
4512     else if (wildmenu)
4513 	win_redr_status_matches(xp, num_files, files_found, -1, showtail);
4514 #endif
4515     else
4516     {
4517 	/* find the length of the longest file name */
4518 	maxlen = 0;
4519 	for (i = 0; i < num_files; ++i)
4520 	{
4521 	    if (!showtail && (xp->xp_context == EXPAND_FILES
4522 			  || xp->xp_context == EXPAND_SHELLCMD
4523 			  || xp->xp_context == EXPAND_BUFFERS))
4524 	    {
4525 		home_replace(NULL, files_found[i], NameBuff, MAXPATHL, TRUE);
4526 		j = vim_strsize(NameBuff);
4527 	    }
4528 	    else
4529 		j = vim_strsize(L_SHOWFILE(i));
4530 	    if (j > maxlen)
4531 		maxlen = j;
4532 	}
4533 
4534 	if (xp->xp_context == EXPAND_TAGS_LISTFILES)
4535 	    lines = num_files;
4536 	else
4537 	{
4538 	    /* compute the number of columns and lines for the listing */
4539 	    maxlen += 2;    /* two spaces between file names */
4540 	    columns = ((int)Columns + 2) / maxlen;
4541 	    if (columns < 1)
4542 		columns = 1;
4543 	    lines = (num_files + columns - 1) / columns;
4544 	}
4545 
4546 	attr = HL_ATTR(HLF_D);	/* find out highlighting for directories */
4547 
4548 	if (xp->xp_context == EXPAND_TAGS_LISTFILES)
4549 	{
4550 	    msg_puts_attr(_("tagname"), HL_ATTR(HLF_T));
4551 	    msg_clr_eos();
4552 	    msg_advance(maxlen - 3);
4553 	    msg_puts_attr(_(" kind file\n"), HL_ATTR(HLF_T));
4554 	}
4555 
4556 	/* list the files line by line */
4557 	for (i = 0; i < lines; ++i)
4558 	{
4559 	    lastlen = 999;
4560 	    for (k = i; k < num_files; k += lines)
4561 	    {
4562 		if (xp->xp_context == EXPAND_TAGS_LISTFILES)
4563 		{
4564 		    msg_outtrans_attr(files_found[k], HL_ATTR(HLF_D));
4565 		    p = files_found[k] + STRLEN(files_found[k]) + 1;
4566 		    msg_advance(maxlen + 1);
4567 		    msg_puts((char *)p);
4568 		    msg_advance(maxlen + 3);
4569 		    msg_outtrans_long_attr(p + 2, HL_ATTR(HLF_D));
4570 		    break;
4571 		}
4572 		for (j = maxlen - lastlen; --j >= 0; )
4573 		    msg_putchar(' ');
4574 		if (xp->xp_context == EXPAND_FILES
4575 					  || xp->xp_context == EXPAND_SHELLCMD
4576 					  || xp->xp_context == EXPAND_BUFFERS)
4577 		{
4578 		    /* highlight directories */
4579 		    if (xp->xp_numfiles != -1)
4580 		    {
4581 			char_u	*halved_slash;
4582 			char_u	*exp_path;
4583 
4584 			/* Expansion was done before and special characters
4585 			 * were escaped, need to halve backslashes.  Also
4586 			 * $HOME has been replaced with ~/. */
4587 			exp_path = expand_env_save_opt(files_found[k], TRUE);
4588 			halved_slash = backslash_halve_save(
4589 				exp_path != NULL ? exp_path : files_found[k]);
4590 			j = mch_isdir(halved_slash != NULL ? halved_slash
4591 							    : files_found[k]);
4592 			vim_free(exp_path);
4593 			vim_free(halved_slash);
4594 		    }
4595 		    else
4596 			/* Expansion was done here, file names are literal. */
4597 			j = mch_isdir(files_found[k]);
4598 		    if (showtail)
4599 			p = L_SHOWFILE(k);
4600 		    else
4601 		    {
4602 			home_replace(NULL, files_found[k], NameBuff, MAXPATHL,
4603 									TRUE);
4604 			p = NameBuff;
4605 		    }
4606 		}
4607 		else
4608 		{
4609 		    j = FALSE;
4610 		    p = L_SHOWFILE(k);
4611 		}
4612 		lastlen = msg_outtrans_attr(p, j ? attr : 0);
4613 	    }
4614 	    if (msg_col > 0)	/* when not wrapped around */
4615 	    {
4616 		msg_clr_eos();
4617 		msg_putchar('\n');
4618 	    }
4619 	    out_flush();		    /* show one line at a time */
4620 	    if (got_int)
4621 	    {
4622 		got_int = FALSE;
4623 		break;
4624 	    }
4625 	}
4626 
4627 	/*
4628 	 * we redraw the command below the lines that we have just listed
4629 	 * This is a bit tricky, but it saves a lot of screen updating.
4630 	 */
4631 	cmdline_row = msg_row;	/* will put it back later */
4632     }
4633 
4634     if (xp->xp_numfiles == -1)
4635 	FreeWild(num_files, files_found);
4636 
4637     return EXPAND_OK;
4638 }
4639 
4640 /*
4641  * Private gettail for showmatches() (and win_redr_status_matches()):
4642  * Find tail of file name path, but ignore trailing "/".
4643  */
4644     char_u *
4645 sm_gettail(char_u *s)
4646 {
4647     char_u	*p;
4648     char_u	*t = s;
4649     int		had_sep = FALSE;
4650 
4651     for (p = s; *p != NUL; )
4652     {
4653 	if (vim_ispathsep(*p)
4654 #ifdef BACKSLASH_IN_FILENAME
4655 		&& !rem_backslash(p)
4656 #endif
4657 	   )
4658 	    had_sep = TRUE;
4659 	else if (had_sep)
4660 	{
4661 	    t = p;
4662 	    had_sep = FALSE;
4663 	}
4664 	MB_PTR_ADV(p);
4665     }
4666     return t;
4667 }
4668 
4669 /*
4670  * Return TRUE if we only need to show the tail of completion matches.
4671  * When not completing file names or there is a wildcard in the path FALSE is
4672  * returned.
4673  */
4674     static int
4675 expand_showtail(expand_T *xp)
4676 {
4677     char_u	*s;
4678     char_u	*end;
4679 
4680     /* When not completing file names a "/" may mean something different. */
4681     if (xp->xp_context != EXPAND_FILES
4682 	    && xp->xp_context != EXPAND_SHELLCMD
4683 	    && xp->xp_context != EXPAND_DIRECTORIES)
4684 	return FALSE;
4685 
4686     end = gettail(xp->xp_pattern);
4687     if (end == xp->xp_pattern)		/* there is no path separator */
4688 	return FALSE;
4689 
4690     for (s = xp->xp_pattern; s < end; s++)
4691     {
4692 	/* Skip escaped wildcards.  Only when the backslash is not a path
4693 	 * separator, on DOS the '*' "path\*\file" must not be skipped. */
4694 	if (rem_backslash(s))
4695 	    ++s;
4696 	else if (vim_strchr((char_u *)"*?[", *s) != NULL)
4697 	    return FALSE;
4698     }
4699     return TRUE;
4700 }
4701 
4702 /*
4703  * Prepare a string for expansion.
4704  * When expanding file names: The string will be used with expand_wildcards().
4705  * Copy "fname[len]" into allocated memory and add a '*' at the end.
4706  * When expanding other names: The string will be used with regcomp().  Copy
4707  * the name into allocated memory and prepend "^".
4708  */
4709     char_u *
4710 addstar(
4711     char_u	*fname,
4712     int		len,
4713     int		context)	/* EXPAND_FILES etc. */
4714 {
4715     char_u	*retval;
4716     int		i, j;
4717     int		new_len;
4718     char_u	*tail;
4719     int		ends_in_star;
4720 
4721     if (context != EXPAND_FILES
4722 	    && context != EXPAND_FILES_IN_PATH
4723 	    && context != EXPAND_SHELLCMD
4724 	    && context != EXPAND_DIRECTORIES)
4725     {
4726 	/*
4727 	 * Matching will be done internally (on something other than files).
4728 	 * So we convert the file-matching-type wildcards into our kind for
4729 	 * use with vim_regcomp().  First work out how long it will be:
4730 	 */
4731 
4732 	/* For help tags the translation is done in find_help_tags().
4733 	 * For a tag pattern starting with "/" no translation is needed. */
4734 	if (context == EXPAND_HELP
4735 		|| context == EXPAND_COLORS
4736 		|| context == EXPAND_COMPILER
4737 		|| context == EXPAND_OWNSYNTAX
4738 		|| context == EXPAND_FILETYPE
4739 		|| context == EXPAND_PACKADD
4740 		|| ((context == EXPAND_TAGS_LISTFILES
4741 			|| context == EXPAND_TAGS)
4742 		    && fname[0] == '/'))
4743 	    retval = vim_strnsave(fname, len);
4744 	else
4745 	{
4746 	    new_len = len + 2;		/* +2 for '^' at start, NUL at end */
4747 	    for (i = 0; i < len; i++)
4748 	    {
4749 		if (fname[i] == '*' || fname[i] == '~')
4750 		    new_len++;		/* '*' needs to be replaced by ".*"
4751 					   '~' needs to be replaced by "\~" */
4752 
4753 		/* Buffer names are like file names.  "." should be literal */
4754 		if (context == EXPAND_BUFFERS && fname[i] == '.')
4755 		    new_len++;		/* "." becomes "\." */
4756 
4757 		/* Custom expansion takes care of special things, match
4758 		 * backslashes literally (perhaps also for other types?) */
4759 		if ((context == EXPAND_USER_DEFINED
4760 			  || context == EXPAND_USER_LIST) && fname[i] == '\\')
4761 		    new_len++;		/* '\' becomes "\\" */
4762 	    }
4763 	    retval = alloc(new_len);
4764 	    if (retval != NULL)
4765 	    {
4766 		retval[0] = '^';
4767 		j = 1;
4768 		for (i = 0; i < len; i++, j++)
4769 		{
4770 		    /* Skip backslash.  But why?  At least keep it for custom
4771 		     * expansion. */
4772 		    if (context != EXPAND_USER_DEFINED
4773 			    && context != EXPAND_USER_LIST
4774 			    && fname[i] == '\\'
4775 			    && ++i == len)
4776 			break;
4777 
4778 		    switch (fname[i])
4779 		    {
4780 			case '*':   retval[j++] = '.';
4781 				    break;
4782 			case '~':   retval[j++] = '\\';
4783 				    break;
4784 			case '?':   retval[j] = '.';
4785 				    continue;
4786 			case '.':   if (context == EXPAND_BUFFERS)
4787 					retval[j++] = '\\';
4788 				    break;
4789 			case '\\':  if (context == EXPAND_USER_DEFINED
4790 					    || context == EXPAND_USER_LIST)
4791 					retval[j++] = '\\';
4792 				    break;
4793 		    }
4794 		    retval[j] = fname[i];
4795 		}
4796 		retval[j] = NUL;
4797 	    }
4798 	}
4799     }
4800     else
4801     {
4802 	retval = alloc(len + 4);
4803 	if (retval != NULL)
4804 	{
4805 	    vim_strncpy(retval, fname, len);
4806 
4807 	    /*
4808 	     * Don't add a star to *, ~, ~user, $var or `cmd`.
4809 	     * * would become **, which walks the whole tree.
4810 	     * ~ would be at the start of the file name, but not the tail.
4811 	     * $ could be anywhere in the tail.
4812 	     * ` could be anywhere in the file name.
4813 	     * When the name ends in '$' don't add a star, remove the '$'.
4814 	     */
4815 	    tail = gettail(retval);
4816 	    ends_in_star = (len > 0 && retval[len - 1] == '*');
4817 #ifndef BACKSLASH_IN_FILENAME
4818 	    for (i = len - 2; i >= 0; --i)
4819 	    {
4820 		if (retval[i] != '\\')
4821 		    break;
4822 		ends_in_star = !ends_in_star;
4823 	    }
4824 #endif
4825 	    if ((*retval != '~' || tail != retval)
4826 		    && !ends_in_star
4827 		    && vim_strchr(tail, '$') == NULL
4828 		    && vim_strchr(retval, '`') == NULL)
4829 		retval[len++] = '*';
4830 	    else if (len > 0 && retval[len - 1] == '$')
4831 		--len;
4832 	    retval[len] = NUL;
4833 	}
4834     }
4835     return retval;
4836 }
4837 
4838 /*
4839  * Must parse the command line so far to work out what context we are in.
4840  * Completion can then be done based on that context.
4841  * This routine sets the variables:
4842  *  xp->xp_pattern	    The start of the pattern to be expanded within
4843  *				the command line (ends at the cursor).
4844  *  xp->xp_context	    The type of thing to expand.  Will be one of:
4845  *
4846  *  EXPAND_UNSUCCESSFUL	    Used sometimes when there is something illegal on
4847  *			    the command line, like an unknown command.	Caller
4848  *			    should beep.
4849  *  EXPAND_NOTHING	    Unrecognised context for completion, use char like
4850  *			    a normal char, rather than for completion.	eg
4851  *			    :s/^I/
4852  *  EXPAND_COMMANDS	    Cursor is still touching the command, so complete
4853  *			    it.
4854  *  EXPAND_BUFFERS	    Complete file names for :buf and :sbuf commands.
4855  *  EXPAND_FILES	    After command with XFILE set, or after setting
4856  *			    with P_EXPAND set.	eg :e ^I, :w>>^I
4857  *  EXPAND_DIRECTORIES	    In some cases this is used instead of the latter
4858  *			    when we know only directories are of interest.  eg
4859  *			    :set dir=^I
4860  *  EXPAND_SHELLCMD	    After ":!cmd", ":r !cmd"  or ":w !cmd".
4861  *  EXPAND_SETTINGS	    Complete variable names.  eg :set d^I
4862  *  EXPAND_BOOL_SETTINGS    Complete boolean variables only,  eg :set no^I
4863  *  EXPAND_TAGS		    Complete tags from the files in p_tags.  eg :ta a^I
4864  *  EXPAND_TAGS_LISTFILES   As above, but list filenames on ^D, after :tselect
4865  *  EXPAND_HELP		    Complete tags from the file 'helpfile'/tags
4866  *  EXPAND_EVENTS	    Complete event names
4867  *  EXPAND_SYNTAX	    Complete :syntax command arguments
4868  *  EXPAND_HIGHLIGHT	    Complete highlight (syntax) group names
4869  *  EXPAND_AUGROUP	    Complete autocommand group names
4870  *  EXPAND_USER_VARS	    Complete user defined variable names, eg :unlet a^I
4871  *  EXPAND_MAPPINGS	    Complete mapping and abbreviation names,
4872  *			      eg :unmap a^I , :cunab x^I
4873  *  EXPAND_FUNCTIONS	    Complete internal or user defined function names,
4874  *			      eg :call sub^I
4875  *  EXPAND_USER_FUNC	    Complete user defined function names, eg :delf F^I
4876  *  EXPAND_EXPRESSION	    Complete internal or user defined function/variable
4877  *			    names in expressions, eg :while s^I
4878  *  EXPAND_ENV_VARS	    Complete environment variable names
4879  *  EXPAND_USER		    Complete user names
4880  */
4881     static void
4882 set_expand_context(expand_T *xp)
4883 {
4884     /* only expansion for ':', '>' and '=' command-lines */
4885     if (ccline.cmdfirstc != ':'
4886 #ifdef FEAT_EVAL
4887 	    && ccline.cmdfirstc != '>' && ccline.cmdfirstc != '='
4888 	    && !ccline.input_fn
4889 #endif
4890 	    )
4891     {
4892 	xp->xp_context = EXPAND_NOTHING;
4893 	return;
4894     }
4895     set_cmd_context(xp, ccline.cmdbuff, ccline.cmdlen, ccline.cmdpos, TRUE);
4896 }
4897 
4898     void
4899 set_cmd_context(
4900     expand_T	*xp,
4901     char_u	*str,	    /* start of command line */
4902     int		len,	    /* length of command line (excl. NUL) */
4903     int		col,	    /* position of cursor */
4904     int		use_ccline UNUSED) /* use ccline for info */
4905 {
4906     int		old_char = NUL;
4907     char_u	*nextcomm;
4908 
4909     /*
4910      * Avoid a UMR warning from Purify, only save the character if it has been
4911      * written before.
4912      */
4913     if (col < len)
4914 	old_char = str[col];
4915     str[col] = NUL;
4916     nextcomm = str;
4917 
4918 #ifdef FEAT_EVAL
4919     if (use_ccline && ccline.cmdfirstc == '=')
4920     {
4921 # ifdef FEAT_CMDL_COMPL
4922 	/* pass CMD_SIZE because there is no real command */
4923 	set_context_for_expression(xp, str, CMD_SIZE);
4924 # endif
4925     }
4926     else if (use_ccline && ccline.input_fn)
4927     {
4928 	xp->xp_context = ccline.xp_context;
4929 	xp->xp_pattern = ccline.cmdbuff;
4930 # if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)
4931 	xp->xp_arg = ccline.xp_arg;
4932 # endif
4933     }
4934     else
4935 #endif
4936 	while (nextcomm != NULL)
4937 	    nextcomm = set_one_cmd_context(xp, nextcomm);
4938 
4939     /* Store the string here so that call_user_expand_func() can get to them
4940      * easily. */
4941     xp->xp_line = str;
4942     xp->xp_col = col;
4943 
4944     str[col] = old_char;
4945 }
4946 
4947 /*
4948  * Expand the command line "str" from context "xp".
4949  * "xp" must have been set by set_cmd_context().
4950  * xp->xp_pattern points into "str", to where the text that is to be expanded
4951  * starts.
4952  * Returns EXPAND_UNSUCCESSFUL when there is something illegal before the
4953  * cursor.
4954  * Returns EXPAND_NOTHING when there is nothing to expand, might insert the
4955  * key that triggered expansion literally.
4956  * Returns EXPAND_OK otherwise.
4957  */
4958     int
4959 expand_cmdline(
4960     expand_T	*xp,
4961     char_u	*str,		/* start of command line */
4962     int		col,		/* position of cursor */
4963     int		*matchcount,	/* return: nr of matches */
4964     char_u	***matches)	/* return: array of pointers to matches */
4965 {
4966     char_u	*file_str = NULL;
4967     int		options = WILD_ADD_SLASH|WILD_SILENT;
4968 
4969     if (xp->xp_context == EXPAND_UNSUCCESSFUL)
4970     {
4971 	beep_flush();
4972 	return EXPAND_UNSUCCESSFUL;  /* Something illegal on command line */
4973     }
4974     if (xp->xp_context == EXPAND_NOTHING)
4975     {
4976 	/* Caller can use the character as a normal char instead */
4977 	return EXPAND_NOTHING;
4978     }
4979 
4980     /* add star to file name, or convert to regexp if not exp. files. */
4981     xp->xp_pattern_len = (int)(str + col - xp->xp_pattern);
4982     file_str = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
4983     if (file_str == NULL)
4984 	return EXPAND_UNSUCCESSFUL;
4985 
4986     if (p_wic)
4987 	options += WILD_ICASE;
4988 
4989     /* find all files that match the description */
4990     if (ExpandFromContext(xp, file_str, matchcount, matches, options) == FAIL)
4991     {
4992 	*matchcount = 0;
4993 	*matches = NULL;
4994     }
4995     vim_free(file_str);
4996 
4997     return EXPAND_OK;
4998 }
4999 
5000 #ifdef FEAT_MULTI_LANG
5001 /*
5002  * Cleanup matches for help tags:
5003  * Remove "@ab" if the top of 'helplang' is "ab" and the language of the first
5004  * tag matches it.  Otherwise remove "@en" if "en" is the only language.
5005  */
5006     static void
5007 cleanup_help_tags(int num_file, char_u **file)
5008 {
5009     int		i, j;
5010     int		len;
5011     char_u	buf[4];
5012     char_u	*p = buf;
5013 
5014     if (p_hlg[0] != NUL && (p_hlg[0] != 'e' || p_hlg[1] != 'n'))
5015     {
5016 	*p++ = '@';
5017 	*p++ = p_hlg[0];
5018 	*p++ = p_hlg[1];
5019     }
5020     *p = NUL;
5021 
5022     for (i = 0; i < num_file; ++i)
5023     {
5024 	len = (int)STRLEN(file[i]) - 3;
5025 	if (len <= 0)
5026 	    continue;
5027 	if (STRCMP(file[i] + len, "@en") == 0)
5028 	{
5029 	    /* Sorting on priority means the same item in another language may
5030 	     * be anywhere.  Search all items for a match up to the "@en". */
5031 	    for (j = 0; j < num_file; ++j)
5032 		if (j != i && (int)STRLEN(file[j]) == len + 3
5033 			   && STRNCMP(file[i], file[j], len + 1) == 0)
5034 		    break;
5035 	    if (j == num_file)
5036 		/* item only exists with @en, remove it */
5037 		file[i][len] = NUL;
5038 	}
5039     }
5040 
5041     if (*buf != NUL)
5042 	for (i = 0; i < num_file; ++i)
5043 	{
5044 	    len = (int)STRLEN(file[i]) - 3;
5045 	    if (len <= 0)
5046 		continue;
5047 	    if (STRCMP(file[i] + len, buf) == 0)
5048 	    {
5049 		/* remove the default language */
5050 		file[i][len] = NUL;
5051 	    }
5052 	}
5053 }
5054 #endif
5055 
5056 /*
5057  * Do the expansion based on xp->xp_context and "pat".
5058  */
5059     static int
5060 ExpandFromContext(
5061     expand_T	*xp,
5062     char_u	*pat,
5063     int		*num_file,
5064     char_u	***file,
5065     int		options)  /* EW_ flags */
5066 {
5067 #ifdef FEAT_CMDL_COMPL
5068     regmatch_T	regmatch;
5069 #endif
5070     int		ret;
5071     int		flags;
5072 
5073     flags = EW_DIR;	/* include directories */
5074     if (options & WILD_LIST_NOTFOUND)
5075 	flags |= EW_NOTFOUND;
5076     if (options & WILD_ADD_SLASH)
5077 	flags |= EW_ADDSLASH;
5078     if (options & WILD_KEEP_ALL)
5079 	flags |= EW_KEEPALL;
5080     if (options & WILD_SILENT)
5081 	flags |= EW_SILENT;
5082     if (options & WILD_ALLLINKS)
5083 	flags |= EW_ALLLINKS;
5084 
5085     if (xp->xp_context == EXPAND_FILES
5086 	    || xp->xp_context == EXPAND_DIRECTORIES
5087 	    || xp->xp_context == EXPAND_FILES_IN_PATH)
5088     {
5089 	/*
5090 	 * Expand file or directory names.
5091 	 */
5092 	int	free_pat = FALSE;
5093 	int	i;
5094 
5095 	/* for ":set path=" and ":set tags=" halve backslashes for escaped
5096 	 * space */
5097 	if (xp->xp_backslash != XP_BS_NONE)
5098 	{
5099 	    free_pat = TRUE;
5100 	    pat = vim_strsave(pat);
5101 	    for (i = 0; pat[i]; ++i)
5102 		if (pat[i] == '\\')
5103 		{
5104 		    if (xp->xp_backslash == XP_BS_THREE
5105 			    && pat[i + 1] == '\\'
5106 			    && pat[i + 2] == '\\'
5107 			    && pat[i + 3] == ' ')
5108 			STRMOVE(pat + i, pat + i + 3);
5109 		    if (xp->xp_backslash == XP_BS_ONE
5110 			    && pat[i + 1] == ' ')
5111 			STRMOVE(pat + i, pat + i + 1);
5112 		}
5113 	}
5114 
5115 	if (xp->xp_context == EXPAND_FILES)
5116 	    flags |= EW_FILE;
5117 	else if (xp->xp_context == EXPAND_FILES_IN_PATH)
5118 	    flags |= (EW_FILE | EW_PATH);
5119 	else
5120 	    flags = (flags | EW_DIR) & ~EW_FILE;
5121 	if (options & WILD_ICASE)
5122 	    flags |= EW_ICASE;
5123 
5124 	/* Expand wildcards, supporting %:h and the like. */
5125 	ret = expand_wildcards_eval(&pat, num_file, file, flags);
5126 	if (free_pat)
5127 	    vim_free(pat);
5128 	return ret;
5129     }
5130 
5131     *file = (char_u **)"";
5132     *num_file = 0;
5133     if (xp->xp_context == EXPAND_HELP)
5134     {
5135 	/* With an empty argument we would get all the help tags, which is
5136 	 * very slow.  Get matches for "help" instead. */
5137 	if (find_help_tags(*pat == NUL ? (char_u *)"help" : pat,
5138 						 num_file, file, FALSE) == OK)
5139 	{
5140 #ifdef FEAT_MULTI_LANG
5141 	    cleanup_help_tags(*num_file, *file);
5142 #endif
5143 	    return OK;
5144 	}
5145 	return FAIL;
5146     }
5147 
5148 #ifndef FEAT_CMDL_COMPL
5149     return FAIL;
5150 #else
5151     if (xp->xp_context == EXPAND_SHELLCMD)
5152 	return expand_shellcmd(pat, num_file, file, flags);
5153     if (xp->xp_context == EXPAND_OLD_SETTING)
5154 	return ExpandOldSetting(num_file, file);
5155     if (xp->xp_context == EXPAND_BUFFERS)
5156 	return ExpandBufnames(pat, num_file, file, options);
5157     if (xp->xp_context == EXPAND_TAGS
5158 	    || xp->xp_context == EXPAND_TAGS_LISTFILES)
5159 	return expand_tags(xp->xp_context == EXPAND_TAGS, pat, num_file, file);
5160     if (xp->xp_context == EXPAND_COLORS)
5161     {
5162 	char *directories[] = {"colors", NULL};
5163 	return ExpandRTDir(pat, DIP_START + DIP_OPT, num_file, file,
5164 								directories);
5165     }
5166     if (xp->xp_context == EXPAND_COMPILER)
5167     {
5168 	char *directories[] = {"compiler", NULL};
5169 	return ExpandRTDir(pat, 0, num_file, file, directories);
5170     }
5171     if (xp->xp_context == EXPAND_OWNSYNTAX)
5172     {
5173 	char *directories[] = {"syntax", NULL};
5174 	return ExpandRTDir(pat, 0, num_file, file, directories);
5175     }
5176     if (xp->xp_context == EXPAND_FILETYPE)
5177     {
5178 	char *directories[] = {"syntax", "indent", "ftplugin", NULL};
5179 	return ExpandRTDir(pat, 0, num_file, file, directories);
5180     }
5181 # if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
5182     if (xp->xp_context == EXPAND_USER_LIST)
5183 	return ExpandUserList(xp, num_file, file);
5184 # endif
5185     if (xp->xp_context == EXPAND_PACKADD)
5186 	return ExpandPackAddDir(pat, num_file, file);
5187 
5188     regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0);
5189     if (regmatch.regprog == NULL)
5190 	return FAIL;
5191 
5192     /* set ignore-case according to p_ic, p_scs and pat */
5193     regmatch.rm_ic = ignorecase(pat);
5194 
5195     if (xp->xp_context == EXPAND_SETTINGS
5196 	    || xp->xp_context == EXPAND_BOOL_SETTINGS)
5197 	ret = ExpandSettings(xp, &regmatch, num_file, file);
5198     else if (xp->xp_context == EXPAND_MAPPINGS)
5199 	ret = ExpandMappings(&regmatch, num_file, file);
5200 # if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
5201     else if (xp->xp_context == EXPAND_USER_DEFINED)
5202 	ret = ExpandUserDefined(xp, &regmatch, num_file, file);
5203 # endif
5204     else
5205     {
5206 	static struct expgen
5207 	{
5208 	    int		context;
5209 	    char_u	*((*func)(expand_T *, int));
5210 	    int		ic;
5211 	    int		escaped;
5212 	} tab[] =
5213 	{
5214 	    {EXPAND_COMMANDS, get_command_name, FALSE, TRUE},
5215 	    {EXPAND_BEHAVE, get_behave_arg, TRUE, TRUE},
5216 	    {EXPAND_MAPCLEAR, get_mapclear_arg, TRUE, TRUE},
5217 	    {EXPAND_MESSAGES, get_messages_arg, TRUE, TRUE},
5218 #ifdef FEAT_CMDHIST
5219 	    {EXPAND_HISTORY, get_history_arg, TRUE, TRUE},
5220 #endif
5221 #ifdef FEAT_USR_CMDS
5222 	    {EXPAND_USER_COMMANDS, get_user_commands, FALSE, TRUE},
5223 	    {EXPAND_USER_ADDR_TYPE, get_user_cmd_addr_type, FALSE, TRUE},
5224 	    {EXPAND_USER_CMD_FLAGS, get_user_cmd_flags, FALSE, TRUE},
5225 	    {EXPAND_USER_NARGS, get_user_cmd_nargs, FALSE, TRUE},
5226 	    {EXPAND_USER_COMPLETE, get_user_cmd_complete, FALSE, TRUE},
5227 #endif
5228 #ifdef FEAT_EVAL
5229 	    {EXPAND_USER_VARS, get_user_var_name, FALSE, TRUE},
5230 	    {EXPAND_FUNCTIONS, get_function_name, FALSE, TRUE},
5231 	    {EXPAND_USER_FUNC, get_user_func_name, FALSE, TRUE},
5232 	    {EXPAND_EXPRESSION, get_expr_name, FALSE, TRUE},
5233 #endif
5234 #ifdef FEAT_MENU
5235 	    {EXPAND_MENUS, get_menu_name, FALSE, TRUE},
5236 	    {EXPAND_MENUNAMES, get_menu_names, FALSE, TRUE},
5237 #endif
5238 #ifdef FEAT_SYN_HL
5239 	    {EXPAND_SYNTAX, get_syntax_name, TRUE, TRUE},
5240 #endif
5241 #ifdef FEAT_PROFILE
5242 	    {EXPAND_SYNTIME, get_syntime_arg, TRUE, TRUE},
5243 #endif
5244 	    {EXPAND_HIGHLIGHT, get_highlight_name, TRUE, TRUE},
5245 	    {EXPAND_EVENTS, get_event_name, TRUE, TRUE},
5246 	    {EXPAND_AUGROUP, get_augroup_name, TRUE, TRUE},
5247 #ifdef FEAT_CSCOPE
5248 	    {EXPAND_CSCOPE, get_cscope_name, TRUE, TRUE},
5249 #endif
5250 #ifdef FEAT_SIGNS
5251 	    {EXPAND_SIGN, get_sign_name, TRUE, TRUE},
5252 #endif
5253 #ifdef FEAT_PROFILE
5254 	    {EXPAND_PROFILE, get_profile_name, TRUE, TRUE},
5255 #endif
5256 #if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
5257 	    {EXPAND_LANGUAGE, get_lang_arg, TRUE, FALSE},
5258 	    {EXPAND_LOCALES, get_locales, TRUE, FALSE},
5259 #endif
5260 	    {EXPAND_ENV_VARS, get_env_name, TRUE, TRUE},
5261 	    {EXPAND_USER, get_users, TRUE, FALSE},
5262 	    {EXPAND_ARGLIST, get_arglist_name, TRUE, FALSE},
5263 	};
5264 	int	i;
5265 
5266 	/*
5267 	 * Find a context in the table and call the ExpandGeneric() with the
5268 	 * right function to do the expansion.
5269 	 */
5270 	ret = FAIL;
5271 	for (i = 0; i < (int)(sizeof(tab) / sizeof(struct expgen)); ++i)
5272 	    if (xp->xp_context == tab[i].context)
5273 	    {
5274 		if (tab[i].ic)
5275 		    regmatch.rm_ic = TRUE;
5276 		ret = ExpandGeneric(xp, &regmatch, num_file, file,
5277 						tab[i].func, tab[i].escaped);
5278 		break;
5279 	    }
5280     }
5281 
5282     vim_regfree(regmatch.regprog);
5283 
5284     return ret;
5285 #endif /* FEAT_CMDL_COMPL */
5286 }
5287 
5288 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
5289 /*
5290  * Expand a list of names.
5291  *
5292  * Generic function for command line completion.  It calls a function to
5293  * obtain strings, one by one.	The strings are matched against a regexp
5294  * program.  Matching strings are copied into an array, which is returned.
5295  *
5296  * Returns OK when no problems encountered, FAIL for error (out of memory).
5297  */
5298     int
5299 ExpandGeneric(
5300     expand_T	*xp,
5301     regmatch_T	*regmatch,
5302     int		*num_file,
5303     char_u	***file,
5304     char_u	*((*func)(expand_T *, int)),
5305 					  /* returns a string from the list */
5306     int		escaped)
5307 {
5308     int		i;
5309     int		count = 0;
5310     int		round;
5311     char_u	*str;
5312 
5313     /* do this loop twice:
5314      * round == 0: count the number of matching names
5315      * round == 1: copy the matching names into allocated memory
5316      */
5317     for (round = 0; round <= 1; ++round)
5318     {
5319 	for (i = 0; ; ++i)
5320 	{
5321 	    str = (*func)(xp, i);
5322 	    if (str == NULL)	    /* end of list */
5323 		break;
5324 	    if (*str == NUL)	    /* skip empty strings */
5325 		continue;
5326 
5327 	    if (vim_regexec(regmatch, str, (colnr_T)0))
5328 	    {
5329 		if (round)
5330 		{
5331 		    if (escaped)
5332 			str = vim_strsave_escaped(str, (char_u *)" \t\\.");
5333 		    else
5334 			str = vim_strsave(str);
5335 		    (*file)[count] = str;
5336 #ifdef FEAT_MENU
5337 		    if (func == get_menu_names && str != NULL)
5338 		    {
5339 			/* test for separator added by get_menu_names() */
5340 			str += STRLEN(str) - 1;
5341 			if (*str == '\001')
5342 			    *str = '.';
5343 		    }
5344 #endif
5345 		}
5346 		++count;
5347 	    }
5348 	}
5349 	if (round == 0)
5350 	{
5351 	    if (count == 0)
5352 		return OK;
5353 	    *num_file = count;
5354 	    *file = (char_u **)alloc((unsigned)(count * sizeof(char_u *)));
5355 	    if (*file == NULL)
5356 	    {
5357 		*file = (char_u **)"";
5358 		return FAIL;
5359 	    }
5360 	    count = 0;
5361 	}
5362     }
5363 
5364     /* Sort the results.  Keep menu's in the specified order. */
5365     if (xp->xp_context != EXPAND_MENUNAMES && xp->xp_context != EXPAND_MENUS)
5366     {
5367 	if (xp->xp_context == EXPAND_EXPRESSION
5368 		|| xp->xp_context == EXPAND_FUNCTIONS
5369 		|| xp->xp_context == EXPAND_USER_FUNC)
5370 	    /* <SNR> functions should be sorted to the end. */
5371 	    qsort((void *)*file, (size_t)*num_file, sizeof(char_u *),
5372 							   sort_func_compare);
5373 	else
5374 	    sort_strings(*file, *num_file);
5375     }
5376 
5377 #ifdef FEAT_CMDL_COMPL
5378     /* Reset the variables used for special highlight names expansion, so that
5379      * they don't show up when getting normal highlight names by ID. */
5380     reset_expand_highlight();
5381 #endif
5382 
5383     return OK;
5384 }
5385 
5386 /*
5387  * Complete a shell command.
5388  * Returns FAIL or OK;
5389  */
5390     static int
5391 expand_shellcmd(
5392     char_u	*filepat,	/* pattern to match with command names */
5393     int		*num_file,	/* return: number of matches */
5394     char_u	***file,	/* return: array with matches */
5395     int		flagsarg)	/* EW_ flags */
5396 {
5397     char_u	*pat;
5398     int		i;
5399     char_u	*path = NULL;
5400     int		mustfree = FALSE;
5401     garray_T    ga;
5402     char_u	*buf = alloc(MAXPATHL);
5403     size_t	l;
5404     char_u	*s, *e;
5405     int		flags = flagsarg;
5406     int		ret;
5407     int		did_curdir = FALSE;
5408     hashtab_T	found_ht;
5409     hashitem_T	*hi;
5410     hash_T	hash;
5411 
5412     if (buf == NULL)
5413 	return FAIL;
5414 
5415     /* for ":set path=" and ":set tags=" halve backslashes for escaped
5416      * space */
5417     pat = vim_strsave(filepat);
5418     for (i = 0; pat[i]; ++i)
5419 	if (pat[i] == '\\' && pat[i + 1] == ' ')
5420 	    STRMOVE(pat + i, pat + i + 1);
5421 
5422     flags |= EW_FILE | EW_EXEC | EW_SHELLCMD;
5423 
5424     if (pat[0] == '.' && (vim_ispathsep(pat[1])
5425 			       || (pat[1] == '.' && vim_ispathsep(pat[2]))))
5426 	path = (char_u *)".";
5427     else
5428     {
5429 	/* For an absolute name we don't use $PATH. */
5430 	if (!mch_isFullName(pat))
5431 	    path = vim_getenv((char_u *)"PATH", &mustfree);
5432 	if (path == NULL)
5433 	    path = (char_u *)"";
5434     }
5435 
5436     /*
5437      * Go over all directories in $PATH.  Expand matches in that directory and
5438      * collect them in "ga".  When "." is not in $PATH also expand for the
5439      * current directory, to find "subdir/cmd".
5440      */
5441     ga_init2(&ga, (int)sizeof(char *), 10);
5442     hash_init(&found_ht);
5443     for (s = path; ; s = e)
5444     {
5445 #if defined(MSWIN)
5446 	e = vim_strchr(s, ';');
5447 #else
5448 	e = vim_strchr(s, ':');
5449 #endif
5450 	if (e == NULL)
5451 	    e = s + STRLEN(s);
5452 
5453 	if (*s == NUL)
5454 	{
5455 	    if (did_curdir)
5456 		break;
5457 	    // Find directories in the current directory, path is empty.
5458 	    did_curdir = TRUE;
5459 	    flags |= EW_DIR;
5460 	}
5461 	else if (STRNCMP(s, ".", (int)(e - s)) == 0)
5462 	{
5463 	    did_curdir = TRUE;
5464 	    flags |= EW_DIR;
5465 	}
5466 	else
5467 	    // Do not match directories inside a $PATH item.
5468 	    flags &= ~EW_DIR;
5469 
5470 	l = e - s;
5471 	if (l > MAXPATHL - 5)
5472 	    break;
5473 	vim_strncpy(buf, s, l);
5474 	add_pathsep(buf);
5475 	l = STRLEN(buf);
5476 	vim_strncpy(buf + l, pat, MAXPATHL - 1 - l);
5477 
5478 	/* Expand matches in one directory of $PATH. */
5479 	ret = expand_wildcards(1, &buf, num_file, file, flags);
5480 	if (ret == OK)
5481 	{
5482 	    if (ga_grow(&ga, *num_file) == FAIL)
5483 		FreeWild(*num_file, *file);
5484 	    else
5485 	    {
5486 		for (i = 0; i < *num_file; ++i)
5487 		{
5488 		    char_u *name = (*file)[i];
5489 
5490 		    if (STRLEN(name) > l)
5491 		    {
5492 			// Check if this name was already found.
5493 			hash = hash_hash(name + l);
5494 			hi = hash_lookup(&found_ht, name + l, hash);
5495 			if (HASHITEM_EMPTY(hi))
5496 			{
5497 			    // Remove the path that was prepended.
5498 			    STRMOVE(name, name + l);
5499 			    ((char_u **)ga.ga_data)[ga.ga_len++] = name;
5500 			    hash_add_item(&found_ht, hi, name, hash);
5501 			    name = NULL;
5502 			}
5503 		    }
5504 		    vim_free(name);
5505 		}
5506 		vim_free(*file);
5507 	    }
5508 	}
5509 	if (*e != NUL)
5510 	    ++e;
5511     }
5512     *file = ga.ga_data;
5513     *num_file = ga.ga_len;
5514 
5515     vim_free(buf);
5516     vim_free(pat);
5517     if (mustfree)
5518 	vim_free(path);
5519     hash_clear(&found_ht);
5520     return OK;
5521 }
5522 
5523 
5524 # if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
5525 /*
5526  * Call "user_expand_func()" to invoke a user defined Vim script function and
5527  * return the result (either a string or a List).
5528  */
5529     static void *
5530 call_user_expand_func(
5531     void	*(*user_expand_func)(char_u *, int, typval_T *),
5532     expand_T	*xp,
5533     int		*num_file,
5534     char_u	***file)
5535 {
5536     int		keep = 0;
5537     typval_T	args[4];
5538     sctx_T	save_current_sctx = current_sctx;
5539     char_u	*pat = NULL;
5540     void	*ret;
5541 
5542     if (xp->xp_arg == NULL || xp->xp_arg[0] == '\0' || xp->xp_line == NULL)
5543 	return NULL;
5544     *num_file = 0;
5545     *file = NULL;
5546 
5547     if (ccline.cmdbuff != NULL)
5548     {
5549 	keep = ccline.cmdbuff[ccline.cmdlen];
5550 	ccline.cmdbuff[ccline.cmdlen] = 0;
5551     }
5552 
5553     pat = vim_strnsave(xp->xp_pattern, xp->xp_pattern_len);
5554 
5555     args[0].v_type = VAR_STRING;
5556     args[0].vval.v_string = pat;
5557     args[1].v_type = VAR_STRING;
5558     args[1].vval.v_string = xp->xp_line;
5559     args[2].v_type = VAR_NUMBER;
5560     args[2].vval.v_number = xp->xp_col;
5561     args[3].v_type = VAR_UNKNOWN;
5562 
5563     current_sctx = xp->xp_script_ctx;
5564 
5565     ret = user_expand_func(xp->xp_arg, 3, args);
5566 
5567     current_sctx = save_current_sctx;
5568     if (ccline.cmdbuff != NULL)
5569 	ccline.cmdbuff[ccline.cmdlen] = keep;
5570 
5571     vim_free(pat);
5572     return ret;
5573 }
5574 
5575 /*
5576  * Expand names with a function defined by the user.
5577  */
5578     static int
5579 ExpandUserDefined(
5580     expand_T	*xp,
5581     regmatch_T	*regmatch,
5582     int		*num_file,
5583     char_u	***file)
5584 {
5585     char_u	*retstr;
5586     char_u	*s;
5587     char_u	*e;
5588     int		keep;
5589     garray_T	ga;
5590     int		skip;
5591 
5592     retstr = call_user_expand_func(call_func_retstr, xp, num_file, file);
5593     if (retstr == NULL)
5594 	return FAIL;
5595 
5596     ga_init2(&ga, (int)sizeof(char *), 3);
5597     for (s = retstr; *s != NUL; s = e)
5598     {
5599 	e = vim_strchr(s, '\n');
5600 	if (e == NULL)
5601 	    e = s + STRLEN(s);
5602 	keep = *e;
5603 	*e = NUL;
5604 
5605 	skip = xp->xp_pattern[0] && vim_regexec(regmatch, s, (colnr_T)0) == 0;
5606 	*e = keep;
5607 
5608 	if (!skip)
5609 	{
5610 	    if (ga_grow(&ga, 1) == FAIL)
5611 		break;
5612 	    ((char_u **)ga.ga_data)[ga.ga_len] = vim_strnsave(s, (int)(e - s));
5613 	    ++ga.ga_len;
5614 	}
5615 
5616 	if (*e != NUL)
5617 	    ++e;
5618     }
5619     vim_free(retstr);
5620     *file = ga.ga_data;
5621     *num_file = ga.ga_len;
5622     return OK;
5623 }
5624 
5625 /*
5626  * Expand names with a list returned by a function defined by the user.
5627  */
5628     static int
5629 ExpandUserList(
5630     expand_T	*xp,
5631     int		*num_file,
5632     char_u	***file)
5633 {
5634     list_T      *retlist;
5635     listitem_T	*li;
5636     garray_T	ga;
5637 
5638     retlist = call_user_expand_func(call_func_retlist, xp, num_file, file);
5639     if (retlist == NULL)
5640 	return FAIL;
5641 
5642     ga_init2(&ga, (int)sizeof(char *), 3);
5643     /* Loop over the items in the list. */
5644     for (li = retlist->lv_first; li != NULL; li = li->li_next)
5645     {
5646 	if (li->li_tv.v_type != VAR_STRING || li->li_tv.vval.v_string == NULL)
5647 	    continue;  /* Skip non-string items and empty strings */
5648 
5649 	if (ga_grow(&ga, 1) == FAIL)
5650 	    break;
5651 
5652 	((char_u **)ga.ga_data)[ga.ga_len] =
5653 					 vim_strsave(li->li_tv.vval.v_string);
5654 	++ga.ga_len;
5655     }
5656     list_unref(retlist);
5657 
5658     *file = ga.ga_data;
5659     *num_file = ga.ga_len;
5660     return OK;
5661 }
5662 #endif
5663 
5664 /*
5665  * Expand color scheme, compiler or filetype names.
5666  * Search from 'runtimepath':
5667  *   'runtimepath'/{dirnames}/{pat}.vim
5668  * When "flags" has DIP_START: search also from 'start' of 'packpath':
5669  *   'packpath'/pack/ * /start/ * /{dirnames}/{pat}.vim
5670  * When "flags" has DIP_OPT: search also from 'opt' of 'packpath':
5671  *   'packpath'/pack/ * /opt/ * /{dirnames}/{pat}.vim
5672  * "dirnames" is an array with one or more directory names.
5673  */
5674     static int
5675 ExpandRTDir(
5676     char_u	*pat,
5677     int		flags,
5678     int		*num_file,
5679     char_u	***file,
5680     char	*dirnames[])
5681 {
5682     char_u	*s;
5683     char_u	*e;
5684     char_u	*match;
5685     garray_T	ga;
5686     int		i;
5687     int		pat_len;
5688 
5689     *num_file = 0;
5690     *file = NULL;
5691     pat_len = (int)STRLEN(pat);
5692     ga_init2(&ga, (int)sizeof(char *), 10);
5693 
5694     for (i = 0; dirnames[i] != NULL; ++i)
5695     {
5696 	s = alloc((unsigned)(STRLEN(dirnames[i]) + pat_len + 7));
5697 	if (s == NULL)
5698 	{
5699 	    ga_clear_strings(&ga);
5700 	    return FAIL;
5701 	}
5702 	sprintf((char *)s, "%s/%s*.vim", dirnames[i], pat);
5703 	globpath(p_rtp, s, &ga, 0);
5704 	vim_free(s);
5705     }
5706 
5707     if (flags & DIP_START) {
5708 	for (i = 0; dirnames[i] != NULL; ++i)
5709 	{
5710 	    s = alloc((unsigned)(STRLEN(dirnames[i]) + pat_len + 22));
5711 	    if (s == NULL)
5712 	    {
5713 		ga_clear_strings(&ga);
5714 		return FAIL;
5715 	    }
5716 	    sprintf((char *)s, "pack/*/start/*/%s/%s*.vim", dirnames[i], pat);
5717 	    globpath(p_pp, s, &ga, 0);
5718 	    vim_free(s);
5719 	}
5720     }
5721 
5722     if (flags & DIP_OPT) {
5723 	for (i = 0; dirnames[i] != NULL; ++i)
5724 	{
5725 	    s = alloc((unsigned)(STRLEN(dirnames[i]) + pat_len + 20));
5726 	    if (s == NULL)
5727 	    {
5728 		ga_clear_strings(&ga);
5729 		return FAIL;
5730 	    }
5731 	    sprintf((char *)s, "pack/*/opt/*/%s/%s*.vim", dirnames[i], pat);
5732 	    globpath(p_pp, s, &ga, 0);
5733 	    vim_free(s);
5734 	}
5735     }
5736 
5737     for (i = 0; i < ga.ga_len; ++i)
5738     {
5739 	match = ((char_u **)ga.ga_data)[i];
5740 	s = match;
5741 	e = s + STRLEN(s);
5742 	if (e - 4 > s && STRNICMP(e - 4, ".vim", 4) == 0)
5743 	{
5744 	    e -= 4;
5745 	    for (s = e; s > match; MB_PTR_BACK(match, s))
5746 		if (s < match || vim_ispathsep(*s))
5747 		    break;
5748 	    ++s;
5749 	    *e = NUL;
5750 	    mch_memmove(match, s, e - s + 1);
5751 	}
5752     }
5753 
5754     if (ga.ga_len == 0)
5755 	return FAIL;
5756 
5757     /* Sort and remove duplicates which can happen when specifying multiple
5758      * directories in dirnames. */
5759     remove_duplicates(&ga);
5760 
5761     *file = ga.ga_data;
5762     *num_file = ga.ga_len;
5763     return OK;
5764 }
5765 
5766 /*
5767  * Expand loadplugin names:
5768  * 'packpath'/pack/ * /opt/{pat}
5769  */
5770     static int
5771 ExpandPackAddDir(
5772     char_u	*pat,
5773     int		*num_file,
5774     char_u	***file)
5775 {
5776     char_u	*s;
5777     char_u	*e;
5778     char_u	*match;
5779     garray_T	ga;
5780     int		i;
5781     int		pat_len;
5782 
5783     *num_file = 0;
5784     *file = NULL;
5785     pat_len = (int)STRLEN(pat);
5786     ga_init2(&ga, (int)sizeof(char *), 10);
5787 
5788     s = alloc((unsigned)(pat_len + 26));
5789     if (s == NULL)
5790     {
5791 	ga_clear_strings(&ga);
5792 	return FAIL;
5793     }
5794     sprintf((char *)s, "pack/*/opt/%s*", pat);
5795     globpath(p_pp, s, &ga, 0);
5796     vim_free(s);
5797 
5798     for (i = 0; i < ga.ga_len; ++i)
5799     {
5800 	match = ((char_u **)ga.ga_data)[i];
5801 	s = gettail(match);
5802 	e = s + STRLEN(s);
5803 	mch_memmove(match, s, e - s + 1);
5804     }
5805 
5806     if (ga.ga_len == 0)
5807 	return FAIL;
5808 
5809     /* Sort and remove duplicates which can happen when specifying multiple
5810      * directories in dirnames. */
5811     remove_duplicates(&ga);
5812 
5813     *file = ga.ga_data;
5814     *num_file = ga.ga_len;
5815     return OK;
5816 }
5817 
5818 #endif
5819 
5820 #if defined(FEAT_CMDL_COMPL) || defined(FEAT_EVAL) || defined(PROTO)
5821 /*
5822  * Expand "file" for all comma-separated directories in "path".
5823  * Adds the matches to "ga".  Caller must init "ga".
5824  */
5825     void
5826 globpath(
5827     char_u	*path,
5828     char_u	*file,
5829     garray_T	*ga,
5830     int		expand_options)
5831 {
5832     expand_T	xpc;
5833     char_u	*buf;
5834     int		i;
5835     int		num_p;
5836     char_u	**p;
5837 
5838     buf = alloc(MAXPATHL);
5839     if (buf == NULL)
5840 	return;
5841 
5842     ExpandInit(&xpc);
5843     xpc.xp_context = EXPAND_FILES;
5844 
5845     /* Loop over all entries in {path}. */
5846     while (*path != NUL)
5847     {
5848 	/* Copy one item of the path to buf[] and concatenate the file name. */
5849 	copy_option_part(&path, buf, MAXPATHL, ",");
5850 	if (STRLEN(buf) + STRLEN(file) + 2 < MAXPATHL)
5851 	{
5852 # if defined(MSWIN)
5853 	    /* Using the platform's path separator (\) makes vim incorrectly
5854 	     * treat it as an escape character, use '/' instead. */
5855 	    if (*buf != NUL && !after_pathsep(buf, buf + STRLEN(buf)))
5856 		STRCAT(buf, "/");
5857 # else
5858 	    add_pathsep(buf);
5859 # endif
5860 	    STRCAT(buf, file);
5861 	    if (ExpandFromContext(&xpc, buf, &num_p, &p,
5862 			     WILD_SILENT|expand_options) != FAIL && num_p > 0)
5863 	    {
5864 		ExpandEscape(&xpc, buf, num_p, p, WILD_SILENT|expand_options);
5865 
5866 		if (ga_grow(ga, num_p) == OK)
5867 		{
5868 		    for (i = 0; i < num_p; ++i)
5869 		    {
5870 			((char_u **)ga->ga_data)[ga->ga_len] =
5871 					vim_strnsave(p[i], (int)STRLEN(p[i]));
5872 			++ga->ga_len;
5873 		    }
5874 		}
5875 
5876 		FreeWild(num_p, p);
5877 	    }
5878 	}
5879     }
5880 
5881     vim_free(buf);
5882 }
5883 
5884 #endif
5885 
5886 #if defined(FEAT_CMDHIST) || defined(PROTO)
5887 
5888 /*********************************
5889  *  Command line history stuff	 *
5890  *********************************/
5891 
5892 /*
5893  * Translate a history character to the associated type number.
5894  */
5895     static int
5896 hist_char2type(int c)
5897 {
5898     if (c == ':')
5899 	return HIST_CMD;
5900     if (c == '=')
5901 	return HIST_EXPR;
5902     if (c == '@')
5903 	return HIST_INPUT;
5904     if (c == '>')
5905 	return HIST_DEBUG;
5906     return HIST_SEARCH;	    /* must be '?' or '/' */
5907 }
5908 
5909 /*
5910  * Table of history names.
5911  * These names are used in :history and various hist...() functions.
5912  * It is sufficient to give the significant prefix of a history name.
5913  */
5914 
5915 static char *(history_names[]) =
5916 {
5917     "cmd",
5918     "search",
5919     "expr",
5920     "input",
5921     "debug",
5922     NULL
5923 };
5924 
5925 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
5926 /*
5927  * Function given to ExpandGeneric() to obtain the possible first
5928  * arguments of the ":history command.
5929  */
5930     static char_u *
5931 get_history_arg(expand_T *xp UNUSED, int idx)
5932 {
5933     static char_u compl[2] = { NUL, NUL };
5934     char *short_names = ":=@>?/";
5935     int short_names_count = (int)STRLEN(short_names);
5936     int history_name_count = sizeof(history_names) / sizeof(char *) - 1;
5937 
5938     if (idx < short_names_count)
5939     {
5940 	compl[0] = (char_u)short_names[idx];
5941 	return compl;
5942     }
5943     if (idx < short_names_count + history_name_count)
5944 	return (char_u *)history_names[idx - short_names_count];
5945     if (idx == short_names_count + history_name_count)
5946 	return (char_u *)"all";
5947     return NULL;
5948 }
5949 #endif
5950 
5951 /*
5952  * init_history() - Initialize the command line history.
5953  * Also used to re-allocate the history when the size changes.
5954  */
5955     void
5956 init_history(void)
5957 {
5958     int		newlen;	    /* new length of history table */
5959     histentry_T	*temp;
5960     int		i;
5961     int		j;
5962     int		type;
5963 
5964     /*
5965      * If size of history table changed, reallocate it
5966      */
5967     newlen = (int)p_hi;
5968     if (newlen != hislen)			/* history length changed */
5969     {
5970 	for (type = 0; type < HIST_COUNT; ++type)   /* adjust the tables */
5971 	{
5972 	    if (newlen)
5973 	    {
5974 		temp = (histentry_T *)lalloc(
5975 				(long_u)(newlen * sizeof(histentry_T)), TRUE);
5976 		if (temp == NULL)   /* out of memory! */
5977 		{
5978 		    if (type == 0)  /* first one: just keep the old length */
5979 		    {
5980 			newlen = hislen;
5981 			break;
5982 		    }
5983 		    /* Already changed one table, now we can only have zero
5984 		     * length for all tables. */
5985 		    newlen = 0;
5986 		    type = -1;
5987 		    continue;
5988 		}
5989 	    }
5990 	    else
5991 		temp = NULL;
5992 	    if (newlen == 0 || temp != NULL)
5993 	    {
5994 		if (hisidx[type] < 0)		/* there are no entries yet */
5995 		{
5996 		    for (i = 0; i < newlen; ++i)
5997 			clear_hist_entry(&temp[i]);
5998 		}
5999 		else if (newlen > hislen)	/* array becomes bigger */
6000 		{
6001 		    for (i = 0; i <= hisidx[type]; ++i)
6002 			temp[i] = history[type][i];
6003 		    j = i;
6004 		    for ( ; i <= newlen - (hislen - hisidx[type]); ++i)
6005 			clear_hist_entry(&temp[i]);
6006 		    for ( ; j < hislen; ++i, ++j)
6007 			temp[i] = history[type][j];
6008 		}
6009 		else				/* array becomes smaller or 0 */
6010 		{
6011 		    j = hisidx[type];
6012 		    for (i = newlen - 1; ; --i)
6013 		    {
6014 			if (i >= 0)		/* copy newest entries */
6015 			    temp[i] = history[type][j];
6016 			else			/* remove older entries */
6017 			    vim_free(history[type][j].hisstr);
6018 			if (--j < 0)
6019 			    j = hislen - 1;
6020 			if (j == hisidx[type])
6021 			    break;
6022 		    }
6023 		    hisidx[type] = newlen - 1;
6024 		}
6025 		vim_free(history[type]);
6026 		history[type] = temp;
6027 	    }
6028 	}
6029 	hislen = newlen;
6030     }
6031 }
6032 
6033     static void
6034 clear_hist_entry(histentry_T *hisptr)
6035 {
6036     hisptr->hisnum = 0;
6037     hisptr->viminfo = FALSE;
6038     hisptr->hisstr = NULL;
6039     hisptr->time_set = 0;
6040 }
6041 
6042 /*
6043  * Check if command line 'str' is already in history.
6044  * If 'move_to_front' is TRUE, matching entry is moved to end of history.
6045  */
6046     static int
6047 in_history(
6048     int	    type,
6049     char_u  *str,
6050     int	    move_to_front,	/* Move the entry to the front if it exists */
6051     int	    sep,
6052     int	    writing)		/* ignore entries read from viminfo */
6053 {
6054     int	    i;
6055     int	    last_i = -1;
6056     char_u  *p;
6057 
6058     if (hisidx[type] < 0)
6059 	return FALSE;
6060     i = hisidx[type];
6061     do
6062     {
6063 	if (history[type][i].hisstr == NULL)
6064 	    return FALSE;
6065 
6066 	/* For search history, check that the separator character matches as
6067 	 * well. */
6068 	p = history[type][i].hisstr;
6069 	if (STRCMP(str, p) == 0
6070 		&& !(writing && history[type][i].viminfo)
6071 		&& (type != HIST_SEARCH || sep == p[STRLEN(p) + 1]))
6072 	{
6073 	    if (!move_to_front)
6074 		return TRUE;
6075 	    last_i = i;
6076 	    break;
6077 	}
6078 	if (--i < 0)
6079 	    i = hislen - 1;
6080     } while (i != hisidx[type]);
6081 
6082     if (last_i >= 0)
6083     {
6084 	str = history[type][i].hisstr;
6085 	while (i != hisidx[type])
6086 	{
6087 	    if (++i >= hislen)
6088 		i = 0;
6089 	    history[type][last_i] = history[type][i];
6090 	    last_i = i;
6091 	}
6092 	history[type][i].hisnum = ++hisnum[type];
6093 	history[type][i].viminfo = FALSE;
6094 	history[type][i].hisstr = str;
6095 	history[type][i].time_set = vim_time();
6096 	return TRUE;
6097     }
6098     return FALSE;
6099 }
6100 
6101 /*
6102  * Convert history name (from table above) to its HIST_ equivalent.
6103  * When "name" is empty, return "cmd" history.
6104  * Returns -1 for unknown history name.
6105  */
6106     int
6107 get_histtype(char_u *name)
6108 {
6109     int		i;
6110     int		len = (int)STRLEN(name);
6111 
6112     /* No argument: use current history. */
6113     if (len == 0)
6114 	return hist_char2type(ccline.cmdfirstc);
6115 
6116     for (i = 0; history_names[i] != NULL; ++i)
6117 	if (STRNICMP(name, history_names[i], len) == 0)
6118 	    return i;
6119 
6120     if (vim_strchr((char_u *)":=@>?/", name[0]) != NULL && name[1] == NUL)
6121 	return hist_char2type(name[0]);
6122 
6123     return -1;
6124 }
6125 
6126 static int	last_maptick = -1;	/* last seen maptick */
6127 
6128 /*
6129  * Add the given string to the given history.  If the string is already in the
6130  * history then it is moved to the front.  "histype" may be one of he HIST_
6131  * values.
6132  */
6133     void
6134 add_to_history(
6135     int		histype,
6136     char_u	*new_entry,
6137     int		in_map,		/* consider maptick when inside a mapping */
6138     int		sep)		/* separator character used (search hist) */
6139 {
6140     histentry_T	*hisptr;
6141     int		len;
6142 
6143     if (hislen == 0)		/* no history */
6144 	return;
6145 
6146     if (cmdmod.keeppatterns && histype == HIST_SEARCH)
6147 	return;
6148 
6149     /*
6150      * Searches inside the same mapping overwrite each other, so that only
6151      * the last line is kept.  Be careful not to remove a line that was moved
6152      * down, only lines that were added.
6153      */
6154     if (histype == HIST_SEARCH && in_map)
6155     {
6156 	if (maptick == last_maptick && hisidx[HIST_SEARCH] >= 0)
6157 	{
6158 	    /* Current line is from the same mapping, remove it */
6159 	    hisptr = &history[HIST_SEARCH][hisidx[HIST_SEARCH]];
6160 	    vim_free(hisptr->hisstr);
6161 	    clear_hist_entry(hisptr);
6162 	    --hisnum[histype];
6163 	    if (--hisidx[HIST_SEARCH] < 0)
6164 		hisidx[HIST_SEARCH] = hislen - 1;
6165 	}
6166 	last_maptick = -1;
6167     }
6168     if (!in_history(histype, new_entry, TRUE, sep, FALSE))
6169     {
6170 	if (++hisidx[histype] == hislen)
6171 	    hisidx[histype] = 0;
6172 	hisptr = &history[histype][hisidx[histype]];
6173 	vim_free(hisptr->hisstr);
6174 
6175 	/* Store the separator after the NUL of the string. */
6176 	len = (int)STRLEN(new_entry);
6177 	hisptr->hisstr = vim_strnsave(new_entry, len + 2);
6178 	if (hisptr->hisstr != NULL)
6179 	    hisptr->hisstr[len + 1] = sep;
6180 
6181 	hisptr->hisnum = ++hisnum[histype];
6182 	hisptr->viminfo = FALSE;
6183 	hisptr->time_set = vim_time();
6184 	if (histype == HIST_SEARCH && in_map)
6185 	    last_maptick = maptick;
6186     }
6187 }
6188 
6189 #if defined(FEAT_EVAL) || defined(PROTO)
6190 
6191 /*
6192  * Get identifier of newest history entry.
6193  * "histype" may be one of the HIST_ values.
6194  */
6195     int
6196 get_history_idx(int histype)
6197 {
6198     if (hislen == 0 || histype < 0 || histype >= HIST_COUNT
6199 		    || hisidx[histype] < 0)
6200 	return -1;
6201 
6202     return history[histype][hisidx[histype]].hisnum;
6203 }
6204 
6205 /*
6206  * Calculate history index from a number:
6207  *   num > 0: seen as identifying number of a history entry
6208  *   num < 0: relative position in history wrt newest entry
6209  * "histype" may be one of the HIST_ values.
6210  */
6211     static int
6212 calc_hist_idx(int histype, int num)
6213 {
6214     int		i;
6215     histentry_T	*hist;
6216     int		wrapped = FALSE;
6217 
6218     if (hislen == 0 || histype < 0 || histype >= HIST_COUNT
6219 		    || (i = hisidx[histype]) < 0 || num == 0)
6220 	return -1;
6221 
6222     hist = history[histype];
6223     if (num > 0)
6224     {
6225 	while (hist[i].hisnum > num)
6226 	    if (--i < 0)
6227 	    {
6228 		if (wrapped)
6229 		    break;
6230 		i += hislen;
6231 		wrapped = TRUE;
6232 	    }
6233 	if (hist[i].hisnum == num && hist[i].hisstr != NULL)
6234 	    return i;
6235     }
6236     else if (-num <= hislen)
6237     {
6238 	i += num + 1;
6239 	if (i < 0)
6240 	    i += hislen;
6241 	if (hist[i].hisstr != NULL)
6242 	    return i;
6243     }
6244     return -1;
6245 }
6246 
6247 /*
6248  * Get a history entry by its index.
6249  * "histype" may be one of the HIST_ values.
6250  */
6251     char_u *
6252 get_history_entry(int histype, int idx)
6253 {
6254     idx = calc_hist_idx(histype, idx);
6255     if (idx >= 0)
6256 	return history[histype][idx].hisstr;
6257     else
6258 	return (char_u *)"";
6259 }
6260 
6261 /*
6262  * Clear all entries of a history.
6263  * "histype" may be one of the HIST_ values.
6264  */
6265     int
6266 clr_history(int histype)
6267 {
6268     int		i;
6269     histentry_T	*hisptr;
6270 
6271     if (hislen != 0 && histype >= 0 && histype < HIST_COUNT)
6272     {
6273 	hisptr = history[histype];
6274 	for (i = hislen; i--;)
6275 	{
6276 	    vim_free(hisptr->hisstr);
6277 	    clear_hist_entry(hisptr);
6278 	    hisptr++;
6279 	}
6280 	hisidx[histype] = -1;	/* mark history as cleared */
6281 	hisnum[histype] = 0;	/* reset identifier counter */
6282 	return OK;
6283     }
6284     return FAIL;
6285 }
6286 
6287 /*
6288  * Remove all entries matching {str} from a history.
6289  * "histype" may be one of the HIST_ values.
6290  */
6291     int
6292 del_history_entry(int histype, char_u *str)
6293 {
6294     regmatch_T	regmatch;
6295     histentry_T	*hisptr;
6296     int		idx;
6297     int		i;
6298     int		last;
6299     int		found = FALSE;
6300 
6301     regmatch.regprog = NULL;
6302     regmatch.rm_ic = FALSE;	/* always match case */
6303     if (hislen != 0
6304 	    && histype >= 0
6305 	    && histype < HIST_COUNT
6306 	    && *str != NUL
6307 	    && (idx = hisidx[histype]) >= 0
6308 	    && (regmatch.regprog = vim_regcomp(str, RE_MAGIC + RE_STRING))
6309 								      != NULL)
6310     {
6311 	i = last = idx;
6312 	do
6313 	{
6314 	    hisptr = &history[histype][i];
6315 	    if (hisptr->hisstr == NULL)
6316 		break;
6317 	    if (vim_regexec(&regmatch, hisptr->hisstr, (colnr_T)0))
6318 	    {
6319 		found = TRUE;
6320 		vim_free(hisptr->hisstr);
6321 		clear_hist_entry(hisptr);
6322 	    }
6323 	    else
6324 	    {
6325 		if (i != last)
6326 		{
6327 		    history[histype][last] = *hisptr;
6328 		    clear_hist_entry(hisptr);
6329 		}
6330 		if (--last < 0)
6331 		    last += hislen;
6332 	    }
6333 	    if (--i < 0)
6334 		i += hislen;
6335 	} while (i != idx);
6336 	if (history[histype][idx].hisstr == NULL)
6337 	    hisidx[histype] = -1;
6338     }
6339     vim_regfree(regmatch.regprog);
6340     return found;
6341 }
6342 
6343 /*
6344  * Remove an indexed entry from a history.
6345  * "histype" may be one of the HIST_ values.
6346  */
6347     int
6348 del_history_idx(int histype, int idx)
6349 {
6350     int	    i, j;
6351 
6352     i = calc_hist_idx(histype, idx);
6353     if (i < 0)
6354 	return FALSE;
6355     idx = hisidx[histype];
6356     vim_free(history[histype][i].hisstr);
6357 
6358     /* When deleting the last added search string in a mapping, reset
6359      * last_maptick, so that the last added search string isn't deleted again.
6360      */
6361     if (histype == HIST_SEARCH && maptick == last_maptick && i == idx)
6362 	last_maptick = -1;
6363 
6364     while (i != idx)
6365     {
6366 	j = (i + 1) % hislen;
6367 	history[histype][i] = history[histype][j];
6368 	i = j;
6369     }
6370     clear_hist_entry(&history[histype][i]);
6371     if (--i < 0)
6372 	i += hislen;
6373     hisidx[histype] = i;
6374     return TRUE;
6375 }
6376 
6377 #endif /* FEAT_EVAL */
6378 
6379 #if defined(FEAT_CRYPT) || defined(PROTO)
6380 /*
6381  * Very specific function to remove the value in ":set key=val" from the
6382  * history.
6383  */
6384     void
6385 remove_key_from_history(void)
6386 {
6387     char_u	*p;
6388     int		i;
6389 
6390     i = hisidx[HIST_CMD];
6391     if (i < 0)
6392 	return;
6393     p = history[HIST_CMD][i].hisstr;
6394     if (p != NULL)
6395 	for ( ; *p; ++p)
6396 	    if (STRNCMP(p, "key", 3) == 0 && !isalpha(p[3]))
6397 	    {
6398 		p = vim_strchr(p + 3, '=');
6399 		if (p == NULL)
6400 		    break;
6401 		++p;
6402 		for (i = 0; p[i] && !VIM_ISWHITE(p[i]); ++i)
6403 		    if (p[i] == '\\' && p[i + 1])
6404 			++i;
6405 		STRMOVE(p, p + i);
6406 		--p;
6407 	    }
6408 }
6409 #endif
6410 
6411 #endif /* FEAT_CMDHIST */
6412 
6413 #if defined(FEAT_EVAL) || defined(FEAT_CMDWIN) || defined(PROTO)
6414 /*
6415  * Get pointer to the command line info to use. save_ccline() may clear
6416  * ccline and put the previous value in prev_ccline.
6417  */
6418     static struct cmdline_info *
6419 get_ccline_ptr(void)
6420 {
6421     if ((State & CMDLINE) == 0)
6422 	return NULL;
6423     if (ccline.cmdbuff != NULL)
6424 	return &ccline;
6425     if (prev_ccline_used && prev_ccline.cmdbuff != NULL)
6426 	return &prev_ccline;
6427     return NULL;
6428 }
6429 #endif
6430 
6431 #if defined(FEAT_EVAL) || defined(PROTO)
6432 /*
6433  * Get the current command line in allocated memory.
6434  * Only works when the command line is being edited.
6435  * Returns NULL when something is wrong.
6436  */
6437     char_u *
6438 get_cmdline_str(void)
6439 {
6440     struct cmdline_info *p;
6441 
6442     if (cmdline_star > 0)
6443 	return NULL;
6444     p = get_ccline_ptr();
6445     if (p == NULL)
6446 	return NULL;
6447     return vim_strnsave(p->cmdbuff, p->cmdlen);
6448 }
6449 
6450 /*
6451  * Get the current command line position, counted in bytes.
6452  * Zero is the first position.
6453  * Only works when the command line is being edited.
6454  * Returns -1 when something is wrong.
6455  */
6456     int
6457 get_cmdline_pos(void)
6458 {
6459     struct cmdline_info *p = get_ccline_ptr();
6460 
6461     if (p == NULL)
6462 	return -1;
6463     return p->cmdpos;
6464 }
6465 
6466 /*
6467  * Set the command line byte position to "pos".  Zero is the first position.
6468  * Only works when the command line is being edited.
6469  * Returns 1 when failed, 0 when OK.
6470  */
6471     int
6472 set_cmdline_pos(
6473     int		pos)
6474 {
6475     struct cmdline_info *p = get_ccline_ptr();
6476 
6477     if (p == NULL)
6478 	return 1;
6479 
6480     /* The position is not set directly but after CTRL-\ e or CTRL-R = has
6481      * changed the command line. */
6482     if (pos < 0)
6483 	new_cmdpos = 0;
6484     else
6485 	new_cmdpos = pos;
6486     return 0;
6487 }
6488 #endif
6489 
6490 #if defined(FEAT_EVAL) || defined(FEAT_CMDWIN) || defined(PROTO)
6491 /*
6492  * Get the current command-line type.
6493  * Returns ':' or '/' or '?' or '@' or '>' or '-'
6494  * Only works when the command line is being edited.
6495  * Returns NUL when something is wrong.
6496  */
6497     int
6498 get_cmdline_type(void)
6499 {
6500     struct cmdline_info *p = get_ccline_ptr();
6501 
6502     if (p == NULL)
6503 	return NUL;
6504     if (p->cmdfirstc == NUL)
6505 	return
6506 # ifdef FEAT_EVAL
6507 	    (p->input_fn) ? '@' :
6508 # endif
6509 	    '-';
6510     return p->cmdfirstc;
6511 }
6512 #endif
6513 
6514 #if defined(FEAT_QUICKFIX) || defined(FEAT_CMDHIST) || defined(PROTO)
6515 /*
6516  * Get indices "num1,num2" that specify a range within a list (not a range of
6517  * text lines in a buffer!) from a string.  Used for ":history" and ":clist".
6518  * Returns OK if parsed successfully, otherwise FAIL.
6519  */
6520     int
6521 get_list_range(char_u **str, int *num1, int *num2)
6522 {
6523     int		len;
6524     int		first = FALSE;
6525     varnumber_T	num;
6526 
6527     *str = skipwhite(*str);
6528     if (**str == '-' || vim_isdigit(**str))  /* parse "from" part of range */
6529     {
6530 	vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0);
6531 	*str += len;
6532 	*num1 = (int)num;
6533 	first = TRUE;
6534     }
6535     *str = skipwhite(*str);
6536     if (**str == ',')			/* parse "to" part of range */
6537     {
6538 	*str = skipwhite(*str + 1);
6539 	vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0);
6540 	if (len > 0)
6541 	{
6542 	    *num2 = (int)num;
6543 	    *str = skipwhite(*str + len);
6544 	}
6545 	else if (!first)		/* no number given at all */
6546 	    return FAIL;
6547     }
6548     else if (first)			/* only one number given */
6549 	*num2 = *num1;
6550     return OK;
6551 }
6552 #endif
6553 
6554 #if defined(FEAT_CMDHIST) || defined(PROTO)
6555 /*
6556  * :history command - print a history
6557  */
6558     void
6559 ex_history(exarg_T *eap)
6560 {
6561     histentry_T	*hist;
6562     int		histype1 = HIST_CMD;
6563     int		histype2 = HIST_CMD;
6564     int		hisidx1 = 1;
6565     int		hisidx2 = -1;
6566     int		idx;
6567     int		i, j, k;
6568     char_u	*end;
6569     char_u	*arg = eap->arg;
6570 
6571     if (hislen == 0)
6572     {
6573 	msg(_("'history' option is zero"));
6574 	return;
6575     }
6576 
6577     if (!(VIM_ISDIGIT(*arg) || *arg == '-' || *arg == ','))
6578     {
6579 	end = arg;
6580 	while (ASCII_ISALPHA(*end)
6581 		|| vim_strchr((char_u *)":=@>/?", *end) != NULL)
6582 	    end++;
6583 	i = *end;
6584 	*end = NUL;
6585 	histype1 = get_histtype(arg);
6586 	if (histype1 == -1)
6587 	{
6588 	    if (STRNICMP(arg, "all", STRLEN(arg)) == 0)
6589 	    {
6590 		histype1 = 0;
6591 		histype2 = HIST_COUNT-1;
6592 	    }
6593 	    else
6594 	    {
6595 		*end = i;
6596 		emsg(_(e_trailing));
6597 		return;
6598 	    }
6599 	}
6600 	else
6601 	    histype2 = histype1;
6602 	*end = i;
6603     }
6604     else
6605 	end = arg;
6606     if (!get_list_range(&end, &hisidx1, &hisidx2) || *end != NUL)
6607     {
6608 	emsg(_(e_trailing));
6609 	return;
6610     }
6611 
6612     for (; !got_int && histype1 <= histype2; ++histype1)
6613     {
6614 	STRCPY(IObuff, "\n      #  ");
6615 	STRCAT(STRCAT(IObuff, history_names[histype1]), " history");
6616 	msg_puts_title((char *)IObuff);
6617 	idx = hisidx[histype1];
6618 	hist = history[histype1];
6619 	j = hisidx1;
6620 	k = hisidx2;
6621 	if (j < 0)
6622 	    j = (-j > hislen) ? 0 : hist[(hislen+j+idx+1) % hislen].hisnum;
6623 	if (k < 0)
6624 	    k = (-k > hislen) ? 0 : hist[(hislen+k+idx+1) % hislen].hisnum;
6625 	if (idx >= 0 && j <= k)
6626 	    for (i = idx + 1; !got_int; ++i)
6627 	    {
6628 		if (i == hislen)
6629 		    i = 0;
6630 		if (hist[i].hisstr != NULL
6631 			&& hist[i].hisnum >= j && hist[i].hisnum <= k)
6632 		{
6633 		    msg_putchar('\n');
6634 		    sprintf((char *)IObuff, "%c%6d  ", i == idx ? '>' : ' ',
6635 							      hist[i].hisnum);
6636 		    if (vim_strsize(hist[i].hisstr) > (int)Columns - 10)
6637 			trunc_string(hist[i].hisstr, IObuff + STRLEN(IObuff),
6638 			     (int)Columns - 10, IOSIZE - (int)STRLEN(IObuff));
6639 		    else
6640 			STRCAT(IObuff, hist[i].hisstr);
6641 		    msg_outtrans(IObuff);
6642 		    out_flush();
6643 		}
6644 		if (i == idx)
6645 		    break;
6646 	    }
6647     }
6648 }
6649 #endif
6650 
6651 #if (defined(FEAT_VIMINFO) && defined(FEAT_CMDHIST)) || defined(PROTO)
6652 /*
6653  * Buffers for history read from a viminfo file.  Only valid while reading.
6654  */
6655 static histentry_T *viminfo_history[HIST_COUNT] =
6656 					       {NULL, NULL, NULL, NULL, NULL};
6657 static int	viminfo_hisidx[HIST_COUNT] = {0, 0, 0, 0, 0};
6658 static int	viminfo_hislen[HIST_COUNT] = {0, 0, 0, 0, 0};
6659 static int	viminfo_add_at_front = FALSE;
6660 
6661 /*
6662  * Translate a history type number to the associated character.
6663  */
6664     static int
6665 hist_type2char(
6666     int	    type,
6667     int	    use_question)	    /* use '?' instead of '/' */
6668 {
6669     if (type == HIST_CMD)
6670 	return ':';
6671     if (type == HIST_SEARCH)
6672     {
6673 	if (use_question)
6674 	    return '?';
6675 	else
6676 	    return '/';
6677     }
6678     if (type == HIST_EXPR)
6679 	return '=';
6680     return '@';
6681 }
6682 
6683 /*
6684  * Prepare for reading the history from the viminfo file.
6685  * This allocates history arrays to store the read history lines.
6686  */
6687     void
6688 prepare_viminfo_history(int asklen, int writing)
6689 {
6690     int	    i;
6691     int	    num;
6692     int	    type;
6693     int	    len;
6694 
6695     init_history();
6696     viminfo_add_at_front = (asklen != 0 && !writing);
6697     if (asklen > hislen)
6698 	asklen = hislen;
6699 
6700     for (type = 0; type < HIST_COUNT; ++type)
6701     {
6702 	/* Count the number of empty spaces in the history list.  Entries read
6703 	 * from viminfo previously are also considered empty.  If there are
6704 	 * more spaces available than we request, then fill them up. */
6705 	for (i = 0, num = 0; i < hislen; i++)
6706 	    if (history[type][i].hisstr == NULL || history[type][i].viminfo)
6707 		num++;
6708 	len = asklen;
6709 	if (num > len)
6710 	    len = num;
6711 	if (len <= 0)
6712 	    viminfo_history[type] = NULL;
6713 	else
6714 	    viminfo_history[type] = (histentry_T *)lalloc(
6715 				  (long_u)(len * sizeof(histentry_T)), FALSE);
6716 	if (viminfo_history[type] == NULL)
6717 	    len = 0;
6718 	viminfo_hislen[type] = len;
6719 	viminfo_hisidx[type] = 0;
6720     }
6721 }
6722 
6723 /*
6724  * Accept a line from the viminfo, store it in the history array when it's
6725  * new.
6726  */
6727     int
6728 read_viminfo_history(vir_T *virp, int writing)
6729 {
6730     int		type;
6731     long_u	len;
6732     char_u	*val;
6733     char_u	*p;
6734 
6735     type = hist_char2type(virp->vir_line[0]);
6736     if (viminfo_hisidx[type] < viminfo_hislen[type])
6737     {
6738 	val = viminfo_readstring(virp, 1, TRUE);
6739 	if (val != NULL && *val != NUL)
6740 	{
6741 	    int sep = (*val == ' ' ? NUL : *val);
6742 
6743 	    if (!in_history(type, val + (type == HIST_SEARCH),
6744 					  viminfo_add_at_front, sep, writing))
6745 	    {
6746 		/* Need to re-allocate to append the separator byte. */
6747 		len = STRLEN(val);
6748 		p = lalloc(len + 2, TRUE);
6749 		if (p != NULL)
6750 		{
6751 		    if (type == HIST_SEARCH)
6752 		    {
6753 			/* Search entry: Move the separator from the first
6754 			 * column to after the NUL. */
6755 			mch_memmove(p, val + 1, (size_t)len);
6756 			p[len] = sep;
6757 		    }
6758 		    else
6759 		    {
6760 			/* Not a search entry: No separator in the viminfo
6761 			 * file, add a NUL separator. */
6762 			mch_memmove(p, val, (size_t)len + 1);
6763 			p[len + 1] = NUL;
6764 		    }
6765 		    viminfo_history[type][viminfo_hisidx[type]].hisstr = p;
6766 		    viminfo_history[type][viminfo_hisidx[type]].time_set = 0;
6767 		    viminfo_history[type][viminfo_hisidx[type]].viminfo = TRUE;
6768 		    viminfo_history[type][viminfo_hisidx[type]].hisnum = 0;
6769 		    viminfo_hisidx[type]++;
6770 		}
6771 	    }
6772 	}
6773 	vim_free(val);
6774     }
6775     return viminfo_readline(virp);
6776 }
6777 
6778 /*
6779  * Accept a new style history line from the viminfo, store it in the history
6780  * array when it's new.
6781  */
6782     void
6783 handle_viminfo_history(
6784 	garray_T    *values,
6785 	int	    writing)
6786 {
6787     int		type;
6788     long_u	len;
6789     char_u	*val;
6790     char_u	*p;
6791     bval_T	*vp = (bval_T *)values->ga_data;
6792 
6793     /* Check the format:
6794      * |{bartype},{histtype},{timestamp},{separator},"text" */
6795     if (values->ga_len < 4
6796 	    || vp[0].bv_type != BVAL_NR
6797 	    || vp[1].bv_type != BVAL_NR
6798 	    || (vp[2].bv_type != BVAL_NR && vp[2].bv_type != BVAL_EMPTY)
6799 	    || vp[3].bv_type != BVAL_STRING)
6800 	return;
6801 
6802     type = vp[0].bv_nr;
6803     if (type >= HIST_COUNT)
6804 	return;
6805     if (viminfo_hisidx[type] < viminfo_hislen[type])
6806     {
6807 	val = vp[3].bv_string;
6808 	if (val != NULL && *val != NUL)
6809 	{
6810 	    int sep = type == HIST_SEARCH && vp[2].bv_type == BVAL_NR
6811 						      ? vp[2].bv_nr : NUL;
6812 	    int idx;
6813 	    int overwrite = FALSE;
6814 
6815 	    if (!in_history(type, val, viminfo_add_at_front, sep, writing))
6816 	    {
6817 		/* If lines were written by an older Vim we need to avoid
6818 		 * getting duplicates. See if the entry already exists. */
6819 		for (idx = 0; idx < viminfo_hisidx[type]; ++idx)
6820 		{
6821 		    p = viminfo_history[type][idx].hisstr;
6822 		    if (STRCMP(val, p) == 0
6823 			  && (type != HIST_SEARCH || sep == p[STRLEN(p) + 1]))
6824 		    {
6825 			overwrite = TRUE;
6826 			break;
6827 		    }
6828 		}
6829 
6830 		if (!overwrite)
6831 		{
6832 		    /* Need to re-allocate to append the separator byte. */
6833 		    len = vp[3].bv_len;
6834 		    p = lalloc(len + 2, TRUE);
6835 		}
6836 		else
6837 		    len = 0; /* for picky compilers */
6838 		if (p != NULL)
6839 		{
6840 		    viminfo_history[type][idx].time_set = vp[1].bv_nr;
6841 		    if (!overwrite)
6842 		    {
6843 			mch_memmove(p, val, (size_t)len + 1);
6844 			/* Put the separator after the NUL. */
6845 			p[len + 1] = sep;
6846 			viminfo_history[type][idx].hisstr = p;
6847 			viminfo_history[type][idx].hisnum = 0;
6848 			viminfo_history[type][idx].viminfo = TRUE;
6849 			viminfo_hisidx[type]++;
6850 		    }
6851 		}
6852 	    }
6853 	}
6854     }
6855 }
6856 
6857 /*
6858  * Concatenate history lines from viminfo after the lines typed in this Vim.
6859  */
6860     static void
6861 concat_history(int type)
6862 {
6863     int idx;
6864     int i;
6865 
6866     idx = hisidx[type] + viminfo_hisidx[type];
6867     if (idx >= hislen)
6868 	idx -= hislen;
6869     else if (idx < 0)
6870 	idx = hislen - 1;
6871     if (viminfo_add_at_front)
6872 	hisidx[type] = idx;
6873     else
6874     {
6875 	if (hisidx[type] == -1)
6876 	    hisidx[type] = hislen - 1;
6877 	do
6878 	{
6879 	    if (history[type][idx].hisstr != NULL
6880 					    || history[type][idx].viminfo)
6881 		break;
6882 	    if (++idx == hislen)
6883 		idx = 0;
6884 	} while (idx != hisidx[type]);
6885 	if (idx != hisidx[type] && --idx < 0)
6886 	    idx = hislen - 1;
6887     }
6888     for (i = 0; i < viminfo_hisidx[type]; i++)
6889     {
6890 	vim_free(history[type][idx].hisstr);
6891 	history[type][idx].hisstr = viminfo_history[type][i].hisstr;
6892 	history[type][idx].viminfo = TRUE;
6893 	history[type][idx].time_set = viminfo_history[type][i].time_set;
6894 	if (--idx < 0)
6895 	    idx = hislen - 1;
6896     }
6897     idx += 1;
6898     idx %= hislen;
6899     for (i = 0; i < viminfo_hisidx[type]; i++)
6900     {
6901 	history[type][idx++].hisnum = ++hisnum[type];
6902 	idx %= hislen;
6903     }
6904 }
6905 
6906 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
6907     static int
6908 #ifdef __BORLANDC__
6909 _RTLENTRYF
6910 #endif
6911 sort_hist(const void *s1, const void *s2)
6912 {
6913     histentry_T *p1 = *(histentry_T **)s1;
6914     histentry_T *p2 = *(histentry_T **)s2;
6915 
6916     if (p1->time_set < p2->time_set) return -1;
6917     if (p1->time_set > p2->time_set) return 1;
6918     return 0;
6919 }
6920 #endif
6921 
6922 /*
6923  * Merge history lines from viminfo and lines typed in this Vim based on the
6924  * timestamp;
6925  */
6926     static void
6927 merge_history(int type)
6928 {
6929     int		max_len;
6930     histentry_T **tot_hist;
6931     histentry_T *new_hist;
6932     int		i;
6933     int		len;
6934 
6935     /* Make one long list with all entries. */
6936     max_len = hislen + viminfo_hisidx[type];
6937     tot_hist = (histentry_T **)alloc(max_len * (int)sizeof(histentry_T *));
6938     new_hist = (histentry_T *)alloc(hislen * (int)sizeof(histentry_T));
6939     if (tot_hist == NULL || new_hist == NULL)
6940     {
6941 	vim_free(tot_hist);
6942 	vim_free(new_hist);
6943 	return;
6944     }
6945     for (i = 0; i < viminfo_hisidx[type]; i++)
6946 	tot_hist[i] = &viminfo_history[type][i];
6947     len = i;
6948     for (i = 0; i < hislen; i++)
6949 	if (history[type][i].hisstr != NULL)
6950 	    tot_hist[len++] = &history[type][i];
6951 
6952     /* Sort the list on timestamp. */
6953     qsort((void *)tot_hist, (size_t)len, sizeof(histentry_T *), sort_hist);
6954 
6955     /* Keep the newest ones. */
6956     for (i = 0; i < hislen; i++)
6957     {
6958 	if (i < len)
6959 	{
6960 	    new_hist[i] = *tot_hist[i];
6961 	    tot_hist[i]->hisstr = NULL;
6962 	    if (new_hist[i].hisnum == 0)
6963 		new_hist[i].hisnum = ++hisnum[type];
6964 	}
6965 	else
6966 	    clear_hist_entry(&new_hist[i]);
6967     }
6968     hisidx[type] = (i < len ? i : len) - 1;
6969 
6970     /* Free what is not kept. */
6971     for (i = 0; i < viminfo_hisidx[type]; i++)
6972 	vim_free(viminfo_history[type][i].hisstr);
6973     for (i = 0; i < hislen; i++)
6974 	vim_free(history[type][i].hisstr);
6975     vim_free(history[type]);
6976     history[type] = new_hist;
6977     vim_free(tot_hist);
6978 }
6979 
6980 /*
6981  * Finish reading history lines from viminfo.  Not used when writing viminfo.
6982  */
6983     void
6984 finish_viminfo_history(vir_T *virp)
6985 {
6986     int	type;
6987     int merge = virp->vir_version >= VIMINFO_VERSION_WITH_HISTORY;
6988 
6989     for (type = 0; type < HIST_COUNT; ++type)
6990     {
6991 	if (history[type] == NULL)
6992 	    continue;
6993 
6994 	if (merge)
6995 	    merge_history(type);
6996 	else
6997 	    concat_history(type);
6998 
6999 	VIM_CLEAR(viminfo_history[type]);
7000 	viminfo_hisidx[type] = 0;
7001     }
7002 }
7003 
7004 /*
7005  * Write history to viminfo file in "fp".
7006  * When "merge" is TRUE merge history lines with a previously read viminfo
7007  * file, data is in viminfo_history[].
7008  * When "merge" is FALSE just write all history lines.  Used for ":wviminfo!".
7009  */
7010     void
7011 write_viminfo_history(FILE *fp, int merge)
7012 {
7013     int	    i;
7014     int	    type;
7015     int	    num_saved;
7016     int     round;
7017 
7018     init_history();
7019     if (hislen == 0)
7020 	return;
7021     for (type = 0; type < HIST_COUNT; ++type)
7022     {
7023 	num_saved = get_viminfo_parameter(hist_type2char(type, FALSE));
7024 	if (num_saved == 0)
7025 	    continue;
7026 	if (num_saved < 0)  /* Use default */
7027 	    num_saved = hislen;
7028 	fprintf(fp, _("\n# %s History (newest to oldest):\n"),
7029 			    type == HIST_CMD ? _("Command Line") :
7030 			    type == HIST_SEARCH ? _("Search String") :
7031 			    type == HIST_EXPR ? _("Expression") :
7032 			    type == HIST_INPUT ? _("Input Line") :
7033 					_("Debug Line"));
7034 	if (num_saved > hislen)
7035 	    num_saved = hislen;
7036 
7037 	/*
7038 	 * Merge typed and viminfo history:
7039 	 * round 1: history of typed commands.
7040 	 * round 2: history from recently read viminfo.
7041 	 */
7042 	for (round = 1; round <= 2; ++round)
7043 	{
7044 	    if (round == 1)
7045 		/* start at newest entry, somewhere in the list */
7046 		i = hisidx[type];
7047 	    else if (viminfo_hisidx[type] > 0)
7048 		/* start at newest entry, first in the list */
7049 		i = 0;
7050 	    else
7051 		/* empty list */
7052 		i = -1;
7053 	    if (i >= 0)
7054 		while (num_saved > 0
7055 			&& !(round == 2 && i >= viminfo_hisidx[type]))
7056 		{
7057 		    char_u  *p;
7058 		    time_t  timestamp;
7059 		    int	    c = NUL;
7060 
7061 		    if (round == 1)
7062 		    {
7063 			p = history[type][i].hisstr;
7064 			timestamp = history[type][i].time_set;
7065 		    }
7066 		    else
7067 		    {
7068 			p = viminfo_history[type] == NULL ? NULL
7069 					    : viminfo_history[type][i].hisstr;
7070 			timestamp = viminfo_history[type] == NULL ? 0
7071 					  : viminfo_history[type][i].time_set;
7072 		    }
7073 
7074 		    if (p != NULL && (round == 2
7075 				       || !merge
7076 				       || !history[type][i].viminfo))
7077 		    {
7078 			--num_saved;
7079 			fputc(hist_type2char(type, TRUE), fp);
7080 			/* For the search history: put the separator in the
7081 			 * second column; use a space if there isn't one. */
7082 			if (type == HIST_SEARCH)
7083 			{
7084 			    c = p[STRLEN(p) + 1];
7085 			    putc(c == NUL ? ' ' : c, fp);
7086 			}
7087 			viminfo_writestring(fp, p);
7088 
7089 			{
7090 			    char    cbuf[NUMBUFLEN];
7091 
7092 			    /* New style history with a bar line. Format:
7093 			     * |{bartype},{histtype},{timestamp},{separator},"text" */
7094 			    if (c == NUL)
7095 				cbuf[0] = NUL;
7096 			    else
7097 				sprintf(cbuf, "%d", c);
7098 			    fprintf(fp, "|%d,%d,%ld,%s,", BARTYPE_HISTORY,
7099 						 type, (long)timestamp, cbuf);
7100 			    barline_writestring(fp, p, LSIZE - 20);
7101 			    putc('\n', fp);
7102 			}
7103 		    }
7104 		    if (round == 1)
7105 		    {
7106 			/* Decrement index, loop around and stop when back at
7107 			 * the start. */
7108 			if (--i < 0)
7109 			    i = hislen - 1;
7110 			if (i == hisidx[type])
7111 			    break;
7112 		    }
7113 		    else
7114 		    {
7115 			/* Increment index. Stop at the end in the while. */
7116 			++i;
7117 		    }
7118 		}
7119 	}
7120 	for (i = 0; i < viminfo_hisidx[type]; ++i)
7121 	    if (viminfo_history[type] != NULL)
7122 		vim_free(viminfo_history[type][i].hisstr);
7123 	VIM_CLEAR(viminfo_history[type]);
7124 	viminfo_hisidx[type] = 0;
7125     }
7126 }
7127 #endif /* FEAT_VIMINFO */
7128 
7129 #if defined(FEAT_FKMAP) || defined(PROTO)
7130 /*
7131  * Write a character at the current cursor+offset position.
7132  * It is directly written into the command buffer block.
7133  */
7134     void
7135 cmd_pchar(int c, int offset)
7136 {
7137     if (ccline.cmdpos + offset >= ccline.cmdlen || ccline.cmdpos + offset < 0)
7138     {
7139 	emsg(_("E198: cmd_pchar beyond the command length"));
7140 	return;
7141     }
7142     ccline.cmdbuff[ccline.cmdpos + offset] = (char_u)c;
7143     ccline.cmdbuff[ccline.cmdlen] = NUL;
7144 }
7145 
7146     int
7147 cmd_gchar(int offset)
7148 {
7149     if (ccline.cmdpos + offset >= ccline.cmdlen || ccline.cmdpos + offset < 0)
7150     {
7151 	// emsg(_("cmd_gchar beyond the command length"));
7152 	return NUL;
7153     }
7154     return (int)ccline.cmdbuff[ccline.cmdpos + offset];
7155 }
7156 #endif
7157 
7158 #if defined(FEAT_CMDWIN) || defined(PROTO)
7159 /*
7160  * Open a window on the current command line and history.  Allow editing in
7161  * the window.  Returns when the window is closed.
7162  * Returns:
7163  *	CR	 if the command is to be executed
7164  *	Ctrl_C	 if it is to be abandoned
7165  *	K_IGNORE if editing continues
7166  */
7167     static int
7168 open_cmdwin(void)
7169 {
7170     bufref_T		old_curbuf;
7171     win_T		*old_curwin = curwin;
7172     bufref_T		bufref;
7173     win_T		*wp;
7174     int			i;
7175     linenr_T		lnum;
7176     int			histtype;
7177     garray_T		winsizes;
7178     int			save_restart_edit = restart_edit;
7179     int			save_State = State;
7180     int			save_exmode = exmode_active;
7181 #ifdef FEAT_RIGHTLEFT
7182     int			save_cmdmsg_rl = cmdmsg_rl;
7183 #endif
7184 #ifdef FEAT_FOLDING
7185     int			save_KeyTyped;
7186 #endif
7187 
7188     /* Can't do this recursively.  Can't do it when typing a password. */
7189     if (cmdwin_type != 0
7190 # if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
7191 	    || cmdline_star > 0
7192 # endif
7193 	    )
7194     {
7195 	beep_flush();
7196 	return K_IGNORE;
7197     }
7198     set_bufref(&old_curbuf, curbuf);
7199 
7200     /* Save current window sizes. */
7201     win_size_save(&winsizes);
7202 
7203     /* Don't execute autocommands while creating the window. */
7204     block_autocmds();
7205 
7206 #if defined(FEAT_INS_EXPAND)
7207     // When using completion in Insert mode with <C-R>=<C-F> one can open the
7208     // command line window, but we don't want the popup menu then.
7209     pum_undisplay();
7210 #endif
7211 
7212     /* don't use a new tab page */
7213     cmdmod.tab = 0;
7214     cmdmod.noswapfile = 1;
7215 
7216     /* Create a window for the command-line buffer. */
7217     if (win_split((int)p_cwh, WSP_BOT) == FAIL)
7218     {
7219 	beep_flush();
7220 	unblock_autocmds();
7221 	return K_IGNORE;
7222     }
7223     cmdwin_type = get_cmdline_type();
7224 
7225     /* Create the command-line buffer empty. */
7226     (void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
7227     (void)setfname(curbuf, (char_u *)"[Command Line]", NULL, TRUE);
7228     set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
7229     curbuf->b_p_ma = TRUE;
7230 #ifdef FEAT_FOLDING
7231     curwin->w_p_fen = FALSE;
7232 #endif
7233 # ifdef FEAT_RIGHTLEFT
7234     curwin->w_p_rl = cmdmsg_rl;
7235     cmdmsg_rl = FALSE;
7236 # endif
7237     RESET_BINDING(curwin);
7238 
7239     /* Do execute autocommands for setting the filetype (load syntax). */
7240     unblock_autocmds();
7241     /* But don't allow switching to another buffer. */
7242     ++curbuf_lock;
7243 
7244     /* Showing the prompt may have set need_wait_return, reset it. */
7245     need_wait_return = FALSE;
7246 
7247     histtype = hist_char2type(cmdwin_type);
7248     if (histtype == HIST_CMD || histtype == HIST_DEBUG)
7249     {
7250 	if (p_wc == TAB)
7251 	{
7252 	    add_map((char_u *)"<buffer> <Tab> <C-X><C-V>", INSERT);
7253 	    add_map((char_u *)"<buffer> <Tab> a<C-X><C-V>", NORMAL);
7254 	}
7255 	set_option_value((char_u *)"ft", 0L, (char_u *)"vim", OPT_LOCAL);
7256     }
7257     --curbuf_lock;
7258 
7259     /* Reset 'textwidth' after setting 'filetype' (the Vim filetype plugin
7260      * sets 'textwidth' to 78). */
7261     curbuf->b_p_tw = 0;
7262 
7263     /* Fill the buffer with the history. */
7264     init_history();
7265     if (hislen > 0)
7266     {
7267 	i = hisidx[histtype];
7268 	if (i >= 0)
7269 	{
7270 	    lnum = 0;
7271 	    do
7272 	    {
7273 		if (++i == hislen)
7274 		    i = 0;
7275 		if (history[histtype][i].hisstr != NULL)
7276 		    ml_append(lnum++, history[histtype][i].hisstr,
7277 							   (colnr_T)0, FALSE);
7278 	    }
7279 	    while (i != hisidx[histtype]);
7280 	}
7281     }
7282 
7283     /* Replace the empty last line with the current command-line and put the
7284      * cursor there. */
7285     ml_replace(curbuf->b_ml.ml_line_count, ccline.cmdbuff, TRUE);
7286     curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
7287     curwin->w_cursor.col = ccline.cmdpos;
7288     changed_line_abv_curs();
7289     invalidate_botline();
7290     redraw_later(SOME_VALID);
7291 
7292     /* No Ex mode here! */
7293     exmode_active = 0;
7294 
7295     State = NORMAL;
7296 # ifdef FEAT_MOUSE
7297     setmouse();
7298 # endif
7299 
7300     /* Trigger CmdwinEnter autocommands. */
7301     trigger_cmd_autocmd(cmdwin_type, EVENT_CMDWINENTER);
7302     if (restart_edit != 0)	/* autocmd with ":startinsert" */
7303 	stuffcharReadbuff(K_NOP);
7304 
7305     i = RedrawingDisabled;
7306     RedrawingDisabled = 0;
7307 
7308     /*
7309      * Call the main loop until <CR> or CTRL-C is typed.
7310      */
7311     cmdwin_result = 0;
7312     main_loop(TRUE, FALSE);
7313 
7314     RedrawingDisabled = i;
7315 
7316 # ifdef FEAT_FOLDING
7317     save_KeyTyped = KeyTyped;
7318 # endif
7319 
7320     /* Trigger CmdwinLeave autocommands. */
7321     trigger_cmd_autocmd(cmdwin_type, EVENT_CMDWINLEAVE);
7322 
7323 # ifdef FEAT_FOLDING
7324     /* Restore KeyTyped in case it is modified by autocommands */
7325     KeyTyped = save_KeyTyped;
7326 # endif
7327 
7328     cmdwin_type = 0;
7329     exmode_active = save_exmode;
7330 
7331     /* Safety check: The old window or buffer was deleted: It's a bug when
7332      * this happens! */
7333     if (!win_valid(old_curwin) || !bufref_valid(&old_curbuf))
7334     {
7335 	cmdwin_result = Ctrl_C;
7336 	emsg(_("E199: Active window or buffer deleted"));
7337     }
7338     else
7339     {
7340 # if defined(FEAT_EVAL)
7341 	/* autocmds may abort script processing */
7342 	if (aborting() && cmdwin_result != K_IGNORE)
7343 	    cmdwin_result = Ctrl_C;
7344 # endif
7345 	/* Set the new command line from the cmdline buffer. */
7346 	vim_free(ccline.cmdbuff);
7347 	if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) /* :qa[!] typed */
7348 	{
7349 	    char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!";
7350 
7351 	    if (histtype == HIST_CMD)
7352 	    {
7353 		/* Execute the command directly. */
7354 		ccline.cmdbuff = vim_strsave((char_u *)p);
7355 		cmdwin_result = CAR;
7356 	    }
7357 	    else
7358 	    {
7359 		/* First need to cancel what we were doing. */
7360 		ccline.cmdbuff = NULL;
7361 		stuffcharReadbuff(':');
7362 		stuffReadbuff((char_u *)p);
7363 		stuffcharReadbuff(CAR);
7364 	    }
7365 	}
7366 	else if (cmdwin_result == K_XF2)	/* :qa typed */
7367 	{
7368 	    ccline.cmdbuff = vim_strsave((char_u *)"qa");
7369 	    cmdwin_result = CAR;
7370 	}
7371 	else if (cmdwin_result == Ctrl_C)
7372 	{
7373 	    /* :q or :close, don't execute any command
7374 	     * and don't modify the cmd window. */
7375 	    ccline.cmdbuff = NULL;
7376 	}
7377 	else
7378 	    ccline.cmdbuff = vim_strsave(ml_get_curline());
7379 	if (ccline.cmdbuff == NULL)
7380 	{
7381 	    ccline.cmdbuff = vim_strsave((char_u *)"");
7382 	    ccline.cmdlen = 0;
7383 	    ccline.cmdbufflen = 1;
7384 	    ccline.cmdpos = 0;
7385 	    cmdwin_result = Ctrl_C;
7386 	}
7387 	else
7388 	{
7389 	    ccline.cmdlen = (int)STRLEN(ccline.cmdbuff);
7390 	    ccline.cmdbufflen = ccline.cmdlen + 1;
7391 	    ccline.cmdpos = curwin->w_cursor.col;
7392 	    if (ccline.cmdpos > ccline.cmdlen)
7393 		ccline.cmdpos = ccline.cmdlen;
7394 	    if (cmdwin_result == K_IGNORE)
7395 	    {
7396 		set_cmdspos_cursor();
7397 		redrawcmd();
7398 	    }
7399 	}
7400 
7401 	/* Don't execute autocommands while deleting the window. */
7402 	block_autocmds();
7403 # ifdef FEAT_CONCEAL
7404 	/* Avoid command-line window first character being concealed. */
7405 	curwin->w_p_cole = 0;
7406 # endif
7407 	wp = curwin;
7408 	set_bufref(&bufref, curbuf);
7409 	win_goto(old_curwin);
7410 	win_close(wp, TRUE);
7411 
7412 	/* win_close() may have already wiped the buffer when 'bh' is
7413 	 * set to 'wipe' */
7414 	if (bufref_valid(&bufref))
7415 	    close_buffer(NULL, bufref.br_buf, DOBUF_WIPE, FALSE);
7416 
7417 	/* Restore window sizes. */
7418 	win_size_restore(&winsizes);
7419 
7420 	unblock_autocmds();
7421     }
7422 
7423     ga_clear(&winsizes);
7424     restart_edit = save_restart_edit;
7425 # ifdef FEAT_RIGHTLEFT
7426     cmdmsg_rl = save_cmdmsg_rl;
7427 # endif
7428 
7429     State = save_State;
7430 # ifdef FEAT_MOUSE
7431     setmouse();
7432 # endif
7433 
7434     return cmdwin_result;
7435 }
7436 #endif /* FEAT_CMDWIN */
7437 
7438 /*
7439  * Used for commands that either take a simple command string argument, or:
7440  *	cmd << endmarker
7441  *	  {script}
7442  *	endmarker
7443  * Returns a pointer to allocated memory with {script} or NULL.
7444  */
7445     char_u *
7446 script_get(exarg_T *eap, char_u *cmd)
7447 {
7448     char_u	*theline;
7449     char	*end_pattern = NULL;
7450     char	dot[] = ".";
7451     garray_T	ga;
7452 
7453     if (cmd[0] != '<' || cmd[1] != '<' || eap->getline == NULL)
7454 	return NULL;
7455 
7456     ga_init2(&ga, 1, 0x400);
7457 
7458     if (cmd[2] != NUL)
7459 	end_pattern = (char *)skipwhite(cmd + 2);
7460     else
7461 	end_pattern = dot;
7462 
7463     for (;;)
7464     {
7465 	theline = eap->getline(
7466 #ifdef FEAT_EVAL
7467 	    eap->cstack->cs_looplevel > 0 ? -1 :
7468 #endif
7469 	    NUL, eap->cookie, 0);
7470 
7471 	if (theline == NULL || STRCMP(end_pattern, theline) == 0)
7472 	{
7473 	    vim_free(theline);
7474 	    break;
7475 	}
7476 
7477 	ga_concat(&ga, theline);
7478 	ga_append(&ga, '\n');
7479 	vim_free(theline);
7480     }
7481     ga_append(&ga, NUL);
7482 
7483     return (char_u *)ga.ga_data;
7484 }
7485