/* vi:set ts=8 sts=4 sw=4:
 *
 * VIM - Vi IMproved	by Bram Moolenaar
 *
 * Do ":help uganda"  in Vim to read copying and usage conditions.
 * Do ":help credits" in Vim to see a list of people who contributed.
 * See README.txt for an overview of the Vim source code.
 */

/*
 * getchar.c
 *
 * functions related with getting a character from the user/mapping/redo/...
 *
 * manipulations with redo buffer and stuff buffer
 * mappings and abbreviations
 */

#include "vim.h"

/*
 * These buffers are used for storing:
 * - stuffed characters: A command that is translated into another command.
 * - redo characters: will redo the last change.
 * - recorded chracters: for the "q" command.
 *
 * The bytes are stored like in the typeahead buffer:
 * - K_SPECIAL introduces a special key (two more bytes follow).  A literal
 *   K_SPECIAL is stored as K_SPECIAL KS_SPECIAL KE_FILLER.
 * - CSI introduces a GUI termcap code (also when gui.in_use is FALSE,
 *   otherwise switching the GUI on would make mappings invalid).
 *   A literal CSI is stored as CSI KS_EXTRA KE_CSI.
 * These translations are also done on multi-byte characters!
 *
 * Escaping CSI bytes is done by the system-specific input functions, called
 * by ui_inchar().
 * Escaping K_SPECIAL is done by inchar().
 * Un-escaping is done by vgetc().
 */

#define MINIMAL_SIZE 20			/* minimal size for b_str */

static struct buffheader redobuff = {{NULL, {NUL}}, NULL, 0, 0};
static struct buffheader old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
#if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO)
static struct buffheader save_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
static struct buffheader save_old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
#endif
static struct buffheader recordbuff = {{NULL, {NUL}}, NULL, 0, 0};

static int typeahead_char = 0;		/* typeahead char that's not flushed */

/*
 * when block_redo is TRUE redo buffer will not be changed
 * used by edit() to repeat insertions and 'V' command for redoing
 */
static int	block_redo = FALSE;

/*
 * Make a hash value for a mapping.
 * "mode" is the lower 4 bits of the State for the mapping.
 * "c1" is the first character of the "lhs".
 * Returns a value between 0 and 255, index in maphash.
 * Put Normal/Visual mode mappings mostly separately from Insert/Cmdline mode.
 */
#define MAP_HASH(mode, c1) (((mode) & (NORMAL + VISUAL + SELECTMODE + OP_PENDING)) ? (c1) : ((c1) ^ 0x80))

/*
 * Each mapping is put in one of the 256 hash lists, to speed up finding it.
 */
static mapblock_T	*(maphash[256]);
static int		maphash_valid = FALSE;

/*
 * List used for abbreviations.
 */
static mapblock_T	*first_abbr = NULL; /* first entry in abbrlist */

static int		KeyNoremap = 0;	    /* remapping flags */

/*
 * variables used by vgetorpeek() and flush_buffers()
 *
 * typebuf.tb_buf[] contains all characters that are not consumed yet.
 * typebuf.tb_buf[typebuf.tb_off] is the first valid character.
 * typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len - 1] is the last valid char.
 * typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len] must be NUL.
 * The head of the buffer may contain the result of mappings, abbreviations
 * and @a commands.  The length of this part is typebuf.tb_maplen.
 * typebuf.tb_silent is the part where <silent> applies.
 * After the head are characters that come from the terminal.
 * typebuf.tb_no_abbr_cnt is the number of characters in typebuf.tb_buf that
 * should not be considered for abbreviations.
 * Some parts of typebuf.tb_buf may not be mapped. These parts are remembered
 * in typebuf.tb_noremap[], which is the same length as typebuf.tb_buf and
 * contains RM_NONE for the characters that are not to be remapped.
 * typebuf.tb_noremap[typebuf.tb_off] is the first valid flag.
 * (typebuf has been put in globals.h, because check_termcode() needs it).
 */
#define RM_YES		0	/* tb_noremap: remap */
#define RM_NONE		1	/* tb_noremap: don't remap */
#define RM_SCRIPT	2	/* tb_noremap: remap local script mappings */
#define RM_ABBR		4	/* tb_noremap: don't remap, do abbrev. */

/* typebuf.tb_buf has three parts: room in front (for result of mappings), the
 * middle for typeahead and room for new characters (which needs to be 3 *
 * MAXMAPLEN) for the Amiga).
 */
#define TYPELEN_INIT	(5 * (MAXMAPLEN + 3))
static char_u	typebuf_init[TYPELEN_INIT];	/* initial typebuf.tb_buf */
static char_u	noremapbuf_init[TYPELEN_INIT];	/* initial typebuf.tb_noremap */

static int	last_recorded_len = 0;	/* number of last recorded chars */

static char_u	*get_buffcont __ARGS((struct buffheader *, int));
static void	add_buff __ARGS((struct buffheader *, char_u *, long n));
static void	add_num_buff __ARGS((struct buffheader *, long));
static void	add_char_buff __ARGS((struct buffheader *, int));
static int	read_stuff __ARGS((int advance));
static void	start_stuff __ARGS((void));
static int	read_redo __ARGS((int, int));
static void	copy_redo __ARGS((int));
static void	init_typebuf __ARGS((void));
static void	gotchars __ARGS((char_u *, int));
static void	may_sync_undo __ARGS((void));
static void	closescript __ARGS((void));
static int	vgetorpeek __ARGS((int));
static void	map_free __ARGS((mapblock_T **));
static void	validate_maphash __ARGS((void));
static void	showmap __ARGS((mapblock_T *mp, int local));
#ifdef FEAT_EVAL
static char_u	*eval_map_expr __ARGS((char_u *str));
#endif

/*
 * Free and clear a buffer.
 */
    void
free_buff(buf)
    struct buffheader	*buf;
{
    struct buffblock	*p, *np;

    for (p = buf->bh_first.b_next; p != NULL; p = np)
    {
	np = p->b_next;
	vim_free(p);
    }
    buf->bh_first.b_next = NULL;
}

/*
 * Return the contents of a buffer as a single string.
 * K_SPECIAL and CSI in the returned string are escaped.
 */
    static char_u *
get_buffcont(buffer, dozero)
    struct buffheader	*buffer;
    int			dozero;	    /* count == zero is not an error */
{
    long_u	    count = 0;
    char_u	    *p = NULL;
    char_u	    *p2;
    char_u	    *str;
    struct buffblock *bp;

    /* compute the total length of the string */
    for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
	count += (long_u)STRLEN(bp->b_str);

    if ((count || dozero) && (p = lalloc(count + 1, TRUE)) != NULL)
    {
	p2 = p;
	for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
	    for (str = bp->b_str; *str; )
		*p2++ = *str++;
	*p2 = NUL;
    }
    return (p);
}

/*
 * Return the contents of the record buffer as a single string
 * and clear the record buffer.
 * K_SPECIAL and CSI in the returned string are escaped.
 */
    char_u *
get_recorded()
{
    char_u	*p;
    size_t	len;

    p = get_buffcont(&recordbuff, TRUE);
    free_buff(&recordbuff);

    /*
     * Remove the characters that were added the last time, these must be the
     * (possibly mapped) characters that stopped the recording.
     */
    len = STRLEN(p);
    if ((int)len >= last_recorded_len)
    {
	len -= last_recorded_len;
	p[len] = NUL;
    }

    /*
     * When stopping recording from Insert mode with CTRL-O q, also remove the
     * CTRL-O.
     */
    if (len > 0 && restart_edit != 0 && p[len - 1] == Ctrl_O)
	p[len - 1] = NUL;

    return (p);
}

/*
 * Return the contents of the redo buffer as a single string.
 * K_SPECIAL and CSI in the returned string are escaped.
 */
    char_u *
get_inserted()
{
    return(get_buffcont(&redobuff, FALSE));
}

/*
 * add string "s" after the current block of buffer "buf"
 * K_SPECIAL and CSI should have been escaped already.
 */
    static void
add_buff(buf, s, slen)
    struct buffheader	*buf;
    char_u		*s;
    long		slen;	/* length of "s" or -1 */
{
    struct buffblock *p;
    long_u	    len;

    if (slen < 0)
	slen = (long)STRLEN(s);
    if (slen == 0)				/* don't add empty strings */
	return;

    if (buf->bh_first.b_next == NULL)	/* first add to list */
    {
	buf->bh_space = 0;
	buf->bh_curr = &(buf->bh_first);
    }
    else if (buf->bh_curr == NULL)	/* buffer has already been read */
    {
	EMSG(_("E222: Add to read buffer"));
	return;
    }
    else if (buf->bh_index != 0)
	STRCPY(buf->bh_first.b_next->b_str,
				 buf->bh_first.b_next->b_str + buf->bh_index);
    buf->bh_index = 0;

    if (buf->bh_space >= (int)slen)
    {
	len = (long_u)STRLEN(buf->bh_curr->b_str);
	vim_strncpy(buf->bh_curr->b_str + len, s, (size_t)slen);
	buf->bh_space -= slen;
    }
    else
    {
	if (slen < MINIMAL_SIZE)
	    len = MINIMAL_SIZE;
	else
	    len = slen;
	p = (struct buffblock *)lalloc((long_u)(sizeof(struct buffblock) + len),
									TRUE);
	if (p == NULL)
	    return; /* no space, just forget it */
	buf->bh_space = (int)(len - slen);
	vim_strncpy(p->b_str, s, (size_t)slen);

	p->b_next = buf->bh_curr->b_next;
	buf->bh_curr->b_next = p;
	buf->bh_curr = p;
    }
    return;
}

/*
 * Add number "n" to buffer "buf".
 */
    static void
add_num_buff(buf, n)
    struct buffheader *buf;
    long	      n;
{
    char_u	number[32];

    sprintf((char *)number, "%ld", n);
    add_buff(buf, number, -1L);
}

/*
 * Add character 'c' to buffer "buf".
 * Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters.
 */
    static void
add_char_buff(buf, c)
    struct buffheader	*buf;
    int			c;
{
#ifdef FEAT_MBYTE
    char_u	bytes[MB_MAXBYTES + 1];
    int		len;
    int		i;
#endif
    char_u	temp[4];

#ifdef FEAT_MBYTE
    if (IS_SPECIAL(c))
	len = 1;
    else
	len = (*mb_char2bytes)(c, bytes);
    for (i = 0; i < len; ++i)
    {
	if (!IS_SPECIAL(c))
	    c = bytes[i];
#endif

	if (IS_SPECIAL(c) || c == K_SPECIAL || c == NUL)
	{
	    /* translate special key code into three byte sequence */
	    temp[0] = K_SPECIAL;
	    temp[1] = K_SECOND(c);
	    temp[2] = K_THIRD(c);
	    temp[3] = NUL;
	}
#ifdef FEAT_GUI
	else if (c == CSI)
	{
	    /* Translate a CSI to a CSI - KS_EXTRA - KE_CSI sequence */
	    temp[0] = CSI;
	    temp[1] = KS_EXTRA;
	    temp[2] = (int)KE_CSI;
	    temp[3] = NUL;
	}
#endif
	else
	{
	    temp[0] = c;
	    temp[1] = NUL;
	}
	add_buff(buf, temp, -1L);
#ifdef FEAT_MBYTE
    }
#endif
}

/*
 * Get one byte from the stuff buffer.
 * If advance == TRUE go to the next char.
 * No translation is done K_SPECIAL and CSI are escaped.
 */
    static int
read_stuff(advance)
    int		advance;
{
    char_u		c;
    struct buffblock	*curr;

    if (stuffbuff.bh_first.b_next == NULL)  /* buffer is empty */
	return NUL;

    curr = stuffbuff.bh_first.b_next;
    c = curr->b_str[stuffbuff.bh_index];

    if (advance)
    {
	if (curr->b_str[++stuffbuff.bh_index] == NUL)
	{
	    stuffbuff.bh_first.b_next = curr->b_next;
	    vim_free(curr);
	    stuffbuff.bh_index = 0;
	}
    }
    return c;
}

/*
 * Prepare the stuff buffer for reading (if it contains something).
 */
    static void
start_stuff()
{
    if (stuffbuff.bh_first.b_next != NULL)
    {
	stuffbuff.bh_curr = &(stuffbuff.bh_first);
	stuffbuff.bh_space = 0;
    }
}

/*
 * Return TRUE if the stuff buffer is empty.
 */
    int
stuff_empty()
{
    return (stuffbuff.bh_first.b_next == NULL);
}

/*
 * Set a typeahead character that won't be flushed.
 */
    void
typeahead_noflush(c)
    int		c;
{
    typeahead_char = c;
}

/*
 * Remove the contents of the stuff buffer and the mapped characters in the
 * typeahead buffer (used in case of an error).  If 'typeahead' is true,
 * flush all typeahead characters (used when interrupted by a CTRL-C).
 */
    void
flush_buffers(typeahead)
    int typeahead;
{
    init_typebuf();

    start_stuff();
    while (read_stuff(TRUE) != NUL)
	;

    if (typeahead)	    /* remove all typeahead */
    {
	/*
	 * We have to get all characters, because we may delete the first part
	 * of an escape sequence.
	 * In an xterm we get one char at a time and we have to get them all.
	 */
	while (inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 10L,
						  typebuf.tb_change_cnt) != 0)
	    ;
	typebuf.tb_off = MAXMAPLEN;
	typebuf.tb_len = 0;
    }
    else		    /* remove mapped characters only */
    {
	typebuf.tb_off += typebuf.tb_maplen;
	typebuf.tb_len -= typebuf.tb_maplen;
    }
    typebuf.tb_maplen = 0;
    typebuf.tb_silent = 0;
    cmd_silent = FALSE;
    typebuf.tb_no_abbr_cnt = 0;
}

/*
 * The previous contents of the redo buffer is kept in old_redobuffer.
 * This is used for the CTRL-O <.> command in insert mode.
 */
    void
ResetRedobuff()
{
    if (!block_redo)
    {
	free_buff(&old_redobuff);
	old_redobuff = redobuff;
	redobuff.bh_first.b_next = NULL;
    }
}

#if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO)
/*
 * Save redobuff and old_redobuff to save_redobuff and save_old_redobuff.
 * Used before executing autocommands and user functions.
 */
static int save_level = 0;

    void
saveRedobuff()
{
    char_u	*s;

    if (save_level++ == 0)
    {
	save_redobuff = redobuff;
	redobuff.bh_first.b_next = NULL;
	save_old_redobuff = old_redobuff;
	old_redobuff.bh_first.b_next = NULL;

	/* Make a copy, so that ":normal ." in a function works. */
	s = get_buffcont(&save_redobuff, FALSE);
	if (s != NULL)
	{
	    add_buff(&redobuff, s, -1L);
	    vim_free(s);
	}
    }
}

/*
 * Restore redobuff and old_redobuff from save_redobuff and save_old_redobuff.
 * Used after executing autocommands and user functions.
 */
    void
restoreRedobuff()
{
    if (--save_level == 0)
    {
	free_buff(&redobuff);
	redobuff = save_redobuff;
	free_buff(&old_redobuff);
	old_redobuff = save_old_redobuff;
    }
}
#endif

/*
 * Append "s" to the redo buffer.
 * K_SPECIAL and CSI should already have been escaped.
 */
    void
AppendToRedobuff(s)
    char_u	   *s;
{
    if (!block_redo)
	add_buff(&redobuff, s, -1L);
}

/*
 * Append to Redo buffer literally, escaping special characters with CTRL-V.
 * K_SPECIAL and CSI are escaped as well.
 */
    void
AppendToRedobuffLit(str, len)
    char_u	*str;
    int		len;	    /* length of "str" or -1 for up to the NUL */
{
    char_u	*s = str;
    int		c;
    char_u	*start;

    if (block_redo)
	return;

    while (len < 0 ? *s != NUL : s - str < len)
    {
	/* Put a string of normal characters in the redo buffer (that's
	 * faster). */
	start = s;
	while (*s >= ' '
#ifndef EBCDIC
		&& *s < DEL	/* EBCDIC: all chars above space are normal */
#endif
		&& (len < 0 || s - str < len))
	    ++s;

	/* Don't put '0' or '^' as last character, just in case a CTRL-D is
	 * typed next. */
	if (*s == NUL && (s[-1] == '0' || s[-1] == '^'))
	    --s;
	if (s > start)
	    add_buff(&redobuff, start, (long)(s - start));

	if (*s == NUL || (len >= 0 && s - str >= len))
	    break;

	/* Handle a special or multibyte character. */
#ifdef FEAT_MBYTE
	if (has_mbyte)
	    /* Handle composing chars separately. */
	    c = mb_cptr2char_adv(&s);
	else
#endif
	    c = *s++;
	if (c < ' ' || c == DEL || (*s == NUL && (c == '0' || c == '^')))
	    add_char_buff(&redobuff, Ctrl_V);

	/* CTRL-V '0' must be inserted as CTRL-V 048 (EBCDIC: xf0) */
	if (*s == NUL && c == '0')
#ifdef EBCDIC
	    add_buff(&redobuff, (char_u *)"xf0", 3L);
#else
	    add_buff(&redobuff, (char_u *)"048", 3L);
#endif
	else
	    add_char_buff(&redobuff, c);
    }
}

/*
 * Append a character to the redo buffer.
 * Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters.
 */
    void
AppendCharToRedobuff(c)
    int		   c;
{
    if (!block_redo)
	add_char_buff(&redobuff, c);
}

/*
 * Append a number to the redo buffer.
 */
    void
AppendNumberToRedobuff(n)
    long	    n;
{
    if (!block_redo)
	add_num_buff(&redobuff, n);
}

/*
 * Append string "s" to the stuff buffer.
 * CSI and K_SPECIAL must already have been escaped.
 */
    void
stuffReadbuff(s)
    char_u	*s;
{
    add_buff(&stuffbuff, s, -1L);
}

    void
stuffReadbuffLen(s, len)
    char_u	*s;
    long	len;
{
    add_buff(&stuffbuff, s, len);
}

#if defined(FEAT_EVAL) || defined(PROTO)
/*
 * Stuff "s" into the stuff buffer, leaving special key codes unmodified and
 * escaping other K_SPECIAL and CSI bytes.
 */
    void
stuffReadbuffSpec(s)
    char_u	*s;
{
    while (*s != NUL)
    {
	if (*s == K_SPECIAL && s[1] != NUL && s[2] != NUL)
	{
	    /* Insert special key literally. */
	    stuffReadbuffLen(s, 3L);
	    s += 3;
	}
	else
#ifdef FEAT_MBYTE
	    stuffcharReadbuff(mb_ptr2char_adv(&s));
#else
	    stuffcharReadbuff(*s++);
#endif
    }
}
#endif

/*
 * Append a character to the stuff buffer.
 * Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters.
 */
    void
stuffcharReadbuff(c)
    int		   c;
{
    add_char_buff(&stuffbuff, c);
}

/*
 * Append a number to the stuff buffer.
 */
    void
stuffnumReadbuff(n)
    long    n;
{
    add_num_buff(&stuffbuff, n);
}

/*
 * Read a character from the redo buffer.  Translates K_SPECIAL, CSI and
 * multibyte characters.
 * The redo buffer is left as it is.
 * if init is TRUE, prepare for redo, return FAIL if nothing to redo, OK
 * otherwise
 * if old is TRUE, use old_redobuff instead of redobuff
 */
    static int
read_redo(init, old_redo)
    int		init;
    int		old_redo;
{
    static struct buffblock	*bp;
    static char_u		*p;
    int				c;
#ifdef FEAT_MBYTE
    int				n;
    char_u			buf[MB_MAXBYTES];
    int				i;
#endif

    if (init)
    {
	if (old_redo)
	    bp = old_redobuff.bh_first.b_next;
	else
	    bp = redobuff.bh_first.b_next;
	if (bp == NULL)
	    return FAIL;
	p = bp->b_str;
	return OK;
    }
    if ((c = *p) != NUL)
    {
	/* Reverse the conversion done by add_char_buff() */
#ifdef FEAT_MBYTE
	/* For a multi-byte character get all the bytes and return the
	 * converted character. */
	if (has_mbyte && (c != K_SPECIAL || p[1] == KS_SPECIAL))
	    n = MB_BYTE2LEN_CHECK(c);
	else
	    n = 1;
	for (i = 0; ; ++i)
#endif
	{
	    if (c == K_SPECIAL) /* special key or escaped K_SPECIAL */
	    {
		c = TO_SPECIAL(p[1], p[2]);
		p += 2;
	    }
#ifdef FEAT_GUI
	    if (c == CSI)	/* escaped CSI */
		p += 2;
#endif
	    if (*++p == NUL && bp->b_next != NULL)
	    {
		bp = bp->b_next;
		p = bp->b_str;
	    }
#ifdef FEAT_MBYTE
	    buf[i] = c;
	    if (i == n - 1)	/* last byte of a character */
	    {
		if (n != 1)
		    c = (*mb_ptr2char)(buf);
		break;
	    }
	    c = *p;
	    if (c == NUL)	/* cannot happen? */
		break;
#endif
	}
    }

    return c;
}

/*
 * Copy the rest of the redo buffer into the stuff buffer (in a slow way).
 * If old_redo is TRUE, use old_redobuff instead of redobuff.
 * The escaped K_SPECIAL and CSI are copied without translation.
 */
    static void
copy_redo(old_redo)
    int	    old_redo;
{
    int	    c;

    while ((c = read_redo(FALSE, old_redo)) != NUL)
	stuffcharReadbuff(c);
}

/*
 * Stuff the redo buffer into the stuffbuff.
 * Insert the redo count into the command.
 * If "old_redo" is TRUE, the last but one command is repeated
 * instead of the last command (inserting text). This is used for
 * CTRL-O <.> in insert mode
 *
 * return FAIL for failure, OK otherwise
 */
    int
start_redo(count, old_redo)
    long    count;
    int	    old_redo;
{
    int	    c;

    /* init the pointers; return if nothing to redo */
    if (read_redo(TRUE, old_redo) == FAIL)
	return FAIL;

    c = read_redo(FALSE, old_redo);

    /* copy the buffer name, if present */
    if (c == '"')
    {
	add_buff(&stuffbuff, (char_u *)"\"", 1L);
	c = read_redo(FALSE, old_redo);

	/* if a numbered buffer is used, increment the number */
	if (c >= '1' && c < '9')
	    ++c;
	add_char_buff(&stuffbuff, c);
	c = read_redo(FALSE, old_redo);
    }

#ifdef FEAT_VISUAL
    if (c == 'v')   /* redo Visual */
    {
	VIsual = curwin->w_cursor;
	VIsual_active = TRUE;
	VIsual_select = FALSE;
	VIsual_reselect = TRUE;
	redo_VIsual_busy = TRUE;
	c = read_redo(FALSE, old_redo);
    }
#endif

    /* try to enter the count (in place of a previous count) */
    if (count)
    {
	while (VIM_ISDIGIT(c))	/* skip "old" count */
	    c = read_redo(FALSE, old_redo);
	add_num_buff(&stuffbuff, count);
    }

    /* copy from the redo buffer into the stuff buffer */
    add_char_buff(&stuffbuff, c);
    copy_redo(old_redo);
    return OK;
}

/*
 * Repeat the last insert (R, o, O, a, A, i or I command) by stuffing
 * the redo buffer into the stuffbuff.
 * return FAIL for failure, OK otherwise
 */
    int
start_redo_ins()
{
    int	    c;

    if (read_redo(TRUE, FALSE) == FAIL)
	return FAIL;
    start_stuff();

    /* skip the count and the command character */
    while ((c = read_redo(FALSE, FALSE)) != NUL)
    {
	if (vim_strchr((char_u *)"AaIiRrOo", c) != NULL)
	{
	    if (c == 'O' || c == 'o')
		stuffReadbuff(NL_STR);
	    break;
	}
    }

    /* copy the typed text from the redo buffer into the stuff buffer */
    copy_redo(FALSE);
    block_redo = TRUE;
    return OK;
}

    void
stop_redo_ins()
{
    block_redo = FALSE;
}

/*
 * Initialize typebuf.tb_buf to point to typebuf_init.
 * alloc() cannot be used here: In out-of-memory situations it would
 * be impossible to type anything.
 */
    static void
init_typebuf()
{
    if (typebuf.tb_buf == NULL)
    {
	typebuf.tb_buf = typebuf_init;
	typebuf.tb_noremap = noremapbuf_init;
	typebuf.tb_buflen = TYPELEN_INIT;
	typebuf.tb_len = 0;
	typebuf.tb_off = 0;
	typebuf.tb_change_cnt = 1;
    }
}

/*
 * insert a string in position 'offset' in the typeahead buffer (for "@r"
 * and ":normal" command, vgetorpeek() and check_termcode())
 *
 * If noremap is REMAP_YES, new string can be mapped again.
 * If noremap is REMAP_NONE, new string cannot be mapped again.
 * If noremap is REMAP_SKIP, fist char of new string cannot be mapped again,
 * but abbreviations are allowed.
 * If noremap is REMAP_SCRIPT, new string cannot be mapped again, except for
 *			script-local mappings.
 * If noremap is > 0, that many characters of the new string cannot be mapped.
 *
 * If nottyped is TRUE, the string does not return KeyTyped (don't use when
 * offset is non-zero!).
 *
 * If silent is TRUE, cmd_silent is set when the characters are obtained.
 *
 * return FAIL for failure, OK otherwise
 */
    int
ins_typebuf(str, noremap, offset, nottyped, silent)
    char_u	*str;
    int		noremap;
    int		offset;
    int		nottyped;
    int		silent;
{
    char_u	*s1, *s2;
    int		newlen;
    int		addlen;
    int		i;
    int		newoff;
    int		val;
    int		nrm;

    init_typebuf();
    if (++typebuf.tb_change_cnt == 0)
	typebuf.tb_change_cnt = 1;

    addlen = (int)STRLEN(str);
    /*
     * Easy case: there is room in front of typebuf.tb_buf[typebuf.tb_off]
     */
    if (offset == 0 && addlen <= typebuf.tb_off)
    {
	typebuf.tb_off -= addlen;
	mch_memmove(typebuf.tb_buf + typebuf.tb_off, str, (size_t)addlen);
    }
    /*
     * Need to allocate new buffer.
     * In typebuf.tb_buf there must always be room for 3 * MAXMAPLEN + 4
     * characters.  We add some extra room to avoid having to allocate too
     * often.
     */
    else
    {
	newoff = MAXMAPLEN + 4;
	newlen = typebuf.tb_len + addlen + newoff + 4 * (MAXMAPLEN + 4);
	if (newlen < 0)		    /* string is getting too long */
	{
	    EMSG(_(e_toocompl));    /* also calls flush_buffers */
	    setcursor();
	    return FAIL;
	}
	s1 = alloc(newlen);
	if (s1 == NULL)		    /* out of memory */
	    return FAIL;
	s2 = alloc(newlen);
	if (s2 == NULL)		    /* out of memory */
	{
	    vim_free(s1);
	    return FAIL;
	}
	typebuf.tb_buflen = newlen;

	/* copy the old chars, before the insertion point */
	mch_memmove(s1 + newoff, typebuf.tb_buf + typebuf.tb_off,
							      (size_t)offset);
	/* copy the new chars */
	mch_memmove(s1 + newoff + offset, str, (size_t)addlen);
	/* copy the old chars, after the insertion point, including the	NUL at
	 * the end */
	mch_memmove(s1 + newoff + offset + addlen,
				     typebuf.tb_buf + typebuf.tb_off + offset,
				       (size_t)(typebuf.tb_len - offset + 1));
	if (typebuf.tb_buf != typebuf_init)
	    vim_free(typebuf.tb_buf);
	typebuf.tb_buf = s1;

	mch_memmove(s2 + newoff, typebuf.tb_noremap + typebuf.tb_off,
							      (size_t)offset);
	mch_memmove(s2 + newoff + offset + addlen,
		   typebuf.tb_noremap + typebuf.tb_off + offset,
					   (size_t)(typebuf.tb_len - offset));
	if (typebuf.tb_noremap != noremapbuf_init)
	    vim_free(typebuf.tb_noremap);
	typebuf.tb_noremap = s2;

	typebuf.tb_off = newoff;
    }
    typebuf.tb_len += addlen;

    /* If noremap == REMAP_SCRIPT: do remap script-local mappings. */
    if (noremap == REMAP_SCRIPT)
	val = RM_SCRIPT;
    else if (noremap == REMAP_SKIP)
	val = RM_ABBR;
    else
	val = RM_NONE;

    /*
     * Adjust typebuf.tb_noremap[] for the new characters:
     * If noremap == REMAP_NONE or REMAP_SCRIPT: new characters are
     *			(sometimes) not remappable
     * If noremap == REMAP_YES: all the new characters are mappable
     * If noremap  > 0: "noremap" characters are not remappable, the rest
     *			mappable
     */
    if (noremap == REMAP_SKIP)
	nrm = 1;
    else if (noremap < 0)
	nrm = addlen;
    else
	nrm = noremap;
    for (i = 0; i < addlen; ++i)
	typebuf.tb_noremap[typebuf.tb_off + i + offset] =
						  (--nrm >= 0) ? val : RM_YES;

    /* tb_maplen and tb_silent only remember the length of mapped and/or
     * silent mappings at the start of the buffer, assuming that a mapped
     * sequence doesn't result in typed characters. */
    if (nottyped || typebuf.tb_maplen > offset)
	typebuf.tb_maplen += addlen;
    if (silent || typebuf.tb_silent > offset)
    {
	typebuf.tb_silent += addlen;
	cmd_silent = TRUE;
    }
    if (typebuf.tb_no_abbr_cnt && offset == 0)	/* and not used for abbrev.s */
	typebuf.tb_no_abbr_cnt += addlen;

    return OK;
}

/*
 * Put character "c" back into the typeahead buffer.
 * Can be used for a character obtained by vgetc() that needs to be put back.
 * Uses cmd_silent, KeyTyped and KeyNoremap to restore the flags belonging to
 * the char.
 */
    void
ins_char_typebuf(c)
    int	    c;
{
#ifdef FEAT_MBYTE
    char_u	buf[MB_MAXBYTES];
#else
    char_u	buf[4];
#endif
    if (IS_SPECIAL(c))
    {
	buf[0] = K_SPECIAL;
	buf[1] = K_SECOND(c);
	buf[2] = K_THIRD(c);
	buf[3] = NUL;
    }
    else
    {
#ifdef FEAT_MBYTE
	buf[(*mb_char2bytes)(c, buf)] = NUL;
#else
	buf[0] = c;
	buf[1] = NUL;
#endif
    }
    (void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
}

/*
 * Return TRUE if the typeahead buffer was changed (while waiting for a
 * character to arrive).  Happens when a message was received from a client or
 * from feedkeys().
 * But check in a more generic way to avoid trouble: When "typebuf.tb_buf"
 * changed it was reallocated and the old pointer can no longer be used.
 * Or "typebuf.tb_off" may have been changed and we would overwrite characters
 * that was just added.
 */
    int
typebuf_changed(tb_change_cnt)
    int		tb_change_cnt;	/* old value of typebuf.tb_change_cnt */
{
    return (tb_change_cnt != 0 && (typebuf.tb_change_cnt != tb_change_cnt
#if defined(FEAT_CLIENTSERVER) || defined(FEAT_EVAL)
	    || typebuf_was_filled
#endif
	   ));
}

/*
 * Return TRUE if there are no characters in the typeahead buffer that have
 * not been typed (result from a mapping or come from ":normal").
 */
    int
typebuf_typed()
{
    return typebuf.tb_maplen == 0;
}

#if defined(FEAT_VISUAL) || defined(PROTO)
/*
 * Return the number of characters that are mapped (or not typed).
 */
    int
typebuf_maplen()
{
    return typebuf.tb_maplen;
}
#endif

/*
 * remove "len" characters from typebuf.tb_buf[typebuf.tb_off + offset]
 */
    void
del_typebuf(len, offset)
    int	len;
    int	offset;
{
    int	    i;

    if (len == 0)
	return;		/* nothing to do */

    typebuf.tb_len -= len;

    /*
     * Easy case: Just increase typebuf.tb_off.
     */
    if (offset == 0 && typebuf.tb_buflen - (typebuf.tb_off + len)
							 >= 3 * MAXMAPLEN + 3)
	typebuf.tb_off += len;
    /*
     * Have to move the characters in typebuf.tb_buf[] and typebuf.tb_noremap[]
     */
    else
    {
	i = typebuf.tb_off + offset;
	/*
	 * Leave some extra room at the end to avoid reallocation.
	 */
	if (typebuf.tb_off > MAXMAPLEN)
	{
	    mch_memmove(typebuf.tb_buf + MAXMAPLEN,
			     typebuf.tb_buf + typebuf.tb_off, (size_t)offset);
	    mch_memmove(typebuf.tb_noremap + MAXMAPLEN,
			 typebuf.tb_noremap + typebuf.tb_off, (size_t)offset);
	    typebuf.tb_off = MAXMAPLEN;
	}
	/* adjust typebuf.tb_buf (include the NUL at the end) */
	mch_memmove(typebuf.tb_buf + typebuf.tb_off + offset,
						     typebuf.tb_buf + i + len,
				       (size_t)(typebuf.tb_len - offset + 1));
	/* adjust typebuf.tb_noremap[] */
	mch_memmove(typebuf.tb_noremap + typebuf.tb_off + offset,
						 typebuf.tb_noremap + i + len,
					   (size_t)(typebuf.tb_len - offset));
    }

    if (typebuf.tb_maplen > offset)		/* adjust tb_maplen */
    {
	if (typebuf.tb_maplen < offset + len)
	    typebuf.tb_maplen = offset;
	else
	    typebuf.tb_maplen -= len;
    }
    if (typebuf.tb_silent > offset)		/* adjust tb_silent */
    {
	if (typebuf.tb_silent < offset + len)
	    typebuf.tb_silent = offset;
	else
	    typebuf.tb_silent -= len;
    }
    if (typebuf.tb_no_abbr_cnt > offset)	/* adjust tb_no_abbr_cnt */
    {
	if (typebuf.tb_no_abbr_cnt < offset + len)
	    typebuf.tb_no_abbr_cnt = offset;
	else
	    typebuf.tb_no_abbr_cnt -= len;
    }

#if defined(FEAT_CLIENTSERVER) || defined(FEAT_EVAL)
    /* Reset the flag that text received from a client or from feedkeys()
     * was inserted in the typeahead buffer. */
    typebuf_was_filled = FALSE;
#endif
    if (++typebuf.tb_change_cnt == 0)
	typebuf.tb_change_cnt = 1;
}

/*
 * Write typed characters to script file.
 * If recording is on put the character in the recordbuffer.
 */
    static void
gotchars(s, len)
    char_u	*s;
    int		len;
{
    int		c;
    char_u	buf[2];

    /* remember how many chars were last recorded */
    if (Recording)
	last_recorded_len += len;

    buf[1] = NUL;
    while (len--)
    {
	/* Handle one byte at a time; no translation to be done. */
	c = *s++;
	updatescript(c);

	if (Recording)
	{
	    buf[0] = c;
	    add_buff(&recordbuff, buf, 1L);
	}
    }
    may_sync_undo();

#ifdef FEAT_EVAL
    /* output "debug mode" message next time in debug mode */
    debug_did_msg = FALSE;
#endif

    /* Since characters have been typed, consider the following to be in
     * another mapping.  Search string will be kept in history. */
    ++maptick;
}

/*
 * Sync undo.  Called when typed characters are obtained from the typeahead
 * buffer, or when a menu is used.
 * Do not sync:
 * - In Insert mode, unless cursor key has been used.
 * - While reading a script file.
 * - When no_u_sync is non-zero.
 */
    static void
may_sync_undo()
{
    if ((!(State & (INSERT + CMDLINE)) || arrow_used)
					       && scriptin[curscript] == NULL)
	u_sync(FALSE);
}

/*
 * Make "typebuf" empty and allocate new buffers.
 * Returns FAIL when out of memory.
 */
    int
alloc_typebuf()
{
    typebuf.tb_buf = alloc(TYPELEN_INIT);
    typebuf.tb_noremap = alloc(TYPELEN_INIT);
    if (typebuf.tb_buf == NULL || typebuf.tb_noremap == NULL)
    {
	free_typebuf();
	return FAIL;
    }
    typebuf.tb_buflen = TYPELEN_INIT;
    typebuf.tb_off = 0;
    typebuf.tb_len = 0;
    typebuf.tb_maplen = 0;
    typebuf.tb_silent = 0;
    typebuf.tb_no_abbr_cnt = 0;
    if (++typebuf.tb_change_cnt == 0)
	typebuf.tb_change_cnt = 1;
    return OK;
}

/*
 * Free the buffers of "typebuf".
 */
    void
free_typebuf()
{
    vim_free(typebuf.tb_buf);
    vim_free(typebuf.tb_noremap);
}

/*
 * When doing ":so! file", the current typeahead needs to be saved, and
 * restored when "file" has been read completely.
 */
static typebuf_T saved_typebuf[NSCRIPT];

    int
save_typebuf()
{
    init_typebuf();
    saved_typebuf[curscript] = typebuf;
    /* If out of memory: restore typebuf and close file. */
    if (alloc_typebuf() == FAIL)
    {
	closescript();
	return FAIL;
    }
    return OK;
}

#if defined(FEAT_EVAL) || defined(FEAT_EX_EXTRA) || defined(PROTO)

/*
 * Save all three kinds of typeahead, so that the user must type at a prompt.
 */
    void
save_typeahead(tp)
    tasave_T	*tp;
{
    tp->save_typebuf = typebuf;
    tp->typebuf_valid = (alloc_typebuf() == OK);
    if (!tp->typebuf_valid)
	typebuf = tp->save_typebuf;

    tp->save_stuffbuff = stuffbuff;
    stuffbuff.bh_first.b_next = NULL;
# ifdef USE_INPUT_BUF
    tp->save_inputbuf = get_input_buf();
# endif
}

/*
 * Restore the typeahead to what it was before calling save_typeahead().
 * The allocated memory is freed, can only be called once!
 */
    void
restore_typeahead(tp)
    tasave_T	*tp;
{
    if (tp->typebuf_valid)
    {
	free_typebuf();
	typebuf = tp->save_typebuf;
    }

    free_buff(&stuffbuff);
    stuffbuff = tp->save_stuffbuff;
# ifdef USE_INPUT_BUF
    set_input_buf(tp->save_inputbuf);
# endif
}
#endif

/*
 * Open a new script file for the ":source!" command.
 */
    void
openscript(name, directly)
    char_u	*name;
    int		directly;	/* when TRUE execute directly */
{
    if (curscript + 1 == NSCRIPT)
    {
	EMSG(_(e_nesting));
	return;
    }

    if (scriptin[curscript] != NULL)	/* already reading script */
	++curscript;
				/* use NameBuff for expanded name */
    expand_env(name, NameBuff, MAXPATHL);
    if ((scriptin[curscript] = mch_fopen((char *)NameBuff, READBIN)) == NULL)
    {
	EMSG2(_(e_notopen), name);
	if (curscript)
	    --curscript;
	return;
    }
    if (save_typebuf() == FAIL)
	return;

    /*
     * Execute the commands from the file right now when using ":source!"
     * after ":global" or ":argdo" or in a loop.  Also when another command
     * follows.  This means the display won't be updated.  Don't do this
     * always, "make test" would fail.
     */
    if (directly)
    {
	oparg_T	oa;
	int	oldcurscript;
	int	save_State = State;
	int	save_restart_edit = restart_edit;
	int	save_insertmode = p_im;
	int	save_finish_op = finish_op;
	int	save_msg_scroll = msg_scroll;

	State = NORMAL;
	msg_scroll = FALSE;	/* no msg scrolling in Normal mode */
	restart_edit = 0;	/* don't go to Insert mode */
	p_im = FALSE;		/* don't use 'insertmode' */
	clear_oparg(&oa);
	finish_op = FALSE;

	oldcurscript = curscript;
	do
	{
	    update_topline_cursor();	/* update cursor position and topline */
	    normal_cmd(&oa, FALSE);	/* execute one command */
	    vpeekc();			/* check for end of file */
	}
	while (scriptin[oldcurscript] != NULL);

	State = save_State;
	msg_scroll = save_msg_scroll;
	restart_edit = save_restart_edit;
	p_im = save_insertmode;
	finish_op = save_finish_op;
    }
}

/*
 * Close the currently active input script.
 */
    static void
closescript()
{
    free_typebuf();
    typebuf = saved_typebuf[curscript];

    fclose(scriptin[curscript]);
    scriptin[curscript] = NULL;
    if (curscript > 0)
	--curscript;
}

#if defined(EXITFREE) || defined(PROTO)
    void
close_all_scripts()
{
    while (scriptin[0] != NULL)
	closescript();
}
#endif

#if defined(FEAT_INS_EXPAND) || defined(PROTO)
/*
 * Return TRUE when reading keys from a script file.
 */
    int
using_script()
{
    return scriptin[curscript] != NULL;
}
#endif

/*
 * This function is called just before doing a blocking wait.  Thus after
 * waiting 'updatetime' for a character to arrive.
 */
    void
before_blocking()
{
    updatescript(0);
#ifdef FEAT_EVAL
    if (may_garbage_collect)
	garbage_collect();
#endif
}

/*
 * updatescipt() is called when a character can be written into the script file
 * or when we have waited some time for a character (c == 0)
 *
 * All the changed memfiles are synced if c == 0 or when the number of typed
 * characters reaches 'updatecount' and 'updatecount' is non-zero.
 */
    void
updatescript(c)
    int c;
{
    static int	    count = 0;

    if (c && scriptout)
	putc(c, scriptout);
    if (c == 0 || (p_uc > 0 && ++count >= p_uc))
    {
	ml_sync_all(c == 0, TRUE);
	count = 0;
    }
}

#define KL_PART_KEY -1		/* keylen value for incomplete key-code */
#define KL_PART_MAP -2		/* keylen value for incomplete mapping */

static int old_char = -1;	/* character put back by vungetc() */
static int old_mod_mask;	/* mod_mask for ungotten character */

/*
 * Get the next input character.
 * Can return a special key or a multi-byte character.
 * Can return NUL when called recursively, use safe_vgetc() if that's not
 * wanted.
 * This translates escaped K_SPECIAL and CSI bytes to a K_SPECIAL or CSI byte.
 * Collects the bytes of a multibyte character into the whole character.
 * Returns the modifers in the global "mod_mask".
 */
    int
vgetc()
{
    int		c, c2;
#ifdef FEAT_MBYTE
    int		n;
    char_u	buf[MB_MAXBYTES];
    int		i;
#endif

#ifdef FEAT_EVAL
    /* Do garbage collection when garbagecollect() was called previously and
     * we are now at the toplevel. */
    if (may_garbage_collect && want_garbage_collect)
	garbage_collect();
#endif

    /*
     * If a character was put back with vungetc, it was already processed.
     * Return it directly.
     */
    if (old_char != -1)
    {
	c = old_char;
	old_char = -1;
	mod_mask = old_mod_mask;
    }
    else
    {
      mod_mask = 0x0;
      last_recorded_len = 0;
      for (;;)			/* this is done twice if there are modifiers */
      {
	if (mod_mask)		/* no mapping after modifier has been read */
	{
	    ++no_mapping;
	    ++allow_keys;
	}
	c = vgetorpeek(TRUE);
	if (mod_mask)
	{
	    --no_mapping;
	    --allow_keys;
	}

	/* Get two extra bytes for special keys */
	if (c == K_SPECIAL
#ifdef FEAT_GUI
		|| c == CSI
#endif
	   )
	{
	    int	    save_allow_keys = allow_keys;

	    ++no_mapping;
	    allow_keys = 0;		/* make sure BS is not found */
	    c2 = vgetorpeek(TRUE);	/* no mapping for these chars */
	    c = vgetorpeek(TRUE);
	    --no_mapping;
	    allow_keys = save_allow_keys;
	    if (c2 == KS_MODIFIER)
	    {
		mod_mask = c;
		continue;
	    }
	    c = TO_SPECIAL(c2, c);

#if defined(FEAT_GUI_W32) && defined(FEAT_MENU) && defined(FEAT_TEAROFF)
	    /* Handle K_TEAROFF here, the caller of vgetc() doesn't need to
	     * know that a menu was torn off */
	    if (c == K_TEAROFF)
	    {
		char_u	name[200];
		int	i;

		/* get menu path, it ends with a <CR> */
		for (i = 0; (c = vgetorpeek(TRUE)) != '\r'; )
		{
		    name[i] = c;
		    if (i < 199)
			++i;
		}
		name[i] = NUL;
		gui_make_tearoff(name);
		continue;
	    }
#endif
#if defined(FEAT_GUI) && defined(HAVE_GTK2) && defined(FEAT_MENU)
	    /* GTK: <F10> normally selects the menu, but it's passed until
	     * here to allow mapping it.  Intercept and invoke the GTK
	     * behavior if it's not mapped. */
	    if (c == K_F10 && gui.menubar != NULL)
	    {
		gtk_menu_shell_select_first(GTK_MENU_SHELL(gui.menubar), FALSE);
		continue;
	    }
#endif

#ifdef FEAT_GUI
	    /* Translate K_CSI to CSI.  The special key is only used to avoid
	     * it being recognized as the start of a special key. */
	    if (c == K_CSI)
		c = CSI;
#endif
	}
#ifdef MSDOS
	/*
	 * If K_NUL was typed, it is replaced by K_NUL, 3 in mch_inchar().
	 * Delete the 3 here.
	 */
	else if (c == K_NUL && vpeekc() == 3)
	    (void)vgetorpeek(TRUE);
#endif

	/* a keypad or special function key was not mapped, use it like
	 * its ASCII equivalent */
	switch (c)
	{
	    case K_KPLUS:		c = '+'; break;
	    case K_KMINUS:		c = '-'; break;
	    case K_KDIVIDE:		c = '/'; break;
	    case K_KMULTIPLY:	c = '*'; break;
	    case K_KENTER:		c = CAR; break;
	    case K_KPOINT:
#ifdef WIN32
				    /* Can be either '.' or a ',', *
				     * depending on the type of keypad. */
				    c = MapVirtualKey(VK_DECIMAL, 2); break;
#else
				    c = '.'; break;
#endif
	    case K_K0:		c = '0'; break;
	    case K_K1:		c = '1'; break;
	    case K_K2:		c = '2'; break;
	    case K_K3:		c = '3'; break;
	    case K_K4:		c = '4'; break;
	    case K_K5:		c = '5'; break;
	    case K_K6:		c = '6'; break;
	    case K_K7:		c = '7'; break;
	    case K_K8:		c = '8'; break;
	    case K_K9:		c = '9'; break;

	    case K_XHOME:
	    case K_ZHOME:	if (mod_mask == MOD_MASK_SHIFT)
				{
				    c = K_S_HOME;
				    mod_mask = 0;
				}
				else if (mod_mask == MOD_MASK_CTRL)
				{
				    c = K_C_HOME;
				    mod_mask = 0;
				}
				else
				    c = K_HOME;
				break;
	    case K_XEND:
	    case K_ZEND:	if (mod_mask == MOD_MASK_SHIFT)
				{
				    c = K_S_END;
				    mod_mask = 0;
				}
				else if (mod_mask == MOD_MASK_CTRL)
				{
				    c = K_C_END;
				    mod_mask = 0;
				}
				else
				    c = K_END;
				break;

	    case K_XUP:		c = K_UP; break;
	    case K_XDOWN:	c = K_DOWN; break;
	    case K_XLEFT:	c = K_LEFT; break;
	    case K_XRIGHT:	c = K_RIGHT; break;
	}

#ifdef FEAT_MBYTE
	/* For a multi-byte character get all the bytes and return the
	 * converted character.
	 * Note: This will loop until enough bytes are received!
	 */
	if (has_mbyte && (n = MB_BYTE2LEN_CHECK(c)) > 1)
	{
	    ++no_mapping;
	    buf[0] = c;
	    for (i = 1; i < n; ++i)
	    {
		buf[i] = vgetorpeek(TRUE);
		if (buf[i] == K_SPECIAL
#ifdef FEAT_GUI
			|| buf[i] == CSI
#endif
			)
		{
		    /* Must be a K_SPECIAL - KS_SPECIAL - KE_FILLER sequence,
		     * which represents a K_SPECIAL (0x80),
		     * or a CSI - KS_EXTRA - KE_CSI sequence, which represents
		     * a CSI (0x9B),
		     * of a K_SPECIAL - KS_EXTRA - KE_CSI, which is CSI too. */
		    c = vgetorpeek(TRUE);
		    if (vgetorpeek(TRUE) == (int)KE_CSI && c == KS_EXTRA)
			buf[i] = CSI;
		}
	    }
	    --no_mapping;
	    c = (*mb_ptr2char)(buf);
	}
#endif

	break;
      }
    }

#ifdef FEAT_EVAL
    /*
     * In the main loop "may_garbage_collect" can be set to do garbage
     * collection in the first next vgetc().  It's disabled after that to
     * avoid internally used Lists and Dicts to be freed.
     */
    may_garbage_collect = FALSE;
#endif

    return c;
}

/*
 * Like vgetc(), but never return a NUL when called recursively, get a key
 * directly from the user (ignoring typeahead).
 */
    int
safe_vgetc()
{
    int	c;

    c = vgetc();
    if (c == NUL)
	c = get_keystroke();
    return c;
}

/*
 * Check if a character is available, such that vgetc() will not block.
 * If the next character is a special character or multi-byte, the returned
 * character is not valid!.
 */
    int
vpeekc()
{
    if (old_char != -1)
	return old_char;
    return vgetorpeek(FALSE);
}

#if defined(FEAT_TERMRESPONSE) || defined(PROTO)
/*
 * Like vpeekc(), but don't allow mapping.  Do allow checking for terminal
 * codes.
 */
    int
vpeekc_nomap()
{
    int		c;

    ++no_mapping;
    ++allow_keys;
    c = vpeekc();
    --no_mapping;
    --allow_keys;
    return c;
}
#endif

#if defined(FEAT_INS_EXPAND) || defined(PROTO)
/*
 * Check if any character is available, also half an escape sequence.
 * Trick: when no typeahead found, but there is something in the typeahead
 * buffer, it must be an ESC that is recognized as the start of a key code.
 */
    int
vpeekc_any()
{
    int		c;

    c = vpeekc();
    if (c == NUL && typebuf.tb_len > 0)
	c = ESC;
    return c;
}
#endif

/*
 * Call vpeekc() without causing anything to be mapped.
 * Return TRUE if a character is available, FALSE otherwise.
 */
    int
char_avail()
{
    int	    retval;

    ++no_mapping;
    retval = vpeekc();
    --no_mapping;
    return (retval != NUL);
}

    void
vungetc(c)	/* unget one character (can only be done once!) */
    int		c;
{
    old_char = c;
    old_mod_mask = mod_mask;
}

/*
 * get a character:
 * 1. from the stuffbuffer
 *	This is used for abbreviated commands like "D" -> "d$".
 *	Also used to redo a command for ".".
 * 2. from the typeahead buffer
 *	Stores text obtained previously but not used yet.
 *	Also stores the result of mappings.
 *	Also used for the ":normal" command.
 * 3. from the user
 *	This may do a blocking wait if "advance" is TRUE.
 *
 * if "advance" is TRUE (vgetc()):
 *	really get the character.
 *	KeyTyped is set to TRUE in the case the user typed the key.
 *	KeyStuffed is TRUE if the character comes from the stuff buffer.
 * if "advance" is FALSE (vpeekc()):
 *	just look whether there is a character available.
 *
 * When "no_mapping" is zero, checks for mappings in the current mode.
 * Only returns one byte (of a multi-byte character).
 * K_SPECIAL and CSI may be escaped, need to get two more bytes then.
 */
    static int
vgetorpeek(advance)
    int	    advance;
{
    int		c, c1;
    int		keylen;
    char_u	*s;
    mapblock_T	*mp;
#ifdef FEAT_LOCALMAP
    mapblock_T	*mp2;
#endif
    mapblock_T	*mp_match;
    int		mp_match_len = 0;
    int		timedout = FALSE;	    /* waited for more than 1 second
						for mapping to complete */
    int		mapdepth = 0;	    /* check for recursive mapping */
    int		mode_deleted = FALSE;   /* set when mode has been deleted */
    int		local_State;
    int		mlen;
    int		max_mlen;
    int		i;
#ifdef FEAT_CMDL_INFO
    int		new_wcol, new_wrow;
#endif
#ifdef FEAT_GUI
# ifdef FEAT_MENU
    int		idx;
# endif
    int		shape_changed = FALSE;  /* adjusted cursor shape */
#endif
    int		n;
#ifdef FEAT_LANGMAP
    int		nolmaplen;
#endif
    int		old_wcol, old_wrow;
    int		wait_tb_len;

    /*
     * This function doesn't work very well when called recursively.  This may
     * happen though, because of:
     * 1. The call to add_to_showcmd().	char_avail() is then used to check if
     * there is a character available, which calls this function.  In that
     * case we must return NUL, to indicate no character is available.
     * 2. A GUI callback function writes to the screen, causing a
     * wait_return().
     * Using ":normal" can also do this, but it saves the typeahead buffer,
     * thus it should be OK.  But don't get a key from the user then.
     */
    if (vgetc_busy > 0
#ifdef FEAT_EX_EXTRA
	    && ex_normal_busy == 0
#endif
	    )
	return NUL;

    local_State = get_real_state();

    ++vgetc_busy;

    if (advance)
	KeyStuffed = FALSE;

    init_typebuf();
    start_stuff();
    if (advance && typebuf.tb_maplen == 0)
	Exec_reg = FALSE;
    do
    {
/*
 * get a character: 1. from the stuffbuffer
 */
	if (typeahead_char != 0)
	{
	    c = typeahead_char;
	    if (advance)
		typeahead_char = 0;
	}
	else
	    c = read_stuff(advance);
	if (c != NUL && !got_int)
	{
	    if (advance)
	    {
		/* KeyTyped = FALSE;  When the command that stuffed something
		 * was typed, behave like the stuffed command was typed.
		 * needed for CTRL-W CTRl-] to open a fold, for example. */
		KeyStuffed = TRUE;
	    }
	    if (typebuf.tb_no_abbr_cnt == 0)
		typebuf.tb_no_abbr_cnt = 1;	/* no abbreviations now */
	}
	else
	{
	    /*
	     * Loop until we either find a matching mapped key, or we
	     * are sure that it is not a mapped key.
	     * If a mapped key sequence is found we go back to the start to
	     * try re-mapping.
	     */
	    for (;;)
	    {
		/*
		 * ui_breakcheck() is slow, don't use it too often when
		 * inside a mapping.  But call it each time for typed
		 * characters.
		 */
		if (typebuf.tb_maplen)
		    line_breakcheck();
		else
		    ui_breakcheck();		/* check for CTRL-C */
		keylen = 0;
		if (got_int)
		{
		    /* flush all input */
		    c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L,
						       typebuf.tb_change_cnt);
		    /*
		     * If inchar() returns TRUE (script file was active) or we
		     * are inside a mapping, get out of insert mode.
		     * Otherwise we behave like having gotten a CTRL-C.
		     * As a result typing CTRL-C in insert mode will
		     * really insert a CTRL-C.
		     */
		    if ((c || typebuf.tb_maplen)
					      && (State & (INSERT + CMDLINE)))
			c = ESC;
		    else
			c = Ctrl_C;
		    flush_buffers(TRUE);	/* flush all typeahead */

		    if (advance)
		    {
			/* Also record this character, it might be needed to
			 * get out of Insert mode. */
			*typebuf.tb_buf = c;
			gotchars(typebuf.tb_buf, 1);
		    }
		    cmd_silent = FALSE;

		    break;
		}
		else if (typebuf.tb_len > 0)
		{
		    /*
		     * Check for a mappable key sequence.
		     * Walk through one maphash[] list until we find an
		     * entry that matches.
		     *
		     * Don't look for mappings if:
		     * - no_mapping set: mapping disabled (e.g. for CTRL-V)
		     * - maphash_valid not set: no mappings present.
		     * - typebuf.tb_buf[typebuf.tb_off] should not be remapped
		     * - in insert or cmdline mode and 'paste' option set
		     * - waiting for "hit return to continue" and CR or SPACE
		     *	 typed
		     * - waiting for a char with --more--
		     * - in Ctrl-X mode, and we get a valid char for that mode
		     */
		    mp = NULL;
		    max_mlen = 0;
		    c1 = typebuf.tb_buf[typebuf.tb_off];
		    if (no_mapping == 0 && maphash_valid
			    && (no_zero_mapping == 0 || c1 != '0')
			    && (typebuf.tb_maplen == 0
				|| (p_remap
				    && (typebuf.tb_noremap[typebuf.tb_off]
						    & (RM_NONE|RM_ABBR)) == 0))
			    && !(p_paste && (State & (INSERT + CMDLINE)))
			    && !(State == HITRETURN && (c1 == CAR || c1 == ' '))
			    && State != ASKMORE
			    && State != CONFIRM
#ifdef FEAT_INS_EXPAND
			    && !((ctrl_x_mode != 0 && vim_is_ctrl_x_key(c1))
				    || ((compl_cont_status & CONT_LOCAL)
					&& (c1 == Ctrl_N || c1 == Ctrl_P)))
#endif
			    )
		    {
#ifdef FEAT_LANGMAP
			if (c1 == K_SPECIAL)
			    nolmaplen = 2;
			else
			{
			    LANGMAP_ADJUST(c1, TRUE);
			    nolmaplen = 0;
			}
#endif
#ifdef FEAT_LOCALMAP
			/* First try buffer-local mappings. */
			mp = curbuf->b_maphash[MAP_HASH(local_State, c1)];
			mp2 = maphash[MAP_HASH(local_State, c1)];
			if (mp == NULL)
			{
			    mp = mp2;
			    mp2 = NULL;
			}
#else
			mp = maphash[MAP_HASH(local_State, c1)];
#endif
			/*
			 * Loop until a partly matching mapping is found or
			 * all (local) mappings have been checked.
			 * The longest full match is remembered in "mp_match".
			 * A full match is only accepted if there is no partly
			 * match, so "aa" and "aaa" can both be mapped.
			 */
			mp_match = NULL;
			mp_match_len = 0;
			for ( ; mp != NULL;
#ifdef FEAT_LOCALMAP
				mp->m_next == NULL ? (mp = mp2, mp2 = NULL) :
#endif
				(mp = mp->m_next))
			{
			    /*
			     * Only consider an entry if the first character
			     * matches and it is for the current state.
			     * Skip ":lmap" mappings if keys were mapped.
			     */
			    if (mp->m_keys[0] == c1
				    && (mp->m_mode & local_State)
				    && ((mp->m_mode & LANGMAP) == 0
					|| typebuf.tb_maplen == 0))
			    {
#ifdef FEAT_LANGMAP
				int	nomap = nolmaplen;
				int	c2;
#endif
				/* find the match length of this mapping */
				for (mlen = 1; mlen < typebuf.tb_len; ++mlen)
				{
#ifdef FEAT_LANGMAP
				    c2 = typebuf.tb_buf[typebuf.tb_off + mlen];
				    if (nomap > 0)
					--nomap;
				    else if (c2 == K_SPECIAL)
					nomap = 2;
				    else
					LANGMAP_ADJUST(c2, TRUE);
				    if (mp->m_keys[mlen] != c2)
#else
				    if (mp->m_keys[mlen] !=
					typebuf.tb_buf[typebuf.tb_off + mlen])
#endif
					break;
				}

#ifdef FEAT_MBYTE
				/* Don't allow mapping the first byte(s) of a
				 * multi-byte char.  Happens when mapping
				 * <M-a> and then changing 'encoding'. */
				if (has_mbyte && MB_BYTE2LEN(c1)
						  > (*mb_ptr2len)(mp->m_keys))
				    mlen = 0;
#endif
				/*
				 * Check an entry whether it matches.
				 * - Full match: mlen == keylen
				 * - Partly match: mlen == typebuf.tb_len
				 */
				keylen = mp->m_keylen;
				if (mlen == keylen
				     || (mlen == typebuf.tb_len
						  && typebuf.tb_len < keylen))
				{
				    /*
				     * If only script-local mappings are
				     * allowed, check if the mapping starts
				     * with K_SNR.
				     */
				    s = typebuf.tb_noremap + typebuf.tb_off;
				    if (*s == RM_SCRIPT
					    && (mp->m_keys[0] != K_SPECIAL
						|| mp->m_keys[1] != KS_EXTRA
						|| mp->m_keys[2]
							      != (int)KE_SNR))
					continue;
				    /*
				     * If one of the typed keys cannot be
				     * remapped, skip the entry.
				     */
				    for (n = mlen; --n >= 0; )
					if (*s++ & (RM_NONE|RM_ABBR))
					    break;
				    if (n >= 0)
					continue;

				    if (keylen > typebuf.tb_len)
				    {
					if (!timedout)
					{
					    /* break at a partly match */
					    keylen = KL_PART_MAP;
					    break;
					}
				    }
				    else if (keylen > mp_match_len)
				    {
					/* found a longer match */
					mp_match = mp;
					mp_match_len = keylen;
				    }
				}
				else
				    /* No match; may have to check for
				     * termcode at next character. */
				    if (max_mlen < mlen)
					max_mlen = mlen;
			    }
			}

			/* If no partly match found, use the longest full
			 * match. */
			if (keylen != KL_PART_MAP)
			{
			    mp = mp_match;
			    keylen = mp_match_len;
			}
		    }

		    /* Check for match with 'pastetoggle' */
		    if (*p_pt != NUL && mp == NULL && (State & (INSERT|NORMAL)))
		    {
			for (mlen = 0; mlen < typebuf.tb_len && p_pt[mlen];
								       ++mlen)
			    if (p_pt[mlen] != typebuf.tb_buf[typebuf.tb_off
								      + mlen])
				    break;
			if (p_pt[mlen] == NUL)	/* match */
			{
			    /* write chars to script file(s) */
			    if (mlen > typebuf.tb_maplen)
				gotchars(typebuf.tb_buf + typebuf.tb_off
							  + typebuf.tb_maplen,
						    mlen - typebuf.tb_maplen);

			    del_typebuf(mlen, 0); /* remove the chars */
			    set_option_value((char_u *)"paste",
						     (long)!p_paste, NULL, 0);
			    if (!(State & INSERT))
			    {
				msg_col = 0;
				msg_row = Rows - 1;
				msg_clr_eos();		/* clear ruler */
			    }
			    showmode();
			    setcursor();
			    continue;
			}
			/* Need more chars for partly match. */
			if (mlen == typebuf.tb_len)
			    keylen = KL_PART_MAP;
			else if (max_mlen < mlen)
			    /* no match, may have to check for termcode at
			     * next character */
			    max_mlen = mlen + 1;
		    }

		    if ((mp == NULL || max_mlen >= mp_match_len)
						     && keylen != KL_PART_MAP)
		    {
			/*
			 * When no matching mapping found or found a
			 * non-matching mapping that matches at least what the
			 * matching mapping matched:
			 * Check if we have a terminal code, when:
			 *  mapping is allowed,
			 *  keys have not been mapped,
			 *  and not an ESC sequence, not in insert mode or
			 *	p_ek is on,
			 *  and when not timed out,
			 */
			if ((no_mapping == 0 || allow_keys != 0)
				&& (typebuf.tb_maplen == 0
				    || (p_remap && typebuf.tb_noremap[
						   typebuf.tb_off] == RM_YES))
				&& !timedout)
			{
			    keylen = check_termcode(max_mlen + 1, NULL, 0);

			    /*
			     * When getting a partial match, but the last
			     * characters were not typed, don't wait for a
			     * typed character to complete the termcode.
			     * This helps a lot when a ":normal" command ends
			     * in an ESC.
			     */
			    if (keylen < 0
				       && typebuf.tb_len == typebuf.tb_maplen)
				keylen = 0;
			}
			else
			    keylen = 0;
			if (keylen == 0)	/* no matching terminal code */
			{
#ifdef AMIGA			/* check for window bounds report */
			    if (typebuf.tb_maplen == 0 && (typebuf.tb_buf[
					       typebuf.tb_off] & 0xff) == CSI)
			    {
				for (s = typebuf.tb_buf + typebuf.tb_off + 1;
					s < typebuf.tb_buf + typebuf.tb_off
							      + typebuf.tb_len
				   && (VIM_ISDIGIT(*s) || *s == ';'
								|| *s == ' ');
					++s)
				    ;
				if (*s == 'r' || *s == '|') /* found one */
				{
				    del_typebuf((int)(s + 1 -
				       (typebuf.tb_buf + typebuf.tb_off)), 0);
				    /* get size and redraw screen */
				    shell_resized();
				    continue;
				}
				if (*s == NUL)	    /* need more characters */
				    keylen = KL_PART_KEY;
			    }
			    if (keylen >= 0)
#endif
			      /* When there was a matching mapping and no
			       * termcode could be replaced after another one,
			       * use that mapping. */
			      if (mp == NULL)
			      {
/*
 * get a character: 2. from the typeahead buffer
 */
				c = typebuf.tb_buf[typebuf.tb_off] & 255;
				if (advance)	/* remove chars from tb_buf */
				{
				    cmd_silent = (typebuf.tb_silent > 0);
				    if (typebuf.tb_maplen > 0)
					KeyTyped = FALSE;
				    else
				    {
					KeyTyped = TRUE;
					/* write char to script file(s) */
					gotchars(typebuf.tb_buf
							 + typebuf.tb_off, 1);
				    }
				    KeyNoremap = typebuf.tb_noremap[
							      typebuf.tb_off];
				    del_typebuf(1, 0);
				}
				break;	    /* got character, break for loop */
			      }
			}
			if (keylen > 0)	    /* full matching terminal code */
			{
#if defined(FEAT_GUI) && defined(FEAT_MENU)
			    if (typebuf.tb_buf[typebuf.tb_off] == K_SPECIAL
					 && typebuf.tb_buf[typebuf.tb_off + 1]
								   == KS_MENU)
			    {
				/*
				 * Using a menu may cause a break in undo!
				 * It's like using gotchars(), but without
				 * recording or writing to a script file.
				 */
				may_sync_undo();
				del_typebuf(3, 0);
				idx = get_menu_index(current_menu, local_State);
				if (idx != MENU_INDEX_INVALID)
				{
# ifdef FEAT_VISUAL
				    /*
				     * In Select mode and a Visual mode menu
				     * is used:  Switch to Visual mode
				     * temporarily.  Append K_SELECT to switch
				     * back to Select mode.
				     */
				    if (VIsual_active && VIsual_select
					    && (current_menu->modes & VISUAL))
				    {
					VIsual_select = FALSE;
					(void)ins_typebuf(K_SELECT_STRING,
						  REMAP_NONE, 0, TRUE, FALSE);
				    }
# endif
				    ins_typebuf(current_menu->strings[idx],
						current_menu->noremap[idx],
						0, TRUE,
						   current_menu->silent[idx]);
				}
			    }
#endif /* FEAT_GUI */
			    continue;	/* try mapping again */
			}

			/* Partial match: get some more characters.  When a
			 * matching mapping was found use that one. */
			if (mp == NULL || keylen < 0)
			    keylen = KL_PART_KEY;
			else
			    keylen = mp_match_len;
		    }

		    /* complete match */
		    if (keylen >= 0 && keylen <= typebuf.tb_len)
		    {
			/* write chars to script file(s) */
			if (keylen > typebuf.tb_maplen)
			    gotchars(typebuf.tb_buf + typebuf.tb_off
							  + typebuf.tb_maplen,
						  keylen - typebuf.tb_maplen);

			cmd_silent = (typebuf.tb_silent > 0);
			del_typebuf(keylen, 0);	/* remove the mapped keys */

			/*
			 * Put the replacement string in front of mapstr.
			 * The depth check catches ":map x y" and ":map y x".
			 */
			if (++mapdepth >= p_mmd)
			{
			    EMSG(_("E223: recursive mapping"));
			    if (State & CMDLINE)
				redrawcmdline();
			    else
				setcursor();
			    flush_buffers(FALSE);
			    mapdepth = 0;	/* for next one */
			    c = -1;
			    break;
			}

#ifdef FEAT_VISUAL
			/*
			 * In Select mode and a Visual mode mapping is used:
			 * Switch to Visual mode temporarily.  Append K_SELECT
			 * to switch back to Select mode.
			 */
			if (VIsual_active && VIsual_select
						     && (mp->m_mode & VISUAL))
			{
			    VIsual_select = FALSE;
			    (void)ins_typebuf(K_SELECT_STRING, REMAP_NONE,
							      0, TRUE, FALSE);
			}
#endif

#ifdef FEAT_EVAL
			/*
			 * Handle ":map <expr>": evaluate the {rhs} as an
			 * expression.  Save and restore the typeahead so that
			 * getchar() can be used.  Also save and restore the
			 * command line for "normal :".
			 */
			if (mp->m_expr)
			{
			    tasave_T	tabuf;
			    int		save_vgetc_busy = vgetc_busy;

			    save_typeahead(&tabuf);
			    if (tabuf.typebuf_valid)
			    {
				vgetc_busy = 0;
				s = eval_map_expr(mp->m_str);
				vgetc_busy = save_vgetc_busy;
			    }
			    else
				s = NULL;
			    restore_typeahead(&tabuf);
			}
			else
#endif
			    s = mp->m_str;

			/*
			 * Insert the 'to' part in the typebuf.tb_buf.
			 * If 'from' field is the same as the start of the
			 * 'to' field, don't remap the first character (but do
			 * allow abbreviations).
			 * If m_noremap is set, don't remap the whole 'to'
			 * part.
			 */
			if (s == NULL)
			    i = FAIL;
			else
			{
			    i = ins_typebuf(s,
				    mp->m_noremap != REMAP_YES
					    ? mp->m_noremap
					    : STRNCMP(s, mp->m_keys,
							  (size_t)keylen) != 0
						     ? REMAP_YES : REMAP_SKIP,
				0, TRUE, cmd_silent || mp->m_silent);
#ifdef FEAT_EVAL
			    if (mp->m_expr)
				vim_free(s);
#endif
			}
			if (i == FAIL)
			{
			    c = -1;
			    break;
			}
			continue;
		    }
		}

/*
 * get a character: 3. from the user - handle <Esc> in Insert mode
 */
		/*
		 * special case: if we get an <ESC> in insert mode and there
		 * are no more characters at once, we pretend to go out of
		 * insert mode.  This prevents the one second delay after
		 * typing an <ESC>.  If we get something after all, we may
		 * have to redisplay the mode. That the cursor is in the wrong
		 * place does not matter.
		 */
		c = 0;
#ifdef FEAT_CMDL_INFO
		new_wcol = curwin->w_wcol;
		new_wrow = curwin->w_wrow;
#endif
		if (	   advance
			&& typebuf.tb_len == 1
			&& typebuf.tb_buf[typebuf.tb_off] == ESC
			&& !no_mapping
#ifdef FEAT_EX_EXTRA
			&& ex_normal_busy == 0
#endif
			&& typebuf.tb_maplen == 0
			&& (State & INSERT)
			&& (p_timeout || (keylen == KL_PART_KEY && p_ttimeout))
			&& (c = inchar(typebuf.tb_buf + typebuf.tb_off
						     + typebuf.tb_len, 3, 25L,
						 typebuf.tb_change_cnt)) == 0)
		{
		    colnr_T	col = 0, vcol;
		    char_u	*ptr;

		    if (mode_displayed)
		    {
			unshowmode(TRUE);
			mode_deleted = TRUE;
		    }
#ifdef FEAT_GUI
		    /* may show different cursor shape */
		    if (gui.in_use)
		    {
			int	    save_State;

			save_State = State;
			State = NORMAL;
			gui_update_cursor(TRUE, FALSE);
			State = save_State;
			shape_changed = TRUE;
		    }
#endif
		    validate_cursor();
		    old_wcol = curwin->w_wcol;
		    old_wrow = curwin->w_wrow;

		    /* move cursor left, if possible */
		    if (curwin->w_cursor.col != 0)
		    {
			if (curwin->w_wcol > 0)
			{
			    if (did_ai)
			    {
				/*
				 * We are expecting to truncate the trailing
				 * white-space, so find the last non-white
				 * character -- webb
				 */
				col = vcol = curwin->w_wcol = 0;
				ptr = ml_get_curline();
				while (col < curwin->w_cursor.col)
				{
				    if (!vim_iswhite(ptr[col]))
					curwin->w_wcol = vcol;
				    vcol += lbr_chartabsize(ptr + col,
							       (colnr_T)vcol);
#ifdef FEAT_MBYTE
				    if (has_mbyte)
					col += (*mb_ptr2len)(ptr + col);
				    else
#endif
					++col;
				}
				curwin->w_wrow = curwin->w_cline_row
					   + curwin->w_wcol / W_WIDTH(curwin);
				curwin->w_wcol %= W_WIDTH(curwin);
				curwin->w_wcol += curwin_col_off();
#ifdef FEAT_MBYTE
				col = 0;	/* no correction needed */
#endif
			    }
			    else
			    {
				--curwin->w_wcol;
#ifdef FEAT_MBYTE
				col = curwin->w_cursor.col - 1;
#endif
			    }
			}
			else if (curwin->w_p_wrap && curwin->w_wrow)
			{
			    --curwin->w_wrow;
			    curwin->w_wcol = W_WIDTH(curwin) - 1;
#ifdef FEAT_MBYTE
			    col = curwin->w_cursor.col - 1;
#endif
			}
#ifdef FEAT_MBYTE
			if (has_mbyte && col > 0 && curwin->w_wcol > 0)
			{
			    /* Correct when the cursor is on the right halve
			     * of a double-wide character. */
			    ptr = ml_get_curline();
			    col -= (*mb_head_off)(ptr, ptr + col);
			    if ((*mb_ptr2cells)(ptr + col) > 1)
				--curwin->w_wcol;
			}
#endif
		    }
		    setcursor();
		    out_flush();
#ifdef FEAT_CMDL_INFO
		    new_wcol = curwin->w_wcol;
		    new_wrow = curwin->w_wrow;
#endif
		    curwin->w_wcol = old_wcol;
		    curwin->w_wrow = old_wrow;
		}
		if (c < 0)
		    continue;	/* end of input script reached */
		typebuf.tb_len += c;

		/* buffer full, don't map */
		if (typebuf.tb_len >= typebuf.tb_maplen + MAXMAPLEN)
		{
		    timedout = TRUE;
		    continue;
		}

#ifdef FEAT_EX_EXTRA
		if (ex_normal_busy > 0)
		{
# ifdef FEAT_CMDWIN
		    static int tc = 0;
# endif

		    /* No typeahead left and inside ":normal".  Must return
		     * something to avoid getting stuck.  When an incomplete
		     * mapping is present, behave like it timed out. */
		    if (typebuf.tb_len > 0)
		    {
			timedout = TRUE;
			continue;
		    }
		    /* When 'insertmode' is set, ESC just beeps in Insert
		     * mode.  Use CTRL-L to make edit() return.
		     * For the command line only CTRL-C always breaks it.
		     * For the cmdline window: Alternate between ESC and
		     * CTRL-C: ESC for most situations and CTRL-C to close the
		     * cmdline window. */
		    if (p_im && (State & INSERT))
			c = Ctrl_L;
		    else if ((State & CMDLINE)
# ifdef FEAT_CMDWIN
			    || (cmdwin_type > 0 && tc == ESC)
# endif
			    )
			c = Ctrl_C;
		    else
			c = ESC;
# ifdef FEAT_CMDWIN
		    tc = c;
# endif
		    break;
		}
#endif

/*
 * get a character: 3. from the user - update display
 */
		/* In insert mode a screen update is skipped when characters
		 * are still available.  But when those available characters
		 * are part of a mapping, and we are going to do a blocking
		 * wait here.  Need to update the screen to display the
		 * changed text so far. */
		if ((State & INSERT) && advance && must_redraw != 0)
		{
		    update_screen(0);
		    setcursor(); /* put cursor back where it belongs */
		}

		/*
		 * If we have a partial match (and are going to wait for more
		 * input from the user), show the partially matched characters
		 * to the user with showcmd.
		 */
#ifdef FEAT_CMDL_INFO
		i = 0;
#endif
		c1 = 0;
		if (typebuf.tb_len > 0 && advance && !exmode_active)
		{
		    if (((State & (NORMAL | INSERT)) || State == LANGMAP)
			    && State != HITRETURN)
		    {
			/* this looks nice when typing a dead character map */
			if (State & INSERT
			    && ptr2cells(typebuf.tb_buf + typebuf.tb_off
						   + typebuf.tb_len - 1) == 1)
			{
			    edit_putchar(typebuf.tb_buf[typebuf.tb_off
						+ typebuf.tb_len - 1], FALSE);
			    setcursor(); /* put cursor back where it belongs */
			    c1 = 1;
			}
#ifdef FEAT_CMDL_INFO
			/* need to use the col and row from above here */
			old_wcol = curwin->w_wcol;
			old_wrow = curwin->w_wrow;
			curwin->w_wcol = new_wcol;
			curwin->w_wrow = new_wrow;
			push_showcmd();
			if (typebuf.tb_len > SHOWCMD_COLS)
			    i = typebuf.tb_len - SHOWCMD_COLS;
			while (i < typebuf.tb_len)
			    (void)add_to_showcmd(typebuf.tb_buf[typebuf.tb_off
								      + i++]);
			curwin->w_wcol = old_wcol;
			curwin->w_wrow = old_wrow;
#endif
		    }

		    /* this looks nice when typing a dead character map */
		    if ((State & CMDLINE)
#if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
			    && cmdline_star == 0
#endif
			    && ptr2cells(typebuf.tb_buf + typebuf.tb_off
						   + typebuf.tb_len - 1) == 1)
		    {
			putcmdline(typebuf.tb_buf[typebuf.tb_off
						+ typebuf.tb_len - 1], FALSE);
			c1 = 1;
		    }
		}

/*
 * get a character: 3. from the user - get it
 */
		wait_tb_len = typebuf.tb_len;
		c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len,
			typebuf.tb_buflen - typebuf.tb_off - typebuf.tb_len - 1,
			!advance
			    ? 0
			    : ((typebuf.tb_len == 0
				    || !(p_timeout || (p_ttimeout
						   && keylen == KL_PART_KEY)))
				    ? -1L
				    : ((keylen == KL_PART_KEY && p_ttm >= 0)
					    ? p_ttm
					    : p_tm)), typebuf.tb_change_cnt);

#ifdef FEAT_CMDL_INFO
		if (i != 0)
		    pop_showcmd();
#endif
		if (c1 == 1)
		{
		    if (State & INSERT)
			edit_unputchar();
		    if (State & CMDLINE)
			unputcmdline();
		    setcursor();	/* put cursor back where it belongs */
		}

		if (c < 0)
		    continue;		/* end of input script reached */
		if (c == NUL)		/* no character available */
		{
		    if (!advance)
			break;
		    if (wait_tb_len > 0)	/* timed out */
		    {
			timedout = TRUE;
			continue;
		    }
		}
		else
		{	    /* allow mapping for just typed characters */
		    while (typebuf.tb_buf[typebuf.tb_off
						     + typebuf.tb_len] != NUL)
			typebuf.tb_noremap[typebuf.tb_off
						 + typebuf.tb_len++] = RM_YES;
#ifdef USE_IM_CONTROL
		    /* Get IM status right after getting keys, not after the
		     * timeout for a mapping (focus may be lost by then). */
		    vgetc_im_active = im_get_status();
#endif
		}
	    }	    /* for (;;) */
	}	/* if (!character from stuffbuf) */

			/* if advance is FALSE don't loop on NULs */
    } while (c < 0 || (advance && c == NUL));

    /*
     * The "INSERT" message is taken care of here:
     *	 if we return an ESC to exit insert mode, the message is deleted
     *	 if we don't return an ESC but deleted the message before, redisplay it
     */
    if (advance && p_smd && msg_silent == 0 && (State & INSERT))
    {
	if (c == ESC && !mode_deleted && !no_mapping && mode_displayed)
	{
	    if (typebuf.tb_len && !KeyTyped)
		redraw_cmdline = TRUE;	    /* delete mode later */
	    else
		unshowmode(FALSE);
	}
	else if (c != ESC && mode_deleted)
	{
	    if (typebuf.tb_len && !KeyTyped)
		redraw_cmdline = TRUE;	    /* show mode later */
	    else
		showmode();
	}
    }
#ifdef FEAT_GUI
    /* may unshow different cursor shape */
    if (gui.in_use && shape_changed)
	gui_update_cursor(TRUE, FALSE);
#endif

    --vgetc_busy;

    return c;
}

/*
 * inchar() - get one character from
 *	1. a scriptfile
 *	2. the keyboard
 *
 *  As much characters as we can get (upto 'maxlen') are put in "buf" and
 *  NUL terminated (buffer length must be 'maxlen' + 1).
 *  Minimum for "maxlen" is 3!!!!
 *
 *  "tb_change_cnt" is the value of typebuf.tb_change_cnt if "buf" points into
 *  it.  When typebuf.tb_change_cnt changes (e.g., when a message is received
 *  from a remote client) "buf" can no longer be used.  "tb_change_cnt" is 0
 *  otherwise.
 *
 *  If we got an interrupt all input is read until none is available.
 *
 *  If wait_time == 0  there is no waiting for the char.
 *  If wait_time == n  we wait for n msec for a character to arrive.
 *  If wait_time == -1 we wait forever for a character to arrive.
 *
 *  Return the number of obtained characters.
 *  Return -1 when end of input script reached.
 */
    int
inchar(buf, maxlen, wait_time, tb_change_cnt)
    char_u	*buf;
    int		maxlen;
    long	wait_time;	    /* milli seconds */
    int		tb_change_cnt;
{
    int		len = 0;	    /* init for GCC */
    int		retesc = FALSE;	    /* return ESC with gotint */
    int		script_char;

    if (wait_time == -1L || wait_time > 100L)  /* flush output before waiting */
    {
	cursor_on();
	out_flush();
#ifdef FEAT_GUI
	if (gui.in_use)
	{
	    gui_update_cursor(FALSE, FALSE);
# ifdef FEAT_MOUSESHAPE
	    if (postponed_mouseshape)
		update_mouseshape(-1);
# endif
	}
#endif
    }

    /*
     * Don't reset these when at the hit-return prompt, otherwise a endless
     * recursive loop may result (write error in swapfile, hit-return, timeout
     * on char wait, flush swapfile, write error....).
     */
    if (State != HITRETURN)
    {
	did_outofmem_msg = FALSE;   /* display out of memory message (again) */
	did_swapwrite_msg = FALSE;  /* display swap file write error again */
    }
    undo_off = FALSE;		    /* restart undo now */

    /*
     * first try script file
     *	If interrupted: Stop reading script files.
     */
    script_char = -1;
    while (scriptin[curscript] != NULL && script_char < 0)
    {
	if (got_int || (script_char = getc(scriptin[curscript])) < 0)
	{
	    /* Reached EOF.
	     * Careful: closescript() frees typebuf.tb_buf[] and buf[] may
	     * point inside typebuf.tb_buf[].  Don't use buf[] after this! */
	    closescript();
	    /*
	     * When reading script file is interrupted, return an ESC to get
	     * back to normal mode.
	     * Otherwise return -1, because typebuf.tb_buf[] has changed.
	     */
	    if (got_int)
		retesc = TRUE;
	    else
		return -1;
	}
	else
	{
	    buf[0] = script_char;
	    len = 1;
	}
    }

    if (script_char < 0)	/* did not get a character from script */
    {
	/*
	 * If we got an interrupt, skip all previously typed characters and
	 * return TRUE if quit reading script file.
	 * Stop reading typeahead when a single CTRL-C was read,
	 * fill_input_buf() returns this when not able to read from stdin.
	 * Don't use buf[] here, closescript() may have freed typebuf.tb_buf[]
	 * and buf may be pointing inside typebuf.tb_buf[].
	 */
	if (got_int)
	{
#define DUM_LEN MAXMAPLEN * 3 + 3
	    char_u	dum[DUM_LEN + 1];

	    for (;;)
	    {
		len = ui_inchar(dum, DUM_LEN, 0L, 0);
		if (len == 0 || (len == 1 && dum[0] == 3))
		    break;
	    }
	    return retesc;
	}

	/*
	 * Always flush the output characters when getting input characters
	 * from the user.
	 */
	out_flush();

	/*
	 * Fill up to a third of the buffer, because each character may be
	 * tripled below.
	 */
	len = ui_inchar(buf, maxlen / 3, wait_time, tb_change_cnt);
    }

    if (typebuf_changed(tb_change_cnt))
	return 0;

    return fix_input_buffer(buf, len, script_char >= 0);
}

/*
 * Fix typed characters for use by vgetc() and check_termcode().
 * buf[] must have room to triple the number of bytes!
 * Returns the new length.
 */
    int
fix_input_buffer(buf, len, script)
    char_u	*buf;
    int		len;
    int		script;		/* TRUE when reading from a script */
{
    int		i;
    char_u	*p = buf;

    /*
     * Two characters are special: NUL and K_SPECIAL.
     * When compiled With the GUI CSI is also special.
     * Replace	     NUL by K_SPECIAL KS_ZERO	 KE_FILLER
     * Replace K_SPECIAL by K_SPECIAL KS_SPECIAL KE_FILLER
     * Replace       CSI by K_SPECIAL KS_EXTRA   KE_CSI
     * Don't replace K_SPECIAL when reading a script file.
     */
    for (i = len; --i >= 0; ++p)
    {
#ifdef FEAT_GUI
	/* When the GUI is used any character can come after a CSI, don't
	 * escape it. */
	if (gui.in_use && p[0] == CSI && i >= 2)
	{
	    p += 2;
	    i -= 2;
	}
	/* When the GUI is not used CSI needs to be escaped. */
	else if (!gui.in_use && p[0] == CSI)
	{
	    mch_memmove(p + 3, p + 1, (size_t)i);
	    *p++ = K_SPECIAL;
	    *p++ = KS_EXTRA;
	    *p = (int)KE_CSI;
	    len += 2;
	}
	else
#endif
	if (p[0] == NUL || (p[0] == K_SPECIAL && !script
#ifdef FEAT_AUTOCMD
		    /* timeout may generate K_CURSORHOLD */
		    && (i < 2 || p[1] != KS_EXTRA || p[2] != (int)KE_CURSORHOLD)
#endif
#if defined(WIN3264) && !defined(FEAT_GUI)
		    /* Win32 console passes modifiers */
		    && (i < 2 || p[1] != KS_MODIFIER)
#endif
		    ))
	{
	    mch_memmove(p + 3, p + 1, (size_t)i);
	    p[2] = K_THIRD(p[0]);
	    p[1] = K_SECOND(p[0]);
	    p[0] = K_SPECIAL;
	    p += 2;
	    len += 2;
	}
    }
    *p = NUL;		/* add trailing NUL */
    return len;
}

#if defined(USE_INPUT_BUF) || defined(PROTO)
/*
 * Return TRUE when bytes are in the input buffer or in the typeahead buffer.
 * Normally the input buffer would be sufficient, but the server_to_input_buf()
 * or feedkeys() may insert characters in the typeahead buffer while we are
 * waiting for input to arrive.
 */
    int
input_available()
{
    return (!vim_is_input_buf_empty()
# if defined(FEAT_CLIENTSERVER) || defined(FEAT_EVAL)
	    || typebuf_was_filled
# endif
	    );
}
#endif

/*
 * map[!]		    : show all key mappings
 * map[!] {lhs}		    : show key mapping for {lhs}
 * map[!] {lhs} {rhs}	    : set key mapping for {lhs} to {rhs}
 * noremap[!] {lhs} {rhs}   : same, but no remapping for {rhs}
 * unmap[!] {lhs}	    : remove key mapping for {lhs}
 * abbr			    : show all abbreviations
 * abbr {lhs}		    : show abbreviations for {lhs}
 * abbr {lhs} {rhs}	    : set abbreviation for {lhs} to {rhs}
 * noreabbr {lhs} {rhs}	    : same, but no remapping for {rhs}
 * unabbr {lhs}		    : remove abbreviation for {lhs}
 *
 * maptype: 0 for :map, 1 for :unmap, 2 for noremap.
 *
 * arg is pointer to any arguments. Note: arg cannot be a read-only string,
 * it will be modified.
 *
 * for :map   mode is NORMAL + VISUAL + SELECTMODE + OP_PENDING
 * for :map!  mode is INSERT + CMDLINE
 * for :cmap  mode is CMDLINE
 * for :imap  mode is INSERT
 * for :lmap  mode is LANGMAP
 * for :nmap  mode is NORMAL
 * for :vmap  mode is VISUAL + SELECTMODE
 * for :xmap  mode is VISUAL
 * for :smap  mode is SELECTMODE
 * for :omap  mode is OP_PENDING
 *
 * for :abbr  mode is INSERT + CMDLINE
 * for :iabbr mode is INSERT
 * for :cabbr mode is CMDLINE
 *
 * Return 0 for success
 *	  1 for invalid arguments
 *	  2 for no match
 *	  4 for out of mem
 *	  5 for entry not unique
 */
    int
do_map(maptype, arg, mode, abbrev)
    int		maptype;
    char_u	*arg;
    int		mode;
    int		abbrev;		/* not a mapping but an abbreviation */
{
    char_u	*keys;
    mapblock_T	*mp, **mpp;
    char_u	*rhs;
    char_u	*p;
    int		n;
    int		len = 0;	/* init for GCC */
    char_u	*newstr;
    int		hasarg;
    int		haskey;
    int		did_it = FALSE;
#ifdef FEAT_LOCALMAP
    int		did_local = FALSE;
#endif
    int		round;
    char_u	*keys_buf = NULL;
    char_u	*arg_buf = NULL;
    int		retval = 0;
    int		do_backslash;
    int		hash;
    int		new_hash;
    mapblock_T	**abbr_table;
    mapblock_T	**map_table;
    int		unique = FALSE;
    int		silent = FALSE;
    int		special = FALSE;
#ifdef FEAT_EVAL
    int		expr = FALSE;
#endif
    int		noremap;

    keys = arg;
    map_table = maphash;
    abbr_table = &first_abbr;

    /* For ":noremap" don't remap, otherwise do remap. */
    if (maptype == 2)
	noremap = REMAP_NONE;
    else
	noremap = REMAP_YES;

    /* Accept <buffer>, <silent>, <expr> <script> and <unique> in any order. */
    for (;;)
    {
#ifdef FEAT_LOCALMAP
	/*
	 * Check for "<buffer>": mapping local to buffer.
	 */
	if (STRNCMP(keys, "<buffer>", 8) == 0)
	{
	    keys = skipwhite(keys + 8);
	    map_table = curbuf->b_maphash;
	    abbr_table = &curbuf->b_first_abbr;
	    continue;
	}
#endif

	/*
	 * Check for "<silent>": don't echo commands.
	 */
	if (STRNCMP(keys, "<silent>", 8) == 0)
	{
	    keys = skipwhite(keys + 8);
	    silent = TRUE;
	    continue;
	}

	/*
	 * Check for "<special>": accept special keys in <>
	 */
	if (STRNCMP(keys, "<special>", 9) == 0)
	{
	    keys = skipwhite(keys + 9);
	    special = TRUE;
	    continue;
	}

#ifdef FEAT_EVAL
	/*
	 * Check for "<script>": remap script-local mappings only
	 */
	if (STRNCMP(keys, "<script>", 8) == 0)
	{
	    keys = skipwhite(keys + 8);
	    noremap = REMAP_SCRIPT;
	    continue;
	}

	/*
	 * Check for "<expr>": {rhs} is an expression.
	 */
	if (STRNCMP(keys, "<expr>", 6) == 0)
	{
	    keys = skipwhite(keys + 6);
	    expr = TRUE;
	    continue;
	}
#endif
	/*
	 * Check for "<unique>": don't overwrite an existing mapping.
	 */
	if (STRNCMP(keys, "<unique>", 8) == 0)
	{
	    keys = skipwhite(keys + 8);
	    unique = TRUE;
	    continue;
	}
	break;
    }

    validate_maphash();

    /*
     * find end of keys and skip CTRL-Vs (and backslashes) in it
     * Accept backslash like CTRL-V when 'cpoptions' does not contain 'B'.
     * with :unmap white space is included in the keys, no argument possible
     */
    p = keys;
    do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL);
    while (*p && (maptype == 1 || !vim_iswhite(*p)))
    {
	if ((p[0] == Ctrl_V || (do_backslash && p[0] == '\\')) &&
								  p[1] != NUL)
	    ++p;		/* skip CTRL-V or backslash */
	++p;
    }
    if (*p != NUL)
	*p++ = NUL;
    p = skipwhite(p);
    rhs = p;
    hasarg = (*rhs != NUL);
    haskey = (*keys != NUL);

    /* check for :unmap without argument */
    if (maptype == 1 && !haskey)
    {
	retval = 1;
	goto theend;
    }

    /*
     * If mapping has been given as ^V<C_UP> say, then replace the term codes
     * with the appropriate two bytes. If it is a shifted special key, unshift
     * it too, giving another two bytes.
     * replace_termcodes() may move the result to allocated memory, which
     * needs to be freed later (*keys_buf and *arg_buf).
     * replace_termcodes() also removes CTRL-Vs and sometimes backslashes.
     */
    if (haskey)
	keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, special);
    if (hasarg)
    {
	if (STRICMP(rhs, "<nop>") == 0)	    /* "<Nop>" means nothing */
	    rhs = (char_u *)"";
	else
	    rhs = replace_termcodes(rhs, &arg_buf, FALSE, TRUE, special);
    }

#ifdef FEAT_FKMAP
    /*
     * when in right-to-left mode and alternate keymap option set,
     * reverse the character flow in the rhs in Farsi.
     */
    if (p_altkeymap && curwin->w_p_rl)
	lrswap(rhs);
#endif

    /*
     * check arguments and translate function keys
     */
    if (haskey)
    {
	len = (int)STRLEN(keys);
	if (len > MAXMAPLEN)		/* maximum length of MAXMAPLEN chars */
	{
	    retval = 1;
	    goto theend;
	}

	if (abbrev && maptype != 1)
	{
	    /*
	     * If an abbreviation ends in a keyword character, the
	     * rest must be all keyword-char or all non-keyword-char.
	     * Otherwise we won't be able to find the start of it in a
	     * vi-compatible way.
	     */
#ifdef FEAT_MBYTE
	    if (has_mbyte)
	    {
		int	first, last;
		int	same = -1;

		first = vim_iswordp(keys);
		last = first;
		p = keys + (*mb_ptr2len)(keys);
		n = 1;
		while (p < keys + len)
		{
		    ++n;			/* nr of (multi-byte) chars */
		    last = vim_iswordp(p);	/* type of last char */
		    if (same == -1 && last != first)
			same = n - 1;		/* count of same char type */
		    p += (*mb_ptr2len)(p);
		}
		if (last && n > 2 && same >= 0 && same < n - 1)
		{
		    retval = 1;
		    goto theend;
		}
	    }
	    else
#endif
		if (vim_iswordc(keys[len - 1]))	/* ends in keyword char */
		    for (n = 0; n < len - 2; ++n)
			if (vim_iswordc(keys[n]) != vim_iswordc(keys[len - 2]))
			{
			    retval = 1;
			    goto theend;
			}
	    /* An abbrevation cannot contain white space. */
	    for (n = 0; n < len; ++n)
		if (vim_iswhite(keys[n]))
		{
		    retval = 1;
		    goto theend;
		}
	}
    }

    if (haskey && hasarg && abbrev)	/* if we will add an abbreviation */
	no_abbr = FALSE;		/* reset flag that indicates there are
							    no abbreviations */

    if (!haskey || (maptype != 1 && !hasarg))
	msg_start();

#ifdef FEAT_LOCALMAP
    /*
     * Check if a new local mapping wasn't already defined globally.
     */
    if (map_table == curbuf->b_maphash && haskey && hasarg && maptype != 1)
    {
	/* need to loop over all global hash lists */
	for (hash = 0; hash < 256 && !got_int; ++hash)
	{
	    if (abbrev)
	    {
		if (hash != 0)	/* there is only one abbreviation list */
		    break;
		mp = first_abbr;
	    }
	    else
		mp = maphash[hash];
	    for ( ; mp != NULL && !got_int; mp = mp->m_next)
	    {
		/* check entries with the same mode */
		if ((mp->m_mode & mode) != 0
			&& mp->m_keylen == len
			&& unique
			&& STRNCMP(mp->m_keys, keys, (size_t)len) == 0)
		{
		    if (abbrev)
			EMSG2(_("E224: global abbreviation already exists for %s"),
				mp->m_keys);
		    else
			EMSG2(_("E225: global mapping already exists for %s"),
				mp->m_keys);
		    retval = 5;
		    goto theend;
		}
	    }
	}
    }

    /*
     * When listing global mappings, also list buffer-local ones here.
     */
    if (map_table != curbuf->b_maphash && !hasarg && maptype != 1)
    {
	/* need to loop over all global hash lists */
	for (hash = 0; hash < 256 && !got_int; ++hash)
	{
	    if (abbrev)
	    {
		if (hash != 0)	/* there is only one abbreviation list */
		    break;
		mp = curbuf->b_first_abbr;
	    }
	    else
		mp = curbuf->b_maphash[hash];
	    for ( ; mp != NULL && !got_int; mp = mp->m_next)
	    {
		/* check entries with the same mode */
		if ((mp->m_mode & mode) != 0)
		{
		    if (!haskey)		    /* show all entries */
		    {
			showmap(mp, TRUE);
			did_local = TRUE;
		    }
		    else
		    {
			n = mp->m_keylen;
			if (STRNCMP(mp->m_keys, keys,
					    (size_t)(n < len ? n : len)) == 0)
			{
			    showmap(mp, TRUE);
			    did_local = TRUE;
			}
		    }
		}
	    }
	}
    }
#endif

    /*
     * Find an entry in the maphash[] list that matches.
     * For :unmap we may loop two times: once to try to unmap an entry with a
     * matching 'from' part, a second time, if the first fails, to unmap an
     * entry with a matching 'to' part. This was done to allow ":ab foo bar"
     * to be unmapped by typing ":unab foo", where "foo" will be replaced by
     * "bar" because of the abbreviation.
     */
    for (round = 0; (round == 0 || maptype == 1) && round <= 1
					      && !did_it && !got_int; ++round)
    {
	/* need to loop over all hash lists */
	for (hash = 0; hash < 256 && !got_int; ++hash)
	{
	    if (abbrev)
	    {
		if (hash > 0)	/* there is only one abbreviation list */
		    break;
		mpp = abbr_table;
	    }
	    else
		mpp = &(map_table[hash]);
	    for (mp = *mpp; mp != NULL && !got_int; mp = *mpp)
	    {

		if (!(mp->m_mode & mode))   /* skip entries with wrong mode */
		{
		    mpp = &(mp->m_next);
		    continue;
		}
		if (!haskey)		    /* show all entries */
		{
		    showmap(mp, map_table != maphash);
		    did_it = TRUE;
		}
		else			    /* do we have a match? */
		{
		    if (round)	    /* second round: Try unmap "rhs" string */
		    {
			n = (int)STRLEN(mp->m_str);
			p = mp->m_str;
		    }
		    else
		    {
			n = mp->m_keylen;
			p = mp->m_keys;
		    }
		    if (STRNCMP(p, keys, (size_t)(n < len ? n : len)) == 0)
		    {
			if (maptype == 1)	/* delete entry */
			{
			    /* Only accept a full match.  For abbreviations we
			     * ignore trailing space when matching with the
			     * "lhs", since an abbreviation can't have
			     * trailing space. */
			    if (n != len && (!abbrev || round || n > len
					       || *skipwhite(keys + n) != NUL))
			    {
				mpp = &(mp->m_next);
				continue;
			    }
			    /*
			     * We reset the indicated mode bits. If nothing is
			     * left the entry is deleted below.
			     */
			    mp->m_mode &= ~mode;
			    did_it = TRUE;	/* remember we did something */
			}
			else if (!hasarg)	/* show matching entry */
			{
			    showmap(mp, map_table != maphash);
			    did_it = TRUE;
			}
			else if (n != len)	/* new entry is ambigious */
			{
			    mpp = &(mp->m_next);
			    continue;
			}
			else if (unique)
			{
			    if (abbrev)
				EMSG2(_("E226: abbreviation already exists for %s"),
									   p);
			    else
				EMSG2(_("E227: mapping already exists for %s"), p);
			    retval = 5;
			    goto theend;
			}
			else			/* new rhs for existing entry */
			{
			    mp->m_mode &= ~mode;	/* remove mode bits */
			    if (mp->m_mode == 0 && !did_it) /* reuse entry */
			    {
				newstr = vim_strsave(rhs);
				if (newstr == NULL)
				{
				    retval = 4;		/* no mem */
				    goto theend;
				}
				vim_free(mp->m_str);
				mp->m_str = newstr;
				mp->m_noremap = noremap;
				mp->m_silent = silent;
				mp->m_mode = mode;
#ifdef FEAT_EVAL
				mp->m_expr = expr;
				mp->m_script_ID = current_SID;
#endif
				did_it = TRUE;
			    }
			}
			if (mp->m_mode == 0)	/* entry can be deleted */
			{
			    map_free(mpp);
			    continue;		/* continue with *mpp */
			}

			/*
			 * May need to put this entry into another hash list.
			 */
			new_hash = MAP_HASH(mp->m_mode, mp->m_keys[0]);
			if (!abbrev && new_hash != hash)
			{
			    *mpp = mp->m_next;
			    mp->m_next = map_table[new_hash];
			    map_table[new_hash] = mp;

			    continue;		/* continue with *mpp */
			}
		    }
		}
		mpp = &(mp->m_next);
	    }
	}
    }

    if (maptype == 1)			    /* delete entry */
    {
	if (!did_it)
	    retval = 2;			    /* no match */
	goto theend;
    }

    if (!haskey || !hasarg)		    /* print entries */
    {
	if (!did_it
#ifdef FEAT_LOCALMAP
		&& !did_local
#endif
		)
	{
	    if (abbrev)
		MSG(_("No abbreviation found"));
	    else
		MSG(_("No mapping found"));
	}
	goto theend;			    /* listing finished */
    }

    if (did_it)			/* have added the new entry already */
	goto theend;

    /*
     * Get here when adding a new entry to the maphash[] list or abbrlist.
     */
    mp = (mapblock_T *)alloc((unsigned)sizeof(mapblock_T));
    if (mp == NULL)
    {
	retval = 4;	    /* no mem */
	goto theend;
    }

    /* If CTRL-C has been mapped, don't always use it for Interrupting */
    if (*keys == Ctrl_C)
	mapped_ctrl_c = TRUE;

    mp->m_keys = vim_strsave(keys);
    mp->m_str = vim_strsave(rhs);
    if (mp->m_keys == NULL || mp->m_str == NULL)
    {
	vim_free(mp->m_keys);
	vim_free(mp->m_str);
	vim_free(mp);
	retval = 4;	/* no mem */
	goto theend;
    }
    mp->m_keylen = (int)STRLEN(mp->m_keys);
    mp->m_noremap = noremap;
    mp->m_silent = silent;
    mp->m_mode = mode;
#ifdef FEAT_EVAL
    mp->m_expr = expr;
    mp->m_script_ID = current_SID;
#endif

    /* add the new entry in front of the abbrlist or maphash[] list */
    if (abbrev)
    {
	mp->m_next = *abbr_table;
	*abbr_table = mp;
    }
    else
    {
	n = MAP_HASH(mp->m_mode, mp->m_keys[0]);
	mp->m_next = map_table[n];
	map_table[n] = mp;
    }

theend:
    vim_free(keys_buf);
    vim_free(arg_buf);
    return retval;
}

/*
 * Delete one entry from the abbrlist or maphash[].
 * "mpp" is a pointer to the m_next field of the PREVIOUS entry!
 */
    static void
map_free(mpp)
    mapblock_T	**mpp;
{
    mapblock_T	*mp;

    mp = *mpp;
    vim_free(mp->m_keys);
    vim_free(mp->m_str);
    *mpp = mp->m_next;
    vim_free(mp);
}

/*
 * Initialize maphash[] for first use.
 */
    static void
validate_maphash()
{
    if (!maphash_valid)
    {
	vim_memset(maphash, 0, sizeof(maphash));
	maphash_valid = TRUE;
    }
}

/*
 * Get the mapping mode from the command name.
 */
    int
get_map_mode(cmdp, forceit)
    char_u	**cmdp;
    int		forceit;
{
    char_u	*p;
    int		modec;
    int		mode;

    p = *cmdp;
    modec = *p++;
    if (modec == 'i')
	mode = INSERT;				/* :imap */
    else if (modec == 'l')
	mode = LANGMAP;				/* :lmap */
    else if (modec == 'c')
	mode = CMDLINE;				/* :cmap */
    else if (modec == 'n' && *p != 'o')		    /* avoid :noremap */
	mode = NORMAL;				/* :nmap */
    else if (modec == 'v')
	mode = VISUAL + SELECTMODE;		/* :vmap */
    else if (modec == 'x')
	mode = VISUAL;				/* :xmap */
    else if (modec == 's')
	mode = SELECTMODE;			/* :smap */
    else if (modec == 'o')
	mode = OP_PENDING;			/* :omap */
    else
    {
	--p;
	if (forceit)
	    mode = INSERT + CMDLINE;		/* :map ! */
	else
	    mode = VISUAL + SELECTMODE + NORMAL + OP_PENDING;/* :map */
    }

    *cmdp = p;
    return mode;
}

/*
 * Clear all mappings or abbreviations.
 * 'abbr' should be FALSE for mappings, TRUE for abbreviations.
 */
/*ARGSUSED*/
    void
map_clear(cmdp, arg, forceit, abbr)
    char_u	*cmdp;
    char_u	*arg;
    int		forceit;
    int		abbr;
{
    int		mode;
#ifdef FEAT_LOCALMAP
    int		local;

    local = (STRCMP(arg, "<buffer>") == 0);
    if (!local && *arg != NUL)
    {
	EMSG(_(e_invarg));
	return;
    }
#endif

    mode = get_map_mode(&cmdp, forceit);
    map_clear_int(curbuf, mode,
#ifdef FEAT_LOCALMAP
	    local,
#else
	    FALSE,
#endif
	    abbr);
}

/*
 * Clear all mappings in "mode".
 */
/*ARGSUSED*/
    void
map_clear_int(buf, mode, local, abbr)
    buf_T	*buf;	    /* buffer for local mappings */
    int		mode;	    /* mode in which to delete */
    int		local;	    /* TRUE for buffer-local mappings */
    int		abbr;	    /* TRUE for abbreviations */
{
    mapblock_T	*mp, **mpp;
    int		hash;
    int		new_hash;

    validate_maphash();

    for (hash = 0; hash < 256; ++hash)
    {
	if (abbr)
	{
	    if (hash > 0)	/* there is only one abbrlist */
		break;
#ifdef FEAT_LOCALMAP
	    if (local)
		mpp = &buf->b_first_abbr;
	    else
#endif
		mpp = &first_abbr;
	}
	else
	{
#ifdef FEAT_LOCALMAP
	    if (local)
		mpp = &buf->b_maphash[hash];
	    else
#endif
		mpp = &maphash[hash];
	}
	while (*mpp != NULL)
	{
	    mp = *mpp;
	    if (mp->m_mode & mode)
	    {
		mp->m_mode &= ~mode;
		if (mp->m_mode == 0) /* entry can be deleted */
		{
		    map_free(mpp);
		    continue;
		}
		/*
		 * May need to put this entry into another hash list.
		 */
		new_hash = MAP_HASH(mp->m_mode, mp->m_keys[0]);
		if (!abbr && new_hash != hash)
		{
		    *mpp = mp->m_next;
#ifdef FEAT_LOCALMAP
		    if (local)
		    {
			mp->m_next = buf->b_maphash[new_hash];
			buf->b_maphash[new_hash] = mp;
		    }
		    else
#endif
		    {
			mp->m_next = maphash[new_hash];
			maphash[new_hash] = mp;
		    }
		    continue;		/* continue with *mpp */
		}
	    }
	    mpp = &(mp->m_next);
	}
    }
}

    static void
showmap(mp, local)
    mapblock_T	*mp;
    int		local;	    /* TRUE for buffer-local map */
{
    int len = 1;

    if (msg_didout || msg_silent != 0)
	msg_putchar('\n');
    if ((mp->m_mode & (INSERT + CMDLINE)) == INSERT + CMDLINE)
	msg_putchar('!');			/* :map! */
    else if (mp->m_mode & INSERT)
	msg_putchar('i');			/* :imap */
    else if (mp->m_mode & LANGMAP)
	msg_putchar('l');			/* :lmap */
    else if (mp->m_mode & CMDLINE)
	msg_putchar('c');			/* :cmap */
    else if ((mp->m_mode & (NORMAL + VISUAL + SELECTMODE + OP_PENDING))
				 == NORMAL + VISUAL + SELECTMODE + OP_PENDING)
	msg_putchar(' ');			/* :map */
    else
    {
	len = 0;
	if (mp->m_mode & NORMAL)
	{
	    msg_putchar('n');		/* :nmap */
	    ++len;
	}
	if (mp->m_mode & OP_PENDING)
	{
	    msg_putchar('o');		/* :omap */
	    ++len;
	}
	if ((mp->m_mode & (VISUAL + SELECTMODE)) == VISUAL + SELECTMODE)
	{
	    msg_putchar('v');		/* :vmap */
	    ++len;
	}
	else
	{
	    if (mp->m_mode & VISUAL)
	    {
		msg_putchar('x');		/* :xmap */
		++len;
	    }
	    if (mp->m_mode & SELECTMODE)
	    {
		msg_putchar('s');		/* :smap */
		++len;
	    }
	}
    }
    while (++len <= 3)
	msg_putchar(' ');

    /* Get length of what we write */
    len = msg_outtrans_special(mp->m_keys, TRUE);
    do
    {
	msg_putchar(' ');		/* padd with blanks */
	++len;
    } while (len < 12);

    if (mp->m_noremap == REMAP_NONE)
	msg_puts_attr((char_u *)"*", hl_attr(HLF_8));
    else if (mp->m_noremap == REMAP_SCRIPT)
	msg_puts_attr((char_u *)"&", hl_attr(HLF_8));
    else
	msg_putchar(' ');

    if (local)
	msg_putchar('@');
    else
	msg_putchar(' ');

    /* Use FALSE below if we only want things like <Up> to show up as such on
     * the rhs, and not M-x etc, TRUE gets both -- webb
     */
    if (*mp->m_str == NUL)
	msg_puts_attr((char_u *)"<Nop>", hl_attr(HLF_8));
    else
	msg_outtrans_special(mp->m_str, FALSE);
#ifdef FEAT_EVAL
    if (p_verbose > 0)
	last_set_msg(mp->m_script_ID);
#endif
    out_flush();			/* show one line at a time */
}

#if defined(FEAT_EVAL) || defined(PROTO)
/*
 * Return TRUE if a map exists that has "str" in the rhs for mode "modechars".
 * Recognize termcap codes in "str".
 * Also checks mappings local to the current buffer.
 */
    int
map_to_exists(str, modechars, abbr)
    char_u	*str;
    char_u	*modechars;
    int		abbr;
{
    int		mode = 0;
    char_u	*rhs;
    char_u	*buf;
    int		retval;

    rhs = replace_termcodes(str, &buf, FALSE, TRUE, FALSE);

    if (vim_strchr(modechars, 'n') != NULL)
	mode |= NORMAL;
    if (vim_strchr(modechars, 'v') != NULL)
	mode |= VISUAL + SELECTMODE;
    if (vim_strchr(modechars, 'x') != NULL)
	mode |= VISUAL;
    if (vim_strchr(modechars, 's') != NULL)
	mode |= SELECTMODE;
    if (vim_strchr(modechars, 'o') != NULL)
	mode |= OP_PENDING;
    if (vim_strchr(modechars, 'i') != NULL)
	mode |= INSERT;
    if (vim_strchr(modechars, 'l') != NULL)
	mode |= LANGMAP;
    if (vim_strchr(modechars, 'c') != NULL)
	mode |= CMDLINE;

    retval = map_to_exists_mode(rhs, mode, abbr);
    vim_free(buf);

    return retval;
}
#endif

/*
 * Return TRUE if a map exists that has "str" in the rhs for mode "mode".
 * Also checks mappings local to the current buffer.
 */
    int
map_to_exists_mode(rhs, mode, abbr)
    char_u	*rhs;
    int		mode;
    int		abbr;
{
    mapblock_T	*mp;
    int		hash;
# ifdef FEAT_LOCALMAP
    int		expand_buffer = FALSE;

    validate_maphash();

    /* Do it twice: once for global maps and once for local maps. */
    for (;;)
    {
# endif
	for (hash = 0; hash < 256; ++hash)
	{
	    if (abbr)
	    {
		if (hash > 0)		/* there is only one abbr list */
		    break;
#ifdef FEAT_LOCALMAP
		if (expand_buffer)
		    mp = curbuf->b_first_abbr;
		else
#endif
		    mp = first_abbr;
	    }
# ifdef FEAT_LOCALMAP
	    else if (expand_buffer)
		mp = curbuf->b_maphash[hash];
# endif
	    else
		mp = maphash[hash];
	    for (; mp; mp = mp->m_next)
	    {
		if ((mp->m_mode & mode)
			&& strstr((char *)mp->m_str, (char *)rhs) != NULL)
		    return TRUE;
	    }
	}
# ifdef FEAT_LOCALMAP
	if (expand_buffer)
	    break;
	expand_buffer = TRUE;
    }
# endif

    return FALSE;
}

#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
/*
 * Used below when expanding mapping/abbreviation names.
 */
static int	expand_mapmodes = 0;
static int	expand_isabbrev = 0;
#ifdef FEAT_LOCALMAP
static int	expand_buffer = FALSE;
#endif

/*
 * Work out what to complete when doing command line completion of mapping
 * or abbreviation names.
 */
    char_u *
set_context_in_map_cmd(xp, cmd, arg, forceit, isabbrev, isunmap, cmdidx)
    expand_T	*xp;
    char_u	*cmd;
    char_u	*arg;
    int		forceit;	/* TRUE if '!' given */
    int		isabbrev;	/* TRUE if abbreviation */
    int		isunmap;	/* TRUE if unmap/unabbrev command */
    cmdidx_T	cmdidx;
{
    if (forceit && cmdidx != CMD_map && cmdidx != CMD_unmap)
	xp->xp_context = EXPAND_NOTHING;
    else
    {
	if (isunmap)
	    expand_mapmodes = get_map_mode(&cmd, forceit || isabbrev);
	else
	{
	    expand_mapmodes = INSERT + CMDLINE;
	    if (!isabbrev)
		expand_mapmodes += VISUAL + SELECTMODE + NORMAL + OP_PENDING;
	}
	expand_isabbrev = isabbrev;
	xp->xp_context = EXPAND_MAPPINGS;
#ifdef FEAT_LOCALMAP
	expand_buffer = FALSE;
#endif
	for (;;)
	{
#ifdef FEAT_LOCALMAP
	    if (STRNCMP(arg, "<buffer>", 8) == 0)
	    {
		expand_buffer = TRUE;
		arg = skipwhite(arg + 8);
		continue;
	    }
#endif
	    if (STRNCMP(arg, "<unique>", 8) == 0)
	    {
		arg = skipwhite(arg + 8);
		continue;
	    }
	    if (STRNCMP(arg, "<silent>", 8) == 0)
	    {
		arg = skipwhite(arg + 8);
		continue;
	    }
#ifdef FEAT_EVAL
	    if (STRNCMP(arg, "<script>", 8) == 0)
	    {
		arg = skipwhite(arg + 8);
		continue;
	    }
	    if (STRNCMP(arg, "<expr>", 6) == 0)
	    {
		arg = skipwhite(arg + 6);
		continue;
	    }
#endif
	    break;
	}
	xp->xp_pattern = arg;
    }

    return NULL;
}

/*
 * Find all mapping/abbreviation names that match regexp 'prog'.
 * For command line expansion of ":[un]map" and ":[un]abbrev" in all modes.
 * Return OK if matches found, FAIL otherwise.
 */
    int
ExpandMappings(regmatch, num_file, file)
    regmatch_T	*regmatch;
    int		*num_file;
    char_u	***file;
{
    mapblock_T	*mp;
    int		hash;
    int		count;
    int		round;
    char_u	*p;
    int		i;

    validate_maphash();

    *num_file = 0;		    /* return values in case of FAIL */
    *file = NULL;

    /*
     * round == 1: Count the matches.
     * round == 2: Build the array to keep the matches.
     */
    for (round = 1; round <= 2; ++round)
    {
	count = 0;

	for (i = 0; i < 5; ++i)
	{
	    if (i == 0)
		p = (char_u *)"<silent>";
	    else if (i == 1)
		p = (char_u *)"<unique>";
#ifdef FEAT_EVAL
	    else if (i == 2)
		p = (char_u *)"<script>";
	    else if (i == 3)
		p = (char_u *)"<expr>";
#endif
#ifdef FEAT_LOCALMAP
	    else if (i == 4 && !expand_buffer)
		p = (char_u *)"<buffer>";
#endif
	    else
		continue;

	    if (vim_regexec(regmatch, p, (colnr_T)0))
	    {
		if (round == 1)
		    ++count;
		else
		    (*file)[count++] = vim_strsave(p);
	    }
	}

	for (hash = 0; hash < 256; ++hash)
	{
	    if (expand_isabbrev)
	    {
		if (hash > 0)	/* only one abbrev list */
		    break; /* for (hash) */
		mp = first_abbr;
	    }
#ifdef FEAT_LOCALMAP
	    else if (expand_buffer)
		mp = curbuf->b_maphash[hash];
#endif
	    else
		mp = maphash[hash];
	    for (; mp; mp = mp->m_next)
	    {
		if (mp->m_mode & expand_mapmodes)
		{
		    p = translate_mapping(mp->m_keys, TRUE);
		    if (p != NULL && vim_regexec(regmatch, p, (colnr_T)0))
		    {
			if (round == 1)
			    ++count;
			else
			{
			    (*file)[count++] = p;
			    p = NULL;
			}
		    }
		    vim_free(p);
		}
	    } /* for (mp) */
	} /* for (hash) */

	if (count == 0)			/* no match found */
	    break; /* for (round) */

	if (round == 1)
	{
	    *file = (char_u **)alloc((unsigned)(count * sizeof(char_u *)));
	    if (*file == NULL)
		return FAIL;
	}
    } /* for (round) */

    if (count > 1)
    {
	char_u	**ptr1;
	char_u	**ptr2;
	char_u	**ptr3;

	/* Sort the matches */
	sort_strings(*file, count);

	/* Remove multiple entries */
	ptr1 = *file;
	ptr2 = ptr1 + 1;
	ptr3 = ptr1 + count;

	while (ptr2 < ptr3)
	{
	    if (STRCMP(*ptr1, *ptr2))
		*++ptr1 = *ptr2++;
	    else
	    {
		vim_free(*ptr2++);
		count--;
	    }
	}
    }

    *num_file = count;
    return (count == 0 ? FAIL : OK);
}
#endif /* FEAT_CMDL_COMPL */

/*
 * Check for an abbreviation.
 * Cursor is at ptr[col]. When inserting, mincol is where insert started.
 * "c" is the character typed before check_abbr was called.  It may have
 * ABBR_OFF added to avoid prepending a CTRL-V to it.
 *
 * Historic vi practice: The last character of an abbreviation must be an id
 * character ([a-zA-Z0-9_]). The characters in front of it must be all id
 * characters or all non-id characters. This allows for abbr. "#i" to
 * "#include".
 *
 * Vim addition: Allow for abbreviations that end in a non-keyword character.
 * Then there must be white space before the abbr.
 *
 * return TRUE if there is an abbreviation, FALSE if not
 */
    int
check_abbr(c, ptr, col, mincol)
    int		c;
    char_u	*ptr;
    int		col;
    int		mincol;
{
    int		len;
    int		scol;		/* starting column of the abbr. */
    int		j;
    char_u	*s;
#ifdef FEAT_MBYTE
    char_u	tb[MB_MAXBYTES + 4];
#else
    char_u	tb[4];
#endif
    mapblock_T	*mp;
#ifdef FEAT_LOCALMAP
    mapblock_T	*mp2;
#endif
#ifdef FEAT_MBYTE
    int		clen = 0;	/* length in characters */
#endif
    int		is_id = TRUE;
    int		vim_abbr;

    if (typebuf.tb_no_abbr_cnt)	/* abbrev. are not recursive */
	return FALSE;
    if ((KeyNoremap & (RM_NONE|RM_SCRIPT)) != 0)
	/* no remapping implies no abbreviation */
	return FALSE;

    /*
     * Check for word before the cursor: If it ends in a keyword char all
     * chars before it must be al keyword chars or non-keyword chars, but not
     * white space. If it ends in a non-keyword char we accept any characters
     * before it except white space.
     */
    if (col == 0)				/* cannot be an abbr. */
	return FALSE;

#ifdef FEAT_MBYTE
    if (has_mbyte)
    {
	char_u *p;

	p = mb_prevptr(ptr, ptr + col);
	if (!vim_iswordp(p))
	    vim_abbr = TRUE;			/* Vim added abbr. */
	else
	{
	    vim_abbr = FALSE;			/* vi compatible abbr. */
	    if (p > ptr)
		is_id = vim_iswordp(mb_prevptr(ptr, p));
	}
	clen = 1;
	while (p > ptr + mincol)
	{
	    p = mb_prevptr(ptr, p);
	    if (vim_isspace(*p) || (!vim_abbr && is_id != vim_iswordp(p)))
	    {
		p += (*mb_ptr2len)(p);
		break;
	    }
	    ++clen;
	}
	scol = (int)(p - ptr);
    }
    else
#endif
    {
	if (!vim_iswordc(ptr[col - 1]))
	    vim_abbr = TRUE;			/* Vim added abbr. */
	else
	{
	    vim_abbr = FALSE;			/* vi compatible abbr. */
	    if (col > 1)
		is_id = vim_iswordc(ptr[col - 2]);
	}
	for (scol = col - 1; scol > 0 && !vim_isspace(ptr[scol - 1])
		&& (vim_abbr || is_id == vim_iswordc(ptr[scol - 1])); --scol)
	    ;
    }

    if (scol < mincol)
	scol = mincol;
    if (scol < col)		/* there is a word in front of the cursor */
    {
	ptr += scol;
	len = col - scol;
#ifdef FEAT_LOCALMAP
	mp = curbuf->b_first_abbr;
	mp2 = first_abbr;
	if (mp == NULL)
	{
	    mp = mp2;
	    mp2 = NULL;
	}
#else
	mp = first_abbr;
#endif
	for ( ; mp;
#ifdef FEAT_LOCALMAP
		mp->m_next == NULL ? (mp = mp2, mp2 = NULL) :
#endif
		(mp = mp->m_next))
	{
	    /* find entries with right mode and keys */
	    if (       (mp->m_mode & State)
		    && mp->m_keylen == len
		    && !STRNCMP(mp->m_keys, ptr, (size_t)len))
		break;
	}
	if (mp != NULL)
	{
	    /*
	     * Found a match:
	     * Insert the rest of the abbreviation in typebuf.tb_buf[].
	     * This goes from end to start.
	     *
	     * Characters 0x000 - 0x100: normal chars, may need CTRL-V,
	     * except K_SPECIAL: Becomes K_SPECIAL KS_SPECIAL KE_FILLER
	     * Characters where IS_SPECIAL() == TRUE: key codes, need
	     * K_SPECIAL. Other characters (with ABBR_OFF): don't use CTRL-V.
	     *
	     * Character CTRL-] is treated specially - it completes the
	     * abbreviation, but is not inserted into the input stream.
	     */
	    j = 0;
					/* special key code, split up */
	    if (c != Ctrl_RSB)
	    {
		if (IS_SPECIAL(c) || c == K_SPECIAL)
		{
		    tb[j++] = K_SPECIAL;
		    tb[j++] = K_SECOND(c);
		    tb[j++] = K_THIRD(c);
		}
		else
		{
		    if (c < ABBR_OFF && (c < ' ' || c > '~'))
			tb[j++] = Ctrl_V;	/* special char needs CTRL-V */
#ifdef FEAT_MBYTE
		    if (has_mbyte)
		    {
			/* if ABBR_OFF has been added, remove it here */
			if (c >= ABBR_OFF)
			    c -= ABBR_OFF;
			j += (*mb_char2bytes)(c, tb + j);
		    }
		    else
#endif
			tb[j++] = c;
		}
		tb[j] = NUL;
					/* insert the last typed char */
		(void)ins_typebuf(tb, 1, 0, TRUE, mp->m_silent);
	    }
#ifdef FEAT_EVAL
	    if (mp->m_expr)
		s = eval_map_expr(mp->m_str);
	    else
#endif
		s = mp->m_str;
	    if (s != NULL)
	    {
					/* insert the to string */
		(void)ins_typebuf(s, mp->m_noremap, 0, TRUE, mp->m_silent);
					/* no abbrev. for these chars */
		typebuf.tb_no_abbr_cnt += (int)STRLEN(s) + j + 1;
#ifdef FEAT_EVAL
		if (mp->m_expr)
		    vim_free(s);
#endif
	    }

	    tb[0] = Ctrl_H;
	    tb[1] = NUL;
#ifdef FEAT_MBYTE
	    if (has_mbyte)
		len = clen;	/* Delete characters instead of bytes */
#endif
	    while (len-- > 0)		/* delete the from string */
		(void)ins_typebuf(tb, 1, 0, TRUE, mp->m_silent);
	    return TRUE;
	}
    }
    return FALSE;
}

#ifdef FEAT_EVAL
/*
 * Evaluate the RHS of a mapping or abbreviations and take care of escaping
 * special characters.
 */
    static char_u *
eval_map_expr(str)
    char_u	*str;
{
    char_u	*res;
    char_u	*p;
    char_u	*save_cmd;
    pos_T	save_cursor;

    save_cmd = save_cmdline_alloc();
    if (save_cmd == NULL)
	return NULL;

    /* Forbid changing text or using ":normal" to avoid most of the bad side
     * effects.  Also restore the cursor position. */
    ++textlock;
#ifdef FEAT_EX_EXTRA
    ++ex_normal_lock;
#endif
    save_cursor = curwin->w_cursor;
    p = eval_to_string(str, NULL, FALSE);
    --textlock;
#ifdef FEAT_EX_EXTRA
    --ex_normal_lock;
#endif
    curwin->w_cursor = save_cursor;

    restore_cmdline_alloc(save_cmd);
    if (p == NULL)
	return NULL;
    res = vim_strsave_escape_csi(p);
    vim_free(p);

    return res;
}
#endif

/*
 * Copy "p" to allocated memory, escaping K_SPECIAL and CSI so that the result
 * can be put in the typeahead buffer.
 * Returns NULL when out of memory.
 */
    char_u *
vim_strsave_escape_csi(p)
    char_u *p;
{
    char_u	*res;
    char_u	*s, *d;

    /* Need a buffer to hold up to three times as much. */
    res = alloc((unsigned)(STRLEN(p) * 3) + 1);
    if (res != NULL)
    {
	d = res;
	for (s = p; *s != NUL; )
	{
	    if (s[0] == K_SPECIAL && s[1] != NUL && s[2] != NUL)
	    {
		/* Copy special key unmodified. */
		*d++ = *s++;
		*d++ = *s++;
		*d++ = *s++;
	    }
	    else
	    {
		/* Add character, possibly multi-byte to destination, escaping
		 * CSI and K_SPECIAL. */
		d = add_char2buf(PTR2CHAR(s), d);
		mb_ptr_adv(s);
	    }
	}
	*d = NUL;
    }
    return res;
}

/*
 * Write map commands for the current mappings to an .exrc file.
 * Return FAIL on error, OK otherwise.
 */
    int
makemap(fd, buf)
    FILE	*fd;
    buf_T	*buf;	    /* buffer for local mappings or NULL */
{
    mapblock_T	*mp;
    char_u	c1, c2;
    char_u	*p;
    char	*cmd;
    int		abbr;
    int		hash;
    int		did_cpo = FALSE;
    int		i;

    validate_maphash();

    /*
     * Do the loop twice: Once for mappings, once for abbreviations.
     * Then loop over all map hash lists.
     */
    for (abbr = 0; abbr < 2; ++abbr)
	for (hash = 0; hash < 256; ++hash)
	{
	    if (abbr)
	    {
		if (hash > 0)		/* there is only one abbr list */
		    break;
#ifdef FEAT_LOCALMAP
		if (buf != NULL)
		    mp = buf->b_first_abbr;
		else
#endif
		    mp = first_abbr;
	    }
	    else
	    {
#ifdef FEAT_LOCALMAP
		if (buf != NULL)
		    mp = buf->b_maphash[hash];
		else
#endif
		    mp = maphash[hash];
	    }

	    for ( ; mp; mp = mp->m_next)
	    {
		/* skip script-local mappings */
		if (mp->m_noremap == REMAP_SCRIPT)
		    continue;

		/* skip mappings that contain a <SNR> (script-local thing),
		 * they probably don't work when loaded again */
		for (p = mp->m_str; *p != NUL; ++p)
		    if (p[0] == K_SPECIAL && p[1] == KS_EXTRA
						       && p[2] == (int)KE_SNR)
			break;
		if (*p != NUL)
		    continue;

		c1 = NUL;
		c2 = NUL;
		if (abbr)
		    cmd = "abbr";
		else
		    cmd = "map";
		switch (mp->m_mode)
		{
		    case NORMAL + VISUAL + SELECTMODE + OP_PENDING:
			break;
		    case NORMAL:
			c1 = 'n';
			break;
		    case VISUAL + SELECTMODE:
			c1 = 'v';
			break;
		    case VISUAL:
			c1 = 'x';
			break;
		    case SELECTMODE:
			c1 = 's';
			break;
		    case OP_PENDING:
			c1 = 'o';
			break;
		    case NORMAL + VISUAL + SELECTMODE:
			c1 = 'n';
			c2 = 'v';
			break;
		    case VISUAL + SELECTMODE + OP_PENDING:
			c1 = 'v';
			c2 = 'o';
			break;
		    case NORMAL + OP_PENDING:
			c1 = 'n';
			c2 = 'o';
			break;
		    case CMDLINE + INSERT:
			if (!abbr)
			    cmd = "map!";
			break;
		    case CMDLINE:
			c1 = 'c';
			break;
		    case INSERT:
			c1 = 'i';
			break;
		    case LANGMAP:
			c1 = 'l';
			break;
		    default:
			EMSG(_("E228: makemap: Illegal mode"));
			return FAIL;
		}
		do	/* may do this twice if c2 is set */
		{
		    /* When outputting <> form, need to make sure that 'cpo'
		     * is set to the Vim default. */
		    if (!did_cpo)
		    {
			if (*mp->m_str == NUL)		/* will use <Nop> */
			    did_cpo = TRUE;
			else
			    for (i = 0; i < 2; ++i)
				for (p = (i ? mp->m_str : mp->m_keys); *p; ++p)
				    if (*p == K_SPECIAL || *p == NL)
					did_cpo = TRUE;
			if (did_cpo)
			{
			    if (fprintf(fd, "let s:cpo_save=&cpo") < 0
				    || put_eol(fd) < 0
				    || fprintf(fd, "set cpo&vim") < 0
				    || put_eol(fd) < 0)
				return FAIL;
			}
		    }
		    if (c1 && putc(c1, fd) < 0)
			return FAIL;
		    if (mp->m_noremap != REMAP_YES && fprintf(fd, "nore") < 0)
			return FAIL;
		    if (fprintf(fd, cmd) < 0)
			return FAIL;
		    if (buf != NULL && fputs(" <buffer>", fd) < 0)
			return FAIL;
		    if (mp->m_silent && fputs(" <silent>", fd) < 0)
			return FAIL;
#ifdef FEAT_EVAL
		    if (mp->m_noremap == REMAP_SCRIPT
						 && fputs("<script>", fd) < 0)
			return FAIL;
		    if (mp->m_expr && fputs(" <expr>", fd) < 0)
			return FAIL;
#endif

		    if (       putc(' ', fd) < 0
			    || put_escstr(fd, mp->m_keys, 0) == FAIL
			    || putc(' ', fd) < 0
			    || put_escstr(fd, mp->m_str, 1) == FAIL
			    || put_eol(fd) < 0)
			return FAIL;
		    c1 = c2;
		    c2 = NUL;
		}
		while (c1);
	    }
	}

    if (did_cpo)
	if (fprintf(fd, "let &cpo=s:cpo_save") < 0
		|| put_eol(fd) < 0
		|| fprintf(fd, "unlet s:cpo_save") < 0
		|| put_eol(fd) < 0)
	    return FAIL;
    return OK;
}

/*
 * write escape string to file
 * "what": 0 for :map lhs, 1 for :map rhs, 2 for :set
 *
 * return FAIL for failure, OK otherwise
 */
    int
put_escstr(fd, strstart, what)
    FILE	*fd;
    char_u	*strstart;
    int		what;
{
    char_u	*str = strstart;
    int		c;
    int		modifiers;

    /* :map xx <Nop> */
    if (*str == NUL && what == 1)
    {
	if (fprintf(fd, "<Nop>") < 0)
	    return FAIL;
	return OK;
    }

    for ( ; *str != NUL; ++str)
    {
#ifdef FEAT_MBYTE
	char_u	*p;

	/* Check for a multi-byte character, which may contain escaped
	 * K_SPECIAL and CSI bytes */
	p = mb_unescape(&str);
	if (p != NULL)
	{
	    while (*p != NUL)
		if (fputc(*p++, fd) < 0)
		    return FAIL;
	    --str;
	    continue;
	}
#endif

	c = *str;
	/*
	 * Special key codes have to be translated to be able to make sense
	 * when they are read back.
	 */
	if (c == K_SPECIAL && what != 2)
	{
	    modifiers = 0x0;
	    if (str[1] == KS_MODIFIER)
	    {
		modifiers = str[2];
		str += 3;
		c = *str;
	    }
	    if (c == K_SPECIAL)
	    {
		c = TO_SPECIAL(str[1], str[2]);
		str += 2;
	    }
	    if (IS_SPECIAL(c) || modifiers)	/* special key */
	    {
		if (fprintf(fd, (char *)get_special_key_name(c, modifiers)) < 0)
		    return FAIL;
		continue;
	    }
	}

	/*
	 * A '\n' in a map command should be written as <NL>.
	 * A '\n' in a set command should be written as \^V^J.
	 */
	if (c == NL)
	{
	    if (what == 2)
	    {
		if (fprintf(fd, IF_EB("\\\026\n", "\\" CTRL_V_STR "\n")) < 0)
		    return FAIL;
	    }
	    else
	    {
		if (fprintf(fd, "<NL>") < 0)
		    return FAIL;
	    }
	    continue;
	}

	/*
	 * Some characters have to be escaped with CTRL-V to
	 * prevent them from misinterpreted in DoOneCmd().
	 * A space, Tab and '"' has to be escaped with a backslash to
	 * prevent it to be misinterpreted in do_set().
	 * A space has to be escaped with a CTRL-V when it's at the start of a
	 * ":map" rhs.
	 * A '<' has to be escaped with a CTRL-V to prevent it being
	 * interpreted as the start of a special key name.
	 * A space in the lhs of a :map needs a CTRL-V.
	 */
	if (what == 2 && (vim_iswhite(c) || c == '"' || c == '\\'))
	{
	    if (putc('\\', fd) < 0)
		return FAIL;
	}
	else if (c < ' ' || c > '~' || c == '|'
		|| (what == 0 && c == ' ')
		|| (what == 1 && str == strstart && c == ' ')
		|| (what != 2 && c == '<'))
	{
	    if (putc(Ctrl_V, fd) < 0)
		return FAIL;
	}
	if (putc(c, fd) < 0)
	    return FAIL;
    }
    return OK;
}

/*
 * Check all mappings for the presence of special key codes.
 * Used after ":set term=xxx".
 */
    void
check_map_keycodes()
{
    mapblock_T	*mp;
    char_u	*p;
    int		i;
    char_u	buf[3];
    char_u	*save_name;
    int		abbr;
    int		hash;
#ifdef FEAT_LOCALMAP
    buf_T	*bp;
#endif

    validate_maphash();
    save_name = sourcing_name;
    sourcing_name = (char_u *)"mappings"; /* avoids giving error messages */

#ifdef FEAT_LOCALMAP
    /* This this once for each buffer, and then once for global
     * mappings/abbreviations with bp == NULL */
    for (bp = firstbuf; ; bp = bp->b_next)
    {
#endif
	/*
	 * Do the loop twice: Once for mappings, once for abbreviations.
	 * Then loop over all map hash lists.
	 */
	for (abbr = 0; abbr <= 1; ++abbr)
	    for (hash = 0; hash < 256; ++hash)
	    {
		if (abbr)
		{
		    if (hash)	    /* there is only one abbr list */
			break;
#ifdef FEAT_LOCALMAP
		    if (bp != NULL)
			mp = bp->b_first_abbr;
		    else
#endif
			mp = first_abbr;
		}
		else
		{
#ifdef FEAT_LOCALMAP
		    if (bp != NULL)
			mp = bp->b_maphash[hash];
		    else
#endif
			mp = maphash[hash];
		}
		for ( ; mp != NULL; mp = mp->m_next)
		{
		    for (i = 0; i <= 1; ++i)	/* do this twice */
		    {
			if (i == 0)
			    p = mp->m_keys;	/* once for the "from" part */
			else
			    p = mp->m_str;	/* and once for the "to" part */
			while (*p)
			{
			    if (*p == K_SPECIAL)
			    {
				++p;
				if (*p < 128)   /* for "normal" tcap entries */
				{
				    buf[0] = p[0];
				    buf[1] = p[1];
				    buf[2] = NUL;
				    (void)add_termcap_entry(buf, FALSE);
				}
				++p;
			    }
			    ++p;
			}
		    }
		}
	    }
#ifdef FEAT_LOCALMAP
	if (bp == NULL)
	    break;
    }
#endif
    sourcing_name = save_name;
}

#ifdef FEAT_EVAL
/*
 * Check the string "keys" against the lhs of all mappings
 * Return pointer to rhs of mapping (mapblock->m_str)
 * NULL otherwise
 */
    char_u *
check_map(keys, mode, exact, ign_mod, abbr)
    char_u	*keys;
    int		mode;
    int		exact;		/* require exact match */
    int		ign_mod;	/* ignore preceding modifier */
    int		abbr;		/* do abbreviations */
{
    int		hash;
    int		len, minlen;
    mapblock_T	*mp;
    char_u	*s;
#ifdef FEAT_LOCALMAP
    int		local;
#endif

    validate_maphash();

    len = (int)STRLEN(keys);
#ifdef FEAT_LOCALMAP
    for (local = 1; local >= 0; --local)
#endif
	/* loop over all hash lists */
	for (hash = 0; hash < 256; ++hash)
	{
	    if (abbr)
	    {
		if (hash > 0)		/* there is only one list. */
		    break;
#ifdef FEAT_LOCALMAP
		if (local)
		    mp = curbuf->b_first_abbr;
		else
#endif
		    mp = first_abbr;
	    }
#ifdef FEAT_LOCALMAP
	    else if (local)
		mp = curbuf->b_maphash[hash];
#endif
	    else
		mp = maphash[hash];
	    for ( ; mp != NULL; mp = mp->m_next)
	    {
		/* skip entries with wrong mode, wrong length and not matching
		 * ones */
		if ((mp->m_mode & mode) && (!exact || mp->m_keylen == len))
		{
		    if (len > mp->m_keylen)
			minlen = mp->m_keylen;
		    else
			minlen = len;
		    s = mp->m_keys;
		    if (ign_mod && s[0] == K_SPECIAL && s[1] == KS_MODIFIER
							       && s[2] != NUL)
		    {
			s += 3;
			if (len > mp->m_keylen - 3)
			    minlen = mp->m_keylen - 3;
		    }
		    if (STRNCMP(s, keys, minlen) == 0)
			return mp->m_str;
		}
	    }
	}

    return NULL;
}
#endif

#if defined(MSDOS) || defined(MSWIN) || defined(OS2) || defined(MACOS)

#define VIS_SEL	(VISUAL+SELECTMODE)	/* abbreviation */

/*
 * Default mappings for some often used keys.
 */
static struct initmap
{
    char_u	*arg;
    int		mode;
} initmappings[] =
{
#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
	/* Use the Windows (CUA) keybindings. */
# ifdef FEAT_GUI
#  if 0	    /* These are now used to move tab pages */
	{(char_u *)"<C-PageUp> H", NORMAL+VIS_SEL},
	{(char_u *)"<C-PageUp> <C-O>H",INSERT},
	{(char_u *)"<C-PageDown> L$", NORMAL+VIS_SEL},
	{(char_u *)"<C-PageDown> <C-O>L<C-O>$", INSERT},
#  endif

	/* paste, copy and cut */
	{(char_u *)"<S-Insert> \"*P", NORMAL},
	{(char_u *)"<S-Insert> \"-d\"*P", VIS_SEL},
	{(char_u *)"<S-Insert> <C-R><C-O>*", INSERT+CMDLINE},
	{(char_u *)"<C-Insert> \"*y", VIS_SEL},
	{(char_u *)"<S-Del> \"*d", VIS_SEL},
	{(char_u *)"<C-Del> \"*d", VIS_SEL},
	{(char_u *)"<C-X> \"*d", VIS_SEL},
	/* Missing: CTRL-C (cancel) and CTRL-V (block selection) */
# else
#  if 0	    /* These are now used to move tab pages */
	{(char_u *)"\316\204 H", NORMAL+VIS_SEL},    /* CTRL-PageUp is "H" */
	{(char_u *)"\316\204 \017H",INSERT},	    /* CTRL-PageUp is "^OH"*/
	{(char_u *)"\316v L$", NORMAL+VIS_SEL},	    /* CTRL-PageDown is "L$" */
	{(char_u *)"\316v \017L\017$", INSERT},	    /* CTRL-PageDown ="^OL^O$"*/
#  endif
	{(char_u *)"\316w <C-Home>", NORMAL+VIS_SEL},
	{(char_u *)"\316w <C-Home>", INSERT+CMDLINE},
	{(char_u *)"\316u <C-End>", NORMAL+VIS_SEL},
	{(char_u *)"\316u <C-End>", INSERT+CMDLINE},

	/* paste, copy and cut */
#  ifdef FEAT_CLIPBOARD
#   ifdef DJGPP
	{(char_u *)"\316\122 \"*P", NORMAL},	    /* SHIFT-Insert is "*P */
	{(char_u *)"\316\122 \"-d\"*P", VIS_SEL},    /* SHIFT-Insert is "-d"*P */
	{(char_u *)"\316\122 \022\017*", INSERT},  /* SHIFT-Insert is ^R^O* */
	{(char_u *)"\316\222 \"*y", VIS_SEL},	    /* CTRL-Insert is "*y */
#    if 0 /* Shift-Del produces the same code as Del */
	{(char_u *)"\316\123 \"*d", VIS_SEL},	    /* SHIFT-Del is "*d */
#    endif
	{(char_u *)"\316\223 \"*d", VIS_SEL},	    /* CTRL-Del is "*d */
	{(char_u *)"\030 \"-d", VIS_SEL},	    /* CTRL-X is "-d */
#   else
	{(char_u *)"\316\324 \"*P", NORMAL},	    /* SHIFT-Insert is "*P */
	{(char_u *)"\316\324 \"-d\"*P", VIS_SEL},    /* SHIFT-Insert is "-d"*P */
	{(char_u *)"\316\324 \022\017*", INSERT},  /* SHIFT-Insert is ^R^O* */
	{(char_u *)"\316\325 \"*y", VIS_SEL},	    /* CTRL-Insert is "*y */
	{(char_u *)"\316\327 \"*d", VIS_SEL},	    /* SHIFT-Del is "*d */
	{(char_u *)"\316\330 \"*d", VIS_SEL},	    /* CTRL-Del is "*d */
	{(char_u *)"\030 \"-d", VIS_SEL},	    /* CTRL-X is "-d */
#   endif
#  else
	{(char_u *)"\316\324 P", NORMAL},	    /* SHIFT-Insert is P */
	{(char_u *)"\316\324 \"-dP", VIS_SEL},	    /* SHIFT-Insert is "-dP */
	{(char_u *)"\316\324 \022\017\"", INSERT}, /* SHIFT-Insert is ^R^O" */
	{(char_u *)"\316\325 y", VIS_SEL},	    /* CTRL-Insert is y */
	{(char_u *)"\316\327 d", VIS_SEL},	    /* SHIFT-Del is d */
	{(char_u *)"\316\330 d", VIS_SEL},	    /* CTRL-Del is d */
#  endif
# endif
#endif

#if defined(MACOS)
	/* Use the Standard MacOS binding. */
	/* paste, copy and cut */
	{(char_u *)"<D-v> \"*P", NORMAL},
	{(char_u *)"<D-v> \"-d\"*P", VIS_SEL},
	{(char_u *)"<D-v> <C-R>*", INSERT+CMDLINE},
	{(char_u *)"<D-c> \"*y", VIS_SEL},
	{(char_u *)"<D-x> \"*d", VIS_SEL},
	{(char_u *)"<Backspace> \"-d", VIS_SEL},
#endif
};

# undef VIS_SEL
#endif

/*
 * Set up default mappings.
 */
    void
init_mappings()
{
#if defined(MSDOS) || defined(MSWIN) || defined(OS2) || defined(MACOS)
    int		i;

    for (i = 0; i < sizeof(initmappings) / sizeof(struct initmap); ++i)
	add_map(initmappings[i].arg, initmappings[i].mode);
#endif
}

#if defined(MSDOS) || defined(MSWIN) || defined(OS2) \
	|| defined(FEAT_CMDWIN) || defined(MACOS) || defined(PROTO)
/*
 * Add a mapping "map" for mode "mode".
 * Need to put string in allocated memory, because do_map() will modify it.
 */
    void
add_map(map, mode)
    char_u	*map;
    int		mode;
{
    char_u	*s;
    char_u	*cpo_save = p_cpo;

    p_cpo = (char_u *)"";	/* Allow <> notation */
    s = vim_strsave(map);
    if (s != NULL)
    {
	(void)do_map(0, s, mode, FALSE);
	vim_free(s);
    }
    p_cpo = cpo_save;
}
#endif
