diff --git a/src/getchar.c b/src/getchar.c
index 8c1a01a..0c1d4e8 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -1900,6 +1900,530 @@
     return (retval != NUL);
 }
 
+typedef enum {
+    map_result_fail,    // failed, break loop
+    map_result_get,     // get a character from typeahead
+    map_result_retry,   // try to map again
+    map_result_nomatch  // no matching mapping, get char
+} map_result_T;
+
+/*
+ * Handle mappings in the typeahead buffer.
+ * - When something was mapped, return map_result_retry for recursive mappings.
+ * - When nothing mapped and typeahead has a character return map_result_get.
+ * - When there is no match yet, return map_result_nomatch, need to get more
+ *   typeahead.
+ */
+    static int
+handle_mapping(
+	    int *keylenp,
+	    int *timedout,
+	    int *mapdepth)
+{
+    mapblock_T	*mp = NULL;
+    mapblock_T	*mp2;
+    mapblock_T	*mp_match;
+    int		mp_match_len = 0;
+    int		max_mlen = 0;
+    int		tb_c1;
+    int		mlen;
+#ifdef FEAT_LANGMAP
+    int		nolmaplen;
+#endif
+    int		keylen = *keylenp;
+    int		i;
+    int		local_State = get_real_state();
+
+    /*
+     * 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
+     */
+    tb_c1 = typebuf.tb_buf[typebuf.tb_off];
+    if (no_mapping == 0 && is_maphash_valid()
+	    && (no_zero_mapping == 0 || tb_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 && (tb_c1 == CAR || tb_c1 == ' '))
+	    && State != ASKMORE
+	    && State != CONFIRM
+#ifdef FEAT_INS_EXPAND
+	    && !((ctrl_x_mode_not_default()
+				   && vim_is_ctrl_x_key(tb_c1))
+		    || ((compl_cont_status & CONT_LOCAL)
+			&& (tb_c1 == Ctrl_N || tb_c1 == Ctrl_P)))
+#endif
+	    )
+    {
+#ifdef FEAT_LANGMAP
+	if (tb_c1 == K_SPECIAL)
+	    nolmaplen = 2;
+	else
+	{
+	    LANGMAP_ADJUST(tb_c1,
+			   (State & (CMDLINE | INSERT)) == 0
+			   && get_real_state() != SELECTMODE);
+	    nolmaplen = 0;
+	}
+#endif
+	// First try buffer-local mappings.
+	mp = get_buf_maphash_list(local_State, tb_c1);
+	mp2 = get_maphash_list(local_State, tb_c1);
+	if (mp == NULL)
+	{
+	    // There are no buffer-local mappings.
+	    mp = mp2;
+	    mp2 = NULL;
+	}
+	/*
+	 * 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;
+		mp->m_next == NULL ? (mp = mp2, mp2 = NULL)
+				   : (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] == tb_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;
+		}
+
+		// Don't allow mapping the first byte(s) of a
+		// multi-byte char.  Happens when mapping
+		// <M-a> and then changing 'encoding'. Beware
+		// that 0x80 is escaped.
+		{
+		    char_u *p1 = mp->m_keys;
+		    char_u *p2 = mb_unescape(&p1);
+
+		    if (has_mbyte && p2 != NULL
+			  && MB_BYTE2LEN(tb_c1) > MB_PTR2LEN(p2))
+			mlen = 0;
+		}
+
+		// 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))
+		{
+		    char_u  *s;
+		    int	    n;
+
+		    // 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 && !(mp_match != NULL
+				       && mp_match->m_nowait))
+			{
+			    // break at a partly match
+			    keylen = KEYLEN_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 != KEYLEN_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
+	    }
+	    status_redraw_all();
+	    redraw_statuslines();
+	    showmode();
+	    setcursor();
+	    *keylenp = keylen;
+	    return map_result_retry;
+	}
+	// Need more chars for partly match.
+	if (mlen == typebuf.tb_len)
+	    keylen = KEYLEN_PART_KEY;
+	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 != KEYLEN_PART_MAP)
+    {
+	int	save_keylen = keylen;
+
+	/*
+	 * 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, NULL);
+
+	    // If no termcode matched but 'pastetoggle'
+	    // matched partially it's like an incomplete key
+	    // sequence.
+	    if (keylen == 0 && save_keylen == KEYLEN_PART_KEY)
+		keylen = KEYLEN_PART_KEY;
+
+	    // 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)
+	    {
+		char_u *s;
+
+		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();
+		    *keylenp = keylen;
+		    return map_result_retry;
+		}
+		if (*s == NUL)	    // need more characters
+		    keylen = KEYLEN_PART_KEY;
+	    }
+	    if (keylen >= 0)
+#endif
+	      // When there was a matching mapping and no
+	      // termcode could be replaced after another one,
+	      // use that mapping (loop around). If there was
+	      // no mapping at all use the character from the
+	      // typeahead buffer right here.
+	      if (mp == NULL)
+	      {
+		*keylenp = keylen;
+		return map_result_get;	    // got character, break for loop
+	      }
+	}
+
+	if (keylen > 0)	    // full matching terminal code
+	{
+#if defined(FEAT_GUI) && defined(FEAT_MENU)
+	    if (typebuf.tb_len >= 2
+		&& typebuf.tb_buf[typebuf.tb_off] == K_SPECIAL
+			 && typebuf.tb_buf[typebuf.tb_off + 1]
+						   == KS_MENU)
+	    {
+		int	idx;
+
+		// 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)
+		{
+		    // 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);
+		    }
+		    ins_typebuf(current_menu->strings[idx],
+				current_menu->noremap[idx],
+				0, TRUE,
+				   current_menu->silent[idx]);
+		}
+	    }
+#endif // FEAT_GUI && FEAT_MENU
+	    *keylenp = keylen;
+	    return map_result_retry;	// try mapping again
+	}
+
+	// Partial match: get some more characters.  When a
+	// matching mapping was found use that one.
+	if (mp == NULL || keylen < 0)
+	    keylen = KEYLEN_PART_KEY;
+	else
+	    keylen = mp_match_len;
+    }
+
+    /*
+     * complete match
+     */
+    if (keylen >= 0 && keylen <= typebuf.tb_len)
+    {
+	char_u *map_str;
+
+#ifdef FEAT_EVAL
+	int save_m_expr;
+	int save_m_noremap;
+	int save_m_silent;
+	char_u *save_m_keys;
+	char_u *save_m_str;
+#else
+# define save_m_noremap mp->m_noremap
+# define save_m_silent mp->m_silent
+#endif
+
+	// 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(FLUSH_MINIMAL);
+	    *mapdepth = 0;	/* for next one */
+	    *keylenp = keylen;
+	    return map_result_fail;
+	}
+
+	/*
+	 * 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);
+	}
+
+#ifdef FEAT_EVAL
+	// Copy the values from *mp that are used, because
+	// evaluating the expression may invoke a function
+	// that redefines the mapping, thereby making *mp
+	// invalid.
+	save_m_expr = mp->m_expr;
+	save_m_noremap = mp->m_noremap;
+	save_m_silent = mp->m_silent;
+	save_m_keys = NULL;  // only saved when needed
+	save_m_str = NULL;  // only saved when needed
+
+	/*
+	 * Handle ":map <expr>": evaluate the {rhs} as an
+	 * expression.  Also save and restore the command line
+	 * for "normal :".
+	 */
+	if (mp->m_expr)
+	{
+	    int save_vgetc_busy = vgetc_busy;
+	    int save_may_garbage_collect = may_garbage_collect;
+
+	    vgetc_busy = 0;
+	    may_garbage_collect = FALSE;
+
+	    save_m_keys = vim_strsave(mp->m_keys);
+	    save_m_str = vim_strsave(mp->m_str);
+	    map_str = eval_map_expr(save_m_str, NUL);
+
+	    vgetc_busy = save_vgetc_busy;
+	    may_garbage_collect = save_may_garbage_collect;
+	}
+	else
+#endif
+	    map_str = 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 (map_str == NULL)
+	    i = FAIL;
+	else
+	{
+	    int noremap;
+
+	    if (save_m_noremap != REMAP_YES)
+		noremap = save_m_noremap;
+	    else if (
+#ifdef FEAT_EVAL
+		STRNCMP(map_str, save_m_keys != NULL
+				   ? save_m_keys : mp->m_keys,
+					 (size_t)keylen)
+#else
+		STRNCMP(map_str, mp->m_keys, (size_t)keylen)
+#endif
+		   != 0)
+		noremap = REMAP_YES;
+	    else
+		noremap = REMAP_SKIP;
+	    i = ins_typebuf(map_str, noremap,
+					 0, TRUE, cmd_silent || save_m_silent);
+#ifdef FEAT_EVAL
+	    if (save_m_expr)
+		vim_free(map_str);
+#endif
+	}
+#ifdef FEAT_EVAL
+	vim_free(save_m_keys);
+	vim_free(save_m_str);
+#endif
+	*keylenp = keylen;
+	if (i == FAIL)
+	    return map_result_fail;
+	return map_result_retry;
+    }
+
+    *keylenp = keylen;
+    return map_result_nomatch;
+}
+
 /*
  * unget one character (can only be done once!)
  */
@@ -1942,33 +2466,18 @@
 vgetorpeek(int advance)
 {
     int		c, c1;
-    int		keylen;
-    char_u	*s;
-    mapblock_T	*mp;
-    mapblock_T	*mp2;
-    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;
 
@@ -1986,8 +2495,6 @@
     if (vgetc_busy > 0 && ex_normal_busy == 0)
 	return NUL;
 
-    local_State = get_real_state();
-
     ++vgetc_busy;
 
     if (advance)
@@ -2032,7 +2539,8 @@
 	     */
 	    for (;;)
 	    {
-		long	    wait_time;
+		long	wait_time;
+		int	keylen = 0;
 
 		/*
 		 * ui_breakcheck() is slow, don't use it too often when
@@ -2043,11 +2551,11 @@
 		    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);
+
 		    /*
 		     * If inchar() returns TRUE (script file was active) or we
 		     * are inside a mapping, get out of Insert mode.
@@ -2076,508 +2584,46 @@
 		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
+		     * Check for a mapping in "typebuf".
 		     */
-		    mp = NULL;
-		    max_mlen = 0;
-		    c1 = typebuf.tb_buf[typebuf.tb_off];
-		    if (no_mapping == 0 && is_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_not_default()
-						      && vim_is_ctrl_x_key(c1))
-				    || ((compl_cont_status & CONT_LOCAL)
-					&& (c1 == Ctrl_N || c1 == Ctrl_P)))
-#endif
-			    )
+		    map_result_T result = handle_mapping(
+						&keylen, &timedout, &mapdepth);
+
+		    if (result == map_result_retry)
+			// try mapping again
+			continue;
+		    if (result == map_result_fail)
 		    {
-#ifdef FEAT_LANGMAP
-			if (c1 == K_SPECIAL)
-			    nolmaplen = 2;
-			else
-			{
-			    LANGMAP_ADJUST(c1,
-					   (State & (CMDLINE | INSERT)) == 0
-					   && get_real_state() != SELECTMODE);
-			    nolmaplen = 0;
-			}
-#endif
-			// First try buffer-local mappings.
-			mp = get_buf_maphash_list(local_State, c1);
-			mp2 = get_maphash_list(local_State, c1);
-			if (mp == NULL)
-			{
-			    // There are no buffer-local mappings.
-			    mp = mp2;
-			    mp2 = NULL;
-			}
-			/*
-			 * 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;
-				mp->m_next == NULL ? (mp = mp2, mp2 = NULL)
-						   : (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;
-				}
-
-				/* Don't allow mapping the first byte(s) of a
-				 * multi-byte char.  Happens when mapping
-				 * <M-a> and then changing 'encoding'. Beware
-				 * that 0x80 is escaped. */
-				{
-				    char_u *p1 = mp->m_keys;
-				    char_u *p2 = mb_unescape(&p1);
-
-				    if (has_mbyte && p2 != NULL
-					  && MB_BYTE2LEN(c1) > MB_PTR2LEN(p2))
-					mlen = 0;
-				}
-				/*
-				 * 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 && !(mp_match != NULL
-						       && mp_match->m_nowait))
-					{
-					    /* break at a partly match */
-					    keylen = KEYLEN_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 != KEYLEN_PART_MAP)
-			{
-			    mp = mp_match;
-			    keylen = mp_match_len;
-			}
+			// failed, use the outer loop
+			c = -1;
+			break;
 		    }
-
-		    /* Check for match with 'pastetoggle' */
-		    if (*p_pt != NUL && mp == NULL && (State & (INSERT|NORMAL)))
+		    if (result == map_result_get)
 		    {
-			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 */
-			    }
-			    status_redraw_all();
-			    redraw_statuslines();
-			    showmode();
-			    setcursor();
-			    continue;
-			}
-			/* Need more chars for partly match. */
-			if (mlen == typebuf.tb_len)
-			    keylen = KEYLEN_PART_KEY;
-			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 != KEYLEN_PART_MAP)
-		    {
-			int	save_keylen = keylen;
-
-			/*
-			 * 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, NULL);
-
-			    /* If no termcode matched but 'pastetoggle'
-			     * matched partially it's like an incomplete key
-			     * sequence. */
-			    if (keylen == 0 && save_keylen == KEYLEN_PART_KEY)
-				keylen = KEYLEN_PART_KEY;
-
-			    /*
-			     * 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 = KEYLEN_PART_KEY;
-			    }
-			    if (keylen >= 0)
-#endif
-			      /* When there was a matching mapping and no
-			       * termcode could be replaced after another one,
-			       * use that mapping (loop around). If there was
-			       * no mapping use the character from the
-			       * typeahead buffer right here. */
-			      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 */
+			c = typebuf.tb_buf[typebuf.tb_off] & 255;
+			if (advance)	/* remove chars from tb_buf */
 			{
-#if defined(FEAT_GUI) && defined(FEAT_MENU)
-			    if (typebuf.tb_len >= 2
-				&& typebuf.tb_buf[typebuf.tb_off] == K_SPECIAL
-					 && typebuf.tb_buf[typebuf.tb_off + 1]
-								   == KS_MENU)
+			    cmd_silent = (typebuf.tb_silent > 0);
+			    if (typebuf.tb_maplen > 0)
+				KeyTyped = FALSE;
+			    else
 			    {
-				/*
-				 * 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)
-				{
-				    /*
-				     * 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);
-				    }
-				    ins_typebuf(current_menu->strings[idx],
-						current_menu->noremap[idx],
-						0, TRUE,
-						   current_menu->silent[idx]);
-				}
+				KeyTyped = TRUE;
+				/* write char to script file(s) */
+				gotchars(typebuf.tb_buf
+						 + typebuf.tb_off, 1);
 			    }
-#endif /* FEAT_GUI && FEAT_MENU */
-			    continue;	/* try mapping again */
+			    KeyNoremap = typebuf.tb_noremap[
+						      typebuf.tb_off];
+			    del_typebuf(1, 0);
 			}
-
-			/* Partial match: get some more characters.  When a
-			 * matching mapping was found use that one. */
-			if (mp == NULL || keylen < 0)
-			    keylen = KEYLEN_PART_KEY;
-			else
-			    keylen = mp_match_len;
+			break;
 		    }
 
-		    /* complete match */
-		    if (keylen >= 0 && keylen <= typebuf.tb_len)
-		    {
-#ifdef FEAT_EVAL
-			int save_m_expr;
-			int save_m_noremap;
-			int save_m_silent;
-			char_u *save_m_keys;
-			char_u *save_m_str;
-#else
-# define save_m_noremap mp->m_noremap
-# define save_m_silent mp->m_silent
-#endif
-
-			/* 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(FLUSH_MINIMAL);
-			    mapdepth = 0;	/* for next one */
-			    c = -1;
-			    break;
-			}
-
-			/*
-			 * 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);
-			}
-
-#ifdef FEAT_EVAL
-			/* Copy the values from *mp that are used, because
-			 * evaluating the expression may invoke a function
-			 * that redefines the mapping, thereby making *mp
-			 * invalid. */
-			save_m_expr = mp->m_expr;
-			save_m_noremap = mp->m_noremap;
-			save_m_silent = mp->m_silent;
-			save_m_keys = NULL;  /* only saved when needed */
-			save_m_str = NULL;  /* only saved when needed */
-
-			/*
-			 * Handle ":map <expr>": evaluate the {rhs} as an
-			 * expression.  Also save and restore the command line
-			 * for "normal :".
-			 */
-			if (mp->m_expr)
-			{
-			    int save_vgetc_busy = vgetc_busy;
-			    int save_may_garbage_collect = may_garbage_collect;
-
-			    vgetc_busy = 0;
-			    may_garbage_collect = FALSE;
-
-			    save_m_keys = vim_strsave(mp->m_keys);
-			    save_m_str = vim_strsave(mp->m_str);
-			    s = eval_map_expr(save_m_str, NUL);
-
-			    vgetc_busy = save_vgetc_busy;
-			    may_garbage_collect = save_may_garbage_collect;
-			}
-			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
-			{
-			    int noremap;
-
-			    if (save_m_noremap != REMAP_YES)
-				noremap = save_m_noremap;
-			    else if (
-#ifdef FEAT_EVAL
-				STRNCMP(s, save_m_keys != NULL
-						   ? save_m_keys : mp->m_keys,
-							 (size_t)keylen)
-#else
-				STRNCMP(s, mp->m_keys, (size_t)keylen)
-#endif
-				   != 0)
-				noremap = REMAP_YES;
-			    else
-				noremap = REMAP_SKIP;
-			    i = ins_typebuf(s, noremap,
-					0, TRUE, cmd_silent || save_m_silent);
-#ifdef FEAT_EVAL
-			    if (save_m_expr)
-				vim_free(s);
-#endif
-			}
-#ifdef FEAT_EVAL
-			vim_free(save_m_keys);
-			vim_free(save_m_str);
-#endif
-			if (i == FAIL)
-			{
-			    c = -1;
-			    break;
-			}
-			continue;
-		    }
+		    // not enough characters, get more
 		}
 
 /*
