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