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