xref: /vim-8.2.3635/src/ex_getln.c (revision ed37d9b3)
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 // The current cmdline_info.  It is initialized in getcmdline() and after that
21 // used by other functions.  When invoking getcmdline() recursively it needs
22 // to be saved with save_cmdline() and restored with restore_cmdline().
23 static cmdline_info_T ccline;
24 
25 #ifdef FEAT_EVAL
26 static int	new_cmdpos;	// position set by set_cmdline_pos()
27 #endif
28 
29 static int	extra_char = NUL;  // extra character to display when redrawing
30 				   // the command line
31 static int	extra_char_shift;
32 
33 #ifdef FEAT_RIGHTLEFT
34 static int	cmd_hkmap = 0;	// Hebrew mapping during command line
35 #endif
36 
37 static char_u	*getcmdline_int(int firstc, long count, int indent, int init_ccline);
38 static int	cmdline_charsize(int idx);
39 static void	set_cmdspos(void);
40 static void	set_cmdspos_cursor(void);
41 static void	correct_cmdspos(int idx, int cells);
42 static void	alloc_cmdbuff(int len);
43 static void	draw_cmdline(int start, int len);
44 static void	save_cmdline(cmdline_info_T *ccp);
45 static void	restore_cmdline(cmdline_info_T *ccp);
46 static int	cmdline_paste(int regname, int literally, int remcr);
47 #ifdef FEAT_WILDMENU
48 static void	cmdline_del(int from);
49 #endif
50 static void	redrawcmdprompt(void);
51 static int	ccheck_abbr(int);
52 
53 #ifdef FEAT_CMDWIN
54 static int	open_cmdwin(void);
55 
56 static int	cedit_key INIT(= -1);	// key value of 'cedit' option
57 #endif
58 
59 
60     static void
61 trigger_cmd_autocmd(int typechar, int evt)
62 {
63     char_u	typestr[2];
64 
65     typestr[0] = typechar;
66     typestr[1] = NUL;
67     apply_autocmds(evt, typestr, typestr, FALSE, curbuf);
68 }
69 
70 /*
71  * Abandon the command line.
72  */
73     static void
74 abandon_cmdline(void)
75 {
76     VIM_CLEAR(ccline.cmdbuff);
77     if (msg_scrolled == 0)
78 	compute_cmdrow();
79     msg("");
80     redraw_cmdline = TRUE;
81 }
82 
83 #ifdef FEAT_SEARCH_EXTRA
84 /*
85  * Guess that the pattern matches everything.  Only finds specific cases, such
86  * as a trailing \|, which can happen while typing a pattern.
87  */
88     static int
89 empty_pattern(char_u *p)
90 {
91     size_t n = STRLEN(p);
92 
93     // remove trailing \v and the like
94     while (n >= 2 && p[n - 2] == '\\'
95 			  && vim_strchr((char_u *)"mMvVcCZ", p[n - 1]) != NULL)
96 	n -= 2;
97     return n == 0 || (n >= 2 && p[n - 2] == '\\' && p[n - 1] == '|');
98 }
99 
100 // Struct to store the viewstate during 'incsearch' highlighting.
101 typedef struct {
102     colnr_T	vs_curswant;
103     colnr_T	vs_leftcol;
104     linenr_T	vs_topline;
105 # ifdef FEAT_DIFF
106     int		vs_topfill;
107 # endif
108     linenr_T	vs_botline;
109     linenr_T	vs_empty_rows;
110 } viewstate_T;
111 
112     static void
113 save_viewstate(viewstate_T *vs)
114 {
115     vs->vs_curswant = curwin->w_curswant;
116     vs->vs_leftcol = curwin->w_leftcol;
117     vs->vs_topline = curwin->w_topline;
118 # ifdef FEAT_DIFF
119     vs->vs_topfill = curwin->w_topfill;
120 # endif
121     vs->vs_botline = curwin->w_botline;
122     vs->vs_empty_rows = curwin->w_empty_rows;
123 }
124 
125     static void
126 restore_viewstate(viewstate_T *vs)
127 {
128     curwin->w_curswant = vs->vs_curswant;
129     curwin->w_leftcol = vs->vs_leftcol;
130     curwin->w_topline = vs->vs_topline;
131 # ifdef FEAT_DIFF
132     curwin->w_topfill = vs->vs_topfill;
133 # endif
134     curwin->w_botline = vs->vs_botline;
135     curwin->w_empty_rows = vs->vs_empty_rows;
136 }
137 
138 // Struct to store the state of 'incsearch' highlighting.
139 typedef struct {
140     pos_T	search_start;	// where 'incsearch' starts searching
141     pos_T	save_cursor;
142     viewstate_T	init_viewstate;
143     viewstate_T	old_viewstate;
144     pos_T	match_start;
145     pos_T	match_end;
146     int		did_incsearch;
147     int		incsearch_postponed;
148     int		magic_save;
149 } incsearch_state_T;
150 
151     static void
152 init_incsearch_state(incsearch_state_T *is_state)
153 {
154     is_state->match_start = curwin->w_cursor;
155     is_state->did_incsearch = FALSE;
156     is_state->incsearch_postponed = FALSE;
157     is_state->magic_save = p_magic;
158     CLEAR_POS(&is_state->match_end);
159     is_state->save_cursor = curwin->w_cursor;  // may be restored later
160     is_state->search_start = curwin->w_cursor;
161     save_viewstate(&is_state->init_viewstate);
162     save_viewstate(&is_state->old_viewstate);
163 }
164 
165 /*
166  * First move cursor to end of match, then to the start.  This
167  * moves the whole match onto the screen when 'nowrap' is set.
168  */
169     static void
170 set_search_match(pos_T *t)
171 {
172     t->lnum += search_match_lines;
173     t->col = search_match_endcol;
174     if (t->lnum > curbuf->b_ml.ml_line_count)
175     {
176 	t->lnum = curbuf->b_ml.ml_line_count;
177 	coladvance((colnr_T)MAXCOL);
178     }
179 }
180 
181 /*
182  * Return TRUE when 'incsearch' highlighting is to be done.
183  * Sets search_first_line and search_last_line to the address range.
184  * May change the last search pattern.
185  */
186     static int
187 do_incsearch_highlighting(int firstc, int *search_delim, incsearch_state_T *is_state,
188 						     int *skiplen, int *patlen)
189 {
190     char_u	*cmd;
191     cmdmod_T	save_cmdmod = cmdmod;
192     char_u	*p;
193     int		delim_optional = FALSE;
194     int		delim;
195     char_u	*end;
196     char	*dummy;
197     exarg_T	ea;
198     pos_T	save_cursor;
199     int		use_last_pat;
200     int		retval = FALSE;
201 
202     *skiplen = 0;
203     *patlen = ccline.cmdlen;
204 
205     if (!p_is || cmd_silent)
206 	return FALSE;
207 
208     // by default search all lines
209     search_first_line = 0;
210     search_last_line = MAXLNUM;
211 
212     if (firstc == '/' || firstc == '?')
213     {
214 	*search_delim = firstc;
215 	return TRUE;
216     }
217     if (firstc != ':')
218 	return FALSE;
219 
220     ++emsg_off;
221     CLEAR_FIELD(ea);
222     ea.line1 = 1;
223     ea.line2 = 1;
224     ea.cmd = ccline.cmdbuff;
225     ea.addr_type = ADDR_LINES;
226 
227     parse_command_modifiers(&ea, &dummy, TRUE);
228     cmdmod = save_cmdmod;
229 
230     cmd = skip_range(ea.cmd, NULL);
231     if (vim_strchr((char_u *)"sgvl", *cmd) == NULL)
232 	goto theend;
233 
234     // Skip over "substitute" to find the pattern separator.
235     for (p = cmd; ASCII_ISALPHA(*p); ++p)
236 	;
237     if (*skipwhite(p) == NUL)
238 	goto theend;
239 
240     if (STRNCMP(cmd, "substitute", p - cmd) == 0
241 	    || STRNCMP(cmd, "smagic", p - cmd) == 0
242 	    || STRNCMP(cmd, "snomagic", MAX(p - cmd, 3)) == 0
243 	    || STRNCMP(cmd, "vglobal", p - cmd) == 0)
244     {
245 	if (*cmd == 's' && cmd[1] == 'm')
246 	    p_magic = TRUE;
247 	else if (*cmd == 's' && cmd[1] == 'n')
248 	    p_magic = FALSE;
249     }
250     else if (STRNCMP(cmd, "sort", MAX(p - cmd, 3)) == 0)
251     {
252 	// skip over ! and flags
253 	if (*p == '!')
254 	    p = skipwhite(p + 1);
255 	while (ASCII_ISALPHA(*(p = skipwhite(p))))
256 	    ++p;
257 	if (*p == NUL)
258 	    goto theend;
259     }
260     else if (STRNCMP(cmd, "vimgrep", MAX(p - cmd, 3)) == 0
261 	|| STRNCMP(cmd, "vimgrepadd", MAX(p - cmd, 8)) == 0
262 	|| STRNCMP(cmd, "lvimgrep", MAX(p - cmd, 2)) == 0
263 	|| STRNCMP(cmd, "lvimgrepadd", MAX(p - cmd, 9)) == 0
264 	|| STRNCMP(cmd, "global", p - cmd) == 0)
265     {
266 	// skip over "!"
267 	if (*p == '!')
268 	{
269 	    p++;
270 	    if (*skipwhite(p) == NUL)
271 		goto theend;
272 	}
273 	if (*cmd != 'g')
274 	    delim_optional = TRUE;
275     }
276     else
277 	goto theend;
278 
279     p = skipwhite(p);
280     delim = (delim_optional && vim_isIDc(*p)) ? ' ' : *p++;
281     *search_delim = delim;
282     end = skip_regexp(p, delim, p_magic);
283 
284     use_last_pat = end == p && *end == delim;
285 
286     if (end == p && !use_last_pat)
287 	goto theend;
288 
289     // Don't do 'hlsearch' highlighting if the pattern matches everything.
290     if (!use_last_pat)
291     {
292 	char c = *end;
293 	int  empty;
294 
295 	*end = NUL;
296 	empty = empty_pattern(p);
297 	*end = c;
298 	if (empty)
299 	    goto theend;
300     }
301 
302     // found a non-empty pattern or //
303     *skiplen = (int)(p - ccline.cmdbuff);
304     *patlen = (int)(end - p);
305 
306     // parse the address range
307     save_cursor = curwin->w_cursor;
308     curwin->w_cursor = is_state->search_start;
309     parse_cmd_address(&ea, &dummy, TRUE);
310     if (ea.addr_count > 0)
311     {
312 	// Allow for reverse match.
313 	if (ea.line2 < ea.line1)
314 	{
315 	    search_first_line = ea.line2;
316 	    search_last_line = ea.line1;
317 	}
318 	else
319 	{
320 	    search_first_line = ea.line1;
321 	    search_last_line = ea.line2;
322 	}
323     }
324     else if (cmd[0] == 's' && cmd[1] != 'o')
325     {
326 	// :s defaults to the current line
327 	search_first_line = curwin->w_cursor.lnum;
328 	search_last_line = curwin->w_cursor.lnum;
329     }
330 
331     curwin->w_cursor = save_cursor;
332     retval = TRUE;
333 theend:
334     --emsg_off;
335     return retval;
336 }
337 
338     static void
339 finish_incsearch_highlighting(
340 	int gotesc,
341 	incsearch_state_T *is_state,
342 	int call_update_screen)
343 {
344     if (is_state->did_incsearch)
345     {
346 	is_state->did_incsearch = FALSE;
347 	if (gotesc)
348 	    curwin->w_cursor = is_state->save_cursor;
349 	else
350 	{
351 	    if (!EQUAL_POS(is_state->save_cursor, is_state->search_start))
352 	    {
353 		// put the '" mark at the original position
354 		curwin->w_cursor = is_state->save_cursor;
355 		setpcmark();
356 	    }
357 	    curwin->w_cursor = is_state->search_start;
358 	}
359 	restore_viewstate(&is_state->old_viewstate);
360 	highlight_match = FALSE;
361 
362 	// by default search all lines
363 	search_first_line = 0;
364 	search_last_line = MAXLNUM;
365 
366 	p_magic = is_state->magic_save;
367 
368 	validate_cursor();	// needed for TAB
369 	redraw_all_later(SOME_VALID);
370 	if (call_update_screen)
371 	    update_screen(SOME_VALID);
372     }
373 }
374 
375 /*
376  * Do 'incsearch' highlighting if desired.
377  */
378     static void
379 may_do_incsearch_highlighting(
380 	int		    firstc,
381 	long		    count,
382 	incsearch_state_T   *is_state)
383 {
384     int		skiplen, patlen;
385     int		found;  // do_search() result
386     pos_T	end_pos;
387 #ifdef FEAT_RELTIME
388     proftime_T	tm;
389     searchit_arg_T sia;
390 #endif
391     int		next_char;
392     int		use_last_pat;
393     int		did_do_incsearch = is_state->did_incsearch;
394     int		search_delim;
395 
396     // Parsing range may already set the last search pattern.
397     // NOTE: must call restore_last_search_pattern() before returning!
398     save_last_search_pattern();
399 
400     if (!do_incsearch_highlighting(firstc, &search_delim, is_state, &skiplen, &patlen))
401     {
402 	restore_last_search_pattern();
403 	finish_incsearch_highlighting(FALSE, is_state, TRUE);
404 	if (did_do_incsearch && vpeekc() == NUL)
405 	    // may have skipped a redraw, do it now
406 	    redrawcmd();
407 	return;
408     }
409 
410     // If there is a character waiting, search and redraw later.
411     if (char_avail())
412     {
413 	restore_last_search_pattern();
414 	is_state->incsearch_postponed = TRUE;
415 	return;
416     }
417     is_state->incsearch_postponed = FALSE;
418 
419     if (search_first_line == 0)
420 	// start at the original cursor position
421 	curwin->w_cursor = is_state->search_start;
422     else if (search_first_line > curbuf->b_ml.ml_line_count)
423     {
424 	// start after the last line
425 	curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
426 	curwin->w_cursor.col = MAXCOL;
427     }
428     else
429     {
430 	// start at the first line in the range
431 	curwin->w_cursor.lnum = search_first_line;
432 	curwin->w_cursor.col = 0;
433     }
434 
435     // Use the previous pattern for ":s//".
436     next_char = ccline.cmdbuff[skiplen + patlen];
437     use_last_pat = patlen == 0 && skiplen > 0
438 				   && ccline.cmdbuff[skiplen - 1] == next_char;
439 
440     // If there is no pattern, don't do anything.
441     if (patlen == 0 && !use_last_pat)
442     {
443 	found = 0;
444 	set_no_hlsearch(TRUE); // turn off previous highlight
445 	redraw_all_later(SOME_VALID);
446     }
447     else
448     {
449 	int search_flags = SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK;
450 
451 	cursor_off();	// so the user knows we're busy
452 	out_flush();
453 	++emsg_off;	// so it doesn't beep if bad expr
454 #ifdef FEAT_RELTIME
455 	// Set the time limit to half a second.
456 	profile_setlimit(500L, &tm);
457 #endif
458 	if (!p_hls)
459 	    search_flags += SEARCH_KEEP;
460 	if (search_first_line != 0)
461 	    search_flags += SEARCH_START;
462 	ccline.cmdbuff[skiplen + patlen] = NUL;
463 #ifdef FEAT_RELTIME
464 	CLEAR_FIELD(sia);
465 	sia.sa_tm = &tm;
466 #endif
467 	found = do_search(NULL, firstc == ':' ? '/' : firstc, search_delim,
468 				 ccline.cmdbuff + skiplen, count, search_flags,
469 #ifdef FEAT_RELTIME
470 		&sia
471 #else
472 		NULL
473 #endif
474 		);
475 	ccline.cmdbuff[skiplen + patlen] = next_char;
476 	--emsg_off;
477 
478 	if (curwin->w_cursor.lnum < search_first_line
479 		|| curwin->w_cursor.lnum > search_last_line)
480 	{
481 	    // match outside of address range
482 	    found = 0;
483 	    curwin->w_cursor = is_state->search_start;
484 	}
485 
486 	// if interrupted while searching, behave like it failed
487 	if (got_int)
488 	{
489 	    (void)vpeekc();	// remove <C-C> from input stream
490 	    got_int = FALSE;	// don't abandon the command line
491 	    found = 0;
492 	}
493 	else if (char_avail())
494 	    // cancelled searching because a char was typed
495 	    is_state->incsearch_postponed = TRUE;
496     }
497     if (found != 0)
498 	highlight_match = TRUE;		// highlight position
499     else
500 	highlight_match = FALSE;	// remove highlight
501 
502     // First restore the old curwin values, so the screen is positioned in the
503     // same way as the actual search command.
504     restore_viewstate(&is_state->old_viewstate);
505     changed_cline_bef_curs();
506     update_topline();
507 
508     if (found != 0)
509     {
510 	pos_T	    save_pos = curwin->w_cursor;
511 
512 	is_state->match_start = curwin->w_cursor;
513 	set_search_match(&curwin->w_cursor);
514 	validate_cursor();
515 	end_pos = curwin->w_cursor;
516 	is_state->match_end = end_pos;
517 	curwin->w_cursor = save_pos;
518     }
519     else
520 	end_pos = curwin->w_cursor; // shutup gcc 4
521 
522     // Disable 'hlsearch' highlighting if the pattern matches everything.
523     // Avoids a flash when typing "foo\|".
524     if (!use_last_pat)
525     {
526 	next_char = ccline.cmdbuff[skiplen + patlen];
527 	ccline.cmdbuff[skiplen + patlen] = NUL;
528 	if (empty_pattern(ccline.cmdbuff) && !no_hlsearch)
529 	{
530 	    redraw_all_later(SOME_VALID);
531 	    set_no_hlsearch(TRUE);
532 	}
533 	ccline.cmdbuff[skiplen + patlen] = next_char;
534     }
535 
536     validate_cursor();
537     // May redraw the status line to show the cursor position.
538     if (p_ru && curwin->w_status_height > 0)
539 	curwin->w_redr_status = TRUE;
540 
541     update_screen(SOME_VALID);
542     highlight_match = FALSE;
543     restore_last_search_pattern();
544 
545     // Leave it at the end to make CTRL-R CTRL-W work.  But not when beyond the
546     // end of the pattern, e.g. for ":s/pat/".
547     if (ccline.cmdbuff[skiplen + patlen] != NUL)
548 	curwin->w_cursor = is_state->search_start;
549     else if (found != 0)
550 	curwin->w_cursor = end_pos;
551 
552     msg_starthere();
553     redrawcmdline();
554     is_state->did_incsearch = TRUE;
555 }
556 
557 /*
558  * May adjust 'incsearch' highlighting for typing CTRL-G and CTRL-T, go to next
559  * or previous match.
560  * Returns FAIL when jumping to cmdline_not_changed;
561  */
562     static int
563 may_adjust_incsearch_highlighting(
564 	int			firstc,
565 	long			count,
566 	incsearch_state_T	*is_state,
567 	int			c)
568 {
569     int	    skiplen, patlen;
570     pos_T   t;
571     char_u  *pat;
572     int	    search_flags = SEARCH_NOOF;
573     int	    i;
574     int	    save;
575     int	    search_delim;
576 
577     // Parsing range may already set the last search pattern.
578     // NOTE: must call restore_last_search_pattern() before returning!
579     save_last_search_pattern();
580 
581     if (!do_incsearch_highlighting(firstc, &search_delim, is_state, &skiplen, &patlen))
582     {
583 	restore_last_search_pattern();
584 	return OK;
585     }
586     if (patlen == 0 && ccline.cmdbuff[skiplen] == NUL)
587     {
588 	restore_last_search_pattern();
589 	return FAIL;
590     }
591 
592     if (search_delim == ccline.cmdbuff[skiplen])
593     {
594 	pat = last_search_pattern();
595 	skiplen = 0;
596 	patlen = (int)STRLEN(pat);
597     }
598     else
599 	pat = ccline.cmdbuff + skiplen;
600 
601     cursor_off();
602     out_flush();
603     if (c == Ctrl_G)
604     {
605 	t = is_state->match_end;
606 	if (LT_POS(is_state->match_start, is_state->match_end))
607 	    // Start searching at the end of the match not at the beginning of
608 	    // the next column.
609 	    (void)decl(&t);
610 	search_flags += SEARCH_COL;
611     }
612     else
613 	t = is_state->match_start;
614     if (!p_hls)
615 	search_flags += SEARCH_KEEP;
616     ++emsg_off;
617     save = pat[patlen];
618     pat[patlen] = NUL;
619     i = searchit(curwin, curbuf, &t, NULL,
620 		 c == Ctrl_G ? FORWARD : BACKWARD,
621 		 pat, count, search_flags, RE_SEARCH, NULL);
622     --emsg_off;
623     pat[patlen] = save;
624     if (i)
625     {
626 	is_state->search_start = is_state->match_start;
627 	is_state->match_end = t;
628 	is_state->match_start = t;
629 	if (c == Ctrl_T && firstc != '?')
630 	{
631 	    // Move just before the current match, so that when nv_search
632 	    // finishes the cursor will be put back on the match.
633 	    is_state->search_start = t;
634 	    (void)decl(&is_state->search_start);
635 	}
636 	else if (c == Ctrl_G && firstc == '?')
637 	{
638 	    // Move just after the current match, so that when nv_search
639 	    // finishes the cursor will be put back on the match.
640 	    is_state->search_start = t;
641 	    (void)incl(&is_state->search_start);
642 	}
643 	if (LT_POS(t, is_state->search_start) && c == Ctrl_G)
644 	{
645 	    // wrap around
646 	    is_state->search_start = t;
647 	    if (firstc == '?')
648 		(void)incl(&is_state->search_start);
649 	    else
650 		(void)decl(&is_state->search_start);
651 	}
652 
653 	set_search_match(&is_state->match_end);
654 	curwin->w_cursor = is_state->match_start;
655 	changed_cline_bef_curs();
656 	update_topline();
657 	validate_cursor();
658 	highlight_match = TRUE;
659 	save_viewstate(&is_state->old_viewstate);
660 	update_screen(NOT_VALID);
661 	highlight_match = FALSE;
662 	redrawcmdline();
663 	curwin->w_cursor = is_state->match_end;
664     }
665     else
666 	vim_beep(BO_ERROR);
667     restore_last_search_pattern();
668     return FAIL;
669 }
670 
671 /*
672  * When CTRL-L typed: add character from the match to the pattern.
673  * May set "*c" to the added character.
674  * Return OK when jumping to cmdline_not_changed.
675  */
676     static int
677 may_add_char_to_search(int firstc, int *c, incsearch_state_T *is_state)
678 {
679     int		skiplen, patlen, search_delim;
680 
681     // Parsing range may already set the last search pattern.
682     // NOTE: must call restore_last_search_pattern() before returning!
683     save_last_search_pattern();
684 
685     if (!do_incsearch_highlighting(firstc, &search_delim, is_state, &skiplen, &patlen))
686     {
687 	restore_last_search_pattern();
688 	return FAIL;
689     }
690     restore_last_search_pattern();
691 
692     // Add a character from under the cursor for 'incsearch'.
693     if (is_state->did_incsearch)
694     {
695 	curwin->w_cursor = is_state->match_end;
696 	*c = gchar_cursor();
697 	if (*c != NUL)
698 	{
699 	    // If 'ignorecase' and 'smartcase' are set and the
700 	    // command line has no uppercase characters, convert
701 	    // the character to lowercase.
702 	    if (p_ic && p_scs && !pat_has_uppercase(ccline.cmdbuff + skiplen))
703 		*c = MB_TOLOWER(*c);
704 	    if (*c == search_delim || vim_strchr((char_u *)(
705 			       p_magic ? "\\~^$.*[" : "\\^$"), *c) != NULL)
706 	    {
707 		// put a backslash before special characters
708 		stuffcharReadbuff(*c);
709 		*c = '\\';
710 	    }
711 	    // add any composing characters
712 	    if (mb_char2len(*c) != mb_ptr2len(ml_get_cursor()))
713 	    {
714 		int save_c = *c;
715 
716 		while (mb_char2len(*c) != mb_ptr2len(ml_get_cursor()))
717 		{
718 		    curwin->w_cursor.col += mb_char2len(*c);
719 		    *c = gchar_cursor();
720 		    stuffcharReadbuff(*c);
721 		}
722 		*c = save_c;
723 	    }
724 	    return FAIL;
725 	}
726     }
727     return OK;
728 }
729 #endif
730 
731 #ifdef FEAT_ARABIC
732 /*
733  * Return TRUE if the command line has an Arabic character at or after "start"
734  * for "len" bytes.
735  */
736     static int
737 cmdline_has_arabic(int start, int len)
738 {
739     int	    j;
740     int	    mb_l;
741     int	    u8c;
742     char_u  *p;
743     int	    u8cc[MAX_MCO];
744 
745     if (!enc_utf8)
746 	return FALSE;
747 
748     for (j = start; j < start + len; j += mb_l)
749     {
750 	p = ccline.cmdbuff + j;
751 	u8c = utfc_ptr2char_len(p, u8cc, start + len - j);
752 	mb_l = utfc_ptr2len_len(p, start + len - j);
753 	if (ARABIC_CHAR(u8c))
754 	    return TRUE;
755     }
756     return FALSE;
757 }
758 #endif
759 
760     void
761 cmdline_init(void)
762 {
763     CLEAR_FIELD(ccline);
764 }
765 
766 /*
767  * getcmdline() - accept a command line starting with firstc.
768  *
769  * firstc == ':'	    get ":" command line.
770  * firstc == '/' or '?'	    get search pattern
771  * firstc == '='	    get expression
772  * firstc == '@'	    get text for input() function
773  * firstc == '>'	    get text for debug mode
774  * firstc == NUL	    get text for :insert command
775  * firstc == -1		    like NUL, and break on CTRL-C
776  *
777  * The line is collected in ccline.cmdbuff, which is reallocated to fit the
778  * command line.
779  *
780  * Careful: getcmdline() can be called recursively!
781  *
782  * Return pointer to allocated string if there is a commandline, NULL
783  * otherwise.
784  */
785     char_u *
786 getcmdline(
787     int		firstc,
788     long	count,		// only used for incremental search
789     int		indent,		// indent for inside conditionals
790     int		do_concat UNUSED)
791 {
792     return getcmdline_int(firstc, count, indent, TRUE);
793 }
794 
795     static char_u *
796 getcmdline_int(
797     int		firstc,
798     long	count UNUSED,	// only used for incremental search
799     int		indent,		// indent for inside conditionals
800     int		init_ccline)	// clear ccline first
801 {
802     int		c;
803     int		i;
804     int		j;
805     int		gotesc = FALSE;		// TRUE when <ESC> just typed
806     int		do_abbr;		// when TRUE check for abbr.
807     char_u	*lookfor = NULL;	// string to match
808     int		hiscnt;			// current history line in use
809     int		histype;		// history type to be used
810 #ifdef FEAT_SEARCH_EXTRA
811     incsearch_state_T	is_state;
812 #endif
813     int		did_wild_list = FALSE;	// did wild_list() recently
814     int		wim_index = 0;		// index in wim_flags[]
815     int		res;
816     int		save_msg_scroll = msg_scroll;
817     int		save_State = State;	// remember State when called
818     int		some_key_typed = FALSE;	// one of the keys was typed
819     // mouse drag and release events are ignored, unless they are
820     // preceded with a mouse down event
821     int		ignore_drag_release = TRUE;
822 #ifdef FEAT_EVAL
823     int		break_ctrl_c = FALSE;
824 #endif
825     expand_T	xpc;
826     long	*b_im_ptr = NULL;
827     cmdline_info_T save_ccline;
828     int		did_save_ccline = FALSE;
829     int		cmdline_type;
830 
831     if (ccline.cmdbuff != NULL)
832     {
833 	// Being called recursively.  Since ccline is global, we need to save
834 	// the current buffer and restore it when returning.
835 	save_cmdline(&save_ccline);
836 	did_save_ccline = TRUE;
837     }
838     if (init_ccline)
839 	CLEAR_FIELD(ccline);
840 
841 #ifdef FEAT_EVAL
842     if (firstc == -1)
843     {
844 	firstc = NUL;
845 	break_ctrl_c = TRUE;
846     }
847 #endif
848 #ifdef FEAT_RIGHTLEFT
849     // start without Hebrew mapping for a command line
850     if (firstc == ':' || firstc == '=' || firstc == '>')
851 	cmd_hkmap = 0;
852 #endif
853 
854     ccline.overstrike = FALSE;		    // always start in insert mode
855 
856 #ifdef FEAT_SEARCH_EXTRA
857     init_incsearch_state(&is_state);
858 #endif
859 
860     /*
861      * set some variables for redrawcmd()
862      */
863     ccline.cmdfirstc = (firstc == '@' ? 0 : firstc);
864     ccline.cmdindent = (firstc > 0 ? indent : 0);
865 
866     // alloc initial ccline.cmdbuff
867     alloc_cmdbuff(exmode_active ? 250 : indent + 1);
868     if (ccline.cmdbuff == NULL)
869 	goto theend;	// out of memory
870     ccline.cmdlen = ccline.cmdpos = 0;
871     ccline.cmdbuff[0] = NUL;
872     sb_text_start_cmdline();
873 
874     // autoindent for :insert and :append
875     if (firstc <= 0)
876     {
877 	vim_memset(ccline.cmdbuff, ' ', indent);
878 	ccline.cmdbuff[indent] = NUL;
879 	ccline.cmdpos = indent;
880 	ccline.cmdspos = indent;
881 	ccline.cmdlen = indent;
882     }
883 
884     ExpandInit(&xpc);
885     ccline.xpc = &xpc;
886 
887 #ifdef FEAT_RIGHTLEFT
888     if (curwin->w_p_rl && *curwin->w_p_rlc == 's'
889 					  && (firstc == '/' || firstc == '?'))
890 	cmdmsg_rl = TRUE;
891     else
892 	cmdmsg_rl = FALSE;
893 #endif
894 
895     redir_off = TRUE;		// don't redirect the typed command
896     if (!cmd_silent)
897     {
898 	i = msg_scrolled;
899 	msg_scrolled = 0;		// avoid wait_return message
900 	gotocmdline(TRUE);
901 	msg_scrolled += i;
902 	redrawcmdprompt();		// draw prompt or indent
903 	set_cmdspos();
904     }
905     xpc.xp_context = EXPAND_NOTHING;
906     xpc.xp_backslash = XP_BS_NONE;
907 #ifndef BACKSLASH_IN_FILENAME
908     xpc.xp_shell = FALSE;
909 #endif
910 
911 #if defined(FEAT_EVAL)
912     if (ccline.input_fn)
913     {
914 	xpc.xp_context = ccline.xp_context;
915 	xpc.xp_pattern = ccline.cmdbuff;
916 	xpc.xp_arg = ccline.xp_arg;
917     }
918 #endif
919 
920     /*
921      * Avoid scrolling when called by a recursive do_cmdline(), e.g. when
922      * doing ":@0" when register 0 doesn't contain a CR.
923      */
924     msg_scroll = FALSE;
925 
926     State = CMDLINE;
927 
928     if (firstc == '/' || firstc == '?' || firstc == '@')
929     {
930 	// Use ":lmap" mappings for search pattern and input().
931 	if (curbuf->b_p_imsearch == B_IMODE_USE_INSERT)
932 	    b_im_ptr = &curbuf->b_p_iminsert;
933 	else
934 	    b_im_ptr = &curbuf->b_p_imsearch;
935 	if (*b_im_ptr == B_IMODE_LMAP)
936 	    State |= LANGMAP;
937 #ifdef HAVE_INPUT_METHOD
938 	im_set_active(*b_im_ptr == B_IMODE_IM);
939 #endif
940     }
941 #ifdef HAVE_INPUT_METHOD
942     else if (p_imcmdline)
943 	im_set_active(TRUE);
944 #endif
945 
946     setmouse();
947 #ifdef CURSOR_SHAPE
948     ui_cursor_shape();		// may show different cursor shape
949 #endif
950 
951     // When inside an autocommand for writing "exiting" may be set and
952     // terminal mode set to cooked.  Need to set raw mode here then.
953     settmode(TMODE_RAW);
954 
955     // Trigger CmdlineEnter autocommands.
956     cmdline_type = firstc == NUL ? '-' : firstc;
957     trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINEENTER);
958 
959     init_history();
960     hiscnt = get_hislen();	// set hiscnt to impossible history value
961     histype = hist_char2type(firstc);
962 
963 #ifdef FEAT_DIGRAPHS
964     do_digraph(-1);		// init digraph typeahead
965 #endif
966 
967     // If something above caused an error, reset the flags, we do want to type
968     // and execute commands. Display may be messed up a bit.
969     if (did_emsg)
970 	redrawcmd();
971     did_emsg = FALSE;
972     got_int = FALSE;
973 
974     /*
975      * Collect the command string, handling editing keys.
976      */
977     for (;;)
978     {
979 	redir_off = TRUE;	// Don't redirect the typed command.
980 				// Repeated, because a ":redir" inside
981 				// completion may switch it on.
982 #ifdef USE_ON_FLY_SCROLL
983 	dont_scroll = FALSE;	// allow scrolling here
984 #endif
985 	quit_more = FALSE;	// reset after CTRL-D which had a more-prompt
986 
987 	did_emsg = FALSE;	// There can't really be a reason why an error
988 				// that occurs while typing a command should
989 				// cause the command not to be executed.
990 
991 	// Trigger SafeState if nothing is pending.
992 	may_trigger_safestate(xpc.xp_numfiles <= 0);
993 
994 	cursorcmd();		// set the cursor on the right spot
995 
996 	// Get a character.  Ignore K_IGNORE and K_NOP, they should not do
997 	// anything, such as stop completion.
998 	do
999 	    c = safe_vgetc();
1000 	while (c == K_IGNORE || c == K_NOP);
1001 
1002 	if (KeyTyped)
1003 	{
1004 	    some_key_typed = TRUE;
1005 #ifdef FEAT_RIGHTLEFT
1006 	    if (cmd_hkmap)
1007 		c = hkmap(c);
1008 	    if (cmdmsg_rl && !KeyStuffed)
1009 	    {
1010 		// Invert horizontal movements and operations.  Only when
1011 		// typed by the user directly, not when the result of a
1012 		// mapping.
1013 		switch (c)
1014 		{
1015 		    case K_RIGHT:   c = K_LEFT; break;
1016 		    case K_S_RIGHT: c = K_S_LEFT; break;
1017 		    case K_C_RIGHT: c = K_C_LEFT; break;
1018 		    case K_LEFT:    c = K_RIGHT; break;
1019 		    case K_S_LEFT:  c = K_S_RIGHT; break;
1020 		    case K_C_LEFT:  c = K_C_RIGHT; break;
1021 		}
1022 	    }
1023 #endif
1024 	}
1025 
1026 	/*
1027 	 * Ignore got_int when CTRL-C was typed here.
1028 	 * Don't ignore it in :global, we really need to break then, e.g., for
1029 	 * ":g/pat/normal /pat" (without the <CR>).
1030 	 * Don't ignore it for the input() function.
1031 	 */
1032 	if ((c == Ctrl_C
1033 #ifdef UNIX
1034 		|| c == intr_char
1035 #endif
1036 				)
1037 #if defined(FEAT_EVAL) || defined(FEAT_CRYPT)
1038 		&& firstc != '@'
1039 #endif
1040 #ifdef FEAT_EVAL
1041 		&& !break_ctrl_c
1042 #endif
1043 		&& !global_busy)
1044 	    got_int = FALSE;
1045 
1046 	// free old command line when finished moving around in the history
1047 	// list
1048 	if (lookfor != NULL
1049 		&& c != K_S_DOWN && c != K_S_UP
1050 		&& c != K_DOWN && c != K_UP
1051 		&& c != K_PAGEDOWN && c != K_PAGEUP
1052 		&& c != K_KPAGEDOWN && c != K_KPAGEUP
1053 		&& c != K_LEFT && c != K_RIGHT
1054 		&& (xpc.xp_numfiles > 0 || (c != Ctrl_P && c != Ctrl_N)))
1055 	    VIM_CLEAR(lookfor);
1056 
1057 	/*
1058 	 * When there are matching completions to select <S-Tab> works like
1059 	 * CTRL-P (unless 'wc' is <S-Tab>).
1060 	 */
1061 	if (c != p_wc && c == K_S_TAB && xpc.xp_numfiles > 0)
1062 	    c = Ctrl_P;
1063 
1064 #ifdef FEAT_WILDMENU
1065 	// Special translations for 'wildmenu'
1066 	if (did_wild_list && p_wmnu)
1067 	{
1068 	    if (c == K_LEFT)
1069 		c = Ctrl_P;
1070 	    else if (c == K_RIGHT)
1071 		c = Ctrl_N;
1072 	}
1073 	// Hitting CR after "emenu Name.": complete submenu
1074 	if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu
1075 		&& ccline.cmdpos > 1
1076 		&& ccline.cmdbuff[ccline.cmdpos - 1] == '.'
1077 		&& ccline.cmdbuff[ccline.cmdpos - 2] != '\\'
1078 		&& (c == '\n' || c == '\r' || c == K_KENTER))
1079 	    c = K_DOWN;
1080 #endif
1081 
1082 	// free expanded names when finished walking through matches
1083 	if (xpc.xp_numfiles != -1
1084 		&& !(c == p_wc && KeyTyped) && c != p_wcm
1085 		&& c != Ctrl_N && c != Ctrl_P && c != Ctrl_A
1086 		&& c != Ctrl_L)
1087 	{
1088 	    (void)ExpandOne(&xpc, NULL, NULL, 0, WILD_FREE);
1089 	    did_wild_list = FALSE;
1090 #ifdef FEAT_WILDMENU
1091 	    if (!p_wmnu || (c != K_UP && c != K_DOWN))
1092 #endif
1093 		xpc.xp_context = EXPAND_NOTHING;
1094 	    wim_index = 0;
1095 #ifdef FEAT_WILDMENU
1096 	    if (p_wmnu && wild_menu_showing != 0)
1097 	    {
1098 		int skt = KeyTyped;
1099 		int old_RedrawingDisabled = RedrawingDisabled;
1100 
1101 		if (ccline.input_fn)
1102 		    RedrawingDisabled = 0;
1103 
1104 		if (wild_menu_showing == WM_SCROLLED)
1105 		{
1106 		    // Entered command line, move it up
1107 		    cmdline_row--;
1108 		    redrawcmd();
1109 		}
1110 		else if (save_p_ls != -1)
1111 		{
1112 		    // restore 'laststatus' and 'winminheight'
1113 		    p_ls = save_p_ls;
1114 		    p_wmh = save_p_wmh;
1115 		    last_status(FALSE);
1116 		    update_screen(VALID);	// redraw the screen NOW
1117 		    redrawcmd();
1118 		    save_p_ls = -1;
1119 		}
1120 		else
1121 		{
1122 		    win_redraw_last_status(topframe);
1123 		    redraw_statuslines();
1124 		}
1125 		KeyTyped = skt;
1126 		wild_menu_showing = 0;
1127 		if (ccline.input_fn)
1128 		    RedrawingDisabled = old_RedrawingDisabled;
1129 	    }
1130 #endif
1131 	}
1132 
1133 #ifdef FEAT_WILDMENU
1134 	// Special translations for 'wildmenu'
1135 	if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu)
1136 	{
1137 	    // Hitting <Down> after "emenu Name.": complete submenu
1138 	    if (c == K_DOWN && ccline.cmdpos > 0
1139 				  && ccline.cmdbuff[ccline.cmdpos - 1] == '.')
1140 		c = p_wc;
1141 	    else if (c == K_UP)
1142 	    {
1143 		// Hitting <Up>: Remove one submenu name in front of the
1144 		// cursor
1145 		int found = FALSE;
1146 
1147 		j = (int)(xpc.xp_pattern - ccline.cmdbuff);
1148 		i = 0;
1149 		while (--j > 0)
1150 		{
1151 		    // check for start of menu name
1152 		    if (ccline.cmdbuff[j] == ' '
1153 			    && ccline.cmdbuff[j - 1] != '\\')
1154 		    {
1155 			i = j + 1;
1156 			break;
1157 		    }
1158 		    // check for start of submenu name
1159 		    if (ccline.cmdbuff[j] == '.'
1160 			    && ccline.cmdbuff[j - 1] != '\\')
1161 		    {
1162 			if (found)
1163 			{
1164 			    i = j + 1;
1165 			    break;
1166 			}
1167 			else
1168 			    found = TRUE;
1169 		    }
1170 		}
1171 		if (i > 0)
1172 		    cmdline_del(i);
1173 		c = p_wc;
1174 		xpc.xp_context = EXPAND_NOTHING;
1175 	    }
1176 	}
1177 	if ((xpc.xp_context == EXPAND_FILES
1178 			      || xpc.xp_context == EXPAND_DIRECTORIES
1179 			      || xpc.xp_context == EXPAND_SHELLCMD) && p_wmnu)
1180 	{
1181 	    char_u upseg[5];
1182 
1183 	    upseg[0] = PATHSEP;
1184 	    upseg[1] = '.';
1185 	    upseg[2] = '.';
1186 	    upseg[3] = PATHSEP;
1187 	    upseg[4] = NUL;
1188 
1189 	    if (c == K_DOWN
1190 		    && ccline.cmdpos > 0
1191 		    && ccline.cmdbuff[ccline.cmdpos - 1] == PATHSEP
1192 		    && (ccline.cmdpos < 3
1193 			|| ccline.cmdbuff[ccline.cmdpos - 2] != '.'
1194 			|| ccline.cmdbuff[ccline.cmdpos - 3] != '.'))
1195 	    {
1196 		// go down a directory
1197 		c = p_wc;
1198 	    }
1199 	    else if (STRNCMP(xpc.xp_pattern, upseg + 1, 3) == 0 && c == K_DOWN)
1200 	    {
1201 		// If in a direct ancestor, strip off one ../ to go down
1202 		int found = FALSE;
1203 
1204 		j = ccline.cmdpos;
1205 		i = (int)(xpc.xp_pattern - ccline.cmdbuff);
1206 		while (--j > i)
1207 		{
1208 		    if (has_mbyte)
1209 			j -= (*mb_head_off)(ccline.cmdbuff, ccline.cmdbuff + j);
1210 		    if (vim_ispathsep(ccline.cmdbuff[j]))
1211 		    {
1212 			found = TRUE;
1213 			break;
1214 		    }
1215 		}
1216 		if (found
1217 			&& ccline.cmdbuff[j - 1] == '.'
1218 			&& ccline.cmdbuff[j - 2] == '.'
1219 			&& (vim_ispathsep(ccline.cmdbuff[j - 3]) || j == i + 2))
1220 		{
1221 		    cmdline_del(j - 2);
1222 		    c = p_wc;
1223 		}
1224 	    }
1225 	    else if (c == K_UP)
1226 	    {
1227 		// go up a directory
1228 		int found = FALSE;
1229 
1230 		j = ccline.cmdpos - 1;
1231 		i = (int)(xpc.xp_pattern - ccline.cmdbuff);
1232 		while (--j > i)
1233 		{
1234 		    if (has_mbyte)
1235 			j -= (*mb_head_off)(ccline.cmdbuff, ccline.cmdbuff + j);
1236 		    if (vim_ispathsep(ccline.cmdbuff[j])
1237 #ifdef BACKSLASH_IN_FILENAME
1238 			    && vim_strchr((char_u *)" *?[{`$%#",
1239 				ccline.cmdbuff[j + 1]) == NULL
1240 #endif
1241 		       )
1242 		    {
1243 			if (found)
1244 			{
1245 			    i = j + 1;
1246 			    break;
1247 			}
1248 			else
1249 			    found = TRUE;
1250 		    }
1251 		}
1252 
1253 		if (!found)
1254 		    j = i;
1255 		else if (STRNCMP(ccline.cmdbuff + j, upseg, 4) == 0)
1256 		    j += 4;
1257 		else if (STRNCMP(ccline.cmdbuff + j, upseg + 1, 3) == 0
1258 			     && j == i)
1259 		    j += 3;
1260 		else
1261 		    j = 0;
1262 		if (j > 0)
1263 		{
1264 		    // TODO this is only for DOS/UNIX systems - need to put in
1265 		    // machine-specific stuff here and in upseg init
1266 		    cmdline_del(j);
1267 		    put_on_cmdline(upseg + 1, 3, FALSE);
1268 		}
1269 		else if (ccline.cmdpos > i)
1270 		    cmdline_del(i);
1271 
1272 		// Now complete in the new directory. Set KeyTyped in case the
1273 		// Up key came from a mapping.
1274 		c = p_wc;
1275 		KeyTyped = TRUE;
1276 	    }
1277 	}
1278 
1279 #endif	// FEAT_WILDMENU
1280 
1281 	// CTRL-\ CTRL-N goes to Normal mode, CTRL-\ CTRL-G goes to Insert
1282 	// mode when 'insertmode' is set, CTRL-\ e prompts for an expression.
1283 	if (c == Ctrl_BSL)
1284 	{
1285 	    ++no_mapping;
1286 	    ++allow_keys;
1287 	    c = plain_vgetc();
1288 	    --no_mapping;
1289 	    --allow_keys;
1290 	    // CTRL-\ e doesn't work when obtaining an expression, unless it
1291 	    // is in a mapping.
1292 	    if (c != Ctrl_N && c != Ctrl_G && (c != 'e'
1293 				    || (ccline.cmdfirstc == '=' && KeyTyped)
1294 #ifdef FEAT_EVAL
1295 				    || cmdline_star > 0
1296 #endif
1297 				    ))
1298 	    {
1299 		vungetc(c);
1300 		c = Ctrl_BSL;
1301 	    }
1302 #ifdef FEAT_EVAL
1303 	    else if (c == 'e')
1304 	    {
1305 		char_u	*p = NULL;
1306 		int	len;
1307 
1308 		/*
1309 		 * Replace the command line with the result of an expression.
1310 		 * Need to save and restore the current command line, to be
1311 		 * able to enter a new one...
1312 		 */
1313 		if (ccline.cmdpos == ccline.cmdlen)
1314 		    new_cmdpos = 99999;	// keep it at the end
1315 		else
1316 		    new_cmdpos = ccline.cmdpos;
1317 
1318 		c = get_expr_register();
1319 		if (c == '=')
1320 		{
1321 		    // Need to save and restore ccline.  And set "textwinlock"
1322 		    // to avoid nasty things like going to another buffer when
1323 		    // evaluating an expression.
1324 		    ++textwinlock;
1325 		    p = get_expr_line();
1326 		    --textwinlock;
1327 
1328 		    if (p != NULL)
1329 		    {
1330 			len = (int)STRLEN(p);
1331 			if (realloc_cmdbuff(len + 1) == OK)
1332 			{
1333 			    ccline.cmdlen = len;
1334 			    STRCPY(ccline.cmdbuff, p);
1335 			    vim_free(p);
1336 
1337 			    // Restore the cursor or use the position set with
1338 			    // set_cmdline_pos().
1339 			    if (new_cmdpos > ccline.cmdlen)
1340 				ccline.cmdpos = ccline.cmdlen;
1341 			    else
1342 				ccline.cmdpos = new_cmdpos;
1343 
1344 			    KeyTyped = FALSE;	// Don't do p_wc completion.
1345 			    redrawcmd();
1346 			    goto cmdline_changed;
1347 			}
1348 			vim_free(p);
1349 		    }
1350 		}
1351 		beep_flush();
1352 		got_int = FALSE;	// don't abandon the command line
1353 		did_emsg = FALSE;
1354 		emsg_on_display = FALSE;
1355 		redrawcmd();
1356 		goto cmdline_not_changed;
1357 	    }
1358 #endif
1359 	    else
1360 	    {
1361 		if (c == Ctrl_G && p_im && restart_edit == 0)
1362 		    restart_edit = 'a';
1363 		gotesc = TRUE;	// will free ccline.cmdbuff after putting it
1364 				// in history
1365 		goto returncmd;	// back to Normal mode
1366 	    }
1367 	}
1368 
1369 #ifdef FEAT_CMDWIN
1370 	if (c == cedit_key || c == K_CMDWIN)
1371 	{
1372 	    // TODO: why is ex_normal_busy checked here?
1373 	    if ((c == K_CMDWIN || ex_normal_busy == 0) && got_int == FALSE)
1374 	    {
1375 		/*
1376 		 * Open a window to edit the command line (and history).
1377 		 */
1378 		c = open_cmdwin();
1379 		some_key_typed = TRUE;
1380 	    }
1381 	}
1382 # ifdef FEAT_DIGRAPHS
1383 	else
1384 # endif
1385 #endif
1386 #ifdef FEAT_DIGRAPHS
1387 	    c = do_digraph(c);
1388 #endif
1389 
1390 	if (c == '\n' || c == '\r' || c == K_KENTER || (c == ESC
1391 			&& (!KeyTyped || vim_strchr(p_cpo, CPO_ESC) != NULL)))
1392 	{
1393 	    // In Ex mode a backslash escapes a newline.
1394 	    if (exmode_active
1395 		    && c != ESC
1396 		    && ccline.cmdpos == ccline.cmdlen
1397 		    && ccline.cmdpos > 0
1398 		    && ccline.cmdbuff[ccline.cmdpos - 1] == '\\')
1399 	    {
1400 		if (c == K_KENTER)
1401 		    c = '\n';
1402 	    }
1403 	    else
1404 	    {
1405 		gotesc = FALSE;	// Might have typed ESC previously, don't
1406 				// truncate the cmdline now.
1407 		if (ccheck_abbr(c + ABBR_OFF))
1408 		    goto cmdline_changed;
1409 		if (!cmd_silent)
1410 		{
1411 		    windgoto(msg_row, 0);
1412 		    out_flush();
1413 		}
1414 		break;
1415 	    }
1416 	}
1417 
1418 	/*
1419 	 * Completion for 'wildchar' or 'wildcharm' key.
1420 	 * - hitting <ESC> twice means: abandon command line.
1421 	 * - wildcard expansion is only done when the 'wildchar' key is really
1422 	 *   typed, not when it comes from a macro
1423 	 */
1424 	if ((c == p_wc && !gotesc && KeyTyped) || c == p_wcm)
1425 	{
1426 	    int options = WILD_NO_BEEP;
1427 	    if (wim_flags[wim_index] & WIM_BUFLASTUSED)
1428 		options |= WILD_BUFLASTUSED;
1429 	    if (xpc.xp_numfiles > 0)   // typed p_wc at least twice
1430 	    {
1431 		// if 'wildmode' contains "list" may still need to list
1432 		if (xpc.xp_numfiles > 1
1433 			&& !did_wild_list
1434 			&& (wim_flags[wim_index] & WIM_LIST))
1435 		{
1436 		    (void)showmatches(&xpc, FALSE);
1437 		    redrawcmd();
1438 		    did_wild_list = TRUE;
1439 		}
1440 		if (wim_flags[wim_index] & WIM_LONGEST)
1441 		    res = nextwild(&xpc, WILD_LONGEST, options,
1442 							       firstc != '@');
1443 		else if (wim_flags[wim_index] & WIM_FULL)
1444 		    res = nextwild(&xpc, WILD_NEXT, options,
1445 							       firstc != '@');
1446 		else
1447 		    res = OK;	    // don't insert 'wildchar' now
1448 	    }
1449 	    else		    // typed p_wc first time
1450 	    {
1451 		wim_index = 0;
1452 		j = ccline.cmdpos;
1453 		// if 'wildmode' first contains "longest", get longest
1454 		// common part
1455 		if (wim_flags[0] & WIM_LONGEST)
1456 		    res = nextwild(&xpc, WILD_LONGEST, options,
1457 							       firstc != '@');
1458 		else
1459 		    res = nextwild(&xpc, WILD_EXPAND_KEEP, options,
1460 							       firstc != '@');
1461 
1462 		// if interrupted while completing, behave like it failed
1463 		if (got_int)
1464 		{
1465 		    (void)vpeekc();	// remove <C-C> from input stream
1466 		    got_int = FALSE;	// don't abandon the command line
1467 		    (void)ExpandOne(&xpc, NULL, NULL, 0, WILD_FREE);
1468 #ifdef FEAT_WILDMENU
1469 		    xpc.xp_context = EXPAND_NOTHING;
1470 #endif
1471 		    goto cmdline_changed;
1472 		}
1473 
1474 		// when more than one match, and 'wildmode' first contains
1475 		// "list", or no change and 'wildmode' contains "longest,list",
1476 		// list all matches
1477 		if (res == OK && xpc.xp_numfiles > 1)
1478 		{
1479 		    // a "longest" that didn't do anything is skipped (but not
1480 		    // "list:longest")
1481 		    if (wim_flags[0] == WIM_LONGEST && ccline.cmdpos == j)
1482 			wim_index = 1;
1483 		    if ((wim_flags[wim_index] & WIM_LIST)
1484 #ifdef FEAT_WILDMENU
1485 			    || (p_wmnu && (wim_flags[wim_index] & WIM_FULL) != 0)
1486 #endif
1487 			    )
1488 		    {
1489 			if (!(wim_flags[0] & WIM_LONGEST))
1490 			{
1491 #ifdef FEAT_WILDMENU
1492 			    int p_wmnu_save = p_wmnu;
1493 			    p_wmnu = 0;
1494 #endif
1495 			    // remove match
1496 			    nextwild(&xpc, WILD_PREV, 0, firstc != '@');
1497 #ifdef FEAT_WILDMENU
1498 			    p_wmnu = p_wmnu_save;
1499 #endif
1500 			}
1501 #ifdef FEAT_WILDMENU
1502 			(void)showmatches(&xpc, p_wmnu
1503 				&& ((wim_flags[wim_index] & WIM_LIST) == 0));
1504 #else
1505 			(void)showmatches(&xpc, FALSE);
1506 #endif
1507 			redrawcmd();
1508 			did_wild_list = TRUE;
1509 			if (wim_flags[wim_index] & WIM_LONGEST)
1510 			    nextwild(&xpc, WILD_LONGEST, options,
1511 							       firstc != '@');
1512 			else if (wim_flags[wim_index] & WIM_FULL)
1513 			    nextwild(&xpc, WILD_NEXT, options,
1514 							       firstc != '@');
1515 		    }
1516 		    else
1517 			vim_beep(BO_WILD);
1518 		}
1519 #ifdef FEAT_WILDMENU
1520 		else if (xpc.xp_numfiles == -1)
1521 		    xpc.xp_context = EXPAND_NOTHING;
1522 #endif
1523 	    }
1524 	    if (wim_index < 3)
1525 		++wim_index;
1526 	    if (c == ESC)
1527 		gotesc = TRUE;
1528 	    if (res == OK)
1529 		goto cmdline_changed;
1530 	}
1531 
1532 	gotesc = FALSE;
1533 
1534 	// <S-Tab> goes to last match, in a clumsy way
1535 	if (c == K_S_TAB && KeyTyped)
1536 	{
1537 	    if (nextwild(&xpc, WILD_EXPAND_KEEP, 0, firstc != '@') == OK
1538 		    && nextwild(&xpc, WILD_PREV, 0, firstc != '@') == OK
1539 		    && nextwild(&xpc, WILD_PREV, 0, firstc != '@') == OK)
1540 		goto cmdline_changed;
1541 	}
1542 
1543 	if (c == NUL || c == K_ZERO)	    // NUL is stored as NL
1544 	    c = NL;
1545 
1546 	do_abbr = TRUE;		// default: check for abbreviation
1547 
1548 	/*
1549 	 * Big switch for a typed command line character.
1550 	 */
1551 	switch (c)
1552 	{
1553 	case K_BS:
1554 	case Ctrl_H:
1555 	case K_DEL:
1556 	case K_KDEL:
1557 	case Ctrl_W:
1558 		if (c == K_KDEL)
1559 		    c = K_DEL;
1560 
1561 		/*
1562 		 * delete current character is the same as backspace on next
1563 		 * character, except at end of line
1564 		 */
1565 		if (c == K_DEL && ccline.cmdpos != ccline.cmdlen)
1566 		    ++ccline.cmdpos;
1567 		if (has_mbyte && c == K_DEL)
1568 		    ccline.cmdpos += mb_off_next(ccline.cmdbuff,
1569 					      ccline.cmdbuff + ccline.cmdpos);
1570 		if (ccline.cmdpos > 0)
1571 		{
1572 		    char_u *p;
1573 
1574 		    j = ccline.cmdpos;
1575 		    p = ccline.cmdbuff + j;
1576 		    if (has_mbyte)
1577 		    {
1578 			p = mb_prevptr(ccline.cmdbuff, p);
1579 			if (c == Ctrl_W)
1580 			{
1581 			    while (p > ccline.cmdbuff && vim_isspace(*p))
1582 				p = mb_prevptr(ccline.cmdbuff, p);
1583 			    i = mb_get_class(p);
1584 			    while (p > ccline.cmdbuff && mb_get_class(p) == i)
1585 				p = mb_prevptr(ccline.cmdbuff, p);
1586 			    if (mb_get_class(p) != i)
1587 				p += (*mb_ptr2len)(p);
1588 			}
1589 		    }
1590 		    else if (c == Ctrl_W)
1591 		    {
1592 			while (p > ccline.cmdbuff && vim_isspace(p[-1]))
1593 			    --p;
1594 			i = vim_iswordc(p[-1]);
1595 			while (p > ccline.cmdbuff && !vim_isspace(p[-1])
1596 				&& vim_iswordc(p[-1]) == i)
1597 			    --p;
1598 		    }
1599 		    else
1600 			--p;
1601 		    ccline.cmdpos = (int)(p - ccline.cmdbuff);
1602 		    ccline.cmdlen -= j - ccline.cmdpos;
1603 		    i = ccline.cmdpos;
1604 		    while (i < ccline.cmdlen)
1605 			ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
1606 
1607 		    // Truncate at the end, required for multi-byte chars.
1608 		    ccline.cmdbuff[ccline.cmdlen] = NUL;
1609 #ifdef FEAT_SEARCH_EXTRA
1610 		    if (ccline.cmdlen == 0)
1611 		    {
1612 			is_state.search_start = is_state.save_cursor;
1613 			// save view settings, so that the screen
1614 			// won't be restored at the wrong position
1615 			is_state.old_viewstate = is_state.init_viewstate;
1616 		    }
1617 #endif
1618 		    redrawcmd();
1619 		}
1620 		else if (ccline.cmdlen == 0 && c != Ctrl_W
1621 				   && ccline.cmdprompt == NULL && indent == 0)
1622 		{
1623 		    // In ex and debug mode it doesn't make sense to return.
1624 		    if (exmode_active
1625 #ifdef FEAT_EVAL
1626 			    || ccline.cmdfirstc == '>'
1627 #endif
1628 			    )
1629 			goto cmdline_not_changed;
1630 
1631 		    VIM_CLEAR(ccline.cmdbuff);	// no commandline to return
1632 		    if (!cmd_silent)
1633 		    {
1634 #ifdef FEAT_RIGHTLEFT
1635 			if (cmdmsg_rl)
1636 			    msg_col = Columns;
1637 			else
1638 #endif
1639 			    msg_col = 0;
1640 			msg_putchar(' ');		// delete ':'
1641 		    }
1642 #ifdef FEAT_SEARCH_EXTRA
1643 		    if (ccline.cmdlen == 0)
1644 			is_state.search_start = is_state.save_cursor;
1645 #endif
1646 		    redraw_cmdline = TRUE;
1647 		    goto returncmd;		// back to cmd mode
1648 		}
1649 		goto cmdline_changed;
1650 
1651 	case K_INS:
1652 	case K_KINS:
1653 		ccline.overstrike = !ccline.overstrike;
1654 #ifdef CURSOR_SHAPE
1655 		ui_cursor_shape();	// may show different cursor shape
1656 #endif
1657 		goto cmdline_not_changed;
1658 
1659 	case Ctrl_HAT:
1660 		if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE))
1661 		{
1662 		    // ":lmap" mappings exists, toggle use of mappings.
1663 		    State ^= LANGMAP;
1664 #ifdef HAVE_INPUT_METHOD
1665 		    im_set_active(FALSE);	// Disable input method
1666 #endif
1667 		    if (b_im_ptr != NULL)
1668 		    {
1669 			if (State & LANGMAP)
1670 			    *b_im_ptr = B_IMODE_LMAP;
1671 			else
1672 			    *b_im_ptr = B_IMODE_NONE;
1673 		    }
1674 		}
1675 #ifdef HAVE_INPUT_METHOD
1676 		else
1677 		{
1678 		    // There are no ":lmap" mappings, toggle IM.  When
1679 		    // 'imdisable' is set don't try getting the status, it's
1680 		    // always off.
1681 		    if ((p_imdisable && b_im_ptr != NULL)
1682 			    ? *b_im_ptr == B_IMODE_IM : im_get_status())
1683 		    {
1684 			im_set_active(FALSE);	// Disable input method
1685 			if (b_im_ptr != NULL)
1686 			    *b_im_ptr = B_IMODE_NONE;
1687 		    }
1688 		    else
1689 		    {
1690 			im_set_active(TRUE);	// Enable input method
1691 			if (b_im_ptr != NULL)
1692 			    *b_im_ptr = B_IMODE_IM;
1693 		    }
1694 		}
1695 #endif
1696 		if (b_im_ptr != NULL)
1697 		{
1698 		    if (b_im_ptr == &curbuf->b_p_iminsert)
1699 			set_iminsert_global();
1700 		    else
1701 			set_imsearch_global();
1702 		}
1703 #ifdef CURSOR_SHAPE
1704 		ui_cursor_shape();	// may show different cursor shape
1705 #endif
1706 #if defined(FEAT_KEYMAP)
1707 		// Show/unshow value of 'keymap' in status lines later.
1708 		status_redraw_curbuf();
1709 #endif
1710 		goto cmdline_not_changed;
1711 
1712 //	case '@':   only in very old vi
1713 	case Ctrl_U:
1714 		// delete all characters left of the cursor
1715 		j = ccline.cmdpos;
1716 		ccline.cmdlen -= j;
1717 		i = ccline.cmdpos = 0;
1718 		while (i < ccline.cmdlen)
1719 		    ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
1720 		// Truncate at the end, required for multi-byte chars.
1721 		ccline.cmdbuff[ccline.cmdlen] = NUL;
1722 #ifdef FEAT_SEARCH_EXTRA
1723 		if (ccline.cmdlen == 0)
1724 		    is_state.search_start = is_state.save_cursor;
1725 #endif
1726 		redrawcmd();
1727 		goto cmdline_changed;
1728 
1729 #ifdef FEAT_CLIPBOARD
1730 	case Ctrl_Y:
1731 		// Copy the modeless selection, if there is one.
1732 		if (clip_star.state != SELECT_CLEARED)
1733 		{
1734 		    if (clip_star.state == SELECT_DONE)
1735 			clip_copy_modeless_selection(TRUE);
1736 		    goto cmdline_not_changed;
1737 		}
1738 		break;
1739 #endif
1740 
1741 	case ESC:	// get here if p_wc != ESC or when ESC typed twice
1742 	case Ctrl_C:
1743 		// In exmode it doesn't make sense to return.  Except when
1744 		// ":normal" runs out of characters.
1745 		if (exmode_active
1746 			       && (ex_normal_busy == 0 || typebuf.tb_len > 0))
1747 		    goto cmdline_not_changed;
1748 
1749 		gotesc = TRUE;		// will free ccline.cmdbuff after
1750 					// putting it in history
1751 		goto returncmd;		// back to cmd mode
1752 
1753 	case Ctrl_R:			// insert register
1754 #ifdef USE_ON_FLY_SCROLL
1755 		dont_scroll = TRUE;	// disallow scrolling here
1756 #endif
1757 		putcmdline('"', TRUE);
1758 		++no_mapping;
1759 		++allow_keys;
1760 		i = c = plain_vgetc();	// CTRL-R <char>
1761 		if (i == Ctrl_O)
1762 		    i = Ctrl_R;		// CTRL-R CTRL-O == CTRL-R CTRL-R
1763 		if (i == Ctrl_R)
1764 		    c = plain_vgetc();	// CTRL-R CTRL-R <char>
1765 		extra_char = NUL;
1766 		--no_mapping;
1767 		--allow_keys;
1768 #ifdef FEAT_EVAL
1769 		/*
1770 		 * Insert the result of an expression.
1771 		 * Need to save the current command line, to be able to enter
1772 		 * a new one...
1773 		 */
1774 		new_cmdpos = -1;
1775 		if (c == '=')
1776 		{
1777 		    if (ccline.cmdfirstc == '='  // can't do this recursively
1778 			    || cmdline_star > 0) // or when typing a password
1779 		    {
1780 			beep_flush();
1781 			c = ESC;
1782 		    }
1783 		    else
1784 			c = get_expr_register();
1785 		}
1786 #endif
1787 		if (c != ESC)	    // use ESC to cancel inserting register
1788 		{
1789 		    cmdline_paste(c, i == Ctrl_R, FALSE);
1790 
1791 #ifdef FEAT_EVAL
1792 		    // When there was a serious error abort getting the
1793 		    // command line.
1794 		    if (aborting())
1795 		    {
1796 			gotesc = TRUE;  // will free ccline.cmdbuff after
1797 					// putting it in history
1798 			goto returncmd; // back to cmd mode
1799 		    }
1800 #endif
1801 		    KeyTyped = FALSE;	// Don't do p_wc completion.
1802 #ifdef FEAT_EVAL
1803 		    if (new_cmdpos >= 0)
1804 		    {
1805 			// set_cmdline_pos() was used
1806 			if (new_cmdpos > ccline.cmdlen)
1807 			    ccline.cmdpos = ccline.cmdlen;
1808 			else
1809 			    ccline.cmdpos = new_cmdpos;
1810 		    }
1811 #endif
1812 		}
1813 		redrawcmd();
1814 		goto cmdline_changed;
1815 
1816 	case Ctrl_D:
1817 		if (showmatches(&xpc, FALSE) == EXPAND_NOTHING)
1818 		    break;	// Use ^D as normal char instead
1819 
1820 		redrawcmd();
1821 		continue;	// don't do incremental search now
1822 
1823 	case K_RIGHT:
1824 	case K_S_RIGHT:
1825 	case K_C_RIGHT:
1826 		do
1827 		{
1828 		    if (ccline.cmdpos >= ccline.cmdlen)
1829 			break;
1830 		    i = cmdline_charsize(ccline.cmdpos);
1831 		    if (KeyTyped && ccline.cmdspos + i >= Columns * Rows)
1832 			break;
1833 		    ccline.cmdspos += i;
1834 		    if (has_mbyte)
1835 			ccline.cmdpos += (*mb_ptr2len)(ccline.cmdbuff
1836 							     + ccline.cmdpos);
1837 		    else
1838 			++ccline.cmdpos;
1839 		}
1840 		while ((c == K_S_RIGHT || c == K_C_RIGHT
1841 			       || (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)))
1842 			&& ccline.cmdbuff[ccline.cmdpos] != ' ');
1843 		if (has_mbyte)
1844 		    set_cmdspos_cursor();
1845 		goto cmdline_not_changed;
1846 
1847 	case K_LEFT:
1848 	case K_S_LEFT:
1849 	case K_C_LEFT:
1850 		if (ccline.cmdpos == 0)
1851 		    goto cmdline_not_changed;
1852 		do
1853 		{
1854 		    --ccline.cmdpos;
1855 		    if (has_mbyte)	// move to first byte of char
1856 			ccline.cmdpos -= (*mb_head_off)(ccline.cmdbuff,
1857 					      ccline.cmdbuff + ccline.cmdpos);
1858 		    ccline.cmdspos -= cmdline_charsize(ccline.cmdpos);
1859 		}
1860 		while (ccline.cmdpos > 0
1861 			&& (c == K_S_LEFT || c == K_C_LEFT
1862 			       || (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)))
1863 			&& ccline.cmdbuff[ccline.cmdpos - 1] != ' ');
1864 		if (has_mbyte)
1865 		    set_cmdspos_cursor();
1866 		goto cmdline_not_changed;
1867 
1868 	case K_IGNORE:
1869 		// Ignore mouse event or open_cmdwin() result.
1870 		goto cmdline_not_changed;
1871 
1872 #ifdef FEAT_GUI_MSWIN
1873 	    // On MS-Windows ignore <M-F4>, we get it when closing the window
1874 	    // was cancelled.
1875 	case K_F4:
1876 	    if (mod_mask == MOD_MASK_ALT)
1877 	    {
1878 		redrawcmd();	    // somehow the cmdline is cleared
1879 		goto cmdline_not_changed;
1880 	    }
1881 	    break;
1882 #endif
1883 
1884 	case K_MIDDLEDRAG:
1885 	case K_MIDDLERELEASE:
1886 		goto cmdline_not_changed;	// Ignore mouse
1887 
1888 	case K_MIDDLEMOUSE:
1889 # ifdef FEAT_GUI
1890 		// When GUI is active, also paste when 'mouse' is empty
1891 		if (!gui.in_use)
1892 # endif
1893 		    if (!mouse_has(MOUSE_COMMAND))
1894 			goto cmdline_not_changed;   // Ignore mouse
1895 # ifdef FEAT_CLIPBOARD
1896 		if (clip_star.available)
1897 		    cmdline_paste('*', TRUE, TRUE);
1898 		else
1899 # endif
1900 		    cmdline_paste(0, TRUE, TRUE);
1901 		redrawcmd();
1902 		goto cmdline_changed;
1903 
1904 # ifdef FEAT_DND
1905 	case K_DROP:
1906 		cmdline_paste('~', TRUE, FALSE);
1907 		redrawcmd();
1908 		goto cmdline_changed;
1909 # endif
1910 
1911 	case K_LEFTDRAG:
1912 	case K_LEFTRELEASE:
1913 	case K_RIGHTDRAG:
1914 	case K_RIGHTRELEASE:
1915 		// Ignore drag and release events when the button-down wasn't
1916 		// seen before.
1917 		if (ignore_drag_release)
1918 		    goto cmdline_not_changed;
1919 		// FALLTHROUGH
1920 	case K_LEFTMOUSE:
1921 	case K_RIGHTMOUSE:
1922 		if (c == K_LEFTRELEASE || c == K_RIGHTRELEASE)
1923 		    ignore_drag_release = TRUE;
1924 		else
1925 		    ignore_drag_release = FALSE;
1926 # ifdef FEAT_GUI
1927 		// When GUI is active, also move when 'mouse' is empty
1928 		if (!gui.in_use)
1929 # endif
1930 		    if (!mouse_has(MOUSE_COMMAND))
1931 			goto cmdline_not_changed;   // Ignore mouse
1932 # ifdef FEAT_CLIPBOARD
1933 		if (mouse_row < cmdline_row && clip_star.available)
1934 		{
1935 		    int	    button, is_click, is_drag;
1936 
1937 		    /*
1938 		     * Handle modeless selection.
1939 		     */
1940 		    button = get_mouse_button(KEY2TERMCAP1(c),
1941 							 &is_click, &is_drag);
1942 		    if (mouse_model_popup() && button == MOUSE_LEFT
1943 					       && (mod_mask & MOD_MASK_SHIFT))
1944 		    {
1945 			// Translate shift-left to right button.
1946 			button = MOUSE_RIGHT;
1947 			mod_mask &= ~MOD_MASK_SHIFT;
1948 		    }
1949 		    clip_modeless(button, is_click, is_drag);
1950 		    goto cmdline_not_changed;
1951 		}
1952 # endif
1953 
1954 		set_cmdspos();
1955 		for (ccline.cmdpos = 0; ccline.cmdpos < ccline.cmdlen;
1956 							      ++ccline.cmdpos)
1957 		{
1958 		    i = cmdline_charsize(ccline.cmdpos);
1959 		    if (mouse_row <= cmdline_row + ccline.cmdspos / Columns
1960 				  && mouse_col < ccline.cmdspos % Columns + i)
1961 			break;
1962 		    if (has_mbyte)
1963 		    {
1964 			// Count ">" for double-wide char that doesn't fit.
1965 			correct_cmdspos(ccline.cmdpos, i);
1966 			ccline.cmdpos += (*mb_ptr2len)(ccline.cmdbuff
1967 							 + ccline.cmdpos) - 1;
1968 		    }
1969 		    ccline.cmdspos += i;
1970 		}
1971 		goto cmdline_not_changed;
1972 
1973 	// Mouse scroll wheel: ignored here
1974 	case K_MOUSEDOWN:
1975 	case K_MOUSEUP:
1976 	case K_MOUSELEFT:
1977 	case K_MOUSERIGHT:
1978 	// Alternate buttons ignored here
1979 	case K_X1MOUSE:
1980 	case K_X1DRAG:
1981 	case K_X1RELEASE:
1982 	case K_X2MOUSE:
1983 	case K_X2DRAG:
1984 	case K_X2RELEASE:
1985 	case K_MOUSEMOVE:
1986 		goto cmdline_not_changed;
1987 
1988 #ifdef FEAT_GUI
1989 	case K_LEFTMOUSE_NM:	// mousefocus click, ignored
1990 	case K_LEFTRELEASE_NM:
1991 		goto cmdline_not_changed;
1992 
1993 	case K_VER_SCROLLBAR:
1994 		if (msg_scrolled == 0)
1995 		{
1996 		    gui_do_scroll();
1997 		    redrawcmd();
1998 		}
1999 		goto cmdline_not_changed;
2000 
2001 	case K_HOR_SCROLLBAR:
2002 		if (msg_scrolled == 0)
2003 		{
2004 		    gui_do_horiz_scroll(scrollbar_value, FALSE);
2005 		    redrawcmd();
2006 		}
2007 		goto cmdline_not_changed;
2008 #endif
2009 #ifdef FEAT_GUI_TABLINE
2010 	case K_TABLINE:
2011 	case K_TABMENU:
2012 		// Don't want to change any tabs here.  Make sure the same tab
2013 		// is still selected.
2014 		if (gui_use_tabline())
2015 		    gui_mch_set_curtab(tabpage_index(curtab));
2016 		goto cmdline_not_changed;
2017 #endif
2018 
2019 	case K_SELECT:	    // end of Select mode mapping - ignore
2020 		goto cmdline_not_changed;
2021 
2022 	case Ctrl_B:	    // begin of command line
2023 	case K_HOME:
2024 	case K_KHOME:
2025 	case K_S_HOME:
2026 	case K_C_HOME:
2027 		ccline.cmdpos = 0;
2028 		set_cmdspos();
2029 		goto cmdline_not_changed;
2030 
2031 	case Ctrl_E:	    // end of command line
2032 	case K_END:
2033 	case K_KEND:
2034 	case K_S_END:
2035 	case K_C_END:
2036 		ccline.cmdpos = ccline.cmdlen;
2037 		set_cmdspos_cursor();
2038 		goto cmdline_not_changed;
2039 
2040 	case Ctrl_A:	    // all matches
2041 		if (nextwild(&xpc, WILD_ALL, 0, firstc != '@') == FAIL)
2042 		    break;
2043 		goto cmdline_changed;
2044 
2045 	case Ctrl_L:
2046 #ifdef FEAT_SEARCH_EXTRA
2047 		if (may_add_char_to_search(firstc, &c, &is_state) == OK)
2048 		    goto cmdline_not_changed;
2049 #endif
2050 
2051 		// completion: longest common part
2052 		if (nextwild(&xpc, WILD_LONGEST, 0, firstc != '@') == FAIL)
2053 		    break;
2054 		goto cmdline_changed;
2055 
2056 	case Ctrl_N:	    // next match
2057 	case Ctrl_P:	    // previous match
2058 		if (xpc.xp_numfiles > 0)
2059 		{
2060 		    if (nextwild(&xpc, (c == Ctrl_P) ? WILD_PREV : WILD_NEXT,
2061 						    0, firstc != '@') == FAIL)
2062 			break;
2063 		    goto cmdline_not_changed;
2064 		}
2065 		// FALLTHROUGH
2066 	case K_UP:
2067 	case K_DOWN:
2068 	case K_S_UP:
2069 	case K_S_DOWN:
2070 	case K_PAGEUP:
2071 	case K_KPAGEUP:
2072 	case K_PAGEDOWN:
2073 	case K_KPAGEDOWN:
2074 		if (get_hislen() == 0 || firstc == NUL)	// no history
2075 		    goto cmdline_not_changed;
2076 
2077 		i = hiscnt;
2078 
2079 		// save current command string so it can be restored later
2080 		if (lookfor == NULL)
2081 		{
2082 		    if ((lookfor = vim_strsave(ccline.cmdbuff)) == NULL)
2083 			goto cmdline_not_changed;
2084 		    lookfor[ccline.cmdpos] = NUL;
2085 		}
2086 
2087 		j = (int)STRLEN(lookfor);
2088 		for (;;)
2089 		{
2090 		    // one step backwards
2091 		    if (c == K_UP|| c == K_S_UP || c == Ctrl_P
2092 			    || c == K_PAGEUP || c == K_KPAGEUP)
2093 		    {
2094 			if (hiscnt == get_hislen())	// first time
2095 			    hiscnt = *get_hisidx(histype);
2096 			else if (hiscnt == 0 && *get_hisidx(histype)
2097 							   != get_hislen() - 1)
2098 			    hiscnt = get_hislen() - 1;
2099 			else if (hiscnt != *get_hisidx(histype) + 1)
2100 			    --hiscnt;
2101 			else			// at top of list
2102 			{
2103 			    hiscnt = i;
2104 			    break;
2105 			}
2106 		    }
2107 		    else    // one step forwards
2108 		    {
2109 			// on last entry, clear the line
2110 			if (hiscnt == *get_hisidx(histype))
2111 			{
2112 			    hiscnt = get_hislen();
2113 			    break;
2114 			}
2115 
2116 			// not on a history line, nothing to do
2117 			if (hiscnt == get_hislen())
2118 			    break;
2119 			if (hiscnt == get_hislen() - 1)   // wrap around
2120 			    hiscnt = 0;
2121 			else
2122 			    ++hiscnt;
2123 		    }
2124 		    if (hiscnt < 0 || get_histentry(histype)[hiscnt].hisstr
2125 								       == NULL)
2126 		    {
2127 			hiscnt = i;
2128 			break;
2129 		    }
2130 		    if ((c != K_UP && c != K_DOWN)
2131 			    || hiscnt == i
2132 			    || STRNCMP(get_histentry(histype)[hiscnt].hisstr,
2133 						    lookfor, (size_t)j) == 0)
2134 			break;
2135 		}
2136 
2137 		if (hiscnt != i)	// jumped to other entry
2138 		{
2139 		    char_u	*p;
2140 		    int		len;
2141 		    int		old_firstc;
2142 
2143 		    VIM_CLEAR(ccline.cmdbuff);
2144 		    xpc.xp_context = EXPAND_NOTHING;
2145 		    if (hiscnt == get_hislen())
2146 			p = lookfor;	// back to the old one
2147 		    else
2148 			p = get_histentry(histype)[hiscnt].hisstr;
2149 
2150 		    if (histype == HIST_SEARCH
2151 			    && p != lookfor
2152 			    && (old_firstc = p[STRLEN(p) + 1]) != firstc)
2153 		    {
2154 			// Correct for the separator character used when
2155 			// adding the history entry vs the one used now.
2156 			// First loop: count length.
2157 			// Second loop: copy the characters.
2158 			for (i = 0; i <= 1; ++i)
2159 			{
2160 			    len = 0;
2161 			    for (j = 0; p[j] != NUL; ++j)
2162 			    {
2163 				// Replace old sep with new sep, unless it is
2164 				// escaped.
2165 				if (p[j] == old_firstc
2166 					      && (j == 0 || p[j - 1] != '\\'))
2167 				{
2168 				    if (i > 0)
2169 					ccline.cmdbuff[len] = firstc;
2170 				}
2171 				else
2172 				{
2173 				    // Escape new sep, unless it is already
2174 				    // escaped.
2175 				    if (p[j] == firstc
2176 					      && (j == 0 || p[j - 1] != '\\'))
2177 				    {
2178 					if (i > 0)
2179 					    ccline.cmdbuff[len] = '\\';
2180 					++len;
2181 				    }
2182 				    if (i > 0)
2183 					ccline.cmdbuff[len] = p[j];
2184 				}
2185 				++len;
2186 			    }
2187 			    if (i == 0)
2188 			    {
2189 				alloc_cmdbuff(len);
2190 				if (ccline.cmdbuff == NULL)
2191 				    goto returncmd;
2192 			    }
2193 			}
2194 			ccline.cmdbuff[len] = NUL;
2195 		    }
2196 		    else
2197 		    {
2198 			alloc_cmdbuff((int)STRLEN(p));
2199 			if (ccline.cmdbuff == NULL)
2200 			    goto returncmd;
2201 			STRCPY(ccline.cmdbuff, p);
2202 		    }
2203 
2204 		    ccline.cmdpos = ccline.cmdlen = (int)STRLEN(ccline.cmdbuff);
2205 		    redrawcmd();
2206 		    goto cmdline_changed;
2207 		}
2208 		beep_flush();
2209 		goto cmdline_not_changed;
2210 
2211 #ifdef FEAT_SEARCH_EXTRA
2212 	case Ctrl_G:	    // next match
2213 	case Ctrl_T:	    // previous match
2214 		if (may_adjust_incsearch_highlighting(
2215 					  firstc, count, &is_state, c) == FAIL)
2216 		    goto cmdline_not_changed;
2217 		break;
2218 #endif
2219 
2220 	case Ctrl_V:
2221 	case Ctrl_Q:
2222 		{
2223 		    int	 prev_mod_mask = mod_mask;
2224 
2225 		    ignore_drag_release = TRUE;
2226 		    putcmdline('^', TRUE);
2227 		    c = get_literal();	    // get next (two) character(s)
2228 		    do_abbr = FALSE;	    // don't do abbreviation now
2229 		    extra_char = NUL;
2230 		    // may need to remove ^ when composing char was typed
2231 		    if (enc_utf8 && utf_iscomposing(c) && !cmd_silent)
2232 		    {
2233 			draw_cmdline(ccline.cmdpos,
2234 						ccline.cmdlen - ccline.cmdpos);
2235 			msg_putchar(' ');
2236 			cursorcmd();
2237 		    }
2238 
2239 		    if ((c == ESC || c == CSI)
2240 					  && !(prev_mod_mask & MOD_MASK_SHIFT))
2241 			// Using CTRL-V: Change any modifyOtherKeys ESC
2242 			// sequence to a normal key.  Don't do this for
2243 			// CTRL-SHIFT-V.
2244 			c = decodeModifyOtherKeys(c);
2245 		}
2246 
2247 		break;
2248 
2249 #ifdef FEAT_DIGRAPHS
2250 	case Ctrl_K:
2251 		ignore_drag_release = TRUE;
2252 		putcmdline('?', TRUE);
2253 # ifdef USE_ON_FLY_SCROLL
2254 		dont_scroll = TRUE;	    // disallow scrolling here
2255 # endif
2256 		c = get_digraph(TRUE);
2257 		extra_char = NUL;
2258 		if (c != NUL)
2259 		    break;
2260 
2261 		redrawcmd();
2262 		goto cmdline_not_changed;
2263 #endif // FEAT_DIGRAPHS
2264 
2265 #ifdef FEAT_RIGHTLEFT
2266 	case Ctrl__:	    // CTRL-_: switch language mode
2267 		if (!p_ari)
2268 		    break;
2269 		cmd_hkmap = !cmd_hkmap;
2270 		goto cmdline_not_changed;
2271 #endif
2272 
2273 	case K_PS:
2274 		bracketed_paste(PASTE_CMDLINE, FALSE, NULL);
2275 		goto cmdline_changed;
2276 
2277 	default:
2278 #ifdef UNIX
2279 		if (c == intr_char)
2280 		{
2281 		    gotesc = TRUE;	// will free ccline.cmdbuff after
2282 					// putting it in history
2283 		    goto returncmd;	// back to Normal mode
2284 		}
2285 #endif
2286 		/*
2287 		 * Normal character with no special meaning.  Just set mod_mask
2288 		 * to 0x0 so that typing Shift-Space in the GUI doesn't enter
2289 		 * the string <S-Space>.  This should only happen after ^V.
2290 		 */
2291 		if (!IS_SPECIAL(c))
2292 		    mod_mask = 0x0;
2293 		break;
2294 	}
2295 	/*
2296 	 * End of switch on command line character.
2297 	 * We come here if we have a normal character.
2298 	 */
2299 
2300 	if (do_abbr && (IS_SPECIAL(c) || !vim_iswordc(c))
2301 		&& (ccheck_abbr(
2302 			// Add ABBR_OFF for characters above 0x100, this is
2303 			// what check_abbr() expects.
2304 				(has_mbyte && c >= 0x100) ? (c + ABBR_OFF) : c)
2305 		    || c == Ctrl_RSB))
2306 	    goto cmdline_changed;
2307 
2308 	/*
2309 	 * put the character in the command line
2310 	 */
2311 	if (IS_SPECIAL(c) || mod_mask != 0)
2312 	    put_on_cmdline(get_special_key_name(c, mod_mask), -1, TRUE);
2313 	else
2314 	{
2315 	    if (has_mbyte)
2316 	    {
2317 		j = (*mb_char2bytes)(c, IObuff);
2318 		IObuff[j] = NUL;	// exclude composing chars
2319 		put_on_cmdline(IObuff, j, TRUE);
2320 	    }
2321 	    else
2322 	    {
2323 		IObuff[0] = c;
2324 		put_on_cmdline(IObuff, 1, TRUE);
2325 	    }
2326 	}
2327 	goto cmdline_changed;
2328 
2329 /*
2330  * This part implements incremental searches for "/" and "?"
2331  * Jump to cmdline_not_changed when a character has been read but the command
2332  * line did not change. Then we only search and redraw if something changed in
2333  * the past.
2334  * Jump to cmdline_changed when the command line did change.
2335  * (Sorry for the goto's, I know it is ugly).
2336  */
2337 cmdline_not_changed:
2338 #ifdef FEAT_SEARCH_EXTRA
2339 	if (!is_state.incsearch_postponed)
2340 	    continue;
2341 #endif
2342 
2343 cmdline_changed:
2344 	// Trigger CmdlineChanged autocommands.
2345 	trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINECHANGED);
2346 
2347 #ifdef FEAT_SEARCH_EXTRA
2348 	may_do_incsearch_highlighting(firstc, count, &is_state);
2349 #endif
2350 
2351 #ifdef FEAT_RIGHTLEFT
2352 	if (cmdmsg_rl
2353 # ifdef FEAT_ARABIC
2354 		|| (p_arshape && !p_tbidi
2355 				       && cmdline_has_arabic(0, ccline.cmdlen))
2356 # endif
2357 		)
2358 	    // Always redraw the whole command line to fix shaping and
2359 	    // right-left typing.  Not efficient, but it works.
2360 	    // Do it only when there are no characters left to read
2361 	    // to avoid useless intermediate redraws.
2362 	    if (vpeekc() == NUL)
2363 		redrawcmd();
2364 #endif
2365     }
2366 
2367 returncmd:
2368 
2369 #ifdef FEAT_RIGHTLEFT
2370     cmdmsg_rl = FALSE;
2371 #endif
2372 
2373     ExpandCleanup(&xpc);
2374     ccline.xpc = NULL;
2375 
2376 #ifdef FEAT_SEARCH_EXTRA
2377     finish_incsearch_highlighting(gotesc, &is_state, FALSE);
2378 #endif
2379 
2380     if (ccline.cmdbuff != NULL)
2381     {
2382 	/*
2383 	 * Put line in history buffer (":" and "=" only when it was typed).
2384 	 */
2385 	if (ccline.cmdlen && firstc != NUL
2386 		&& (some_key_typed || histype == HIST_SEARCH))
2387 	{
2388 	    add_to_history(histype, ccline.cmdbuff, TRUE,
2389 				       histype == HIST_SEARCH ? firstc : NUL);
2390 	    if (firstc == ':')
2391 	    {
2392 		vim_free(new_last_cmdline);
2393 		new_last_cmdline = vim_strsave(ccline.cmdbuff);
2394 	    }
2395 	}
2396 
2397 	if (gotesc)
2398 	    abandon_cmdline();
2399     }
2400 
2401     /*
2402      * If the screen was shifted up, redraw the whole screen (later).
2403      * If the line is too long, clear it, so ruler and shown command do
2404      * not get printed in the middle of it.
2405      */
2406     msg_check();
2407     msg_scroll = save_msg_scroll;
2408     redir_off = FALSE;
2409 
2410     // When the command line was typed, no need for a wait-return prompt.
2411     if (some_key_typed)
2412 	need_wait_return = FALSE;
2413 
2414     // Trigger CmdlineLeave autocommands.
2415     trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINELEAVE);
2416 
2417     State = save_State;
2418 #ifdef HAVE_INPUT_METHOD
2419     if (b_im_ptr != NULL && *b_im_ptr != B_IMODE_LMAP)
2420 	im_save_status(b_im_ptr);
2421     im_set_active(FALSE);
2422 #endif
2423     setmouse();
2424 #ifdef CURSOR_SHAPE
2425     ui_cursor_shape();		// may show different cursor shape
2426 #endif
2427     sb_text_end_cmdline();
2428 
2429 theend:
2430     {
2431 	char_u *p = ccline.cmdbuff;
2432 
2433 	if (did_save_ccline)
2434 	    restore_cmdline(&save_ccline);
2435 	else
2436 	    ccline.cmdbuff = NULL;
2437 	return p;
2438     }
2439 }
2440 
2441 #if (defined(FEAT_CRYPT) || defined(FEAT_EVAL)) || defined(PROTO)
2442 /*
2443  * Get a command line with a prompt.
2444  * This is prepared to be called recursively from getcmdline() (e.g. by
2445  * f_input() when evaluating an expression from CTRL-R =).
2446  * Returns the command line in allocated memory, or NULL.
2447  */
2448     char_u *
2449 getcmdline_prompt(
2450     int		firstc,
2451     char_u	*prompt,	// command line prompt
2452     int		attr,		// attributes for prompt
2453     int		xp_context,	// type of expansion
2454     char_u	*xp_arg)	// user-defined expansion argument
2455 {
2456     char_u		*s;
2457     cmdline_info_T	save_ccline;
2458     int			did_save_ccline = FALSE;
2459     int			msg_col_save = msg_col;
2460     int			msg_silent_save = msg_silent;
2461 
2462     if (ccline.cmdbuff != NULL)
2463     {
2464 	// Save the values of the current cmdline and restore them below.
2465 	save_cmdline(&save_ccline);
2466 	did_save_ccline = TRUE;
2467     }
2468 
2469     CLEAR_FIELD(ccline);
2470     ccline.cmdprompt = prompt;
2471     ccline.cmdattr = attr;
2472 # ifdef FEAT_EVAL
2473     ccline.xp_context = xp_context;
2474     ccline.xp_arg = xp_arg;
2475     ccline.input_fn = (firstc == '@');
2476 # endif
2477     msg_silent = 0;
2478     s = getcmdline_int(firstc, 1L, 0, FALSE);
2479 
2480     if (did_save_ccline)
2481 	restore_cmdline(&save_ccline);
2482 
2483     msg_silent = msg_silent_save;
2484     // Restore msg_col, the prompt from input() may have changed it.
2485     // But only if called recursively and the commandline is therefore being
2486     // restored to an old one; if not, the input() prompt stays on the screen,
2487     // so we need its modified msg_col left intact.
2488     if (ccline.cmdbuff != NULL)
2489 	msg_col = msg_col_save;
2490 
2491     return s;
2492 }
2493 #endif
2494 
2495 /*
2496  * Read the 'wildmode' option, fill wim_flags[].
2497  */
2498     int
2499 check_opt_wim(void)
2500 {
2501     char_u	new_wim_flags[4];
2502     char_u	*p;
2503     int		i;
2504     int		idx = 0;
2505 
2506     for (i = 0; i < 4; ++i)
2507 	new_wim_flags[i] = 0;
2508 
2509     for (p = p_wim; *p; ++p)
2510     {
2511 	for (i = 0; ASCII_ISALPHA(p[i]); ++i)
2512 	    ;
2513 	if (p[i] != NUL && p[i] != ',' && p[i] != ':')
2514 	    return FAIL;
2515 	if (i == 7 && STRNCMP(p, "longest", 7) == 0)
2516 	    new_wim_flags[idx] |= WIM_LONGEST;
2517 	else if (i == 4 && STRNCMP(p, "full", 4) == 0)
2518 	    new_wim_flags[idx] |= WIM_FULL;
2519 	else if (i == 4 && STRNCMP(p, "list", 4) == 0)
2520 	    new_wim_flags[idx] |= WIM_LIST;
2521 	else if (i == 8 && STRNCMP(p, "lastused", 8) == 0)
2522 	    new_wim_flags[idx] |= WIM_BUFLASTUSED;
2523 	else
2524 	    return FAIL;
2525 	p += i;
2526 	if (*p == NUL)
2527 	    break;
2528 	if (*p == ',')
2529 	{
2530 	    if (idx == 3)
2531 		return FAIL;
2532 	    ++idx;
2533 	}
2534     }
2535 
2536     // fill remaining entries with last flag
2537     while (idx < 3)
2538     {
2539 	new_wim_flags[idx + 1] = new_wim_flags[idx];
2540 	++idx;
2541     }
2542 
2543     // only when there are no errors, wim_flags[] is changed
2544     for (i = 0; i < 4; ++i)
2545 	wim_flags[i] = new_wim_flags[i];
2546     return OK;
2547 }
2548 
2549 /*
2550  * Return TRUE when the text must not be changed and we can't switch to
2551  * another window or buffer.  TRUE when editing the command line, evaluating
2552  * 'balloonexpr', etc.
2553  */
2554     int
2555 text_and_win_locked(void)
2556 {
2557 #ifdef FEAT_CMDWIN
2558     if (cmdwin_type != 0)
2559 	return TRUE;
2560 #endif
2561     return textwinlock != 0;
2562 }
2563 
2564 /*
2565  * Give an error message for a command that isn't allowed while the cmdline
2566  * window is open or editing the cmdline in another way.
2567  */
2568     void
2569 text_locked_msg(void)
2570 {
2571     emsg(_(get_text_locked_msg()));
2572 }
2573 
2574     char *
2575 get_text_locked_msg(void)
2576 {
2577 #ifdef FEAT_CMDWIN
2578     if (cmdwin_type != 0)
2579 	return e_cmdwin;
2580 #endif
2581     if (textwinlock != 0)
2582 	return e_textwinlock;
2583     return e_textlock;
2584 }
2585 
2586 /*
2587  * Return TRUE when the text must not be changed and/or we cannot switch to
2588  * another window.  TRUE while evaluating 'completefunc'.
2589  */
2590     int
2591 text_locked(void)
2592 {
2593     return text_and_win_locked() || textlock != 0;
2594 }
2595 
2596 /*
2597  * Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is
2598  * and give an error message.
2599  */
2600     int
2601 curbuf_locked(void)
2602 {
2603     if (curbuf_lock > 0)
2604     {
2605 	emsg(_("E788: Not allowed to edit another buffer now"));
2606 	return TRUE;
2607     }
2608     return allbuf_locked();
2609 }
2610 
2611 /*
2612  * Check if "allbuf_lock" is set and return TRUE when it is and give an error
2613  * message.
2614  */
2615     int
2616 allbuf_locked(void)
2617 {
2618     if (allbuf_lock > 0)
2619     {
2620 	emsg(_("E811: Not allowed to change buffer information now"));
2621 	return TRUE;
2622     }
2623     return FALSE;
2624 }
2625 
2626     static int
2627 cmdline_charsize(int idx)
2628 {
2629 #if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
2630     if (cmdline_star > 0)	    // showing '*', always 1 position
2631 	return 1;
2632 #endif
2633     return ptr2cells(ccline.cmdbuff + idx);
2634 }
2635 
2636 /*
2637  * Compute the offset of the cursor on the command line for the prompt and
2638  * indent.
2639  */
2640     static void
2641 set_cmdspos(void)
2642 {
2643     if (ccline.cmdfirstc != NUL)
2644 	ccline.cmdspos = 1 + ccline.cmdindent;
2645     else
2646 	ccline.cmdspos = 0 + ccline.cmdindent;
2647 }
2648 
2649 /*
2650  * Compute the screen position for the cursor on the command line.
2651  */
2652     static void
2653 set_cmdspos_cursor(void)
2654 {
2655     int		i, m, c;
2656 
2657     set_cmdspos();
2658     if (KeyTyped)
2659     {
2660 	m = Columns * Rows;
2661 	if (m < 0)	// overflow, Columns or Rows at weird value
2662 	    m = MAXCOL;
2663     }
2664     else
2665 	m = MAXCOL;
2666     for (i = 0; i < ccline.cmdlen && i < ccline.cmdpos; ++i)
2667     {
2668 	c = cmdline_charsize(i);
2669 	// Count ">" for double-wide multi-byte char that doesn't fit.
2670 	if (has_mbyte)
2671 	    correct_cmdspos(i, c);
2672 	// If the cmdline doesn't fit, show cursor on last visible char.
2673 	// Don't move the cursor itself, so we can still append.
2674 	if ((ccline.cmdspos += c) >= m)
2675 	{
2676 	    ccline.cmdspos -= c;
2677 	    break;
2678 	}
2679 	if (has_mbyte)
2680 	    i += (*mb_ptr2len)(ccline.cmdbuff + i) - 1;
2681     }
2682 }
2683 
2684 /*
2685  * Check if the character at "idx", which is "cells" wide, is a multi-byte
2686  * character that doesn't fit, so that a ">" must be displayed.
2687  */
2688     static void
2689 correct_cmdspos(int idx, int cells)
2690 {
2691     if ((*mb_ptr2len)(ccline.cmdbuff + idx) > 1
2692 		&& (*mb_ptr2cells)(ccline.cmdbuff + idx) > 1
2693 		&& ccline.cmdspos % Columns + cells > Columns)
2694 	ccline.cmdspos++;
2695 }
2696 
2697 /*
2698  * Get an Ex command line for the ":" command.
2699  */
2700     char_u *
2701 getexline(
2702     int		c,		// normally ':', NUL for ":append"
2703     void	*cookie UNUSED,
2704     int		indent,		// indent for inside conditionals
2705     int		do_concat)
2706 {
2707     // When executing a register, remove ':' that's in front of each line.
2708     if (exec_from_reg && vpeekc() == ':')
2709 	(void)vgetc();
2710     return getcmdline(c, 1L, indent, do_concat);
2711 }
2712 
2713 /*
2714  * Get an Ex command line for Ex mode.
2715  * In Ex mode we only use the OS supplied line editing features and no
2716  * mappings or abbreviations.
2717  * Returns a string in allocated memory or NULL.
2718  */
2719     char_u *
2720 getexmodeline(
2721     int		promptc,	// normally ':', NUL for ":append" and '?' for
2722 				// :s prompt
2723     void	*cookie UNUSED,
2724     int		indent,		// indent for inside conditionals
2725     int		do_concat UNUSED)
2726 {
2727     garray_T	line_ga;
2728     char_u	*pend;
2729     int		startcol = 0;
2730     int		c1 = 0;
2731     int		escaped = FALSE;	// CTRL-V typed
2732     int		vcol = 0;
2733     char_u	*p;
2734     int		prev_char;
2735     int		len;
2736 
2737     // Switch cursor on now.  This avoids that it happens after the "\n", which
2738     // confuses the system function that computes tabstops.
2739     cursor_on();
2740 
2741     // always start in column 0; write a newline if necessary
2742     compute_cmdrow();
2743     if ((msg_col || msg_didout) && promptc != '?')
2744 	msg_putchar('\n');
2745     if (promptc == ':')
2746     {
2747 	// indent that is only displayed, not in the line itself
2748 	if (p_prompt)
2749 	    msg_putchar(':');
2750 	while (indent-- > 0)
2751 	    msg_putchar(' ');
2752 	startcol = msg_col;
2753     }
2754 
2755     ga_init2(&line_ga, 1, 30);
2756 
2757     // autoindent for :insert and :append is in the line itself
2758     if (promptc <= 0)
2759     {
2760 	vcol = indent;
2761 	while (indent >= 8)
2762 	{
2763 	    ga_append(&line_ga, TAB);
2764 	    msg_puts("        ");
2765 	    indent -= 8;
2766 	}
2767 	while (indent-- > 0)
2768 	{
2769 	    ga_append(&line_ga, ' ');
2770 	    msg_putchar(' ');
2771 	}
2772     }
2773     ++no_mapping;
2774     ++allow_keys;
2775 
2776     /*
2777      * Get the line, one character at a time.
2778      */
2779     got_int = FALSE;
2780     while (!got_int)
2781     {
2782 	long    sw;
2783 	char_u *s;
2784 
2785 	if (ga_grow(&line_ga, 40) == FAIL)
2786 	    break;
2787 
2788 	/*
2789 	 * Get one character at a time.
2790 	 */
2791 	prev_char = c1;
2792 
2793 	// Check for a ":normal" command and no more characters left.
2794 	if (ex_normal_busy > 0 && typebuf.tb_len == 0)
2795 	    c1 = '\n';
2796 	else
2797 	    c1 = vgetc();
2798 
2799 	/*
2800 	 * Handle line editing.
2801 	 * Previously this was left to the system, putting the terminal in
2802 	 * cooked mode, but then CTRL-D and CTRL-T can't be used properly.
2803 	 */
2804 	if (got_int)
2805 	{
2806 	    msg_putchar('\n');
2807 	    break;
2808 	}
2809 
2810 	if (c1 == K_PS)
2811 	{
2812 	    bracketed_paste(PASTE_EX, FALSE, &line_ga);
2813 	    goto redraw;
2814 	}
2815 
2816 	if (!escaped)
2817 	{
2818 	    // CR typed means "enter", which is NL
2819 	    if (c1 == '\r')
2820 		c1 = '\n';
2821 
2822 	    if (c1 == BS || c1 == K_BS
2823 			  || c1 == DEL || c1 == K_DEL || c1 == K_KDEL)
2824 	    {
2825 		if (line_ga.ga_len > 0)
2826 		{
2827 		    if (has_mbyte)
2828 		    {
2829 			p = (char_u *)line_ga.ga_data;
2830 			p[line_ga.ga_len] = NUL;
2831 			len = (*mb_head_off)(p, p + line_ga.ga_len - 1) + 1;
2832 			line_ga.ga_len -= len;
2833 		    }
2834 		    else
2835 			--line_ga.ga_len;
2836 		    goto redraw;
2837 		}
2838 		continue;
2839 	    }
2840 
2841 	    if (c1 == Ctrl_U)
2842 	    {
2843 		msg_col = startcol;
2844 		msg_clr_eos();
2845 		line_ga.ga_len = 0;
2846 		goto redraw;
2847 	    }
2848 
2849 	    if (c1 == Ctrl_T)
2850 	    {
2851 		sw = get_sw_value(curbuf);
2852 		p = (char_u *)line_ga.ga_data;
2853 		p[line_ga.ga_len] = NUL;
2854 		indent = get_indent_str(p, 8, FALSE);
2855 		indent += sw - indent % sw;
2856 add_indent:
2857 		while (get_indent_str(p, 8, FALSE) < indent)
2858 		{
2859 		    (void)ga_grow(&line_ga, 2);  // one more for the NUL
2860 		    p = (char_u *)line_ga.ga_data;
2861 		    s = skipwhite(p);
2862 		    mch_memmove(s + 1, s, line_ga.ga_len - (s - p) + 1);
2863 		    *s = ' ';
2864 		    ++line_ga.ga_len;
2865 		}
2866 redraw:
2867 		// redraw the line
2868 		msg_col = startcol;
2869 		vcol = 0;
2870 		p = (char_u *)line_ga.ga_data;
2871 		p[line_ga.ga_len] = NUL;
2872 		while (p < (char_u *)line_ga.ga_data + line_ga.ga_len)
2873 		{
2874 		    if (*p == TAB)
2875 		    {
2876 			do
2877 			    msg_putchar(' ');
2878 			while (++vcol % 8);
2879 			++p;
2880 		    }
2881 		    else
2882 		    {
2883 			len = mb_ptr2len(p);
2884 			msg_outtrans_len(p, len);
2885 			vcol += ptr2cells(p);
2886 			p += len;
2887 		    }
2888 		}
2889 		msg_clr_eos();
2890 		windgoto(msg_row, msg_col);
2891 		continue;
2892 	    }
2893 
2894 	    if (c1 == Ctrl_D)
2895 	    {
2896 		// Delete one shiftwidth.
2897 		p = (char_u *)line_ga.ga_data;
2898 		if (prev_char == '0' || prev_char == '^')
2899 		{
2900 		    if (prev_char == '^')
2901 			ex_keep_indent = TRUE;
2902 		    indent = 0;
2903 		    p[--line_ga.ga_len] = NUL;
2904 		}
2905 		else
2906 		{
2907 		    p[line_ga.ga_len] = NUL;
2908 		    indent = get_indent_str(p, 8, FALSE);
2909 		    if (indent > 0)
2910 		    {
2911 			--indent;
2912 			indent -= indent % get_sw_value(curbuf);
2913 		    }
2914 		}
2915 		while (get_indent_str(p, 8, FALSE) > indent)
2916 		{
2917 		    s = skipwhite(p);
2918 		    mch_memmove(s - 1, s, line_ga.ga_len - (s - p) + 1);
2919 		    --line_ga.ga_len;
2920 		}
2921 		goto add_indent;
2922 	    }
2923 
2924 	    if (c1 == Ctrl_V || c1 == Ctrl_Q)
2925 	    {
2926 		escaped = TRUE;
2927 		continue;
2928 	    }
2929 
2930 	    // Ignore special key codes: mouse movement, K_IGNORE, etc.
2931 	    if (IS_SPECIAL(c1))
2932 		continue;
2933 	}
2934 
2935 	if (IS_SPECIAL(c1))
2936 	    c1 = '?';
2937 	if (has_mbyte)
2938 	    len = (*mb_char2bytes)(c1,
2939 				  (char_u *)line_ga.ga_data + line_ga.ga_len);
2940 	else
2941 	{
2942 	    len = 1;
2943 	    ((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
2944 	}
2945 	if (c1 == '\n')
2946 	    msg_putchar('\n');
2947 	else if (c1 == TAB)
2948 	{
2949 	    // Don't use chartabsize(), 'ts' can be different
2950 	    do
2951 		msg_putchar(' ');
2952 	    while (++vcol % 8);
2953 	}
2954 	else
2955 	{
2956 	    msg_outtrans_len(
2957 		     ((char_u *)line_ga.ga_data) + line_ga.ga_len, len);
2958 	    vcol += char2cells(c1);
2959 	}
2960 	line_ga.ga_len += len;
2961 	escaped = FALSE;
2962 
2963 	windgoto(msg_row, msg_col);
2964 	pend = (char_u *)(line_ga.ga_data) + line_ga.ga_len;
2965 
2966 	// We are done when a NL is entered, but not when it comes after an
2967 	// odd number of backslashes, that results in a NUL.
2968 	if (line_ga.ga_len > 0 && pend[-1] == '\n')
2969 	{
2970 	    int bcount = 0;
2971 
2972 	    while (line_ga.ga_len - 2 >= bcount && pend[-2 - bcount] == '\\')
2973 		++bcount;
2974 
2975 	    if (bcount > 0)
2976 	    {
2977 		// Halve the number of backslashes: "\NL" -> "NUL", "\\NL" ->
2978 		// "\NL", etc.
2979 		line_ga.ga_len -= (bcount + 1) / 2;
2980 		pend -= (bcount + 1) / 2;
2981 		pend[-1] = '\n';
2982 	    }
2983 
2984 	    if ((bcount & 1) == 0)
2985 	    {
2986 		--line_ga.ga_len;
2987 		--pend;
2988 		*pend = NUL;
2989 		break;
2990 	    }
2991 	}
2992     }
2993 
2994     --no_mapping;
2995     --allow_keys;
2996 
2997     // make following messages go to the next line
2998     msg_didout = FALSE;
2999     msg_col = 0;
3000     if (msg_row < Rows - 1)
3001 	++msg_row;
3002     emsg_on_display = FALSE;		// don't want ui_delay()
3003 
3004     if (got_int)
3005 	ga_clear(&line_ga);
3006 
3007     return (char_u *)line_ga.ga_data;
3008 }
3009 
3010 # if defined(MCH_CURSOR_SHAPE) || defined(FEAT_GUI) \
3011 	|| defined(FEAT_MOUSESHAPE) || defined(PROTO)
3012 /*
3013  * Return TRUE if ccline.overstrike is on.
3014  */
3015     int
3016 cmdline_overstrike(void)
3017 {
3018     return ccline.overstrike;
3019 }
3020 
3021 /*
3022  * Return TRUE if the cursor is at the end of the cmdline.
3023  */
3024     int
3025 cmdline_at_end(void)
3026 {
3027     return (ccline.cmdpos >= ccline.cmdlen);
3028 }
3029 #endif
3030 
3031 #if (defined(FEAT_XIM) && (defined(FEAT_GUI_GTK))) || defined(PROTO)
3032 /*
3033  * Return the virtual column number at the current cursor position.
3034  * This is used by the IM code to obtain the start of the preedit string.
3035  */
3036     colnr_T
3037 cmdline_getvcol_cursor(void)
3038 {
3039     if (ccline.cmdbuff == NULL || ccline.cmdpos > ccline.cmdlen)
3040 	return MAXCOL;
3041 
3042     if (has_mbyte)
3043     {
3044 	colnr_T	col;
3045 	int	i = 0;
3046 
3047 	for (col = 0; i < ccline.cmdpos; ++col)
3048 	    i += (*mb_ptr2len)(ccline.cmdbuff + i);
3049 
3050 	return col;
3051     }
3052     else
3053 	return ccline.cmdpos;
3054 }
3055 #endif
3056 
3057 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
3058 /*
3059  * If part of the command line is an IM preedit string, redraw it with
3060  * IM feedback attributes.  The cursor position is restored after drawing.
3061  */
3062     static void
3063 redrawcmd_preedit(void)
3064 {
3065     if ((State & CMDLINE)
3066 	    && xic != NULL
3067 	    // && im_get_status()  doesn't work when using SCIM
3068 	    && !p_imdisable
3069 	    && im_is_preediting())
3070     {
3071 	int	cmdpos = 0;
3072 	int	cmdspos;
3073 	int	old_row;
3074 	int	old_col;
3075 	colnr_T	col;
3076 
3077 	old_row = msg_row;
3078 	old_col = msg_col;
3079 	cmdspos = ((ccline.cmdfirstc != NUL) ? 1 : 0) + ccline.cmdindent;
3080 
3081 	if (has_mbyte)
3082 	{
3083 	    for (col = 0; col < preedit_start_col
3084 			  && cmdpos < ccline.cmdlen; ++col)
3085 	    {
3086 		cmdspos += (*mb_ptr2cells)(ccline.cmdbuff + cmdpos);
3087 		cmdpos  += (*mb_ptr2len)(ccline.cmdbuff + cmdpos);
3088 	    }
3089 	}
3090 	else
3091 	{
3092 	    cmdspos += preedit_start_col;
3093 	    cmdpos  += preedit_start_col;
3094 	}
3095 
3096 	msg_row = cmdline_row + (cmdspos / (int)Columns);
3097 	msg_col = cmdspos % (int)Columns;
3098 	if (msg_row >= Rows)
3099 	    msg_row = Rows - 1;
3100 
3101 	for (col = 0; cmdpos < ccline.cmdlen; ++col)
3102 	{
3103 	    int char_len;
3104 	    int char_attr;
3105 
3106 	    char_attr = im_get_feedback_attr(col);
3107 	    if (char_attr < 0)
3108 		break; // end of preedit string
3109 
3110 	    if (has_mbyte)
3111 		char_len = (*mb_ptr2len)(ccline.cmdbuff + cmdpos);
3112 	    else
3113 		char_len = 1;
3114 
3115 	    msg_outtrans_len_attr(ccline.cmdbuff + cmdpos, char_len, char_attr);
3116 	    cmdpos += char_len;
3117 	}
3118 
3119 	msg_row = old_row;
3120 	msg_col = old_col;
3121     }
3122 }
3123 #endif // FEAT_XIM && FEAT_GUI_GTK
3124 
3125 /*
3126  * Allocate a new command line buffer.
3127  * Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
3128  */
3129     static void
3130 alloc_cmdbuff(int len)
3131 {
3132     /*
3133      * give some extra space to avoid having to allocate all the time
3134      */
3135     if (len < 80)
3136 	len = 100;
3137     else
3138 	len += 20;
3139 
3140     ccline.cmdbuff = alloc(len);    // caller should check for out-of-memory
3141     ccline.cmdbufflen = len;
3142 }
3143 
3144 /*
3145  * Re-allocate the command line to length len + something extra.
3146  * return FAIL for failure, OK otherwise
3147  */
3148     int
3149 realloc_cmdbuff(int len)
3150 {
3151     char_u	*p;
3152 
3153     if (len < ccline.cmdbufflen)
3154 	return OK;			// no need to resize
3155 
3156     p = ccline.cmdbuff;
3157     alloc_cmdbuff(len);			// will get some more
3158     if (ccline.cmdbuff == NULL)		// out of memory
3159     {
3160 	ccline.cmdbuff = p;		// keep the old one
3161 	return FAIL;
3162     }
3163     // There isn't always a NUL after the command, but it may need to be
3164     // there, thus copy up to the NUL and add a NUL.
3165     mch_memmove(ccline.cmdbuff, p, (size_t)ccline.cmdlen);
3166     ccline.cmdbuff[ccline.cmdlen] = NUL;
3167     vim_free(p);
3168 
3169     if (ccline.xpc != NULL
3170 	    && ccline.xpc->xp_pattern != NULL
3171 	    && ccline.xpc->xp_context != EXPAND_NOTHING
3172 	    && ccline.xpc->xp_context != EXPAND_UNSUCCESSFUL)
3173     {
3174 	int i = (int)(ccline.xpc->xp_pattern - p);
3175 
3176 	// If xp_pattern points inside the old cmdbuff it needs to be adjusted
3177 	// to point into the newly allocated memory.
3178 	if (i >= 0 && i <= ccline.cmdlen)
3179 	    ccline.xpc->xp_pattern = ccline.cmdbuff + i;
3180     }
3181 
3182     return OK;
3183 }
3184 
3185 #if defined(FEAT_ARABIC) || defined(PROTO)
3186 static char_u	*arshape_buf = NULL;
3187 
3188 # if defined(EXITFREE) || defined(PROTO)
3189     void
3190 free_arshape_buf(void)
3191 {
3192     vim_free(arshape_buf);
3193 }
3194 # endif
3195 #endif
3196 
3197 /*
3198  * Draw part of the cmdline at the current cursor position.  But draw stars
3199  * when cmdline_star is TRUE.
3200  */
3201     static void
3202 draw_cmdline(int start, int len)
3203 {
3204 #if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
3205     int		i;
3206 
3207     if (cmdline_star > 0)
3208 	for (i = 0; i < len; ++i)
3209 	{
3210 	    msg_putchar('*');
3211 	    if (has_mbyte)
3212 		i += (*mb_ptr2len)(ccline.cmdbuff + start + i) - 1;
3213 	}
3214     else
3215 #endif
3216 #ifdef FEAT_ARABIC
3217 	if (p_arshape && !p_tbidi && cmdline_has_arabic(start, len))
3218     {
3219 	static int	buflen = 0;
3220 	char_u		*p;
3221 	int		j;
3222 	int		newlen = 0;
3223 	int		mb_l;
3224 	int		pc, pc1 = 0;
3225 	int		prev_c = 0;
3226 	int		prev_c1 = 0;
3227 	int		u8c;
3228 	int		u8cc[MAX_MCO];
3229 	int		nc = 0;
3230 
3231 	/*
3232 	 * Do arabic shaping into a temporary buffer.  This is very
3233 	 * inefficient!
3234 	 */
3235 	if (len * 2 + 2 > buflen)
3236 	{
3237 	    // Re-allocate the buffer.  We keep it around to avoid a lot of
3238 	    // alloc()/free() calls.
3239 	    vim_free(arshape_buf);
3240 	    buflen = len * 2 + 2;
3241 	    arshape_buf = alloc(buflen);
3242 	    if (arshape_buf == NULL)
3243 		return;	// out of memory
3244 	}
3245 
3246 	if (utf_iscomposing(utf_ptr2char(ccline.cmdbuff + start)))
3247 	{
3248 	    // Prepend a space to draw the leading composing char on.
3249 	    arshape_buf[0] = ' ';
3250 	    newlen = 1;
3251 	}
3252 
3253 	for (j = start; j < start + len; j += mb_l)
3254 	{
3255 	    p = ccline.cmdbuff + j;
3256 	    u8c = utfc_ptr2char_len(p, u8cc, start + len - j);
3257 	    mb_l = utfc_ptr2len_len(p, start + len - j);
3258 	    if (ARABIC_CHAR(u8c))
3259 	    {
3260 		// Do Arabic shaping.
3261 		if (cmdmsg_rl)
3262 		{
3263 		    // displaying from right to left
3264 		    pc = prev_c;
3265 		    pc1 = prev_c1;
3266 		    prev_c1 = u8cc[0];
3267 		    if (j + mb_l >= start + len)
3268 			nc = NUL;
3269 		    else
3270 			nc = utf_ptr2char(p + mb_l);
3271 		}
3272 		else
3273 		{
3274 		    // displaying from left to right
3275 		    if (j + mb_l >= start + len)
3276 			pc = NUL;
3277 		    else
3278 		    {
3279 			int	pcc[MAX_MCO];
3280 
3281 			pc = utfc_ptr2char_len(p + mb_l, pcc,
3282 						      start + len - j - mb_l);
3283 			pc1 = pcc[0];
3284 		    }
3285 		    nc = prev_c;
3286 		}
3287 		prev_c = u8c;
3288 
3289 		u8c = arabic_shape(u8c, NULL, &u8cc[0], pc, pc1, nc);
3290 
3291 		newlen += (*mb_char2bytes)(u8c, arshape_buf + newlen);
3292 		if (u8cc[0] != 0)
3293 		{
3294 		    newlen += (*mb_char2bytes)(u8cc[0], arshape_buf + newlen);
3295 		    if (u8cc[1] != 0)
3296 			newlen += (*mb_char2bytes)(u8cc[1],
3297 							arshape_buf + newlen);
3298 		}
3299 	    }
3300 	    else
3301 	    {
3302 		prev_c = u8c;
3303 		mch_memmove(arshape_buf + newlen, p, mb_l);
3304 		newlen += mb_l;
3305 	    }
3306 	}
3307 
3308 	msg_outtrans_len(arshape_buf, newlen);
3309     }
3310     else
3311 #endif
3312 	msg_outtrans_len(ccline.cmdbuff + start, len);
3313 }
3314 
3315 /*
3316  * Put a character on the command line.  Shifts the following text to the
3317  * right when "shift" is TRUE.  Used for CTRL-V, CTRL-K, etc.
3318  * "c" must be printable (fit in one display cell)!
3319  */
3320     void
3321 putcmdline(int c, int shift)
3322 {
3323     if (cmd_silent)
3324 	return;
3325     msg_no_more = TRUE;
3326     msg_putchar(c);
3327     if (shift)
3328 	draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
3329     msg_no_more = FALSE;
3330     cursorcmd();
3331     extra_char = c;
3332     extra_char_shift = shift;
3333 }
3334 
3335 /*
3336  * Undo a putcmdline(c, FALSE).
3337  */
3338     void
3339 unputcmdline(void)
3340 {
3341     if (cmd_silent)
3342 	return;
3343     msg_no_more = TRUE;
3344     if (ccline.cmdlen == ccline.cmdpos)
3345 	msg_putchar(' ');
3346     else if (has_mbyte)
3347 	draw_cmdline(ccline.cmdpos,
3348 			       (*mb_ptr2len)(ccline.cmdbuff + ccline.cmdpos));
3349     else
3350 	draw_cmdline(ccline.cmdpos, 1);
3351     msg_no_more = FALSE;
3352     cursorcmd();
3353     extra_char = NUL;
3354 }
3355 
3356 /*
3357  * Put the given string, of the given length, onto the command line.
3358  * If len is -1, then STRLEN() is used to calculate the length.
3359  * If 'redraw' is TRUE then the new part of the command line, and the remaining
3360  * part will be redrawn, otherwise it will not.  If this function is called
3361  * twice in a row, then 'redraw' should be FALSE and redrawcmd() should be
3362  * called afterwards.
3363  */
3364     int
3365 put_on_cmdline(char_u *str, int len, int redraw)
3366 {
3367     int		retval;
3368     int		i;
3369     int		m;
3370     int		c;
3371 
3372     if (len < 0)
3373 	len = (int)STRLEN(str);
3374 
3375     // Check if ccline.cmdbuff needs to be longer
3376     if (ccline.cmdlen + len + 1 >= ccline.cmdbufflen)
3377 	retval = realloc_cmdbuff(ccline.cmdlen + len + 1);
3378     else
3379 	retval = OK;
3380     if (retval == OK)
3381     {
3382 	if (!ccline.overstrike)
3383 	{
3384 	    mch_memmove(ccline.cmdbuff + ccline.cmdpos + len,
3385 					       ccline.cmdbuff + ccline.cmdpos,
3386 				     (size_t)(ccline.cmdlen - ccline.cmdpos));
3387 	    ccline.cmdlen += len;
3388 	}
3389 	else
3390 	{
3391 	    if (has_mbyte)
3392 	    {
3393 		// Count nr of characters in the new string.
3394 		m = 0;
3395 		for (i = 0; i < len; i += (*mb_ptr2len)(str + i))
3396 		    ++m;
3397 		// Count nr of bytes in cmdline that are overwritten by these
3398 		// characters.
3399 		for (i = ccline.cmdpos; i < ccline.cmdlen && m > 0;
3400 				 i += (*mb_ptr2len)(ccline.cmdbuff + i))
3401 		    --m;
3402 		if (i < ccline.cmdlen)
3403 		{
3404 		    mch_memmove(ccline.cmdbuff + ccline.cmdpos + len,
3405 			    ccline.cmdbuff + i, (size_t)(ccline.cmdlen - i));
3406 		    ccline.cmdlen += ccline.cmdpos + len - i;
3407 		}
3408 		else
3409 		    ccline.cmdlen = ccline.cmdpos + len;
3410 	    }
3411 	    else if (ccline.cmdpos + len > ccline.cmdlen)
3412 		ccline.cmdlen = ccline.cmdpos + len;
3413 	}
3414 	mch_memmove(ccline.cmdbuff + ccline.cmdpos, str, (size_t)len);
3415 	ccline.cmdbuff[ccline.cmdlen] = NUL;
3416 
3417 	if (enc_utf8)
3418 	{
3419 	    // When the inserted text starts with a composing character,
3420 	    // backup to the character before it.  There could be two of them.
3421 	    i = 0;
3422 	    c = utf_ptr2char(ccline.cmdbuff + ccline.cmdpos);
3423 	    while (ccline.cmdpos > 0 && utf_iscomposing(c))
3424 	    {
3425 		i = (*mb_head_off)(ccline.cmdbuff,
3426 				      ccline.cmdbuff + ccline.cmdpos - 1) + 1;
3427 		ccline.cmdpos -= i;
3428 		len += i;
3429 		c = utf_ptr2char(ccline.cmdbuff + ccline.cmdpos);
3430 	    }
3431 #ifdef FEAT_ARABIC
3432 	    if (i == 0 && ccline.cmdpos > 0 && arabic_maycombine(c))
3433 	    {
3434 		// Check the previous character for Arabic combining pair.
3435 		i = (*mb_head_off)(ccline.cmdbuff,
3436 				      ccline.cmdbuff + ccline.cmdpos - 1) + 1;
3437 		if (arabic_combine(utf_ptr2char(ccline.cmdbuff
3438 						     + ccline.cmdpos - i), c))
3439 		{
3440 		    ccline.cmdpos -= i;
3441 		    len += i;
3442 		}
3443 		else
3444 		    i = 0;
3445 	    }
3446 #endif
3447 	    if (i != 0)
3448 	    {
3449 		// Also backup the cursor position.
3450 		i = ptr2cells(ccline.cmdbuff + ccline.cmdpos);
3451 		ccline.cmdspos -= i;
3452 		msg_col -= i;
3453 		if (msg_col < 0)
3454 		{
3455 		    msg_col += Columns;
3456 		    --msg_row;
3457 		}
3458 	    }
3459 	}
3460 
3461 	if (redraw && !cmd_silent)
3462 	{
3463 	    msg_no_more = TRUE;
3464 	    i = cmdline_row;
3465 	    cursorcmd();
3466 	    draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
3467 	    // Avoid clearing the rest of the line too often.
3468 	    if (cmdline_row != i || ccline.overstrike)
3469 		msg_clr_eos();
3470 	    msg_no_more = FALSE;
3471 	}
3472 	if (KeyTyped)
3473 	{
3474 	    m = Columns * Rows;
3475 	    if (m < 0)	// overflow, Columns or Rows at weird value
3476 		m = MAXCOL;
3477 	}
3478 	else
3479 	    m = MAXCOL;
3480 	for (i = 0; i < len; ++i)
3481 	{
3482 	    c = cmdline_charsize(ccline.cmdpos);
3483 	    // count ">" for a double-wide char that doesn't fit.
3484 	    if (has_mbyte)
3485 		correct_cmdspos(ccline.cmdpos, c);
3486 	    // Stop cursor at the end of the screen, but do increment the
3487 	    // insert position, so that entering a very long command
3488 	    // works, even though you can't see it.
3489 	    if (ccline.cmdspos + c < m)
3490 		ccline.cmdspos += c;
3491 
3492 	    if (has_mbyte)
3493 	    {
3494 		c = (*mb_ptr2len)(ccline.cmdbuff + ccline.cmdpos) - 1;
3495 		if (c > len - i - 1)
3496 		    c = len - i - 1;
3497 		ccline.cmdpos += c;
3498 		i += c;
3499 	    }
3500 	    ++ccline.cmdpos;
3501 	}
3502     }
3503     if (redraw)
3504 	msg_check();
3505     return retval;
3506 }
3507 
3508 static cmdline_info_T	prev_ccline;
3509 static int		prev_ccline_used = FALSE;
3510 
3511 /*
3512  * Save ccline, because obtaining the "=" register may execute "normal :cmd"
3513  * and overwrite it.  But get_cmdline_str() may need it, thus make it
3514  * available globally in prev_ccline.
3515  */
3516     static void
3517 save_cmdline(cmdline_info_T *ccp)
3518 {
3519     if (!prev_ccline_used)
3520     {
3521 	CLEAR_FIELD(prev_ccline);
3522 	prev_ccline_used = TRUE;
3523     }
3524     *ccp = prev_ccline;
3525     prev_ccline = ccline;
3526     ccline.cmdbuff = NULL;  // signal that ccline is not in use
3527 }
3528 
3529 /*
3530  * Restore ccline after it has been saved with save_cmdline().
3531  */
3532     static void
3533 restore_cmdline(cmdline_info_T *ccp)
3534 {
3535     ccline = prev_ccline;
3536     prev_ccline = *ccp;
3537 }
3538 
3539 /*
3540  * Paste a yank register into the command line.
3541  * Used by CTRL-R command in command-line mode.
3542  * insert_reg() can't be used here, because special characters from the
3543  * register contents will be interpreted as commands.
3544  *
3545  * Return FAIL for failure, OK otherwise.
3546  */
3547     static int
3548 cmdline_paste(
3549     int regname,
3550     int literally,	// Insert text literally instead of "as typed"
3551     int remcr)		// remove trailing CR
3552 {
3553     long		i;
3554     char_u		*arg;
3555     char_u		*p;
3556     int			allocated;
3557 
3558     // check for valid regname; also accept special characters for CTRL-R in
3559     // the command line
3560     if (regname != Ctrl_F && regname != Ctrl_P && regname != Ctrl_W
3561 	    && regname != Ctrl_A && regname != Ctrl_L
3562 	    && !valid_yank_reg(regname, FALSE))
3563 	return FAIL;
3564 
3565     // A register containing CTRL-R can cause an endless loop.  Allow using
3566     // CTRL-C to break the loop.
3567     line_breakcheck();
3568     if (got_int)
3569 	return FAIL;
3570 
3571 #ifdef FEAT_CLIPBOARD
3572     regname = may_get_selection(regname);
3573 #endif
3574 
3575     // Need to  set "textwinlock" to avoid nasty things like going to another
3576     // buffer when evaluating an expression.
3577     ++textwinlock;
3578     i = get_spec_reg(regname, &arg, &allocated, TRUE);
3579     --textwinlock;
3580 
3581     if (i)
3582     {
3583 	// Got the value of a special register in "arg".
3584 	if (arg == NULL)
3585 	    return FAIL;
3586 
3587 	// When 'incsearch' is set and CTRL-R CTRL-W used: skip the duplicate
3588 	// part of the word.
3589 	p = arg;
3590 	if (p_is && regname == Ctrl_W)
3591 	{
3592 	    char_u  *w;
3593 	    int	    len;
3594 
3595 	    // Locate start of last word in the cmd buffer.
3596 	    for (w = ccline.cmdbuff + ccline.cmdpos; w > ccline.cmdbuff; )
3597 	    {
3598 		if (has_mbyte)
3599 		{
3600 		    len = (*mb_head_off)(ccline.cmdbuff, w - 1) + 1;
3601 		    if (!vim_iswordc(mb_ptr2char(w - len)))
3602 			break;
3603 		    w -= len;
3604 		}
3605 		else
3606 		{
3607 		    if (!vim_iswordc(w[-1]))
3608 			break;
3609 		    --w;
3610 		}
3611 	    }
3612 	    len = (int)((ccline.cmdbuff + ccline.cmdpos) - w);
3613 	    if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0)
3614 		p += len;
3615 	}
3616 
3617 	cmdline_paste_str(p, literally);
3618 	if (allocated)
3619 	    vim_free(arg);
3620 	return OK;
3621     }
3622 
3623     return cmdline_paste_reg(regname, literally, remcr);
3624 }
3625 
3626 /*
3627  * Put a string on the command line.
3628  * When "literally" is TRUE, insert literally.
3629  * When "literally" is FALSE, insert as typed, but don't leave the command
3630  * line.
3631  */
3632     void
3633 cmdline_paste_str(char_u *s, int literally)
3634 {
3635     int		c, cv;
3636 
3637     if (literally)
3638 	put_on_cmdline(s, -1, TRUE);
3639     else
3640 	while (*s != NUL)
3641 	{
3642 	    cv = *s;
3643 	    if (cv == Ctrl_V && s[1])
3644 		++s;
3645 	    if (has_mbyte)
3646 		c = mb_cptr2char_adv(&s);
3647 	    else
3648 		c = *s++;
3649 	    if (cv == Ctrl_V || c == ESC || c == Ctrl_C
3650 		    || c == CAR || c == NL || c == Ctrl_L
3651 #ifdef UNIX
3652 		    || c == intr_char
3653 #endif
3654 		    || (c == Ctrl_BSL && *s == Ctrl_N))
3655 		stuffcharReadbuff(Ctrl_V);
3656 	    stuffcharReadbuff(c);
3657 	}
3658 }
3659 
3660 #ifdef FEAT_WILDMENU
3661 /*
3662  * Delete characters on the command line, from "from" to the current
3663  * position.
3664  */
3665     static void
3666 cmdline_del(int from)
3667 {
3668     mch_memmove(ccline.cmdbuff + from, ccline.cmdbuff + ccline.cmdpos,
3669 	    (size_t)(ccline.cmdlen - ccline.cmdpos + 1));
3670     ccline.cmdlen -= ccline.cmdpos - from;
3671     ccline.cmdpos = from;
3672 }
3673 #endif
3674 
3675 /*
3676  * This function is called when the screen size changes and with incremental
3677  * search and in other situations where the command line may have been
3678  * overwritten.
3679  */
3680     void
3681 redrawcmdline(void)
3682 {
3683     redrawcmdline_ex(TRUE);
3684 }
3685 
3686     void
3687 redrawcmdline_ex(int do_compute_cmdrow)
3688 {
3689     if (cmd_silent)
3690 	return;
3691     need_wait_return = FALSE;
3692     if (do_compute_cmdrow)
3693 	compute_cmdrow();
3694     redrawcmd();
3695     cursorcmd();
3696 }
3697 
3698     static void
3699 redrawcmdprompt(void)
3700 {
3701     int		i;
3702 
3703     if (cmd_silent)
3704 	return;
3705     if (ccline.cmdfirstc != NUL)
3706 	msg_putchar(ccline.cmdfirstc);
3707     if (ccline.cmdprompt != NULL)
3708     {
3709 	msg_puts_attr((char *)ccline.cmdprompt, ccline.cmdattr);
3710 	ccline.cmdindent = msg_col + (msg_row - cmdline_row) * Columns;
3711 	// do the reverse of set_cmdspos()
3712 	if (ccline.cmdfirstc != NUL)
3713 	    --ccline.cmdindent;
3714     }
3715     else
3716 	for (i = ccline.cmdindent; i > 0; --i)
3717 	    msg_putchar(' ');
3718 }
3719 
3720 /*
3721  * Redraw what is currently on the command line.
3722  */
3723     void
3724 redrawcmd(void)
3725 {
3726     if (cmd_silent)
3727 	return;
3728 
3729     // when 'incsearch' is set there may be no command line while redrawing
3730     if (ccline.cmdbuff == NULL)
3731     {
3732 	windgoto(cmdline_row, 0);
3733 	msg_clr_eos();
3734 	return;
3735     }
3736 
3737     msg_start();
3738     redrawcmdprompt();
3739 
3740     // Don't use more prompt, truncate the cmdline if it doesn't fit.
3741     msg_no_more = TRUE;
3742     draw_cmdline(0, ccline.cmdlen);
3743     msg_clr_eos();
3744     msg_no_more = FALSE;
3745 
3746     set_cmdspos_cursor();
3747     if (extra_char != NUL)
3748 	putcmdline(extra_char, extra_char_shift);
3749 
3750     /*
3751      * An emsg() before may have set msg_scroll. This is used in normal mode,
3752      * in cmdline mode we can reset them now.
3753      */
3754     msg_scroll = FALSE;		// next message overwrites cmdline
3755 
3756     // Typing ':' at the more prompt may set skip_redraw.  We don't want this
3757     // in cmdline mode
3758     skip_redraw = FALSE;
3759 }
3760 
3761     void
3762 compute_cmdrow(void)
3763 {
3764     if (exmode_active || msg_scrolled != 0)
3765 	cmdline_row = Rows - 1;
3766     else
3767 	cmdline_row = W_WINROW(lastwin) + lastwin->w_height
3768 						    + lastwin->w_status_height;
3769 }
3770 
3771     void
3772 cursorcmd(void)
3773 {
3774     if (cmd_silent)
3775 	return;
3776 
3777 #ifdef FEAT_RIGHTLEFT
3778     if (cmdmsg_rl)
3779     {
3780 	msg_row = cmdline_row  + (ccline.cmdspos / (int)(Columns - 1));
3781 	msg_col = (int)Columns - (ccline.cmdspos % (int)(Columns - 1)) - 1;
3782 	if (msg_row <= 0)
3783 	    msg_row = Rows - 1;
3784     }
3785     else
3786 #endif
3787     {
3788 	msg_row = cmdline_row + (ccline.cmdspos / (int)Columns);
3789 	msg_col = ccline.cmdspos % (int)Columns;
3790 	if (msg_row >= Rows)
3791 	    msg_row = Rows - 1;
3792     }
3793 
3794     windgoto(msg_row, msg_col);
3795 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
3796     if (p_imst == IM_ON_THE_SPOT)
3797 	redrawcmd_preedit();
3798 #endif
3799 #ifdef MCH_CURSOR_SHAPE
3800     mch_update_cursor();
3801 #endif
3802 }
3803 
3804     void
3805 gotocmdline(int clr)
3806 {
3807     msg_start();
3808 #ifdef FEAT_RIGHTLEFT
3809     if (cmdmsg_rl)
3810 	msg_col = Columns - 1;
3811     else
3812 #endif
3813 	msg_col = 0;	    // always start in column 0
3814     if (clr)		    // clear the bottom line(s)
3815 	msg_clr_eos();	    // will reset clear_cmdline
3816     windgoto(cmdline_row, 0);
3817 }
3818 
3819 /*
3820  * Check the word in front of the cursor for an abbreviation.
3821  * Called when the non-id character "c" has been entered.
3822  * When an abbreviation is recognized it is removed from the text with
3823  * backspaces and the replacement string is inserted, followed by "c".
3824  */
3825     static int
3826 ccheck_abbr(int c)
3827 {
3828     int spos = 0;
3829 
3830     if (p_paste || no_abbr)	    // no abbreviations or in paste mode
3831 	return FALSE;
3832 
3833     // Do not consider '<,'> be part of the mapping, skip leading whitespace.
3834     // Actually accepts any mark.
3835     while (VIM_ISWHITE(ccline.cmdbuff[spos]) && spos < ccline.cmdlen)
3836 	spos++;
3837     if (ccline.cmdlen - spos > 5
3838 	    && ccline.cmdbuff[spos] == '\''
3839 	    && ccline.cmdbuff[spos + 2] == ','
3840 	    && ccline.cmdbuff[spos + 3] == '\'')
3841 	spos += 5;
3842     else
3843 	// check abbreviation from the beginning of the commandline
3844 	spos = 0;
3845 
3846     return check_abbr(c, ccline.cmdbuff, ccline.cmdpos, spos);
3847 }
3848 
3849 /*
3850  * Escape special characters in "fname" for when used as a file name argument
3851  * after a Vim command, or, when "shell" is non-zero, a shell command.
3852  * Returns the result in allocated memory.
3853  */
3854     char_u *
3855 vim_strsave_fnameescape(char_u *fname, int shell UNUSED)
3856 {
3857     char_u	*p;
3858 #ifdef BACKSLASH_IN_FILENAME
3859     char_u	buf[20];
3860     int		j = 0;
3861 
3862     // Don't escape '[', '{' and '!' if they are in 'isfname'.
3863     for (p = PATH_ESC_CHARS; *p != NUL; ++p)
3864 	if ((*p != '[' && *p != '{' && *p != '!') || !vim_isfilec(*p))
3865 	    buf[j++] = *p;
3866     buf[j] = NUL;
3867     p = vim_strsave_escaped(fname, buf);
3868 #else
3869     p = vim_strsave_escaped(fname, shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS);
3870     if (shell && csh_like_shell() && p != NULL)
3871     {
3872 	char_u	    *s;
3873 
3874 	// For csh and similar shells need to put two backslashes before '!'.
3875 	// One is taken by Vim, one by the shell.
3876 	s = vim_strsave_escaped(p, (char_u *)"!");
3877 	vim_free(p);
3878 	p = s;
3879     }
3880 #endif
3881 
3882     // '>' and '+' are special at the start of some commands, e.g. ":edit" and
3883     // ":write".  "cd -" has a special meaning.
3884     if (p != NULL && (*p == '>' || *p == '+' || (*p == '-' && p[1] == NUL)))
3885 	escape_fname(&p);
3886 
3887     return p;
3888 }
3889 
3890 /*
3891  * Put a backslash before the file name in "pp", which is in allocated memory.
3892  */
3893     void
3894 escape_fname(char_u **pp)
3895 {
3896     char_u	*p;
3897 
3898     p = alloc(STRLEN(*pp) + 2);
3899     if (p != NULL)
3900     {
3901 	p[0] = '\\';
3902 	STRCPY(p + 1, *pp);
3903 	vim_free(*pp);
3904 	*pp = p;
3905     }
3906 }
3907 
3908 /*
3909  * For each file name in files[num_files]:
3910  * If 'orig_pat' starts with "~/", replace the home directory with "~".
3911  */
3912     void
3913 tilde_replace(
3914     char_u  *orig_pat,
3915     int	    num_files,
3916     char_u  **files)
3917 {
3918     int	    i;
3919     char_u  *p;
3920 
3921     if (orig_pat[0] == '~' && vim_ispathsep(orig_pat[1]))
3922     {
3923 	for (i = 0; i < num_files; ++i)
3924 	{
3925 	    p = home_replace_save(NULL, files[i]);
3926 	    if (p != NULL)
3927 	    {
3928 		vim_free(files[i]);
3929 		files[i] = p;
3930 	    }
3931 	}
3932     }
3933 }
3934 
3935 /*
3936  * Get a pointer to the current command line info.
3937  */
3938     cmdline_info_T *
3939 get_cmdline_info(void)
3940 {
3941     return &ccline;
3942 }
3943 
3944 #if defined(FEAT_EVAL) || defined(FEAT_CMDWIN) || defined(PROTO)
3945 /*
3946  * Get pointer to the command line info to use. save_ccline() may clear
3947  * ccline and put the previous value in prev_ccline.
3948  */
3949     static cmdline_info_T *
3950 get_ccline_ptr(void)
3951 {
3952     if ((State & CMDLINE) == 0)
3953 	return NULL;
3954     if (ccline.cmdbuff != NULL)
3955 	return &ccline;
3956     if (prev_ccline_used && prev_ccline.cmdbuff != NULL)
3957 	return &prev_ccline;
3958     return NULL;
3959 }
3960 #endif
3961 
3962 #if defined(FEAT_EVAL) || defined(PROTO)
3963 /*
3964  * Get the current command line in allocated memory.
3965  * Only works when the command line is being edited.
3966  * Returns NULL when something is wrong.
3967  */
3968     static char_u *
3969 get_cmdline_str(void)
3970 {
3971     cmdline_info_T *p;
3972 
3973     if (cmdline_star > 0)
3974 	return NULL;
3975     p = get_ccline_ptr();
3976     if (p == NULL)
3977 	return NULL;
3978     return vim_strnsave(p->cmdbuff, p->cmdlen);
3979 }
3980 
3981 /*
3982  * "getcmdline()" function
3983  */
3984     void
3985 f_getcmdline(typval_T *argvars UNUSED, typval_T *rettv)
3986 {
3987     rettv->v_type = VAR_STRING;
3988     rettv->vval.v_string = get_cmdline_str();
3989 }
3990 
3991 /*
3992  * "getcmdpos()" function
3993  */
3994     void
3995 f_getcmdpos(typval_T *argvars UNUSED, typval_T *rettv)
3996 {
3997     cmdline_info_T *p = get_ccline_ptr();
3998 
3999     rettv->vval.v_number = 0;
4000     if (p != NULL)
4001     rettv->vval.v_number = p->cmdpos + 1;
4002 }
4003 
4004 /*
4005  * Set the command line byte position to "pos".  Zero is the first position.
4006  * Only works when the command line is being edited.
4007  * Returns 1 when failed, 0 when OK.
4008  */
4009     static int
4010 set_cmdline_pos(
4011     int		pos)
4012 {
4013     cmdline_info_T *p = get_ccline_ptr();
4014 
4015     if (p == NULL)
4016 	return 1;
4017 
4018     // The position is not set directly but after CTRL-\ e or CTRL-R = has
4019     // changed the command line.
4020     if (pos < 0)
4021 	new_cmdpos = 0;
4022     else
4023 	new_cmdpos = pos;
4024     return 0;
4025 }
4026 
4027 /*
4028  * "setcmdpos()" function
4029  */
4030     void
4031 f_setcmdpos(typval_T *argvars, typval_T *rettv)
4032 {
4033     int		pos = (int)tv_get_number(&argvars[0]) - 1;
4034 
4035     if (pos >= 0)
4036 	rettv->vval.v_number = set_cmdline_pos(pos);
4037 }
4038 
4039 /*
4040  * "getcmdtype()" function
4041  */
4042     void
4043 f_getcmdtype(typval_T *argvars UNUSED, typval_T *rettv)
4044 {
4045     rettv->v_type = VAR_STRING;
4046     rettv->vval.v_string = alloc(2);
4047     if (rettv->vval.v_string != NULL)
4048     {
4049 	rettv->vval.v_string[0] = get_cmdline_type();
4050 	rettv->vval.v_string[1] = NUL;
4051     }
4052 }
4053 
4054 #endif
4055 
4056 #if defined(FEAT_EVAL) || defined(FEAT_CMDWIN) || defined(PROTO)
4057 /*
4058  * Get the current command-line type.
4059  * Returns ':' or '/' or '?' or '@' or '>' or '-'
4060  * Only works when the command line is being edited.
4061  * Returns NUL when something is wrong.
4062  */
4063     int
4064 get_cmdline_type(void)
4065 {
4066     cmdline_info_T *p = get_ccline_ptr();
4067 
4068     if (p == NULL)
4069 	return NUL;
4070     if (p->cmdfirstc == NUL)
4071 	return
4072 # ifdef FEAT_EVAL
4073 	    (p->input_fn) ? '@' :
4074 # endif
4075 	    '-';
4076     return p->cmdfirstc;
4077 }
4078 #endif
4079 
4080 /*
4081  * Return the first character of the current command line.
4082  */
4083     int
4084 get_cmdline_firstc(void)
4085 {
4086     return ccline.cmdfirstc;
4087 }
4088 
4089 /*
4090  * Get indices "num1,num2" that specify a range within a list (not a range of
4091  * text lines in a buffer!) from a string.  Used for ":history" and ":clist".
4092  * Returns OK if parsed successfully, otherwise FAIL.
4093  */
4094     int
4095 get_list_range(char_u **str, int *num1, int *num2)
4096 {
4097     int		len;
4098     int		first = FALSE;
4099     varnumber_T	num;
4100 
4101     *str = skipwhite(*str);
4102     if (**str == '-' || vim_isdigit(**str))  // parse "from" part of range
4103     {
4104 	vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, FALSE);
4105 	*str += len;
4106 	*num1 = (int)num;
4107 	first = TRUE;
4108     }
4109     *str = skipwhite(*str);
4110     if (**str == ',')			// parse "to" part of range
4111     {
4112 	*str = skipwhite(*str + 1);
4113 	vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, FALSE);
4114 	if (len > 0)
4115 	{
4116 	    *num2 = (int)num;
4117 	    *str = skipwhite(*str + len);
4118 	}
4119 	else if (!first)		// no number given at all
4120 	    return FAIL;
4121     }
4122     else if (first)			// only one number given
4123 	*num2 = *num1;
4124     return OK;
4125 }
4126 
4127 #if defined(FEAT_CMDWIN) || defined(PROTO)
4128 /*
4129  * Check value of 'cedit' and set cedit_key.
4130  * Returns NULL if value is OK, error message otherwise.
4131  */
4132     char *
4133 check_cedit(void)
4134 {
4135     int n;
4136 
4137     if (*p_cedit == NUL)
4138 	cedit_key = -1;
4139     else
4140     {
4141 	n = string_to_key(p_cedit, FALSE);
4142 	if (vim_isprintc(n))
4143 	    return e_invarg;
4144 	cedit_key = n;
4145     }
4146     return NULL;
4147 }
4148 
4149 /*
4150  * Open a window on the current command line and history.  Allow editing in
4151  * the window.  Returns when the window is closed.
4152  * Returns:
4153  *	CR	 if the command is to be executed
4154  *	Ctrl_C	 if it is to be abandoned
4155  *	K_IGNORE if editing continues
4156  */
4157     static int
4158 open_cmdwin(void)
4159 {
4160     bufref_T		old_curbuf;
4161     win_T		*old_curwin = curwin;
4162     bufref_T		bufref;
4163     win_T		*wp;
4164     int			i;
4165     linenr_T		lnum;
4166     int			histtype;
4167     garray_T		winsizes;
4168     int			save_restart_edit = restart_edit;
4169     int			save_State = State;
4170     int			save_exmode = exmode_active;
4171 #ifdef FEAT_RIGHTLEFT
4172     int			save_cmdmsg_rl = cmdmsg_rl;
4173 #endif
4174 #ifdef FEAT_FOLDING
4175     int			save_KeyTyped;
4176 #endif
4177 
4178     // Can't do this recursively.  Can't do it when typing a password.
4179     if (cmdwin_type != 0
4180 # if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
4181 	    || cmdline_star > 0
4182 # endif
4183 	    )
4184     {
4185 	beep_flush();
4186 	return K_IGNORE;
4187     }
4188     set_bufref(&old_curbuf, curbuf);
4189 
4190     // Save current window sizes.
4191     win_size_save(&winsizes);
4192 
4193     // When using completion in Insert mode with <C-R>=<C-F> one can open the
4194     // command line window, but we don't want the popup menu then.
4195     pum_undisplay();
4196 
4197     // don't use a new tab page
4198     cmdmod.tab = 0;
4199     cmdmod.noswapfile = 1;
4200 
4201     // Create a window for the command-line buffer.
4202     if (win_split((int)p_cwh, WSP_BOT) == FAIL)
4203     {
4204 	beep_flush();
4205 	ga_clear(&winsizes);
4206 	return K_IGNORE;
4207     }
4208     cmdwin_type = get_cmdline_type();
4209 
4210     // Create the command-line buffer empty.
4211     (void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
4212     apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf);
4213     (void)setfname(curbuf, (char_u *)"[Command Line]", NULL, TRUE);
4214     apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf);
4215     set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
4216     curbuf->b_p_ma = TRUE;
4217 #ifdef FEAT_FOLDING
4218     curwin->w_p_fen = FALSE;
4219 #endif
4220 # ifdef FEAT_RIGHTLEFT
4221     curwin->w_p_rl = cmdmsg_rl;
4222     cmdmsg_rl = FALSE;
4223 # endif
4224     RESET_BINDING(curwin);
4225 
4226     // Don't allow switching to another buffer.
4227     ++curbuf_lock;
4228 
4229     // Showing the prompt may have set need_wait_return, reset it.
4230     need_wait_return = FALSE;
4231 
4232     histtype = hist_char2type(cmdwin_type);
4233     if (histtype == HIST_CMD || histtype == HIST_DEBUG)
4234     {
4235 	if (p_wc == TAB)
4236 	{
4237 	    add_map((char_u *)"<buffer> <Tab> <C-X><C-V>", INSERT);
4238 	    add_map((char_u *)"<buffer> <Tab> a<C-X><C-V>", NORMAL);
4239 	}
4240 	set_option_value((char_u *)"ft", 0L, (char_u *)"vim", OPT_LOCAL);
4241     }
4242     --curbuf_lock;
4243 
4244     // Reset 'textwidth' after setting 'filetype' (the Vim filetype plugin
4245     // sets 'textwidth' to 78).
4246     curbuf->b_p_tw = 0;
4247 
4248     // Fill the buffer with the history.
4249     init_history();
4250     if (get_hislen() > 0)
4251     {
4252 	i = *get_hisidx(histtype);
4253 	if (i >= 0)
4254 	{
4255 	    lnum = 0;
4256 	    do
4257 	    {
4258 		if (++i == get_hislen())
4259 		    i = 0;
4260 		if (get_histentry(histtype)[i].hisstr != NULL)
4261 		    ml_append(lnum++, get_histentry(histtype)[i].hisstr,
4262 							   (colnr_T)0, FALSE);
4263 	    }
4264 	    while (i != *get_hisidx(histtype));
4265 	}
4266     }
4267 
4268     // Replace the empty last line with the current command-line and put the
4269     // cursor there.
4270     ml_replace(curbuf->b_ml.ml_line_count, ccline.cmdbuff, TRUE);
4271     curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
4272     curwin->w_cursor.col = ccline.cmdpos;
4273     changed_line_abv_curs();
4274     invalidate_botline();
4275     redraw_later(SOME_VALID);
4276 
4277     // No Ex mode here!
4278     exmode_active = 0;
4279 
4280     State = NORMAL;
4281     setmouse();
4282 
4283     // Reset here so it can be set by a CmdWinEnter autocommand.
4284     cmdwin_result = 0;
4285 
4286     // Trigger CmdwinEnter autocommands.
4287     trigger_cmd_autocmd(cmdwin_type, EVENT_CMDWINENTER);
4288     if (restart_edit != 0)	// autocmd with ":startinsert"
4289 	stuffcharReadbuff(K_NOP);
4290 
4291     i = RedrawingDisabled;
4292     RedrawingDisabled = 0;
4293 
4294     /*
4295      * Call the main loop until <CR> or CTRL-C is typed.
4296      */
4297     main_loop(TRUE, FALSE);
4298 
4299     RedrawingDisabled = i;
4300 
4301 # ifdef FEAT_FOLDING
4302     save_KeyTyped = KeyTyped;
4303 # endif
4304 
4305     // Trigger CmdwinLeave autocommands.
4306     trigger_cmd_autocmd(cmdwin_type, EVENT_CMDWINLEAVE);
4307 
4308 # ifdef FEAT_FOLDING
4309     // Restore KeyTyped in case it is modified by autocommands
4310     KeyTyped = save_KeyTyped;
4311 # endif
4312 
4313     cmdwin_type = 0;
4314     exmode_active = save_exmode;
4315 
4316     // Safety check: The old window or buffer was deleted: It's a bug when
4317     // this happens!
4318     if (!win_valid(old_curwin) || !bufref_valid(&old_curbuf))
4319     {
4320 	cmdwin_result = Ctrl_C;
4321 	emsg(_("E199: Active window or buffer deleted"));
4322     }
4323     else
4324     {
4325 # if defined(FEAT_EVAL)
4326 	// autocmds may abort script processing
4327 	if (aborting() && cmdwin_result != K_IGNORE)
4328 	    cmdwin_result = Ctrl_C;
4329 # endif
4330 	// Set the new command line from the cmdline buffer.
4331 	vim_free(ccline.cmdbuff);
4332 	if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) // :qa[!] typed
4333 	{
4334 	    char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!";
4335 
4336 	    if (histtype == HIST_CMD)
4337 	    {
4338 		// Execute the command directly.
4339 		ccline.cmdbuff = vim_strsave((char_u *)p);
4340 		cmdwin_result = CAR;
4341 	    }
4342 	    else
4343 	    {
4344 		// First need to cancel what we were doing.
4345 		ccline.cmdbuff = NULL;
4346 		stuffcharReadbuff(':');
4347 		stuffReadbuff((char_u *)p);
4348 		stuffcharReadbuff(CAR);
4349 	    }
4350 	}
4351 	else if (cmdwin_result == K_XF2)	// :qa typed
4352 	{
4353 	    ccline.cmdbuff = vim_strsave((char_u *)"qa");
4354 	    cmdwin_result = CAR;
4355 	}
4356 	else if (cmdwin_result == Ctrl_C)
4357 	{
4358 	    // :q or :close, don't execute any command
4359 	    // and don't modify the cmd window.
4360 	    ccline.cmdbuff = NULL;
4361 	}
4362 	else
4363 	    ccline.cmdbuff = vim_strsave(ml_get_curline());
4364 	if (ccline.cmdbuff == NULL)
4365 	{
4366 	    ccline.cmdbuff = vim_strsave((char_u *)"");
4367 	    ccline.cmdlen = 0;
4368 	    ccline.cmdbufflen = 1;
4369 	    ccline.cmdpos = 0;
4370 	    cmdwin_result = Ctrl_C;
4371 	}
4372 	else
4373 	{
4374 	    ccline.cmdlen = (int)STRLEN(ccline.cmdbuff);
4375 	    ccline.cmdbufflen = ccline.cmdlen + 1;
4376 	    ccline.cmdpos = curwin->w_cursor.col;
4377 	    if (ccline.cmdpos > ccline.cmdlen)
4378 		ccline.cmdpos = ccline.cmdlen;
4379 	    if (cmdwin_result == K_IGNORE)
4380 	    {
4381 		set_cmdspos_cursor();
4382 		redrawcmd();
4383 	    }
4384 	}
4385 
4386 # ifdef FEAT_CONCEAL
4387 	// Avoid command-line window first character being concealed.
4388 	curwin->w_p_cole = 0;
4389 # endif
4390 	wp = curwin;
4391 	set_bufref(&bufref, curbuf);
4392 	win_goto(old_curwin);
4393 	win_close(wp, TRUE);
4394 
4395 	// win_close() may have already wiped the buffer when 'bh' is
4396 	// set to 'wipe'
4397 	if (bufref_valid(&bufref))
4398 	    close_buffer(NULL, bufref.br_buf, DOBUF_WIPE, FALSE, FALSE);
4399 
4400 	// Restore window sizes.
4401 	win_size_restore(&winsizes);
4402     }
4403 
4404     ga_clear(&winsizes);
4405     restart_edit = save_restart_edit;
4406 # ifdef FEAT_RIGHTLEFT
4407     cmdmsg_rl = save_cmdmsg_rl;
4408 # endif
4409 
4410     State = save_State;
4411     setmouse();
4412 
4413     return cmdwin_result;
4414 }
4415 #endif // FEAT_CMDWIN
4416 
4417 /*
4418  * Used for commands that either take a simple command string argument, or:
4419  *	cmd << endmarker
4420  *	  {script}
4421  *	endmarker
4422  * Returns a pointer to allocated memory with {script} or NULL.
4423  */
4424     char_u *
4425 script_get(exarg_T *eap UNUSED, char_u *cmd UNUSED)
4426 {
4427 #ifdef FEAT_EVAL
4428     list_T	*l;
4429     listitem_T	*li;
4430     char_u	*s;
4431     garray_T	ga;
4432 
4433     if (cmd[0] != '<' || cmd[1] != '<' || eap->getline == NULL)
4434 	return NULL;
4435     cmd += 2;
4436 
4437     l = heredoc_get(eap, cmd, TRUE);
4438     if (l == NULL)
4439 	return NULL;
4440 
4441     ga_init2(&ga, 1, 0x400);
4442 
4443     FOR_ALL_LIST_ITEMS(l, li)
4444     {
4445 	s = tv_get_string(&li->li_tv);
4446 	ga_concat(&ga, s);
4447 	ga_append(&ga, '\n');
4448     }
4449     ga_append(&ga, NUL);
4450 
4451     list_free(l);
4452     return (char_u *)ga.ga_data;
4453 #else
4454     return NULL;
4455 #endif
4456 }
4457 
4458 #if defined(FEAT_EVAL) || defined(PROTO)
4459 /*
4460  * This function is used by f_input() and f_inputdialog() functions. The third
4461  * argument to f_input() specifies the type of completion to use at the
4462  * prompt. The third argument to f_inputdialog() specifies the value to return
4463  * when the user cancels the prompt.
4464  */
4465     void
4466 get_user_input(
4467     typval_T	*argvars,
4468     typval_T	*rettv,
4469     int		inputdialog,
4470     int		secret)
4471 {
4472     char_u	*prompt = tv_get_string_chk(&argvars[0]);
4473     char_u	*p = NULL;
4474     int		c;
4475     char_u	buf[NUMBUFLEN];
4476     int		cmd_silent_save = cmd_silent;
4477     char_u	*defstr = (char_u *)"";
4478     int		xp_type = EXPAND_NOTHING;
4479     char_u	*xp_arg = NULL;
4480 
4481     rettv->v_type = VAR_STRING;
4482     rettv->vval.v_string = NULL;
4483     if (input_busy)
4484 	return;  // this doesn't work recursively.
4485 
4486 #ifdef NO_CONSOLE_INPUT
4487     // While starting up, there is no place to enter text. When running tests
4488     // with --not-a-term we assume feedkeys() will be used.
4489     if (no_console_input() && !is_not_a_term())
4490 	return;
4491 #endif
4492 
4493     cmd_silent = FALSE;		// Want to see the prompt.
4494     if (prompt != NULL)
4495     {
4496 	// Only the part of the message after the last NL is considered as
4497 	// prompt for the command line
4498 	p = vim_strrchr(prompt, '\n');
4499 	if (p == NULL)
4500 	    p = prompt;
4501 	else
4502 	{
4503 	    ++p;
4504 	    c = *p;
4505 	    *p = NUL;
4506 	    msg_start();
4507 	    msg_clr_eos();
4508 	    msg_puts_attr((char *)prompt, get_echo_attr());
4509 	    msg_didout = FALSE;
4510 	    msg_starthere();
4511 	    *p = c;
4512 	}
4513 	cmdline_row = msg_row;
4514 
4515 	if (argvars[1].v_type != VAR_UNKNOWN)
4516 	{
4517 	    defstr = tv_get_string_buf_chk(&argvars[1], buf);
4518 	    if (defstr != NULL)
4519 		stuffReadbuffSpec(defstr);
4520 
4521 	    if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN)
4522 	    {
4523 		char_u	*xp_name;
4524 		int	xp_namelen;
4525 		long	argt;
4526 
4527 		// input() with a third argument: completion
4528 		rettv->vval.v_string = NULL;
4529 
4530 		xp_name = tv_get_string_buf_chk(&argvars[2], buf);
4531 		if (xp_name == NULL)
4532 		    return;
4533 
4534 		xp_namelen = (int)STRLEN(xp_name);
4535 
4536 		if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt,
4537 							     &xp_arg) == FAIL)
4538 		    return;
4539 	    }
4540 	}
4541 
4542 	if (defstr != NULL)
4543 	{
4544 	    int save_ex_normal_busy = ex_normal_busy;
4545 	    int save_vgetc_busy = vgetc_busy;
4546 	    int save_input_busy = input_busy;
4547 
4548 	    input_busy |= vgetc_busy;
4549 	    ex_normal_busy = 0;
4550 	    vgetc_busy = 0;
4551 	    rettv->vval.v_string =
4552 		getcmdline_prompt(secret ? NUL : '@', p, get_echo_attr(),
4553 							      xp_type, xp_arg);
4554 	    ex_normal_busy = save_ex_normal_busy;
4555 	    vgetc_busy = save_vgetc_busy;
4556 	    input_busy = save_input_busy;
4557 	}
4558 	if (inputdialog && rettv->vval.v_string == NULL
4559 		&& argvars[1].v_type != VAR_UNKNOWN
4560 		&& argvars[2].v_type != VAR_UNKNOWN)
4561 	    rettv->vval.v_string = vim_strsave(tv_get_string_buf(
4562 							   &argvars[2], buf));
4563 
4564 	vim_free(xp_arg);
4565 
4566 	// since the user typed this, no need to wait for return
4567 	need_wait_return = FALSE;
4568 	msg_didout = FALSE;
4569     }
4570     cmd_silent = cmd_silent_save;
4571 }
4572 #endif
4573