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