diff --git a/src/getchar.c b/src/getchar.c
index 8c1a01a..ea628cb 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;
+    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
 		}
 
 /*
