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