xref: /vim-8.2.3635/src/edit.c (revision eeed665b)
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  * edit.c: functions for Insert mode
12  */
13 
14 #include "vim.h"
15 
16 #ifdef FEAT_INS_EXPAND
17 /*
18  * definitions used for CTRL-X submode
19  */
20 # define CTRL_X_WANT_IDENT	0x100
21 
22 # define CTRL_X_NORMAL		0  /* CTRL-N CTRL-P completion, default */
23 # define CTRL_X_NOT_DEFINED_YET	1
24 # define CTRL_X_SCROLL		2
25 # define CTRL_X_WHOLE_LINE	3
26 # define CTRL_X_FILES		4
27 # define CTRL_X_TAGS		(5 + CTRL_X_WANT_IDENT)
28 # define CTRL_X_PATH_PATTERNS	(6 + CTRL_X_WANT_IDENT)
29 # define CTRL_X_PATH_DEFINES	(7 + CTRL_X_WANT_IDENT)
30 # define CTRL_X_FINISHED		8
31 # define CTRL_X_DICTIONARY	(9 + CTRL_X_WANT_IDENT)
32 # define CTRL_X_THESAURUS	(10 + CTRL_X_WANT_IDENT)
33 # define CTRL_X_CMDLINE		11
34 # define CTRL_X_FUNCTION		12
35 # define CTRL_X_OMNI		13
36 # define CTRL_X_SPELL		14
37 # define CTRL_X_LOCAL_MSG	15	/* only used in "ctrl_x_msgs" */
38 # define CTRL_X_EVAL		16	/* for builtin function complete() */
39 
40 # define CTRL_X_MSG(i) ctrl_x_msgs[(i) & ~CTRL_X_WANT_IDENT]
41 # define CTRL_X_MODE_LINE_OR_EVAL(m) ((m) == CTRL_X_WHOLE_LINE || (m) == CTRL_X_EVAL)
42 
43 /* Message for CTRL-X mode, index is ctrl_x_mode. */
44 static char *ctrl_x_msgs[] =
45 {
46     N_(" Keyword completion (^N^P)"), /* CTRL_X_NORMAL, ^P/^N compl. */
47     N_(" ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"),
48     NULL, /* CTRL_X_SCROLL: depends on state */
49     N_(" Whole line completion (^L^N^P)"),
50     N_(" File name completion (^F^N^P)"),
51     N_(" Tag completion (^]^N^P)"),
52     N_(" Path pattern completion (^N^P)"),
53     N_(" Definition completion (^D^N^P)"),
54     NULL, /* CTRL_X_FINISHED */
55     N_(" Dictionary completion (^K^N^P)"),
56     N_(" Thesaurus completion (^T^N^P)"),
57     N_(" Command-line completion (^V^N^P)"),
58     N_(" User defined completion (^U^N^P)"),
59     N_(" Omni completion (^O^N^P)"),
60     N_(" Spelling suggestion (s^N^P)"),
61     N_(" Keyword Local completion (^N^P)"),
62     NULL,   /* CTRL_X_EVAL doesn't use msg. */
63 };
64 
65 static char e_hitend[] = N_("Hit end of paragraph");
66 # ifdef FEAT_COMPL_FUNC
67 static char e_complwin[] = N_("E839: Completion function changed window");
68 static char e_compldel[] = N_("E840: Completion function deleted text");
69 # endif
70 
71 /*
72  * Structure used to store one match for insert completion.
73  */
74 typedef struct compl_S compl_T;
75 struct compl_S
76 {
77     compl_T	*cp_next;
78     compl_T	*cp_prev;
79     char_u	*cp_str;	/* matched text */
80     char	cp_icase;	/* TRUE or FALSE: ignore case */
81     char_u	*(cp_text[CPT_COUNT]);	/* text for the menu */
82     char_u	*cp_fname;	/* file containing the match, allocated when
83 				 * cp_flags has FREE_FNAME */
84     int		cp_flags;	/* ORIGINAL_TEXT, CONT_S_IPOS or FREE_FNAME */
85     int		cp_number;	/* sequence number */
86 };
87 
88 # define ORIGINAL_TEXT	(1)   /* the original text when the expansion begun */
89 # define FREE_FNAME	(2)
90 
91 /*
92  * All the current matches are stored in a list.
93  * "compl_first_match" points to the start of the list.
94  * "compl_curr_match" points to the currently selected entry.
95  * "compl_shown_match" is different from compl_curr_match during
96  * ins_compl_get_exp().
97  */
98 static compl_T    *compl_first_match = NULL;
99 static compl_T    *compl_curr_match = NULL;
100 static compl_T    *compl_shown_match = NULL;
101 static compl_T    *compl_old_match = NULL;
102 
103 /* After using a cursor key <Enter> selects a match in the popup menu,
104  * otherwise it inserts a line break. */
105 static int	  compl_enter_selects = FALSE;
106 
107 /* When "compl_leader" is not NULL only matches that start with this string
108  * are used. */
109 static char_u	  *compl_leader = NULL;
110 
111 static int	  compl_get_longest = FALSE;	/* put longest common string
112 						   in compl_leader */
113 
114 static int	  compl_no_insert = FALSE;	/* FALSE: select & insert
115 						   TRUE: noinsert */
116 static int	  compl_no_select = FALSE;	/* FALSE: select & insert
117 						   TRUE: noselect */
118 
119 static int	  compl_used_match;	/* Selected one of the matches.  When
120 					   FALSE the match was edited or using
121 					   the longest common string. */
122 
123 static int	  compl_was_interrupted = FALSE;  /* didn't finish finding
124 						     completions. */
125 
126 static int	  compl_restarting = FALSE;	/* don't insert match */
127 
128 /* When the first completion is done "compl_started" is set.  When it's
129  * FALSE the word to be completed must be located. */
130 static int	  compl_started = FALSE;
131 
132 /* Which Ctrl-X mode are we in? */
133 static int	  ctrl_x_mode = CTRL_X_NORMAL;
134 
135 /* Set when doing something for completion that may call edit() recursively,
136  * which is not allowed. */
137 static int	  compl_busy = FALSE;
138 
139 static int	  compl_matches = 0;
140 static char_u	  *compl_pattern = NULL;
141 static int	  compl_direction = FORWARD;
142 static int	  compl_shows_dir = FORWARD;
143 static int	  compl_pending = 0;	    /* > 1 for postponed CTRL-N */
144 static pos_T	  compl_startpos;
145 static colnr_T	  compl_col = 0;	    /* column where the text starts
146 					     * that is being completed */
147 static char_u	  *compl_orig_text = NULL;  /* text as it was before
148 					     * completion started */
149 static int	  compl_cont_mode = 0;
150 static expand_T	  compl_xp;
151 
152 static int	  compl_opt_refresh_always = FALSE;
153 
154 static void ins_ctrl_x(void);
155 static int  has_compl_option(int dict_opt);
156 static int  ins_compl_accept_char(int c);
157 static int ins_compl_add(char_u *str, int len, int icase, char_u *fname, char_u **cptext, int cdir, int flags, int adup);
158 static void ins_compl_longest_match(compl_T *match);
159 static void ins_compl_del_pum(void);
160 static int  pum_wanted(void);
161 static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, regmatch_T *regmatch, char_u *buf, int *dir);
162 static char_u *find_line_end(char_u *ptr);
163 static void ins_compl_free(void);
164 static void ins_compl_clear(void);
165 static int  ins_compl_bs(void);
166 static int  ins_compl_need_restart(void);
167 static void ins_compl_new_leader(void);
168 static void ins_compl_addleader(int c);
169 static int  ins_compl_len(void);
170 static void ins_compl_restart(void);
171 static void ins_compl_set_original_text(char_u *str);
172 static void ins_compl_addfrommatch(void);
173 static int  ins_compl_prep(int c);
174 static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg);
175 # if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL)
176 static void ins_compl_add_list(list_T *list);
177 static void ins_compl_add_dict(dict_T *dict);
178 # endif
179 static void ins_compl_delete(void);
180 static void ins_compl_insert(int in_compl_func);
181 static int  ins_compl_key2dir(int c);
182 static int  ins_compl_pum_key(int c);
183 static int  ins_compl_key2count(int c);
184 static int  ins_complete(int c, int enable_pum);
185 static void show_pum(int prev_w_wrow, int prev_w_leftcol);
186 static unsigned  quote_meta(char_u *dest, char_u *str, int len);
187 #endif /* FEAT_INS_EXPAND */
188 
189 #define BACKSPACE_CHAR		    1
190 #define BACKSPACE_WORD		    2
191 #define BACKSPACE_WORD_NOT_SPACE    3
192 #define BACKSPACE_LINE		    4
193 
194 static void ins_redraw(int ready);
195 static void ins_ctrl_v(void);
196 #ifdef FEAT_JOB_CHANNEL
197 static void init_prompt(int cmdchar_todo);
198 #endif
199 static void undisplay_dollar(void);
200 static void insert_special(int, int, int);
201 static void internal_format(int textwidth, int second_indent, int flags, int format_only, int c);
202 static void check_auto_format(int);
203 static void redo_literal(int c);
204 static void start_arrow(pos_T *end_insert_pos);
205 static void start_arrow_common(pos_T *end_insert_pos, int change);
206 #ifdef FEAT_SPELL
207 static void check_spell_redraw(void);
208 static void spell_back_to_badword(void);
209 static int  spell_bad_len = 0;	/* length of located bad word */
210 #endif
211 static void stop_insert(pos_T *end_insert_pos, int esc, int nomove);
212 static int  echeck_abbr(int);
213 static void replace_join(int off);
214 #ifdef FEAT_MBYTE
215 static void mb_replace_pop_ins(int cc);
216 #endif
217 static void replace_flush(void);
218 static void replace_do_bs(int limit_col);
219 static int del_char_after_col(int limit_col);
220 #ifdef FEAT_CINDENT
221 static int cindent_on(void);
222 #endif
223 static void ins_reg(void);
224 static void ins_ctrl_g(void);
225 static void ins_ctrl_hat(void);
226 static int  ins_esc(long *count, int cmdchar, int nomove);
227 #ifdef FEAT_RIGHTLEFT
228 static void ins_ctrl_(void);
229 #endif
230 static int ins_start_select(int c);
231 static void ins_insert(int replaceState);
232 static void ins_ctrl_o(void);
233 static void ins_shift(int c, int lastc);
234 static void ins_del(void);
235 static int  ins_bs(int c, int mode, int *inserted_space_p);
236 #ifdef FEAT_MOUSE
237 static void ins_mouse(int c);
238 static void ins_mousescroll(int dir);
239 #endif
240 #if defined(FEAT_GUI_TABLINE) || defined(PROTO)
241 static void ins_tabline(int c);
242 #endif
243 static void ins_left(int end_change);
244 static void ins_home(int c);
245 static void ins_end(int c);
246 static void ins_s_left(void);
247 static void ins_right(int end_change);
248 static void ins_s_right(void);
249 static void ins_up(int startcol);
250 static void ins_pageup(void);
251 static void ins_down(int startcol);
252 static void ins_pagedown(void);
253 #ifdef FEAT_DND
254 static void ins_drop(void);
255 #endif
256 static int  ins_tab(void);
257 static int  ins_eol(int c);
258 #ifdef FEAT_DIGRAPHS
259 static int  ins_digraph(void);
260 #endif
261 static int  ins_ctrl_ey(int tc);
262 #ifdef FEAT_SMARTINDENT
263 static void ins_try_si(int c);
264 #endif
265 #if defined(FEAT_EVAL)
266 static char_u *do_insert_char_pre(int c);
267 #endif
268 static int ins_apply_autocmds(event_T event);
269 
270 static colnr_T	Insstart_textlen;	/* length of line when insert started */
271 static colnr_T	Insstart_blank_vcol;	/* vcol for first inserted blank */
272 static int	update_Insstart_orig = TRUE; /* set Insstart_orig to Insstart */
273 
274 static char_u	*last_insert = NULL;	/* the text of the previous insert,
275 					   K_SPECIAL and CSI are escaped */
276 static int	last_insert_skip; /* nr of chars in front of previous insert */
277 static int	new_insert_skip;  /* nr of chars in front of current insert */
278 static int	did_restart_edit;	/* "restart_edit" when calling edit() */
279 
280 #ifdef FEAT_CINDENT
281 static int	can_cindent;		/* may do cindenting on this line */
282 #endif
283 
284 static int	old_indent = 0;		/* for ^^D command in insert mode */
285 
286 #ifdef FEAT_RIGHTLEFT
287 static int	revins_on;		/* reverse insert mode on */
288 static int	revins_chars;		/* how much to skip after edit */
289 static int	revins_legal;		/* was the last char 'legal'? */
290 static int	revins_scol;		/* start column of revins session */
291 #endif
292 
293 static int	ins_need_undo;		/* call u_save() before inserting a
294 					   char.  Set when edit() is called.
295 					   after that arrow_used is used. */
296 
297 static int	did_add_space = FALSE;	/* auto_format() added an extra space
298 					   under the cursor */
299 static int	dont_sync_undo = FALSE;	/* CTRL-G U prevents syncing undo for
300 					   the next left/right cursor */
301 
302 /*
303  * edit(): Start inserting text.
304  *
305  * "cmdchar" can be:
306  * 'i'	normal insert command
307  * 'a'	normal append command
308  * K_PS bracketed paste
309  * 'R'	replace command
310  * 'r'	"r<CR>" command: insert one <CR>.  Note: count can be > 1, for redo,
311  *	but still only one <CR> is inserted.  The <Esc> is not used for redo.
312  * 'g'	"gI" command.
313  * 'V'	"gR" command for Virtual Replace mode.
314  * 'v'	"gr" command for single character Virtual Replace mode.
315  *
316  * This function is not called recursively.  For CTRL-O commands, it returns
317  * and lets the caller handle the Normal-mode command.
318  *
319  * Return TRUE if a CTRL-O command caused the return (insert mode pending).
320  */
321     int
322 edit(
323     int		cmdchar,
324     int		startln,	/* if set, insert at start of line */
325     long	count)
326 {
327     int		c = 0;
328     char_u	*ptr;
329     int		lastc = 0;
330     int		mincol;
331     static linenr_T o_lnum = 0;
332     int		i;
333     int		did_backspace = TRUE;	    /* previous char was backspace */
334 #ifdef FEAT_CINDENT
335     int		line_is_white = FALSE;	    /* line is empty before insert */
336 #endif
337     linenr_T	old_topline = 0;	    /* topline before insertion */
338 #ifdef FEAT_DIFF
339     int		old_topfill = -1;
340 #endif
341     int		inserted_space = FALSE;     /* just inserted a space */
342     int		replaceState = REPLACE;
343     int		nomove = FALSE;		    /* don't move cursor on return */
344 #ifdef FEAT_JOB_CHANNEL
345     int		cmdchar_todo = cmdchar;
346 #endif
347 
348     /* Remember whether editing was restarted after CTRL-O. */
349     did_restart_edit = restart_edit;
350 
351     /* sleep before redrawing, needed for "CTRL-O :" that results in an
352      * error message */
353     check_for_delay(TRUE);
354 
355     /* set Insstart_orig to Insstart */
356     update_Insstart_orig = TRUE;
357 
358 #ifdef HAVE_SANDBOX
359     /* Don't allow inserting in the sandbox. */
360     if (sandbox != 0)
361     {
362 	EMSG(_(e_sandbox));
363 	return FALSE;
364     }
365 #endif
366     /* Don't allow changes in the buffer while editing the cmdline.  The
367      * caller of getcmdline() may get confused. */
368     if (textlock != 0)
369     {
370 	EMSG(_(e_secure));
371 	return FALSE;
372     }
373 
374 #ifdef FEAT_INS_EXPAND
375     /* Don't allow recursive insert mode when busy with completion. */
376     if (compl_started || compl_busy || pum_visible())
377     {
378 	EMSG(_(e_secure));
379 	return FALSE;
380     }
381     ins_compl_clear();	    /* clear stuff for CTRL-X mode */
382 #endif
383 
384     /*
385      * Trigger InsertEnter autocommands.  Do not do this for "r<CR>" or "grx".
386      */
387     if (cmdchar != 'r' && cmdchar != 'v')
388     {
389 	pos_T   save_cursor = curwin->w_cursor;
390 
391 #ifdef FEAT_EVAL
392 	if (cmdchar == 'R')
393 	    ptr = (char_u *)"r";
394 	else if (cmdchar == 'V')
395 	    ptr = (char_u *)"v";
396 	else
397 	    ptr = (char_u *)"i";
398 	set_vim_var_string(VV_INSERTMODE, ptr, 1);
399 	set_vim_var_string(VV_CHAR, NULL, -1);  /* clear v:char */
400 #endif
401 	ins_apply_autocmds(EVENT_INSERTENTER);
402 
403 	/* Make sure the cursor didn't move.  Do call check_cursor_col() in
404 	 * case the text was modified.  Since Insert mode was not started yet
405 	 * a call to check_cursor_col() may move the cursor, especially with
406 	 * the "A" command, thus set State to avoid that. Also check that the
407 	 * line number is still valid (lines may have been deleted).
408 	 * Do not restore if v:char was set to a non-empty string. */
409 	if (!EQUAL_POS(curwin->w_cursor, save_cursor)
410 #ifdef FEAT_EVAL
411 		&& *get_vim_var_str(VV_CHAR) == NUL
412 #endif
413 		&& save_cursor.lnum <= curbuf->b_ml.ml_line_count)
414 	{
415 	    int save_state = State;
416 
417 	    curwin->w_cursor = save_cursor;
418 	    State = INSERT;
419 	    check_cursor_col();
420 	    State = save_state;
421 	}
422     }
423 
424 #ifdef FEAT_CONCEAL
425     /* Check if the cursor line needs redrawing before changing State.  If
426      * 'concealcursor' is "n" it needs to be redrawn without concealing. */
427     conceal_check_cursor_line();
428 #endif
429 
430 #ifdef FEAT_MOUSE
431     /*
432      * When doing a paste with the middle mouse button, Insstart is set to
433      * where the paste started.
434      */
435     if (where_paste_started.lnum != 0)
436 	Insstart = where_paste_started;
437     else
438 #endif
439     {
440 	Insstart = curwin->w_cursor;
441 	if (startln)
442 	    Insstart.col = 0;
443     }
444     Insstart_textlen = (colnr_T)linetabsize(ml_get_curline());
445     Insstart_blank_vcol = MAXCOL;
446     if (!did_ai)
447 	ai_col = 0;
448 
449     if (cmdchar != NUL && restart_edit == 0)
450     {
451 	ResetRedobuff();
452 	AppendNumberToRedobuff(count);
453 	if (cmdchar == 'V' || cmdchar == 'v')
454 	{
455 	    /* "gR" or "gr" command */
456 	    AppendCharToRedobuff('g');
457 	    AppendCharToRedobuff((cmdchar == 'v') ? 'r' : 'R');
458 	}
459 	else
460 	{
461 	    if (cmdchar == K_PS)
462 		AppendCharToRedobuff('a');
463 	    else
464 		AppendCharToRedobuff(cmdchar);
465 	    if (cmdchar == 'g')		    /* "gI" command */
466 		AppendCharToRedobuff('I');
467 	    else if (cmdchar == 'r')	    /* "r<CR>" command */
468 		count = 1;		    /* insert only one <CR> */
469 	}
470     }
471 
472     if (cmdchar == 'R')
473     {
474 #ifdef FEAT_FKMAP
475 	if (p_fkmap && p_ri)
476 	{
477 	    beep_flush();
478 	    EMSG(farsi_text_3);	    /* encoded in Farsi */
479 	    State = INSERT;
480 	}
481 	else
482 #endif
483 	State = REPLACE;
484     }
485     else if (cmdchar == 'V' || cmdchar == 'v')
486     {
487 	State = VREPLACE;
488 	replaceState = VREPLACE;
489 	orig_line_count = curbuf->b_ml.ml_line_count;
490 	vr_lines_changed = 1;
491     }
492     else
493 	State = INSERT;
494 
495     stop_insert_mode = FALSE;
496 
497     /*
498      * Need to recompute the cursor position, it might move when the cursor is
499      * on a TAB or special character.
500      */
501     curs_columns(TRUE);
502 
503     /*
504      * Enable langmap or IME, indicated by 'iminsert'.
505      * Note that IME may enabled/disabled without us noticing here, thus the
506      * 'iminsert' value may not reflect what is actually used.  It is updated
507      * when hitting <Esc>.
508      */
509     if (curbuf->b_p_iminsert == B_IMODE_LMAP)
510 	State |= LANGMAP;
511 #ifdef HAVE_INPUT_METHOD
512     im_set_active(curbuf->b_p_iminsert == B_IMODE_IM);
513 #endif
514 
515 #ifdef FEAT_MOUSE
516     setmouse();
517 #endif
518 #ifdef FEAT_CMDL_INFO
519     clear_showcmd();
520 #endif
521 #ifdef FEAT_RIGHTLEFT
522     /* there is no reverse replace mode */
523     revins_on = (State == INSERT && p_ri);
524     if (revins_on)
525 	undisplay_dollar();
526     revins_chars = 0;
527     revins_legal = 0;
528     revins_scol = -1;
529 #endif
530     if (!p_ek)
531 	/* Disable bracketed paste mode, we won't recognize the escape
532 	 * sequences. */
533 	out_str(T_BD);
534 
535     /*
536      * Handle restarting Insert mode.
537      * Don't do this for "CTRL-O ." (repeat an insert): In that case we get
538      * here with something in the stuff buffer.
539      */
540     if (restart_edit != 0 && stuff_empty())
541     {
542 #ifdef FEAT_MOUSE
543 	/*
544 	 * After a paste we consider text typed to be part of the insert for
545 	 * the pasted text. You can backspace over the pasted text too.
546 	 */
547 	if (where_paste_started.lnum)
548 	    arrow_used = FALSE;
549 	else
550 #endif
551 	    arrow_used = TRUE;
552 	restart_edit = 0;
553 
554 	/*
555 	 * If the cursor was after the end-of-line before the CTRL-O and it is
556 	 * now at the end-of-line, put it after the end-of-line (this is not
557 	 * correct in very rare cases).
558 	 * Also do this if curswant is greater than the current virtual
559 	 * column.  Eg after "^O$" or "^O80|".
560 	 */
561 	validate_virtcol();
562 	update_curswant();
563 	if (((ins_at_eol && curwin->w_cursor.lnum == o_lnum)
564 		    || curwin->w_curswant > curwin->w_virtcol)
565 		&& *(ptr = ml_get_curline() + curwin->w_cursor.col) != NUL)
566 	{
567 	    if (ptr[1] == NUL)
568 		++curwin->w_cursor.col;
569 #ifdef FEAT_MBYTE
570 	    else if (has_mbyte)
571 	    {
572 		i = (*mb_ptr2len)(ptr);
573 		if (ptr[i] == NUL)
574 		    curwin->w_cursor.col += i;
575 	    }
576 #endif
577 	}
578 	ins_at_eol = FALSE;
579     }
580     else
581 	arrow_used = FALSE;
582 
583     /* we are in insert mode now, don't need to start it anymore */
584     need_start_insertmode = FALSE;
585 
586     /* Need to save the line for undo before inserting the first char. */
587     ins_need_undo = TRUE;
588 
589 #ifdef FEAT_MOUSE
590     where_paste_started.lnum = 0;
591 #endif
592 #ifdef FEAT_CINDENT
593     can_cindent = TRUE;
594 #endif
595 #ifdef FEAT_FOLDING
596     /* The cursor line is not in a closed fold, unless 'insertmode' is set or
597      * restarting. */
598     if (!p_im && did_restart_edit == 0)
599 	foldOpenCursor();
600 #endif
601 
602     /*
603      * If 'showmode' is set, show the current (insert/replace/..) mode.
604      * A warning message for changing a readonly file is given here, before
605      * actually changing anything.  It's put after the mode, if any.
606      */
607     i = 0;
608     if (p_smd && msg_silent == 0)
609 	i = showmode();
610 
611     if (!p_im && did_restart_edit == 0)
612 	change_warning(i == 0 ? 0 : i + 1);
613 
614 #ifdef CURSOR_SHAPE
615     ui_cursor_shape();		/* may show different cursor shape */
616 #endif
617 #ifdef FEAT_DIGRAPHS
618     do_digraph(-1);		/* clear digraphs */
619 #endif
620 
621     /*
622      * Get the current length of the redo buffer, those characters have to be
623      * skipped if we want to get to the inserted characters.
624      */
625     ptr = get_inserted();
626     if (ptr == NULL)
627 	new_insert_skip = 0;
628     else
629     {
630 	new_insert_skip = (int)STRLEN(ptr);
631 	vim_free(ptr);
632     }
633 
634     old_indent = 0;
635 
636     /*
637      * Main loop in Insert mode: repeat until Insert mode is left.
638      */
639     for (;;)
640     {
641 #ifdef FEAT_RIGHTLEFT
642 	if (!revins_legal)
643 	    revins_scol = -1;	    /* reset on illegal motions */
644 	else
645 	    revins_legal = 0;
646 #endif
647 	if (arrow_used)	    /* don't repeat insert when arrow key used */
648 	    count = 0;
649 
650 	if (update_Insstart_orig)
651 	    Insstart_orig = Insstart;
652 
653 	if (stop_insert_mode
654 #ifdef FEAT_INS_EXPAND
655 		&& !pum_visible()
656 #endif
657 		)
658 	{
659 	    /* ":stopinsert" used or 'insertmode' reset */
660 	    count = 0;
661 	    goto doESCkey;
662 	}
663 
664 	/* set curwin->w_curswant for next K_DOWN or K_UP */
665 	if (!arrow_used)
666 	    curwin->w_set_curswant = TRUE;
667 
668 	/* If there is no typeahead may check for timestamps (e.g., for when a
669 	 * menu invoked a shell command). */
670 	if (stuff_empty())
671 	{
672 	    did_check_timestamps = FALSE;
673 	    if (need_check_timestamps)
674 		check_timestamps(FALSE);
675 	}
676 
677 	/*
678 	 * When emsg() was called msg_scroll will have been set.
679 	 */
680 	msg_scroll = FALSE;
681 
682 #ifdef FEAT_GUI
683 	/* When 'mousefocus' is set a mouse movement may have taken us to
684 	 * another window.  "need_mouse_correct" may then be set because of an
685 	 * autocommand. */
686 	if (need_mouse_correct)
687 	    gui_mouse_correct();
688 #endif
689 
690 #ifdef FEAT_FOLDING
691 	/* Open fold at the cursor line, according to 'foldopen'. */
692 	if (fdo_flags & FDO_INSERT)
693 	    foldOpenCursor();
694 	/* Close folds where the cursor isn't, according to 'foldclose' */
695 	if (!char_avail())
696 	    foldCheckClose();
697 #endif
698 
699 #ifdef FEAT_JOB_CHANNEL
700 	if (bt_prompt(curbuf))
701 	{
702 	    init_prompt(cmdchar_todo);
703 	    cmdchar_todo = NUL;
704 	}
705 #endif
706 
707 	/*
708 	 * If we inserted a character at the last position of the last line in
709 	 * the window, scroll the window one line up. This avoids an extra
710 	 * redraw.
711 	 * This is detected when the cursor column is smaller after inserting
712 	 * something.
713 	 * Don't do this when the topline changed already, it has
714 	 * already been adjusted (by insertchar() calling open_line())).
715 	 */
716 	if (curbuf->b_mod_set
717 		&& curwin->w_p_wrap
718 		&& !did_backspace
719 		&& curwin->w_topline == old_topline
720 #ifdef FEAT_DIFF
721 		&& curwin->w_topfill == old_topfill
722 #endif
723 		)
724 	{
725 	    mincol = curwin->w_wcol;
726 	    validate_cursor_col();
727 
728 	    if (
729 #ifdef FEAT_VARTABS
730 		(int)curwin->w_wcol < mincol - tabstop_at(
731 					  get_nolist_virtcol(), curbuf->b_p_ts,
732 							 curbuf->b_p_vts_array)
733 #else
734 		(int)curwin->w_wcol < mincol - curbuf->b_p_ts
735 #endif
736 		    && curwin->w_wrow == W_WINROW(curwin)
737 						 + curwin->w_height - 1 - p_so
738 		    && (curwin->w_cursor.lnum != curwin->w_topline
739 #ifdef FEAT_DIFF
740 			|| curwin->w_topfill > 0
741 #endif
742 		    ))
743 	    {
744 #ifdef FEAT_DIFF
745 		if (curwin->w_topfill > 0)
746 		    --curwin->w_topfill;
747 		else
748 #endif
749 #ifdef FEAT_FOLDING
750 		if (hasFolding(curwin->w_topline, NULL, &old_topline))
751 		    set_topline(curwin, old_topline + 1);
752 		else
753 #endif
754 		    set_topline(curwin, curwin->w_topline + 1);
755 	    }
756 	}
757 
758 	/* May need to adjust w_topline to show the cursor. */
759 	update_topline();
760 
761 	did_backspace = FALSE;
762 
763 	validate_cursor();		/* may set must_redraw */
764 
765 	/*
766 	 * Redraw the display when no characters are waiting.
767 	 * Also shows mode, ruler and positions cursor.
768 	 */
769 	ins_redraw(TRUE);
770 
771 	if (curwin->w_p_scb)
772 	    do_check_scrollbind(TRUE);
773 
774 	if (curwin->w_p_crb)
775 	    do_check_cursorbind();
776 	update_curswant();
777 	old_topline = curwin->w_topline;
778 #ifdef FEAT_DIFF
779 	old_topfill = curwin->w_topfill;
780 #endif
781 
782 #ifdef USE_ON_FLY_SCROLL
783 	dont_scroll = FALSE;		/* allow scrolling here */
784 #endif
785 
786 	/*
787 	 * Get a character for Insert mode.  Ignore K_IGNORE and K_NOP.
788 	 */
789 	if (c != K_CURSORHOLD)
790 	    lastc = c;		/* remember the previous char for CTRL-D */
791 
792 	/* After using CTRL-G U the next cursor key will not break undo. */
793 	if (dont_sync_undo == MAYBE)
794 	    dont_sync_undo = TRUE;
795 	else
796 	    dont_sync_undo = FALSE;
797 	if (cmdchar == K_PS)
798 	    /* Got here from normal mode when bracketed paste started. */
799 	    c = K_PS;
800 	else
801 	    do
802 	    {
803 		c = safe_vgetc();
804 
805 		if (stop_insert_mode)
806 		{
807 		    // Insert mode ended, possibly from a callback.
808 		    count = 0;
809 		    nomove = TRUE;
810 		    goto doESCkey;
811 		}
812 	    } while (c == K_IGNORE || c == K_NOP);
813 
814 	/* Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V. */
815 	did_cursorhold = TRUE;
816 
817 #ifdef FEAT_RIGHTLEFT
818 	if (p_hkmap && KeyTyped)
819 	    c = hkmap(c);		/* Hebrew mode mapping */
820 #endif
821 #ifdef FEAT_FKMAP
822 	if (p_fkmap && KeyTyped)
823 	    c = fkmap(c);		/* Farsi mode mapping */
824 #endif
825 
826 #ifdef FEAT_INS_EXPAND
827 	/*
828 	 * Special handling of keys while the popup menu is visible or wanted
829 	 * and the cursor is still in the completed word.  Only when there is
830 	 * a match, skip this when no matches were found.
831 	 */
832 	if (compl_started
833 		&& pum_wanted()
834 		&& curwin->w_cursor.col >= compl_col
835 		&& (compl_shown_match == NULL
836 		    || compl_shown_match != compl_shown_match->cp_next))
837 	{
838 	    /* BS: Delete one character from "compl_leader". */
839 	    if ((c == K_BS || c == Ctrl_H)
840 			&& curwin->w_cursor.col > compl_col
841 			&& (c = ins_compl_bs()) == NUL)
842 		continue;
843 
844 	    /* When no match was selected or it was edited. */
845 	    if (!compl_used_match)
846 	    {
847 		/* CTRL-L: Add one character from the current match to
848 		 * "compl_leader".  Except when at the original match and
849 		 * there is nothing to add, CTRL-L works like CTRL-P then. */
850 		if (c == Ctrl_L
851 			&& (!CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)
852 			    || (int)STRLEN(compl_shown_match->cp_str)
853 					  > curwin->w_cursor.col - compl_col))
854 		{
855 		    ins_compl_addfrommatch();
856 		    continue;
857 		}
858 
859 		/* A non-white character that fits in with the current
860 		 * completion: Add to "compl_leader". */
861 		if (ins_compl_accept_char(c))
862 		{
863 #if defined(FEAT_EVAL)
864 		    /* Trigger InsertCharPre. */
865 		    char_u *str = do_insert_char_pre(c);
866 		    char_u *p;
867 
868 		    if (str != NULL)
869 		    {
870 			for (p = str; *p != NUL; MB_PTR_ADV(p))
871 			    ins_compl_addleader(PTR2CHAR(p));
872 			vim_free(str);
873 		    }
874 		    else
875 #endif
876 			ins_compl_addleader(c);
877 		    continue;
878 		}
879 
880 		/* Pressing CTRL-Y selects the current match.  When
881 		 * compl_enter_selects is set the Enter key does the same. */
882 		if ((c == Ctrl_Y || (compl_enter_selects
883 				    && (c == CAR || c == K_KENTER || c == NL)))
884 			&& stop_arrow() == OK)
885 		{
886 		    ins_compl_delete();
887 		    ins_compl_insert(FALSE);
888 		}
889 	    }
890 	}
891 
892 	/* Prepare for or stop CTRL-X mode.  This doesn't do completion, but
893 	 * it does fix up the text when finishing completion. */
894 	compl_get_longest = FALSE;
895 	if (ins_compl_prep(c))
896 	    continue;
897 #endif
898 
899 	/* CTRL-\ CTRL-N goes to Normal mode,
900 	 * CTRL-\ CTRL-G goes to mode selected with 'insertmode',
901 	 * CTRL-\ CTRL-O is like CTRL-O but without moving the cursor.  */
902 	if (c == Ctrl_BSL)
903 	{
904 	    /* may need to redraw when no more chars available now */
905 	    ins_redraw(FALSE);
906 	    ++no_mapping;
907 	    ++allow_keys;
908 	    c = plain_vgetc();
909 	    --no_mapping;
910 	    --allow_keys;
911 	    if (c != Ctrl_N && c != Ctrl_G && c != Ctrl_O)
912 	    {
913 		/* it's something else */
914 		vungetc(c);
915 		c = Ctrl_BSL;
916 	    }
917 	    else if (c == Ctrl_G && p_im)
918 		continue;
919 	    else
920 	    {
921 		if (c == Ctrl_O)
922 		{
923 		    ins_ctrl_o();
924 		    ins_at_eol = FALSE;	/* cursor keeps its column */
925 		    nomove = TRUE;
926 		}
927 		count = 0;
928 		goto doESCkey;
929 	    }
930 	}
931 
932 #ifdef FEAT_DIGRAPHS
933 	c = do_digraph(c);
934 #endif
935 
936 #ifdef FEAT_INS_EXPAND
937 	if ((c == Ctrl_V || c == Ctrl_Q) && ctrl_x_mode == CTRL_X_CMDLINE)
938 	    goto docomplete;
939 #endif
940 	if (c == Ctrl_V || c == Ctrl_Q)
941 	{
942 	    ins_ctrl_v();
943 	    c = Ctrl_V;	/* pretend CTRL-V is last typed character */
944 	    continue;
945 	}
946 
947 #ifdef FEAT_CINDENT
948 	if (cindent_on()
949 # ifdef FEAT_INS_EXPAND
950 		&& ctrl_x_mode == 0
951 # endif
952 	   )
953 	{
954 	    /* A key name preceded by a bang means this key is not to be
955 	     * inserted.  Skip ahead to the re-indenting below.
956 	     * A key name preceded by a star means that indenting has to be
957 	     * done before inserting the key. */
958 	    line_is_white = inindent(0);
959 	    if (in_cinkeys(c, '!', line_is_white))
960 		goto force_cindent;
961 	    if (can_cindent && in_cinkeys(c, '*', line_is_white)
962 							&& stop_arrow() == OK)
963 		do_c_expr_indent();
964 	}
965 #endif
966 
967 #ifdef FEAT_RIGHTLEFT
968 	if (curwin->w_p_rl)
969 	    switch (c)
970 	    {
971 		case K_LEFT:	c = K_RIGHT; break;
972 		case K_S_LEFT:	c = K_S_RIGHT; break;
973 		case K_C_LEFT:	c = K_C_RIGHT; break;
974 		case K_RIGHT:	c = K_LEFT; break;
975 		case K_S_RIGHT: c = K_S_LEFT; break;
976 		case K_C_RIGHT: c = K_C_LEFT; break;
977 	    }
978 #endif
979 
980 	/*
981 	 * If 'keymodel' contains "startsel", may start selection.  If it
982 	 * does, a CTRL-O and c will be stuffed, we need to get these
983 	 * characters.
984 	 */
985 	if (ins_start_select(c))
986 	    continue;
987 
988 	/*
989 	 * The big switch to handle a character in insert mode.
990 	 */
991 	switch (c)
992 	{
993 	case ESC:	/* End input mode */
994 	    if (echeck_abbr(ESC + ABBR_OFF))
995 		break;
996 	    /* FALLTHROUGH */
997 
998 	case Ctrl_C:	/* End input mode */
999 #ifdef FEAT_CMDWIN
1000 	    if (c == Ctrl_C && cmdwin_type != 0)
1001 	    {
1002 		/* Close the cmdline window. */
1003 		cmdwin_result = K_IGNORE;
1004 		got_int = FALSE; /* don't stop executing autocommands et al. */
1005 		nomove = TRUE;
1006 		goto doESCkey;
1007 	    }
1008 #endif
1009 #ifdef FEAT_JOB_CHANNEL
1010 	    if (c == Ctrl_C && bt_prompt(curbuf))
1011 	    {
1012 		if (invoke_prompt_interrupt())
1013 		{
1014 		    if (!bt_prompt(curbuf))
1015 			// buffer changed to a non-prompt buffer, get out of
1016 			// Insert mode
1017 			goto doESCkey;
1018 		    break;
1019 		}
1020 	    }
1021 #endif
1022 
1023 #ifdef UNIX
1024 do_intr:
1025 #endif
1026 	    /* when 'insertmode' set, and not halfway a mapping, don't leave
1027 	     * Insert mode */
1028 	    if (goto_im())
1029 	    {
1030 		if (got_int)
1031 		{
1032 		    (void)vgetc();		/* flush all buffers */
1033 		    got_int = FALSE;
1034 		}
1035 		else
1036 		    vim_beep(BO_IM);
1037 		break;
1038 	    }
1039 doESCkey:
1040 	    /*
1041 	     * This is the ONLY return from edit()!
1042 	     */
1043 	    /* Always update o_lnum, so that a "CTRL-O ." that adds a line
1044 	     * still puts the cursor back after the inserted text. */
1045 	    if (ins_at_eol && gchar_cursor() == NUL)
1046 		o_lnum = curwin->w_cursor.lnum;
1047 
1048 	    if (ins_esc(&count, cmdchar, nomove))
1049 	    {
1050 		// When CTRL-C was typed got_int will be set, with the result
1051 		// that the autocommands won't be executed. When mapped got_int
1052 		// is not set, but let's keep the behavior the same.
1053 		if (cmdchar != 'r' && cmdchar != 'v' && c != Ctrl_C)
1054 		    ins_apply_autocmds(EVENT_INSERTLEAVE);
1055 		did_cursorhold = FALSE;
1056 		return (c == Ctrl_O);
1057 	    }
1058 	    continue;
1059 
1060 	case Ctrl_Z:	/* suspend when 'insertmode' set */
1061 	    if (!p_im)
1062 		goto normalchar;	/* insert CTRL-Z as normal char */
1063 	    do_cmdline_cmd((char_u *)"stop");
1064 #ifdef CURSOR_SHAPE
1065 	    ui_cursor_shape();		/* may need to update cursor shape */
1066 #endif
1067 	    continue;
1068 
1069 	case Ctrl_O:	/* execute one command */
1070 #ifdef FEAT_COMPL_FUNC
1071 	    if (ctrl_x_mode == CTRL_X_OMNI)
1072 		goto docomplete;
1073 #endif
1074 	    if (echeck_abbr(Ctrl_O + ABBR_OFF))
1075 		break;
1076 	    ins_ctrl_o();
1077 
1078 #ifdef FEAT_VIRTUALEDIT
1079 	    /* don't move the cursor left when 'virtualedit' has "onemore". */
1080 	    if (ve_flags & VE_ONEMORE)
1081 	    {
1082 		ins_at_eol = FALSE;
1083 		nomove = TRUE;
1084 	    }
1085 #endif
1086 	    count = 0;
1087 	    goto doESCkey;
1088 
1089 	case K_INS:	/* toggle insert/replace mode */
1090 	case K_KINS:
1091 	    ins_insert(replaceState);
1092 	    break;
1093 
1094 	case K_SELECT:	/* end of Select mode mapping - ignore */
1095 	    break;
1096 
1097 	case K_HELP:	/* Help key works like <ESC> <Help> */
1098 	case K_F1:
1099 	case K_XF1:
1100 	    stuffcharReadbuff(K_HELP);
1101 	    if (p_im)
1102 		need_start_insertmode = TRUE;
1103 	    goto doESCkey;
1104 
1105 #ifdef FEAT_NETBEANS_INTG
1106 	case K_F21:	/* NetBeans command */
1107 	    ++no_mapping;		/* don't map the next key hits */
1108 	    i = plain_vgetc();
1109 	    --no_mapping;
1110 	    netbeans_keycommand(i);
1111 	    break;
1112 #endif
1113 
1114 	case K_ZERO:	/* Insert the previously inserted text. */
1115 	case NUL:
1116 	case Ctrl_A:
1117 	    /* For ^@ the trailing ESC will end the insert, unless there is an
1118 	     * error.  */
1119 	    if (stuff_inserted(NUL, 1L, (c == Ctrl_A)) == FAIL
1120 						   && c != Ctrl_A && !p_im)
1121 		goto doESCkey;		/* quit insert mode */
1122 	    inserted_space = FALSE;
1123 	    break;
1124 
1125 	case Ctrl_R:	/* insert the contents of a register */
1126 	    ins_reg();
1127 	    auto_format(FALSE, TRUE);
1128 	    inserted_space = FALSE;
1129 	    break;
1130 
1131 	case Ctrl_G:	/* commands starting with CTRL-G */
1132 	    ins_ctrl_g();
1133 	    break;
1134 
1135 	case Ctrl_HAT:	/* switch input mode and/or langmap */
1136 	    ins_ctrl_hat();
1137 	    break;
1138 
1139 #ifdef FEAT_RIGHTLEFT
1140 	case Ctrl__:	/* switch between languages */
1141 	    if (!p_ari)
1142 		goto normalchar;
1143 	    ins_ctrl_();
1144 	    break;
1145 #endif
1146 
1147 	case Ctrl_D:	/* Make indent one shiftwidth smaller. */
1148 #if defined(FEAT_INS_EXPAND) && defined(FEAT_FIND_ID)
1149 	    if (ctrl_x_mode == CTRL_X_PATH_DEFINES)
1150 		goto docomplete;
1151 #endif
1152 	    /* FALLTHROUGH */
1153 
1154 	case Ctrl_T:	/* Make indent one shiftwidth greater. */
1155 # ifdef FEAT_INS_EXPAND
1156 	    if (c == Ctrl_T && ctrl_x_mode == CTRL_X_THESAURUS)
1157 	    {
1158 		if (has_compl_option(FALSE))
1159 		    goto docomplete;
1160 		break;
1161 	    }
1162 # endif
1163 	    ins_shift(c, lastc);
1164 	    auto_format(FALSE, TRUE);
1165 	    inserted_space = FALSE;
1166 	    break;
1167 
1168 	case K_DEL:	/* delete character under the cursor */
1169 	case K_KDEL:
1170 	    ins_del();
1171 	    auto_format(FALSE, TRUE);
1172 	    break;
1173 
1174 	case K_BS:	/* delete character before the cursor */
1175 	case Ctrl_H:
1176 	    did_backspace = ins_bs(c, BACKSPACE_CHAR, &inserted_space);
1177 	    auto_format(FALSE, TRUE);
1178 	    break;
1179 
1180 	case Ctrl_W:	/* delete word before the cursor */
1181 #ifdef FEAT_JOB_CHANNEL
1182 	    if (bt_prompt(curbuf) && (mod_mask & MOD_MASK_SHIFT) == 0)
1183 	    {
1184 		// In a prompt window CTRL-W is used for window commands.
1185 		// Use Shift-CTRL-W to delete a word.
1186 		stuffcharReadbuff(Ctrl_W);
1187 		restart_edit = 'A';
1188 		nomove = TRUE;
1189 		count = 0;
1190 		goto doESCkey;
1191 	    }
1192 #endif
1193 	    did_backspace = ins_bs(c, BACKSPACE_WORD, &inserted_space);
1194 	    auto_format(FALSE, TRUE);
1195 	    break;
1196 
1197 	case Ctrl_U:	/* delete all inserted text in current line */
1198 # ifdef FEAT_COMPL_FUNC
1199 	    /* CTRL-X CTRL-U completes with 'completefunc'. */
1200 	    if (ctrl_x_mode == CTRL_X_FUNCTION)
1201 		goto docomplete;
1202 # endif
1203 	    did_backspace = ins_bs(c, BACKSPACE_LINE, &inserted_space);
1204 	    auto_format(FALSE, TRUE);
1205 	    inserted_space = FALSE;
1206 	    break;
1207 
1208 #ifdef FEAT_MOUSE
1209 	case K_LEFTMOUSE:   /* mouse keys */
1210 	case K_LEFTMOUSE_NM:
1211 	case K_LEFTDRAG:
1212 	case K_LEFTRELEASE:
1213 	case K_LEFTRELEASE_NM:
1214 	case K_MOUSEMOVE:
1215 	case K_MIDDLEMOUSE:
1216 	case K_MIDDLEDRAG:
1217 	case K_MIDDLERELEASE:
1218 	case K_RIGHTMOUSE:
1219 	case K_RIGHTDRAG:
1220 	case K_RIGHTRELEASE:
1221 	case K_X1MOUSE:
1222 	case K_X1DRAG:
1223 	case K_X1RELEASE:
1224 	case K_X2MOUSE:
1225 	case K_X2DRAG:
1226 	case K_X2RELEASE:
1227 	    ins_mouse(c);
1228 	    break;
1229 
1230 	case K_MOUSEDOWN: /* Default action for scroll wheel up: scroll up */
1231 	    ins_mousescroll(MSCR_DOWN);
1232 	    break;
1233 
1234 	case K_MOUSEUP:	/* Default action for scroll wheel down: scroll down */
1235 	    ins_mousescroll(MSCR_UP);
1236 	    break;
1237 
1238 	case K_MOUSELEFT: /* Scroll wheel left */
1239 	    ins_mousescroll(MSCR_LEFT);
1240 	    break;
1241 
1242 	case K_MOUSERIGHT: /* Scroll wheel right */
1243 	    ins_mousescroll(MSCR_RIGHT);
1244 	    break;
1245 #endif
1246 	case K_PS:
1247 	    bracketed_paste(PASTE_INSERT, FALSE, NULL);
1248 	    if (cmdchar == K_PS)
1249 		/* invoked from normal mode, bail out */
1250 		goto doESCkey;
1251 	    break;
1252 	case K_PE:
1253 	    /* Got K_PE without K_PS, ignore. */
1254 	    break;
1255 
1256 #ifdef FEAT_GUI_TABLINE
1257 	case K_TABLINE:
1258 	case K_TABMENU:
1259 	    ins_tabline(c);
1260 	    break;
1261 #endif
1262 
1263 	case K_IGNORE:	/* Something mapped to nothing */
1264 	    break;
1265 
1266 	case K_CURSORHOLD:	/* Didn't type something for a while. */
1267 	    ins_apply_autocmds(EVENT_CURSORHOLDI);
1268 	    did_cursorhold = TRUE;
1269 	    break;
1270 
1271 #ifdef FEAT_GUI_W32
1272 	    /* On Win32 ignore <M-F4>, we get it when closing the window was
1273 	     * cancelled. */
1274 	case K_F4:
1275 	    if (mod_mask != MOD_MASK_ALT)
1276 		goto normalchar;
1277 	    break;
1278 #endif
1279 
1280 #ifdef FEAT_GUI
1281 	case K_VER_SCROLLBAR:
1282 	    ins_scroll();
1283 	    break;
1284 
1285 	case K_HOR_SCROLLBAR:
1286 	    ins_horscroll();
1287 	    break;
1288 #endif
1289 
1290 	case K_HOME:	/* <Home> */
1291 	case K_KHOME:
1292 	case K_S_HOME:
1293 	case K_C_HOME:
1294 	    ins_home(c);
1295 	    break;
1296 
1297 	case K_END:	/* <End> */
1298 	case K_KEND:
1299 	case K_S_END:
1300 	case K_C_END:
1301 	    ins_end(c);
1302 	    break;
1303 
1304 	case K_LEFT:	/* <Left> */
1305 	    if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL))
1306 		ins_s_left();
1307 	    else
1308 		ins_left(dont_sync_undo == FALSE);
1309 	    break;
1310 
1311 	case K_S_LEFT:	/* <S-Left> */
1312 	case K_C_LEFT:
1313 	    ins_s_left();
1314 	    break;
1315 
1316 	case K_RIGHT:	/* <Right> */
1317 	    if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL))
1318 		ins_s_right();
1319 	    else
1320 		ins_right(dont_sync_undo == FALSE);
1321 	    break;
1322 
1323 	case K_S_RIGHT:	/* <S-Right> */
1324 	case K_C_RIGHT:
1325 	    ins_s_right();
1326 	    break;
1327 
1328 	case K_UP:	/* <Up> */
1329 #ifdef FEAT_INS_EXPAND
1330 	    if (pum_visible())
1331 		goto docomplete;
1332 #endif
1333 	    if (mod_mask & MOD_MASK_SHIFT)
1334 		ins_pageup();
1335 	    else
1336 		ins_up(FALSE);
1337 	    break;
1338 
1339 	case K_S_UP:	/* <S-Up> */
1340 	case K_PAGEUP:
1341 	case K_KPAGEUP:
1342 #ifdef FEAT_INS_EXPAND
1343 	    if (pum_visible())
1344 		goto docomplete;
1345 #endif
1346 	    ins_pageup();
1347 	    break;
1348 
1349 	case K_DOWN:	/* <Down> */
1350 #ifdef FEAT_INS_EXPAND
1351 	    if (pum_visible())
1352 		goto docomplete;
1353 #endif
1354 	    if (mod_mask & MOD_MASK_SHIFT)
1355 		ins_pagedown();
1356 	    else
1357 		ins_down(FALSE);
1358 	    break;
1359 
1360 	case K_S_DOWN:	/* <S-Down> */
1361 	case K_PAGEDOWN:
1362 	case K_KPAGEDOWN:
1363 #ifdef FEAT_INS_EXPAND
1364 	    if (pum_visible())
1365 		goto docomplete;
1366 #endif
1367 	    ins_pagedown();
1368 	    break;
1369 
1370 #ifdef FEAT_DND
1371 	case K_DROP:	/* drag-n-drop event */
1372 	    ins_drop();
1373 	    break;
1374 #endif
1375 
1376 	case K_S_TAB:	/* When not mapped, use like a normal TAB */
1377 	    c = TAB;
1378 	    /* FALLTHROUGH */
1379 
1380 	case TAB:	/* TAB or Complete patterns along path */
1381 #if defined(FEAT_INS_EXPAND) && defined(FEAT_FIND_ID)
1382 	    if (ctrl_x_mode == CTRL_X_PATH_PATTERNS)
1383 		goto docomplete;
1384 #endif
1385 	    inserted_space = FALSE;
1386 	    if (ins_tab())
1387 		goto normalchar;	/* insert TAB as a normal char */
1388 	    auto_format(FALSE, TRUE);
1389 	    break;
1390 
1391 	case K_KENTER:	/* <Enter> */
1392 	    c = CAR;
1393 	    /* FALLTHROUGH */
1394 	case CAR:
1395 	case NL:
1396 #if defined(FEAT_QUICKFIX)
1397 	    /* In a quickfix window a <CR> jumps to the error under the
1398 	     * cursor. */
1399 	    if (bt_quickfix(curbuf) && c == CAR)
1400 	    {
1401 		if (curwin->w_llist_ref == NULL)    /* quickfix window */
1402 		    do_cmdline_cmd((char_u *)".cc");
1403 		else				    /* location list window */
1404 		    do_cmdline_cmd((char_u *)".ll");
1405 		break;
1406 	    }
1407 #endif
1408 #ifdef FEAT_CMDWIN
1409 	    if (cmdwin_type != 0)
1410 	    {
1411 		/* Execute the command in the cmdline window. */
1412 		cmdwin_result = CAR;
1413 		goto doESCkey;
1414 	    }
1415 #endif
1416 #ifdef FEAT_JOB_CHANNEL
1417 	    if (bt_prompt(curbuf))
1418 	    {
1419 		invoke_prompt_callback();
1420 		if (!bt_prompt(curbuf))
1421 		    // buffer changed to a non-prompt buffer, get out of
1422 		    // Insert mode
1423 		    goto doESCkey;
1424 		break;
1425 	    }
1426 #endif
1427 	    if (ins_eol(c) == FAIL && !p_im)
1428 		goto doESCkey;	    /* out of memory */
1429 	    auto_format(FALSE, FALSE);
1430 	    inserted_space = FALSE;
1431 	    break;
1432 
1433 #if defined(FEAT_DIGRAPHS) || defined(FEAT_INS_EXPAND)
1434 	case Ctrl_K:	    /* digraph or keyword completion */
1435 # ifdef FEAT_INS_EXPAND
1436 	    if (ctrl_x_mode == CTRL_X_DICTIONARY)
1437 	    {
1438 		if (has_compl_option(TRUE))
1439 		    goto docomplete;
1440 		break;
1441 	    }
1442 # endif
1443 # ifdef FEAT_DIGRAPHS
1444 	    c = ins_digraph();
1445 	    if (c == NUL)
1446 		break;
1447 # endif
1448 	    goto normalchar;
1449 #endif
1450 
1451 #ifdef FEAT_INS_EXPAND
1452 	case Ctrl_X:	/* Enter CTRL-X mode */
1453 	    ins_ctrl_x();
1454 	    break;
1455 
1456 	case Ctrl_RSB:	/* Tag name completion after ^X */
1457 	    if (ctrl_x_mode != CTRL_X_TAGS)
1458 		goto normalchar;
1459 	    goto docomplete;
1460 
1461 	case Ctrl_F:	/* File name completion after ^X */
1462 	    if (ctrl_x_mode != CTRL_X_FILES)
1463 		goto normalchar;
1464 	    goto docomplete;
1465 
1466 	case 's':	/* Spelling completion after ^X */
1467 	case Ctrl_S:
1468 	    if (ctrl_x_mode != CTRL_X_SPELL)
1469 		goto normalchar;
1470 	    goto docomplete;
1471 #endif
1472 
1473 	case Ctrl_L:	/* Whole line completion after ^X */
1474 #ifdef FEAT_INS_EXPAND
1475 	    if (ctrl_x_mode != CTRL_X_WHOLE_LINE)
1476 #endif
1477 	    {
1478 		/* CTRL-L with 'insertmode' set: Leave Insert mode */
1479 		if (p_im)
1480 		{
1481 		    if (echeck_abbr(Ctrl_L + ABBR_OFF))
1482 			break;
1483 		    goto doESCkey;
1484 		}
1485 		goto normalchar;
1486 	    }
1487 #ifdef FEAT_INS_EXPAND
1488 	    /* FALLTHROUGH */
1489 
1490 	case Ctrl_P:	/* Do previous/next pattern completion */
1491 	case Ctrl_N:
1492 	    /* if 'complete' is empty then plain ^P is no longer special,
1493 	     * but it is under other ^X modes */
1494 	    if (*curbuf->b_p_cpt == NUL
1495 		    && (ctrl_x_mode == CTRL_X_NORMAL
1496 			|| ctrl_x_mode == CTRL_X_WHOLE_LINE)
1497 		    && !(compl_cont_status & CONT_LOCAL))
1498 		goto normalchar;
1499 
1500 docomplete:
1501 	    compl_busy = TRUE;
1502 #ifdef FEAT_FOLDING
1503 	    disable_fold_update++;  /* don't redraw folds here */
1504 #endif
1505 	    if (ins_complete(c, TRUE) == FAIL)
1506 		compl_cont_status = 0;
1507 #ifdef FEAT_FOLDING
1508 	    disable_fold_update--;
1509 #endif
1510 	    compl_busy = FALSE;
1511 	    break;
1512 #endif /* FEAT_INS_EXPAND */
1513 
1514 	case Ctrl_Y:	/* copy from previous line or scroll down */
1515 	case Ctrl_E:	/* copy from next line	   or scroll up */
1516 	    c = ins_ctrl_ey(c);
1517 	    break;
1518 
1519 	  default:
1520 #ifdef UNIX
1521 	    if (c == intr_char)		/* special interrupt char */
1522 		goto do_intr;
1523 #endif
1524 
1525 normalchar:
1526 	    /*
1527 	     * Insert a normal character.
1528 	     */
1529 #if defined(FEAT_EVAL)
1530 	    if (!p_paste)
1531 	    {
1532 		/* Trigger InsertCharPre. */
1533 		char_u *str = do_insert_char_pre(c);
1534 		char_u *p;
1535 
1536 		if (str != NULL)
1537 		{
1538 		    if (*str != NUL && stop_arrow() != FAIL)
1539 		    {
1540 			/* Insert the new value of v:char literally. */
1541 			for (p = str; *p != NUL; MB_PTR_ADV(p))
1542 			{
1543 			    c = PTR2CHAR(p);
1544 			    if (c == CAR || c == K_KENTER || c == NL)
1545 				ins_eol(c);
1546 			    else
1547 				ins_char(c);
1548 			}
1549 			AppendToRedobuffLit(str, -1);
1550 		    }
1551 		    vim_free(str);
1552 		    c = NUL;
1553 		}
1554 
1555 		/* If the new value is already inserted or an empty string
1556 		 * then don't insert any character. */
1557 		if (c == NUL)
1558 		    break;
1559 	    }
1560 #endif
1561 #ifdef FEAT_SMARTINDENT
1562 	    /* Try to perform smart-indenting. */
1563 	    ins_try_si(c);
1564 #endif
1565 
1566 	    if (c == ' ')
1567 	    {
1568 		inserted_space = TRUE;
1569 #ifdef FEAT_CINDENT
1570 		if (inindent(0))
1571 		    can_cindent = FALSE;
1572 #endif
1573 		if (Insstart_blank_vcol == MAXCOL
1574 			&& curwin->w_cursor.lnum == Insstart.lnum)
1575 		    Insstart_blank_vcol = get_nolist_virtcol();
1576 	    }
1577 
1578 	    /* Insert a normal character and check for abbreviations on a
1579 	     * special character.  Let CTRL-] expand abbreviations without
1580 	     * inserting it. */
1581 	    if (vim_iswordc(c) || (!echeck_abbr(
1582 #ifdef FEAT_MBYTE
1583 			/* Add ABBR_OFF for characters above 0x100, this is
1584 			 * what check_abbr() expects. */
1585 			(has_mbyte && c >= 0x100) ? (c + ABBR_OFF) :
1586 #endif
1587 		       c) && c != Ctrl_RSB))
1588 	    {
1589 		insert_special(c, FALSE, FALSE);
1590 #ifdef FEAT_RIGHTLEFT
1591 		revins_legal++;
1592 		revins_chars++;
1593 #endif
1594 	    }
1595 
1596 	    auto_format(FALSE, TRUE);
1597 
1598 #ifdef FEAT_FOLDING
1599 	    /* When inserting a character the cursor line must never be in a
1600 	     * closed fold. */
1601 	    foldOpenCursor();
1602 #endif
1603 	    break;
1604 	}   /* end of switch (c) */
1605 
1606 	/* If typed something may trigger CursorHoldI again. */
1607 	if (c != K_CURSORHOLD
1608 #ifdef FEAT_COMPL_FUNC
1609 		/* but not in CTRL-X mode, a script can't restore the state */
1610 		&& ctrl_x_mode == CTRL_X_NORMAL
1611 #endif
1612 	       )
1613 	    did_cursorhold = FALSE;
1614 
1615 	/* If the cursor was moved we didn't just insert a space */
1616 	if (arrow_used)
1617 	    inserted_space = FALSE;
1618 
1619 #ifdef FEAT_CINDENT
1620 	if (can_cindent && cindent_on()
1621 # ifdef FEAT_INS_EXPAND
1622 		&& ctrl_x_mode == CTRL_X_NORMAL
1623 # endif
1624 	   )
1625 	{
1626 force_cindent:
1627 	    /*
1628 	     * Indent now if a key was typed that is in 'cinkeys'.
1629 	     */
1630 	    if (in_cinkeys(c, ' ', line_is_white))
1631 	    {
1632 		if (stop_arrow() == OK)
1633 		    /* re-indent the current line */
1634 		    do_c_expr_indent();
1635 	    }
1636 	}
1637 #endif /* FEAT_CINDENT */
1638 
1639     }	/* for (;;) */
1640     /* NOTREACHED */
1641 }
1642 
1643 /*
1644  * Redraw for Insert mode.
1645  * This is postponed until getting the next character to make '$' in the 'cpo'
1646  * option work correctly.
1647  * Only redraw when there are no characters available.  This speeds up
1648  * inserting sequences of characters (e.g., for CTRL-R).
1649  */
1650     static void
1651 ins_redraw(
1652     int		ready UNUSED)	    /* not busy with something */
1653 {
1654 #ifdef FEAT_CONCEAL
1655     linenr_T	conceal_old_cursor_line = 0;
1656     linenr_T	conceal_new_cursor_line = 0;
1657     int		conceal_update_lines = FALSE;
1658 #endif
1659 
1660     if (char_avail())
1661 	return;
1662 
1663 #if defined(FEAT_CONCEAL)
1664     /* Trigger CursorMoved if the cursor moved.  Not when the popup menu is
1665      * visible, the command might delete it. */
1666     if (ready && (has_cursormovedI()
1667 # if defined(FEAT_CONCEAL)
1668 		|| curwin->w_p_cole > 0
1669 # endif
1670 		)
1671 	    && !EQUAL_POS(last_cursormoved, curwin->w_cursor)
1672 # ifdef FEAT_INS_EXPAND
1673 	    && !pum_visible()
1674 # endif
1675        )
1676     {
1677 # ifdef FEAT_SYN_HL
1678 	/* Need to update the screen first, to make sure syntax
1679 	 * highlighting is correct after making a change (e.g., inserting
1680 	 * a "(".  The autocommand may also require a redraw, so it's done
1681 	 * again below, unfortunately. */
1682 	if (syntax_present(curwin) && must_redraw)
1683 	    update_screen(0);
1684 # endif
1685 	if (has_cursormovedI())
1686 	{
1687 	    /* Make sure curswant is correct, an autocommand may call
1688 	     * getcurpos(). */
1689 	    update_curswant();
1690 	    ins_apply_autocmds(EVENT_CURSORMOVEDI);
1691 	}
1692 # ifdef FEAT_CONCEAL
1693 	if (curwin->w_p_cole > 0)
1694 	{
1695 	    conceal_old_cursor_line = last_cursormoved.lnum;
1696 	    conceal_new_cursor_line = curwin->w_cursor.lnum;
1697 	    conceal_update_lines = TRUE;
1698 	}
1699 # endif
1700 	last_cursormoved = curwin->w_cursor;
1701     }
1702 #endif
1703 
1704     /* Trigger TextChangedI if b_changedtick differs. */
1705     if (ready && has_textchangedI()
1706 	    && curbuf->b_last_changedtick != CHANGEDTICK(curbuf)
1707 #ifdef FEAT_INS_EXPAND
1708 	    && !pum_visible()
1709 #endif
1710 	    )
1711     {
1712 	aco_save_T	aco;
1713 	varnumber_T	tick = CHANGEDTICK(curbuf);
1714 
1715 	// save and restore curwin and curbuf, in case the autocmd changes them
1716 	aucmd_prepbuf(&aco, curbuf);
1717 	apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
1718 	aucmd_restbuf(&aco);
1719 	curbuf->b_last_changedtick = CHANGEDTICK(curbuf);
1720 	if (tick != CHANGEDTICK(curbuf))  // see ins_apply_autocmds()
1721 	    u_save(curwin->w_cursor.lnum,
1722 					(linenr_T)(curwin->w_cursor.lnum + 1));
1723     }
1724 
1725 #ifdef FEAT_INS_EXPAND
1726     /* Trigger TextChangedP if b_changedtick differs. When the popupmenu closes
1727      * TextChangedI will need to trigger for backwards compatibility, thus use
1728      * different b_last_changedtick* variables. */
1729     if (ready && has_textchangedP()
1730 	    && curbuf->b_last_changedtick_pum != CHANGEDTICK(curbuf)
1731 	    && pum_visible())
1732     {
1733 	aco_save_T	aco;
1734 	varnumber_T	tick = CHANGEDTICK(curbuf);
1735 
1736 	// save and restore curwin and curbuf, in case the autocmd changes them
1737 	aucmd_prepbuf(&aco, curbuf);
1738 	apply_autocmds(EVENT_TEXTCHANGEDP, NULL, NULL, FALSE, curbuf);
1739 	aucmd_restbuf(&aco);
1740 	curbuf->b_last_changedtick_pum = CHANGEDTICK(curbuf);
1741 	if (tick != CHANGEDTICK(curbuf))  // see ins_apply_autocmds()
1742 	    u_save(curwin->w_cursor.lnum,
1743 					(linenr_T)(curwin->w_cursor.lnum + 1));
1744     }
1745 #endif
1746 
1747     if (must_redraw)
1748 	update_screen(0);
1749     else if (clear_cmdline || redraw_cmdline)
1750 	showmode();		/* clear cmdline and show mode */
1751 # if defined(FEAT_CONCEAL)
1752     if ((conceal_update_lines
1753 	    && (conceal_old_cursor_line != conceal_new_cursor_line
1754 		|| conceal_cursor_line(curwin)))
1755 	    || need_cursor_line_redraw)
1756     {
1757 	if (conceal_old_cursor_line != conceal_new_cursor_line)
1758 	    update_single_line(curwin, conceal_old_cursor_line);
1759 	update_single_line(curwin, conceal_new_cursor_line == 0
1760 		       ? curwin->w_cursor.lnum : conceal_new_cursor_line);
1761 	curwin->w_valid &= ~VALID_CROW;
1762     }
1763 # endif
1764     showruler(FALSE);
1765     setcursor();
1766     emsg_on_display = FALSE;	/* may remove error message now */
1767 }
1768 
1769 /*
1770  * Handle a CTRL-V or CTRL-Q typed in Insert mode.
1771  */
1772     static void
1773 ins_ctrl_v(void)
1774 {
1775     int		c;
1776     int		did_putchar = FALSE;
1777 
1778     /* may need to redraw when no more chars available now */
1779     ins_redraw(FALSE);
1780 
1781     if (redrawing() && !char_avail())
1782     {
1783 	edit_putchar('^', TRUE);
1784 	did_putchar = TRUE;
1785     }
1786     AppendToRedobuff((char_u *)CTRL_V_STR);	/* CTRL-V */
1787 
1788 #ifdef FEAT_CMDL_INFO
1789     add_to_showcmd_c(Ctrl_V);
1790 #endif
1791 
1792     c = get_literal();
1793     if (did_putchar)
1794 	/* when the line fits in 'columns' the '^' is at the start of the next
1795 	 * line and will not removed by the redraw */
1796 	edit_unputchar();
1797 #ifdef FEAT_CMDL_INFO
1798     clear_showcmd();
1799 #endif
1800     insert_special(c, FALSE, TRUE);
1801 #ifdef FEAT_RIGHTLEFT
1802     revins_chars++;
1803     revins_legal++;
1804 #endif
1805 }
1806 
1807 /*
1808  * Put a character directly onto the screen.  It's not stored in a buffer.
1809  * Used while handling CTRL-K, CTRL-V, etc. in Insert mode.
1810  */
1811 static int  pc_status;
1812 #define PC_STATUS_UNSET	0	/* pc_bytes was not set */
1813 #define PC_STATUS_RIGHT	1	/* right halve of double-wide char */
1814 #define PC_STATUS_LEFT	2	/* left halve of double-wide char */
1815 #define PC_STATUS_SET	3	/* pc_bytes was filled */
1816 static char_u pc_bytes[MB_MAXBYTES + 1]; /* saved bytes */
1817 static int  pc_attr;
1818 static int  pc_row;
1819 static int  pc_col;
1820 
1821     void
1822 edit_putchar(int c, int highlight)
1823 {
1824     int	    attr;
1825 
1826     if (ScreenLines != NULL)
1827     {
1828 	update_topline();	/* just in case w_topline isn't valid */
1829 	validate_cursor();
1830 	if (highlight)
1831 	    attr = HL_ATTR(HLF_8);
1832 	else
1833 	    attr = 0;
1834 	pc_row = W_WINROW(curwin) + curwin->w_wrow;
1835 	pc_col = curwin->w_wincol;
1836 #if defined(FEAT_RIGHTLEFT) || defined(FEAT_MBYTE)
1837 	pc_status = PC_STATUS_UNSET;
1838 #endif
1839 #ifdef FEAT_RIGHTLEFT
1840 	if (curwin->w_p_rl)
1841 	{
1842 	    pc_col += curwin->w_width - 1 - curwin->w_wcol;
1843 # ifdef FEAT_MBYTE
1844 	    if (has_mbyte)
1845 	    {
1846 		int fix_col = mb_fix_col(pc_col, pc_row);
1847 
1848 		if (fix_col != pc_col)
1849 		{
1850 		    screen_putchar(' ', pc_row, fix_col, attr);
1851 		    --curwin->w_wcol;
1852 		    pc_status = PC_STATUS_RIGHT;
1853 		}
1854 	    }
1855 # endif
1856 	}
1857 	else
1858 #endif
1859 	{
1860 	    pc_col += curwin->w_wcol;
1861 #ifdef FEAT_MBYTE
1862 	    if (mb_lefthalve(pc_row, pc_col))
1863 		pc_status = PC_STATUS_LEFT;
1864 #endif
1865 	}
1866 
1867 	/* save the character to be able to put it back */
1868 #if defined(FEAT_RIGHTLEFT) || defined(FEAT_MBYTE)
1869 	if (pc_status == PC_STATUS_UNSET)
1870 #endif
1871 	{
1872 	    screen_getbytes(pc_row, pc_col, pc_bytes, &pc_attr);
1873 	    pc_status = PC_STATUS_SET;
1874 	}
1875 	screen_putchar(c, pc_row, pc_col, attr);
1876     }
1877 }
1878 
1879 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
1880 /*
1881  * Return the effective prompt for the current buffer.
1882  */
1883     char_u *
1884 prompt_text(void)
1885 {
1886     if (curbuf->b_prompt_text == NULL)
1887 	return (char_u *)"% ";
1888     return curbuf->b_prompt_text;
1889 }
1890 
1891 /*
1892  * Prepare for prompt mode: Make sure the last line has the prompt text.
1893  * Move the cursor to this line.
1894  */
1895     static void
1896 init_prompt(int cmdchar_todo)
1897 {
1898     char_u *prompt = prompt_text();
1899     char_u *text;
1900 
1901     curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
1902     text = ml_get_curline();
1903     if (STRNCMP(text, prompt, STRLEN(prompt)) != 0)
1904     {
1905 	// prompt is missing, insert it or append a line with it
1906 	if (*text == NUL)
1907 	    ml_replace(curbuf->b_ml.ml_line_count, prompt, TRUE);
1908 	else
1909 	    ml_append(curbuf->b_ml.ml_line_count, prompt, 0, FALSE);
1910 	curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
1911 	coladvance((colnr_T)MAXCOL);
1912 	changed_bytes(curbuf->b_ml.ml_line_count, 0);
1913     }
1914 
1915     // Insert always starts after the prompt, allow editing text after it.
1916     if (Insstart_orig.lnum != curwin->w_cursor.lnum
1917 				   || Insstart_orig.col != (int)STRLEN(prompt))
1918     {
1919 	Insstart.lnum = curwin->w_cursor.lnum;
1920 	Insstart.col = (int)STRLEN(prompt);
1921 	Insstart_orig = Insstart;
1922 	Insstart_textlen = Insstart.col;
1923 	Insstart_blank_vcol = MAXCOL;
1924 	arrow_used = FALSE;
1925     }
1926 
1927     if (cmdchar_todo == 'A')
1928 	coladvance((colnr_T)MAXCOL);
1929     if (cmdchar_todo == 'I' || curwin->w_cursor.col <= (int)STRLEN(prompt))
1930 	curwin->w_cursor.col = (int)STRLEN(prompt);
1931     /* Make sure the cursor is in a valid position. */
1932     check_cursor();
1933 }
1934 
1935 /*
1936  * Return TRUE if the cursor is in the editable position of the prompt line.
1937  */
1938     int
1939 prompt_curpos_editable()
1940 {
1941     return curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count
1942 	&& curwin->w_cursor.col >= (int)STRLEN(prompt_text());
1943 }
1944 #endif
1945 
1946 /*
1947  * Undo the previous edit_putchar().
1948  */
1949     void
1950 edit_unputchar(void)
1951 {
1952     if (pc_status != PC_STATUS_UNSET && pc_row >= msg_scrolled)
1953     {
1954 #if defined(FEAT_MBYTE)
1955 	if (pc_status == PC_STATUS_RIGHT)
1956 	    ++curwin->w_wcol;
1957 	if (pc_status == PC_STATUS_RIGHT || pc_status == PC_STATUS_LEFT)
1958 	    redrawWinline(curwin, curwin->w_cursor.lnum, FALSE);
1959 	else
1960 #endif
1961 	    screen_puts(pc_bytes, pc_row - msg_scrolled, pc_col, pc_attr);
1962     }
1963 }
1964 
1965 /*
1966  * Called when p_dollar is set: display a '$' at the end of the changed text
1967  * Only works when cursor is in the line that changes.
1968  */
1969     void
1970 display_dollar(colnr_T col)
1971 {
1972     colnr_T save_col;
1973 
1974     if (!redrawing())
1975 	return;
1976 
1977     cursor_off();
1978     save_col = curwin->w_cursor.col;
1979     curwin->w_cursor.col = col;
1980 #ifdef FEAT_MBYTE
1981     if (has_mbyte)
1982     {
1983 	char_u *p;
1984 
1985 	/* If on the last byte of a multi-byte move to the first byte. */
1986 	p = ml_get_curline();
1987 	curwin->w_cursor.col -= (*mb_head_off)(p, p + col);
1988     }
1989 #endif
1990     curs_columns(FALSE);	    /* recompute w_wrow and w_wcol */
1991     if (curwin->w_wcol < curwin->w_width)
1992     {
1993 	edit_putchar('$', FALSE);
1994 	dollar_vcol = curwin->w_virtcol;
1995     }
1996     curwin->w_cursor.col = save_col;
1997 }
1998 
1999 /*
2000  * Call this function before moving the cursor from the normal insert position
2001  * in insert mode.
2002  */
2003     static void
2004 undisplay_dollar(void)
2005 {
2006     if (dollar_vcol >= 0)
2007     {
2008 	dollar_vcol = -1;
2009 	redrawWinline(curwin, curwin->w_cursor.lnum, FALSE);
2010     }
2011 }
2012 
2013 /*
2014  * Insert an indent (for <Tab> or CTRL-T) or delete an indent (for CTRL-D).
2015  * Keep the cursor on the same character.
2016  * type == INDENT_INC	increase indent (for CTRL-T or <Tab>)
2017  * type == INDENT_DEC	decrease indent (for CTRL-D)
2018  * type == INDENT_SET	set indent to "amount"
2019  * if round is TRUE, round the indent to 'shiftwidth' (only with _INC and _Dec).
2020  */
2021     void
2022 change_indent(
2023     int		type,
2024     int		amount,
2025     int		round,
2026     int		replaced,	/* replaced character, put on replace stack */
2027     int		call_changed_bytes)	/* call changed_bytes() */
2028 {
2029     int		vcol;
2030     int		last_vcol;
2031     int		insstart_less;		/* reduction for Insstart.col */
2032     int		new_cursor_col;
2033     int		i;
2034     char_u	*ptr;
2035     int		save_p_list;
2036     int		start_col;
2037     colnr_T	vc;
2038     colnr_T	orig_col = 0;		/* init for GCC */
2039     char_u	*new_line, *orig_line = NULL;	/* init for GCC */
2040 
2041     /* VREPLACE mode needs to know what the line was like before changing */
2042     if (State & VREPLACE_FLAG)
2043     {
2044 	orig_line = vim_strsave(ml_get_curline());  /* Deal with NULL below */
2045 	orig_col = curwin->w_cursor.col;
2046     }
2047 
2048     /* for the following tricks we don't want list mode */
2049     save_p_list = curwin->w_p_list;
2050     curwin->w_p_list = FALSE;
2051     vc = getvcol_nolist(&curwin->w_cursor);
2052     vcol = vc;
2053 
2054     /*
2055      * For Replace mode we need to fix the replace stack later, which is only
2056      * possible when the cursor is in the indent.  Remember the number of
2057      * characters before the cursor if it's possible.
2058      */
2059     start_col = curwin->w_cursor.col;
2060 
2061     /* determine offset from first non-blank */
2062     new_cursor_col = curwin->w_cursor.col;
2063     beginline(BL_WHITE);
2064     new_cursor_col -= curwin->w_cursor.col;
2065 
2066     insstart_less = curwin->w_cursor.col;
2067 
2068     /*
2069      * If the cursor is in the indent, compute how many screen columns the
2070      * cursor is to the left of the first non-blank.
2071      */
2072     if (new_cursor_col < 0)
2073 	vcol = get_indent() - vcol;
2074 
2075     if (new_cursor_col > 0)	    /* can't fix replace stack */
2076 	start_col = -1;
2077 
2078     /*
2079      * Set the new indent.  The cursor will be put on the first non-blank.
2080      */
2081     if (type == INDENT_SET)
2082 	(void)set_indent(amount, call_changed_bytes ? SIN_CHANGED : 0);
2083     else
2084     {
2085 	int	save_State = State;
2086 
2087 	/* Avoid being called recursively. */
2088 	if (State & VREPLACE_FLAG)
2089 	    State = INSERT;
2090 	shift_line(type == INDENT_DEC, round, 1, call_changed_bytes);
2091 	State = save_State;
2092     }
2093     insstart_less -= curwin->w_cursor.col;
2094 
2095     /*
2096      * Try to put cursor on same character.
2097      * If the cursor is at or after the first non-blank in the line,
2098      * compute the cursor column relative to the column of the first
2099      * non-blank character.
2100      * If we are not in insert mode, leave the cursor on the first non-blank.
2101      * If the cursor is before the first non-blank, position it relative
2102      * to the first non-blank, counted in screen columns.
2103      */
2104     if (new_cursor_col >= 0)
2105     {
2106 	/*
2107 	 * When changing the indent while the cursor is touching it, reset
2108 	 * Insstart_col to 0.
2109 	 */
2110 	if (new_cursor_col == 0)
2111 	    insstart_less = MAXCOL;
2112 	new_cursor_col += curwin->w_cursor.col;
2113     }
2114     else if (!(State & INSERT))
2115 	new_cursor_col = curwin->w_cursor.col;
2116     else
2117     {
2118 	/*
2119 	 * Compute the screen column where the cursor should be.
2120 	 */
2121 	vcol = get_indent() - vcol;
2122 	curwin->w_virtcol = (colnr_T)((vcol < 0) ? 0 : vcol);
2123 
2124 	/*
2125 	 * Advance the cursor until we reach the right screen column.
2126 	 */
2127 	vcol = last_vcol = 0;
2128 	new_cursor_col = -1;
2129 	ptr = ml_get_curline();
2130 	while (vcol <= (int)curwin->w_virtcol)
2131 	{
2132 	    last_vcol = vcol;
2133 #ifdef FEAT_MBYTE
2134 	    if (has_mbyte && new_cursor_col >= 0)
2135 		new_cursor_col += (*mb_ptr2len)(ptr + new_cursor_col);
2136 	    else
2137 #endif
2138 		++new_cursor_col;
2139 	    vcol += lbr_chartabsize(ptr, ptr + new_cursor_col, (colnr_T)vcol);
2140 	}
2141 	vcol = last_vcol;
2142 
2143 	/*
2144 	 * May need to insert spaces to be able to position the cursor on
2145 	 * the right screen column.
2146 	 */
2147 	if (vcol != (int)curwin->w_virtcol)
2148 	{
2149 	    curwin->w_cursor.col = (colnr_T)new_cursor_col;
2150 	    i = (int)curwin->w_virtcol - vcol;
2151 	    ptr = alloc((unsigned)(i + 1));
2152 	    if (ptr != NULL)
2153 	    {
2154 		new_cursor_col += i;
2155 		ptr[i] = NUL;
2156 		while (--i >= 0)
2157 		    ptr[i] = ' ';
2158 		ins_str(ptr);
2159 		vim_free(ptr);
2160 	    }
2161 	}
2162 
2163 	/*
2164 	 * When changing the indent while the cursor is in it, reset
2165 	 * Insstart_col to 0.
2166 	 */
2167 	insstart_less = MAXCOL;
2168     }
2169 
2170     curwin->w_p_list = save_p_list;
2171 
2172     if (new_cursor_col <= 0)
2173 	curwin->w_cursor.col = 0;
2174     else
2175 	curwin->w_cursor.col = (colnr_T)new_cursor_col;
2176     curwin->w_set_curswant = TRUE;
2177     changed_cline_bef_curs();
2178 
2179     /*
2180      * May have to adjust the start of the insert.
2181      */
2182     if (State & INSERT)
2183     {
2184 	if (curwin->w_cursor.lnum == Insstart.lnum && Insstart.col != 0)
2185 	{
2186 	    if ((int)Insstart.col <= insstart_less)
2187 		Insstart.col = 0;
2188 	    else
2189 		Insstart.col -= insstart_less;
2190 	}
2191 	if ((int)ai_col <= insstart_less)
2192 	    ai_col = 0;
2193 	else
2194 	    ai_col -= insstart_less;
2195     }
2196 
2197     /*
2198      * For REPLACE mode, may have to fix the replace stack, if it's possible.
2199      * If the number of characters before the cursor decreased, need to pop a
2200      * few characters from the replace stack.
2201      * If the number of characters before the cursor increased, need to push a
2202      * few NULs onto the replace stack.
2203      */
2204     if (REPLACE_NORMAL(State) && start_col >= 0)
2205     {
2206 	while (start_col > (int)curwin->w_cursor.col)
2207 	{
2208 	    replace_join(0);	    /* remove a NUL from the replace stack */
2209 	    --start_col;
2210 	}
2211 	while (start_col < (int)curwin->w_cursor.col || replaced)
2212 	{
2213 	    replace_push(NUL);
2214 	    if (replaced)
2215 	    {
2216 		replace_push(replaced);
2217 		replaced = NUL;
2218 	    }
2219 	    ++start_col;
2220 	}
2221     }
2222 
2223     /*
2224      * For VREPLACE mode, we also have to fix the replace stack.  In this case
2225      * it is always possible because we backspace over the whole line and then
2226      * put it back again the way we wanted it.
2227      */
2228     if (State & VREPLACE_FLAG)
2229     {
2230 	/* If orig_line didn't allocate, just return.  At least we did the job,
2231 	 * even if you can't backspace. */
2232 	if (orig_line == NULL)
2233 	    return;
2234 
2235 	/* Save new line */
2236 	new_line = vim_strsave(ml_get_curline());
2237 	if (new_line == NULL)
2238 	    return;
2239 
2240 	/* We only put back the new line up to the cursor */
2241 	new_line[curwin->w_cursor.col] = NUL;
2242 
2243 	/* Put back original line */
2244 	ml_replace(curwin->w_cursor.lnum, orig_line, FALSE);
2245 	curwin->w_cursor.col = orig_col;
2246 
2247 	/* Backspace from cursor to start of line */
2248 	backspace_until_column(0);
2249 
2250 	/* Insert new stuff into line again */
2251 	ins_bytes(new_line);
2252 
2253 	vim_free(new_line);
2254     }
2255 }
2256 
2257 /*
2258  * Truncate the space at the end of a line.  This is to be used only in an
2259  * insert mode.  It handles fixing the replace stack for REPLACE and VREPLACE
2260  * modes.
2261  */
2262     void
2263 truncate_spaces(char_u *line)
2264 {
2265     int	    i;
2266 
2267     /* find start of trailing white space */
2268     for (i = (int)STRLEN(line) - 1; i >= 0 && VIM_ISWHITE(line[i]); i--)
2269     {
2270 	if (State & REPLACE_FLAG)
2271 	    replace_join(0);	    /* remove a NUL from the replace stack */
2272     }
2273     line[i + 1] = NUL;
2274 }
2275 
2276 /*
2277  * Backspace the cursor until the given column.  Handles REPLACE and VREPLACE
2278  * modes correctly.  May also be used when not in insert mode at all.
2279  * Will attempt not to go before "col" even when there is a composing
2280  * character.
2281  */
2282     void
2283 backspace_until_column(int col)
2284 {
2285     while ((int)curwin->w_cursor.col > col)
2286     {
2287 	curwin->w_cursor.col--;
2288 	if (State & REPLACE_FLAG)
2289 	    replace_do_bs(col);
2290 	else if (!del_char_after_col(col))
2291 	    break;
2292     }
2293 }
2294 
2295 /*
2296  * Like del_char(), but make sure not to go before column "limit_col".
2297  * Only matters when there are composing characters.
2298  * Return TRUE when something was deleted.
2299  */
2300    static int
2301 del_char_after_col(int limit_col UNUSED)
2302 {
2303 #ifdef FEAT_MBYTE
2304     if (enc_utf8 && limit_col >= 0)
2305     {
2306 	colnr_T ecol = curwin->w_cursor.col + 1;
2307 
2308 	/* Make sure the cursor is at the start of a character, but
2309 	 * skip forward again when going too far back because of a
2310 	 * composing character. */
2311 	mb_adjust_cursor();
2312 	while (curwin->w_cursor.col < (colnr_T)limit_col)
2313 	{
2314 	    int l = utf_ptr2len(ml_get_cursor());
2315 
2316 	    if (l == 0)  /* end of line */
2317 		break;
2318 	    curwin->w_cursor.col += l;
2319 	}
2320 	if (*ml_get_cursor() == NUL || curwin->w_cursor.col == ecol)
2321 	    return FALSE;
2322 	del_bytes((long)((int)ecol - curwin->w_cursor.col), FALSE, TRUE);
2323     }
2324     else
2325 #endif
2326 	(void)del_char(FALSE);
2327     return TRUE;
2328 }
2329 
2330 #if defined(FEAT_INS_EXPAND) || defined(PROTO)
2331 /*
2332  * CTRL-X pressed in Insert mode.
2333  */
2334     static void
2335 ins_ctrl_x(void)
2336 {
2337     /* CTRL-X after CTRL-X CTRL-V doesn't do anything, so that CTRL-X
2338      * CTRL-V works like CTRL-N */
2339     if (ctrl_x_mode != CTRL_X_CMDLINE)
2340     {
2341 	/* if the next ^X<> won't ADD nothing, then reset
2342 	 * compl_cont_status */
2343 	if (compl_cont_status & CONT_N_ADDS)
2344 	    compl_cont_status |= CONT_INTRPT;
2345 	else
2346 	    compl_cont_status = 0;
2347 	/* We're not sure which CTRL-X mode it will be yet */
2348 	ctrl_x_mode = CTRL_X_NOT_DEFINED_YET;
2349 	edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode));
2350 	edit_submode_pre = NULL;
2351 	showmode();
2352     }
2353 }
2354 
2355 /*
2356  * Whether other than default completion has been selected.
2357  */
2358     int
2359 ctrl_x_mode_not_default(void)
2360 {
2361     return ctrl_x_mode != CTRL_X_NORMAL;
2362 }
2363 
2364 /*
2365  * Whether CTRL-X was typed without a following character.
2366  */
2367     int
2368 ctrl_x_mode_not_defined_yet(void)
2369 {
2370     return ctrl_x_mode == CTRL_X_NOT_DEFINED_YET;
2371 }
2372 
2373 /*
2374  * Return TRUE if the 'dict' or 'tsr' option can be used.
2375  */
2376     static int
2377 has_compl_option(int dict_opt)
2378 {
2379     if (dict_opt ? (*curbuf->b_p_dict == NUL && *p_dict == NUL
2380 # ifdef FEAT_SPELL
2381 							&& !curwin->w_p_spell
2382 # endif
2383 							)
2384 		 : (*curbuf->b_p_tsr == NUL && *p_tsr == NUL))
2385     {
2386 	ctrl_x_mode = CTRL_X_NORMAL;
2387 	edit_submode = NULL;
2388 	msg_attr(dict_opt ? (char_u *)_("'dictionary' option is empty")
2389 			  : (char_u *)_("'thesaurus' option is empty"),
2390 							      HL_ATTR(HLF_E));
2391 	if (emsg_silent == 0)
2392 	{
2393 	    vim_beep(BO_COMPL);
2394 	    setcursor();
2395 	    out_flush();
2396 #ifdef FEAT_EVAL
2397 	    if (!get_vim_var_nr(VV_TESTING))
2398 #endif
2399 		ui_delay(2000L, FALSE);
2400 	}
2401 	return FALSE;
2402     }
2403     return TRUE;
2404 }
2405 
2406 /*
2407  * Is the character 'c' a valid key to go to or keep us in CTRL-X mode?
2408  * This depends on the current mode.
2409  */
2410     int
2411 vim_is_ctrl_x_key(int c)
2412 {
2413     // Always allow ^R - let its results then be checked
2414     if (c == Ctrl_R)
2415 	return TRUE;
2416 
2417     /* Accept <PageUp> and <PageDown> if the popup menu is visible. */
2418     if (ins_compl_pum_key(c))
2419 	return TRUE;
2420 
2421     switch (ctrl_x_mode)
2422     {
2423 	case 0:		    /* Not in any CTRL-X mode */
2424 	    return (c == Ctrl_N || c == Ctrl_P || c == Ctrl_X);
2425 	case CTRL_X_NOT_DEFINED_YET:
2426 	    return (   c == Ctrl_X || c == Ctrl_Y || c == Ctrl_E
2427 		    || c == Ctrl_L || c == Ctrl_F || c == Ctrl_RSB
2428 		    || c == Ctrl_I || c == Ctrl_D || c == Ctrl_P
2429 		    || c == Ctrl_N || c == Ctrl_T || c == Ctrl_V
2430 		    || c == Ctrl_Q || c == Ctrl_U || c == Ctrl_O
2431 		    || c == Ctrl_S || c == Ctrl_K || c == 's');
2432 	case CTRL_X_SCROLL:
2433 	    return (c == Ctrl_Y || c == Ctrl_E);
2434 	case CTRL_X_WHOLE_LINE:
2435 	    return (c == Ctrl_L || c == Ctrl_P || c == Ctrl_N);
2436 	case CTRL_X_FILES:
2437 	    return (c == Ctrl_F || c == Ctrl_P || c == Ctrl_N);
2438 	case CTRL_X_DICTIONARY:
2439 	    return (c == Ctrl_K || c == Ctrl_P || c == Ctrl_N);
2440 	case CTRL_X_THESAURUS:
2441 	    return (c == Ctrl_T || c == Ctrl_P || c == Ctrl_N);
2442 	case CTRL_X_TAGS:
2443 	    return (c == Ctrl_RSB || c == Ctrl_P || c == Ctrl_N);
2444 #ifdef FEAT_FIND_ID
2445 	case CTRL_X_PATH_PATTERNS:
2446 	    return (c == Ctrl_P || c == Ctrl_N);
2447 	case CTRL_X_PATH_DEFINES:
2448 	    return (c == Ctrl_D || c == Ctrl_P || c == Ctrl_N);
2449 #endif
2450 	case CTRL_X_CMDLINE:
2451 	    return (c == Ctrl_V || c == Ctrl_Q || c == Ctrl_P || c == Ctrl_N
2452 		    || c == Ctrl_X);
2453 #ifdef FEAT_COMPL_FUNC
2454 	case CTRL_X_FUNCTION:
2455 	    return (c == Ctrl_U || c == Ctrl_P || c == Ctrl_N);
2456 	case CTRL_X_OMNI:
2457 	    return (c == Ctrl_O || c == Ctrl_P || c == Ctrl_N);
2458 #endif
2459 	case CTRL_X_SPELL:
2460 	    return (c == Ctrl_S || c == Ctrl_P || c == Ctrl_N);
2461 	case CTRL_X_EVAL:
2462 	    return (c == Ctrl_P || c == Ctrl_N);
2463     }
2464     internal_error("vim_is_ctrl_x_key()");
2465     return FALSE;
2466 }
2467 
2468 /*
2469  * Return TRUE when character "c" is part of the item currently being
2470  * completed.  Used to decide whether to abandon complete mode when the menu
2471  * is visible.
2472  */
2473     static int
2474 ins_compl_accept_char(int c)
2475 {
2476     if (ctrl_x_mode & CTRL_X_WANT_IDENT)
2477 	/* When expanding an identifier only accept identifier chars. */
2478 	return vim_isIDc(c);
2479 
2480     switch (ctrl_x_mode)
2481     {
2482 	case CTRL_X_FILES:
2483 	    /* When expanding file name only accept file name chars. But not
2484 	     * path separators, so that "proto/<Tab>" expands files in
2485 	     * "proto", not "proto/" as a whole */
2486 	    return vim_isfilec(c) && !vim_ispathsep(c);
2487 
2488 	case CTRL_X_CMDLINE:
2489 	case CTRL_X_OMNI:
2490 	    /* Command line and Omni completion can work with just about any
2491 	     * printable character, but do stop at white space. */
2492 	    return vim_isprintc(c) && !VIM_ISWHITE(c);
2493 
2494 	case CTRL_X_WHOLE_LINE:
2495 	    /* For while line completion a space can be part of the line. */
2496 	    return vim_isprintc(c);
2497     }
2498     return vim_iswordc(c);
2499 }
2500 
2501 /*
2502  * This is like ins_compl_add(), but if 'ic' and 'inf' are set, then the
2503  * case of the originally typed text is used, and the case of the completed
2504  * text is inferred, ie this tries to work out what case you probably wanted
2505  * the rest of the word to be in -- webb
2506  */
2507     int
2508 ins_compl_add_infercase(
2509     char_u	*str,
2510     int		len,
2511     int		icase,
2512     char_u	*fname,
2513     int		dir,
2514     int		flags)
2515 {
2516     char_u	*p;
2517     int		i, c;
2518     int		actual_len;		/* Take multi-byte characters */
2519     int		actual_compl_length;	/* into account. */
2520     int		min_len;
2521     int		*wca;			/* Wide character array. */
2522     int		has_lower = FALSE;
2523     int		was_letter = FALSE;
2524 
2525     if (p_ic && curbuf->b_p_inf && len > 0)
2526     {
2527 	/* Infer case of completed part. */
2528 
2529 	/* Find actual length of completion. */
2530 #ifdef FEAT_MBYTE
2531 	if (has_mbyte)
2532 	{
2533 	    p = str;
2534 	    actual_len = 0;
2535 	    while (*p != NUL)
2536 	    {
2537 		MB_PTR_ADV(p);
2538 		++actual_len;
2539 	    }
2540 	}
2541 	else
2542 #endif
2543 	    actual_len = len;
2544 
2545 	/* Find actual length of original text. */
2546 #ifdef FEAT_MBYTE
2547 	if (has_mbyte)
2548 	{
2549 	    p = compl_orig_text;
2550 	    actual_compl_length = 0;
2551 	    while (*p != NUL)
2552 	    {
2553 		MB_PTR_ADV(p);
2554 		++actual_compl_length;
2555 	    }
2556 	}
2557 	else
2558 #endif
2559 	    actual_compl_length = compl_length;
2560 
2561 	/* "actual_len" may be smaller than "actual_compl_length" when using
2562 	 * thesaurus, only use the minimum when comparing. */
2563 	min_len = actual_len < actual_compl_length
2564 					   ? actual_len : actual_compl_length;
2565 
2566 	/* Allocate wide character array for the completion and fill it. */
2567 	wca = (int *)alloc((unsigned)(actual_len * sizeof(int)));
2568 	if (wca != NULL)
2569 	{
2570 	    p = str;
2571 	    for (i = 0; i < actual_len; ++i)
2572 #ifdef FEAT_MBYTE
2573 		if (has_mbyte)
2574 		    wca[i] = mb_ptr2char_adv(&p);
2575 		else
2576 #endif
2577 		    wca[i] = *(p++);
2578 
2579 	    /* Rule 1: Were any chars converted to lower? */
2580 	    p = compl_orig_text;
2581 	    for (i = 0; i < min_len; ++i)
2582 	    {
2583 #ifdef FEAT_MBYTE
2584 		if (has_mbyte)
2585 		    c = mb_ptr2char_adv(&p);
2586 		else
2587 #endif
2588 		    c = *(p++);
2589 		if (MB_ISLOWER(c))
2590 		{
2591 		    has_lower = TRUE;
2592 		    if (MB_ISUPPER(wca[i]))
2593 		    {
2594 			/* Rule 1 is satisfied. */
2595 			for (i = actual_compl_length; i < actual_len; ++i)
2596 			    wca[i] = MB_TOLOWER(wca[i]);
2597 			break;
2598 		    }
2599 		}
2600 	    }
2601 
2602 	    /*
2603 	     * Rule 2: No lower case, 2nd consecutive letter converted to
2604 	     * upper case.
2605 	     */
2606 	    if (!has_lower)
2607 	    {
2608 		p = compl_orig_text;
2609 		for (i = 0; i < min_len; ++i)
2610 		{
2611 #ifdef FEAT_MBYTE
2612 		    if (has_mbyte)
2613 			c = mb_ptr2char_adv(&p);
2614 		    else
2615 #endif
2616 			c = *(p++);
2617 		    if (was_letter && MB_ISUPPER(c) && MB_ISLOWER(wca[i]))
2618 		    {
2619 			/* Rule 2 is satisfied. */
2620 			for (i = actual_compl_length; i < actual_len; ++i)
2621 			    wca[i] = MB_TOUPPER(wca[i]);
2622 			break;
2623 		    }
2624 		    was_letter = MB_ISLOWER(c) || MB_ISUPPER(c);
2625 		}
2626 	    }
2627 
2628 	    /* Copy the original case of the part we typed. */
2629 	    p = compl_orig_text;
2630 	    for (i = 0; i < min_len; ++i)
2631 	    {
2632 #ifdef FEAT_MBYTE
2633 		if (has_mbyte)
2634 		    c = mb_ptr2char_adv(&p);
2635 		else
2636 #endif
2637 		    c = *(p++);
2638 		if (MB_ISLOWER(c))
2639 		    wca[i] = MB_TOLOWER(wca[i]);
2640 		else if (MB_ISUPPER(c))
2641 		    wca[i] = MB_TOUPPER(wca[i]);
2642 	    }
2643 
2644 	    /*
2645 	     * Generate encoding specific output from wide character array.
2646 	     * Multi-byte characters can occupy up to five bytes more than
2647 	     * ASCII characters, and we also need one byte for NUL, so stay
2648 	     * six bytes away from the edge of IObuff.
2649 	     */
2650 	    p = IObuff;
2651 	    i = 0;
2652 	    while (i < actual_len && (p - IObuff + 6) < IOSIZE)
2653 #ifdef FEAT_MBYTE
2654 		if (has_mbyte)
2655 		    p += (*mb_char2bytes)(wca[i++], p);
2656 		else
2657 #endif
2658 		    *(p++) = wca[i++];
2659 	    *p = NUL;
2660 
2661 	    vim_free(wca);
2662 	}
2663 
2664 	return ins_compl_add(IObuff, len, icase, fname, NULL, dir,
2665 								flags, FALSE);
2666     }
2667     return ins_compl_add(str, len, icase, fname, NULL, dir, flags, FALSE);
2668 }
2669 
2670 /*
2671  * Add a match to the list of matches.
2672  * If the given string is already in the list of completions, then return
2673  * NOTDONE, otherwise add it to the list and return OK.  If there is an error,
2674  * maybe because alloc() returns NULL, then FAIL is returned.
2675  */
2676     static int
2677 ins_compl_add(
2678     char_u	*str,
2679     int		len,
2680     int		icase,
2681     char_u	*fname,
2682     char_u	**cptext,   /* extra text for popup menu or NULL */
2683     int		cdir,
2684     int		flags,
2685     int		adup)	    /* accept duplicate match */
2686 {
2687     compl_T	*match;
2688     int		dir = (cdir == 0 ? compl_direction : cdir);
2689 
2690     ui_breakcheck();
2691     if (got_int)
2692 	return FAIL;
2693     if (len < 0)
2694 	len = (int)STRLEN(str);
2695 
2696     /*
2697      * If the same match is already present, don't add it.
2698      */
2699     if (compl_first_match != NULL && !adup)
2700     {
2701 	match = compl_first_match;
2702 	do
2703 	{
2704 	    if (    !(match->cp_flags & ORIGINAL_TEXT)
2705 		    && STRNCMP(match->cp_str, str, len) == 0
2706 		    && match->cp_str[len] == NUL)
2707 		return NOTDONE;
2708 	    match = match->cp_next;
2709 	} while (match != NULL && match != compl_first_match);
2710     }
2711 
2712     /* Remove any popup menu before changing the list of matches. */
2713     ins_compl_del_pum();
2714 
2715     /*
2716      * Allocate a new match structure.
2717      * Copy the values to the new match structure.
2718      */
2719     match = (compl_T *)alloc_clear((unsigned)sizeof(compl_T));
2720     if (match == NULL)
2721 	return FAIL;
2722     match->cp_number = -1;
2723     if (flags & ORIGINAL_TEXT)
2724 	match->cp_number = 0;
2725     if ((match->cp_str = vim_strnsave(str, len)) == NULL)
2726     {
2727 	vim_free(match);
2728 	return FAIL;
2729     }
2730     match->cp_icase = icase;
2731 
2732     /* match-fname is:
2733      * - compl_curr_match->cp_fname if it is a string equal to fname.
2734      * - a copy of fname, FREE_FNAME is set to free later THE allocated mem.
2735      * - NULL otherwise.	--Acevedo */
2736     if (fname != NULL
2737 	    && compl_curr_match != NULL
2738 	    && compl_curr_match->cp_fname != NULL
2739 	    && STRCMP(fname, compl_curr_match->cp_fname) == 0)
2740 	match->cp_fname = compl_curr_match->cp_fname;
2741     else if (fname != NULL)
2742     {
2743 	match->cp_fname = vim_strsave(fname);
2744 	flags |= FREE_FNAME;
2745     }
2746     else
2747 	match->cp_fname = NULL;
2748     match->cp_flags = flags;
2749 
2750     if (cptext != NULL)
2751     {
2752 	int i;
2753 
2754 	for (i = 0; i < CPT_COUNT; ++i)
2755 	    if (cptext[i] != NULL && *cptext[i] != NUL)
2756 		match->cp_text[i] = vim_strsave(cptext[i]);
2757     }
2758 
2759     /*
2760      * Link the new match structure in the list of matches.
2761      */
2762     if (compl_first_match == NULL)
2763 	match->cp_next = match->cp_prev = NULL;
2764     else if (dir == FORWARD)
2765     {
2766 	match->cp_next = compl_curr_match->cp_next;
2767 	match->cp_prev = compl_curr_match;
2768     }
2769     else	/* BACKWARD */
2770     {
2771 	match->cp_next = compl_curr_match;
2772 	match->cp_prev = compl_curr_match->cp_prev;
2773     }
2774     if (match->cp_next)
2775 	match->cp_next->cp_prev = match;
2776     if (match->cp_prev)
2777 	match->cp_prev->cp_next = match;
2778     else	/* if there's nothing before, it is the first match */
2779 	compl_first_match = match;
2780     compl_curr_match = match;
2781 
2782     /*
2783      * Find the longest common string if still doing that.
2784      */
2785     if (compl_get_longest && (flags & ORIGINAL_TEXT) == 0)
2786 	ins_compl_longest_match(match);
2787 
2788     return OK;
2789 }
2790 
2791 /*
2792  * Return TRUE if "str[len]" matches with match->cp_str, considering
2793  * match->cp_icase.
2794  */
2795     static int
2796 ins_compl_equal(compl_T *match, char_u *str, int len)
2797 {
2798     if (match->cp_icase)
2799 	return STRNICMP(match->cp_str, str, (size_t)len) == 0;
2800     return STRNCMP(match->cp_str, str, (size_t)len) == 0;
2801 }
2802 
2803 /*
2804  * Reduce the longest common string for match "match".
2805  */
2806     static void
2807 ins_compl_longest_match(compl_T *match)
2808 {
2809     char_u	*p, *s;
2810     int		c1, c2;
2811     int		had_match;
2812 
2813     if (compl_leader == NULL)
2814     {
2815 	/* First match, use it as a whole. */
2816 	compl_leader = vim_strsave(match->cp_str);
2817 	if (compl_leader != NULL)
2818 	{
2819 	    had_match = (curwin->w_cursor.col > compl_col);
2820 	    ins_compl_delete();
2821 	    ins_bytes(compl_leader + ins_compl_len());
2822 	    ins_redraw(FALSE);
2823 
2824 	    /* When the match isn't there (to avoid matching itself) remove it
2825 	     * again after redrawing. */
2826 	    if (!had_match)
2827 		ins_compl_delete();
2828 	    compl_used_match = FALSE;
2829 	}
2830     }
2831     else
2832     {
2833 	/* Reduce the text if this match differs from compl_leader. */
2834 	p = compl_leader;
2835 	s = match->cp_str;
2836 	while (*p != NUL)
2837 	{
2838 #ifdef FEAT_MBYTE
2839 	    if (has_mbyte)
2840 	    {
2841 		c1 = mb_ptr2char(p);
2842 		c2 = mb_ptr2char(s);
2843 	    }
2844 	    else
2845 #endif
2846 	    {
2847 		c1 = *p;
2848 		c2 = *s;
2849 	    }
2850 	    if (match->cp_icase ? (MB_TOLOWER(c1) != MB_TOLOWER(c2))
2851 								 : (c1 != c2))
2852 		break;
2853 #ifdef FEAT_MBYTE
2854 	    if (has_mbyte)
2855 	    {
2856 		MB_PTR_ADV(p);
2857 		MB_PTR_ADV(s);
2858 	    }
2859 	    else
2860 #endif
2861 	    {
2862 		++p;
2863 		++s;
2864 	    }
2865 	}
2866 
2867 	if (*p != NUL)
2868 	{
2869 	    /* Leader was shortened, need to change the inserted text. */
2870 	    *p = NUL;
2871 	    had_match = (curwin->w_cursor.col > compl_col);
2872 	    ins_compl_delete();
2873 	    ins_bytes(compl_leader + ins_compl_len());
2874 	    ins_redraw(FALSE);
2875 
2876 	    /* When the match isn't there (to avoid matching itself) remove it
2877 	     * again after redrawing. */
2878 	    if (!had_match)
2879 		ins_compl_delete();
2880 	}
2881 
2882 	compl_used_match = FALSE;
2883     }
2884 }
2885 
2886 /*
2887  * Add an array of matches to the list of matches.
2888  * Frees matches[].
2889  */
2890     static void
2891 ins_compl_add_matches(
2892     int		num_matches,
2893     char_u	**matches,
2894     int		icase)
2895 {
2896     int		i;
2897     int		add_r = OK;
2898     int		dir = compl_direction;
2899 
2900     for (i = 0; i < num_matches && add_r != FAIL; i++)
2901 	if ((add_r = ins_compl_add(matches[i], -1, icase,
2902 					    NULL, NULL, dir, 0, FALSE)) == OK)
2903 	    /* if dir was BACKWARD then honor it just once */
2904 	    dir = FORWARD;
2905     FreeWild(num_matches, matches);
2906 }
2907 
2908 /* Make the completion list cyclic.
2909  * Return the number of matches (excluding the original).
2910  */
2911     static int
2912 ins_compl_make_cyclic(void)
2913 {
2914     compl_T *match;
2915     int	    count = 0;
2916 
2917     if (compl_first_match != NULL)
2918     {
2919 	/*
2920 	 * Find the end of the list.
2921 	 */
2922 	match = compl_first_match;
2923 	/* there's always an entry for the compl_orig_text, it doesn't count. */
2924 	while (match->cp_next != NULL && match->cp_next != compl_first_match)
2925 	{
2926 	    match = match->cp_next;
2927 	    ++count;
2928 	}
2929 	match->cp_next = compl_first_match;
2930 	compl_first_match->cp_prev = match;
2931     }
2932     return count;
2933 }
2934 
2935 /*
2936  * Set variables that store noselect and noinsert behavior from the
2937  * 'completeopt' value.
2938  */
2939     void
2940 completeopt_was_set(void)
2941 {
2942     compl_no_insert = FALSE;
2943     compl_no_select = FALSE;
2944     if (strstr((char *)p_cot, "noselect") != NULL)
2945 	compl_no_select = TRUE;
2946     if (strstr((char *)p_cot, "noinsert") != NULL)
2947 	compl_no_insert = TRUE;
2948 }
2949 
2950 /*
2951  * Start completion for the complete() function.
2952  * "startcol" is where the matched text starts (1 is first column).
2953  * "list" is the list of matches.
2954  */
2955     void
2956 set_completion(colnr_T startcol, list_T *list)
2957 {
2958     int save_w_wrow = curwin->w_wrow;
2959     int save_w_leftcol = curwin->w_leftcol;
2960 
2961     /* If already doing completions stop it. */
2962     if (ctrl_x_mode != CTRL_X_NORMAL)
2963 	ins_compl_prep(' ');
2964     ins_compl_clear();
2965     ins_compl_free();
2966 
2967     compl_direction = FORWARD;
2968     if (startcol > curwin->w_cursor.col)
2969 	startcol = curwin->w_cursor.col;
2970     compl_col = startcol;
2971     compl_length = (int)curwin->w_cursor.col - (int)startcol;
2972     /* compl_pattern doesn't need to be set */
2973     compl_orig_text = vim_strnsave(ml_get_curline() + compl_col, compl_length);
2974     if (compl_orig_text == NULL || ins_compl_add(compl_orig_text,
2975 			-1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK)
2976 	return;
2977 
2978     ctrl_x_mode = CTRL_X_EVAL;
2979 
2980     ins_compl_add_list(list);
2981     compl_matches = ins_compl_make_cyclic();
2982     compl_started = TRUE;
2983     compl_used_match = TRUE;
2984     compl_cont_status = 0;
2985 
2986     compl_curr_match = compl_first_match;
2987     if (compl_no_insert || compl_no_select)
2988     {
2989 	ins_complete(K_DOWN, FALSE);
2990 	if (compl_no_select)
2991 	    /* Down/Up has no real effect. */
2992 	    ins_complete(K_UP, FALSE);
2993     }
2994     else
2995 	ins_complete(Ctrl_N, FALSE);
2996     compl_enter_selects = compl_no_insert;
2997 
2998     /* Lazily show the popup menu, unless we got interrupted. */
2999     if (!compl_interrupted)
3000 	show_pum(save_w_wrow, save_w_leftcol);
3001     out_flush();
3002 }
3003 
3004 
3005 /* "compl_match_array" points the currently displayed list of entries in the
3006  * popup menu.  It is NULL when there is no popup menu. */
3007 static pumitem_T *compl_match_array = NULL;
3008 static int compl_match_arraysize;
3009 
3010 /*
3011  * Update the screen and when there is any scrolling remove the popup menu.
3012  */
3013     static void
3014 ins_compl_upd_pum(void)
3015 {
3016     int		h;
3017 
3018     if (compl_match_array != NULL)
3019     {
3020 	h = curwin->w_cline_height;
3021 	update_screen(0);
3022 	if (h != curwin->w_cline_height)
3023 	    ins_compl_del_pum();
3024     }
3025 }
3026 
3027 /*
3028  * Remove any popup menu.
3029  */
3030     static void
3031 ins_compl_del_pum(void)
3032 {
3033     if (compl_match_array != NULL)
3034     {
3035 	pum_undisplay();
3036 	VIM_CLEAR(compl_match_array);
3037     }
3038 }
3039 
3040 /*
3041  * Return TRUE if the popup menu should be displayed.
3042  */
3043     static int
3044 pum_wanted(void)
3045 {
3046     /* 'completeopt' must contain "menu" or "menuone" */
3047     if (vim_strchr(p_cot, 'm') == NULL)
3048 	return FALSE;
3049 
3050     /* The display looks bad on a B&W display. */
3051     if (t_colors < 8
3052 #ifdef FEAT_GUI
3053 	    && !gui.in_use
3054 #endif
3055 	    )
3056 	return FALSE;
3057     return TRUE;
3058 }
3059 
3060 /*
3061  * Return TRUE if there are two or more matches to be shown in the popup menu.
3062  * One if 'completopt' contains "menuone".
3063  */
3064     static int
3065 pum_enough_matches(void)
3066 {
3067     compl_T     *compl;
3068     int		i;
3069 
3070     /* Don't display the popup menu if there are no matches or there is only
3071      * one (ignoring the original text). */
3072     compl = compl_first_match;
3073     i = 0;
3074     do
3075     {
3076 	if (compl == NULL
3077 		      || ((compl->cp_flags & ORIGINAL_TEXT) == 0 && ++i == 2))
3078 	    break;
3079 	compl = compl->cp_next;
3080     } while (compl != compl_first_match);
3081 
3082     if (strstr((char *)p_cot, "menuone") != NULL)
3083 	return (i >= 1);
3084     return (i >= 2);
3085 }
3086 
3087 /*
3088  * Show the popup menu for the list of matches.
3089  * Also adjusts "compl_shown_match" to an entry that is actually displayed.
3090  */
3091     void
3092 ins_compl_show_pum(void)
3093 {
3094     compl_T     *compl;
3095     compl_T     *shown_compl = NULL;
3096     int		did_find_shown_match = FALSE;
3097     int		shown_match_ok = FALSE;
3098     int		i;
3099     int		cur = -1;
3100     colnr_T	col;
3101     int		lead_len = 0;
3102 
3103     if (!pum_wanted() || !pum_enough_matches())
3104 	return;
3105 
3106 #if defined(FEAT_EVAL)
3107     /* Dirty hard-coded hack: remove any matchparen highlighting. */
3108     do_cmdline_cmd((char_u *)"if exists('g:loaded_matchparen')|3match none|endif");
3109 #endif
3110 
3111     /* Update the screen before drawing the popup menu over it. */
3112     update_screen(0);
3113 
3114     if (compl_match_array == NULL)
3115     {
3116 	/* Need to build the popup menu list. */
3117 	compl_match_arraysize = 0;
3118 	compl = compl_first_match;
3119 	if (compl_leader != NULL)
3120 	    lead_len = (int)STRLEN(compl_leader);
3121 	do
3122 	{
3123 	    if ((compl->cp_flags & ORIGINAL_TEXT) == 0
3124 		    && (compl_leader == NULL
3125 			|| ins_compl_equal(compl, compl_leader, lead_len)))
3126 		++compl_match_arraysize;
3127 	    compl = compl->cp_next;
3128 	} while (compl != NULL && compl != compl_first_match);
3129 	if (compl_match_arraysize == 0)
3130 	    return;
3131 	compl_match_array = (pumitem_T *)alloc_clear(
3132 				    (unsigned)(sizeof(pumitem_T)
3133 						    * compl_match_arraysize));
3134 	if (compl_match_array != NULL)
3135 	{
3136 	    /* If the current match is the original text don't find the first
3137 	     * match after it, don't highlight anything. */
3138 	    if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
3139 		shown_match_ok = TRUE;
3140 
3141 	    i = 0;
3142 	    compl = compl_first_match;
3143 	    do
3144 	    {
3145 		if ((compl->cp_flags & ORIGINAL_TEXT) == 0
3146 			&& (compl_leader == NULL
3147 			    || ins_compl_equal(compl, compl_leader, lead_len)))
3148 		{
3149 		    if (!shown_match_ok)
3150 		    {
3151 			if (compl == compl_shown_match || did_find_shown_match)
3152 			{
3153 			    /* This item is the shown match or this is the
3154 			     * first displayed item after the shown match. */
3155 			    compl_shown_match = compl;
3156 			    did_find_shown_match = TRUE;
3157 			    shown_match_ok = TRUE;
3158 			}
3159 			else
3160 			    /* Remember this displayed match for when the
3161 			     * shown match is just below it. */
3162 			    shown_compl = compl;
3163 			cur = i;
3164 		    }
3165 
3166 		    if (compl->cp_text[CPT_ABBR] != NULL)
3167 			compl_match_array[i].pum_text =
3168 						     compl->cp_text[CPT_ABBR];
3169 		    else
3170 			compl_match_array[i].pum_text = compl->cp_str;
3171 		    compl_match_array[i].pum_kind = compl->cp_text[CPT_KIND];
3172 		    compl_match_array[i].pum_info = compl->cp_text[CPT_INFO];
3173 		    if (compl->cp_text[CPT_MENU] != NULL)
3174 			compl_match_array[i++].pum_extra =
3175 						     compl->cp_text[CPT_MENU];
3176 		    else
3177 			compl_match_array[i++].pum_extra = compl->cp_fname;
3178 		}
3179 
3180 		if (compl == compl_shown_match)
3181 		{
3182 		    did_find_shown_match = TRUE;
3183 
3184 		    /* When the original text is the shown match don't set
3185 		     * compl_shown_match. */
3186 		    if (compl->cp_flags & ORIGINAL_TEXT)
3187 			shown_match_ok = TRUE;
3188 
3189 		    if (!shown_match_ok && shown_compl != NULL)
3190 		    {
3191 			/* The shown match isn't displayed, set it to the
3192 			 * previously displayed match. */
3193 			compl_shown_match = shown_compl;
3194 			shown_match_ok = TRUE;
3195 		    }
3196 		}
3197 		compl = compl->cp_next;
3198 	    } while (compl != NULL && compl != compl_first_match);
3199 
3200 	    if (!shown_match_ok)    /* no displayed match at all */
3201 		cur = -1;
3202 	}
3203     }
3204     else
3205     {
3206 	/* popup menu already exists, only need to find the current item.*/
3207 	for (i = 0; i < compl_match_arraysize; ++i)
3208 	    if (compl_match_array[i].pum_text == compl_shown_match->cp_str
3209 		    || compl_match_array[i].pum_text
3210 				      == compl_shown_match->cp_text[CPT_ABBR])
3211 	    {
3212 		cur = i;
3213 		break;
3214 	    }
3215     }
3216 
3217     if (compl_match_array != NULL)
3218     {
3219 	/* In Replace mode when a $ is displayed at the end of the line only
3220 	 * part of the screen would be updated.  We do need to redraw here. */
3221 	dollar_vcol = -1;
3222 
3223 	/* Compute the screen column of the start of the completed text.
3224 	 * Use the cursor to get all wrapping and other settings right. */
3225 	col = curwin->w_cursor.col;
3226 	curwin->w_cursor.col = compl_col;
3227 	pum_display(compl_match_array, compl_match_arraysize, cur);
3228 	curwin->w_cursor.col = col;
3229     }
3230 }
3231 
3232 #define DICT_FIRST	(1)	/* use just first element in "dict" */
3233 #define DICT_EXACT	(2)	/* "dict" is the exact name of a file */
3234 
3235 /*
3236  * Add any identifiers that match the given pattern in the list of dictionary
3237  * files "dict_start" to the list of completions.
3238  */
3239     static void
3240 ins_compl_dictionaries(
3241     char_u	*dict_start,
3242     char_u	*pat,
3243     int		flags,		/* DICT_FIRST and/or DICT_EXACT */
3244     int		thesaurus)	/* Thesaurus completion */
3245 {
3246     char_u	*dict = dict_start;
3247     char_u	*ptr;
3248     char_u	*buf;
3249     regmatch_T	regmatch;
3250     char_u	**files;
3251     int		count;
3252     int		save_p_scs;
3253     int		dir = compl_direction;
3254 
3255     if (*dict == NUL)
3256     {
3257 #ifdef FEAT_SPELL
3258 	/* When 'dictionary' is empty and spell checking is enabled use
3259 	 * "spell". */
3260 	if (!thesaurus && curwin->w_p_spell)
3261 	    dict = (char_u *)"spell";
3262 	else
3263 #endif
3264 	    return;
3265     }
3266 
3267     buf = alloc(LSIZE);
3268     if (buf == NULL)
3269 	return;
3270     regmatch.regprog = NULL;	/* so that we can goto theend */
3271 
3272     /* If 'infercase' is set, don't use 'smartcase' here */
3273     save_p_scs = p_scs;
3274     if (curbuf->b_p_inf)
3275 	p_scs = FALSE;
3276 
3277     /* When invoked to match whole lines for CTRL-X CTRL-L adjust the pattern
3278      * to only match at the start of a line.  Otherwise just match the
3279      * pattern. Also need to double backslashes. */
3280     if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
3281     {
3282 	char_u *pat_esc = vim_strsave_escaped(pat, (char_u *)"\\");
3283 	size_t len;
3284 
3285 	if (pat_esc == NULL)
3286 	    goto theend;
3287 	len = STRLEN(pat_esc) + 10;
3288 	ptr = alloc((unsigned)len);
3289 	if (ptr == NULL)
3290 	{
3291 	    vim_free(pat_esc);
3292 	    goto theend;
3293 	}
3294 	vim_snprintf((char *)ptr, len, "^\\s*\\zs\\V%s", pat_esc);
3295 	regmatch.regprog = vim_regcomp(ptr, RE_MAGIC);
3296 	vim_free(pat_esc);
3297 	vim_free(ptr);
3298     }
3299     else
3300     {
3301 	regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0);
3302 	if (regmatch.regprog == NULL)
3303 	    goto theend;
3304     }
3305 
3306     /* ignore case depends on 'ignorecase', 'smartcase' and "pat" */
3307     regmatch.rm_ic = ignorecase(pat);
3308     while (*dict != NUL && !got_int && !compl_interrupted)
3309     {
3310 	/* copy one dictionary file name into buf */
3311 	if (flags == DICT_EXACT)
3312 	{
3313 	    count = 1;
3314 	    files = &dict;
3315 	}
3316 	else
3317 	{
3318 	    /* Expand wildcards in the dictionary name, but do not allow
3319 	     * backticks (for security, the 'dict' option may have been set in
3320 	     * a modeline). */
3321 	    copy_option_part(&dict, buf, LSIZE, ",");
3322 # ifdef FEAT_SPELL
3323 	    if (!thesaurus && STRCMP(buf, "spell") == 0)
3324 		count = -1;
3325 	    else
3326 # endif
3327 		if (vim_strchr(buf, '`') != NULL
3328 		    || expand_wildcards(1, &buf, &count, &files,
3329 						     EW_FILE|EW_SILENT) != OK)
3330 		count = 0;
3331 	}
3332 
3333 # ifdef FEAT_SPELL
3334 	if (count == -1)
3335 	{
3336 	    /* Complete from active spelling.  Skip "\<" in the pattern, we
3337 	     * don't use it as a RE. */
3338 	    if (pat[0] == '\\' && pat[1] == '<')
3339 		ptr = pat + 2;
3340 	    else
3341 		ptr = pat;
3342 	    spell_dump_compl(ptr, regmatch.rm_ic, &dir, 0);
3343 	}
3344 	else
3345 # endif
3346 	    if (count > 0)	/* avoid warning for using "files" uninit */
3347 	{
3348 	    ins_compl_files(count, files, thesaurus, flags,
3349 							&regmatch, buf, &dir);
3350 	    if (flags != DICT_EXACT)
3351 		FreeWild(count, files);
3352 	}
3353 	if (flags != 0)
3354 	    break;
3355     }
3356 
3357 theend:
3358     p_scs = save_p_scs;
3359     vim_regfree(regmatch.regprog);
3360     vim_free(buf);
3361 }
3362 
3363     static void
3364 ins_compl_files(
3365     int		count,
3366     char_u	**files,
3367     int		thesaurus,
3368     int		flags,
3369     regmatch_T	*regmatch,
3370     char_u	*buf,
3371     int		*dir)
3372 {
3373     char_u	*ptr;
3374     int		i;
3375     FILE	*fp;
3376     int		add_r;
3377 
3378     for (i = 0; i < count && !got_int && !compl_interrupted; i++)
3379     {
3380 	fp = mch_fopen((char *)files[i], "r");  /* open dictionary file */
3381 	if (flags != DICT_EXACT)
3382 	{
3383 	    vim_snprintf((char *)IObuff, IOSIZE,
3384 			      _("Scanning dictionary: %s"), (char *)files[i]);
3385 	    (void)msg_trunc_attr(IObuff, TRUE, HL_ATTR(HLF_R));
3386 	}
3387 
3388 	if (fp != NULL)
3389 	{
3390 	    /*
3391 	     * Read dictionary file line by line.
3392 	     * Check each line for a match.
3393 	     */
3394 	    while (!got_int && !compl_interrupted
3395 					    && !vim_fgets(buf, LSIZE, fp))
3396 	    {
3397 		ptr = buf;
3398 		while (vim_regexec(regmatch, buf, (colnr_T)(ptr - buf)))
3399 		{
3400 		    ptr = regmatch->startp[0];
3401 		    if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
3402 			ptr = find_line_end(ptr);
3403 		    else
3404 			ptr = find_word_end(ptr);
3405 		    add_r = ins_compl_add_infercase(regmatch->startp[0],
3406 					  (int)(ptr - regmatch->startp[0]),
3407 						     p_ic, files[i], *dir, 0);
3408 		    if (thesaurus)
3409 		    {
3410 			char_u *wstart;
3411 
3412 			/*
3413 			 * Add the other matches on the line
3414 			 */
3415 			ptr = buf;
3416 			while (!got_int)
3417 			{
3418 			    /* Find start of the next word.  Skip white
3419 			     * space and punctuation. */
3420 			    ptr = find_word_start(ptr);
3421 			    if (*ptr == NUL || *ptr == NL)
3422 				break;
3423 			    wstart = ptr;
3424 
3425 			    /* Find end of the word. */
3426 #ifdef FEAT_MBYTE
3427 			    if (has_mbyte)
3428 				/* Japanese words may have characters in
3429 				 * different classes, only separate words
3430 				 * with single-byte non-word characters. */
3431 				while (*ptr != NUL)
3432 				{
3433 				    int l = (*mb_ptr2len)(ptr);
3434 
3435 				    if (l < 2 && !vim_iswordc(*ptr))
3436 					break;
3437 				    ptr += l;
3438 				}
3439 			    else
3440 #endif
3441 				ptr = find_word_end(ptr);
3442 
3443 			    /* Add the word. Skip the regexp match. */
3444 			    if (wstart != regmatch->startp[0])
3445 				add_r = ins_compl_add_infercase(wstart,
3446 					(int)(ptr - wstart),
3447 					p_ic, files[i], *dir, 0);
3448 			}
3449 		    }
3450 		    if (add_r == OK)
3451 			/* if dir was BACKWARD then honor it just once */
3452 			*dir = FORWARD;
3453 		    else if (add_r == FAIL)
3454 			break;
3455 		    /* avoid expensive call to vim_regexec() when at end
3456 		     * of line */
3457 		    if (*ptr == '\n' || got_int)
3458 			break;
3459 		}
3460 		line_breakcheck();
3461 		ins_compl_check_keys(50, FALSE);
3462 	    }
3463 	    fclose(fp);
3464 	}
3465     }
3466 }
3467 
3468 /*
3469  * Find the start of the next word.
3470  * Returns a pointer to the first char of the word.  Also stops at a NUL.
3471  */
3472     char_u *
3473 find_word_start(char_u *ptr)
3474 {
3475 #ifdef FEAT_MBYTE
3476     if (has_mbyte)
3477 	while (*ptr != NUL && *ptr != '\n' && mb_get_class(ptr) <= 1)
3478 	    ptr += (*mb_ptr2len)(ptr);
3479     else
3480 #endif
3481 	while (*ptr != NUL && *ptr != '\n' && !vim_iswordc(*ptr))
3482 	    ++ptr;
3483     return ptr;
3484 }
3485 
3486 /*
3487  * Find the end of the word.  Assumes it starts inside a word.
3488  * Returns a pointer to just after the word.
3489  */
3490     char_u *
3491 find_word_end(char_u *ptr)
3492 {
3493 #ifdef FEAT_MBYTE
3494     int		start_class;
3495 
3496     if (has_mbyte)
3497     {
3498 	start_class = mb_get_class(ptr);
3499 	if (start_class > 1)
3500 	    while (*ptr != NUL)
3501 	    {
3502 		ptr += (*mb_ptr2len)(ptr);
3503 		if (mb_get_class(ptr) != start_class)
3504 		    break;
3505 	    }
3506     }
3507     else
3508 #endif
3509 	while (vim_iswordc(*ptr))
3510 	    ++ptr;
3511     return ptr;
3512 }
3513 
3514 /*
3515  * Find the end of the line, omitting CR and NL at the end.
3516  * Returns a pointer to just after the line.
3517  */
3518     static char_u *
3519 find_line_end(char_u *ptr)
3520 {
3521     char_u	*s;
3522 
3523     s = ptr + STRLEN(ptr);
3524     while (s > ptr && (s[-1] == CAR || s[-1] == NL))
3525 	--s;
3526     return s;
3527 }
3528 
3529 /*
3530  * Free the list of completions
3531  */
3532     static void
3533 ins_compl_free(void)
3534 {
3535     compl_T *match;
3536     int	    i;
3537 
3538     VIM_CLEAR(compl_pattern);
3539     VIM_CLEAR(compl_leader);
3540 
3541     if (compl_first_match == NULL)
3542 	return;
3543 
3544     ins_compl_del_pum();
3545     pum_clear();
3546 
3547     compl_curr_match = compl_first_match;
3548     do
3549     {
3550 	match = compl_curr_match;
3551 	compl_curr_match = compl_curr_match->cp_next;
3552 	vim_free(match->cp_str);
3553 	/* several entries may use the same fname, free it just once. */
3554 	if (match->cp_flags & FREE_FNAME)
3555 	    vim_free(match->cp_fname);
3556 	for (i = 0; i < CPT_COUNT; ++i)
3557 	    vim_free(match->cp_text[i]);
3558 	vim_free(match);
3559     } while (compl_curr_match != NULL && compl_curr_match != compl_first_match);
3560     compl_first_match = compl_curr_match = NULL;
3561     compl_shown_match = NULL;
3562     compl_old_match = NULL;
3563 }
3564 
3565     static void
3566 ins_compl_clear(void)
3567 {
3568     compl_cont_status = 0;
3569     compl_started = FALSE;
3570     compl_matches = 0;
3571     VIM_CLEAR(compl_pattern);
3572     VIM_CLEAR(compl_leader);
3573     edit_submode_extra = NULL;
3574     VIM_CLEAR(compl_orig_text);
3575     compl_enter_selects = FALSE;
3576     /* clear v:completed_item */
3577     set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED));
3578 }
3579 
3580 /*
3581  * Return TRUE when Insert completion is active.
3582  */
3583     int
3584 ins_compl_active(void)
3585 {
3586     return compl_started;
3587 }
3588 
3589 /*
3590  * Delete one character before the cursor and show the subset of the matches
3591  * that match the word that is now before the cursor.
3592  * Returns the character to be used, NUL if the work is done and another char
3593  * to be got from the user.
3594  */
3595     static int
3596 ins_compl_bs(void)
3597 {
3598     char_u	*line;
3599     char_u	*p;
3600 
3601     line = ml_get_curline();
3602     p = line + curwin->w_cursor.col;
3603     MB_PTR_BACK(line, p);
3604 
3605     /* Stop completion when the whole word was deleted.  For Omni completion
3606      * allow the word to be deleted, we won't match everything.
3607      * Respect the 'backspace' option. */
3608     if ((int)(p - line) - (int)compl_col < 0
3609 	    || ((int)(p - line) - (int)compl_col == 0
3610 		&& ctrl_x_mode != CTRL_X_OMNI) || ctrl_x_mode == CTRL_X_EVAL
3611 	    || (!can_bs(BS_START) && (int)(p - line) - (int)compl_col
3612 							- compl_length < 0))
3613 	return K_BS;
3614 
3615     /* Deleted more than what was used to find matches or didn't finish
3616      * finding all matches: need to look for matches all over again. */
3617     if (curwin->w_cursor.col <= compl_col + compl_length
3618 						  || ins_compl_need_restart())
3619 	ins_compl_restart();
3620 
3621     vim_free(compl_leader);
3622     compl_leader = vim_strnsave(line + compl_col, (int)(p - line) - compl_col);
3623     if (compl_leader != NULL)
3624     {
3625 	ins_compl_new_leader();
3626 	if (compl_shown_match != NULL)
3627 	    /* Make sure current match is not a hidden item. */
3628 	    compl_curr_match = compl_shown_match;
3629 	return NUL;
3630     }
3631     return K_BS;
3632 }
3633 
3634 /*
3635  * Return TRUE when we need to find matches again, ins_compl_restart() is to
3636  * be called.
3637  */
3638     static int
3639 ins_compl_need_restart(void)
3640 {
3641     /* Return TRUE if we didn't complete finding matches or when the
3642      * 'completefunc' returned "always" in the "refresh" dictionary item. */
3643     return compl_was_interrupted
3644 	|| ((ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI)
3645 						  && compl_opt_refresh_always);
3646 }
3647 
3648 /*
3649  * Called after changing "compl_leader".
3650  * Show the popup menu with a different set of matches.
3651  * May also search for matches again if the previous search was interrupted.
3652  */
3653     static void
3654 ins_compl_new_leader(void)
3655 {
3656     ins_compl_del_pum();
3657     ins_compl_delete();
3658     ins_bytes(compl_leader + ins_compl_len());
3659     compl_used_match = FALSE;
3660 
3661     if (compl_started)
3662 	ins_compl_set_original_text(compl_leader);
3663     else
3664     {
3665 #ifdef FEAT_SPELL
3666 	spell_bad_len = 0;	/* need to redetect bad word */
3667 #endif
3668 	/*
3669 	 * Matches were cleared, need to search for them now.  First display
3670 	 * the changed text before the cursor.  Set "compl_restarting" to
3671 	 * avoid that the first match is inserted.
3672 	 */
3673 	update_screen(0);
3674 #ifdef FEAT_GUI
3675 	if (gui.in_use)
3676 	{
3677 	    /* Show the cursor after the match, not after the redrawn text. */
3678 	    setcursor();
3679 	    out_flush_cursor(FALSE, FALSE);
3680 	}
3681 #endif
3682 	compl_restarting = TRUE;
3683 	if (ins_complete(Ctrl_N, TRUE) == FAIL)
3684 	    compl_cont_status = 0;
3685 	compl_restarting = FALSE;
3686     }
3687 
3688     compl_enter_selects = !compl_used_match;
3689 
3690     /* Show the popup menu with a different set of matches. */
3691     ins_compl_show_pum();
3692 
3693     /* Don't let Enter select the original text when there is no popup menu. */
3694     if (compl_match_array == NULL)
3695 	compl_enter_selects = FALSE;
3696 }
3697 
3698 /*
3699  * Return the length of the completion, from the completion start column to
3700  * the cursor column.  Making sure it never goes below zero.
3701  */
3702     static int
3703 ins_compl_len(void)
3704 {
3705     int off = (int)curwin->w_cursor.col - (int)compl_col;
3706 
3707     if (off < 0)
3708 	return 0;
3709     return off;
3710 }
3711 
3712 /*
3713  * Append one character to the match leader.  May reduce the number of
3714  * matches.
3715  */
3716     static void
3717 ins_compl_addleader(int c)
3718 {
3719 #ifdef FEAT_MBYTE
3720     int		cc;
3721 #endif
3722 
3723     if (stop_arrow() == FAIL)
3724 	return;
3725 #ifdef FEAT_MBYTE
3726     if (has_mbyte && (cc = (*mb_char2len)(c)) > 1)
3727     {
3728 	char_u	buf[MB_MAXBYTES + 1];
3729 
3730 	(*mb_char2bytes)(c, buf);
3731 	buf[cc] = NUL;
3732 	ins_char_bytes(buf, cc);
3733 	if (compl_opt_refresh_always)
3734 	    AppendToRedobuff(buf);
3735     }
3736     else
3737 #endif
3738     {
3739 	ins_char(c);
3740 	if (compl_opt_refresh_always)
3741 	    AppendCharToRedobuff(c);
3742     }
3743 
3744     /* If we didn't complete finding matches we must search again. */
3745     if (ins_compl_need_restart())
3746 	ins_compl_restart();
3747 
3748     /* When 'always' is set, don't reset compl_leader. While completing,
3749      * cursor doesn't point original position, changing compl_leader would
3750      * break redo. */
3751     if (!compl_opt_refresh_always)
3752     {
3753 	vim_free(compl_leader);
3754 	compl_leader = vim_strnsave(ml_get_curline() + compl_col,
3755 				     (int)(curwin->w_cursor.col - compl_col));
3756 	if (compl_leader != NULL)
3757 	    ins_compl_new_leader();
3758     }
3759 }
3760 
3761 /*
3762  * Setup for finding completions again without leaving CTRL-X mode.  Used when
3763  * BS or a key was typed while still searching for matches.
3764  */
3765     static void
3766 ins_compl_restart(void)
3767 {
3768     ins_compl_free();
3769     compl_started = FALSE;
3770     compl_matches = 0;
3771     compl_cont_status = 0;
3772     compl_cont_mode = 0;
3773 }
3774 
3775 /*
3776  * Set the first match, the original text.
3777  */
3778     static void
3779 ins_compl_set_original_text(char_u *str)
3780 {
3781     char_u	*p;
3782 
3783     /* Replace the original text entry.
3784      * The ORIGINAL_TEXT flag is either at the first item or might possibly be
3785      * at the last item for backward completion */
3786     if (compl_first_match->cp_flags & ORIGINAL_TEXT)	/* safety check */
3787     {
3788 	p = vim_strsave(str);
3789 	if (p != NULL)
3790 	{
3791 	    vim_free(compl_first_match->cp_str);
3792 	    compl_first_match->cp_str = p;
3793 	}
3794     }
3795     else if (compl_first_match->cp_prev != NULL
3796 	    && (compl_first_match->cp_prev->cp_flags & ORIGINAL_TEXT))
3797     {
3798        p = vim_strsave(str);
3799        if (p != NULL)
3800        {
3801            vim_free(compl_first_match->cp_prev->cp_str);
3802            compl_first_match->cp_prev->cp_str = p;
3803        }
3804     }
3805 }
3806 
3807 /*
3808  * Append one character to the match leader.  May reduce the number of
3809  * matches.
3810  */
3811     static void
3812 ins_compl_addfrommatch(void)
3813 {
3814     char_u	*p;
3815     int		len = (int)curwin->w_cursor.col - (int)compl_col;
3816     int		c;
3817     compl_T	*cp;
3818 
3819     p = compl_shown_match->cp_str;
3820     if ((int)STRLEN(p) <= len)   /* the match is too short */
3821     {
3822 	/* When still at the original match use the first entry that matches
3823 	 * the leader. */
3824 	if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
3825 	{
3826 	    p = NULL;
3827 	    for (cp = compl_shown_match->cp_next; cp != NULL
3828 				 && cp != compl_first_match; cp = cp->cp_next)
3829 	    {
3830 		if (compl_leader == NULL
3831 			|| ins_compl_equal(cp, compl_leader,
3832 						   (int)STRLEN(compl_leader)))
3833 		{
3834 		    p = cp->cp_str;
3835 		    break;
3836 		}
3837 	    }
3838 	    if (p == NULL || (int)STRLEN(p) <= len)
3839 		return;
3840 	}
3841 	else
3842 	    return;
3843     }
3844     p += len;
3845     c = PTR2CHAR(p);
3846     ins_compl_addleader(c);
3847 }
3848 
3849 /*
3850  * Prepare for Insert mode completion, or stop it.
3851  * Called just after typing a character in Insert mode.
3852  * Returns TRUE when the character is not to be inserted;
3853  */
3854     static int
3855 ins_compl_prep(int c)
3856 {
3857     char_u	*ptr;
3858     int		want_cindent;
3859     int		retval = FALSE;
3860 
3861     /* Forget any previous 'special' messages if this is actually
3862      * a ^X mode key - bar ^R, in which case we wait to see what it gives us.
3863      */
3864     if (c != Ctrl_R && vim_is_ctrl_x_key(c))
3865 	edit_submode_extra = NULL;
3866 
3867     /* Ignore end of Select mode mapping and mouse scroll buttons. */
3868     if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP
3869 	    || c == K_MOUSELEFT || c == K_MOUSERIGHT)
3870 	return retval;
3871 
3872     /* Set "compl_get_longest" when finding the first matches. */
3873     if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET
3874 			   || (ctrl_x_mode == CTRL_X_NORMAL && !compl_started))
3875     {
3876 	compl_get_longest = (strstr((char *)p_cot, "longest") != NULL);
3877 	compl_used_match = TRUE;
3878 
3879     }
3880 
3881     if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET)
3882     {
3883 	/*
3884 	 * We have just typed CTRL-X and aren't quite sure which CTRL-X mode
3885 	 * it will be yet.  Now we decide.
3886 	 */
3887 	switch (c)
3888 	{
3889 	    case Ctrl_E:
3890 	    case Ctrl_Y:
3891 		ctrl_x_mode = CTRL_X_SCROLL;
3892 		if (!(State & REPLACE_FLAG))
3893 		    edit_submode = (char_u *)_(" (insert) Scroll (^E/^Y)");
3894 		else
3895 		    edit_submode = (char_u *)_(" (replace) Scroll (^E/^Y)");
3896 		edit_submode_pre = NULL;
3897 		showmode();
3898 		break;
3899 	    case Ctrl_L:
3900 		ctrl_x_mode = CTRL_X_WHOLE_LINE;
3901 		break;
3902 	    case Ctrl_F:
3903 		ctrl_x_mode = CTRL_X_FILES;
3904 		break;
3905 	    case Ctrl_K:
3906 		ctrl_x_mode = CTRL_X_DICTIONARY;
3907 		break;
3908 	    case Ctrl_R:
3909 		/* Simply allow ^R to happen without affecting ^X mode */
3910 		break;
3911 	    case Ctrl_T:
3912 		ctrl_x_mode = CTRL_X_THESAURUS;
3913 		break;
3914 #ifdef FEAT_COMPL_FUNC
3915 	    case Ctrl_U:
3916 		ctrl_x_mode = CTRL_X_FUNCTION;
3917 		break;
3918 	    case Ctrl_O:
3919 		ctrl_x_mode = CTRL_X_OMNI;
3920 		break;
3921 #endif
3922 	    case 's':
3923 	    case Ctrl_S:
3924 		ctrl_x_mode = CTRL_X_SPELL;
3925 #ifdef FEAT_SPELL
3926 		++emsg_off;	/* Avoid getting the E756 error twice. */
3927 		spell_back_to_badword();
3928 		--emsg_off;
3929 #endif
3930 		break;
3931 	    case Ctrl_RSB:
3932 		ctrl_x_mode = CTRL_X_TAGS;
3933 		break;
3934 #ifdef FEAT_FIND_ID
3935 	    case Ctrl_I:
3936 	    case K_S_TAB:
3937 		ctrl_x_mode = CTRL_X_PATH_PATTERNS;
3938 		break;
3939 	    case Ctrl_D:
3940 		ctrl_x_mode = CTRL_X_PATH_DEFINES;
3941 		break;
3942 #endif
3943 	    case Ctrl_V:
3944 	    case Ctrl_Q:
3945 		ctrl_x_mode = CTRL_X_CMDLINE;
3946 		break;
3947 	    case Ctrl_P:
3948 	    case Ctrl_N:
3949 		/* ^X^P means LOCAL expansion if nothing interrupted (eg we
3950 		 * just started ^X mode, or there were enough ^X's to cancel
3951 		 * the previous mode, say ^X^F^X^X^P or ^P^X^X^X^P, see below)
3952 		 * do normal expansion when interrupting a different mode (say
3953 		 * ^X^F^X^P or ^P^X^X^P, see below)
3954 		 * nothing changes if interrupting mode 0, (eg, the flag
3955 		 * doesn't change when going to ADDING mode  -- Acevedo */
3956 		if (!(compl_cont_status & CONT_INTRPT))
3957 		    compl_cont_status |= CONT_LOCAL;
3958 		else if (compl_cont_mode != 0)
3959 		    compl_cont_status &= ~CONT_LOCAL;
3960 		/* FALLTHROUGH */
3961 	    default:
3962 		/* If we have typed at least 2 ^X's... for modes != 0, we set
3963 		 * compl_cont_status = 0 (eg, as if we had just started ^X
3964 		 * mode).
3965 		 * For mode 0, we set "compl_cont_mode" to an impossible
3966 		 * value, in both cases ^X^X can be used to restart the same
3967 		 * mode (avoiding ADDING mode).
3968 		 * Undocumented feature: In a mode != 0 ^X^P and ^X^X^P start
3969 		 * 'complete' and local ^P expansions respectively.
3970 		 * In mode 0 an extra ^X is needed since ^X^P goes to ADDING
3971 		 * mode  -- Acevedo */
3972 		if (c == Ctrl_X)
3973 		{
3974 		    if (compl_cont_mode != 0)
3975 			compl_cont_status = 0;
3976 		    else
3977 			compl_cont_mode = CTRL_X_NOT_DEFINED_YET;
3978 		}
3979 		ctrl_x_mode = CTRL_X_NORMAL;
3980 		edit_submode = NULL;
3981 		showmode();
3982 		break;
3983 	}
3984     }
3985     else if (ctrl_x_mode != CTRL_X_NORMAL)
3986     {
3987 	/* We're already in CTRL-X mode, do we stay in it? */
3988 	if (!vim_is_ctrl_x_key(c))
3989 	{
3990 	    if (ctrl_x_mode == CTRL_X_SCROLL)
3991 		ctrl_x_mode = CTRL_X_NORMAL;
3992 	    else
3993 		ctrl_x_mode = CTRL_X_FINISHED;
3994 	    edit_submode = NULL;
3995 	}
3996 	showmode();
3997     }
3998 
3999     if (compl_started || ctrl_x_mode == CTRL_X_FINISHED)
4000     {
4001 	/* Show error message from attempted keyword completion (probably
4002 	 * 'Pattern not found') until another key is hit, then go back to
4003 	 * showing what mode we are in. */
4004 	showmode();
4005 	if ((ctrl_x_mode == CTRL_X_NORMAL && c != Ctrl_N && c != Ctrl_P
4006 				       && c != Ctrl_R && !ins_compl_pum_key(c))
4007 		|| ctrl_x_mode == CTRL_X_FINISHED)
4008 	{
4009 	    /* Get here when we have finished typing a sequence of ^N and
4010 	     * ^P or other completion characters in CTRL-X mode.  Free up
4011 	     * memory that was used, and make sure we can redo the insert. */
4012 	    if (compl_curr_match != NULL || compl_leader != NULL || c == Ctrl_E)
4013 	    {
4014 		/*
4015 		 * If any of the original typed text has been changed, eg when
4016 		 * ignorecase is set, we must add back-spaces to the redo
4017 		 * buffer.  We add as few as necessary to delete just the part
4018 		 * of the original text that has changed.
4019 		 * When using the longest match, edited the match or used
4020 		 * CTRL-E then don't use the current match.
4021 		 */
4022 		if (compl_curr_match != NULL && compl_used_match && c != Ctrl_E)
4023 		    ptr = compl_curr_match->cp_str;
4024 		else
4025 		    ptr = NULL;
4026 		ins_compl_fixRedoBufForLeader(ptr);
4027 	    }
4028 
4029 #ifdef FEAT_CINDENT
4030 	    want_cindent = (can_cindent && cindent_on());
4031 #endif
4032 	    /*
4033 	     * When completing whole lines: fix indent for 'cindent'.
4034 	     * Otherwise, break line if it's too long.
4035 	     */
4036 	    if (compl_cont_mode == CTRL_X_WHOLE_LINE)
4037 	    {
4038 #ifdef FEAT_CINDENT
4039 		/* re-indent the current line */
4040 		if (want_cindent)
4041 		{
4042 		    do_c_expr_indent();
4043 		    want_cindent = FALSE;	/* don't do it again */
4044 		}
4045 #endif
4046 	    }
4047 	    else
4048 	    {
4049 		int prev_col = curwin->w_cursor.col;
4050 
4051 		/* put the cursor on the last char, for 'tw' formatting */
4052 		if (prev_col > 0)
4053 		    dec_cursor();
4054 		/* only format when something was inserted */
4055 		if (!arrow_used && !ins_need_undo && c != Ctrl_E)
4056 		    insertchar(NUL, 0, -1);
4057 		if (prev_col > 0
4058 			     && ml_get_curline()[curwin->w_cursor.col] != NUL)
4059 		    inc_cursor();
4060 	    }
4061 
4062 	    /* If the popup menu is displayed pressing CTRL-Y means accepting
4063 	     * the selection without inserting anything.  When
4064 	     * compl_enter_selects is set the Enter key does the same. */
4065 	    if ((c == Ctrl_Y || (compl_enter_selects
4066 				   && (c == CAR || c == K_KENTER || c == NL)))
4067 		    && pum_visible())
4068 		retval = TRUE;
4069 
4070 	    /* CTRL-E means completion is Ended, go back to the typed text.
4071 	     * but only do this, if the Popup is still visible */
4072 	    if (c == Ctrl_E)
4073 	    {
4074 		ins_compl_delete();
4075 		if (compl_leader != NULL)
4076 		    ins_bytes(compl_leader + ins_compl_len());
4077 		else if (compl_first_match != NULL)
4078 		    ins_bytes(compl_orig_text + ins_compl_len());
4079 		retval = TRUE;
4080 	    }
4081 
4082 	    auto_format(FALSE, TRUE);
4083 
4084 	    ins_compl_free();
4085 	    compl_started = FALSE;
4086 	    compl_matches = 0;
4087 	    if (!shortmess(SHM_COMPLETIONMENU))
4088 		msg_clr_cmdline();	/* necessary for "noshowmode" */
4089 	    ctrl_x_mode = CTRL_X_NORMAL;
4090 	    compl_enter_selects = FALSE;
4091 	    if (edit_submode != NULL)
4092 	    {
4093 		edit_submode = NULL;
4094 		showmode();
4095 	    }
4096 
4097 #ifdef FEAT_CMDWIN
4098 	    if (c == Ctrl_C && cmdwin_type != 0)
4099 		/* Avoid the popup menu remains displayed when leaving the
4100 		 * command line window. */
4101 		update_screen(0);
4102 #endif
4103 #ifdef FEAT_CINDENT
4104 	    /*
4105 	     * Indent now if a key was typed that is in 'cinkeys'.
4106 	     */
4107 	    if (want_cindent && in_cinkeys(KEY_COMPLETE, ' ', inindent(0)))
4108 		do_c_expr_indent();
4109 #endif
4110 	    /* Trigger the CompleteDone event to give scripts a chance to act
4111 	     * upon the completion. */
4112 	    ins_apply_autocmds(EVENT_COMPLETEDONE);
4113 	}
4114     }
4115     else if (ctrl_x_mode == CTRL_X_LOCAL_MSG)
4116 	/* Trigger the CompleteDone event to give scripts a chance to act
4117 	 * upon the (possibly failed) completion. */
4118 	ins_apply_autocmds(EVENT_COMPLETEDONE);
4119 
4120     /* reset continue_* if we left expansion-mode, if we stay they'll be
4121      * (re)set properly in ins_complete() */
4122     if (!vim_is_ctrl_x_key(c))
4123     {
4124 	compl_cont_status = 0;
4125 	compl_cont_mode = 0;
4126     }
4127 
4128     return retval;
4129 }
4130 
4131 /*
4132  * Fix the redo buffer for the completion leader replacing some of the typed
4133  * text.  This inserts backspaces and appends the changed text.
4134  * "ptr" is the known leader text or NUL.
4135  */
4136     static void
4137 ins_compl_fixRedoBufForLeader(char_u *ptr_arg)
4138 {
4139     int	    len;
4140     char_u  *p;
4141     char_u  *ptr = ptr_arg;
4142 
4143     if (ptr == NULL)
4144     {
4145 	if (compl_leader != NULL)
4146 	    ptr = compl_leader;
4147 	else
4148 	    return;  /* nothing to do */
4149     }
4150     if (compl_orig_text != NULL)
4151     {
4152 	p = compl_orig_text;
4153 	for (len = 0; p[len] != NUL && p[len] == ptr[len]; ++len)
4154 	    ;
4155 #ifdef FEAT_MBYTE
4156 	if (len > 0)
4157 	    len -= (*mb_head_off)(p, p + len);
4158 #endif
4159 	for (p += len; *p != NUL; MB_PTR_ADV(p))
4160 	    AppendCharToRedobuff(K_BS);
4161     }
4162     else
4163 	len = 0;
4164     if (ptr != NULL)
4165 	AppendToRedobuffLit(ptr + len, -1);
4166 }
4167 
4168 /*
4169  * Loops through the list of windows, loaded-buffers or non-loaded-buffers
4170  * (depending on flag) starting from buf and looking for a non-scanned
4171  * buffer (other than curbuf).	curbuf is special, if it is called with
4172  * buf=curbuf then it has to be the first call for a given flag/expansion.
4173  *
4174  * Returns the buffer to scan, if any, otherwise returns curbuf -- Acevedo
4175  */
4176     static buf_T *
4177 ins_compl_next_buf(buf_T *buf, int flag)
4178 {
4179     static win_T *wp;
4180 
4181     if (flag == 'w')		/* just windows */
4182     {
4183 	if (buf == curbuf)	/* first call for this flag/expansion */
4184 	    wp = curwin;
4185 	while ((wp = (wp->w_next != NULL ? wp->w_next : firstwin)) != curwin
4186 		&& wp->w_buffer->b_scanned)
4187 	    ;
4188 	buf = wp->w_buffer;
4189     }
4190     else
4191 	/* 'b' (just loaded buffers), 'u' (just non-loaded buffers) or 'U'
4192 	 * (unlisted buffers)
4193 	 * When completing whole lines skip unloaded buffers. */
4194 	while ((buf = (buf->b_next != NULL ? buf->b_next : firstbuf)) != curbuf
4195 		&& ((flag == 'U'
4196 			? buf->b_p_bl
4197 			: (!buf->b_p_bl
4198 			    || (buf->b_ml.ml_mfp == NULL) != (flag == 'u')))
4199 		    || buf->b_scanned))
4200 	    ;
4201     return buf;
4202 }
4203 
4204 #ifdef FEAT_COMPL_FUNC
4205 /*
4206  * Execute user defined complete function 'completefunc' or 'omnifunc', and
4207  * get matches in "matches".
4208  */
4209     static void
4210 expand_by_function(
4211     int		type,	    /* CTRL_X_OMNI or CTRL_X_FUNCTION */
4212     char_u	*base)
4213 {
4214     list_T      *matchlist = NULL;
4215     dict_T	*matchdict = NULL;
4216     typval_T	args[3];
4217     char_u	*funcname;
4218     pos_T	pos;
4219     win_T	*curwin_save;
4220     buf_T	*curbuf_save;
4221     typval_T	rettv;
4222 
4223     funcname = (type == CTRL_X_FUNCTION) ? curbuf->b_p_cfu : curbuf->b_p_ofu;
4224     if (*funcname == NUL)
4225 	return;
4226 
4227     /* Call 'completefunc' to obtain the list of matches. */
4228     args[0].v_type = VAR_NUMBER;
4229     args[0].vval.v_number = 0;
4230     args[1].v_type = VAR_STRING;
4231     args[1].vval.v_string = base != NULL ? base : (char_u *)"";
4232     args[2].v_type = VAR_UNKNOWN;
4233 
4234     pos = curwin->w_cursor;
4235     curwin_save = curwin;
4236     curbuf_save = curbuf;
4237 
4238     /* Call a function, which returns a list or dict. */
4239     if (call_vim_function(funcname, 2, args, &rettv) == OK)
4240     {
4241 	switch (rettv.v_type)
4242 	{
4243 	    case VAR_LIST:
4244 		matchlist = rettv.vval.v_list;
4245 		break;
4246 	    case VAR_DICT:
4247 		matchdict = rettv.vval.v_dict;
4248 		break;
4249 	    default:
4250 		/* TODO: Give error message? */
4251 		clear_tv(&rettv);
4252 		break;
4253 	}
4254     }
4255 
4256     if (curwin_save != curwin || curbuf_save != curbuf)
4257     {
4258 	EMSG(_(e_complwin));
4259 	goto theend;
4260     }
4261     curwin->w_cursor = pos;	/* restore the cursor position */
4262     validate_cursor();
4263     if (!EQUAL_POS(curwin->w_cursor, pos))
4264     {
4265 	EMSG(_(e_compldel));
4266 	goto theend;
4267     }
4268 
4269     if (matchlist != NULL)
4270 	ins_compl_add_list(matchlist);
4271     else if (matchdict != NULL)
4272 	ins_compl_add_dict(matchdict);
4273 
4274 theend:
4275     if (matchdict != NULL)
4276 	dict_unref(matchdict);
4277     if (matchlist != NULL)
4278 	list_unref(matchlist);
4279 }
4280 #endif /* FEAT_COMPL_FUNC */
4281 
4282 #if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL) || defined(PROTO)
4283 /*
4284  * Add completions from a list.
4285  */
4286     static void
4287 ins_compl_add_list(list_T *list)
4288 {
4289     listitem_T	*li;
4290     int		dir = compl_direction;
4291 
4292     /* Go through the List with matches and add each of them. */
4293     for (li = list->lv_first; li != NULL; li = li->li_next)
4294     {
4295 	if (ins_compl_add_tv(&li->li_tv, dir) == OK)
4296 	    /* if dir was BACKWARD then honor it just once */
4297 	    dir = FORWARD;
4298 	else if (did_emsg)
4299 	    break;
4300     }
4301 }
4302 
4303 /*
4304  * Add completions from a dict.
4305  */
4306     static void
4307 ins_compl_add_dict(dict_T *dict)
4308 {
4309     dictitem_T	*di_refresh;
4310     dictitem_T	*di_words;
4311 
4312     /* Check for optional "refresh" item. */
4313     compl_opt_refresh_always = FALSE;
4314     di_refresh = dict_find(dict, (char_u *)"refresh", 7);
4315     if (di_refresh != NULL && di_refresh->di_tv.v_type == VAR_STRING)
4316     {
4317 	char_u	*v = di_refresh->di_tv.vval.v_string;
4318 
4319 	if (v != NULL && STRCMP(v, (char_u *)"always") == 0)
4320 	    compl_opt_refresh_always = TRUE;
4321     }
4322 
4323     /* Add completions from a "words" list. */
4324     di_words = dict_find(dict, (char_u *)"words", 5);
4325     if (di_words != NULL && di_words->di_tv.v_type == VAR_LIST)
4326 	ins_compl_add_list(di_words->di_tv.vval.v_list);
4327 }
4328 
4329 /*
4330  * Add a match to the list of matches from a typeval_T.
4331  * If the given string is already in the list of completions, then return
4332  * NOTDONE, otherwise add it to the list and return OK.  If there is an error,
4333  * maybe because alloc() returns NULL, then FAIL is returned.
4334  */
4335     int
4336 ins_compl_add_tv(typval_T *tv, int dir)
4337 {
4338     char_u	*word;
4339     int		icase = FALSE;
4340     int		adup = FALSE;
4341     int		aempty = FALSE;
4342     char_u	*(cptext[CPT_COUNT]);
4343 
4344     if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL)
4345     {
4346 	word = dict_get_string(tv->vval.v_dict, (char_u *)"word", FALSE);
4347 	cptext[CPT_ABBR] = dict_get_string(tv->vval.v_dict,
4348 						     (char_u *)"abbr", FALSE);
4349 	cptext[CPT_MENU] = dict_get_string(tv->vval.v_dict,
4350 						     (char_u *)"menu", FALSE);
4351 	cptext[CPT_KIND] = dict_get_string(tv->vval.v_dict,
4352 						     (char_u *)"kind", FALSE);
4353 	cptext[CPT_INFO] = dict_get_string(tv->vval.v_dict,
4354 						     (char_u *)"info", FALSE);
4355 	cptext[CPT_USER_DATA] = dict_get_string(tv->vval.v_dict,
4356 						 (char_u *)"user_data", FALSE);
4357 	if (dict_get_string(tv->vval.v_dict, (char_u *)"icase", FALSE) != NULL)
4358 	    icase = dict_get_number(tv->vval.v_dict, (char_u *)"icase");
4359 	if (dict_get_string(tv->vval.v_dict, (char_u *)"dup", FALSE) != NULL)
4360 	    adup = dict_get_number(tv->vval.v_dict, (char_u *)"dup");
4361 	if (dict_get_string(tv->vval.v_dict, (char_u *)"empty", FALSE) != NULL)
4362 	    aempty = dict_get_number(tv->vval.v_dict, (char_u *)"empty");
4363     }
4364     else
4365     {
4366 	word = get_tv_string_chk(tv);
4367 	vim_memset(cptext, 0, sizeof(cptext));
4368     }
4369     if (word == NULL || (!aempty && *word == NUL))
4370 	return FAIL;
4371     return ins_compl_add(word, -1, icase, NULL, cptext, dir, 0, adup);
4372 }
4373 #endif
4374 
4375 /*
4376  * Get the next expansion(s), using "compl_pattern".
4377  * The search starts at position "ini" in curbuf and in the direction
4378  * compl_direction.
4379  * When "compl_started" is FALSE start at that position, otherwise continue
4380  * where we stopped searching before.
4381  * This may return before finding all the matches.
4382  * Return the total number of matches or -1 if still unknown -- Acevedo
4383  */
4384     static int
4385 ins_compl_get_exp(pos_T *ini)
4386 {
4387     static pos_T	first_match_pos;
4388     static pos_T	last_match_pos;
4389     static char_u	*e_cpt = (char_u *)"";	/* curr. entry in 'complete' */
4390     static int		found_all = FALSE;	/* Found all matches of a
4391 						   certain type. */
4392     static buf_T	*ins_buf = NULL;	/* buffer being scanned */
4393 
4394     pos_T	*pos;
4395     char_u	**matches;
4396     int		save_p_scs;
4397     int		save_p_ws;
4398     int		save_p_ic;
4399     int		i;
4400     int		num_matches;
4401     int		len;
4402     int		found_new_match;
4403     int		type = ctrl_x_mode;
4404     char_u	*ptr;
4405     char_u	*dict = NULL;
4406     int		dict_f = 0;
4407     int		set_match_pos;
4408 
4409     if (!compl_started)
4410     {
4411 	FOR_ALL_BUFFERS(ins_buf)
4412 	    ins_buf->b_scanned = 0;
4413 	found_all = FALSE;
4414 	ins_buf = curbuf;
4415 	e_cpt = (compl_cont_status & CONT_LOCAL)
4416 					    ? (char_u *)"." : curbuf->b_p_cpt;
4417 	last_match_pos = first_match_pos = *ini;
4418     }
4419     else if (ins_buf != curbuf && !buf_valid(ins_buf))
4420 	ins_buf = curbuf;  // In case the buffer was wiped out.
4421 
4422     compl_old_match = compl_curr_match;	/* remember the last current match */
4423     pos = (compl_direction == FORWARD) ? &last_match_pos : &first_match_pos;
4424 
4425     /*
4426      * For ^N/^P loop over all the flags/windows/buffers in 'complete'.
4427      */
4428     for (;;)
4429     {
4430 	found_new_match = FAIL;
4431 	set_match_pos = FALSE;
4432 
4433 	/* For ^N/^P pick a new entry from e_cpt if compl_started is off,
4434 	 * or if found_all says this entry is done.  For ^X^L only use the
4435 	 * entries from 'complete' that look in loaded buffers. */
4436 	if ((ctrl_x_mode == CTRL_X_NORMAL
4437 		    || CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
4438 					&& (!compl_started || found_all))
4439 	{
4440 	    found_all = FALSE;
4441 	    while (*e_cpt == ',' || *e_cpt == ' ')
4442 		e_cpt++;
4443 	    if (*e_cpt == '.' && !curbuf->b_scanned)
4444 	    {
4445 		ins_buf = curbuf;
4446 		first_match_pos = *ini;
4447 		/* Move the cursor back one character so that ^N can match the
4448 		 * word immediately after the cursor. */
4449 		if (ctrl_x_mode == CTRL_X_NORMAL && dec(&first_match_pos) < 0)
4450 		{
4451 		    /* Move the cursor to after the last character in the
4452 		     * buffer, so that word at start of buffer is found
4453 		     * correctly. */
4454 		    first_match_pos.lnum = ins_buf->b_ml.ml_line_count;
4455 		    first_match_pos.col =
4456 				 (colnr_T)STRLEN(ml_get(first_match_pos.lnum));
4457 		}
4458 		last_match_pos = first_match_pos;
4459 		type = 0;
4460 
4461 		/* Remember the first match so that the loop stops when we
4462 		 * wrap and come back there a second time. */
4463 		set_match_pos = TRUE;
4464 	    }
4465 	    else if (vim_strchr((char_u *)"buwU", *e_cpt) != NULL
4466 		 && (ins_buf = ins_compl_next_buf(ins_buf, *e_cpt)) != curbuf)
4467 	    {
4468 		/* Scan a buffer, but not the current one. */
4469 		if (ins_buf->b_ml.ml_mfp != NULL)   /* loaded buffer */
4470 		{
4471 		    compl_started = TRUE;
4472 		    first_match_pos.col = last_match_pos.col = 0;
4473 		    first_match_pos.lnum = ins_buf->b_ml.ml_line_count + 1;
4474 		    last_match_pos.lnum = 0;
4475 		    type = 0;
4476 		}
4477 		else	/* unloaded buffer, scan like dictionary */
4478 		{
4479 		    found_all = TRUE;
4480 		    if (ins_buf->b_fname == NULL)
4481 			continue;
4482 		    type = CTRL_X_DICTIONARY;
4483 		    dict = ins_buf->b_fname;
4484 		    dict_f = DICT_EXACT;
4485 		}
4486 		vim_snprintf((char *)IObuff, IOSIZE, _("Scanning: %s"),
4487 			ins_buf->b_fname == NULL
4488 			    ? buf_spname(ins_buf)
4489 			    : ins_buf->b_sfname == NULL
4490 				? ins_buf->b_fname
4491 				: ins_buf->b_sfname);
4492 		(void)msg_trunc_attr(IObuff, TRUE, HL_ATTR(HLF_R));
4493 	    }
4494 	    else if (*e_cpt == NUL)
4495 		break;
4496 	    else
4497 	    {
4498 		if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
4499 		    type = -1;
4500 		else if (*e_cpt == 'k' || *e_cpt == 's')
4501 		{
4502 		    if (*e_cpt == 'k')
4503 			type = CTRL_X_DICTIONARY;
4504 		    else
4505 			type = CTRL_X_THESAURUS;
4506 		    if (*++e_cpt != ',' && *e_cpt != NUL)
4507 		    {
4508 			dict = e_cpt;
4509 			dict_f = DICT_FIRST;
4510 		    }
4511 		}
4512 #ifdef FEAT_FIND_ID
4513 		else if (*e_cpt == 'i')
4514 		    type = CTRL_X_PATH_PATTERNS;
4515 		else if (*e_cpt == 'd')
4516 		    type = CTRL_X_PATH_DEFINES;
4517 #endif
4518 		else if (*e_cpt == ']' || *e_cpt == 't')
4519 		{
4520 		    type = CTRL_X_TAGS;
4521 		    vim_snprintf((char *)IObuff, IOSIZE, _("Scanning tags."));
4522 		    (void)msg_trunc_attr(IObuff, TRUE, HL_ATTR(HLF_R));
4523 		}
4524 		else
4525 		    type = -1;
4526 
4527 		/* in any case e_cpt is advanced to the next entry */
4528 		(void)copy_option_part(&e_cpt, IObuff, IOSIZE, ",");
4529 
4530 		found_all = TRUE;
4531 		if (type == -1)
4532 		    continue;
4533 	    }
4534 	}
4535 
4536 	/* If complete() was called then compl_pattern has been reset.  The
4537 	 * following won't work then, bail out. */
4538 	if (compl_pattern == NULL)
4539 	    break;
4540 
4541 	switch (type)
4542 	{
4543 	case -1:
4544 	    break;
4545 #ifdef FEAT_FIND_ID
4546 	case CTRL_X_PATH_PATTERNS:
4547 	case CTRL_X_PATH_DEFINES:
4548 	    find_pattern_in_path(compl_pattern, compl_direction,
4549 				 (int)STRLEN(compl_pattern), FALSE, FALSE,
4550 				 (type == CTRL_X_PATH_DEFINES
4551 				  && !(compl_cont_status & CONT_SOL))
4552 				 ? FIND_DEFINE : FIND_ANY, 1L, ACTION_EXPAND,
4553 				 (linenr_T)1, (linenr_T)MAXLNUM);
4554 	    break;
4555 #endif
4556 
4557 	case CTRL_X_DICTIONARY:
4558 	case CTRL_X_THESAURUS:
4559 	    ins_compl_dictionaries(
4560 		    dict != NULL ? dict
4561 			 : (type == CTRL_X_THESAURUS
4562 			     ? (*curbuf->b_p_tsr == NUL
4563 				 ? p_tsr
4564 				 : curbuf->b_p_tsr)
4565 			     : (*curbuf->b_p_dict == NUL
4566 				 ? p_dict
4567 				 : curbuf->b_p_dict)),
4568 			    compl_pattern,
4569 				 dict != NULL ? dict_f
4570 					       : 0, type == CTRL_X_THESAURUS);
4571 	    dict = NULL;
4572 	    break;
4573 
4574 	case CTRL_X_TAGS:
4575 	    /* set p_ic according to p_ic, p_scs and pat for find_tags(). */
4576 	    save_p_ic = p_ic;
4577 	    p_ic = ignorecase(compl_pattern);
4578 
4579 	    /* Find up to TAG_MANY matches.  Avoids that an enormous number
4580 	     * of matches is found when compl_pattern is empty */
4581 	    if (find_tags(compl_pattern, &num_matches, &matches,
4582 		    TAG_REGEXP | TAG_NAMES | TAG_NOIC | TAG_INS_COMP
4583 		    | (ctrl_x_mode != CTRL_X_NORMAL ? TAG_VERBOSE : 0),
4584 		    TAG_MANY, curbuf->b_ffname) == OK && num_matches > 0)
4585 	    {
4586 		ins_compl_add_matches(num_matches, matches, p_ic);
4587 	    }
4588 	    p_ic = save_p_ic;
4589 	    break;
4590 
4591 	case CTRL_X_FILES:
4592 	    if (expand_wildcards(1, &compl_pattern, &num_matches, &matches,
4593 				  EW_FILE|EW_DIR|EW_ADDSLASH|EW_SILENT) == OK)
4594 	    {
4595 
4596 		/* May change home directory back to "~". */
4597 		tilde_replace(compl_pattern, num_matches, matches);
4598 		ins_compl_add_matches(num_matches, matches, p_fic || p_wic);
4599 	    }
4600 	    break;
4601 
4602 	case CTRL_X_CMDLINE:
4603 	    if (expand_cmdline(&compl_xp, compl_pattern,
4604 			(int)STRLEN(compl_pattern),
4605 					 &num_matches, &matches) == EXPAND_OK)
4606 		ins_compl_add_matches(num_matches, matches, FALSE);
4607 	    break;
4608 
4609 #ifdef FEAT_COMPL_FUNC
4610 	case CTRL_X_FUNCTION:
4611 	case CTRL_X_OMNI:
4612 	    expand_by_function(type, compl_pattern);
4613 	    break;
4614 #endif
4615 
4616 	case CTRL_X_SPELL:
4617 #ifdef FEAT_SPELL
4618 	    num_matches = expand_spelling(first_match_pos.lnum,
4619 						     compl_pattern, &matches);
4620 	    if (num_matches > 0)
4621 		ins_compl_add_matches(num_matches, matches, p_ic);
4622 #endif
4623 	    break;
4624 
4625 	default:	/* normal ^P/^N and ^X^L */
4626 	    /*
4627 	     * If 'infercase' is set, don't use 'smartcase' here
4628 	     */
4629 	    save_p_scs = p_scs;
4630 	    if (ins_buf->b_p_inf)
4631 		p_scs = FALSE;
4632 
4633 	    /*	Buffers other than curbuf are scanned from the beginning or the
4634 	     *	end but never from the middle, thus setting nowrapscan in this
4635 	     *	buffers is a good idea, on the other hand, we always set
4636 	     *	wrapscan for curbuf to avoid missing matches -- Acevedo,Webb */
4637 	    save_p_ws = p_ws;
4638 	    if (ins_buf != curbuf)
4639 		p_ws = FALSE;
4640 	    else if (*e_cpt == '.')
4641 		p_ws = TRUE;
4642 	    for (;;)
4643 	    {
4644 		int	flags = 0;
4645 
4646 		++msg_silent;  /* Don't want messages for wrapscan. */
4647 
4648 		/* CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)
4649 		 * || word-wise search that
4650 		 * has added a word that was at the beginning of the line */
4651 		if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)
4652 			|| (compl_cont_status & CONT_SOL))
4653 		    found_new_match = search_for_exact_line(ins_buf, pos,
4654 					      compl_direction, compl_pattern);
4655 		else
4656 		    found_new_match = searchit(NULL, ins_buf, pos,
4657 							      compl_direction,
4658 				 compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG,
4659 					     RE_LAST, (linenr_T)0, NULL, NULL);
4660 		--msg_silent;
4661 		if (!compl_started || set_match_pos)
4662 		{
4663 		    /* set "compl_started" even on fail */
4664 		    compl_started = TRUE;
4665 		    first_match_pos = *pos;
4666 		    last_match_pos = *pos;
4667 		    set_match_pos = FALSE;
4668 		}
4669 		else if (first_match_pos.lnum == last_match_pos.lnum
4670 				 && first_match_pos.col == last_match_pos.col)
4671 		    found_new_match = FAIL;
4672 		if (found_new_match == FAIL)
4673 		{
4674 		    if (ins_buf == curbuf)
4675 			found_all = TRUE;
4676 		    break;
4677 		}
4678 
4679 		/* when ADDING, the text before the cursor matches, skip it */
4680 		if (	(compl_cont_status & CONT_ADDING) && ins_buf == curbuf
4681 			&& ini->lnum == pos->lnum
4682 			&& ini->col  == pos->col)
4683 		    continue;
4684 		ptr = ml_get_buf(ins_buf, pos->lnum, FALSE) + pos->col;
4685 		if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
4686 		{
4687 		    if (compl_cont_status & CONT_ADDING)
4688 		    {
4689 			if (pos->lnum >= ins_buf->b_ml.ml_line_count)
4690 			    continue;
4691 			ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE);
4692 			if (!p_paste)
4693 			    ptr = skipwhite(ptr);
4694 		    }
4695 		    len = (int)STRLEN(ptr);
4696 		}
4697 		else
4698 		{
4699 		    char_u	*tmp_ptr = ptr;
4700 
4701 		    if (compl_cont_status & CONT_ADDING)
4702 		    {
4703 			tmp_ptr += compl_length;
4704 			/* Skip if already inside a word. */
4705 			if (vim_iswordp(tmp_ptr))
4706 			    continue;
4707 			/* Find start of next word. */
4708 			tmp_ptr = find_word_start(tmp_ptr);
4709 		    }
4710 		    /* Find end of this word. */
4711 		    tmp_ptr = find_word_end(tmp_ptr);
4712 		    len = (int)(tmp_ptr - ptr);
4713 
4714 		    if ((compl_cont_status & CONT_ADDING)
4715 						       && len == compl_length)
4716 		    {
4717 			if (pos->lnum < ins_buf->b_ml.ml_line_count)
4718 			{
4719 			    /* Try next line, if any. the new word will be
4720 			     * "join" as if the normal command "J" was used.
4721 			     * IOSIZE is always greater than
4722 			     * compl_length, so the next STRNCPY always
4723 			     * works -- Acevedo */
4724 			    STRNCPY(IObuff, ptr, len);
4725 			    ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE);
4726 			    tmp_ptr = ptr = skipwhite(ptr);
4727 			    /* Find start of next word. */
4728 			    tmp_ptr = find_word_start(tmp_ptr);
4729 			    /* Find end of next word. */
4730 			    tmp_ptr = find_word_end(tmp_ptr);
4731 			    if (tmp_ptr > ptr)
4732 			    {
4733 				if (*ptr != ')' && IObuff[len - 1] != TAB)
4734 				{
4735 				    if (IObuff[len - 1] != ' ')
4736 					IObuff[len++] = ' ';
4737 				    /* IObuf =~ "\k.* ", thus len >= 2 */
4738 				    if (p_js
4739 					&& (IObuff[len - 2] == '.'
4740 					    || (vim_strchr(p_cpo, CPO_JOINSP)
4741 								       == NULL
4742 						&& (IObuff[len - 2] == '?'
4743 						 || IObuff[len - 2] == '!'))))
4744 					IObuff[len++] = ' ';
4745 				}
4746 				/* copy as much as possible of the new word */
4747 				if (tmp_ptr - ptr >= IOSIZE - len)
4748 				    tmp_ptr = ptr + IOSIZE - len - 1;
4749 				STRNCPY(IObuff + len, ptr, tmp_ptr - ptr);
4750 				len += (int)(tmp_ptr - ptr);
4751 				flags |= CONT_S_IPOS;
4752 			    }
4753 			    IObuff[len] = NUL;
4754 			    ptr = IObuff;
4755 			}
4756 			if (len == compl_length)
4757 			    continue;
4758 		    }
4759 		}
4760 		if (ins_compl_add_infercase(ptr, len, p_ic,
4761 				 ins_buf == curbuf ? NULL : ins_buf->b_sfname,
4762 					   0, flags) != NOTDONE)
4763 		{
4764 		    found_new_match = OK;
4765 		    break;
4766 		}
4767 	    }
4768 	    p_scs = save_p_scs;
4769 	    p_ws = save_p_ws;
4770 	}
4771 
4772 	/* check if compl_curr_match has changed, (e.g. other type of
4773 	 * expansion added something) */
4774 	if (type != 0 && compl_curr_match != compl_old_match)
4775 	    found_new_match = OK;
4776 
4777 	/* break the loop for specialized modes (use 'complete' just for the
4778 	 * generic ctrl_x_mode == CTRL_X_NORMAL) or when we've found a new
4779 	 * match */
4780 	if ((ctrl_x_mode != CTRL_X_NORMAL
4781 		    && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
4782 						   || found_new_match != FAIL)
4783 	{
4784 	    if (got_int)
4785 		break;
4786 	    /* Fill the popup menu as soon as possible. */
4787 	    if (type != -1)
4788 		ins_compl_check_keys(0, FALSE);
4789 
4790 	    if ((ctrl_x_mode != CTRL_X_NORMAL
4791 			&& !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
4792 							 || compl_interrupted)
4793 		break;
4794 	    compl_started = TRUE;
4795 	}
4796 	else
4797 	{
4798 	    /* Mark a buffer scanned when it has been scanned completely */
4799 	    if (type == 0 || type == CTRL_X_PATH_PATTERNS)
4800 		ins_buf->b_scanned = TRUE;
4801 
4802 	    compl_started = FALSE;
4803 	}
4804     }
4805     compl_started = TRUE;
4806 
4807     if ((ctrl_x_mode == CTRL_X_NORMAL || CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
4808 	    && *e_cpt == NUL)		/* Got to end of 'complete' */
4809 	found_new_match = FAIL;
4810 
4811     i = -1;		/* total of matches, unknown */
4812     if (found_new_match == FAIL || (ctrl_x_mode != CTRL_X_NORMAL
4813 				    && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)))
4814 	i = ins_compl_make_cyclic();
4815 
4816     if (compl_old_match != NULL)
4817     {
4818 	/* If several matches were added (FORWARD) or the search failed and has
4819 	 * just been made cyclic then we have to move compl_curr_match to the
4820 	 * next or previous entry (if any) -- Acevedo */
4821 	compl_curr_match = compl_direction == FORWARD ? compl_old_match->cp_next
4822 						    : compl_old_match->cp_prev;
4823 	if (compl_curr_match == NULL)
4824 	    compl_curr_match = compl_old_match;
4825     }
4826     return i;
4827 }
4828 
4829 /* Delete the old text being completed. */
4830     static void
4831 ins_compl_delete(void)
4832 {
4833     int	    col;
4834 
4835     /*
4836      * In insert mode: Delete the typed part.
4837      * In replace mode: Put the old characters back, if any.
4838      */
4839     col = compl_col + (compl_cont_status & CONT_ADDING ? compl_length : 0);
4840     if ((int)curwin->w_cursor.col > col)
4841     {
4842 	if (stop_arrow() == FAIL)
4843 	    return;
4844 	backspace_until_column(col);
4845     }
4846 
4847     /* TODO: is this sufficient for redrawing?  Redrawing everything causes
4848      * flicker, thus we can't do that. */
4849     changed_cline_bef_curs();
4850     /* clear v:completed_item */
4851     set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED));
4852 }
4853 
4854 /*
4855  * Insert the new text being completed.
4856  * "in_compl_func" is TRUE when called from complete_check().
4857  */
4858     static void
4859 ins_compl_insert(int in_compl_func)
4860 {
4861     dict_T	*dict;
4862 
4863     ins_bytes(compl_shown_match->cp_str + ins_compl_len());
4864     if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
4865 	compl_used_match = FALSE;
4866     else
4867 	compl_used_match = TRUE;
4868 
4869     /* Set completed item. */
4870     /* { word, abbr, menu, kind, info } */
4871     dict = dict_alloc_lock(VAR_FIXED);
4872     if (dict != NULL)
4873     {
4874 	dict_add_string(dict, "word", compl_shown_match->cp_str);
4875 	dict_add_string(dict, "abbr", compl_shown_match->cp_text[CPT_ABBR]);
4876 	dict_add_string(dict, "menu", compl_shown_match->cp_text[CPT_MENU]);
4877 	dict_add_string(dict, "kind", compl_shown_match->cp_text[CPT_KIND]);
4878 	dict_add_string(dict, "info", compl_shown_match->cp_text[CPT_INFO]);
4879 	dict_add_string(dict, "user_data",
4880 				 compl_shown_match->cp_text[CPT_USER_DATA]);
4881     }
4882     set_vim_var_dict(VV_COMPLETED_ITEM, dict);
4883     if (!in_compl_func)
4884 	compl_curr_match = compl_shown_match;
4885 }
4886 
4887 /*
4888  * Fill in the next completion in the current direction.
4889  * If "allow_get_expansion" is TRUE, then we may call ins_compl_get_exp() to
4890  * get more completions.  If it is FALSE, then we just do nothing when there
4891  * are no more completions in a given direction.  The latter case is used when
4892  * we are still in the middle of finding completions, to allow browsing
4893  * through the ones found so far.
4894  * Return the total number of matches, or -1 if still unknown -- webb.
4895  *
4896  * compl_curr_match is currently being used by ins_compl_get_exp(), so we use
4897  * compl_shown_match here.
4898  *
4899  * Note that this function may be called recursively once only.  First with
4900  * "allow_get_expansion" TRUE, which calls ins_compl_get_exp(), which in turn
4901  * calls this function with "allow_get_expansion" FALSE.
4902  */
4903     static int
4904 ins_compl_next(
4905     int	    allow_get_expansion,
4906     int	    count,		/* repeat completion this many times; should
4907 				   be at least 1 */
4908     int	    insert_match,	/* Insert the newly selected match */
4909     int	    in_compl_func)	/* called from complete_check() */
4910 {
4911     int	    num_matches = -1;
4912     int	    todo = count;
4913     compl_T *found_compl = NULL;
4914     int	    found_end = FALSE;
4915     int	    advance;
4916     int	    started = compl_started;
4917 
4918     /* When user complete function return -1 for findstart which is next
4919      * time of 'always', compl_shown_match become NULL. */
4920     if (compl_shown_match == NULL)
4921 	return -1;
4922 
4923     if (compl_leader != NULL
4924 			&& (compl_shown_match->cp_flags & ORIGINAL_TEXT) == 0)
4925     {
4926 	/* Set "compl_shown_match" to the actually shown match, it may differ
4927 	 * when "compl_leader" is used to omit some of the matches. */
4928 	while (!ins_compl_equal(compl_shown_match,
4929 				      compl_leader, (int)STRLEN(compl_leader))
4930 		&& compl_shown_match->cp_next != NULL
4931 		&& compl_shown_match->cp_next != compl_first_match)
4932 	    compl_shown_match = compl_shown_match->cp_next;
4933 
4934 	/* If we didn't find it searching forward, and compl_shows_dir is
4935 	 * backward, find the last match. */
4936 	if (compl_shows_dir == BACKWARD
4937 		&& !ins_compl_equal(compl_shown_match,
4938 				      compl_leader, (int)STRLEN(compl_leader))
4939 		&& (compl_shown_match->cp_next == NULL
4940 		    || compl_shown_match->cp_next == compl_first_match))
4941 	{
4942 	    while (!ins_compl_equal(compl_shown_match,
4943 				      compl_leader, (int)STRLEN(compl_leader))
4944 		    && compl_shown_match->cp_prev != NULL
4945 		    && compl_shown_match->cp_prev != compl_first_match)
4946 		compl_shown_match = compl_shown_match->cp_prev;
4947 	}
4948     }
4949 
4950     if (allow_get_expansion && insert_match
4951 	    && (!(compl_get_longest || compl_restarting) || compl_used_match))
4952 	/* Delete old text to be replaced */
4953 	ins_compl_delete();
4954 
4955     /* When finding the longest common text we stick at the original text,
4956      * don't let CTRL-N or CTRL-P move to the first match. */
4957     advance = count != 1 || !allow_get_expansion || !compl_get_longest;
4958 
4959     /* When restarting the search don't insert the first match either. */
4960     if (compl_restarting)
4961     {
4962 	advance = FALSE;
4963 	compl_restarting = FALSE;
4964     }
4965 
4966     /* Repeat this for when <PageUp> or <PageDown> is typed.  But don't wrap
4967      * around. */
4968     while (--todo >= 0)
4969     {
4970 	if (compl_shows_dir == FORWARD && compl_shown_match->cp_next != NULL)
4971 	{
4972 	    compl_shown_match = compl_shown_match->cp_next;
4973 	    found_end = (compl_first_match != NULL
4974 			   && (compl_shown_match->cp_next == compl_first_match
4975 			       || compl_shown_match == compl_first_match));
4976 	}
4977 	else if (compl_shows_dir == BACKWARD
4978 					&& compl_shown_match->cp_prev != NULL)
4979 	{
4980 	    found_end = (compl_shown_match == compl_first_match);
4981 	    compl_shown_match = compl_shown_match->cp_prev;
4982 	    found_end |= (compl_shown_match == compl_first_match);
4983 	}
4984 	else
4985 	{
4986 	    if (!allow_get_expansion)
4987 	    {
4988 		if (advance)
4989 		{
4990 		    if (compl_shows_dir == BACKWARD)
4991 			compl_pending -= todo + 1;
4992 		    else
4993 			compl_pending += todo + 1;
4994 		}
4995 		return -1;
4996 	    }
4997 
4998 	    if (!compl_no_select && advance)
4999 	    {
5000 		if (compl_shows_dir == BACKWARD)
5001 		    --compl_pending;
5002 		else
5003 		    ++compl_pending;
5004 	    }
5005 
5006 	    /* Find matches. */
5007 	    num_matches = ins_compl_get_exp(&compl_startpos);
5008 
5009 	    /* handle any pending completions */
5010 	    while (compl_pending != 0 && compl_direction == compl_shows_dir
5011 								   && advance)
5012 	    {
5013 		if (compl_pending > 0 && compl_shown_match->cp_next != NULL)
5014 		{
5015 		    compl_shown_match = compl_shown_match->cp_next;
5016 		    --compl_pending;
5017 		}
5018 		if (compl_pending < 0 && compl_shown_match->cp_prev != NULL)
5019 		{
5020 		    compl_shown_match = compl_shown_match->cp_prev;
5021 		    ++compl_pending;
5022 		}
5023 		else
5024 		    break;
5025 	    }
5026 	    found_end = FALSE;
5027 	}
5028 	if ((compl_shown_match->cp_flags & ORIGINAL_TEXT) == 0
5029 		&& compl_leader != NULL
5030 		&& !ins_compl_equal(compl_shown_match,
5031 				     compl_leader, (int)STRLEN(compl_leader)))
5032 	    ++todo;
5033 	else
5034 	    /* Remember a matching item. */
5035 	    found_compl = compl_shown_match;
5036 
5037 	/* Stop at the end of the list when we found a usable match. */
5038 	if (found_end)
5039 	{
5040 	    if (found_compl != NULL)
5041 	    {
5042 		compl_shown_match = found_compl;
5043 		break;
5044 	    }
5045 	    todo = 1;	    /* use first usable match after wrapping around */
5046 	}
5047     }
5048 
5049     /* Insert the text of the new completion, or the compl_leader. */
5050     if (compl_no_insert && !started)
5051     {
5052 	ins_bytes(compl_orig_text + ins_compl_len());
5053 	compl_used_match = FALSE;
5054     }
5055     else if (insert_match)
5056     {
5057 	if (!compl_get_longest || compl_used_match)
5058 	    ins_compl_insert(in_compl_func);
5059 	else
5060 	    ins_bytes(compl_leader + ins_compl_len());
5061     }
5062     else
5063 	compl_used_match = FALSE;
5064 
5065     if (!allow_get_expansion)
5066     {
5067 	/* may undisplay the popup menu first */
5068 	ins_compl_upd_pum();
5069 
5070 	/* redraw to show the user what was inserted */
5071 	update_screen(0);
5072 
5073 	/* display the updated popup menu */
5074 	ins_compl_show_pum();
5075 #ifdef FEAT_GUI
5076 	if (gui.in_use)
5077 	{
5078 	    /* Show the cursor after the match, not after the redrawn text. */
5079 	    setcursor();
5080 	    out_flush_cursor(FALSE, FALSE);
5081 	}
5082 #endif
5083 
5084 	/* Delete old text to be replaced, since we're still searching and
5085 	 * don't want to match ourselves!  */
5086 	ins_compl_delete();
5087     }
5088 
5089     /* Enter will select a match when the match wasn't inserted and the popup
5090      * menu is visible. */
5091     if (compl_no_insert && !started)
5092 	compl_enter_selects = TRUE;
5093     else
5094 	compl_enter_selects = !insert_match && compl_match_array != NULL;
5095 
5096     /*
5097      * Show the file name for the match (if any)
5098      * Truncate the file name to avoid a wait for return.
5099      */
5100     if (compl_shown_match->cp_fname != NULL)
5101     {
5102 	char	*lead = _("match in file");
5103 	int	space = sc_col - vim_strsize((char_u *)lead) - 2;
5104 	char_u	*s;
5105 	char_u	*e;
5106 
5107 	if (space > 0)
5108 	{
5109 	    /* We need the tail that fits.  With double-byte encoding going
5110 	     * back from the end is very slow, thus go from the start and keep
5111 	     * the text that fits in "space" between "s" and "e". */
5112 	    for (s = e = compl_shown_match->cp_fname; *e != NUL; MB_PTR_ADV(e))
5113 	    {
5114 		space -= ptr2cells(e);
5115 		while (space < 0)
5116 		{
5117 		    space += ptr2cells(s);
5118 		    MB_PTR_ADV(s);
5119 		}
5120 	    }
5121 	    vim_snprintf((char *)IObuff, IOSIZE, "%s %s%s", lead,
5122 				s > compl_shown_match->cp_fname ? "<" : "", s);
5123 	    msg(IObuff);
5124 	    redraw_cmdline = FALSE;	    /* don't overwrite! */
5125 	}
5126     }
5127 
5128     return num_matches;
5129 }
5130 
5131 /*
5132  * Call this while finding completions, to check whether the user has hit a key
5133  * that should change the currently displayed completion, or exit completion
5134  * mode.  Also, when compl_pending is not zero, show a completion as soon as
5135  * possible. -- webb
5136  * "frequency" specifies out of how many calls we actually check.
5137  * "in_compl_func" is TRUE when called from complete_check(), don't set
5138  * compl_curr_match.
5139  */
5140     void
5141 ins_compl_check_keys(int frequency, int in_compl_func)
5142 {
5143     static int	count = 0;
5144     int		c;
5145 
5146     /* Don't check when reading keys from a script, :normal or feedkeys().
5147      * That would break the test scripts.  But do check for keys when called
5148      * from complete_check(). */
5149     if (!in_compl_func && (using_script() || ex_normal_busy))
5150 	return;
5151 
5152     /* Only do this at regular intervals */
5153     if (++count < frequency)
5154 	return;
5155     count = 0;
5156 
5157     /* Check for a typed key.  Do use mappings, otherwise vim_is_ctrl_x_key()
5158      * can't do its work correctly. */
5159     c = vpeekc_any();
5160     if (c != NUL)
5161     {
5162 	if (vim_is_ctrl_x_key(c) && c != Ctrl_X && c != Ctrl_R)
5163 	{
5164 	    c = safe_vgetc();	/* Eat the character */
5165 	    compl_shows_dir = ins_compl_key2dir(c);
5166 	    (void)ins_compl_next(FALSE, ins_compl_key2count(c),
5167 				      c != K_UP && c != K_DOWN, in_compl_func);
5168 	}
5169 	else
5170 	{
5171 	    /* Need to get the character to have KeyTyped set.  We'll put it
5172 	     * back with vungetc() below.  But skip K_IGNORE. */
5173 	    c = safe_vgetc();
5174 	    if (c != K_IGNORE)
5175 	    {
5176 		/* Don't interrupt completion when the character wasn't typed,
5177 		 * e.g., when doing @q to replay keys. */
5178 		if (c != Ctrl_R && KeyTyped)
5179 		    compl_interrupted = TRUE;
5180 
5181 		vungetc(c);
5182 	    }
5183 	}
5184     }
5185     if (compl_pending != 0 && !got_int && !compl_no_insert)
5186     {
5187 	int todo = compl_pending > 0 ? compl_pending : -compl_pending;
5188 
5189 	compl_pending = 0;
5190 	(void)ins_compl_next(FALSE, todo, TRUE, in_compl_func);
5191     }
5192 }
5193 
5194 /*
5195  * Decide the direction of Insert mode complete from the key typed.
5196  * Returns BACKWARD or FORWARD.
5197  */
5198     static int
5199 ins_compl_key2dir(int c)
5200 {
5201     if (c == Ctrl_P || c == Ctrl_L
5202 	    || c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP || c == K_UP)
5203 	return BACKWARD;
5204     return FORWARD;
5205 }
5206 
5207 /*
5208  * Return TRUE for keys that are used for completion only when the popup menu
5209  * is visible.
5210  */
5211     static int
5212 ins_compl_pum_key(int c)
5213 {
5214     return pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP
5215 		     || c == K_PAGEDOWN || c == K_KPAGEDOWN || c == K_S_DOWN
5216 		     || c == K_UP || c == K_DOWN);
5217 }
5218 
5219 /*
5220  * Decide the number of completions to move forward.
5221  * Returns 1 for most keys, height of the popup menu for page-up/down keys.
5222  */
5223     static int
5224 ins_compl_key2count(int c)
5225 {
5226     int		h;
5227 
5228     if (ins_compl_pum_key(c) && c != K_UP && c != K_DOWN)
5229     {
5230 	h = pum_get_height();
5231 	if (h > 3)
5232 	    h -= 2; /* keep some context */
5233 	return h;
5234     }
5235     return 1;
5236 }
5237 
5238 /*
5239  * Return TRUE if completion with "c" should insert the match, FALSE if only
5240  * to change the currently selected completion.
5241  */
5242     static int
5243 ins_compl_use_match(int c)
5244 {
5245     switch (c)
5246     {
5247 	case K_UP:
5248 	case K_DOWN:
5249 	case K_PAGEDOWN:
5250 	case K_KPAGEDOWN:
5251 	case K_S_DOWN:
5252 	case K_PAGEUP:
5253 	case K_KPAGEUP:
5254 	case K_S_UP:
5255 	    return FALSE;
5256     }
5257     return TRUE;
5258 }
5259 
5260 /*
5261  * Do Insert mode completion.
5262  * Called when character "c" was typed, which has a meaning for completion.
5263  * Returns OK if completion was done, FAIL if something failed (out of mem).
5264  */
5265     static int
5266 ins_complete(int c, int enable_pum)
5267 {
5268     char_u	*line;
5269     int		startcol = 0;	    /* column where searched text starts */
5270     colnr_T	curs_col;	    /* cursor column */
5271     int		n;
5272     int		save_w_wrow;
5273     int		save_w_leftcol;
5274     int		insert_match;
5275     int		save_did_ai = did_ai;
5276 
5277     compl_direction = ins_compl_key2dir(c);
5278     insert_match = ins_compl_use_match(c);
5279 
5280     if (!compl_started)
5281     {
5282 	/* First time we hit ^N or ^P (in a row, I mean) */
5283 
5284 	did_ai = FALSE;
5285 #ifdef FEAT_SMARTINDENT
5286 	did_si = FALSE;
5287 	can_si = FALSE;
5288 	can_si_back = FALSE;
5289 #endif
5290 	if (stop_arrow() == FAIL)
5291 	    return FAIL;
5292 
5293 	line = ml_get(curwin->w_cursor.lnum);
5294 	curs_col = curwin->w_cursor.col;
5295 	compl_pending = 0;
5296 
5297 	/* If this same ctrl_x_mode has been interrupted use the text from
5298 	 * "compl_startpos" to the cursor as a pattern to add a new word
5299 	 * instead of expand the one before the cursor, in word-wise if
5300 	 * "compl_startpos" is not in the same line as the cursor then fix it
5301 	 * (the line has been split because it was longer than 'tw').  if SOL
5302 	 * is set then skip the previous pattern, a word at the beginning of
5303 	 * the line has been inserted, we'll look for that  -- Acevedo. */
5304 	if ((compl_cont_status & CONT_INTRPT) == CONT_INTRPT
5305 					    && compl_cont_mode == ctrl_x_mode)
5306 	{
5307 	    /*
5308 	     * it is a continued search
5309 	     */
5310 	    compl_cont_status &= ~CONT_INTRPT;	/* remove INTRPT */
5311 	    if (ctrl_x_mode == CTRL_X_NORMAL
5312 		    || ctrl_x_mode == CTRL_X_PATH_PATTERNS
5313 		    || ctrl_x_mode == CTRL_X_PATH_DEFINES)
5314 	    {
5315 		if (compl_startpos.lnum != curwin->w_cursor.lnum)
5316 		{
5317 		    /* line (probably) wrapped, set compl_startpos to the
5318 		     * first non_blank in the line, if it is not a wordchar
5319 		     * include it to get a better pattern, but then we don't
5320 		     * want the "\\<" prefix, check it bellow */
5321 		    compl_col = (colnr_T)getwhitecols(line);
5322 		    compl_startpos.col = compl_col;
5323 		    compl_startpos.lnum = curwin->w_cursor.lnum;
5324 		    compl_cont_status &= ~CONT_SOL;   /* clear SOL if present */
5325 		}
5326 		else
5327 		{
5328 		    /* S_IPOS was set when we inserted a word that was at the
5329 		     * beginning of the line, which means that we'll go to SOL
5330 		     * mode but first we need to redefine compl_startpos */
5331 		    if (compl_cont_status & CONT_S_IPOS)
5332 		    {
5333 			compl_cont_status |= CONT_SOL;
5334 			compl_startpos.col = (colnr_T)(skipwhite(
5335 						line + compl_length
5336 						+ compl_startpos.col) - line);
5337 		    }
5338 		    compl_col = compl_startpos.col;
5339 		}
5340 		compl_length = curwin->w_cursor.col - (int)compl_col;
5341 		/* IObuff is used to add a "word from the next line" would we
5342 		 * have enough space?  just being paranoid */
5343 #define	MIN_SPACE 75
5344 		if (compl_length > (IOSIZE - MIN_SPACE))
5345 		{
5346 		    compl_cont_status &= ~CONT_SOL;
5347 		    compl_length = (IOSIZE - MIN_SPACE);
5348 		    compl_col = curwin->w_cursor.col - compl_length;
5349 		}
5350 		compl_cont_status |= CONT_ADDING | CONT_N_ADDS;
5351 		if (compl_length < 1)
5352 		    compl_cont_status &= CONT_LOCAL;
5353 	    }
5354 	    else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
5355 		compl_cont_status = CONT_ADDING | CONT_N_ADDS;
5356 	    else
5357 		compl_cont_status = 0;
5358 	}
5359 	else
5360 	    compl_cont_status &= CONT_LOCAL;
5361 
5362 	if (!(compl_cont_status & CONT_ADDING))	/* normal expansion */
5363 	{
5364 	    compl_cont_mode = ctrl_x_mode;
5365 	    if (ctrl_x_mode != CTRL_X_NORMAL)
5366 		/* Remove LOCAL if ctrl_x_mode != CTRL_X_NORMAL */
5367 		compl_cont_status = 0;
5368 	    compl_cont_status |= CONT_N_ADDS;
5369 	    compl_startpos = curwin->w_cursor;
5370 	    startcol = (int)curs_col;
5371 	    compl_col = 0;
5372 	}
5373 
5374 	/* Work out completion pattern and original text -- webb */
5375 	if (ctrl_x_mode == CTRL_X_NORMAL || (ctrl_x_mode & CTRL_X_WANT_IDENT))
5376 	{
5377 	    if ((compl_cont_status & CONT_SOL)
5378 		    || ctrl_x_mode == CTRL_X_PATH_DEFINES)
5379 	    {
5380 		if (!(compl_cont_status & CONT_ADDING))
5381 		{
5382 		    while (--startcol >= 0 && vim_isIDc(line[startcol]))
5383 			;
5384 		    compl_col += ++startcol;
5385 		    compl_length = curs_col - startcol;
5386 		}
5387 		if (p_ic)
5388 		    compl_pattern = str_foldcase(line + compl_col,
5389 						       compl_length, NULL, 0);
5390 		else
5391 		    compl_pattern = vim_strnsave(line + compl_col,
5392 								compl_length);
5393 		if (compl_pattern == NULL)
5394 		    return FAIL;
5395 	    }
5396 	    else if (compl_cont_status & CONT_ADDING)
5397 	    {
5398 		char_u	    *prefix = (char_u *)"\\<";
5399 
5400 		/* we need up to 2 extra chars for the prefix */
5401 		compl_pattern = alloc(quote_meta(NULL, line + compl_col,
5402 							   compl_length) + 2);
5403 		if (compl_pattern == NULL)
5404 		    return FAIL;
5405 		if (!vim_iswordp(line + compl_col)
5406 			|| (compl_col > 0
5407 			    && (
5408 #ifdef FEAT_MBYTE
5409 				vim_iswordp(mb_prevptr(line, line + compl_col))
5410 #else
5411 				vim_iswordc(line[compl_col - 1])
5412 #endif
5413 				)))
5414 		    prefix = (char_u *)"";
5415 		STRCPY((char *)compl_pattern, prefix);
5416 		(void)quote_meta(compl_pattern + STRLEN(prefix),
5417 					      line + compl_col, compl_length);
5418 	    }
5419 	    else if (--startcol < 0 ||
5420 #ifdef FEAT_MBYTE
5421 			   !vim_iswordp(mb_prevptr(line, line + startcol + 1))
5422 #else
5423 			   !vim_iswordc(line[startcol])
5424 #endif
5425 		    )
5426 	    {
5427 		/* Match any word of at least two chars */
5428 		compl_pattern = vim_strsave((char_u *)"\\<\\k\\k");
5429 		if (compl_pattern == NULL)
5430 		    return FAIL;
5431 		compl_col += curs_col;
5432 		compl_length = 0;
5433 	    }
5434 	    else
5435 	    {
5436 #ifdef FEAT_MBYTE
5437 		/* Search the point of change class of multibyte character
5438 		 * or not a word single byte character backward.  */
5439 		if (has_mbyte)
5440 		{
5441 		    int base_class;
5442 		    int head_off;
5443 
5444 		    startcol -= (*mb_head_off)(line, line + startcol);
5445 		    base_class = mb_get_class(line + startcol);
5446 		    while (--startcol >= 0)
5447 		    {
5448 			head_off = (*mb_head_off)(line, line + startcol);
5449 			if (base_class != mb_get_class(line + startcol
5450 								  - head_off))
5451 			    break;
5452 			startcol -= head_off;
5453 		    }
5454 		}
5455 		else
5456 #endif
5457 		    while (--startcol >= 0 && vim_iswordc(line[startcol]))
5458 			;
5459 		compl_col += ++startcol;
5460 		compl_length = (int)curs_col - startcol;
5461 		if (compl_length == 1)
5462 		{
5463 		    /* Only match word with at least two chars -- webb
5464 		     * there's no need to call quote_meta,
5465 		     * alloc(7) is enough  -- Acevedo
5466 		     */
5467 		    compl_pattern = alloc(7);
5468 		    if (compl_pattern == NULL)
5469 			return FAIL;
5470 		    STRCPY((char *)compl_pattern, "\\<");
5471 		    (void)quote_meta(compl_pattern + 2, line + compl_col, 1);
5472 		    STRCAT((char *)compl_pattern, "\\k");
5473 		}
5474 		else
5475 		{
5476 		    compl_pattern = alloc(quote_meta(NULL, line + compl_col,
5477 							   compl_length) + 2);
5478 		    if (compl_pattern == NULL)
5479 			return FAIL;
5480 		    STRCPY((char *)compl_pattern, "\\<");
5481 		    (void)quote_meta(compl_pattern + 2, line + compl_col,
5482 								compl_length);
5483 		}
5484 	    }
5485 	}
5486 	else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
5487 	{
5488 	    compl_col = (colnr_T)getwhitecols(line);
5489 	    compl_length = (int)curs_col - (int)compl_col;
5490 	    if (compl_length < 0)	/* cursor in indent: empty pattern */
5491 		compl_length = 0;
5492 	    if (p_ic)
5493 		compl_pattern = str_foldcase(line + compl_col, compl_length,
5494 								     NULL, 0);
5495 	    else
5496 		compl_pattern = vim_strnsave(line + compl_col, compl_length);
5497 	    if (compl_pattern == NULL)
5498 		return FAIL;
5499 	}
5500 	else if (ctrl_x_mode == CTRL_X_FILES)
5501 	{
5502 	    /* Go back to just before the first filename character. */
5503 	    if (startcol > 0)
5504 	    {
5505 		char_u	*p = line + startcol;
5506 
5507 		MB_PTR_BACK(line, p);
5508 		while (p > line && vim_isfilec(PTR2CHAR(p)))
5509 		    MB_PTR_BACK(line, p);
5510 		if (p == line && vim_isfilec(PTR2CHAR(p)))
5511 		    startcol = 0;
5512 		else
5513 		    startcol = (int)(p - line) + 1;
5514 	    }
5515 
5516 	    compl_col += startcol;
5517 	    compl_length = (int)curs_col - startcol;
5518 	    compl_pattern = addstar(line + compl_col, compl_length,
5519 								EXPAND_FILES);
5520 	    if (compl_pattern == NULL)
5521 		return FAIL;
5522 	}
5523 	else if (ctrl_x_mode == CTRL_X_CMDLINE)
5524 	{
5525 	    compl_pattern = vim_strnsave(line, curs_col);
5526 	    if (compl_pattern == NULL)
5527 		return FAIL;
5528 	    set_cmd_context(&compl_xp, compl_pattern,
5529 				  (int)STRLEN(compl_pattern), curs_col, FALSE);
5530 	    if (compl_xp.xp_context == EXPAND_UNSUCCESSFUL
5531 		    || compl_xp.xp_context == EXPAND_NOTHING)
5532 		/* No completion possible, use an empty pattern to get a
5533 		 * "pattern not found" message. */
5534 		compl_col = curs_col;
5535 	    else
5536 		compl_col = (int)(compl_xp.xp_pattern - compl_pattern);
5537 	    compl_length = curs_col - compl_col;
5538 	}
5539 	else if (ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI)
5540 	{
5541 #ifdef FEAT_COMPL_FUNC
5542 	    /*
5543 	     * Call user defined function 'completefunc' with "a:findstart"
5544 	     * set to 1 to obtain the length of text to use for completion.
5545 	     */
5546 	    typval_T	args[3];
5547 	    int		col;
5548 	    char_u	*funcname;
5549 	    pos_T	pos;
5550 	    win_T	*curwin_save;
5551 	    buf_T	*curbuf_save;
5552 
5553 	    /* Call 'completefunc' or 'omnifunc' and get pattern length as a
5554 	     * string */
5555 	    funcname = ctrl_x_mode == CTRL_X_FUNCTION
5556 					  ? curbuf->b_p_cfu : curbuf->b_p_ofu;
5557 	    if (*funcname == NUL)
5558 	    {
5559 		EMSG2(_(e_notset), ctrl_x_mode == CTRL_X_FUNCTION
5560 					     ? "completefunc" : "omnifunc");
5561 		/* restore did_ai, so that adding comment leader works */
5562 		did_ai = save_did_ai;
5563 		return FAIL;
5564 	    }
5565 
5566 	    args[0].v_type = VAR_NUMBER;
5567 	    args[0].vval.v_number = 1;
5568 	    args[1].v_type = VAR_STRING;
5569 	    args[1].vval.v_string = (char_u *)"";
5570 	    args[2].v_type = VAR_UNKNOWN;
5571 	    pos = curwin->w_cursor;
5572 	    curwin_save = curwin;
5573 	    curbuf_save = curbuf;
5574 	    col = call_func_retnr(funcname, 2, args);
5575 	    if (curwin_save != curwin || curbuf_save != curbuf)
5576 	    {
5577 		EMSG(_(e_complwin));
5578 		return FAIL;
5579 	    }
5580 	    curwin->w_cursor = pos;	/* restore the cursor position */
5581 	    validate_cursor();
5582 	    if (!EQUAL_POS(curwin->w_cursor, pos))
5583 	    {
5584 		EMSG(_(e_compldel));
5585 		return FAIL;
5586 	    }
5587 
5588 	    /* Return value -2 means the user complete function wants to
5589 	     * cancel the complete without an error.
5590 	     * Return value -3 does the same as -2 and leaves CTRL-X mode.*/
5591 	    if (col == -2)
5592 		return FAIL;
5593 	    if (col == -3)
5594 	    {
5595 		ctrl_x_mode = CTRL_X_NORMAL;
5596 		edit_submode = NULL;
5597 		if (!shortmess(SHM_COMPLETIONMENU))
5598 		    msg_clr_cmdline();
5599 		return FAIL;
5600 	    }
5601 
5602 	    /*
5603 	     * Reset extended parameters of completion, when start new
5604 	     * completion.
5605 	     */
5606 	    compl_opt_refresh_always = FALSE;
5607 
5608 	    if (col < 0)
5609 		col = curs_col;
5610 	    compl_col = col;
5611 	    if (compl_col > curs_col)
5612 		compl_col = curs_col;
5613 
5614 	    /* Setup variables for completion.  Need to obtain "line" again,
5615 	     * it may have become invalid. */
5616 	    line = ml_get(curwin->w_cursor.lnum);
5617 	    compl_length = curs_col - compl_col;
5618 	    compl_pattern = vim_strnsave(line + compl_col, compl_length);
5619 	    if (compl_pattern == NULL)
5620 #endif
5621 		return FAIL;
5622 	}
5623 	else if (ctrl_x_mode == CTRL_X_SPELL)
5624 	{
5625 #ifdef FEAT_SPELL
5626 	    if (spell_bad_len > 0)
5627 		compl_col = curs_col - spell_bad_len;
5628 	    else
5629 		compl_col = spell_word_start(startcol);
5630 	    if (compl_col >= (colnr_T)startcol)
5631 	    {
5632 		compl_length = 0;
5633 		compl_col = curs_col;
5634 	    }
5635 	    else
5636 	    {
5637 		spell_expand_check_cap(compl_col);
5638 		compl_length = (int)curs_col - compl_col;
5639 	    }
5640 	    /* Need to obtain "line" again, it may have become invalid. */
5641 	    line = ml_get(curwin->w_cursor.lnum);
5642 	    compl_pattern = vim_strnsave(line + compl_col, compl_length);
5643 	    if (compl_pattern == NULL)
5644 #endif
5645 		return FAIL;
5646 	}
5647 	else
5648 	{
5649 	    internal_error("ins_complete()");
5650 	    return FAIL;
5651 	}
5652 
5653 	if (compl_cont_status & CONT_ADDING)
5654 	{
5655 	    edit_submode_pre = (char_u *)_(" Adding");
5656 	    if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
5657 	    {
5658 		/* Insert a new line, keep indentation but ignore 'comments' */
5659 #ifdef FEAT_COMMENTS
5660 		char_u *old = curbuf->b_p_com;
5661 
5662 		curbuf->b_p_com = (char_u *)"";
5663 #endif
5664 		compl_startpos.lnum = curwin->w_cursor.lnum;
5665 		compl_startpos.col = compl_col;
5666 		ins_eol('\r');
5667 #ifdef FEAT_COMMENTS
5668 		curbuf->b_p_com = old;
5669 #endif
5670 		compl_length = 0;
5671 		compl_col = curwin->w_cursor.col;
5672 	    }
5673 	}
5674 	else
5675 	{
5676 	    edit_submode_pre = NULL;
5677 	    compl_startpos.col = compl_col;
5678 	}
5679 
5680 	if (compl_cont_status & CONT_LOCAL)
5681 	    edit_submode = (char_u *)_(ctrl_x_msgs[CTRL_X_LOCAL_MSG]);
5682 	else
5683 	    edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode));
5684 
5685 	/* If any of the original typed text has been changed we need to fix
5686 	 * the redo buffer. */
5687 	ins_compl_fixRedoBufForLeader(NULL);
5688 
5689 	/* Always add completion for the original text. */
5690 	vim_free(compl_orig_text);
5691 	compl_orig_text = vim_strnsave(line + compl_col, compl_length);
5692 	if (compl_orig_text == NULL || ins_compl_add(compl_orig_text,
5693 			-1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK)
5694 	{
5695 	    VIM_CLEAR(compl_pattern);
5696 	    VIM_CLEAR(compl_orig_text);
5697 	    return FAIL;
5698 	}
5699 
5700 	/* showmode might reset the internal line pointers, so it must
5701 	 * be called before line = ml_get(), or when this address is no
5702 	 * longer needed.  -- Acevedo.
5703 	 */
5704 	edit_submode_extra = (char_u *)_("-- Searching...");
5705 	edit_submode_highl = HLF_COUNT;
5706 	showmode();
5707 	edit_submode_extra = NULL;
5708 	out_flush();
5709     }
5710     else if (insert_match && stop_arrow() == FAIL)
5711 	return FAIL;
5712 
5713     compl_shown_match = compl_curr_match;
5714     compl_shows_dir = compl_direction;
5715 
5716     /*
5717      * Find next match (and following matches).
5718      */
5719     save_w_wrow = curwin->w_wrow;
5720     save_w_leftcol = curwin->w_leftcol;
5721     n = ins_compl_next(TRUE, ins_compl_key2count(c), insert_match, FALSE);
5722 
5723     /* may undisplay the popup menu */
5724     ins_compl_upd_pum();
5725 
5726     if (n > 1)		/* all matches have been found */
5727 	compl_matches = n;
5728     compl_curr_match = compl_shown_match;
5729     compl_direction = compl_shows_dir;
5730 
5731     /* Eat the ESC that vgetc() returns after a CTRL-C to avoid leaving Insert
5732      * mode. */
5733     if (got_int && !global_busy)
5734     {
5735 	(void)vgetc();
5736 	got_int = FALSE;
5737     }
5738 
5739     /* we found no match if the list has only the "compl_orig_text"-entry */
5740     if (compl_first_match == compl_first_match->cp_next)
5741     {
5742 	edit_submode_extra = (compl_cont_status & CONT_ADDING)
5743 			&& compl_length > 1
5744 			     ? (char_u *)_(e_hitend) : (char_u *)_(e_patnotf);
5745 	edit_submode_highl = HLF_E;
5746 	/* remove N_ADDS flag, so next ^X<> won't try to go to ADDING mode,
5747 	 * because we couldn't expand anything at first place, but if we used
5748 	 * ^P, ^N, ^X^I or ^X^D we might want to add-expand a single-char-word
5749 	 * (such as M in M'exico) if not tried already.  -- Acevedo */
5750 	if (	   compl_length > 1
5751 		|| (compl_cont_status & CONT_ADDING)
5752 		|| (ctrl_x_mode != CTRL_X_NORMAL
5753 		    && ctrl_x_mode != CTRL_X_PATH_PATTERNS
5754 		    && ctrl_x_mode != CTRL_X_PATH_DEFINES))
5755 	    compl_cont_status &= ~CONT_N_ADDS;
5756     }
5757 
5758     if (compl_curr_match->cp_flags & CONT_S_IPOS)
5759 	compl_cont_status |= CONT_S_IPOS;
5760     else
5761 	compl_cont_status &= ~CONT_S_IPOS;
5762 
5763     if (edit_submode_extra == NULL)
5764     {
5765 	if (compl_curr_match->cp_flags & ORIGINAL_TEXT)
5766 	{
5767 	    edit_submode_extra = (char_u *)_("Back at original");
5768 	    edit_submode_highl = HLF_W;
5769 	}
5770 	else if (compl_cont_status & CONT_S_IPOS)
5771 	{
5772 	    edit_submode_extra = (char_u *)_("Word from other line");
5773 	    edit_submode_highl = HLF_COUNT;
5774 	}
5775 	else if (compl_curr_match->cp_next == compl_curr_match->cp_prev)
5776 	{
5777 	    edit_submode_extra = (char_u *)_("The only match");
5778 	    edit_submode_highl = HLF_COUNT;
5779 	}
5780 	else
5781 	{
5782 	    /* Update completion sequence number when needed. */
5783 	    if (compl_curr_match->cp_number == -1)
5784 	    {
5785 		int		number = 0;
5786 		compl_T		*match;
5787 
5788 		if (compl_direction == FORWARD)
5789 		{
5790 		    /* search backwards for the first valid (!= -1) number.
5791 		     * This should normally succeed already at the first loop
5792 		     * cycle, so it's fast! */
5793 		    for (match = compl_curr_match->cp_prev; match != NULL
5794 			    && match != compl_first_match;
5795 						       match = match->cp_prev)
5796 			if (match->cp_number != -1)
5797 			{
5798 			    number = match->cp_number;
5799 			    break;
5800 			}
5801 		    if (match != NULL)
5802 			/* go up and assign all numbers which are not assigned
5803 			 * yet */
5804 			for (match = match->cp_next;
5805 				match != NULL && match->cp_number == -1;
5806 						       match = match->cp_next)
5807 			    match->cp_number = ++number;
5808 		}
5809 		else /* BACKWARD */
5810 		{
5811 		    /* search forwards (upwards) for the first valid (!= -1)
5812 		     * number.  This should normally succeed already at the
5813 		     * first loop cycle, so it's fast! */
5814 		    for (match = compl_curr_match->cp_next; match != NULL
5815 			    && match != compl_first_match;
5816 						       match = match->cp_next)
5817 			if (match->cp_number != -1)
5818 			{
5819 			    number = match->cp_number;
5820 			    break;
5821 			}
5822 		    if (match != NULL)
5823 			/* go down and assign all numbers which are not
5824 			 * assigned yet */
5825 			for (match = match->cp_prev; match
5826 				&& match->cp_number == -1;
5827 						       match = match->cp_prev)
5828 			    match->cp_number = ++number;
5829 		}
5830 	    }
5831 
5832 	    /* The match should always have a sequence number now, this is
5833 	     * just a safety check. */
5834 	    if (compl_curr_match->cp_number != -1)
5835 	    {
5836 		/* Space for 10 text chars. + 2x10-digit no.s = 31.
5837 		 * Translations may need more than twice that. */
5838 		static char_u match_ref[81];
5839 
5840 		if (compl_matches > 0)
5841 		    vim_snprintf((char *)match_ref, sizeof(match_ref),
5842 				_("match %d of %d"),
5843 				compl_curr_match->cp_number, compl_matches);
5844 		else
5845 		    vim_snprintf((char *)match_ref, sizeof(match_ref),
5846 				_("match %d"),
5847 				compl_curr_match->cp_number);
5848 		edit_submode_extra = match_ref;
5849 		edit_submode_highl = HLF_R;
5850 		if (dollar_vcol >= 0)
5851 		    curs_columns(FALSE);
5852 	    }
5853 	}
5854     }
5855 
5856     /* Show a message about what (completion) mode we're in. */
5857     showmode();
5858     if (!shortmess(SHM_COMPLETIONMENU))
5859     {
5860 	if (edit_submode_extra != NULL)
5861 	{
5862 	    if (!p_smd)
5863 		msg_attr(edit_submode_extra,
5864 			edit_submode_highl < HLF_COUNT
5865 			? HL_ATTR(edit_submode_highl) : 0);
5866 	}
5867 	else
5868 	    msg_clr_cmdline();	/* necessary for "noshowmode" */
5869     }
5870 
5871     /* Show the popup menu, unless we got interrupted. */
5872     if (enable_pum && !compl_interrupted)
5873 	show_pum(save_w_wrow, save_w_leftcol);
5874 
5875     compl_was_interrupted = compl_interrupted;
5876     compl_interrupted = FALSE;
5877 
5878     return OK;
5879 }
5880 
5881     static void
5882 show_pum(int prev_w_wrow, int prev_w_leftcol)
5883 {
5884     /* RedrawingDisabled may be set when invoked through complete(). */
5885     int n = RedrawingDisabled;
5886 
5887     RedrawingDisabled = 0;
5888 
5889     /* If the cursor moved or the display scrolled we need to remove the pum
5890      * first. */
5891     setcursor();
5892     if (prev_w_wrow != curwin->w_wrow || prev_w_leftcol != curwin->w_leftcol)
5893 	ins_compl_del_pum();
5894 
5895     ins_compl_show_pum();
5896     setcursor();
5897     RedrawingDisabled = n;
5898 }
5899 
5900 /*
5901  * Looks in the first "len" chars. of "src" for search-metachars.
5902  * If dest is not NULL the chars. are copied there quoting (with
5903  * a backslash) the metachars, and dest would be NUL terminated.
5904  * Returns the length (needed) of dest
5905  */
5906     static unsigned
5907 quote_meta(char_u *dest, char_u *src, int len)
5908 {
5909     unsigned	m = (unsigned)len + 1;  /* one extra for the NUL */
5910 
5911     for ( ; --len >= 0; src++)
5912     {
5913 	switch (*src)
5914 	{
5915 	    case '.':
5916 	    case '*':
5917 	    case '[':
5918 		if (ctrl_x_mode == CTRL_X_DICTIONARY
5919 					   || ctrl_x_mode == CTRL_X_THESAURUS)
5920 		    break;
5921 		/* FALLTHROUGH */
5922 	    case '~':
5923 		if (!p_magic)	/* quote these only if magic is set */
5924 		    break;
5925 		/* FALLTHROUGH */
5926 	    case '\\':
5927 		if (ctrl_x_mode == CTRL_X_DICTIONARY
5928 					   || ctrl_x_mode == CTRL_X_THESAURUS)
5929 		    break;
5930 		/* FALLTHROUGH */
5931 	    case '^':		/* currently it's not needed. */
5932 	    case '$':
5933 		m++;
5934 		if (dest != NULL)
5935 		    *dest++ = '\\';
5936 		break;
5937 	}
5938 	if (dest != NULL)
5939 	    *dest++ = *src;
5940 # ifdef FEAT_MBYTE
5941 	/* Copy remaining bytes of a multibyte character. */
5942 	if (has_mbyte)
5943 	{
5944 	    int i, mb_len;
5945 
5946 	    mb_len = (*mb_ptr2len)(src) - 1;
5947 	    if (mb_len > 0 && len >= mb_len)
5948 		for (i = 0; i < mb_len; ++i)
5949 		{
5950 		    --len;
5951 		    ++src;
5952 		    if (dest != NULL)
5953 			*dest++ = *src;
5954 		}
5955 	}
5956 # endif
5957     }
5958     if (dest != NULL)
5959 	*dest = NUL;
5960 
5961     return m;
5962 }
5963 #endif /* FEAT_INS_EXPAND */
5964 
5965 /*
5966  * Next character is interpreted literally.
5967  * A one, two or three digit decimal number is interpreted as its byte value.
5968  * If one or two digits are entered, the next character is given to vungetc().
5969  * For Unicode a character > 255 may be returned.
5970  */
5971     int
5972 get_literal(void)
5973 {
5974     int		cc;
5975     int		nc;
5976     int		i;
5977     int		hex = FALSE;
5978     int		octal = FALSE;
5979 #ifdef FEAT_MBYTE
5980     int		unicode = 0;
5981 #endif
5982 
5983     if (got_int)
5984 	return Ctrl_C;
5985 
5986 #ifdef FEAT_GUI
5987     /*
5988      * In GUI there is no point inserting the internal code for a special key.
5989      * It is more useful to insert the string "<KEY>" instead.	This would
5990      * probably be useful in a text window too, but it would not be
5991      * vi-compatible (maybe there should be an option for it?) -- webb
5992      */
5993     if (gui.in_use)
5994 	++allow_keys;
5995 #endif
5996 #ifdef USE_ON_FLY_SCROLL
5997     dont_scroll = TRUE;		/* disallow scrolling here */
5998 #endif
5999     ++no_mapping;		/* don't map the next key hits */
6000     cc = 0;
6001     i = 0;
6002     for (;;)
6003     {
6004 	nc = plain_vgetc();
6005 #ifdef FEAT_CMDL_INFO
6006 	if (!(State & CMDLINE)
6007 # ifdef FEAT_MBYTE
6008 		&& MB_BYTE2LEN_CHECK(nc) == 1
6009 # endif
6010 	   )
6011 	    add_to_showcmd(nc);
6012 #endif
6013 	if (nc == 'x' || nc == 'X')
6014 	    hex = TRUE;
6015 	else if (nc == 'o' || nc == 'O')
6016 	    octal = TRUE;
6017 #ifdef FEAT_MBYTE
6018 	else if (nc == 'u' || nc == 'U')
6019 	    unicode = nc;
6020 #endif
6021 	else
6022 	{
6023 	    if (hex
6024 #ifdef FEAT_MBYTE
6025 		    || unicode != 0
6026 #endif
6027 		    )
6028 	    {
6029 		if (!vim_isxdigit(nc))
6030 		    break;
6031 		cc = cc * 16 + hex2nr(nc);
6032 	    }
6033 	    else if (octal)
6034 	    {
6035 		if (nc < '0' || nc > '7')
6036 		    break;
6037 		cc = cc * 8 + nc - '0';
6038 	    }
6039 	    else
6040 	    {
6041 		if (!VIM_ISDIGIT(nc))
6042 		    break;
6043 		cc = cc * 10 + nc - '0';
6044 	    }
6045 
6046 	    ++i;
6047 	}
6048 
6049 	if (cc > 255
6050 #ifdef FEAT_MBYTE
6051 		&& unicode == 0
6052 #endif
6053 		)
6054 	    cc = 255;		/* limit range to 0-255 */
6055 	nc = 0;
6056 
6057 	if (hex)		/* hex: up to two chars */
6058 	{
6059 	    if (i >= 2)
6060 		break;
6061 	}
6062 #ifdef FEAT_MBYTE
6063 	else if (unicode)	/* Unicode: up to four or eight chars */
6064 	{
6065 	    if ((unicode == 'u' && i >= 4) || (unicode == 'U' && i >= 8))
6066 		break;
6067 	}
6068 #endif
6069 	else if (i >= 3)	/* decimal or octal: up to three chars */
6070 	    break;
6071     }
6072     if (i == 0)	    /* no number entered */
6073     {
6074 	if (nc == K_ZERO)   /* NUL is stored as NL */
6075 	{
6076 	    cc = '\n';
6077 	    nc = 0;
6078 	}
6079 	else
6080 	{
6081 	    cc = nc;
6082 	    nc = 0;
6083 	}
6084     }
6085 
6086     if (cc == 0)	/* NUL is stored as NL */
6087 	cc = '\n';
6088 #ifdef FEAT_MBYTE
6089     if (enc_dbcs && (cc & 0xff) == 0)
6090 	cc = '?';	/* don't accept an illegal DBCS char, the NUL in the
6091 			   second byte will cause trouble! */
6092 #endif
6093 
6094     --no_mapping;
6095 #ifdef FEAT_GUI
6096     if (gui.in_use)
6097 	--allow_keys;
6098 #endif
6099     if (nc)
6100 	vungetc(nc);
6101     got_int = FALSE;	    /* CTRL-C typed after CTRL-V is not an interrupt */
6102     return cc;
6103 }
6104 
6105 /*
6106  * Insert character, taking care of special keys and mod_mask
6107  */
6108     static void
6109 insert_special(
6110     int	    c,
6111     int	    allow_modmask,
6112     int	    ctrlv)	    /* c was typed after CTRL-V */
6113 {
6114     char_u  *p;
6115     int	    len;
6116 
6117     /*
6118      * Special function key, translate into "<Key>". Up to the last '>' is
6119      * inserted with ins_str(), so as not to replace characters in replace
6120      * mode.
6121      * Only use mod_mask for special keys, to avoid things like <S-Space>,
6122      * unless 'allow_modmask' is TRUE.
6123      */
6124 #ifdef MACOS_X
6125     /* Command-key never produces a normal key */
6126     if (mod_mask & MOD_MASK_CMD)
6127 	allow_modmask = TRUE;
6128 #endif
6129     if (IS_SPECIAL(c) || (mod_mask && allow_modmask))
6130     {
6131 	p = get_special_key_name(c, mod_mask);
6132 	len = (int)STRLEN(p);
6133 	c = p[len - 1];
6134 	if (len > 2)
6135 	{
6136 	    if (stop_arrow() == FAIL)
6137 		return;
6138 	    p[len - 1] = NUL;
6139 	    ins_str(p);
6140 	    AppendToRedobuffLit(p, -1);
6141 	    ctrlv = FALSE;
6142 	}
6143     }
6144     if (stop_arrow() == OK)
6145 	insertchar(c, ctrlv ? INSCHAR_CTRLV : 0, -1);
6146 }
6147 
6148 /*
6149  * Special characters in this context are those that need processing other
6150  * than the simple insertion that can be performed here. This includes ESC
6151  * which terminates the insert, and CR/NL which need special processing to
6152  * open up a new line. This routine tries to optimize insertions performed by
6153  * the "redo", "undo" or "put" commands, so it needs to know when it should
6154  * stop and defer processing to the "normal" mechanism.
6155  * '0' and '^' are special, because they can be followed by CTRL-D.
6156  */
6157 #ifdef EBCDIC
6158 # define ISSPECIAL(c)	((c) < ' ' || (c) == '0' || (c) == '^')
6159 #else
6160 # define ISSPECIAL(c)	((c) < ' ' || (c) >= DEL || (c) == '0' || (c) == '^')
6161 #endif
6162 
6163 #ifdef FEAT_MBYTE
6164 # define WHITECHAR(cc) (VIM_ISWHITE(cc) && (!enc_utf8 || !utf_iscomposing(utf_ptr2char(ml_get_cursor() + 1))))
6165 #else
6166 # define WHITECHAR(cc) VIM_ISWHITE(cc)
6167 #endif
6168 
6169 /*
6170  * "flags": INSCHAR_FORMAT - force formatting
6171  *	    INSCHAR_CTRLV  - char typed just after CTRL-V
6172  *	    INSCHAR_NO_FEX - don't use 'formatexpr'
6173  *
6174  *   NOTE: passes the flags value straight through to internal_format() which,
6175  *	   beside INSCHAR_FORMAT (above), is also looking for these:
6176  *	    INSCHAR_DO_COM   - format comments
6177  *	    INSCHAR_COM_LIST - format comments with num list or 2nd line indent
6178  */
6179     void
6180 insertchar(
6181     int		c,			/* character to insert or NUL */
6182     int		flags,			/* INSCHAR_FORMAT, etc. */
6183     int		second_indent)		/* indent for second line if >= 0 */
6184 {
6185     int		textwidth;
6186 #ifdef FEAT_COMMENTS
6187     char_u	*p;
6188 #endif
6189     int		fo_ins_blank;
6190     int		force_format = flags & INSCHAR_FORMAT;
6191 
6192     textwidth = comp_textwidth(force_format);
6193     fo_ins_blank = has_format_option(FO_INS_BLANK);
6194 
6195     /*
6196      * Try to break the line in two or more pieces when:
6197      * - Always do this if we have been called to do formatting only.
6198      * - Always do this when 'formatoptions' has the 'a' flag and the line
6199      *   ends in white space.
6200      * - Otherwise:
6201      *	 - Don't do this if inserting a blank
6202      *	 - Don't do this if an existing character is being replaced, unless
6203      *	   we're in VREPLACE mode.
6204      *	 - Do this if the cursor is not on the line where insert started
6205      *	 or - 'formatoptions' doesn't have 'l' or the line was not too long
6206      *	       before the insert.
6207      *	    - 'formatoptions' doesn't have 'b' or a blank was inserted at or
6208      *	      before 'textwidth'
6209      */
6210     if (textwidth > 0
6211 	    && (force_format
6212 		|| (!VIM_ISWHITE(c)
6213 		    && !((State & REPLACE_FLAG)
6214 			&& !(State & VREPLACE_FLAG)
6215 			&& *ml_get_cursor() != NUL)
6216 		    && (curwin->w_cursor.lnum != Insstart.lnum
6217 			|| ((!has_format_option(FO_INS_LONG)
6218 				|| Insstart_textlen <= (colnr_T)textwidth)
6219 			    && (!fo_ins_blank
6220 				|| Insstart_blank_vcol <= (colnr_T)textwidth
6221 			    ))))))
6222     {
6223 	/* Format with 'formatexpr' when it's set.  Use internal formatting
6224 	 * when 'formatexpr' isn't set or it returns non-zero. */
6225 #if defined(FEAT_EVAL)
6226 	int     do_internal = TRUE;
6227 	colnr_T virtcol = get_nolist_virtcol()
6228 				  + char2cells(c != NUL ? c : gchar_cursor());
6229 
6230 	if (*curbuf->b_p_fex != NUL && (flags & INSCHAR_NO_FEX) == 0
6231 		&& (force_format || virtcol > (colnr_T)textwidth))
6232 	{
6233 	    do_internal = (fex_format(curwin->w_cursor.lnum, 1L, c) != 0);
6234 	    /* It may be required to save for undo again, e.g. when setline()
6235 	     * was called. */
6236 	    ins_need_undo = TRUE;
6237 	}
6238 	if (do_internal)
6239 #endif
6240 	    internal_format(textwidth, second_indent, flags, c == NUL, c);
6241     }
6242 
6243     if (c == NUL)	    /* only formatting was wanted */
6244 	return;
6245 
6246 #ifdef FEAT_COMMENTS
6247     /* Check whether this character should end a comment. */
6248     if (did_ai && (int)c == end_comment_pending)
6249     {
6250 	char_u  *line;
6251 	char_u	lead_end[COM_MAX_LEN];	    /* end-comment string */
6252 	int	middle_len, end_len;
6253 	int	i;
6254 
6255 	/*
6256 	 * Need to remove existing (middle) comment leader and insert end
6257 	 * comment leader.  First, check what comment leader we can find.
6258 	 */
6259 	i = get_leader_len(line = ml_get_curline(), &p, FALSE, TRUE);
6260 	if (i > 0 && vim_strchr(p, COM_MIDDLE) != NULL)	/* Just checking */
6261 	{
6262 	    /* Skip middle-comment string */
6263 	    while (*p && p[-1] != ':')	/* find end of middle flags */
6264 		++p;
6265 	    middle_len = copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
6266 	    /* Don't count trailing white space for middle_len */
6267 	    while (middle_len > 0 && VIM_ISWHITE(lead_end[middle_len - 1]))
6268 		--middle_len;
6269 
6270 	    /* Find the end-comment string */
6271 	    while (*p && p[-1] != ':')	/* find end of end flags */
6272 		++p;
6273 	    end_len = copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
6274 
6275 	    /* Skip white space before the cursor */
6276 	    i = curwin->w_cursor.col;
6277 	    while (--i >= 0 && VIM_ISWHITE(line[i]))
6278 		;
6279 	    i++;
6280 
6281 	    /* Skip to before the middle leader */
6282 	    i -= middle_len;
6283 
6284 	    /* Check some expected things before we go on */
6285 	    if (i >= 0 && lead_end[end_len - 1] == end_comment_pending)
6286 	    {
6287 		/* Backspace over all the stuff we want to replace */
6288 		backspace_until_column(i);
6289 
6290 		/*
6291 		 * Insert the end-comment string, except for the last
6292 		 * character, which will get inserted as normal later.
6293 		 */
6294 		ins_bytes_len(lead_end, end_len - 1);
6295 	    }
6296 	}
6297     }
6298     end_comment_pending = NUL;
6299 #endif
6300 
6301     did_ai = FALSE;
6302 #ifdef FEAT_SMARTINDENT
6303     did_si = FALSE;
6304     can_si = FALSE;
6305     can_si_back = FALSE;
6306 #endif
6307 
6308     /*
6309      * If there's any pending input, grab up to INPUT_BUFLEN at once.
6310      * This speeds up normal text input considerably.
6311      * Don't do this when 'cindent' or 'indentexpr' is set, because we might
6312      * need to re-indent at a ':', or any other character (but not what
6313      * 'paste' is set)..
6314      * Don't do this when there an InsertCharPre autocommand is defined,
6315      * because we need to fire the event for every character.
6316      * Do the check for InsertCharPre before the call to vpeekc() because the
6317      * InsertCharPre autocommand could change the input buffer.
6318      */
6319 #ifdef USE_ON_FLY_SCROLL
6320     dont_scroll = FALSE;		/* allow scrolling here */
6321 #endif
6322 
6323     if (       !ISSPECIAL(c)
6324 #ifdef FEAT_MBYTE
6325 	    && (!has_mbyte || (*mb_char2len)(c) == 1)
6326 #endif
6327 	    && !has_insertcharpre()
6328 	    && vpeekc() != NUL
6329 	    && !(State & REPLACE_FLAG)
6330 #ifdef FEAT_CINDENT
6331 	    && !cindent_on()
6332 #endif
6333 #ifdef FEAT_RIGHTLEFT
6334 	    && !p_ri
6335 #endif
6336 	   )
6337     {
6338 #define INPUT_BUFLEN 100
6339 	char_u		buf[INPUT_BUFLEN + 1];
6340 	int		i;
6341 	colnr_T		virtcol = 0;
6342 
6343 	buf[0] = c;
6344 	i = 1;
6345 	if (textwidth > 0)
6346 	    virtcol = get_nolist_virtcol();
6347 	/*
6348 	 * Stop the string when:
6349 	 * - no more chars available
6350 	 * - finding a special character (command key)
6351 	 * - buffer is full
6352 	 * - running into the 'textwidth' boundary
6353 	 * - need to check for abbreviation: A non-word char after a word-char
6354 	 */
6355 	while (	   (c = vpeekc()) != NUL
6356 		&& !ISSPECIAL(c)
6357 #ifdef FEAT_MBYTE
6358 		&& (!has_mbyte || MB_BYTE2LEN_CHECK(c) == 1)
6359 #endif
6360 		&& i < INPUT_BUFLEN
6361 # ifdef FEAT_FKMAP
6362 		&& !(p_fkmap && KeyTyped) /* Farsi mode mapping moves cursor */
6363 # endif
6364 		&& (textwidth == 0
6365 		    || (virtcol += byte2cells(buf[i - 1])) < (colnr_T)textwidth)
6366 		&& !(!no_abbr && !vim_iswordc(c) && vim_iswordc(buf[i - 1])))
6367 	{
6368 #ifdef FEAT_RIGHTLEFT
6369 	    c = vgetc();
6370 	    if (p_hkmap && KeyTyped)
6371 		c = hkmap(c);		    /* Hebrew mode mapping */
6372 	    buf[i++] = c;
6373 #else
6374 	    buf[i++] = vgetc();
6375 #endif
6376 	}
6377 
6378 #ifdef FEAT_DIGRAPHS
6379 	do_digraph(-1);			/* clear digraphs */
6380 	do_digraph(buf[i-1]);		/* may be the start of a digraph */
6381 #endif
6382 	buf[i] = NUL;
6383 	ins_str(buf);
6384 	if (flags & INSCHAR_CTRLV)
6385 	{
6386 	    redo_literal(*buf);
6387 	    i = 1;
6388 	}
6389 	else
6390 	    i = 0;
6391 	if (buf[i] != NUL)
6392 	    AppendToRedobuffLit(buf + i, -1);
6393     }
6394     else
6395     {
6396 #ifdef FEAT_MBYTE
6397 	int		cc;
6398 
6399 	if (has_mbyte && (cc = (*mb_char2len)(c)) > 1)
6400 	{
6401 	    char_u	buf[MB_MAXBYTES + 1];
6402 
6403 	    (*mb_char2bytes)(c, buf);
6404 	    buf[cc] = NUL;
6405 	    ins_char_bytes(buf, cc);
6406 	    AppendCharToRedobuff(c);
6407 	}
6408 	else
6409 #endif
6410 	{
6411 	    ins_char(c);
6412 	    if (flags & INSCHAR_CTRLV)
6413 		redo_literal(c);
6414 	    else
6415 		AppendCharToRedobuff(c);
6416 	}
6417     }
6418 }
6419 
6420 /*
6421  * Format text at the current insert position.
6422  *
6423  * If the INSCHAR_COM_LIST flag is present, then the value of second_indent
6424  * will be the comment leader length sent to open_line().
6425  */
6426     static void
6427 internal_format(
6428     int		textwidth,
6429     int		second_indent,
6430     int		flags,
6431     int		format_only,
6432     int		c) /* character to be inserted (can be NUL) */
6433 {
6434     int		cc;
6435     int		save_char = NUL;
6436     int		haveto_redraw = FALSE;
6437     int		fo_ins_blank = has_format_option(FO_INS_BLANK);
6438 #ifdef FEAT_MBYTE
6439     int		fo_multibyte = has_format_option(FO_MBYTE_BREAK);
6440 #endif
6441     int		fo_white_par = has_format_option(FO_WHITE_PAR);
6442     int		first_line = TRUE;
6443 #ifdef FEAT_COMMENTS
6444     colnr_T	leader_len;
6445     int		no_leader = FALSE;
6446     int		do_comments = (flags & INSCHAR_DO_COM);
6447 #endif
6448 #ifdef FEAT_LINEBREAK
6449     int		has_lbr = curwin->w_p_lbr;
6450 
6451     /* make sure win_lbr_chartabsize() counts correctly */
6452     curwin->w_p_lbr = FALSE;
6453 #endif
6454 
6455     /*
6456      * When 'ai' is off we don't want a space under the cursor to be
6457      * deleted.  Replace it with an 'x' temporarily.
6458      */
6459     if (!curbuf->b_p_ai && !(State & VREPLACE_FLAG))
6460     {
6461 	cc = gchar_cursor();
6462 	if (VIM_ISWHITE(cc))
6463 	{
6464 	    save_char = cc;
6465 	    pchar_cursor('x');
6466 	}
6467     }
6468 
6469     /*
6470      * Repeat breaking lines, until the current line is not too long.
6471      */
6472     while (!got_int)
6473     {
6474 	int	startcol;		/* Cursor column at entry */
6475 	int	wantcol;		/* column at textwidth border */
6476 	int	foundcol;		/* column for start of spaces */
6477 	int	end_foundcol = 0;	/* column for start of word */
6478 	colnr_T	len;
6479 	colnr_T	virtcol;
6480 	int	orig_col = 0;
6481 	char_u	*saved_text = NULL;
6482 	colnr_T	col;
6483 	colnr_T	end_col;
6484 
6485 	virtcol = get_nolist_virtcol()
6486 		+ char2cells(c != NUL ? c : gchar_cursor());
6487 	if (virtcol <= (colnr_T)textwidth)
6488 	    break;
6489 
6490 #ifdef FEAT_COMMENTS
6491 	if (no_leader)
6492 	    do_comments = FALSE;
6493 	else if (!(flags & INSCHAR_FORMAT)
6494 				       && has_format_option(FO_WRAP_COMS))
6495 	    do_comments = TRUE;
6496 
6497 	/* Don't break until after the comment leader */
6498 	if (do_comments)
6499 	    leader_len = get_leader_len(ml_get_curline(), NULL, FALSE, TRUE);
6500 	else
6501 	    leader_len = 0;
6502 
6503 	/* If the line doesn't start with a comment leader, then don't
6504 	 * start one in a following broken line.  Avoids that a %word
6505 	 * moved to the start of the next line causes all following lines
6506 	 * to start with %. */
6507 	if (leader_len == 0)
6508 	    no_leader = TRUE;
6509 #endif
6510 	if (!(flags & INSCHAR_FORMAT)
6511 #ifdef FEAT_COMMENTS
6512 		&& leader_len == 0
6513 #endif
6514 		&& !has_format_option(FO_WRAP))
6515 
6516 	    break;
6517 	if ((startcol = curwin->w_cursor.col) == 0)
6518 	    break;
6519 
6520 	/* find column of textwidth border */
6521 	coladvance((colnr_T)textwidth);
6522 	wantcol = curwin->w_cursor.col;
6523 
6524 	curwin->w_cursor.col = startcol;
6525 	foundcol = 0;
6526 
6527 	/*
6528 	 * Find position to break at.
6529 	 * Stop at first entered white when 'formatoptions' has 'v'
6530 	 */
6531 	while ((!fo_ins_blank && !has_format_option(FO_INS_VI))
6532 		    || (flags & INSCHAR_FORMAT)
6533 		    || curwin->w_cursor.lnum != Insstart.lnum
6534 		    || curwin->w_cursor.col >= Insstart.col)
6535 	{
6536 	    if (curwin->w_cursor.col == startcol && c != NUL)
6537 		cc = c;
6538 	    else
6539 		cc = gchar_cursor();
6540 	    if (WHITECHAR(cc))
6541 	    {
6542 		/* remember position of blank just before text */
6543 		end_col = curwin->w_cursor.col;
6544 
6545 		/* find start of sequence of blanks */
6546 		while (curwin->w_cursor.col > 0 && WHITECHAR(cc))
6547 		{
6548 		    dec_cursor();
6549 		    cc = gchar_cursor();
6550 		}
6551 		if (curwin->w_cursor.col == 0 && WHITECHAR(cc))
6552 		    break;		/* only spaces in front of text */
6553 #ifdef FEAT_COMMENTS
6554 		/* Don't break until after the comment leader */
6555 		if (curwin->w_cursor.col < leader_len)
6556 		    break;
6557 #endif
6558 		if (has_format_option(FO_ONE_LETTER))
6559 		{
6560 		    /* do not break after one-letter words */
6561 		    if (curwin->w_cursor.col == 0)
6562 			break;	/* one-letter word at begin */
6563 #ifdef FEAT_COMMENTS
6564 		    /* do not break "#a b" when 'tw' is 2 */
6565 		    if (curwin->w_cursor.col <= leader_len)
6566 			break;
6567 #endif
6568 		    col = curwin->w_cursor.col;
6569 		    dec_cursor();
6570 		    cc = gchar_cursor();
6571 
6572 		    if (WHITECHAR(cc))
6573 			continue;	/* one-letter, continue */
6574 		    curwin->w_cursor.col = col;
6575 		}
6576 
6577 		inc_cursor();
6578 
6579 		end_foundcol = end_col + 1;
6580 		foundcol = curwin->w_cursor.col;
6581 		if (curwin->w_cursor.col <= (colnr_T)wantcol)
6582 		    break;
6583 	    }
6584 #ifdef FEAT_MBYTE
6585 	    else if (cc >= 0x100 && fo_multibyte)
6586 	    {
6587 		/* Break after or before a multi-byte character. */
6588 		if (curwin->w_cursor.col != startcol)
6589 		{
6590 #ifdef FEAT_COMMENTS
6591 		    /* Don't break until after the comment leader */
6592 		    if (curwin->w_cursor.col < leader_len)
6593 			break;
6594 #endif
6595 		    col = curwin->w_cursor.col;
6596 		    inc_cursor();
6597 		    /* Don't change end_foundcol if already set. */
6598 		    if (foundcol != curwin->w_cursor.col)
6599 		    {
6600 			foundcol = curwin->w_cursor.col;
6601 			end_foundcol = foundcol;
6602 			if (curwin->w_cursor.col <= (colnr_T)wantcol)
6603 			    break;
6604 		    }
6605 		    curwin->w_cursor.col = col;
6606 		}
6607 
6608 		if (curwin->w_cursor.col == 0)
6609 		    break;
6610 
6611 		col = curwin->w_cursor.col;
6612 
6613 		dec_cursor();
6614 		cc = gchar_cursor();
6615 
6616 		if (WHITECHAR(cc))
6617 		    continue;		/* break with space */
6618 #ifdef FEAT_COMMENTS
6619 		/* Don't break until after the comment leader */
6620 		if (curwin->w_cursor.col < leader_len)
6621 		    break;
6622 #endif
6623 
6624 		curwin->w_cursor.col = col;
6625 
6626 		foundcol = curwin->w_cursor.col;
6627 		end_foundcol = foundcol;
6628 		if (curwin->w_cursor.col <= (colnr_T)wantcol)
6629 		    break;
6630 	    }
6631 #endif
6632 	    if (curwin->w_cursor.col == 0)
6633 		break;
6634 	    dec_cursor();
6635 	}
6636 
6637 	if (foundcol == 0)		/* no spaces, cannot break line */
6638 	{
6639 	    curwin->w_cursor.col = startcol;
6640 	    break;
6641 	}
6642 
6643 	/* Going to break the line, remove any "$" now. */
6644 	undisplay_dollar();
6645 
6646 	/*
6647 	 * Offset between cursor position and line break is used by replace
6648 	 * stack functions.  VREPLACE does not use this, and backspaces
6649 	 * over the text instead.
6650 	 */
6651 	if (State & VREPLACE_FLAG)
6652 	    orig_col = startcol;	/* Will start backspacing from here */
6653 	else
6654 	    replace_offset = startcol - end_foundcol;
6655 
6656 	/*
6657 	 * adjust startcol for spaces that will be deleted and
6658 	 * characters that will remain on top line
6659 	 */
6660 	curwin->w_cursor.col = foundcol;
6661 	while ((cc = gchar_cursor(), WHITECHAR(cc))
6662 		    && (!fo_white_par || curwin->w_cursor.col < startcol))
6663 	    inc_cursor();
6664 	startcol -= curwin->w_cursor.col;
6665 	if (startcol < 0)
6666 	    startcol = 0;
6667 
6668 	if (State & VREPLACE_FLAG)
6669 	{
6670 	    /*
6671 	     * In VREPLACE mode, we will backspace over the text to be
6672 	     * wrapped, so save a copy now to put on the next line.
6673 	     */
6674 	    saved_text = vim_strsave(ml_get_cursor());
6675 	    curwin->w_cursor.col = orig_col;
6676 	    if (saved_text == NULL)
6677 		break;	/* Can't do it, out of memory */
6678 	    saved_text[startcol] = NUL;
6679 
6680 	    /* Backspace over characters that will move to the next line */
6681 	    if (!fo_white_par)
6682 		backspace_until_column(foundcol);
6683 	}
6684 	else
6685 	{
6686 	    /* put cursor after pos. to break line */
6687 	    if (!fo_white_par)
6688 		curwin->w_cursor.col = foundcol;
6689 	}
6690 
6691 	/*
6692 	 * Split the line just before the margin.
6693 	 * Only insert/delete lines, but don't really redraw the window.
6694 	 */
6695 	open_line(FORWARD, OPENLINE_DELSPACES + OPENLINE_MARKFIX
6696 		+ (fo_white_par ? OPENLINE_KEEPTRAIL : 0)
6697 #ifdef FEAT_COMMENTS
6698 		+ (do_comments ? OPENLINE_DO_COM : 0)
6699 		+ ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0)
6700 #endif
6701 		, ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent));
6702 	if (!(flags & INSCHAR_COM_LIST))
6703 	    old_indent = 0;
6704 
6705 	replace_offset = 0;
6706 	if (first_line)
6707 	{
6708 	    if (!(flags & INSCHAR_COM_LIST))
6709 	    {
6710 		/*
6711 		 * This section is for auto-wrap of numeric lists.  When not
6712 		 * in insert mode (i.e. format_lines()), the INSCHAR_COM_LIST
6713 		 * flag will be set and open_line() will handle it (as seen
6714 		 * above).  The code here (and in get_number_indent()) will
6715 		 * recognize comments if needed...
6716 		 */
6717 		if (second_indent < 0 && has_format_option(FO_Q_NUMBER))
6718 		    second_indent =
6719 				 get_number_indent(curwin->w_cursor.lnum - 1);
6720 		if (second_indent >= 0)
6721 		{
6722 		    if (State & VREPLACE_FLAG)
6723 			change_indent(INDENT_SET, second_indent,
6724 							    FALSE, NUL, TRUE);
6725 		    else
6726 #ifdef FEAT_COMMENTS
6727 			if (leader_len > 0 && second_indent - leader_len > 0)
6728 		    {
6729 			int i;
6730 			int padding = second_indent - leader_len;
6731 
6732 			/* We started at the first_line of a numbered list
6733 			 * that has a comment.  the open_line() function has
6734 			 * inserted the proper comment leader and positioned
6735 			 * the cursor at the end of the split line.  Now we
6736 			 * add the additional whitespace needed after the
6737 			 * comment leader for the numbered list.  */
6738 			for (i = 0; i < padding; i++)
6739 			    ins_str((char_u *)" ");
6740 			changed_bytes(curwin->w_cursor.lnum, leader_len);
6741 		    }
6742 		    else
6743 		    {
6744 #endif
6745 			(void)set_indent(second_indent, SIN_CHANGED);
6746 #ifdef FEAT_COMMENTS
6747 		    }
6748 #endif
6749 		}
6750 	    }
6751 	    first_line = FALSE;
6752 	}
6753 
6754 	if (State & VREPLACE_FLAG)
6755 	{
6756 	    /*
6757 	     * In VREPLACE mode we have backspaced over the text to be
6758 	     * moved, now we re-insert it into the new line.
6759 	     */
6760 	    ins_bytes(saved_text);
6761 	    vim_free(saved_text);
6762 	}
6763 	else
6764 	{
6765 	    /*
6766 	     * Check if cursor is not past the NUL off the line, cindent
6767 	     * may have added or removed indent.
6768 	     */
6769 	    curwin->w_cursor.col += startcol;
6770 	    len = (colnr_T)STRLEN(ml_get_curline());
6771 	    if (curwin->w_cursor.col > len)
6772 		curwin->w_cursor.col = len;
6773 	}
6774 
6775 	haveto_redraw = TRUE;
6776 #ifdef FEAT_CINDENT
6777 	can_cindent = TRUE;
6778 #endif
6779 	/* moved the cursor, don't autoindent or cindent now */
6780 	did_ai = FALSE;
6781 #ifdef FEAT_SMARTINDENT
6782 	did_si = FALSE;
6783 	can_si = FALSE;
6784 	can_si_back = FALSE;
6785 #endif
6786 	line_breakcheck();
6787     }
6788 
6789     if (save_char != NUL)		/* put back space after cursor */
6790 	pchar_cursor(save_char);
6791 
6792 #ifdef FEAT_LINEBREAK
6793     curwin->w_p_lbr = has_lbr;
6794 #endif
6795     if (!format_only && haveto_redraw)
6796     {
6797 	update_topline();
6798 	redraw_curbuf_later(VALID);
6799     }
6800 }
6801 
6802 /*
6803  * Called after inserting or deleting text: When 'formatoptions' includes the
6804  * 'a' flag format from the current line until the end of the paragraph.
6805  * Keep the cursor at the same position relative to the text.
6806  * The caller must have saved the cursor line for undo, following ones will be
6807  * saved here.
6808  */
6809     void
6810 auto_format(
6811     int		trailblank,	/* when TRUE also format with trailing blank */
6812     int		prev_line)	/* may start in previous line */
6813 {
6814     pos_T	pos;
6815     colnr_T	len;
6816     char_u	*old;
6817     char_u	*new, *pnew;
6818     int		wasatend;
6819     int		cc;
6820 
6821     if (!has_format_option(FO_AUTO))
6822 	return;
6823 
6824     pos = curwin->w_cursor;
6825     old = ml_get_curline();
6826 
6827     /* may remove added space */
6828     check_auto_format(FALSE);
6829 
6830     /* Don't format in Insert mode when the cursor is on a trailing blank, the
6831      * user might insert normal text next.  Also skip formatting when "1" is
6832      * in 'formatoptions' and there is a single character before the cursor.
6833      * Otherwise the line would be broken and when typing another non-white
6834      * next they are not joined back together. */
6835     wasatend = (pos.col == (colnr_T)STRLEN(old));
6836     if (*old != NUL && !trailblank && wasatend)
6837     {
6838 	dec_cursor();
6839 	cc = gchar_cursor();
6840 	if (!WHITECHAR(cc) && curwin->w_cursor.col > 0
6841 					  && has_format_option(FO_ONE_LETTER))
6842 	    dec_cursor();
6843 	cc = gchar_cursor();
6844 	if (WHITECHAR(cc))
6845 	{
6846 	    curwin->w_cursor = pos;
6847 	    return;
6848 	}
6849 	curwin->w_cursor = pos;
6850     }
6851 
6852 #ifdef FEAT_COMMENTS
6853     /* With the 'c' flag in 'formatoptions' and 't' missing: only format
6854      * comments. */
6855     if (has_format_option(FO_WRAP_COMS) && !has_format_option(FO_WRAP)
6856 				     && get_leader_len(old, NULL, FALSE, TRUE) == 0)
6857 	return;
6858 #endif
6859 
6860     /*
6861      * May start formatting in a previous line, so that after "x" a word is
6862      * moved to the previous line if it fits there now.  Only when this is not
6863      * the start of a paragraph.
6864      */
6865     if (prev_line && !paragraph_start(curwin->w_cursor.lnum))
6866     {
6867 	--curwin->w_cursor.lnum;
6868 	if (u_save_cursor() == FAIL)
6869 	    return;
6870     }
6871 
6872     /*
6873      * Do the formatting and restore the cursor position.  "saved_cursor" will
6874      * be adjusted for the text formatting.
6875      */
6876     saved_cursor = pos;
6877     format_lines((linenr_T)-1, FALSE);
6878     curwin->w_cursor = saved_cursor;
6879     saved_cursor.lnum = 0;
6880 
6881     if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
6882     {
6883 	/* "cannot happen" */
6884 	curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
6885 	coladvance((colnr_T)MAXCOL);
6886     }
6887     else
6888 	check_cursor_col();
6889 
6890     /* Insert mode: If the cursor is now after the end of the line while it
6891      * previously wasn't, the line was broken.  Because of the rule above we
6892      * need to add a space when 'w' is in 'formatoptions' to keep a paragraph
6893      * formatted. */
6894     if (!wasatend && has_format_option(FO_WHITE_PAR))
6895     {
6896 	new = ml_get_curline();
6897 	len = (colnr_T)STRLEN(new);
6898 	if (curwin->w_cursor.col == len)
6899 	{
6900 	    pnew = vim_strnsave(new, len + 2);
6901 	    pnew[len] = ' ';
6902 	    pnew[len + 1] = NUL;
6903 	    ml_replace(curwin->w_cursor.lnum, pnew, FALSE);
6904 	    /* remove the space later */
6905 	    did_add_space = TRUE;
6906 	}
6907 	else
6908 	    /* may remove added space */
6909 	    check_auto_format(FALSE);
6910     }
6911 
6912     check_cursor();
6913 }
6914 
6915 /*
6916  * When an extra space was added to continue a paragraph for auto-formatting,
6917  * delete it now.  The space must be under the cursor, just after the insert
6918  * position.
6919  */
6920     static void
6921 check_auto_format(
6922     int		end_insert)	    /* TRUE when ending Insert mode */
6923 {
6924     int		c = ' ';
6925     int		cc;
6926 
6927     if (did_add_space)
6928     {
6929 	cc = gchar_cursor();
6930 	if (!WHITECHAR(cc))
6931 	    /* Somehow the space was removed already. */
6932 	    did_add_space = FALSE;
6933 	else
6934 	{
6935 	    if (!end_insert)
6936 	    {
6937 		inc_cursor();
6938 		c = gchar_cursor();
6939 		dec_cursor();
6940 	    }
6941 	    if (c != NUL)
6942 	    {
6943 		/* The space is no longer at the end of the line, delete it. */
6944 		del_char(FALSE);
6945 		did_add_space = FALSE;
6946 	    }
6947 	}
6948     }
6949 }
6950 
6951 /*
6952  * Find out textwidth to be used for formatting:
6953  *	if 'textwidth' option is set, use it
6954  *	else if 'wrapmargin' option is set, use curwin->w_width - 'wrapmargin'
6955  *	if invalid value, use 0.
6956  *	Set default to window width (maximum 79) for "gq" operator.
6957  */
6958     int
6959 comp_textwidth(
6960     int		ff)	/* force formatting (for "gq" command) */
6961 {
6962     int		textwidth;
6963 
6964     textwidth = curbuf->b_p_tw;
6965     if (textwidth == 0 && curbuf->b_p_wm)
6966     {
6967 	/* The width is the window width minus 'wrapmargin' minus all the
6968 	 * things that add to the margin. */
6969 	textwidth = curwin->w_width - curbuf->b_p_wm;
6970 #ifdef FEAT_CMDWIN
6971 	if (cmdwin_type != 0)
6972 	    textwidth -= 1;
6973 #endif
6974 #ifdef FEAT_FOLDING
6975 	textwidth -= curwin->w_p_fdc;
6976 #endif
6977 #ifdef FEAT_SIGNS
6978 	if (signcolumn_on(curwin))
6979 	    textwidth -= 1;
6980 #endif
6981 	if (curwin->w_p_nu || curwin->w_p_rnu)
6982 	    textwidth -= 8;
6983     }
6984     if (textwidth < 0)
6985 	textwidth = 0;
6986     if (ff && textwidth == 0)
6987     {
6988 	textwidth = curwin->w_width - 1;
6989 	if (textwidth > 79)
6990 	    textwidth = 79;
6991     }
6992     return textwidth;
6993 }
6994 
6995 /*
6996  * Put a character in the redo buffer, for when just after a CTRL-V.
6997  */
6998     static void
6999 redo_literal(int c)
7000 {
7001     char_u	buf[10];
7002 
7003     /* Only digits need special treatment.  Translate them into a string of
7004      * three digits. */
7005     if (VIM_ISDIGIT(c))
7006     {
7007 	vim_snprintf((char *)buf, sizeof(buf), "%03d", c);
7008 	AppendToRedobuff(buf);
7009     }
7010     else
7011 	AppendCharToRedobuff(c);
7012 }
7013 
7014 /*
7015  * start_arrow() is called when an arrow key is used in insert mode.
7016  * For undo/redo it resembles hitting the <ESC> key.
7017  */
7018     static void
7019 start_arrow(
7020     pos_T    *end_insert_pos)		/* can be NULL */
7021 {
7022     start_arrow_common(end_insert_pos, TRUE);
7023 }
7024 
7025 /*
7026  * Like start_arrow() but with end_change argument.
7027  * Will prepare for redo of CTRL-G U if "end_change" is FALSE.
7028  */
7029     static void
7030 start_arrow_with_change(
7031     pos_T    *end_insert_pos,		/* can be NULL */
7032     int	      end_change)		/* end undoable change */
7033 {
7034     start_arrow_common(end_insert_pos, end_change);
7035     if (!end_change)
7036     {
7037 	AppendCharToRedobuff(Ctrl_G);
7038 	AppendCharToRedobuff('U');
7039     }
7040 }
7041 
7042     static void
7043 start_arrow_common(
7044     pos_T    *end_insert_pos,		/* can be NULL */
7045     int	      end_change)		/* end undoable change */
7046 {
7047     if (!arrow_used && end_change)	/* something has been inserted */
7048     {
7049 	AppendToRedobuff(ESC_STR);
7050 	stop_insert(end_insert_pos, FALSE, FALSE);
7051 	arrow_used = TRUE;	/* this means we stopped the current insert */
7052     }
7053 #ifdef FEAT_SPELL
7054     check_spell_redraw();
7055 #endif
7056 }
7057 
7058 #ifdef FEAT_SPELL
7059 /*
7060  * If we skipped highlighting word at cursor, do it now.
7061  * It may be skipped again, thus reset spell_redraw_lnum first.
7062  */
7063     static void
7064 check_spell_redraw(void)
7065 {
7066     if (spell_redraw_lnum != 0)
7067     {
7068 	linenr_T	lnum = spell_redraw_lnum;
7069 
7070 	spell_redraw_lnum = 0;
7071 	redrawWinline(curwin, lnum, FALSE);
7072     }
7073 }
7074 
7075 /*
7076  * Called when starting CTRL_X_SPELL mode: Move backwards to a previous badly
7077  * spelled word, if there is one.
7078  */
7079     static void
7080 spell_back_to_badword(void)
7081 {
7082     pos_T	tpos = curwin->w_cursor;
7083 
7084     spell_bad_len = spell_move_to(curwin, BACKWARD, TRUE, TRUE, NULL);
7085     if (curwin->w_cursor.col != tpos.col)
7086 	start_arrow(&tpos);
7087 }
7088 #endif
7089 
7090 /*
7091  * stop_arrow() is called before a change is made in insert mode.
7092  * If an arrow key has been used, start a new insertion.
7093  * Returns FAIL if undo is impossible, shouldn't insert then.
7094  */
7095     int
7096 stop_arrow(void)
7097 {
7098     if (arrow_used)
7099     {
7100 	Insstart = curwin->w_cursor;	/* new insertion starts here */
7101 	if (Insstart.col > Insstart_orig.col && !ins_need_undo)
7102 	    /* Don't update the original insert position when moved to the
7103 	     * right, except when nothing was inserted yet. */
7104 	    update_Insstart_orig = FALSE;
7105 	Insstart_textlen = (colnr_T)linetabsize(ml_get_curline());
7106 
7107 	if (u_save_cursor() == OK)
7108 	{
7109 	    arrow_used = FALSE;
7110 	    ins_need_undo = FALSE;
7111 	}
7112 
7113 	ai_col = 0;
7114 	if (State & VREPLACE_FLAG)
7115 	{
7116 	    orig_line_count = curbuf->b_ml.ml_line_count;
7117 	    vr_lines_changed = 1;
7118 	}
7119 	ResetRedobuff();
7120 	AppendToRedobuff((char_u *)"1i");   /* pretend we start an insertion */
7121 	new_insert_skip = 2;
7122     }
7123     else if (ins_need_undo)
7124     {
7125 	if (u_save_cursor() == OK)
7126 	    ins_need_undo = FALSE;
7127     }
7128 
7129 #ifdef FEAT_FOLDING
7130     /* Always open fold at the cursor line when inserting something. */
7131     foldOpenCursor();
7132 #endif
7133 
7134     return (arrow_used || ins_need_undo ? FAIL : OK);
7135 }
7136 
7137 /*
7138  * Do a few things to stop inserting.
7139  * "end_insert_pos" is where insert ended.  It is NULL when we already jumped
7140  * to another window/buffer.
7141  */
7142     static void
7143 stop_insert(
7144     pos_T	*end_insert_pos,
7145     int		esc,			/* called by ins_esc() */
7146     int		nomove)			/* <c-\><c-o>, don't move cursor */
7147 {
7148     int		cc;
7149     char_u	*ptr;
7150 
7151     stop_redo_ins();
7152     replace_flush();		/* abandon replace stack */
7153 
7154     /*
7155      * Save the inserted text for later redo with ^@ and CTRL-A.
7156      * Don't do it when "restart_edit" was set and nothing was inserted,
7157      * otherwise CTRL-O w and then <Left> will clear "last_insert".
7158      */
7159     ptr = get_inserted();
7160     if (did_restart_edit == 0 || (ptr != NULL
7161 				       && (int)STRLEN(ptr) > new_insert_skip))
7162     {
7163 	vim_free(last_insert);
7164 	last_insert = ptr;
7165 	last_insert_skip = new_insert_skip;
7166     }
7167     else
7168 	vim_free(ptr);
7169 
7170     if (!arrow_used && end_insert_pos != NULL)
7171     {
7172 	/* Auto-format now.  It may seem strange to do this when stopping an
7173 	 * insertion (or moving the cursor), but it's required when appending
7174 	 * a line and having it end in a space.  But only do it when something
7175 	 * was actually inserted, otherwise undo won't work. */
7176 	if (!ins_need_undo && has_format_option(FO_AUTO))
7177 	{
7178 	    pos_T   tpos = curwin->w_cursor;
7179 
7180 	    /* When the cursor is at the end of the line after a space the
7181 	     * formatting will move it to the following word.  Avoid that by
7182 	     * moving the cursor onto the space. */
7183 	    cc = 'x';
7184 	    if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL)
7185 	    {
7186 		dec_cursor();
7187 		cc = gchar_cursor();
7188 		if (!VIM_ISWHITE(cc))
7189 		    curwin->w_cursor = tpos;
7190 	    }
7191 
7192 	    auto_format(TRUE, FALSE);
7193 
7194 	    if (VIM_ISWHITE(cc))
7195 	    {
7196 		if (gchar_cursor() != NUL)
7197 		    inc_cursor();
7198 #ifdef FEAT_VIRTUALEDIT
7199 		/* If the cursor is still at the same character, also keep
7200 		 * the "coladd". */
7201 		if (gchar_cursor() == NUL
7202 			&& curwin->w_cursor.lnum == tpos.lnum
7203 			&& curwin->w_cursor.col == tpos.col)
7204 		    curwin->w_cursor.coladd = tpos.coladd;
7205 #endif
7206 	    }
7207 	}
7208 
7209 	/* If a space was inserted for auto-formatting, remove it now. */
7210 	check_auto_format(TRUE);
7211 
7212 	/* If we just did an auto-indent, remove the white space from the end
7213 	 * of the line, and put the cursor back.
7214 	 * Do this when ESC was used or moving the cursor up/down.
7215 	 * Check for the old position still being valid, just in case the text
7216 	 * got changed unexpectedly. */
7217 	if (!nomove && did_ai && (esc || (vim_strchr(p_cpo, CPO_INDENT) == NULL
7218 			&& curwin->w_cursor.lnum != end_insert_pos->lnum))
7219 		&& end_insert_pos->lnum <= curbuf->b_ml.ml_line_count)
7220 	{
7221 	    pos_T	tpos = curwin->w_cursor;
7222 
7223 	    curwin->w_cursor = *end_insert_pos;
7224 	    check_cursor_col();  /* make sure it is not past the line */
7225 	    for (;;)
7226 	    {
7227 		if (gchar_cursor() == NUL && curwin->w_cursor.col > 0)
7228 		    --curwin->w_cursor.col;
7229 		cc = gchar_cursor();
7230 		if (!VIM_ISWHITE(cc))
7231 		    break;
7232 		if (del_char(TRUE) == FAIL)
7233 		    break;  /* should not happen */
7234 	    }
7235 	    if (curwin->w_cursor.lnum != tpos.lnum)
7236 		curwin->w_cursor = tpos;
7237 	    else
7238 	    {
7239 		/* reset tpos, could have been invalidated in the loop above */
7240 		tpos = curwin->w_cursor;
7241 		tpos.col++;
7242 		if (cc != NUL && gchar_pos(&tpos) == NUL)
7243 		    ++curwin->w_cursor.col;	/* put cursor back on the NUL */
7244 	    }
7245 
7246 	    /* <C-S-Right> may have started Visual mode, adjust the position for
7247 	     * deleted characters. */
7248 	    if (VIsual_active && VIsual.lnum == curwin->w_cursor.lnum)
7249 	    {
7250 		int len = (int)STRLEN(ml_get_curline());
7251 
7252 		if (VIsual.col > len)
7253 		{
7254 		    VIsual.col = len;
7255 #ifdef FEAT_VIRTUALEDIT
7256 		    VIsual.coladd = 0;
7257 #endif
7258 		}
7259 	    }
7260 	}
7261     }
7262     did_ai = FALSE;
7263 #ifdef FEAT_SMARTINDENT
7264     did_si = FALSE;
7265     can_si = FALSE;
7266     can_si_back = FALSE;
7267 #endif
7268 
7269     /* Set '[ and '] to the inserted text.  When end_insert_pos is NULL we are
7270      * now in a different buffer. */
7271     if (end_insert_pos != NULL)
7272     {
7273 	curbuf->b_op_start = Insstart;
7274 	curbuf->b_op_start_orig = Insstart_orig;
7275 	curbuf->b_op_end = *end_insert_pos;
7276     }
7277 }
7278 
7279 /*
7280  * Set the last inserted text to a single character.
7281  * Used for the replace command.
7282  */
7283     void
7284 set_last_insert(int c)
7285 {
7286     char_u	*s;
7287 
7288     vim_free(last_insert);
7289     last_insert = alloc(MB_MAXBYTES * 3 + 5);
7290     if (last_insert != NULL)
7291     {
7292 	s = last_insert;
7293 	/* Use the CTRL-V only when entering a special char */
7294 	if (c < ' ' || c == DEL)
7295 	    *s++ = Ctrl_V;
7296 	s = add_char2buf(c, s);
7297 	*s++ = ESC;
7298 	*s++ = NUL;
7299 	last_insert_skip = 0;
7300     }
7301 }
7302 
7303 #if defined(EXITFREE) || defined(PROTO)
7304     void
7305 free_last_insert(void)
7306 {
7307     VIM_CLEAR(last_insert);
7308 # ifdef FEAT_INS_EXPAND
7309     VIM_CLEAR(compl_orig_text);
7310 # endif
7311 }
7312 #endif
7313 
7314 /*
7315  * Add character "c" to buffer "s".  Escape the special meaning of K_SPECIAL
7316  * and CSI.  Handle multi-byte characters.
7317  * Returns a pointer to after the added bytes.
7318  */
7319     char_u *
7320 add_char2buf(int c, char_u *s)
7321 {
7322 #ifdef FEAT_MBYTE
7323     char_u	temp[MB_MAXBYTES + 1];
7324     int		i;
7325     int		len;
7326 
7327     len = (*mb_char2bytes)(c, temp);
7328     for (i = 0; i < len; ++i)
7329     {
7330 	c = temp[i];
7331 #endif
7332 	/* Need to escape K_SPECIAL and CSI like in the typeahead buffer. */
7333 	if (c == K_SPECIAL)
7334 	{
7335 	    *s++ = K_SPECIAL;
7336 	    *s++ = KS_SPECIAL;
7337 	    *s++ = KE_FILLER;
7338 	}
7339 #ifdef FEAT_GUI
7340 	else if (c == CSI)
7341 	{
7342 	    *s++ = CSI;
7343 	    *s++ = KS_EXTRA;
7344 	    *s++ = (int)KE_CSI;
7345 	}
7346 #endif
7347 	else
7348 	    *s++ = c;
7349 #ifdef FEAT_MBYTE
7350     }
7351 #endif
7352     return s;
7353 }
7354 
7355 /*
7356  * move cursor to start of line
7357  * if flags & BL_WHITE	move to first non-white
7358  * if flags & BL_SOL	move to first non-white if startofline is set,
7359  *			    otherwise keep "curswant" column
7360  * if flags & BL_FIX	don't leave the cursor on a NUL.
7361  */
7362     void
7363 beginline(int flags)
7364 {
7365     if ((flags & BL_SOL) && !p_sol)
7366 	coladvance(curwin->w_curswant);
7367     else
7368     {
7369 	curwin->w_cursor.col = 0;
7370 #ifdef FEAT_VIRTUALEDIT
7371 	curwin->w_cursor.coladd = 0;
7372 #endif
7373 
7374 	if (flags & (BL_WHITE | BL_SOL))
7375 	{
7376 	    char_u  *ptr;
7377 
7378 	    for (ptr = ml_get_curline(); VIM_ISWHITE(*ptr)
7379 			       && !((flags & BL_FIX) && ptr[1] == NUL); ++ptr)
7380 		++curwin->w_cursor.col;
7381 	}
7382 	curwin->w_set_curswant = TRUE;
7383     }
7384 }
7385 
7386 /*
7387  * oneright oneleft cursor_down cursor_up
7388  *
7389  * Move one char {right,left,down,up}.
7390  * Doesn't move onto the NUL past the end of the line, unless it is allowed.
7391  * Return OK when successful, FAIL when we hit a line of file boundary.
7392  */
7393 
7394     int
7395 oneright(void)
7396 {
7397     char_u	*ptr;
7398     int		l;
7399 
7400 #ifdef FEAT_VIRTUALEDIT
7401     if (virtual_active())
7402     {
7403 	pos_T	prevpos = curwin->w_cursor;
7404 
7405 	/* Adjust for multi-wide char (excluding TAB) */
7406 	ptr = ml_get_cursor();
7407 	coladvance(getviscol() + ((*ptr != TAB && vim_isprintc(
7408 # ifdef FEAT_MBYTE
7409 			    (*mb_ptr2char)(ptr)
7410 # else
7411 			    *ptr
7412 # endif
7413 			    ))
7414 		    ? ptr2cells(ptr) : 1));
7415 	curwin->w_set_curswant = TRUE;
7416 	/* Return OK if the cursor moved, FAIL otherwise (at window edge). */
7417 	return (prevpos.col != curwin->w_cursor.col
7418 		    || prevpos.coladd != curwin->w_cursor.coladd) ? OK : FAIL;
7419     }
7420 #endif
7421 
7422     ptr = ml_get_cursor();
7423     if (*ptr == NUL)
7424 	return FAIL;	    /* already at the very end */
7425 
7426 #ifdef FEAT_MBYTE
7427     if (has_mbyte)
7428 	l = (*mb_ptr2len)(ptr);
7429     else
7430 #endif
7431 	l = 1;
7432 
7433     /* move "l" bytes right, but don't end up on the NUL, unless 'virtualedit'
7434      * contains "onemore". */
7435     if (ptr[l] == NUL
7436 #ifdef FEAT_VIRTUALEDIT
7437 	    && (ve_flags & VE_ONEMORE) == 0
7438 #endif
7439 	    )
7440 	return FAIL;
7441     curwin->w_cursor.col += l;
7442 
7443     curwin->w_set_curswant = TRUE;
7444     return OK;
7445 }
7446 
7447     int
7448 oneleft(void)
7449 {
7450 #ifdef FEAT_VIRTUALEDIT
7451     if (virtual_active())
7452     {
7453 # ifdef FEAT_LINEBREAK
7454 	int width;
7455 # endif
7456 	int v = getviscol();
7457 
7458 	if (v == 0)
7459 	    return FAIL;
7460 
7461 # ifdef FEAT_LINEBREAK
7462 	/* We might get stuck on 'showbreak', skip over it. */
7463 	width = 1;
7464 	for (;;)
7465 	{
7466 	    coladvance(v - width);
7467 	    /* getviscol() is slow, skip it when 'showbreak' is empty,
7468 	     * 'breakindent' is not set and there are no multi-byte
7469 	     * characters */
7470 	    if ((*p_sbr == NUL && !curwin->w_p_bri
7471 #  ifdef FEAT_MBYTE
7472 			&& !has_mbyte
7473 #  endif
7474 			) || getviscol() < v)
7475 		break;
7476 	    ++width;
7477 	}
7478 # else
7479 	coladvance(v - 1);
7480 # endif
7481 
7482 	if (curwin->w_cursor.coladd == 1)
7483 	{
7484 	    char_u *ptr;
7485 
7486 	    /* Adjust for multi-wide char (not a TAB) */
7487 	    ptr = ml_get_cursor();
7488 	    if (*ptr != TAB && vim_isprintc(
7489 #  ifdef FEAT_MBYTE
7490 			    (*mb_ptr2char)(ptr)
7491 #  else
7492 			    *ptr
7493 #  endif
7494 			    ) && ptr2cells(ptr) > 1)
7495 		curwin->w_cursor.coladd = 0;
7496 	}
7497 
7498 	curwin->w_set_curswant = TRUE;
7499 	return OK;
7500     }
7501 #endif
7502 
7503     if (curwin->w_cursor.col == 0)
7504 	return FAIL;
7505 
7506     curwin->w_set_curswant = TRUE;
7507     --curwin->w_cursor.col;
7508 
7509 #ifdef FEAT_MBYTE
7510     /* if the character on the left of the current cursor is a multi-byte
7511      * character, move to its first byte */
7512     if (has_mbyte)
7513 	mb_adjust_cursor();
7514 #endif
7515     return OK;
7516 }
7517 
7518     int
7519 cursor_up(
7520     long	n,
7521     int		upd_topline)	    /* When TRUE: update topline */
7522 {
7523     linenr_T	lnum;
7524 
7525     if (n > 0)
7526     {
7527 	lnum = curwin->w_cursor.lnum;
7528 	/* This fails if the cursor is already in the first line or the count
7529 	 * is larger than the line number and '-' is in 'cpoptions' */
7530 	if (lnum <= 1 || (n >= lnum && vim_strchr(p_cpo, CPO_MINUS) != NULL))
7531 	    return FAIL;
7532 	if (n >= lnum)
7533 	    lnum = 1;
7534 	else
7535 #ifdef FEAT_FOLDING
7536 	    if (hasAnyFolding(curwin))
7537 	{
7538 	    /*
7539 	     * Count each sequence of folded lines as one logical line.
7540 	     */
7541 	    /* go to the start of the current fold */
7542 	    (void)hasFolding(lnum, &lnum, NULL);
7543 
7544 	    while (n--)
7545 	    {
7546 		/* move up one line */
7547 		--lnum;
7548 		if (lnum <= 1)
7549 		    break;
7550 		/* If we entered a fold, move to the beginning, unless in
7551 		 * Insert mode or when 'foldopen' contains "all": it will open
7552 		 * in a moment. */
7553 		if (n > 0 || !((State & INSERT) || (fdo_flags & FDO_ALL)))
7554 		    (void)hasFolding(lnum, &lnum, NULL);
7555 	    }
7556 	    if (lnum < 1)
7557 		lnum = 1;
7558 	}
7559 	else
7560 #endif
7561 	    lnum -= n;
7562 	curwin->w_cursor.lnum = lnum;
7563     }
7564 
7565     /* try to advance to the column we want to be at */
7566     coladvance(curwin->w_curswant);
7567 
7568     if (upd_topline)
7569 	update_topline();	/* make sure curwin->w_topline is valid */
7570 
7571     return OK;
7572 }
7573 
7574 /*
7575  * Cursor down a number of logical lines.
7576  */
7577     int
7578 cursor_down(
7579     long	n,
7580     int		upd_topline)	    /* When TRUE: update topline */
7581 {
7582     linenr_T	lnum;
7583 
7584     if (n > 0)
7585     {
7586 	lnum = curwin->w_cursor.lnum;
7587 #ifdef FEAT_FOLDING
7588 	/* Move to last line of fold, will fail if it's the end-of-file. */
7589 	(void)hasFolding(lnum, NULL, &lnum);
7590 #endif
7591 	/* This fails if the cursor is already in the last line or would move
7592 	 * beyond the last line and '-' is in 'cpoptions' */
7593 	if (lnum >= curbuf->b_ml.ml_line_count
7594 		|| (lnum + n > curbuf->b_ml.ml_line_count
7595 		    && vim_strchr(p_cpo, CPO_MINUS) != NULL))
7596 	    return FAIL;
7597 	if (lnum + n >= curbuf->b_ml.ml_line_count)
7598 	    lnum = curbuf->b_ml.ml_line_count;
7599 	else
7600 #ifdef FEAT_FOLDING
7601 	if (hasAnyFolding(curwin))
7602 	{
7603 	    linenr_T	last;
7604 
7605 	    /* count each sequence of folded lines as one logical line */
7606 	    while (n--)
7607 	    {
7608 		if (hasFolding(lnum, NULL, &last))
7609 		    lnum = last + 1;
7610 		else
7611 		    ++lnum;
7612 		if (lnum >= curbuf->b_ml.ml_line_count)
7613 		    break;
7614 	    }
7615 	    if (lnum > curbuf->b_ml.ml_line_count)
7616 		lnum = curbuf->b_ml.ml_line_count;
7617 	}
7618 	else
7619 #endif
7620 	    lnum += n;
7621 	curwin->w_cursor.lnum = lnum;
7622     }
7623 
7624     /* try to advance to the column we want to be at */
7625     coladvance(curwin->w_curswant);
7626 
7627     if (upd_topline)
7628 	update_topline();	/* make sure curwin->w_topline is valid */
7629 
7630     return OK;
7631 }
7632 
7633 /*
7634  * Stuff the last inserted text in the read buffer.
7635  * Last_insert actually is a copy of the redo buffer, so we
7636  * first have to remove the command.
7637  */
7638     int
7639 stuff_inserted(
7640     int	    c,		/* Command character to be inserted */
7641     long    count,	/* Repeat this many times */
7642     int	    no_esc)	/* Don't add an ESC at the end */
7643 {
7644     char_u	*esc_ptr;
7645     char_u	*ptr;
7646     char_u	*last_ptr;
7647     char_u	last = NUL;
7648 
7649     ptr = get_last_insert();
7650     if (ptr == NULL)
7651     {
7652 	EMSG(_(e_noinstext));
7653 	return FAIL;
7654     }
7655 
7656     /* may want to stuff the command character, to start Insert mode */
7657     if (c != NUL)
7658 	stuffcharReadbuff(c);
7659     if ((esc_ptr = (char_u *)vim_strrchr(ptr, ESC)) != NULL)
7660 	*esc_ptr = NUL;	    /* remove the ESC */
7661 
7662     /* when the last char is either "0" or "^" it will be quoted if no ESC
7663      * comes after it OR if it will inserted more than once and "ptr"
7664      * starts with ^D.	-- Acevedo
7665      */
7666     last_ptr = (esc_ptr ? esc_ptr : ptr + STRLEN(ptr)) - 1;
7667     if (last_ptr >= ptr && (*last_ptr == '0' || *last_ptr == '^')
7668 	    && (no_esc || (*ptr == Ctrl_D && count > 1)))
7669     {
7670 	last = *last_ptr;
7671 	*last_ptr = NUL;
7672     }
7673 
7674     do
7675     {
7676 	stuffReadbuff(ptr);
7677 	/* a trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^" */
7678 	if (last)
7679 	    stuffReadbuff((char_u *)(last == '0'
7680 			? IF_EB("\026\060\064\070", CTRL_V_STR "xf0")
7681 			: IF_EB("\026^", CTRL_V_STR "^")));
7682     }
7683     while (--count > 0);
7684 
7685     if (last)
7686 	*last_ptr = last;
7687 
7688     if (esc_ptr != NULL)
7689 	*esc_ptr = ESC;	    /* put the ESC back */
7690 
7691     /* may want to stuff a trailing ESC, to get out of Insert mode */
7692     if (!no_esc)
7693 	stuffcharReadbuff(ESC);
7694 
7695     return OK;
7696 }
7697 
7698     char_u *
7699 get_last_insert(void)
7700 {
7701     if (last_insert == NULL)
7702 	return NULL;
7703     return last_insert + last_insert_skip;
7704 }
7705 
7706 /*
7707  * Get last inserted string, and remove trailing <Esc>.
7708  * Returns pointer to allocated memory (must be freed) or NULL.
7709  */
7710     char_u *
7711 get_last_insert_save(void)
7712 {
7713     char_u	*s;
7714     int		len;
7715 
7716     if (last_insert == NULL)
7717 	return NULL;
7718     s = vim_strsave(last_insert + last_insert_skip);
7719     if (s != NULL)
7720     {
7721 	len = (int)STRLEN(s);
7722 	if (len > 0 && s[len - 1] == ESC)	/* remove trailing ESC */
7723 	    s[len - 1] = NUL;
7724     }
7725     return s;
7726 }
7727 
7728 /*
7729  * Check the word in front of the cursor for an abbreviation.
7730  * Called when the non-id character "c" has been entered.
7731  * When an abbreviation is recognized it is removed from the text and
7732  * the replacement string is inserted in typebuf.tb_buf[], followed by "c".
7733  */
7734     static int
7735 echeck_abbr(int c)
7736 {
7737     /* Don't check for abbreviation in paste mode, when disabled and just
7738      * after moving around with cursor keys. */
7739     if (p_paste || no_abbr || arrow_used)
7740 	return FALSE;
7741 
7742     return check_abbr(c, ml_get_curline(), curwin->w_cursor.col,
7743 		curwin->w_cursor.lnum == Insstart.lnum ? Insstart.col : 0);
7744 }
7745 
7746 /*
7747  * replace-stack functions
7748  *
7749  * When replacing characters, the replaced characters are remembered for each
7750  * new character.  This is used to re-insert the old text when backspacing.
7751  *
7752  * There is a NUL headed list of characters for each character that is
7753  * currently in the file after the insertion point.  When BS is used, one NUL
7754  * headed list is put back for the deleted character.
7755  *
7756  * For a newline, there are two NUL headed lists.  One contains the characters
7757  * that the NL replaced.  The extra one stores the characters after the cursor
7758  * that were deleted (always white space).
7759  *
7760  * Replace_offset is normally 0, in which case replace_push will add a new
7761  * character at the end of the stack.  If replace_offset is not 0, that many
7762  * characters will be left on the stack above the newly inserted character.
7763  */
7764 
7765 static char_u	*replace_stack = NULL;
7766 static long	replace_stack_nr = 0;	    /* next entry in replace stack */
7767 static long	replace_stack_len = 0;	    /* max. number of entries */
7768 
7769     void
7770 replace_push(
7771     int	    c)	    /* character that is replaced (NUL is none) */
7772 {
7773     char_u  *p;
7774 
7775     if (replace_stack_nr < replace_offset)	/* nothing to do */
7776 	return;
7777     if (replace_stack_len <= replace_stack_nr)
7778     {
7779 	replace_stack_len += 50;
7780 	p = lalloc(sizeof(char_u) * replace_stack_len, TRUE);
7781 	if (p == NULL)	    /* out of memory */
7782 	{
7783 	    replace_stack_len -= 50;
7784 	    return;
7785 	}
7786 	if (replace_stack != NULL)
7787 	{
7788 	    mch_memmove(p, replace_stack,
7789 				 (size_t)(replace_stack_nr * sizeof(char_u)));
7790 	    vim_free(replace_stack);
7791 	}
7792 	replace_stack = p;
7793     }
7794     p = replace_stack + replace_stack_nr - replace_offset;
7795     if (replace_offset)
7796 	mch_memmove(p + 1, p, (size_t)(replace_offset * sizeof(char_u)));
7797     *p = c;
7798     ++replace_stack_nr;
7799 }
7800 
7801 #if defined(FEAT_MBYTE) || defined(PROTO)
7802 /*
7803  * Push a character onto the replace stack.  Handles a multi-byte character in
7804  * reverse byte order, so that the first byte is popped off first.
7805  * Return the number of bytes done (includes composing characters).
7806  */
7807     int
7808 replace_push_mb(char_u *p)
7809 {
7810     int l = (*mb_ptr2len)(p);
7811     int j;
7812 
7813     for (j = l - 1; j >= 0; --j)
7814 	replace_push(p[j]);
7815     return l;
7816 }
7817 #endif
7818 
7819 /*
7820  * Pop one item from the replace stack.
7821  * return -1 if stack empty
7822  * return replaced character or NUL otherwise
7823  */
7824     static int
7825 replace_pop(void)
7826 {
7827     if (replace_stack_nr == 0)
7828 	return -1;
7829     return (int)replace_stack[--replace_stack_nr];
7830 }
7831 
7832 /*
7833  * Join the top two items on the replace stack.  This removes to "off"'th NUL
7834  * encountered.
7835  */
7836     static void
7837 replace_join(
7838     int	    off)	/* offset for which NUL to remove */
7839 {
7840     int	    i;
7841 
7842     for (i = replace_stack_nr; --i >= 0; )
7843 	if (replace_stack[i] == NUL && off-- <= 0)
7844 	{
7845 	    --replace_stack_nr;
7846 	    mch_memmove(replace_stack + i, replace_stack + i + 1,
7847 					      (size_t)(replace_stack_nr - i));
7848 	    return;
7849 	}
7850 }
7851 
7852 /*
7853  * Pop bytes from the replace stack until a NUL is found, and insert them
7854  * before the cursor.  Can only be used in REPLACE or VREPLACE mode.
7855  */
7856     static void
7857 replace_pop_ins(void)
7858 {
7859     int	    cc;
7860     int	    oldState = State;
7861 
7862     State = NORMAL;			/* don't want REPLACE here */
7863     while ((cc = replace_pop()) > 0)
7864     {
7865 #ifdef FEAT_MBYTE
7866 	mb_replace_pop_ins(cc);
7867 #else
7868 	ins_char(cc);
7869 #endif
7870 	dec_cursor();
7871     }
7872     State = oldState;
7873 }
7874 
7875 #ifdef FEAT_MBYTE
7876 /*
7877  * Insert bytes popped from the replace stack. "cc" is the first byte.  If it
7878  * indicates a multi-byte char, pop the other bytes too.
7879  */
7880     static void
7881 mb_replace_pop_ins(int cc)
7882 {
7883     int		n;
7884     char_u	buf[MB_MAXBYTES + 1];
7885     int		i;
7886     int		c;
7887 
7888     if (has_mbyte && (n = MB_BYTE2LEN(cc)) > 1)
7889     {
7890 	buf[0] = cc;
7891 	for (i = 1; i < n; ++i)
7892 	    buf[i] = replace_pop();
7893 	ins_bytes_len(buf, n);
7894     }
7895     else
7896 	ins_char(cc);
7897 
7898     if (enc_utf8)
7899 	/* Handle composing chars. */
7900 	for (;;)
7901 	{
7902 	    c = replace_pop();
7903 	    if (c == -1)	    /* stack empty */
7904 		break;
7905 	    if ((n = MB_BYTE2LEN(c)) == 1)
7906 	    {
7907 		/* Not a multi-byte char, put it back. */
7908 		replace_push(c);
7909 		break;
7910 	    }
7911 	    else
7912 	    {
7913 		buf[0] = c;
7914 		for (i = 1; i < n; ++i)
7915 		    buf[i] = replace_pop();
7916 		if (utf_iscomposing(utf_ptr2char(buf)))
7917 		    ins_bytes_len(buf, n);
7918 		else
7919 		{
7920 		    /* Not a composing char, put it back. */
7921 		    for (i = n - 1; i >= 0; --i)
7922 			replace_push(buf[i]);
7923 		    break;
7924 		}
7925 	    }
7926 	}
7927 }
7928 #endif
7929 
7930 /*
7931  * make the replace stack empty
7932  * (called when exiting replace mode)
7933  */
7934     static void
7935 replace_flush(void)
7936 {
7937     VIM_CLEAR(replace_stack);
7938     replace_stack_len = 0;
7939     replace_stack_nr = 0;
7940 }
7941 
7942 /*
7943  * Handle doing a BS for one character.
7944  * cc < 0: replace stack empty, just move cursor
7945  * cc == 0: character was inserted, delete it
7946  * cc > 0: character was replaced, put cc (first byte of original char) back
7947  * and check for more characters to be put back
7948  * When "limit_col" is >= 0, don't delete before this column.  Matters when
7949  * using composing characters, use del_char_after_col() instead of del_char().
7950  */
7951     static void
7952 replace_do_bs(int limit_col)
7953 {
7954     int		cc;
7955     int		orig_len = 0;
7956     int		ins_len;
7957     int		orig_vcols = 0;
7958     colnr_T	start_vcol;
7959     char_u	*p;
7960     int		i;
7961     int		vcol;
7962 
7963     cc = replace_pop();
7964     if (cc > 0)
7965     {
7966 	if (State & VREPLACE_FLAG)
7967 	{
7968 	    /* Get the number of screen cells used by the character we are
7969 	     * going to delete. */
7970 	    getvcol(curwin, &curwin->w_cursor, NULL, &start_vcol, NULL);
7971 	    orig_vcols = chartabsize(ml_get_cursor(), start_vcol);
7972 	}
7973 #ifdef FEAT_MBYTE
7974 	if (has_mbyte)
7975 	{
7976 	    (void)del_char_after_col(limit_col);
7977 	    if (State & VREPLACE_FLAG)
7978 		orig_len = (int)STRLEN(ml_get_cursor());
7979 	    replace_push(cc);
7980 	}
7981 	else
7982 #endif
7983 	{
7984 	    pchar_cursor(cc);
7985 	    if (State & VREPLACE_FLAG)
7986 		orig_len = (int)STRLEN(ml_get_cursor()) - 1;
7987 	}
7988 	replace_pop_ins();
7989 
7990 	if (State & VREPLACE_FLAG)
7991 	{
7992 	    /* Get the number of screen cells used by the inserted characters */
7993 	    p = ml_get_cursor();
7994 	    ins_len = (int)STRLEN(p) - orig_len;
7995 	    vcol = start_vcol;
7996 	    for (i = 0; i < ins_len; ++i)
7997 	    {
7998 		vcol += chartabsize(p + i, vcol);
7999 #ifdef FEAT_MBYTE
8000 		i += (*mb_ptr2len)(p) - 1;
8001 #endif
8002 	    }
8003 	    vcol -= start_vcol;
8004 
8005 	    /* Delete spaces that were inserted after the cursor to keep the
8006 	     * text aligned. */
8007 	    curwin->w_cursor.col += ins_len;
8008 	    while (vcol > orig_vcols && gchar_cursor() == ' ')
8009 	    {
8010 		del_char(FALSE);
8011 		++orig_vcols;
8012 	    }
8013 	    curwin->w_cursor.col -= ins_len;
8014 	}
8015 
8016 	/* mark the buffer as changed and prepare for displaying */
8017 	changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
8018     }
8019     else if (cc == 0)
8020 	(void)del_char_after_col(limit_col);
8021 }
8022 
8023 #ifdef FEAT_CINDENT
8024 /*
8025  * Return TRUE if C-indenting is on.
8026  */
8027     static int
8028 cindent_on(void)
8029 {
8030     return (!p_paste && (curbuf->b_p_cin
8031 # ifdef FEAT_EVAL
8032 		    || *curbuf->b_p_inde != NUL
8033 # endif
8034 		    ));
8035 }
8036 #endif
8037 
8038 #if defined(FEAT_LISP) || defined(FEAT_CINDENT) || defined(PROTO)
8039 /*
8040  * Re-indent the current line, based on the current contents of it and the
8041  * surrounding lines. Fixing the cursor position seems really easy -- I'm very
8042  * confused what all the part that handles Control-T is doing that I'm not.
8043  * "get_the_indent" should be get_c_indent, get_expr_indent or get_lisp_indent.
8044  */
8045 
8046     void
8047 fixthisline(int (*get_the_indent)(void))
8048 {
8049     int amount = get_the_indent();
8050 
8051     if (amount >= 0)
8052     {
8053 	change_indent(INDENT_SET, amount, FALSE, 0, TRUE);
8054 	if (linewhite(curwin->w_cursor.lnum))
8055 	    did_ai = TRUE;	/* delete the indent if the line stays empty */
8056     }
8057 }
8058 
8059     void
8060 fix_indent(void)
8061 {
8062     if (p_paste)
8063 	return;
8064 # ifdef FEAT_LISP
8065     if (curbuf->b_p_lisp && curbuf->b_p_ai)
8066 	fixthisline(get_lisp_indent);
8067 # endif
8068 # if defined(FEAT_LISP) && defined(FEAT_CINDENT)
8069     else
8070 # endif
8071 # ifdef FEAT_CINDENT
8072 	if (cindent_on())
8073 	    do_c_expr_indent();
8074 # endif
8075 }
8076 
8077 #endif
8078 
8079 #ifdef FEAT_CINDENT
8080 /*
8081  * return TRUE if 'cinkeys' contains the key "keytyped",
8082  * when == '*':	    Only if key is preceded with '*'	(indent before insert)
8083  * when == '!':	    Only if key is preceded with '!'	(don't insert)
8084  * when == ' ':	    Only if key is not preceded with '*'(indent afterwards)
8085  *
8086  * "keytyped" can have a few special values:
8087  * KEY_OPEN_FORW
8088  * KEY_OPEN_BACK
8089  * KEY_COMPLETE	    just finished completion.
8090  *
8091  * If line_is_empty is TRUE accept keys with '0' before them.
8092  */
8093     int
8094 in_cinkeys(
8095     int		keytyped,
8096     int		when,
8097     int		line_is_empty)
8098 {
8099     char_u	*look;
8100     int		try_match;
8101     int		try_match_word;
8102     char_u	*p;
8103     char_u	*line;
8104     int		icase;
8105     int		i;
8106 
8107     if (keytyped == NUL)
8108 	/* Can happen with CTRL-Y and CTRL-E on a short line. */
8109 	return FALSE;
8110 
8111 #ifdef FEAT_EVAL
8112     if (*curbuf->b_p_inde != NUL)
8113 	look = curbuf->b_p_indk;	/* 'indentexpr' set: use 'indentkeys' */
8114     else
8115 #endif
8116 	look = curbuf->b_p_cink;	/* 'indentexpr' empty: use 'cinkeys' */
8117     while (*look)
8118     {
8119 	/*
8120 	 * Find out if we want to try a match with this key, depending on
8121 	 * 'when' and a '*' or '!' before the key.
8122 	 */
8123 	switch (when)
8124 	{
8125 	    case '*': try_match = (*look == '*'); break;
8126 	    case '!': try_match = (*look == '!'); break;
8127 	     default: try_match = (*look != '*'); break;
8128 	}
8129 	if (*look == '*' || *look == '!')
8130 	    ++look;
8131 
8132 	/*
8133 	 * If there is a '0', only accept a match if the line is empty.
8134 	 * But may still match when typing last char of a word.
8135 	 */
8136 	if (*look == '0')
8137 	{
8138 	    try_match_word = try_match;
8139 	    if (!line_is_empty)
8140 		try_match = FALSE;
8141 	    ++look;
8142 	}
8143 	else
8144 	    try_match_word = FALSE;
8145 
8146 	/*
8147 	 * does it look like a control character?
8148 	 */
8149 	if (*look == '^'
8150 #ifdef EBCDIC
8151 		&& (Ctrl_chr(look[1]) != 0)
8152 #else
8153 		&& look[1] >= '?' && look[1] <= '_'
8154 #endif
8155 		)
8156 	{
8157 	    if (try_match && keytyped == Ctrl_chr(look[1]))
8158 		return TRUE;
8159 	    look += 2;
8160 	}
8161 	/*
8162 	 * 'o' means "o" command, open forward.
8163 	 * 'O' means "O" command, open backward.
8164 	 */
8165 	else if (*look == 'o')
8166 	{
8167 	    if (try_match && keytyped == KEY_OPEN_FORW)
8168 		return TRUE;
8169 	    ++look;
8170 	}
8171 	else if (*look == 'O')
8172 	{
8173 	    if (try_match && keytyped == KEY_OPEN_BACK)
8174 		return TRUE;
8175 	    ++look;
8176 	}
8177 
8178 	/*
8179 	 * 'e' means to check for "else" at start of line and just before the
8180 	 * cursor.
8181 	 */
8182 	else if (*look == 'e')
8183 	{
8184 	    if (try_match && keytyped == 'e' && curwin->w_cursor.col >= 4)
8185 	    {
8186 		p = ml_get_curline();
8187 		if (skipwhite(p) == p + curwin->w_cursor.col - 4 &&
8188 			STRNCMP(p + curwin->w_cursor.col - 4, "else", 4) == 0)
8189 		    return TRUE;
8190 	    }
8191 	    ++look;
8192 	}
8193 
8194 	/*
8195 	 * ':' only causes an indent if it is at the end of a label or case
8196 	 * statement, or when it was before typing the ':' (to fix
8197 	 * class::method for C++).
8198 	 */
8199 	else if (*look == ':')
8200 	{
8201 	    if (try_match && keytyped == ':')
8202 	    {
8203 		p = ml_get_curline();
8204 		if (cin_iscase(p, FALSE) || cin_isscopedecl(p) || cin_islabel())
8205 		    return TRUE;
8206 		/* Need to get the line again after cin_islabel(). */
8207 		p = ml_get_curline();
8208 		if (curwin->w_cursor.col > 2
8209 			&& p[curwin->w_cursor.col - 1] == ':'
8210 			&& p[curwin->w_cursor.col - 2] == ':')
8211 		{
8212 		    p[curwin->w_cursor.col - 1] = ' ';
8213 		    i = (cin_iscase(p, FALSE) || cin_isscopedecl(p)
8214 							    || cin_islabel());
8215 		    p = ml_get_curline();
8216 		    p[curwin->w_cursor.col - 1] = ':';
8217 		    if (i)
8218 			return TRUE;
8219 		}
8220 	    }
8221 	    ++look;
8222 	}
8223 
8224 
8225 	/*
8226 	 * Is it a key in <>, maybe?
8227 	 */
8228 	else if (*look == '<')
8229 	{
8230 	    if (try_match)
8231 	    {
8232 		/*
8233 		 * make up some named keys <o>, <O>, <e>, <0>, <>>, <<>, <*>,
8234 		 * <:> and <!> so that people can re-indent on o, O, e, 0, <,
8235 		 * >, *, : and ! keys if they really really want to.
8236 		 */
8237 		if (vim_strchr((char_u *)"<>!*oOe0:", look[1]) != NULL
8238 						       && keytyped == look[1])
8239 		    return TRUE;
8240 
8241 		if (keytyped == get_special_key_code(look + 1))
8242 		    return TRUE;
8243 	    }
8244 	    while (*look && *look != '>')
8245 		look++;
8246 	    while (*look == '>')
8247 		look++;
8248 	}
8249 
8250 	/*
8251 	 * Is it a word: "=word"?
8252 	 */
8253 	else if (*look == '=' && look[1] != ',' && look[1] != NUL)
8254 	{
8255 	    ++look;
8256 	    if (*look == '~')
8257 	    {
8258 		icase = TRUE;
8259 		++look;
8260 	    }
8261 	    else
8262 		icase = FALSE;
8263 	    p = vim_strchr(look, ',');
8264 	    if (p == NULL)
8265 		p = look + STRLEN(look);
8266 	    if ((try_match || try_match_word)
8267 		    && curwin->w_cursor.col >= (colnr_T)(p - look))
8268 	    {
8269 		int		match = FALSE;
8270 
8271 #ifdef FEAT_INS_EXPAND
8272 		if (keytyped == KEY_COMPLETE)
8273 		{
8274 		    char_u	*s;
8275 
8276 		    /* Just completed a word, check if it starts with "look".
8277 		     * search back for the start of a word. */
8278 		    line = ml_get_curline();
8279 # ifdef FEAT_MBYTE
8280 		    if (has_mbyte)
8281 		    {
8282 			char_u	*n;
8283 
8284 			for (s = line + curwin->w_cursor.col; s > line; s = n)
8285 			{
8286 			    n = mb_prevptr(line, s);
8287 			    if (!vim_iswordp(n))
8288 				break;
8289 			}
8290 		    }
8291 		    else
8292 # endif
8293 			for (s = line + curwin->w_cursor.col; s > line; --s)
8294 			    if (!vim_iswordc(s[-1]))
8295 				break;
8296 		    if (s + (p - look) <= line + curwin->w_cursor.col
8297 			    && (icase
8298 				? MB_STRNICMP(s, look, p - look)
8299 				: STRNCMP(s, look, p - look)) == 0)
8300 			match = TRUE;
8301 		}
8302 		else
8303 #endif
8304 		    /* TODO: multi-byte */
8305 		    if (keytyped == (int)p[-1] || (icase && keytyped < 256
8306 			 && TOLOWER_LOC(keytyped) == TOLOWER_LOC((int)p[-1])))
8307 		{
8308 		    line = ml_get_cursor();
8309 		    if ((curwin->w_cursor.col == (colnr_T)(p - look)
8310 				|| !vim_iswordc(line[-(p - look) - 1]))
8311 			    && (icase
8312 				? MB_STRNICMP(line - (p - look), look, p - look)
8313 				: STRNCMP(line - (p - look), look, p - look))
8314 									 == 0)
8315 			match = TRUE;
8316 		}
8317 		if (match && try_match_word && !try_match)
8318 		{
8319 		    /* "0=word": Check if there are only blanks before the
8320 		     * word. */
8321 		    if (getwhitecols_curline() !=
8322 				     (int)(curwin->w_cursor.col - (p - look)))
8323 			match = FALSE;
8324 		}
8325 		if (match)
8326 		    return TRUE;
8327 	    }
8328 	    look = p;
8329 	}
8330 
8331 	/*
8332 	 * ok, it's a boring generic character.
8333 	 */
8334 	else
8335 	{
8336 	    if (try_match && *look == keytyped)
8337 		return TRUE;
8338 	    if (*look != NUL)
8339 		++look;
8340 	}
8341 
8342 	/*
8343 	 * Skip over ", ".
8344 	 */
8345 	look = skip_to_option_part(look);
8346     }
8347     return FALSE;
8348 }
8349 #endif /* FEAT_CINDENT */
8350 
8351 #if defined(FEAT_RIGHTLEFT) || defined(PROTO)
8352 /*
8353  * Map Hebrew keyboard when in hkmap mode.
8354  */
8355     int
8356 hkmap(int c)
8357 {
8358     if (p_hkmapp)   /* phonetic mapping, by Ilya Dogolazky */
8359     {
8360 	enum {hALEF=0, BET, GIMEL, DALET, HEI, VAV, ZAIN, HET, TET, IUD,
8361 	    KAFsofit, hKAF, LAMED, MEMsofit, MEM, NUNsofit, NUN, SAMEH, AIN,
8362 	    PEIsofit, PEI, ZADIsofit, ZADI, KOF, RESH, hSHIN, TAV};
8363 	static char_u map[26] =
8364 	    {(char_u)hALEF/*a*/, (char_u)BET  /*b*/, (char_u)hKAF    /*c*/,
8365 	     (char_u)DALET/*d*/, (char_u)-1   /*e*/, (char_u)PEIsofit/*f*/,
8366 	     (char_u)GIMEL/*g*/, (char_u)HEI  /*h*/, (char_u)IUD     /*i*/,
8367 	     (char_u)HET  /*j*/, (char_u)KOF  /*k*/, (char_u)LAMED   /*l*/,
8368 	     (char_u)MEM  /*m*/, (char_u)NUN  /*n*/, (char_u)SAMEH   /*o*/,
8369 	     (char_u)PEI  /*p*/, (char_u)-1   /*q*/, (char_u)RESH    /*r*/,
8370 	     (char_u)ZAIN /*s*/, (char_u)TAV  /*t*/, (char_u)TET     /*u*/,
8371 	     (char_u)VAV  /*v*/, (char_u)hSHIN/*w*/, (char_u)-1      /*x*/,
8372 	     (char_u)AIN  /*y*/, (char_u)ZADI /*z*/};
8373 
8374 	if (c == 'N' || c == 'M' || c == 'P' || c == 'C' || c == 'Z')
8375 	    return (int)(map[CharOrd(c)] - 1 + p_aleph);
8376 							    /* '-1'='sofit' */
8377 	else if (c == 'x')
8378 	    return 'X';
8379 	else if (c == 'q')
8380 	    return '\''; /* {geresh}={'} */
8381 	else if (c == 246)
8382 	    return ' ';  /* \"o --> ' ' for a german keyboard */
8383 	else if (c == 228)
8384 	    return ' ';  /* \"a --> ' '      -- / --	       */
8385 	else if (c == 252)
8386 	    return ' ';  /* \"u --> ' '      -- / --	       */
8387 #ifdef EBCDIC
8388 	else if (islower(c))
8389 #else
8390 	/* NOTE: islower() does not do the right thing for us on Linux so we
8391 	 * do this the same was as 5.7 and previous, so it works correctly on
8392 	 * all systems.  Specifically, the e.g. Delete and Arrow keys are
8393 	 * munged and won't work if e.g. searching for Hebrew text.
8394 	 */
8395 	else if (c >= 'a' && c <= 'z')
8396 #endif
8397 	    return (int)(map[CharOrdLow(c)] + p_aleph);
8398 	else
8399 	    return c;
8400     }
8401     else
8402     {
8403 	switch (c)
8404 	{
8405 	    case '`':	return ';';
8406 	    case '/':	return '.';
8407 	    case '\'':	return ',';
8408 	    case 'q':	return '/';
8409 	    case 'w':	return '\'';
8410 
8411 			/* Hebrew letters - set offset from 'a' */
8412 	    case ',':	c = '{'; break;
8413 	    case '.':	c = 'v'; break;
8414 	    case ';':	c = 't'; break;
8415 	    default: {
8416 			 static char str[] = "zqbcxlsjphmkwonu ydafe rig";
8417 
8418 #ifdef EBCDIC
8419 			 /* see note about islower() above */
8420 			 if (!islower(c))
8421 #else
8422 			 if (c < 'a' || c > 'z')
8423 #endif
8424 			     return c;
8425 			 c = str[CharOrdLow(c)];
8426 			 break;
8427 		     }
8428 	}
8429 
8430 	return (int)(CharOrdLow(c) + p_aleph);
8431     }
8432 }
8433 #endif
8434 
8435     static void
8436 ins_reg(void)
8437 {
8438     int		need_redraw = FALSE;
8439     int		regname;
8440     int		literally = 0;
8441     int		vis_active = VIsual_active;
8442 
8443     /*
8444      * If we are going to wait for a character, show a '"'.
8445      */
8446     pc_status = PC_STATUS_UNSET;
8447     if (redrawing() && !char_avail())
8448     {
8449 	/* may need to redraw when no more chars available now */
8450 	ins_redraw(FALSE);
8451 
8452 	edit_putchar('"', TRUE);
8453 #ifdef FEAT_CMDL_INFO
8454 	add_to_showcmd_c(Ctrl_R);
8455 #endif
8456     }
8457 
8458 #ifdef USE_ON_FLY_SCROLL
8459     dont_scroll = TRUE;		/* disallow scrolling here */
8460 #endif
8461 
8462     /*
8463      * Don't map the register name. This also prevents the mode message to be
8464      * deleted when ESC is hit.
8465      */
8466     ++no_mapping;
8467     regname = plain_vgetc();
8468     LANGMAP_ADJUST(regname, TRUE);
8469     if (regname == Ctrl_R || regname == Ctrl_O || regname == Ctrl_P)
8470     {
8471 	/* Get a third key for literal register insertion */
8472 	literally = regname;
8473 #ifdef FEAT_CMDL_INFO
8474 	add_to_showcmd_c(literally);
8475 #endif
8476 	regname = plain_vgetc();
8477 	LANGMAP_ADJUST(regname, TRUE);
8478     }
8479     --no_mapping;
8480 
8481 #ifdef FEAT_EVAL
8482     /* Don't call u_sync() while typing the expression or giving an error
8483      * message for it. Only call it explicitly. */
8484     ++no_u_sync;
8485     if (regname == '=')
8486     {
8487 # ifdef HAVE_INPUT_METHOD
8488 	int	im_on = im_get_status();
8489 # endif
8490 	/* Sync undo when evaluating the expression calls setline() or
8491 	 * append(), so that it can be undone separately. */
8492 	u_sync_once = 2;
8493 
8494 	regname = get_expr_register();
8495 # ifdef HAVE_INPUT_METHOD
8496 	/* Restore the Input Method. */
8497 	if (im_on)
8498 	    im_set_active(TRUE);
8499 # endif
8500     }
8501     if (regname == NUL || !valid_yank_reg(regname, FALSE))
8502     {
8503 	vim_beep(BO_REG);
8504 	need_redraw = TRUE;	/* remove the '"' */
8505     }
8506     else
8507     {
8508 #endif
8509 	if (literally == Ctrl_O || literally == Ctrl_P)
8510 	{
8511 	    /* Append the command to the redo buffer. */
8512 	    AppendCharToRedobuff(Ctrl_R);
8513 	    AppendCharToRedobuff(literally);
8514 	    AppendCharToRedobuff(regname);
8515 
8516 	    do_put(regname, BACKWARD, 1L,
8517 		 (literally == Ctrl_P ? PUT_FIXINDENT : 0) | PUT_CURSEND);
8518 	}
8519 	else if (insert_reg(regname, literally) == FAIL)
8520 	{
8521 	    vim_beep(BO_REG);
8522 	    need_redraw = TRUE;	/* remove the '"' */
8523 	}
8524 	else if (stop_insert_mode)
8525 	    /* When the '=' register was used and a function was invoked that
8526 	     * did ":stopinsert" then stuff_empty() returns FALSE but we won't
8527 	     * insert anything, need to remove the '"' */
8528 	    need_redraw = TRUE;
8529 
8530 #ifdef FEAT_EVAL
8531     }
8532     --no_u_sync;
8533     if (u_sync_once == 1)
8534 	ins_need_undo = TRUE;
8535     u_sync_once = 0;
8536 #endif
8537 #ifdef FEAT_CMDL_INFO
8538     clear_showcmd();
8539 #endif
8540 
8541     /* If the inserted register is empty, we need to remove the '"' */
8542     if (need_redraw || stuff_empty())
8543 	edit_unputchar();
8544 
8545     /* Disallow starting Visual mode here, would get a weird mode. */
8546     if (!vis_active && VIsual_active)
8547 	end_visual_mode();
8548 }
8549 
8550 /*
8551  * CTRL-G commands in Insert mode.
8552  */
8553     static void
8554 ins_ctrl_g(void)
8555 {
8556     int		c;
8557 
8558 #ifdef FEAT_INS_EXPAND
8559     /* Right after CTRL-X the cursor will be after the ruler. */
8560     setcursor();
8561 #endif
8562 
8563     /*
8564      * Don't map the second key. This also prevents the mode message to be
8565      * deleted when ESC is hit.
8566      */
8567     ++no_mapping;
8568     c = plain_vgetc();
8569     --no_mapping;
8570     switch (c)
8571     {
8572 	/* CTRL-G k and CTRL-G <Up>: cursor up to Insstart.col */
8573 	case K_UP:
8574 	case Ctrl_K:
8575 	case 'k': ins_up(TRUE);
8576 		  break;
8577 
8578 	/* CTRL-G j and CTRL-G <Down>: cursor down to Insstart.col */
8579 	case K_DOWN:
8580 	case Ctrl_J:
8581 	case 'j': ins_down(TRUE);
8582 		  break;
8583 
8584 	/* CTRL-G u: start new undoable edit */
8585 	case 'u': u_sync(TRUE);
8586 		  ins_need_undo = TRUE;
8587 
8588 		  /* Need to reset Insstart, esp. because a BS that joins
8589 		   * a line to the previous one must save for undo. */
8590 		  update_Insstart_orig = FALSE;
8591 		  Insstart = curwin->w_cursor;
8592 		  break;
8593 
8594 	/* CTRL-G U: do not break undo with the next char */
8595 	case 'U':
8596 		  /* Allow one left/right cursor movement with the next char,
8597 		   * without breaking undo. */
8598 		  dont_sync_undo = MAYBE;
8599 		  break;
8600 
8601 	/* Unknown CTRL-G command, reserved for future expansion. */
8602 	default:  vim_beep(BO_CTRLG);
8603     }
8604 }
8605 
8606 /*
8607  * CTRL-^ in Insert mode.
8608  */
8609     static void
8610 ins_ctrl_hat(void)
8611 {
8612     if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE))
8613     {
8614 	/* ":lmap" mappings exists, Toggle use of ":lmap" mappings. */
8615 	if (State & LANGMAP)
8616 	{
8617 	    curbuf->b_p_iminsert = B_IMODE_NONE;
8618 	    State &= ~LANGMAP;
8619 	}
8620 	else
8621 	{
8622 	    curbuf->b_p_iminsert = B_IMODE_LMAP;
8623 	    State |= LANGMAP;
8624 #ifdef HAVE_INPUT_METHOD
8625 	    im_set_active(FALSE);
8626 #endif
8627 	}
8628     }
8629 #ifdef HAVE_INPUT_METHOD
8630     else
8631     {
8632 	/* There are no ":lmap" mappings, toggle IM */
8633 	if (im_get_status())
8634 	{
8635 	    curbuf->b_p_iminsert = B_IMODE_NONE;
8636 	    im_set_active(FALSE);
8637 	}
8638 	else
8639 	{
8640 	    curbuf->b_p_iminsert = B_IMODE_IM;
8641 	    State &= ~LANGMAP;
8642 	    im_set_active(TRUE);
8643 	}
8644     }
8645 #endif
8646     set_iminsert_global();
8647     showmode();
8648 #ifdef FEAT_GUI
8649     /* may show different cursor shape or color */
8650     if (gui.in_use)
8651 	gui_update_cursor(TRUE, FALSE);
8652 #endif
8653 #if defined(FEAT_KEYMAP)
8654     /* Show/unshow value of 'keymap' in status lines. */
8655     status_redraw_curbuf();
8656 #endif
8657 }
8658 
8659 /*
8660  * Handle ESC in insert mode.
8661  * Returns TRUE when leaving insert mode, FALSE when going to repeat the
8662  * insert.
8663  */
8664     static int
8665 ins_esc(
8666     long	*count,
8667     int		cmdchar,
8668     int		nomove)	    /* don't move cursor */
8669 {
8670     int		temp;
8671     static int	disabled_redraw = FALSE;
8672 
8673 #ifdef FEAT_SPELL
8674     check_spell_redraw();
8675 #endif
8676 #if defined(FEAT_HANGULIN)
8677 # if defined(ESC_CHG_TO_ENG_MODE)
8678     hangul_input_state_set(0);
8679 # endif
8680     if (composing_hangul)
8681     {
8682 	push_raw_key(composing_hangul_buffer, 2);
8683 	composing_hangul = 0;
8684     }
8685 #endif
8686 
8687     temp = curwin->w_cursor.col;
8688     if (disabled_redraw)
8689     {
8690 	--RedrawingDisabled;
8691 	disabled_redraw = FALSE;
8692     }
8693     if (!arrow_used)
8694     {
8695 	/*
8696 	 * Don't append the ESC for "r<CR>" and "grx".
8697 	 * When 'insertmode' is set only CTRL-L stops Insert mode.  Needed for
8698 	 * when "count" is non-zero.
8699 	 */
8700 	if (cmdchar != 'r' && cmdchar != 'v')
8701 	    AppendToRedobuff(p_im ? (char_u *)"\014" : ESC_STR);
8702 
8703 	/*
8704 	 * Repeating insert may take a long time.  Check for
8705 	 * interrupt now and then.
8706 	 */
8707 	if (*count > 0)
8708 	{
8709 	    line_breakcheck();
8710 	    if (got_int)
8711 		*count = 0;
8712 	}
8713 
8714 	if (--*count > 0)	/* repeat what was typed */
8715 	{
8716 	    /* Vi repeats the insert without replacing characters. */
8717 	    if (vim_strchr(p_cpo, CPO_REPLCNT) != NULL)
8718 		State &= ~REPLACE_FLAG;
8719 
8720 	    (void)start_redo_ins();
8721 	    if (cmdchar == 'r' || cmdchar == 'v')
8722 		stuffRedoReadbuff(ESC_STR);	/* no ESC in redo buffer */
8723 	    ++RedrawingDisabled;
8724 	    disabled_redraw = TRUE;
8725 	    return FALSE;	/* repeat the insert */
8726 	}
8727 	stop_insert(&curwin->w_cursor, TRUE, nomove);
8728 	undisplay_dollar();
8729     }
8730 
8731     /* When an autoindent was removed, curswant stays after the
8732      * indent */
8733     if (restart_edit == NUL && (colnr_T)temp == curwin->w_cursor.col)
8734 	curwin->w_set_curswant = TRUE;
8735 
8736     /* Remember the last Insert position in the '^ mark. */
8737     if (!cmdmod.keepjumps)
8738 	curbuf->b_last_insert = curwin->w_cursor;
8739 
8740     /*
8741      * The cursor should end up on the last inserted character.
8742      * Don't do it for CTRL-O, unless past the end of the line.
8743      */
8744     if (!nomove
8745 	    && (curwin->w_cursor.col != 0
8746 #ifdef FEAT_VIRTUALEDIT
8747 		|| curwin->w_cursor.coladd > 0
8748 #endif
8749 	       )
8750 	    && (restart_edit == NUL
8751 		   || (gchar_cursor() == NUL && !VIsual_active))
8752 #ifdef FEAT_RIGHTLEFT
8753 	    && !revins_on
8754 #endif
8755 				      )
8756     {
8757 #ifdef FEAT_VIRTUALEDIT
8758 	if (curwin->w_cursor.coladd > 0 || ve_flags == VE_ALL)
8759 	{
8760 	    oneleft();
8761 	    if (restart_edit != NUL)
8762 		++curwin->w_cursor.coladd;
8763 	}
8764 	else
8765 #endif
8766 	{
8767 	    --curwin->w_cursor.col;
8768 #ifdef FEAT_MBYTE
8769 	    /* Correct cursor for multi-byte character. */
8770 	    if (has_mbyte)
8771 		mb_adjust_cursor();
8772 #endif
8773 	}
8774     }
8775 
8776 #ifdef HAVE_INPUT_METHOD
8777     /* Disable IM to allow typing English directly for Normal mode commands.
8778      * When ":lmap" is enabled don't change 'iminsert' (IM can be enabled as
8779      * well). */
8780     if (!(State & LANGMAP))
8781 	im_save_status(&curbuf->b_p_iminsert);
8782     im_set_active(FALSE);
8783 #endif
8784 
8785     State = NORMAL;
8786     /* need to position cursor again (e.g. when on a TAB ) */
8787     changed_cline_bef_curs();
8788 
8789 #ifdef FEAT_MOUSE
8790     setmouse();
8791 #endif
8792 #ifdef CURSOR_SHAPE
8793     ui_cursor_shape();		/* may show different cursor shape */
8794 #endif
8795     if (!p_ek)
8796 	/* Re-enable bracketed paste mode. */
8797 	out_str(T_BE);
8798 
8799     /*
8800      * When recording or for CTRL-O, need to display the new mode.
8801      * Otherwise remove the mode message.
8802      */
8803     if (reg_recording != 0 || restart_edit != NUL)
8804 	showmode();
8805     else if (p_smd)
8806 	MSG("");
8807 
8808     return TRUE;	    /* exit Insert mode */
8809 }
8810 
8811 #ifdef FEAT_RIGHTLEFT
8812 /*
8813  * Toggle language: hkmap and revins_on.
8814  * Move to end of reverse inserted text.
8815  */
8816     static void
8817 ins_ctrl_(void)
8818 {
8819     if (revins_on && revins_chars && revins_scol >= 0)
8820     {
8821 	while (gchar_cursor() != NUL && revins_chars--)
8822 	    ++curwin->w_cursor.col;
8823     }
8824     p_ri = !p_ri;
8825     revins_on = (State == INSERT && p_ri);
8826     if (revins_on)
8827     {
8828 	revins_scol = curwin->w_cursor.col;
8829 	revins_legal++;
8830 	revins_chars = 0;
8831 	undisplay_dollar();
8832     }
8833     else
8834 	revins_scol = -1;
8835 #ifdef FEAT_FKMAP
8836     if (p_altkeymap)
8837     {
8838 	/*
8839 	 * to be consistent also for redo command, using '.'
8840 	 * set arrow_used to true and stop it - causing to redo
8841 	 * characters entered in one mode (normal/reverse insert).
8842 	 */
8843 	arrow_used = TRUE;
8844 	(void)stop_arrow();
8845 	p_fkmap = curwin->w_p_rl ^ p_ri;
8846 	if (p_fkmap && p_ri)
8847 	    State = INSERT;
8848     }
8849     else
8850 #endif
8851 	p_hkmap = curwin->w_p_rl ^ p_ri;    /* be consistent! */
8852     showmode();
8853 }
8854 #endif
8855 
8856 /*
8857  * If 'keymodel' contains "startsel", may start selection.
8858  * Returns TRUE when a CTRL-O and other keys stuffed.
8859  */
8860     static int
8861 ins_start_select(int c)
8862 {
8863     if (km_startsel)
8864 	switch (c)
8865 	{
8866 	    case K_KHOME:
8867 	    case K_KEND:
8868 	    case K_PAGEUP:
8869 	    case K_KPAGEUP:
8870 	    case K_PAGEDOWN:
8871 	    case K_KPAGEDOWN:
8872 # ifdef MACOS_X
8873 	    case K_LEFT:
8874 	    case K_RIGHT:
8875 	    case K_UP:
8876 	    case K_DOWN:
8877 	    case K_END:
8878 	    case K_HOME:
8879 # endif
8880 		if (!(mod_mask & MOD_MASK_SHIFT))
8881 		    break;
8882 		/* FALLTHROUGH */
8883 	    case K_S_LEFT:
8884 	    case K_S_RIGHT:
8885 	    case K_S_UP:
8886 	    case K_S_DOWN:
8887 	    case K_S_END:
8888 	    case K_S_HOME:
8889 		/* Start selection right away, the cursor can move with
8890 		 * CTRL-O when beyond the end of the line. */
8891 		start_selection();
8892 
8893 		/* Execute the key in (insert) Select mode. */
8894 		stuffcharReadbuff(Ctrl_O);
8895 		if (mod_mask)
8896 		{
8897 		    char_u	    buf[4];
8898 
8899 		    buf[0] = K_SPECIAL;
8900 		    buf[1] = KS_MODIFIER;
8901 		    buf[2] = mod_mask;
8902 		    buf[3] = NUL;
8903 		    stuffReadbuff(buf);
8904 		}
8905 		stuffcharReadbuff(c);
8906 		return TRUE;
8907 	}
8908     return FALSE;
8909 }
8910 
8911 /*
8912  * <Insert> key in Insert mode: toggle insert/replace mode.
8913  */
8914     static void
8915 ins_insert(int replaceState)
8916 {
8917 #ifdef FEAT_FKMAP
8918     if (p_fkmap && p_ri)
8919     {
8920 	beep_flush();
8921 	EMSG(farsi_text_3);	/* encoded in Farsi */
8922 	return;
8923     }
8924 #endif
8925 
8926 # ifdef FEAT_EVAL
8927     set_vim_var_string(VV_INSERTMODE,
8928 		   (char_u *)((State & REPLACE_FLAG) ? "i"
8929 		          : replaceState == VREPLACE ? "v"
8930 						     : "r"), 1);
8931 # endif
8932     ins_apply_autocmds(EVENT_INSERTCHANGE);
8933     if (State & REPLACE_FLAG)
8934 	State = INSERT | (State & LANGMAP);
8935     else
8936 	State = replaceState | (State & LANGMAP);
8937     AppendCharToRedobuff(K_INS);
8938     showmode();
8939 #ifdef CURSOR_SHAPE
8940     ui_cursor_shape();		/* may show different cursor shape */
8941 #endif
8942 }
8943 
8944 /*
8945  * Pressed CTRL-O in Insert mode.
8946  */
8947     static void
8948 ins_ctrl_o(void)
8949 {
8950     if (State & VREPLACE_FLAG)
8951 	restart_edit = 'V';
8952     else
8953 	if (State & REPLACE_FLAG)
8954 	restart_edit = 'R';
8955     else
8956 	restart_edit = 'I';
8957 #ifdef FEAT_VIRTUALEDIT
8958     if (virtual_active())
8959 	ins_at_eol = FALSE;	/* cursor always keeps its column */
8960     else
8961 #endif
8962 	ins_at_eol = (gchar_cursor() == NUL);
8963 }
8964 
8965 /*
8966  * If the cursor is on an indent, ^T/^D insert/delete one
8967  * shiftwidth.	Otherwise ^T/^D behave like a "<<" or ">>".
8968  * Always round the indent to 'shiftwidth', this is compatible
8969  * with vi.  But vi only supports ^T and ^D after an
8970  * autoindent, we support it everywhere.
8971  */
8972     static void
8973 ins_shift(int c, int lastc)
8974 {
8975     if (stop_arrow() == FAIL)
8976 	return;
8977     AppendCharToRedobuff(c);
8978 
8979     /*
8980      * 0^D and ^^D: remove all indent.
8981      */
8982     if (c == Ctrl_D && (lastc == '0' || lastc == '^')
8983 						  && curwin->w_cursor.col > 0)
8984     {
8985 	--curwin->w_cursor.col;
8986 	(void)del_char(FALSE);		/* delete the '^' or '0' */
8987 	/* In Replace mode, restore the characters that '^' or '0' replaced. */
8988 	if (State & REPLACE_FLAG)
8989 	    replace_pop_ins();
8990 	if (lastc == '^')
8991 	    old_indent = get_indent();	/* remember curr. indent */
8992 	change_indent(INDENT_SET, 0, TRUE, 0, TRUE);
8993     }
8994     else
8995 	change_indent(c == Ctrl_D ? INDENT_DEC : INDENT_INC, 0, TRUE, 0, TRUE);
8996 
8997     if (did_ai && *skipwhite(ml_get_curline()) != NUL)
8998 	did_ai = FALSE;
8999 #ifdef FEAT_SMARTINDENT
9000     did_si = FALSE;
9001     can_si = FALSE;
9002     can_si_back = FALSE;
9003 #endif
9004 #ifdef FEAT_CINDENT
9005     can_cindent = FALSE;	/* no cindenting after ^D or ^T */
9006 #endif
9007 }
9008 
9009     static void
9010 ins_del(void)
9011 {
9012     int	    temp;
9013 
9014     if (stop_arrow() == FAIL)
9015 	return;
9016     if (gchar_cursor() == NUL)		/* delete newline */
9017     {
9018 	temp = curwin->w_cursor.col;
9019 	if (!can_bs(BS_EOL)		/* only if "eol" included */
9020 		|| do_join(2, FALSE, TRUE, FALSE, FALSE) == FAIL)
9021 	    vim_beep(BO_BS);
9022 	else
9023 	{
9024 	    curwin->w_cursor.col = temp;
9025 	    /* Adjust orig_line_count in case more lines have been deleted than
9026 	     * have been added. That makes sure, that open_line() later
9027 	     * can access all buffer lines correctly */
9028 	    if (State & VREPLACE_FLAG &&
9029 		    orig_line_count > curbuf->b_ml.ml_line_count)
9030 		orig_line_count = curbuf->b_ml.ml_line_count;
9031 	}
9032     }
9033     else if (del_char(FALSE) == FAIL)  /* delete char under cursor */
9034 	vim_beep(BO_BS);
9035     did_ai = FALSE;
9036 #ifdef FEAT_SMARTINDENT
9037     did_si = FALSE;
9038     can_si = FALSE;
9039     can_si_back = FALSE;
9040 #endif
9041     AppendCharToRedobuff(K_DEL);
9042 }
9043 
9044 /*
9045  * Delete one character for ins_bs().
9046  */
9047     static void
9048 ins_bs_one(colnr_T *vcolp)
9049 {
9050     dec_cursor();
9051     getvcol(curwin, &curwin->w_cursor, vcolp, NULL, NULL);
9052     if (State & REPLACE_FLAG)
9053     {
9054 	/* Don't delete characters before the insert point when in
9055 	 * Replace mode */
9056 	if (curwin->w_cursor.lnum != Insstart.lnum
9057 		|| curwin->w_cursor.col >= Insstart.col)
9058 	    replace_do_bs(-1);
9059     }
9060     else
9061 	(void)del_char(FALSE);
9062 }
9063 
9064 /*
9065  * Handle Backspace, delete-word and delete-line in Insert mode.
9066  * Return TRUE when backspace was actually used.
9067  */
9068     static int
9069 ins_bs(
9070     int		c,
9071     int		mode,
9072     int		*inserted_space_p)
9073 {
9074     linenr_T	lnum;
9075     int		cc;
9076     int		temp = 0;	    /* init for GCC */
9077     colnr_T	save_col;
9078     colnr_T	mincol;
9079     int		did_backspace = FALSE;
9080     int		in_indent;
9081     int		oldState;
9082 #ifdef FEAT_MBYTE
9083     int		cpc[MAX_MCO];	    /* composing characters */
9084 #endif
9085 
9086     /*
9087      * can't delete anything in an empty file
9088      * can't backup past first character in buffer
9089      * can't backup past starting point unless 'backspace' > 1
9090      * can backup to a previous line if 'backspace' == 0
9091      */
9092     if (       BUFEMPTY()
9093 	    || (
9094 #ifdef FEAT_RIGHTLEFT
9095 		!revins_on &&
9096 #endif
9097 		((curwin->w_cursor.lnum == 1 && curwin->w_cursor.col == 0)
9098 		    || (!can_bs(BS_START)
9099 			&& (arrow_used
9100 			    || (curwin->w_cursor.lnum == Insstart_orig.lnum
9101 				&& curwin->w_cursor.col <= Insstart_orig.col)))
9102 		    || (!can_bs(BS_INDENT) && !arrow_used && ai_col > 0
9103 					 && curwin->w_cursor.col <= ai_col)
9104 		    || (!can_bs(BS_EOL) && curwin->w_cursor.col == 0))))
9105     {
9106 	vim_beep(BO_BS);
9107 	return FALSE;
9108     }
9109 
9110     if (stop_arrow() == FAIL)
9111 	return FALSE;
9112     in_indent = inindent(0);
9113 #ifdef FEAT_CINDENT
9114     if (in_indent)
9115 	can_cindent = FALSE;
9116 #endif
9117 #ifdef FEAT_COMMENTS
9118     end_comment_pending = NUL;	/* After BS, don't auto-end comment */
9119 #endif
9120 #ifdef FEAT_RIGHTLEFT
9121     if (revins_on)	    /* put cursor after last inserted char */
9122 	inc_cursor();
9123 #endif
9124 
9125 #ifdef FEAT_VIRTUALEDIT
9126     /* Virtualedit:
9127      *	BACKSPACE_CHAR eats a virtual space
9128      *	BACKSPACE_WORD eats all coladd
9129      *	BACKSPACE_LINE eats all coladd and keeps going
9130      */
9131     if (curwin->w_cursor.coladd > 0)
9132     {
9133 	if (mode == BACKSPACE_CHAR)
9134 	{
9135 	    --curwin->w_cursor.coladd;
9136 	    return TRUE;
9137 	}
9138 	if (mode == BACKSPACE_WORD)
9139 	{
9140 	    curwin->w_cursor.coladd = 0;
9141 	    return TRUE;
9142 	}
9143 	curwin->w_cursor.coladd = 0;
9144     }
9145 #endif
9146 
9147     /*
9148      * Delete newline!
9149      */
9150     if (curwin->w_cursor.col == 0)
9151     {
9152 	lnum = Insstart.lnum;
9153 	if (curwin->w_cursor.lnum == lnum
9154 #ifdef FEAT_RIGHTLEFT
9155 			|| revins_on
9156 #endif
9157 				    )
9158 	{
9159 	    if (u_save((linenr_T)(curwin->w_cursor.lnum - 2),
9160 			       (linenr_T)(curwin->w_cursor.lnum + 1)) == FAIL)
9161 		return FALSE;
9162 	    --Insstart.lnum;
9163 	    Insstart.col = (colnr_T)STRLEN(ml_get(Insstart.lnum));
9164 	}
9165 	/*
9166 	 * In replace mode:
9167 	 * cc < 0: NL was inserted, delete it
9168 	 * cc >= 0: NL was replaced, put original characters back
9169 	 */
9170 	cc = -1;
9171 	if (State & REPLACE_FLAG)
9172 	    cc = replace_pop();	    /* returns -1 if NL was inserted */
9173 	/*
9174 	 * In replace mode, in the line we started replacing, we only move the
9175 	 * cursor.
9176 	 */
9177 	if ((State & REPLACE_FLAG) && curwin->w_cursor.lnum <= lnum)
9178 	{
9179 	    dec_cursor();
9180 	}
9181 	else
9182 	{
9183 	    if (!(State & VREPLACE_FLAG)
9184 				   || curwin->w_cursor.lnum > orig_line_count)
9185 	    {
9186 		temp = gchar_cursor();	/* remember current char */
9187 		--curwin->w_cursor.lnum;
9188 
9189 		/* When "aw" is in 'formatoptions' we must delete the space at
9190 		 * the end of the line, otherwise the line will be broken
9191 		 * again when auto-formatting. */
9192 		if (has_format_option(FO_AUTO)
9193 					   && has_format_option(FO_WHITE_PAR))
9194 		{
9195 		    char_u  *ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum,
9196 									TRUE);
9197 		    int	    len;
9198 
9199 		    len = (int)STRLEN(ptr);
9200 		    if (len > 0 && ptr[len - 1] == ' ')
9201 			ptr[len - 1] = NUL;
9202 		}
9203 
9204 		(void)do_join(2, FALSE, FALSE, FALSE, FALSE);
9205 		if (temp == NUL && gchar_cursor() != NUL)
9206 		    inc_cursor();
9207 	    }
9208 	    else
9209 		dec_cursor();
9210 
9211 	    /*
9212 	     * In REPLACE mode we have to put back the text that was replaced
9213 	     * by the NL. On the replace stack is first a NUL-terminated
9214 	     * sequence of characters that were deleted and then the
9215 	     * characters that NL replaced.
9216 	     */
9217 	    if (State & REPLACE_FLAG)
9218 	    {
9219 		/*
9220 		 * Do the next ins_char() in NORMAL state, to
9221 		 * prevent ins_char() from replacing characters and
9222 		 * avoiding showmatch().
9223 		 */
9224 		oldState = State;
9225 		State = NORMAL;
9226 		/*
9227 		 * restore characters (blanks) deleted after cursor
9228 		 */
9229 		while (cc > 0)
9230 		{
9231 		    save_col = curwin->w_cursor.col;
9232 #ifdef FEAT_MBYTE
9233 		    mb_replace_pop_ins(cc);
9234 #else
9235 		    ins_char(cc);
9236 #endif
9237 		    curwin->w_cursor.col = save_col;
9238 		    cc = replace_pop();
9239 		}
9240 		/* restore the characters that NL replaced */
9241 		replace_pop_ins();
9242 		State = oldState;
9243 	    }
9244 	}
9245 	did_ai = FALSE;
9246     }
9247     else
9248     {
9249 	/*
9250 	 * Delete character(s) before the cursor.
9251 	 */
9252 #ifdef FEAT_RIGHTLEFT
9253 	if (revins_on)		/* put cursor on last inserted char */
9254 	    dec_cursor();
9255 #endif
9256 	mincol = 0;
9257 						/* keep indent */
9258 	if (mode == BACKSPACE_LINE
9259 		&& (curbuf->b_p_ai
9260 #ifdef FEAT_CINDENT
9261 		    || cindent_on()
9262 #endif
9263 		   )
9264 #ifdef FEAT_RIGHTLEFT
9265 		&& !revins_on
9266 #endif
9267 			    )
9268 	{
9269 	    save_col = curwin->w_cursor.col;
9270 	    beginline(BL_WHITE);
9271 	    if (curwin->w_cursor.col < save_col)
9272 		mincol = curwin->w_cursor.col;
9273 	    curwin->w_cursor.col = save_col;
9274 	}
9275 
9276 	/*
9277 	 * Handle deleting one 'shiftwidth' or 'softtabstop'.
9278 	 */
9279 	if (	   mode == BACKSPACE_CHAR
9280 		&& ((p_sta && in_indent)
9281 		    || ((get_sts_value() != 0
9282 #ifdef FEAT_VARTABS
9283 			|| tabstop_count(curbuf->b_p_vsts_array)
9284 #endif
9285 			)
9286 			&& curwin->w_cursor.col > 0
9287 			&& (*(ml_get_cursor() - 1) == TAB
9288 			    || (*(ml_get_cursor() - 1) == ' '
9289 				&& (!*inserted_space_p
9290 				    || arrow_used))))))
9291 	{
9292 	    int		ts;
9293 	    colnr_T	vcol;
9294 	    colnr_T	want_vcol;
9295 	    colnr_T	start_vcol;
9296 
9297 	    *inserted_space_p = FALSE;
9298 	    /* Compute the virtual column where we want to be.  Since
9299 	     * 'showbreak' may get in the way, need to get the last column of
9300 	     * the previous character. */
9301 	    getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
9302 	    start_vcol = vcol;
9303 	    dec_cursor();
9304 	    getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol);
9305 	    inc_cursor();
9306 #ifdef FEAT_VARTABS
9307 	    if (p_sta && in_indent)
9308 	    {
9309 		ts = (int)get_sw_value(curbuf);
9310 		want_vcol = (want_vcol / ts) * ts;
9311 	    }
9312 	    else
9313 		want_vcol = tabstop_start(want_vcol, get_sts_value(),
9314 						     curbuf->b_p_vsts_array);
9315 #else
9316 	    if (p_sta && in_indent)
9317 		ts = (int)get_sw_value(curbuf);
9318 	    else
9319 		ts = (int)get_sts_value();
9320 	    want_vcol = (want_vcol / ts) * ts;
9321 #endif
9322 
9323 	    /* delete characters until we are at or before want_vcol */
9324 	    while (vcol > want_vcol
9325 		    && (cc = *(ml_get_cursor() - 1), VIM_ISWHITE(cc)))
9326 		ins_bs_one(&vcol);
9327 
9328 	    /* insert extra spaces until we are at want_vcol */
9329 	    while (vcol < want_vcol)
9330 	    {
9331 		/* Remember the first char we inserted */
9332 		if (curwin->w_cursor.lnum == Insstart_orig.lnum
9333 				   && curwin->w_cursor.col < Insstart_orig.col)
9334 		    Insstart_orig.col = curwin->w_cursor.col;
9335 
9336 		if (State & VREPLACE_FLAG)
9337 		    ins_char(' ');
9338 		else
9339 		{
9340 		    ins_str((char_u *)" ");
9341 		    if ((State & REPLACE_FLAG))
9342 			replace_push(NUL);
9343 		}
9344 		getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
9345 	    }
9346 
9347 	    /* If we are now back where we started delete one character.  Can
9348 	     * happen when using 'sts' and 'linebreak'. */
9349 	    if (vcol >= start_vcol)
9350 		ins_bs_one(&vcol);
9351 	}
9352 
9353 	/*
9354 	 * Delete upto starting point, start of line or previous word.
9355 	 */
9356 	else
9357 	{
9358 #ifdef FEAT_MBYTE
9359 	    int cclass = 0, prev_cclass = 0;
9360 
9361 	    if (has_mbyte)
9362 		cclass = mb_get_class(ml_get_cursor());
9363 #endif
9364 	    do
9365 	    {
9366 #ifdef FEAT_RIGHTLEFT
9367 		if (!revins_on) /* put cursor on char to be deleted */
9368 #endif
9369 		    dec_cursor();
9370 
9371 		cc = gchar_cursor();
9372 #ifdef FEAT_MBYTE
9373 		/* look multi-byte character class */
9374 		if (has_mbyte)
9375 		{
9376 		    prev_cclass = cclass;
9377 		    cclass = mb_get_class(ml_get_cursor());
9378 		}
9379 #endif
9380 
9381 		/* start of word? */
9382 		if (mode == BACKSPACE_WORD && !vim_isspace(cc))
9383 		{
9384 		    mode = BACKSPACE_WORD_NOT_SPACE;
9385 		    temp = vim_iswordc(cc);
9386 		}
9387 		/* end of word? */
9388 		else if (mode == BACKSPACE_WORD_NOT_SPACE
9389 			&& ((vim_isspace(cc) || vim_iswordc(cc) != temp)
9390 #ifdef FEAT_MBYTE
9391 			|| prev_cclass != cclass
9392 #endif
9393 			))
9394 		{
9395 #ifdef FEAT_RIGHTLEFT
9396 		    if (!revins_on)
9397 #endif
9398 			inc_cursor();
9399 #ifdef FEAT_RIGHTLEFT
9400 		    else if (State & REPLACE_FLAG)
9401 			dec_cursor();
9402 #endif
9403 		    break;
9404 		}
9405 		if (State & REPLACE_FLAG)
9406 		    replace_do_bs(-1);
9407 		else
9408 		{
9409 #ifdef FEAT_MBYTE
9410 		    if (enc_utf8 && p_deco)
9411 			(void)utfc_ptr2char(ml_get_cursor(), cpc);
9412 #endif
9413 		    (void)del_char(FALSE);
9414 #ifdef FEAT_MBYTE
9415 		    /*
9416 		     * If there are combining characters and 'delcombine' is set
9417 		     * move the cursor back.  Don't back up before the base
9418 		     * character.
9419 		     */
9420 		    if (enc_utf8 && p_deco && cpc[0] != NUL)
9421 			inc_cursor();
9422 #endif
9423 #ifdef FEAT_RIGHTLEFT
9424 		    if (revins_chars)
9425 		    {
9426 			revins_chars--;
9427 			revins_legal++;
9428 		    }
9429 		    if (revins_on && gchar_cursor() == NUL)
9430 			break;
9431 #endif
9432 		}
9433 		/* Just a single backspace?: */
9434 		if (mode == BACKSPACE_CHAR)
9435 		    break;
9436 	    } while (
9437 #ifdef FEAT_RIGHTLEFT
9438 		    revins_on ||
9439 #endif
9440 		    (curwin->w_cursor.col > mincol
9441 		    && (curwin->w_cursor.lnum != Insstart_orig.lnum
9442 			|| curwin->w_cursor.col != Insstart_orig.col)));
9443 	}
9444 	did_backspace = TRUE;
9445     }
9446 #ifdef FEAT_SMARTINDENT
9447     did_si = FALSE;
9448     can_si = FALSE;
9449     can_si_back = FALSE;
9450 #endif
9451     if (curwin->w_cursor.col <= 1)
9452 	did_ai = FALSE;
9453     /*
9454      * It's a little strange to put backspaces into the redo
9455      * buffer, but it makes auto-indent a lot easier to deal
9456      * with.
9457      */
9458     AppendCharToRedobuff(c);
9459 
9460     /* If deleted before the insertion point, adjust it */
9461     if (curwin->w_cursor.lnum == Insstart_orig.lnum
9462 				  && curwin->w_cursor.col < Insstart_orig.col)
9463 	Insstart_orig.col = curwin->w_cursor.col;
9464 
9465     /* vi behaviour: the cursor moves backward but the character that
9466      *		     was there remains visible
9467      * Vim behaviour: the cursor moves backward and the character that
9468      *		      was there is erased from the screen.
9469      * We can emulate the vi behaviour by pretending there is a dollar
9470      * displayed even when there isn't.
9471      *  --pkv Sun Jan 19 01:56:40 EST 2003 */
9472     if (vim_strchr(p_cpo, CPO_BACKSPACE) != NULL && dollar_vcol == -1)
9473 	dollar_vcol = curwin->w_virtcol;
9474 
9475 #ifdef FEAT_FOLDING
9476     /* When deleting a char the cursor line must never be in a closed fold.
9477      * E.g., when 'foldmethod' is indent and deleting the first non-white
9478      * char before a Tab. */
9479     if (did_backspace)
9480 	foldOpenCursor();
9481 #endif
9482 
9483     return did_backspace;
9484 }
9485 
9486 #ifdef FEAT_MOUSE
9487     static void
9488 ins_mouse(int c)
9489 {
9490     pos_T	tpos;
9491     win_T	*old_curwin = curwin;
9492 
9493 # ifdef FEAT_GUI
9494     /* When GUI is active, also move/paste when 'mouse' is empty */
9495     if (!gui.in_use)
9496 # endif
9497 	if (!mouse_has(MOUSE_INSERT))
9498 	    return;
9499 
9500     undisplay_dollar();
9501     tpos = curwin->w_cursor;
9502     if (do_mouse(NULL, c, BACKWARD, 1L, 0))
9503     {
9504 	win_T	*new_curwin = curwin;
9505 
9506 	if (curwin != old_curwin && win_valid(old_curwin))
9507 	{
9508 	    /* Mouse took us to another window.  We need to go back to the
9509 	     * previous one to stop insert there properly. */
9510 	    curwin = old_curwin;
9511 	    curbuf = curwin->w_buffer;
9512 #ifdef FEAT_JOB_CHANNEL
9513 	    if (bt_prompt(curbuf))
9514 		// Restart Insert mode when re-entering the prompt buffer.
9515 		curbuf->b_prompt_insert = 'A';
9516 #endif
9517 	}
9518 	start_arrow(curwin == old_curwin ? &tpos : NULL);
9519 	if (curwin != new_curwin && win_valid(new_curwin))
9520 	{
9521 	    curwin = new_curwin;
9522 	    curbuf = curwin->w_buffer;
9523 	}
9524 # ifdef FEAT_CINDENT
9525 	can_cindent = TRUE;
9526 # endif
9527     }
9528 
9529     /* redraw status lines (in case another window became active) */
9530     redraw_statuslines();
9531 }
9532 
9533     static void
9534 ins_mousescroll(int dir)
9535 {
9536     pos_T	tpos;
9537     win_T	*old_curwin = curwin, *wp;
9538 # ifdef FEAT_INS_EXPAND
9539     int		did_scroll = FALSE;
9540 # endif
9541 
9542     tpos = curwin->w_cursor;
9543 
9544     if (mouse_row >= 0 && mouse_col >= 0)
9545     {
9546 	int row, col;
9547 
9548 	row = mouse_row;
9549 	col = mouse_col;
9550 
9551 	/* find the window at the pointer coordinates */
9552 	wp = mouse_find_win(&row, &col);
9553 	if (wp == NULL)
9554 	    return;
9555 	curwin = wp;
9556 	curbuf = curwin->w_buffer;
9557     }
9558     if (curwin == old_curwin)
9559 	undisplay_dollar();
9560 
9561 # ifdef FEAT_INS_EXPAND
9562     /* Don't scroll the window in which completion is being done. */
9563     if (!pum_visible() || curwin != old_curwin)
9564 # endif
9565     {
9566 	if (dir == MSCR_DOWN || dir == MSCR_UP)
9567 	{
9568 	    if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
9569 		scroll_redraw(dir,
9570 			(long)(curwin->w_botline - curwin->w_topline));
9571 	    else
9572 		scroll_redraw(dir, 3L);
9573 	}
9574 #ifdef FEAT_GUI
9575 	else
9576 	{
9577 	    int val, step = 6;
9578 
9579 	    if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
9580 		step = curwin->w_width;
9581 	    val = curwin->w_leftcol + (dir == MSCR_RIGHT ? -step : step);
9582 	    if (val < 0)
9583 		val = 0;
9584 	    gui_do_horiz_scroll(val, TRUE);
9585 	}
9586 #endif
9587 # ifdef FEAT_INS_EXPAND
9588 	did_scroll = TRUE;
9589 # endif
9590     }
9591 
9592     curwin->w_redr_status = TRUE;
9593 
9594     curwin = old_curwin;
9595     curbuf = curwin->w_buffer;
9596 
9597 # ifdef FEAT_INS_EXPAND
9598     /* The popup menu may overlay the window, need to redraw it.
9599      * TODO: Would be more efficient to only redraw the windows that are
9600      * overlapped by the popup menu. */
9601     if (pum_visible() && did_scroll)
9602     {
9603 	redraw_all_later(NOT_VALID);
9604 	ins_compl_show_pum();
9605     }
9606 # endif
9607 
9608     if (!EQUAL_POS(curwin->w_cursor, tpos))
9609     {
9610 	start_arrow(&tpos);
9611 # ifdef FEAT_CINDENT
9612 	can_cindent = TRUE;
9613 # endif
9614     }
9615 }
9616 #endif
9617 
9618 /*
9619  * Handle receiving P_PS: start paste mode.  Inserts the following text up to
9620  * P_PE literally.
9621  * When "drop" is TRUE then consume the text and drop it.
9622  */
9623     int
9624 bracketed_paste(paste_mode_T mode, int drop, garray_T *gap)
9625 {
9626     int		c;
9627     char_u	buf[NUMBUFLEN + MB_MAXBYTES];
9628     int		idx = 0;
9629     char_u	*end = find_termcode((char_u *)"PE");
9630     int		ret_char = -1;
9631     int		save_allow_keys = allow_keys;
9632     int		save_paste = p_paste;
9633 
9634     /* If the end code is too long we can't detect it, read everything. */
9635     if (STRLEN(end) >= NUMBUFLEN)
9636 	end = NULL;
9637     ++no_mapping;
9638     allow_keys = 0;
9639     if (!p_paste)
9640 	// Also have the side effects of setting 'paste' to make it work much
9641 	// faster.
9642 	set_option_value((char_u *)"paste", TRUE, NULL, 0);
9643 
9644     for (;;)
9645     {
9646 	// When the end is not defined read everything there is.
9647 	if (end == NULL && vpeekc() == NUL)
9648 	    break;
9649 	do
9650 	{
9651 	    c = vgetc();
9652 	} while (c == K_IGNORE || c == K_VER_SCROLLBAR || c == K_HOR_SCROLLBAR);
9653 	if (c == NUL || got_int)
9654 	    // When CTRL-C was encountered the typeahead will be flushed and we
9655 	    // won't get the end sequence.
9656 	    break;
9657 
9658 #ifdef FEAT_MBYTE
9659 	if (has_mbyte)
9660 	    idx += (*mb_char2bytes)(c, buf + idx);
9661 	else
9662 #endif
9663 	    buf[idx++] = c;
9664 	buf[idx] = NUL;
9665 	if (end != NULL && STRNCMP(buf, end, idx) == 0)
9666 	{
9667 	    if (end[idx] == NUL)
9668 		break; /* Found the end of paste code. */
9669 	    continue;
9670 	}
9671 	if (!drop)
9672 	{
9673 	    switch (mode)
9674 	    {
9675 		case PASTE_CMDLINE:
9676 		    put_on_cmdline(buf, idx, TRUE);
9677 		    break;
9678 
9679 		case PASTE_EX:
9680 		    if (gap != NULL && ga_grow(gap, idx) == OK)
9681 		    {
9682 			mch_memmove((char *)gap->ga_data + gap->ga_len,
9683 							     buf, (size_t)idx);
9684 			gap->ga_len += idx;
9685 		    }
9686 		    break;
9687 
9688 		case PASTE_INSERT:
9689 		    if (stop_arrow() == OK)
9690 		    {
9691 			c = buf[0];
9692 			if (idx == 1 && (c == CAR || c == K_KENTER || c == NL))
9693 			    ins_eol(c);
9694 			else
9695 			{
9696 			    ins_char_bytes(buf, idx);
9697 			    AppendToRedobuffLit(buf, idx);
9698 			}
9699 		    }
9700 		    break;
9701 
9702 		case PASTE_ONE_CHAR:
9703 		    if (ret_char == -1)
9704 		    {
9705 #ifdef FEAT_MBYTE
9706 			if (has_mbyte)
9707 			    ret_char = (*mb_ptr2char)(buf);
9708 			else
9709 #endif
9710 			    ret_char = buf[0];
9711 		    }
9712 		    break;
9713 	    }
9714 	}
9715 	idx = 0;
9716     }
9717 
9718     --no_mapping;
9719     allow_keys = save_allow_keys;
9720     if (!save_paste)
9721 	set_option_value((char_u *)"paste", FALSE, NULL, 0);
9722 
9723     return ret_char;
9724 }
9725 
9726 #if defined(FEAT_GUI_TABLINE) || defined(PROTO)
9727     static void
9728 ins_tabline(int c)
9729 {
9730     /* We will be leaving the current window, unless closing another tab. */
9731     if (c != K_TABMENU || current_tabmenu != TABLINE_MENU_CLOSE
9732 		|| (current_tab != 0 && current_tab != tabpage_index(curtab)))
9733     {
9734 	undisplay_dollar();
9735 	start_arrow(&curwin->w_cursor);
9736 # ifdef FEAT_CINDENT
9737 	can_cindent = TRUE;
9738 # endif
9739     }
9740 
9741     if (c == K_TABLINE)
9742 	goto_tabpage(current_tab);
9743     else
9744     {
9745 	handle_tabmenu();
9746 	redraw_statuslines();	/* will redraw the tabline when needed */
9747     }
9748 }
9749 #endif
9750 
9751 #if defined(FEAT_GUI) || defined(PROTO)
9752     void
9753 ins_scroll(void)
9754 {
9755     pos_T	tpos;
9756 
9757     undisplay_dollar();
9758     tpos = curwin->w_cursor;
9759     if (gui_do_scroll())
9760     {
9761 	start_arrow(&tpos);
9762 # ifdef FEAT_CINDENT
9763 	can_cindent = TRUE;
9764 # endif
9765     }
9766 }
9767 
9768     void
9769 ins_horscroll(void)
9770 {
9771     pos_T	tpos;
9772 
9773     undisplay_dollar();
9774     tpos = curwin->w_cursor;
9775     if (gui_do_horiz_scroll(scrollbar_value, FALSE))
9776     {
9777 	start_arrow(&tpos);
9778 # ifdef FEAT_CINDENT
9779 	can_cindent = TRUE;
9780 # endif
9781     }
9782 }
9783 #endif
9784 
9785     static void
9786 ins_left(
9787     int	    end_change) /* end undoable change */
9788 {
9789     pos_T	tpos;
9790 
9791 #ifdef FEAT_FOLDING
9792     if ((fdo_flags & FDO_HOR) && KeyTyped)
9793 	foldOpenCursor();
9794 #endif
9795     undisplay_dollar();
9796     tpos = curwin->w_cursor;
9797     if (oneleft() == OK)
9798     {
9799 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
9800 	/* Only call start_arrow() when not busy with preediting, it will
9801 	 * break undo.  K_LEFT is inserted in im_correct_cursor(). */
9802 	if (p_imst == IM_OVER_THE_SPOT || !im_is_preediting())
9803 #endif
9804 	{
9805 	    start_arrow_with_change(&tpos, end_change);
9806 	    if (!end_change)
9807 		AppendCharToRedobuff(K_LEFT);
9808 	}
9809 #ifdef FEAT_RIGHTLEFT
9810 	/* If exit reversed string, position is fixed */
9811 	if (revins_scol != -1 && (int)curwin->w_cursor.col >= revins_scol)
9812 	    revins_legal++;
9813 	revins_chars++;
9814 #endif
9815     }
9816 
9817     /*
9818      * if 'whichwrap' set for cursor in insert mode may go to
9819      * previous line
9820      */
9821     else if (vim_strchr(p_ww, '[') != NULL && curwin->w_cursor.lnum > 1)
9822     {
9823 	/* always break undo when moving upwards/downwards, else undo may break */
9824 	start_arrow(&tpos);
9825 	--(curwin->w_cursor.lnum);
9826 	coladvance((colnr_T)MAXCOL);
9827 	curwin->w_set_curswant = TRUE;	/* so we stay at the end */
9828     }
9829     else
9830 	vim_beep(BO_CRSR);
9831     dont_sync_undo = FALSE;
9832 }
9833 
9834     static void
9835 ins_home(int c)
9836 {
9837     pos_T	tpos;
9838 
9839 #ifdef FEAT_FOLDING
9840     if ((fdo_flags & FDO_HOR) && KeyTyped)
9841 	foldOpenCursor();
9842 #endif
9843     undisplay_dollar();
9844     tpos = curwin->w_cursor;
9845     if (c == K_C_HOME)
9846 	curwin->w_cursor.lnum = 1;
9847     curwin->w_cursor.col = 0;
9848 #ifdef FEAT_VIRTUALEDIT
9849     curwin->w_cursor.coladd = 0;
9850 #endif
9851     curwin->w_curswant = 0;
9852     start_arrow(&tpos);
9853 }
9854 
9855     static void
9856 ins_end(int c)
9857 {
9858     pos_T	tpos;
9859 
9860 #ifdef FEAT_FOLDING
9861     if ((fdo_flags & FDO_HOR) && KeyTyped)
9862 	foldOpenCursor();
9863 #endif
9864     undisplay_dollar();
9865     tpos = curwin->w_cursor;
9866     if (c == K_C_END)
9867 	curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
9868     coladvance((colnr_T)MAXCOL);
9869     curwin->w_curswant = MAXCOL;
9870 
9871     start_arrow(&tpos);
9872 }
9873 
9874     static void
9875 ins_s_left(void)
9876 {
9877 #ifdef FEAT_FOLDING
9878     if ((fdo_flags & FDO_HOR) && KeyTyped)
9879 	foldOpenCursor();
9880 #endif
9881     undisplay_dollar();
9882     if (curwin->w_cursor.lnum > 1 || curwin->w_cursor.col > 0)
9883     {
9884 	start_arrow(&curwin->w_cursor);
9885 	(void)bck_word(1L, FALSE, FALSE);
9886 	curwin->w_set_curswant = TRUE;
9887     }
9888     else
9889 	vim_beep(BO_CRSR);
9890 }
9891 
9892     static void
9893 ins_right(
9894     int	    end_change) /* end undoable change */
9895 {
9896 #ifdef FEAT_FOLDING
9897     if ((fdo_flags & FDO_HOR) && KeyTyped)
9898 	foldOpenCursor();
9899 #endif
9900     undisplay_dollar();
9901     if (gchar_cursor() != NUL
9902 #ifdef FEAT_VIRTUALEDIT
9903 	    || virtual_active()
9904 #endif
9905 	    )
9906     {
9907 	start_arrow_with_change(&curwin->w_cursor, end_change);
9908 	if (!end_change)
9909 	    AppendCharToRedobuff(K_RIGHT);
9910 	curwin->w_set_curswant = TRUE;
9911 #ifdef FEAT_VIRTUALEDIT
9912 	if (virtual_active())
9913 	    oneright();
9914 	else
9915 #endif
9916 	{
9917 #ifdef FEAT_MBYTE
9918 	    if (has_mbyte)
9919 		curwin->w_cursor.col += (*mb_ptr2len)(ml_get_cursor());
9920 	    else
9921 #endif
9922 		++curwin->w_cursor.col;
9923 	}
9924 
9925 #ifdef FEAT_RIGHTLEFT
9926 	revins_legal++;
9927 	if (revins_chars)
9928 	    revins_chars--;
9929 #endif
9930     }
9931     /* if 'whichwrap' set for cursor in insert mode, may move the
9932      * cursor to the next line */
9933     else if (vim_strchr(p_ww, ']') != NULL
9934 	    && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
9935     {
9936 	start_arrow(&curwin->w_cursor);
9937 	curwin->w_set_curswant = TRUE;
9938 	++curwin->w_cursor.lnum;
9939 	curwin->w_cursor.col = 0;
9940     }
9941     else
9942 	vim_beep(BO_CRSR);
9943     dont_sync_undo = FALSE;
9944 }
9945 
9946     static void
9947 ins_s_right(void)
9948 {
9949 #ifdef FEAT_FOLDING
9950     if ((fdo_flags & FDO_HOR) && KeyTyped)
9951 	foldOpenCursor();
9952 #endif
9953     undisplay_dollar();
9954     if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count
9955 	    || gchar_cursor() != NUL)
9956     {
9957 	start_arrow(&curwin->w_cursor);
9958 	(void)fwd_word(1L, FALSE, 0);
9959 	curwin->w_set_curswant = TRUE;
9960     }
9961     else
9962 	vim_beep(BO_CRSR);
9963 }
9964 
9965     static void
9966 ins_up(
9967     int		startcol)	/* when TRUE move to Insstart.col */
9968 {
9969     pos_T	tpos;
9970     linenr_T	old_topline = curwin->w_topline;
9971 #ifdef FEAT_DIFF
9972     int		old_topfill = curwin->w_topfill;
9973 #endif
9974 
9975     undisplay_dollar();
9976     tpos = curwin->w_cursor;
9977     if (cursor_up(1L, TRUE) == OK)
9978     {
9979 	if (startcol)
9980 	    coladvance(getvcol_nolist(&Insstart));
9981 	if (old_topline != curwin->w_topline
9982 #ifdef FEAT_DIFF
9983 		|| old_topfill != curwin->w_topfill
9984 #endif
9985 		)
9986 	    redraw_later(VALID);
9987 	start_arrow(&tpos);
9988 #ifdef FEAT_CINDENT
9989 	can_cindent = TRUE;
9990 #endif
9991     }
9992     else
9993 	vim_beep(BO_CRSR);
9994 }
9995 
9996     static void
9997 ins_pageup(void)
9998 {
9999     pos_T	tpos;
10000 
10001     undisplay_dollar();
10002 
10003     if (mod_mask & MOD_MASK_CTRL)
10004     {
10005 	/* <C-PageUp>: tab page back */
10006 	if (first_tabpage->tp_next != NULL)
10007 	{
10008 	    start_arrow(&curwin->w_cursor);
10009 	    goto_tabpage(-1);
10010 	}
10011 	return;
10012     }
10013 
10014     tpos = curwin->w_cursor;
10015     if (onepage(BACKWARD, 1L) == OK)
10016     {
10017 	start_arrow(&tpos);
10018 #ifdef FEAT_CINDENT
10019 	can_cindent = TRUE;
10020 #endif
10021     }
10022     else
10023 	vim_beep(BO_CRSR);
10024 }
10025 
10026     static void
10027 ins_down(
10028     int		startcol)	/* when TRUE move to Insstart.col */
10029 {
10030     pos_T	tpos;
10031     linenr_T	old_topline = curwin->w_topline;
10032 #ifdef FEAT_DIFF
10033     int		old_topfill = curwin->w_topfill;
10034 #endif
10035 
10036     undisplay_dollar();
10037     tpos = curwin->w_cursor;
10038     if (cursor_down(1L, TRUE) == OK)
10039     {
10040 	if (startcol)
10041 	    coladvance(getvcol_nolist(&Insstart));
10042 	if (old_topline != curwin->w_topline
10043 #ifdef FEAT_DIFF
10044 		|| old_topfill != curwin->w_topfill
10045 #endif
10046 		)
10047 	    redraw_later(VALID);
10048 	start_arrow(&tpos);
10049 #ifdef FEAT_CINDENT
10050 	can_cindent = TRUE;
10051 #endif
10052     }
10053     else
10054 	vim_beep(BO_CRSR);
10055 }
10056 
10057     static void
10058 ins_pagedown(void)
10059 {
10060     pos_T	tpos;
10061 
10062     undisplay_dollar();
10063 
10064     if (mod_mask & MOD_MASK_CTRL)
10065     {
10066 	/* <C-PageDown>: tab page forward */
10067 	if (first_tabpage->tp_next != NULL)
10068 	{
10069 	    start_arrow(&curwin->w_cursor);
10070 	    goto_tabpage(0);
10071 	}
10072 	return;
10073     }
10074 
10075     tpos = curwin->w_cursor;
10076     if (onepage(FORWARD, 1L) == OK)
10077     {
10078 	start_arrow(&tpos);
10079 #ifdef FEAT_CINDENT
10080 	can_cindent = TRUE;
10081 #endif
10082     }
10083     else
10084 	vim_beep(BO_CRSR);
10085 }
10086 
10087 #ifdef FEAT_DND
10088     static void
10089 ins_drop(void)
10090 {
10091     do_put('~', BACKWARD, 1L, PUT_CURSEND);
10092 }
10093 #endif
10094 
10095 /*
10096  * Handle TAB in Insert or Replace mode.
10097  * Return TRUE when the TAB needs to be inserted like a normal character.
10098  */
10099     static int
10100 ins_tab(void)
10101 {
10102     int		ind;
10103     int		i;
10104     int		temp;
10105 
10106     if (Insstart_blank_vcol == MAXCOL && curwin->w_cursor.lnum == Insstart.lnum)
10107 	Insstart_blank_vcol = get_nolist_virtcol();
10108     if (echeck_abbr(TAB + ABBR_OFF))
10109 	return FALSE;
10110 
10111     ind = inindent(0);
10112 #ifdef FEAT_CINDENT
10113     if (ind)
10114 	can_cindent = FALSE;
10115 #endif
10116 
10117     /*
10118      * When nothing special, insert TAB like a normal character.
10119      */
10120     if (!curbuf->b_p_et
10121 #ifdef FEAT_VARTABS
10122 	    && !(p_sta && ind
10123 		/* These five lines mean 'tabstop' != 'shiftwidth' */
10124 		&& ((tabstop_count(curbuf->b_p_vts_array) > 1)
10125 		    || (tabstop_count(curbuf->b_p_vts_array) == 1
10126 		        && tabstop_first(curbuf->b_p_vts_array)
10127 						       != get_sw_value(curbuf))
10128 	            || (tabstop_count(curbuf->b_p_vts_array) == 0
10129 		        && curbuf->b_p_ts != get_sw_value(curbuf))))
10130 	    && tabstop_count(curbuf->b_p_vsts_array) == 0
10131 #else
10132 	    && !(p_sta && ind && curbuf->b_p_ts != get_sw_value(curbuf))
10133 #endif
10134 	    && get_sts_value() == 0)
10135 	return TRUE;
10136 
10137     if (stop_arrow() == FAIL)
10138 	return TRUE;
10139 
10140     did_ai = FALSE;
10141 #ifdef FEAT_SMARTINDENT
10142     did_si = FALSE;
10143     can_si = FALSE;
10144     can_si_back = FALSE;
10145 #endif
10146     AppendToRedobuff((char_u *)"\t");
10147 
10148 #ifdef FEAT_VARTABS
10149     if (p_sta && ind)		/* insert tab in indent, use 'shiftwidth' */
10150     {
10151 	temp = (int)get_sw_value(curbuf);
10152 	temp -= get_nolist_virtcol() % temp;
10153     }
10154     else if (tabstop_count(curbuf->b_p_vsts_array) > 0 || curbuf->b_p_sts != 0)
10155 	                        /* use 'softtabstop' when set */
10156 	temp = tabstop_padding(get_nolist_virtcol(), get_sts_value(),
10157 						     curbuf->b_p_vsts_array);
10158     else			/* otherwise use 'tabstop' */
10159 	temp = tabstop_padding(get_nolist_virtcol(), curbuf->b_p_ts,
10160 						     curbuf->b_p_vts_array);
10161 #else
10162     if (p_sta && ind)		/* insert tab in indent, use 'shiftwidth' */
10163 	temp = (int)get_sw_value(curbuf);
10164     else if (curbuf->b_p_sts != 0) /* use 'softtabstop' when set */
10165 	temp = (int)get_sts_value();
10166     else			/* otherwise use 'tabstop' */
10167 	temp = (int)curbuf->b_p_ts;
10168     temp -= get_nolist_virtcol() % temp;
10169 #endif
10170 
10171     /*
10172      * Insert the first space with ins_char().	It will delete one char in
10173      * replace mode.  Insert the rest with ins_str(); it will not delete any
10174      * chars.  For VREPLACE mode, we use ins_char() for all characters.
10175      */
10176     ins_char(' ');
10177     while (--temp > 0)
10178     {
10179 	if (State & VREPLACE_FLAG)
10180 	    ins_char(' ');
10181 	else
10182 	{
10183 	    ins_str((char_u *)" ");
10184 	    if (State & REPLACE_FLAG)	    /* no char replaced */
10185 		replace_push(NUL);
10186 	}
10187     }
10188 
10189     /*
10190      * When 'expandtab' not set: Replace spaces by TABs where possible.
10191      */
10192 #ifdef FEAT_VARTABS
10193     if (!curbuf->b_p_et && (tabstop_count(curbuf->b_p_vsts_array) > 0
10194                             || get_sts_value() > 0
10195 			    || (p_sta && ind)))
10196 #else
10197     if (!curbuf->b_p_et && (get_sts_value() || (p_sta && ind)))
10198 #endif
10199     {
10200 	char_u		*ptr;
10201 	char_u		*saved_line = NULL;	/* init for GCC */
10202 	pos_T		pos;
10203 	pos_T		fpos;
10204 	pos_T		*cursor;
10205 	colnr_T		want_vcol, vcol;
10206 	int		change_col = -1;
10207 	int		save_list = curwin->w_p_list;
10208 
10209 	/*
10210 	 * Get the current line.  For VREPLACE mode, don't make real changes
10211 	 * yet, just work on a copy of the line.
10212 	 */
10213 	if (State & VREPLACE_FLAG)
10214 	{
10215 	    pos = curwin->w_cursor;
10216 	    cursor = &pos;
10217 	    saved_line = vim_strsave(ml_get_curline());
10218 	    if (saved_line == NULL)
10219 		return FALSE;
10220 	    ptr = saved_line + pos.col;
10221 	}
10222 	else
10223 	{
10224 	    ptr = ml_get_cursor();
10225 	    cursor = &curwin->w_cursor;
10226 	}
10227 
10228 	/* When 'L' is not in 'cpoptions' a tab always takes up 'ts' spaces. */
10229 	if (vim_strchr(p_cpo, CPO_LISTWM) == NULL)
10230 	    curwin->w_p_list = FALSE;
10231 
10232 	/* Find first white before the cursor */
10233 	fpos = curwin->w_cursor;
10234 	while (fpos.col > 0 && VIM_ISWHITE(ptr[-1]))
10235 	{
10236 	    --fpos.col;
10237 	    --ptr;
10238 	}
10239 
10240 	/* In Replace mode, don't change characters before the insert point. */
10241 	if ((State & REPLACE_FLAG)
10242 		&& fpos.lnum == Insstart.lnum
10243 		&& fpos.col < Insstart.col)
10244 	{
10245 	    ptr += Insstart.col - fpos.col;
10246 	    fpos.col = Insstart.col;
10247 	}
10248 
10249 	/* compute virtual column numbers of first white and cursor */
10250 	getvcol(curwin, &fpos, &vcol, NULL, NULL);
10251 	getvcol(curwin, cursor, &want_vcol, NULL, NULL);
10252 
10253 	/* Use as many TABs as possible.  Beware of 'breakindent', 'showbreak'
10254 	 * and 'linebreak' adding extra virtual columns. */
10255 	while (VIM_ISWHITE(*ptr))
10256 	{
10257 	    i = lbr_chartabsize(NULL, (char_u *)"\t", vcol);
10258 	    if (vcol + i > want_vcol)
10259 		break;
10260 	    if (*ptr != TAB)
10261 	    {
10262 		*ptr = TAB;
10263 		if (change_col < 0)
10264 		{
10265 		    change_col = fpos.col;  /* Column of first change */
10266 		    /* May have to adjust Insstart */
10267 		    if (fpos.lnum == Insstart.lnum && fpos.col < Insstart.col)
10268 			Insstart.col = fpos.col;
10269 		}
10270 	    }
10271 	    ++fpos.col;
10272 	    ++ptr;
10273 	    vcol += i;
10274 	}
10275 
10276 	if (change_col >= 0)
10277 	{
10278 	    int repl_off = 0;
10279 	    char_u *line = ptr;
10280 
10281 	    /* Skip over the spaces we need. */
10282 	    while (vcol < want_vcol && *ptr == ' ')
10283 	    {
10284 		vcol += lbr_chartabsize(line, ptr, vcol);
10285 		++ptr;
10286 		++repl_off;
10287 	    }
10288 	    if (vcol > want_vcol)
10289 	    {
10290 		/* Must have a char with 'showbreak' just before it. */
10291 		--ptr;
10292 		--repl_off;
10293 	    }
10294 	    fpos.col += repl_off;
10295 
10296 	    /* Delete following spaces. */
10297 	    i = cursor->col - fpos.col;
10298 	    if (i > 0)
10299 	    {
10300 		STRMOVE(ptr, ptr + i);
10301 		/* correct replace stack. */
10302 		if ((State & REPLACE_FLAG) && !(State & VREPLACE_FLAG))
10303 		    for (temp = i; --temp >= 0; )
10304 			replace_join(repl_off);
10305 #ifdef FEAT_TEXT_PROP
10306 		curbuf->b_ml.ml_line_len -= i;
10307 #endif
10308 	    }
10309 #ifdef FEAT_NETBEANS_INTG
10310 	    if (netbeans_active())
10311 	    {
10312 		netbeans_removed(curbuf, fpos.lnum, cursor->col, (long)(i + 1));
10313 		netbeans_inserted(curbuf, fpos.lnum, cursor->col,
10314 							   (char_u *)"\t", 1);
10315 	    }
10316 #endif
10317 	    cursor->col -= i;
10318 
10319 	    /*
10320 	     * In VREPLACE mode, we haven't changed anything yet.  Do it now by
10321 	     * backspacing over the changed spacing and then inserting the new
10322 	     * spacing.
10323 	     */
10324 	    if (State & VREPLACE_FLAG)
10325 	    {
10326 		/* Backspace from real cursor to change_col */
10327 		backspace_until_column(change_col);
10328 
10329 		/* Insert each char in saved_line from changed_col to
10330 		 * ptr-cursor */
10331 		ins_bytes_len(saved_line + change_col,
10332 						    cursor->col - change_col);
10333 	    }
10334 	}
10335 
10336 	if (State & VREPLACE_FLAG)
10337 	    vim_free(saved_line);
10338 	curwin->w_p_list = save_list;
10339     }
10340 
10341     return FALSE;
10342 }
10343 
10344 /*
10345  * Handle CR or NL in insert mode.
10346  * Return FAIL when out of memory or can't undo.
10347  */
10348     static int
10349 ins_eol(int c)
10350 {
10351     int	    i;
10352 
10353     if (echeck_abbr(c + ABBR_OFF))
10354 	return OK;
10355     if (stop_arrow() == FAIL)
10356 	return FAIL;
10357     undisplay_dollar();
10358 
10359     /*
10360      * Strange Vi behaviour: In Replace mode, typing a NL will not delete the
10361      * character under the cursor.  Only push a NUL on the replace stack,
10362      * nothing to put back when the NL is deleted.
10363      */
10364     if ((State & REPLACE_FLAG) && !(State & VREPLACE_FLAG))
10365 	replace_push(NUL);
10366 
10367     /*
10368      * In VREPLACE mode, a NL replaces the rest of the line, and starts
10369      * replacing the next line, so we push all of the characters left on the
10370      * line onto the replace stack.  This is not done here though, it is done
10371      * in open_line().
10372      */
10373 
10374 #ifdef FEAT_VIRTUALEDIT
10375     /* Put cursor on NUL if on the last char and coladd is 1 (happens after
10376      * CTRL-O). */
10377     if (virtual_active() && curwin->w_cursor.coladd > 0)
10378 	coladvance(getviscol());
10379 #endif
10380 
10381 #ifdef FEAT_RIGHTLEFT
10382 # ifdef FEAT_FKMAP
10383     if (p_altkeymap && p_fkmap)
10384 	fkmap(NL);
10385 # endif
10386     /* NL in reverse insert will always start in the end of
10387      * current line. */
10388     if (revins_on)
10389 	curwin->w_cursor.col += (colnr_T)STRLEN(ml_get_cursor());
10390 #endif
10391 
10392     AppendToRedobuff(NL_STR);
10393     i = open_line(FORWARD,
10394 #ifdef FEAT_COMMENTS
10395 	    has_format_option(FO_RET_COMS) ? OPENLINE_DO_COM :
10396 #endif
10397 	    0, old_indent);
10398     old_indent = 0;
10399 #ifdef FEAT_CINDENT
10400     can_cindent = TRUE;
10401 #endif
10402 #ifdef FEAT_FOLDING
10403     /* When inserting a line the cursor line must never be in a closed fold. */
10404     foldOpenCursor();
10405 #endif
10406 
10407     return i;
10408 }
10409 
10410 #ifdef FEAT_DIGRAPHS
10411 /*
10412  * Handle digraph in insert mode.
10413  * Returns character still to be inserted, or NUL when nothing remaining to be
10414  * done.
10415  */
10416     static int
10417 ins_digraph(void)
10418 {
10419     int	    c;
10420     int	    cc;
10421     int	    did_putchar = FALSE;
10422 
10423     pc_status = PC_STATUS_UNSET;
10424     if (redrawing() && !char_avail())
10425     {
10426 	/* may need to redraw when no more chars available now */
10427 	ins_redraw(FALSE);
10428 
10429 	edit_putchar('?', TRUE);
10430 	did_putchar = TRUE;
10431 #ifdef FEAT_CMDL_INFO
10432 	add_to_showcmd_c(Ctrl_K);
10433 #endif
10434     }
10435 
10436 #ifdef USE_ON_FLY_SCROLL
10437     dont_scroll = TRUE;		/* disallow scrolling here */
10438 #endif
10439 
10440     /* don't map the digraph chars. This also prevents the
10441      * mode message to be deleted when ESC is hit */
10442     ++no_mapping;
10443     ++allow_keys;
10444     c = plain_vgetc();
10445     --no_mapping;
10446     --allow_keys;
10447     if (did_putchar)
10448 	/* when the line fits in 'columns' the '?' is at the start of the next
10449 	 * line and will not be removed by the redraw */
10450 	edit_unputchar();
10451 
10452     if (IS_SPECIAL(c) || mod_mask)	    /* special key */
10453     {
10454 #ifdef FEAT_CMDL_INFO
10455 	clear_showcmd();
10456 #endif
10457 	insert_special(c, TRUE, FALSE);
10458 	return NUL;
10459     }
10460     if (c != ESC)
10461     {
10462 	did_putchar = FALSE;
10463 	if (redrawing() && !char_avail())
10464 	{
10465 	    /* may need to redraw when no more chars available now */
10466 	    ins_redraw(FALSE);
10467 
10468 	    if (char2cells(c) == 1)
10469 	    {
10470 		ins_redraw(FALSE);
10471 		edit_putchar(c, TRUE);
10472 		did_putchar = TRUE;
10473 	    }
10474 #ifdef FEAT_CMDL_INFO
10475 	    add_to_showcmd_c(c);
10476 #endif
10477 	}
10478 	++no_mapping;
10479 	++allow_keys;
10480 	cc = plain_vgetc();
10481 	--no_mapping;
10482 	--allow_keys;
10483 	if (did_putchar)
10484 	    /* when the line fits in 'columns' the '?' is at the start of the
10485 	     * next line and will not be removed by a redraw */
10486 	    edit_unputchar();
10487 	if (cc != ESC)
10488 	{
10489 	    AppendToRedobuff((char_u *)CTRL_V_STR);
10490 	    c = getdigraph(c, cc, TRUE);
10491 #ifdef FEAT_CMDL_INFO
10492 	    clear_showcmd();
10493 #endif
10494 	    return c;
10495 	}
10496     }
10497 #ifdef FEAT_CMDL_INFO
10498     clear_showcmd();
10499 #endif
10500     return NUL;
10501 }
10502 #endif
10503 
10504 /*
10505  * Handle CTRL-E and CTRL-Y in Insert mode: copy char from other line.
10506  * Returns the char to be inserted, or NUL if none found.
10507  */
10508     int
10509 ins_copychar(linenr_T lnum)
10510 {
10511     int	    c;
10512     int	    temp;
10513     char_u  *ptr, *prev_ptr;
10514     char_u  *line;
10515 
10516     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)
10517     {
10518 	vim_beep(BO_COPY);
10519 	return NUL;
10520     }
10521 
10522     /* try to advance to the cursor column */
10523     temp = 0;
10524     line = ptr = ml_get(lnum);
10525     prev_ptr = ptr;
10526     validate_virtcol();
10527     while ((colnr_T)temp < curwin->w_virtcol && *ptr != NUL)
10528     {
10529 	prev_ptr = ptr;
10530 	temp += lbr_chartabsize_adv(line, &ptr, (colnr_T)temp);
10531     }
10532     if ((colnr_T)temp > curwin->w_virtcol)
10533 	ptr = prev_ptr;
10534 
10535 #ifdef FEAT_MBYTE
10536     c = (*mb_ptr2char)(ptr);
10537 #else
10538     c = *ptr;
10539 #endif
10540     if (c == NUL)
10541 	vim_beep(BO_COPY);
10542     return c;
10543 }
10544 
10545 /*
10546  * CTRL-Y or CTRL-E typed in Insert mode.
10547  */
10548     static int
10549 ins_ctrl_ey(int tc)
10550 {
10551     int	    c = tc;
10552 
10553 #ifdef FEAT_INS_EXPAND
10554     if (ctrl_x_mode == CTRL_X_SCROLL)
10555     {
10556 	if (c == Ctrl_Y)
10557 	    scrolldown_clamp();
10558 	else
10559 	    scrollup_clamp();
10560 	redraw_later(VALID);
10561     }
10562     else
10563 #endif
10564     {
10565 	c = ins_copychar(curwin->w_cursor.lnum + (c == Ctrl_Y ? -1 : 1));
10566 	if (c != NUL)
10567 	{
10568 	    long	tw_save;
10569 
10570 	    /* The character must be taken literally, insert like it
10571 	     * was typed after a CTRL-V, and pretend 'textwidth'
10572 	     * wasn't set.  Digits, 'o' and 'x' are special after a
10573 	     * CTRL-V, don't use it for these. */
10574 	    if (c < 256 && !isalnum(c))
10575 		AppendToRedobuff((char_u *)CTRL_V_STR);	/* CTRL-V */
10576 	    tw_save = curbuf->b_p_tw;
10577 	    curbuf->b_p_tw = -1;
10578 	    insert_special(c, TRUE, FALSE);
10579 	    curbuf->b_p_tw = tw_save;
10580 #ifdef FEAT_RIGHTLEFT
10581 	    revins_chars++;
10582 	    revins_legal++;
10583 #endif
10584 	    c = Ctrl_V;	/* pretend CTRL-V is last character */
10585 	    auto_format(FALSE, TRUE);
10586 	}
10587     }
10588     return c;
10589 }
10590 
10591 #ifdef FEAT_SMARTINDENT
10592 /*
10593  * Try to do some very smart auto-indenting.
10594  * Used when inserting a "normal" character.
10595  */
10596     static void
10597 ins_try_si(int c)
10598 {
10599     pos_T	*pos, old_pos;
10600     char_u	*ptr;
10601     int		i;
10602     int		temp;
10603 
10604     /*
10605      * do some very smart indenting when entering '{' or '}'
10606      */
10607     if (((did_si || can_si_back) && c == '{') || (can_si && c == '}'))
10608     {
10609 	/*
10610 	 * for '}' set indent equal to indent of line containing matching '{'
10611 	 */
10612 	if (c == '}' && (pos = findmatch(NULL, '{')) != NULL)
10613 	{
10614 	    old_pos = curwin->w_cursor;
10615 	    /*
10616 	     * If the matching '{' has a ')' immediately before it (ignoring
10617 	     * white-space), then line up with the start of the line
10618 	     * containing the matching '(' if there is one.  This handles the
10619 	     * case where an "if (..\n..) {" statement continues over multiple
10620 	     * lines -- webb
10621 	     */
10622 	    ptr = ml_get(pos->lnum);
10623 	    i = pos->col;
10624 	    if (i > 0)		/* skip blanks before '{' */
10625 		while (--i > 0 && VIM_ISWHITE(ptr[i]))
10626 		    ;
10627 	    curwin->w_cursor.lnum = pos->lnum;
10628 	    curwin->w_cursor.col = i;
10629 	    if (ptr[i] == ')' && (pos = findmatch(NULL, '(')) != NULL)
10630 		curwin->w_cursor = *pos;
10631 	    i = get_indent();
10632 	    curwin->w_cursor = old_pos;
10633 	    if (State & VREPLACE_FLAG)
10634 		change_indent(INDENT_SET, i, FALSE, NUL, TRUE);
10635 	    else
10636 		(void)set_indent(i, SIN_CHANGED);
10637 	}
10638 	else if (curwin->w_cursor.col > 0)
10639 	{
10640 	    /*
10641 	     * when inserting '{' after "O" reduce indent, but not
10642 	     * more than indent of previous line
10643 	     */
10644 	    temp = TRUE;
10645 	    if (c == '{' && can_si_back && curwin->w_cursor.lnum > 1)
10646 	    {
10647 		old_pos = curwin->w_cursor;
10648 		i = get_indent();
10649 		while (curwin->w_cursor.lnum > 1)
10650 		{
10651 		    ptr = skipwhite(ml_get(--(curwin->w_cursor.lnum)));
10652 
10653 		    /* ignore empty lines and lines starting with '#'. */
10654 		    if (*ptr != '#' && *ptr != NUL)
10655 			break;
10656 		}
10657 		if (get_indent() >= i)
10658 		    temp = FALSE;
10659 		curwin->w_cursor = old_pos;
10660 	    }
10661 	    if (temp)
10662 		shift_line(TRUE, FALSE, 1, TRUE);
10663 	}
10664     }
10665 
10666     /*
10667      * set indent of '#' always to 0
10668      */
10669     if (curwin->w_cursor.col > 0 && can_si && c == '#')
10670     {
10671 	/* remember current indent for next line */
10672 	old_indent = get_indent();
10673 	(void)set_indent(0, SIN_CHANGED);
10674     }
10675 
10676     /* Adjust ai_col, the char at this position can be deleted. */
10677     if (ai_col > curwin->w_cursor.col)
10678 	ai_col = curwin->w_cursor.col;
10679 }
10680 #endif
10681 
10682 /*
10683  * Get the value that w_virtcol would have when 'list' is off.
10684  * Unless 'cpo' contains the 'L' flag.
10685  */
10686     colnr_T
10687 get_nolist_virtcol(void)
10688 {
10689     // check validity of cursor in current buffer
10690     if (curwin->w_buffer == NULL
10691 	|| curwin->w_buffer->b_ml.ml_mfp == NULL
10692 	|| curwin->w_cursor.lnum > curwin->w_buffer->b_ml.ml_line_count)
10693 	return 0;
10694     if (curwin->w_p_list && vim_strchr(p_cpo, CPO_LISTWM) == NULL)
10695 	return getvcol_nolist(&curwin->w_cursor);
10696     validate_virtcol();
10697     return curwin->w_virtcol;
10698 }
10699 
10700 #if defined(FEAT_EVAL)
10701 /*
10702  * Handle the InsertCharPre autocommand.
10703  * "c" is the character that was typed.
10704  * Return a pointer to allocated memory with the replacement string.
10705  * Return NULL to continue inserting "c".
10706  */
10707     static char_u *
10708 do_insert_char_pre(int c)
10709 {
10710     char_u	*res;
10711     char_u	buf[MB_MAXBYTES + 1];
10712 
10713     /* Return quickly when there is nothing to do. */
10714     if (!has_insertcharpre())
10715 	return NULL;
10716 
10717 # ifdef FEAT_MBYTE
10718     if (has_mbyte)
10719 	buf[(*mb_char2bytes)(c, buf)] = NUL;
10720     else
10721 # endif
10722     {
10723 	buf[0] = c;
10724 	buf[1] = NUL;
10725     }
10726 
10727     /* Lock the text to avoid weird things from happening. */
10728     ++textlock;
10729     set_vim_var_string(VV_CHAR, buf, -1);  /* set v:char */
10730 
10731     res = NULL;
10732     if (ins_apply_autocmds(EVENT_INSERTCHARPRE))
10733     {
10734 	/* Get the value of v:char.  It may be empty or more than one
10735 	 * character.  Only use it when changed, otherwise continue with the
10736 	 * original character to avoid breaking autoindent. */
10737 	if (STRCMP(buf, get_vim_var_str(VV_CHAR)) != 0)
10738 	    res = vim_strsave(get_vim_var_str(VV_CHAR));
10739     }
10740 
10741     set_vim_var_string(VV_CHAR, NULL, -1);  /* clear v:char */
10742     --textlock;
10743 
10744     return res;
10745 }
10746 #endif
10747 
10748 /*
10749  * Trigger "event" and take care of fixing undo.
10750  */
10751     static int
10752 ins_apply_autocmds(event_T event)
10753 {
10754     varnumber_T	tick = CHANGEDTICK(curbuf);
10755     int r;
10756 
10757     r = apply_autocmds(event, NULL, NULL, FALSE, curbuf);
10758 
10759     // If u_savesub() was called then we are not prepared to start
10760     // a new line.  Call u_save() with no contents to fix that.
10761     if (tick != CHANGEDTICK(curbuf))
10762 	u_save(curwin->w_cursor.lnum, (linenr_T)(curwin->w_cursor.lnum + 1));
10763 
10764     return r;
10765 }
10766