comparison src/getchar.c @ 17594:3b18d5341c03 v8.1.1794

patch 8.1.1794: tests are flaky commit https://github.com/vim/vim/commit/f2d8b7a0a69fd71018341755da5ce55d067b5923 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Aug 2 22:46:11 2019 +0200 patch 8.1.1794: tests are flaky Problem: Tests are flaky. Solution: Undo the change to vgetorpeek().
author Bram Moolenaar <Bram@vim.org>
date Fri, 02 Aug 2019 23:00:07 +0200
parents 8d20183f2a8c
children ca42eb789472
comparison
equal deleted inserted replaced
17593:8746304ac416 17594:3b18d5341c03
1898 retval = vpeekc(); 1898 retval = vpeekc();
1899 --no_mapping; 1899 --no_mapping;
1900 return (retval != NUL); 1900 return (retval != NUL);
1901 } 1901 }
1902 1902
1903 typedef enum {
1904 map_result_fail, // failed, break loop
1905 map_result_get, // get a character from typeahead
1906 map_result_retry, // try to map again
1907 map_result_nomatch // no matching mapping, get char
1908 } map_result_T;
1909
1910 /*
1911 * Handle mappings in the typeahead buffer.
1912 * - When something was mapped, return map_result_retry for recursive mappings.
1913 * - When nothing mapped and typeahead has a character return map_result_get.
1914 * - When there is no match yet, return map_result_nomatch, need to get more
1915 * typeahead.
1916 */
1917 static int
1918 handle_mapping(
1919 int *keylenp,
1920 int *timedout,
1921 int *mapdepth)
1922 {
1923 mapblock_T *mp = NULL;
1924 mapblock_T *mp2;
1925 mapblock_T *mp_match;
1926 int mp_match_len = 0;
1927 int max_mlen = 0;
1928 int tb_c1;
1929 int mlen;
1930 #ifdef FEAT_LANGMAP
1931 int nolmaplen;
1932 #endif
1933 int keylen;
1934 int i;
1935 int local_State = get_real_state();
1936
1937 /*
1938 * Check for a mappable key sequence.
1939 * Walk through one maphash[] list until we find an
1940 * entry that matches.
1941 *
1942 * Don't look for mappings if:
1943 * - no_mapping set: mapping disabled (e.g. for CTRL-V)
1944 * - maphash_valid not set: no mappings present.
1945 * - typebuf.tb_buf[typebuf.tb_off] should not be remapped
1946 * - in insert or cmdline mode and 'paste' option set
1947 * - waiting for "hit return to continue" and CR or SPACE
1948 * typed
1949 * - waiting for a char with --more--
1950 * - in Ctrl-X mode, and we get a valid char for that mode
1951 */
1952 tb_c1 = typebuf.tb_buf[typebuf.tb_off];
1953 if (no_mapping == 0 && is_maphash_valid()
1954 && (no_zero_mapping == 0 || tb_c1 != '0')
1955 && (typebuf.tb_maplen == 0
1956 || (p_remap
1957 && (typebuf.tb_noremap[typebuf.tb_off]
1958 & (RM_NONE|RM_ABBR)) == 0))
1959 && !(p_paste && (State & (INSERT + CMDLINE)))
1960 && !(State == HITRETURN && (tb_c1 == CAR || tb_c1 == ' '))
1961 && State != ASKMORE
1962 && State != CONFIRM
1963 #ifdef FEAT_INS_EXPAND
1964 && !((ctrl_x_mode_not_default()
1965 && vim_is_ctrl_x_key(tb_c1))
1966 || ((compl_cont_status & CONT_LOCAL)
1967 && (tb_c1 == Ctrl_N || tb_c1 == Ctrl_P)))
1968 #endif
1969 )
1970 {
1971 #ifdef FEAT_LANGMAP
1972 if (tb_c1 == K_SPECIAL)
1973 nolmaplen = 2;
1974 else
1975 {
1976 LANGMAP_ADJUST(tb_c1,
1977 (State & (CMDLINE | INSERT)) == 0
1978 && get_real_state() != SELECTMODE);
1979 nolmaplen = 0;
1980 }
1981 #endif
1982 // First try buffer-local mappings.
1983 mp = get_buf_maphash_list(local_State, tb_c1);
1984 mp2 = get_maphash_list(local_State, tb_c1);
1985 if (mp == NULL)
1986 {
1987 // There are no buffer-local mappings.
1988 mp = mp2;
1989 mp2 = NULL;
1990 }
1991 /*
1992 * Loop until a partly matching mapping is found or
1993 * all (local) mappings have been checked.
1994 * The longest full match is remembered in "mp_match".
1995 * A full match is only accepted if there is no partly
1996 * match, so "aa" and "aaa" can both be mapped.
1997 */
1998 mp_match = NULL;
1999 mp_match_len = 0;
2000 for ( ; mp != NULL;
2001 mp->m_next == NULL ? (mp = mp2, mp2 = NULL)
2002 : (mp = mp->m_next))
2003 {
2004 // Only consider an entry if the first character
2005 // matches and it is for the current state.
2006 // Skip ":lmap" mappings if keys were mapped.
2007 if (mp->m_keys[0] == tb_c1
2008 && (mp->m_mode & local_State)
2009 && ((mp->m_mode & LANGMAP) == 0
2010 || typebuf.tb_maplen == 0))
2011 {
2012 #ifdef FEAT_LANGMAP
2013 int nomap = nolmaplen;
2014 int c2;
2015 #endif
2016 // find the match length of this mapping
2017 for (mlen = 1; mlen < typebuf.tb_len; ++mlen)
2018 {
2019 #ifdef FEAT_LANGMAP
2020 c2 = typebuf.tb_buf[typebuf.tb_off + mlen];
2021 if (nomap > 0)
2022 --nomap;
2023 else if (c2 == K_SPECIAL)
2024 nomap = 2;
2025 else
2026 LANGMAP_ADJUST(c2, TRUE);
2027 if (mp->m_keys[mlen] != c2)
2028 #else
2029 if (mp->m_keys[mlen] !=
2030 typebuf.tb_buf[typebuf.tb_off + mlen])
2031 #endif
2032 break;
2033 }
2034
2035 // Don't allow mapping the first byte(s) of a
2036 // multi-byte char. Happens when mapping
2037 // <M-a> and then changing 'encoding'. Beware
2038 // that 0x80 is escaped.
2039 {
2040 char_u *p1 = mp->m_keys;
2041 char_u *p2 = mb_unescape(&p1);
2042
2043 if (has_mbyte && p2 != NULL
2044 && MB_BYTE2LEN(tb_c1) > MB_PTR2LEN(p2))
2045 mlen = 0;
2046 }
2047
2048 // Check an entry whether it matches.
2049 // - Full match: mlen == keylen
2050 // - Partly match: mlen == typebuf.tb_len
2051 keylen = mp->m_keylen;
2052 if (mlen == keylen
2053 || (mlen == typebuf.tb_len
2054 && typebuf.tb_len < keylen))
2055 {
2056 char_u *s;
2057 int n;
2058
2059 // If only script-local mappings are
2060 // allowed, check if the mapping starts
2061 // with K_SNR.
2062 s = typebuf.tb_noremap + typebuf.tb_off;
2063 if (*s == RM_SCRIPT
2064 && (mp->m_keys[0] != K_SPECIAL
2065 || mp->m_keys[1] != KS_EXTRA
2066 || mp->m_keys[2]
2067 != (int)KE_SNR))
2068 continue;
2069
2070 // If one of the typed keys cannot be
2071 // remapped, skip the entry.
2072 for (n = mlen; --n >= 0; )
2073 if (*s++ & (RM_NONE|RM_ABBR))
2074 break;
2075 if (n >= 0)
2076 continue;
2077
2078 if (keylen > typebuf.tb_len)
2079 {
2080 if (!*timedout && !(mp_match != NULL
2081 && mp_match->m_nowait))
2082 {
2083 // break at a partly match
2084 keylen = KEYLEN_PART_MAP;
2085 break;
2086 }
2087 }
2088 else if (keylen > mp_match_len)
2089 {
2090 // found a longer match
2091 mp_match = mp;
2092 mp_match_len = keylen;
2093 }
2094 }
2095 else
2096 // No match; may have to check for
2097 // termcode at next character.
2098 if (max_mlen < mlen)
2099 max_mlen = mlen;
2100 }
2101 }
2102
2103 // If no partly match found, use the longest full
2104 // match.
2105 if (keylen != KEYLEN_PART_MAP)
2106 {
2107 mp = mp_match;
2108 keylen = mp_match_len;
2109 }
2110 }
2111
2112 /*
2113 * Check for match with 'pastetoggle'
2114 */
2115 if (*p_pt != NUL && mp == NULL && (State & (INSERT|NORMAL)))
2116 {
2117 for (mlen = 0; mlen < typebuf.tb_len && p_pt[mlen];
2118 ++mlen)
2119 if (p_pt[mlen] != typebuf.tb_buf[typebuf.tb_off
2120 + mlen])
2121 break;
2122 if (p_pt[mlen] == NUL) // match
2123 {
2124 // write chars to script file(s)
2125 if (mlen > typebuf.tb_maplen)
2126 gotchars(typebuf.tb_buf + typebuf.tb_off
2127 + typebuf.tb_maplen,
2128 mlen - typebuf.tb_maplen);
2129
2130 del_typebuf(mlen, 0); // remove the chars
2131 set_option_value((char_u *)"paste",
2132 (long)!p_paste, NULL, 0);
2133 if (!(State & INSERT))
2134 {
2135 msg_col = 0;
2136 msg_row = Rows - 1;
2137 msg_clr_eos(); // clear ruler
2138 }
2139 status_redraw_all();
2140 redraw_statuslines();
2141 showmode();
2142 setcursor();
2143 *keylenp = keylen;
2144 return map_result_retry;
2145 }
2146 // Need more chars for partly match.
2147 if (mlen == typebuf.tb_len)
2148 keylen = KEYLEN_PART_KEY;
2149 else if (max_mlen < mlen)
2150 // no match, may have to check for termcode at
2151 // next character
2152 max_mlen = mlen + 1;
2153 }
2154
2155 if ((mp == NULL || max_mlen >= mp_match_len)
2156 && keylen != KEYLEN_PART_MAP)
2157 {
2158 int save_keylen = keylen;
2159
2160 /*
2161 * When no matching mapping found or found a
2162 * non-matching mapping that matches at least what the
2163 * matching mapping matched:
2164 * Check if we have a terminal code, when:
2165 * mapping is allowed,
2166 * keys have not been mapped,
2167 * and not an ESC sequence, not in insert mode or
2168 * p_ek is on,
2169 * and when not timed out,
2170 */
2171 if ((no_mapping == 0 || allow_keys != 0)
2172 && (typebuf.tb_maplen == 0
2173 || (p_remap && typebuf.tb_noremap[
2174 typebuf.tb_off] == RM_YES))
2175 && !*timedout)
2176 {
2177 keylen = check_termcode(max_mlen + 1,
2178 NULL, 0, NULL);
2179
2180 // If no termcode matched but 'pastetoggle'
2181 // matched partially it's like an incomplete key
2182 // sequence.
2183 if (keylen == 0 && save_keylen == KEYLEN_PART_KEY)
2184 keylen = KEYLEN_PART_KEY;
2185
2186 // When getting a partial match, but the last
2187 // characters were not typed, don't wait for a
2188 // typed character to complete the termcode.
2189 // This helps a lot when a ":normal" command ends
2190 // in an ESC.
2191 if (keylen < 0
2192 && typebuf.tb_len == typebuf.tb_maplen)
2193 keylen = 0;
2194 }
2195 else
2196 keylen = 0;
2197 if (keylen == 0) // no matching terminal code
2198 {
2199 #ifdef AMIGA // check for window bounds report
2200 if (typebuf.tb_maplen == 0 && (typebuf.tb_buf[
2201 typebuf.tb_off] & 0xff) == CSI)
2202 {
2203 char_u *s;
2204
2205 for (s = typebuf.tb_buf + typebuf.tb_off + 1;
2206 s < typebuf.tb_buf + typebuf.tb_off
2207 + typebuf.tb_len
2208 && (VIM_ISDIGIT(*s) || *s == ';'
2209 || *s == ' ');
2210 ++s)
2211 ;
2212 if (*s == 'r' || *s == '|') // found one
2213 {
2214 del_typebuf((int)(s + 1 -
2215 (typebuf.tb_buf + typebuf.tb_off)), 0);
2216 // get size and redraw screen
2217 shell_resized();
2218 *keylenp = keylen;
2219 return map_result_retry;
2220 }
2221 if (*s == NUL) // need more characters
2222 keylen = KEYLEN_PART_KEY;
2223 }
2224 if (keylen >= 0)
2225 #endif
2226 // When there was a matching mapping and no
2227 // termcode could be replaced after another one,
2228 // use that mapping (loop around). If there was
2229 // no mapping at all use the character from the
2230 // typeahead buffer right here.
2231 if (mp == NULL)
2232 {
2233 *keylenp = keylen;
2234 return map_result_get; // got character, break for loop
2235 }
2236 }
2237
2238 if (keylen > 0) // full matching terminal code
2239 {
2240 #if defined(FEAT_GUI) && defined(FEAT_MENU)
2241 if (typebuf.tb_len >= 2
2242 && typebuf.tb_buf[typebuf.tb_off] == K_SPECIAL
2243 && typebuf.tb_buf[typebuf.tb_off + 1]
2244 == KS_MENU)
2245 {
2246 int idx;
2247
2248 // Using a menu may cause a break in undo!
2249 // It's like using gotchars(), but without
2250 // recording or writing to a script file.
2251 may_sync_undo();
2252 del_typebuf(3, 0);
2253 idx = get_menu_index(current_menu, local_State);
2254 if (idx != MENU_INDEX_INVALID)
2255 {
2256 // In Select mode and a Visual mode menu
2257 // is used: Switch to Visual mode
2258 // temporarily. Append K_SELECT to switch
2259 // back to Select mode.
2260 if (VIsual_active && VIsual_select
2261 && (current_menu->modes & VISUAL))
2262 {
2263 VIsual_select = FALSE;
2264 (void)ins_typebuf(K_SELECT_STRING,
2265 REMAP_NONE, 0, TRUE, FALSE);
2266 }
2267 ins_typebuf(current_menu->strings[idx],
2268 current_menu->noremap[idx],
2269 0, TRUE,
2270 current_menu->silent[idx]);
2271 }
2272 }
2273 #endif // FEAT_GUI && FEAT_MENU
2274 *keylenp = keylen;
2275 return map_result_retry; // try mapping again
2276 }
2277
2278 // Partial match: get some more characters. When a
2279 // matching mapping was found use that one.
2280 if (mp == NULL || keylen < 0)
2281 keylen = KEYLEN_PART_KEY;
2282 else
2283 keylen = mp_match_len;
2284 }
2285
2286 /*
2287 * complete match
2288 */
2289 if (keylen >= 0 && keylen <= typebuf.tb_len)
2290 {
2291 char_u *map_str;
2292
2293 #ifdef FEAT_EVAL
2294 int save_m_expr;
2295 int save_m_noremap;
2296 int save_m_silent;
2297 char_u *save_m_keys;
2298 char_u *save_m_str;
2299 #else
2300 # define save_m_noremap mp->m_noremap
2301 # define save_m_silent mp->m_silent
2302 #endif
2303
2304 // write chars to script file(s)
2305 if (keylen > typebuf.tb_maplen)
2306 gotchars(typebuf.tb_buf + typebuf.tb_off
2307 + typebuf.tb_maplen,
2308 keylen - typebuf.tb_maplen);
2309
2310 cmd_silent = (typebuf.tb_silent > 0);
2311 del_typebuf(keylen, 0); // remove the mapped keys
2312
2313 /*
2314 * Put the replacement string in front of mapstr.
2315 * The depth check catches ":map x y" and ":map y x".
2316 */
2317 if (++*mapdepth >= p_mmd)
2318 {
2319 emsg(_("E223: recursive mapping"));
2320 if (State & CMDLINE)
2321 redrawcmdline();
2322 else
2323 setcursor();
2324 flush_buffers(FLUSH_MINIMAL);
2325 *mapdepth = 0; /* for next one */
2326 *keylenp = keylen;
2327 return map_result_fail;
2328 }
2329
2330 /*
2331 * In Select mode and a Visual mode mapping is used:
2332 * Switch to Visual mode temporarily. Append K_SELECT
2333 * to switch back to Select mode.
2334 */
2335 if (VIsual_active && VIsual_select
2336 && (mp->m_mode & VISUAL))
2337 {
2338 VIsual_select = FALSE;
2339 (void)ins_typebuf(K_SELECT_STRING, REMAP_NONE,
2340 0, TRUE, FALSE);
2341 }
2342
2343 #ifdef FEAT_EVAL
2344 // Copy the values from *mp that are used, because
2345 // evaluating the expression may invoke a function
2346 // that redefines the mapping, thereby making *mp
2347 // invalid.
2348 save_m_expr = mp->m_expr;
2349 save_m_noremap = mp->m_noremap;
2350 save_m_silent = mp->m_silent;
2351 save_m_keys = NULL; // only saved when needed
2352 save_m_str = NULL; // only saved when needed
2353
2354 /*
2355 * Handle ":map <expr>": evaluate the {rhs} as an
2356 * expression. Also save and restore the command line
2357 * for "normal :".
2358 */
2359 if (mp->m_expr)
2360 {
2361 int save_vgetc_busy = vgetc_busy;
2362 int save_may_garbage_collect = may_garbage_collect;
2363
2364 vgetc_busy = 0;
2365 may_garbage_collect = FALSE;
2366
2367 save_m_keys = vim_strsave(mp->m_keys);
2368 save_m_str = vim_strsave(mp->m_str);
2369 map_str = eval_map_expr(save_m_str, NUL);
2370
2371 vgetc_busy = save_vgetc_busy;
2372 may_garbage_collect = save_may_garbage_collect;
2373 }
2374 else
2375 #endif
2376 map_str = mp->m_str;
2377
2378 /*
2379 * Insert the 'to' part in the typebuf.tb_buf.
2380 * If 'from' field is the same as the start of the
2381 * 'to' field, don't remap the first character (but do
2382 * allow abbreviations).
2383 * If m_noremap is set, don't remap the whole 'to'
2384 * part.
2385 */
2386 if (map_str == NULL)
2387 i = FAIL;
2388 else
2389 {
2390 int noremap;
2391
2392 if (save_m_noremap != REMAP_YES)
2393 noremap = save_m_noremap;
2394 else if (
2395 #ifdef FEAT_EVAL
2396 STRNCMP(map_str, save_m_keys != NULL
2397 ? save_m_keys : mp->m_keys,
2398 (size_t)keylen)
2399 #else
2400 STRNCMP(map_str, mp->m_keys, (size_t)keylen)
2401 #endif
2402 != 0)
2403 noremap = REMAP_YES;
2404 else
2405 noremap = REMAP_SKIP;
2406 i = ins_typebuf(map_str, noremap,
2407 0, TRUE, cmd_silent || save_m_silent);
2408 #ifdef FEAT_EVAL
2409 if (save_m_expr)
2410 vim_free(map_str);
2411 #endif
2412 }
2413 #ifdef FEAT_EVAL
2414 vim_free(save_m_keys);
2415 vim_free(save_m_str);
2416 #endif
2417 *keylenp = keylen;
2418 if (i == FAIL)
2419 return map_result_fail;
2420 return map_result_retry;
2421 }
2422
2423 *keylenp = keylen;
2424 return map_result_nomatch;
2425 }
2426
2427 /* 1903 /*
2428 * unget one character (can only be done once!) 1904 * unget one character (can only be done once!)
2429 */ 1905 */
2430 void 1906 void
2431 vungetc(int c) 1907 vungetc(int c)
2464 */ 1940 */
2465 static int 1941 static int
2466 vgetorpeek(int advance) 1942 vgetorpeek(int advance)
2467 { 1943 {
2468 int c, c1; 1944 int c, c1;
1945 int keylen;
1946 char_u *s;
1947 mapblock_T *mp;
1948 mapblock_T *mp2;
1949 mapblock_T *mp_match;
1950 int mp_match_len = 0;
2469 int timedout = FALSE; /* waited for more than 1 second 1951 int timedout = FALSE; /* waited for more than 1 second
2470 for mapping to complete */ 1952 for mapping to complete */
2471 int mapdepth = 0; /* check for recursive mapping */ 1953 int mapdepth = 0; /* check for recursive mapping */
2472 int mode_deleted = FALSE; /* set when mode has been deleted */ 1954 int mode_deleted = FALSE; /* set when mode has been deleted */
1955 int local_State;
1956 int mlen;
1957 int max_mlen;
2473 int i; 1958 int i;
2474 #ifdef FEAT_CMDL_INFO 1959 #ifdef FEAT_CMDL_INFO
2475 int new_wcol, new_wrow; 1960 int new_wcol, new_wrow;
2476 #endif 1961 #endif
2477 #ifdef FEAT_GUI 1962 #ifdef FEAT_GUI
1963 # ifdef FEAT_MENU
1964 int idx;
1965 # endif
2478 int shape_changed = FALSE; /* adjusted cursor shape */ 1966 int shape_changed = FALSE; /* adjusted cursor shape */
2479 #endif 1967 #endif
2480 int n; 1968 int n;
1969 #ifdef FEAT_LANGMAP
1970 int nolmaplen;
1971 #endif
2481 int old_wcol, old_wrow; 1972 int old_wcol, old_wrow;
2482 int wait_tb_len; 1973 int wait_tb_len;
2483 1974
2484 /* 1975 /*
2485 * This function doesn't work very well when called recursively. This may 1976 * This function doesn't work very well when called recursively. This may
2492 * Using ":normal" can also do this, but it saves the typeahead buffer, 1983 * Using ":normal" can also do this, but it saves the typeahead buffer,
2493 * thus it should be OK. But don't get a key from the user then. 1984 * thus it should be OK. But don't get a key from the user then.
2494 */ 1985 */
2495 if (vgetc_busy > 0 && ex_normal_busy == 0) 1986 if (vgetc_busy > 0 && ex_normal_busy == 0)
2496 return NUL; 1987 return NUL;
1988
1989 local_State = get_real_state();
2497 1990
2498 ++vgetc_busy; 1991 ++vgetc_busy;
2499 1992
2500 if (advance) 1993 if (advance)
2501 KeyStuffed = FALSE; 1994 KeyStuffed = FALSE;
2537 * If a mapped key sequence is found we go back to the start to 2030 * If a mapped key sequence is found we go back to the start to
2538 * try re-mapping. 2031 * try re-mapping.
2539 */ 2032 */
2540 for (;;) 2033 for (;;)
2541 { 2034 {
2542 long wait_time; 2035 long wait_time;
2543 int keylen = 0;
2544 2036
2545 /* 2037 /*
2546 * ui_breakcheck() is slow, don't use it too often when 2038 * ui_breakcheck() is slow, don't use it too often when
2547 * inside a mapping. But call it each time for typed 2039 * inside a mapping. But call it each time for typed
2548 * characters. 2040 * characters.
2549 */ 2041 */
2550 if (typebuf.tb_maplen) 2042 if (typebuf.tb_maplen)
2551 line_breakcheck(); 2043 line_breakcheck();
2552 else 2044 else
2553 ui_breakcheck(); /* check for CTRL-C */ 2045 ui_breakcheck(); /* check for CTRL-C */
2046 keylen = 0;
2554 if (got_int) 2047 if (got_int)
2555 { 2048 {
2556 /* flush all input */ 2049 /* flush all input */
2557 c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L); 2050 c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L);
2558
2559 /* 2051 /*
2560 * If inchar() returns TRUE (script file was active) or we 2052 * If inchar() returns TRUE (script file was active) or we
2561 * are inside a mapping, get out of Insert mode. 2053 * are inside a mapping, get out of Insert mode.
2562 * Otherwise we behave like having gotten a CTRL-C. 2054 * Otherwise we behave like having gotten a CTRL-C.
2563 * As a result typing CTRL-C in insert mode will 2055 * As a result typing CTRL-C in insert mode will
2582 break; 2074 break;
2583 } 2075 }
2584 else if (typebuf.tb_len > 0) 2076 else if (typebuf.tb_len > 0)
2585 { 2077 {
2586 /* 2078 /*
2587 * Check for a mapping in "typebuf". 2079 * Check for a mappable key sequence.
2080 * Walk through one maphash[] list until we find an
2081 * entry that matches.
2082 *
2083 * Don't look for mappings if:
2084 * - no_mapping set: mapping disabled (e.g. for CTRL-V)
2085 * - maphash_valid not set: no mappings present.
2086 * - typebuf.tb_buf[typebuf.tb_off] should not be remapped
2087 * - in insert or cmdline mode and 'paste' option set
2088 * - waiting for "hit return to continue" and CR or SPACE
2089 * typed
2090 * - waiting for a char with --more--
2091 * - in Ctrl-X mode, and we get a valid char for that mode
2588 */ 2092 */
2589 map_result_T result = handle_mapping( 2093 mp = NULL;
2590 &keylen, &timedout, &mapdepth); 2094 max_mlen = 0;
2591 2095 c1 = typebuf.tb_buf[typebuf.tb_off];
2592 if (result == map_result_retry) 2096 if (no_mapping == 0 && is_maphash_valid()
2593 // try mapping again 2097 && (no_zero_mapping == 0 || c1 != '0')
2098 && (typebuf.tb_maplen == 0
2099 || (p_remap
2100 && (typebuf.tb_noremap[typebuf.tb_off]
2101 & (RM_NONE|RM_ABBR)) == 0))
2102 && !(p_paste && (State & (INSERT + CMDLINE)))
2103 && !(State == HITRETURN && (c1 == CAR || c1 == ' '))
2104 && State != ASKMORE
2105 && State != CONFIRM
2106 #ifdef FEAT_INS_EXPAND
2107 && !((ctrl_x_mode_not_default()
2108 && vim_is_ctrl_x_key(c1))
2109 || ((compl_cont_status & CONT_LOCAL)
2110 && (c1 == Ctrl_N || c1 == Ctrl_P)))
2111 #endif
2112 )
2113 {
2114 #ifdef FEAT_LANGMAP
2115 if (c1 == K_SPECIAL)
2116 nolmaplen = 2;
2117 else
2118 {
2119 LANGMAP_ADJUST(c1,
2120 (State & (CMDLINE | INSERT)) == 0
2121 && get_real_state() != SELECTMODE);
2122 nolmaplen = 0;
2123 }
2124 #endif
2125 // First try buffer-local mappings.
2126 mp = get_buf_maphash_list(local_State, c1);
2127 mp2 = get_maphash_list(local_State, c1);
2128 if (mp == NULL)
2129 {
2130 // There are no buffer-local mappings.
2131 mp = mp2;
2132 mp2 = NULL;
2133 }
2134 /*
2135 * Loop until a partly matching mapping is found or
2136 * all (local) mappings have been checked.
2137 * The longest full match is remembered in "mp_match".
2138 * A full match is only accepted if there is no partly
2139 * match, so "aa" and "aaa" can both be mapped.
2140 */
2141 mp_match = NULL;
2142 mp_match_len = 0;
2143 for ( ; mp != NULL;
2144 mp->m_next == NULL ? (mp = mp2, mp2 = NULL)
2145 : (mp = mp->m_next))
2146 {
2147 /*
2148 * Only consider an entry if the first character
2149 * matches and it is for the current state.
2150 * Skip ":lmap" mappings if keys were mapped.
2151 */
2152 if (mp->m_keys[0] == c1
2153 && (mp->m_mode & local_State)
2154 && ((mp->m_mode & LANGMAP) == 0
2155 || typebuf.tb_maplen == 0))
2156 {
2157 #ifdef FEAT_LANGMAP
2158 int nomap = nolmaplen;
2159 int c2;
2160 #endif
2161 /* find the match length of this mapping */
2162 for (mlen = 1; mlen < typebuf.tb_len; ++mlen)
2163 {
2164 #ifdef FEAT_LANGMAP
2165 c2 = typebuf.tb_buf[typebuf.tb_off + mlen];
2166 if (nomap > 0)
2167 --nomap;
2168 else if (c2 == K_SPECIAL)
2169 nomap = 2;
2170 else
2171 LANGMAP_ADJUST(c2, TRUE);
2172 if (mp->m_keys[mlen] != c2)
2173 #else
2174 if (mp->m_keys[mlen] !=
2175 typebuf.tb_buf[typebuf.tb_off + mlen])
2176 #endif
2177 break;
2178 }
2179
2180 /* Don't allow mapping the first byte(s) of a
2181 * multi-byte char. Happens when mapping
2182 * <M-a> and then changing 'encoding'. Beware
2183 * that 0x80 is escaped. */
2184 {
2185 char_u *p1 = mp->m_keys;
2186 char_u *p2 = mb_unescape(&p1);
2187
2188 if (has_mbyte && p2 != NULL
2189 && MB_BYTE2LEN(c1) > MB_PTR2LEN(p2))
2190 mlen = 0;
2191 }
2192 /*
2193 * Check an entry whether it matches.
2194 * - Full match: mlen == keylen
2195 * - Partly match: mlen == typebuf.tb_len
2196 */
2197 keylen = mp->m_keylen;
2198 if (mlen == keylen
2199 || (mlen == typebuf.tb_len
2200 && typebuf.tb_len < keylen))
2201 {
2202 /*
2203 * If only script-local mappings are
2204 * allowed, check if the mapping starts
2205 * with K_SNR.
2206 */
2207 s = typebuf.tb_noremap + typebuf.tb_off;
2208 if (*s == RM_SCRIPT
2209 && (mp->m_keys[0] != K_SPECIAL
2210 || mp->m_keys[1] != KS_EXTRA
2211 || mp->m_keys[2]
2212 != (int)KE_SNR))
2213 continue;
2214 /*
2215 * If one of the typed keys cannot be
2216 * remapped, skip the entry.
2217 */
2218 for (n = mlen; --n >= 0; )
2219 if (*s++ & (RM_NONE|RM_ABBR))
2220 break;
2221 if (n >= 0)
2222 continue;
2223
2224 if (keylen > typebuf.tb_len)
2225 {
2226 if (!timedout && !(mp_match != NULL
2227 && mp_match->m_nowait))
2228 {
2229 /* break at a partly match */
2230 keylen = KEYLEN_PART_MAP;
2231 break;
2232 }
2233 }
2234 else if (keylen > mp_match_len)
2235 {
2236 /* found a longer match */
2237 mp_match = mp;
2238 mp_match_len = keylen;
2239 }
2240 }
2241 else
2242 /* No match; may have to check for
2243 * termcode at next character. */
2244 if (max_mlen < mlen)
2245 max_mlen = mlen;
2246 }
2247 }
2248
2249 /* If no partly match found, use the longest full
2250 * match. */
2251 if (keylen != KEYLEN_PART_MAP)
2252 {
2253 mp = mp_match;
2254 keylen = mp_match_len;
2255 }
2256 }
2257
2258 /* Check for match with 'pastetoggle' */
2259 if (*p_pt != NUL && mp == NULL && (State & (INSERT|NORMAL)))
2260 {
2261 for (mlen = 0; mlen < typebuf.tb_len && p_pt[mlen];
2262 ++mlen)
2263 if (p_pt[mlen] != typebuf.tb_buf[typebuf.tb_off
2264 + mlen])
2265 break;
2266 if (p_pt[mlen] == NUL) /* match */
2267 {
2268 /* write chars to script file(s) */
2269 if (mlen > typebuf.tb_maplen)
2270 gotchars(typebuf.tb_buf + typebuf.tb_off
2271 + typebuf.tb_maplen,
2272 mlen - typebuf.tb_maplen);
2273
2274 del_typebuf(mlen, 0); /* remove the chars */
2275 set_option_value((char_u *)"paste",
2276 (long)!p_paste, NULL, 0);
2277 if (!(State & INSERT))
2278 {
2279 msg_col = 0;
2280 msg_row = Rows - 1;
2281 msg_clr_eos(); /* clear ruler */
2282 }
2283 status_redraw_all();
2284 redraw_statuslines();
2285 showmode();
2286 setcursor();
2287 continue;
2288 }
2289 /* Need more chars for partly match. */
2290 if (mlen == typebuf.tb_len)
2291 keylen = KEYLEN_PART_KEY;
2292 else if (max_mlen < mlen)
2293 /* no match, may have to check for termcode at
2294 * next character */
2295 max_mlen = mlen + 1;
2296 }
2297
2298 if ((mp == NULL || max_mlen >= mp_match_len)
2299 && keylen != KEYLEN_PART_MAP)
2300 {
2301 int save_keylen = keylen;
2302
2303 /*
2304 * When no matching mapping found or found a
2305 * non-matching mapping that matches at least what the
2306 * matching mapping matched:
2307 * Check if we have a terminal code, when:
2308 * mapping is allowed,
2309 * keys have not been mapped,
2310 * and not an ESC sequence, not in insert mode or
2311 * p_ek is on,
2312 * and when not timed out,
2313 */
2314 if ((no_mapping == 0 || allow_keys != 0)
2315 && (typebuf.tb_maplen == 0
2316 || (p_remap && typebuf.tb_noremap[
2317 typebuf.tb_off] == RM_YES))
2318 && !timedout)
2319 {
2320 keylen = check_termcode(max_mlen + 1,
2321 NULL, 0, NULL);
2322
2323 /* If no termcode matched but 'pastetoggle'
2324 * matched partially it's like an incomplete key
2325 * sequence. */
2326 if (keylen == 0 && save_keylen == KEYLEN_PART_KEY)
2327 keylen = KEYLEN_PART_KEY;
2328
2329 /*
2330 * When getting a partial match, but the last
2331 * characters were not typed, don't wait for a
2332 * typed character to complete the termcode.
2333 * This helps a lot when a ":normal" command ends
2334 * in an ESC.
2335 */
2336 if (keylen < 0
2337 && typebuf.tb_len == typebuf.tb_maplen)
2338 keylen = 0;
2339 }
2340 else
2341 keylen = 0;
2342 if (keylen == 0) /* no matching terminal code */
2343 {
2344 #ifdef AMIGA /* check for window bounds report */
2345 if (typebuf.tb_maplen == 0 && (typebuf.tb_buf[
2346 typebuf.tb_off] & 0xff) == CSI)
2347 {
2348 for (s = typebuf.tb_buf + typebuf.tb_off + 1;
2349 s < typebuf.tb_buf + typebuf.tb_off
2350 + typebuf.tb_len
2351 && (VIM_ISDIGIT(*s) || *s == ';'
2352 || *s == ' ');
2353 ++s)
2354 ;
2355 if (*s == 'r' || *s == '|') /* found one */
2356 {
2357 del_typebuf((int)(s + 1 -
2358 (typebuf.tb_buf + typebuf.tb_off)), 0);
2359 /* get size and redraw screen */
2360 shell_resized();
2361 continue;
2362 }
2363 if (*s == NUL) /* need more characters */
2364 keylen = KEYLEN_PART_KEY;
2365 }
2366 if (keylen >= 0)
2367 #endif
2368 /* When there was a matching mapping and no
2369 * termcode could be replaced after another one,
2370 * use that mapping (loop around). If there was
2371 * no mapping use the character from the
2372 * typeahead buffer right here. */
2373 if (mp == NULL)
2374 {
2375 /*
2376 * get a character: 2. from the typeahead buffer
2377 */
2378 c = typebuf.tb_buf[typebuf.tb_off] & 255;
2379 if (advance) /* remove chars from tb_buf */
2380 {
2381 cmd_silent = (typebuf.tb_silent > 0);
2382 if (typebuf.tb_maplen > 0)
2383 KeyTyped = FALSE;
2384 else
2385 {
2386 KeyTyped = TRUE;
2387 /* write char to script file(s) */
2388 gotchars(typebuf.tb_buf
2389 + typebuf.tb_off, 1);
2390 }
2391 KeyNoremap = typebuf.tb_noremap[
2392 typebuf.tb_off];
2393 del_typebuf(1, 0);
2394 }
2395 break; /* got character, break for loop */
2396 }
2397 }
2398 if (keylen > 0) /* full matching terminal code */
2399 {
2400 #if defined(FEAT_GUI) && defined(FEAT_MENU)
2401 if (typebuf.tb_len >= 2
2402 && typebuf.tb_buf[typebuf.tb_off] == K_SPECIAL
2403 && typebuf.tb_buf[typebuf.tb_off + 1]
2404 == KS_MENU)
2405 {
2406 /*
2407 * Using a menu may cause a break in undo!
2408 * It's like using gotchars(), but without
2409 * recording or writing to a script file.
2410 */
2411 may_sync_undo();
2412 del_typebuf(3, 0);
2413 idx = get_menu_index(current_menu, local_State);
2414 if (idx != MENU_INDEX_INVALID)
2415 {
2416 /*
2417 * In Select mode and a Visual mode menu
2418 * is used: Switch to Visual mode
2419 * temporarily. Append K_SELECT to switch
2420 * back to Select mode.
2421 */
2422 if (VIsual_active && VIsual_select
2423 && (current_menu->modes & VISUAL))
2424 {
2425 VIsual_select = FALSE;
2426 (void)ins_typebuf(K_SELECT_STRING,
2427 REMAP_NONE, 0, TRUE, FALSE);
2428 }
2429 ins_typebuf(current_menu->strings[idx],
2430 current_menu->noremap[idx],
2431 0, TRUE,
2432 current_menu->silent[idx]);
2433 }
2434 }
2435 #endif /* FEAT_GUI && FEAT_MENU */
2436 continue; /* try mapping again */
2437 }
2438
2439 /* Partial match: get some more characters. When a
2440 * matching mapping was found use that one. */
2441 if (mp == NULL || keylen < 0)
2442 keylen = KEYLEN_PART_KEY;
2443 else
2444 keylen = mp_match_len;
2445 }
2446
2447 /* complete match */
2448 if (keylen >= 0 && keylen <= typebuf.tb_len)
2449 {
2450 #ifdef FEAT_EVAL
2451 int save_m_expr;
2452 int save_m_noremap;
2453 int save_m_silent;
2454 char_u *save_m_keys;
2455 char_u *save_m_str;
2456 #else
2457 # define save_m_noremap mp->m_noremap
2458 # define save_m_silent mp->m_silent
2459 #endif
2460
2461 /* write chars to script file(s) */
2462 if (keylen > typebuf.tb_maplen)
2463 gotchars(typebuf.tb_buf + typebuf.tb_off
2464 + typebuf.tb_maplen,
2465 keylen - typebuf.tb_maplen);
2466
2467 cmd_silent = (typebuf.tb_silent > 0);
2468 del_typebuf(keylen, 0); /* remove the mapped keys */
2469
2470 /*
2471 * Put the replacement string in front of mapstr.
2472 * The depth check catches ":map x y" and ":map y x".
2473 */
2474 if (++mapdepth >= p_mmd)
2475 {
2476 emsg(_("E223: recursive mapping"));
2477 if (State & CMDLINE)
2478 redrawcmdline();
2479 else
2480 setcursor();
2481 flush_buffers(FLUSH_MINIMAL);
2482 mapdepth = 0; /* for next one */
2483 c = -1;
2484 break;
2485 }
2486
2487 /*
2488 * In Select mode and a Visual mode mapping is used:
2489 * Switch to Visual mode temporarily. Append K_SELECT
2490 * to switch back to Select mode.
2491 */
2492 if (VIsual_active && VIsual_select
2493 && (mp->m_mode & VISUAL))
2494 {
2495 VIsual_select = FALSE;
2496 (void)ins_typebuf(K_SELECT_STRING, REMAP_NONE,
2497 0, TRUE, FALSE);
2498 }
2499
2500 #ifdef FEAT_EVAL
2501 /* Copy the values from *mp that are used, because
2502 * evaluating the expression may invoke a function
2503 * that redefines the mapping, thereby making *mp
2504 * invalid. */
2505 save_m_expr = mp->m_expr;
2506 save_m_noremap = mp->m_noremap;
2507 save_m_silent = mp->m_silent;
2508 save_m_keys = NULL; /* only saved when needed */
2509 save_m_str = NULL; /* only saved when needed */
2510
2511 /*
2512 * Handle ":map <expr>": evaluate the {rhs} as an
2513 * expression. Also save and restore the command line
2514 * for "normal :".
2515 */
2516 if (mp->m_expr)
2517 {
2518 int save_vgetc_busy = vgetc_busy;
2519 int save_may_garbage_collect = may_garbage_collect;
2520
2521 vgetc_busy = 0;
2522 may_garbage_collect = FALSE;
2523
2524 save_m_keys = vim_strsave(mp->m_keys);
2525 save_m_str = vim_strsave(mp->m_str);
2526 s = eval_map_expr(save_m_str, NUL);
2527
2528 vgetc_busy = save_vgetc_busy;
2529 may_garbage_collect = save_may_garbage_collect;
2530 }
2531 else
2532 #endif
2533 s = mp->m_str;
2534
2535 /*
2536 * Insert the 'to' part in the typebuf.tb_buf.
2537 * If 'from' field is the same as the start of the
2538 * 'to' field, don't remap the first character (but do
2539 * allow abbreviations).
2540 * If m_noremap is set, don't remap the whole 'to'
2541 * part.
2542 */
2543 if (s == NULL)
2544 i = FAIL;
2545 else
2546 {
2547 int noremap;
2548
2549 if (save_m_noremap != REMAP_YES)
2550 noremap = save_m_noremap;
2551 else if (
2552 #ifdef FEAT_EVAL
2553 STRNCMP(s, save_m_keys != NULL
2554 ? save_m_keys : mp->m_keys,
2555 (size_t)keylen)
2556 #else
2557 STRNCMP(s, mp->m_keys, (size_t)keylen)
2558 #endif
2559 != 0)
2560 noremap = REMAP_YES;
2561 else
2562 noremap = REMAP_SKIP;
2563 i = ins_typebuf(s, noremap,
2564 0, TRUE, cmd_silent || save_m_silent);
2565 #ifdef FEAT_EVAL
2566 if (save_m_expr)
2567 vim_free(s);
2568 #endif
2569 }
2570 #ifdef FEAT_EVAL
2571 vim_free(save_m_keys);
2572 vim_free(save_m_str);
2573 #endif
2574 if (i == FAIL)
2575 {
2576 c = -1;
2577 break;
2578 }
2594 continue; 2579 continue;
2595 if (result == map_result_fail)
2596 {
2597 // failed, use the outer loop
2598 c = -1;
2599 break;
2600 } 2580 }
2601 if (result == map_result_get)
2602 {
2603 /*
2604 * get a character: 2. from the typeahead buffer
2605 */
2606 c = typebuf.tb_buf[typebuf.tb_off] & 255;
2607 if (advance) /* remove chars from tb_buf */
2608 {
2609 cmd_silent = (typebuf.tb_silent > 0);
2610 if (typebuf.tb_maplen > 0)
2611 KeyTyped = FALSE;
2612 else
2613 {
2614 KeyTyped = TRUE;
2615 /* write char to script file(s) */
2616 gotchars(typebuf.tb_buf
2617 + typebuf.tb_off, 1);
2618 }
2619 KeyNoremap = typebuf.tb_noremap[
2620 typebuf.tb_off];
2621 del_typebuf(1, 0);
2622 }
2623 break;
2624 }
2625
2626 // not enough characters, get more
2627 } 2581 }
2628 2582
2629 /* 2583 /*
2630 * get a character: 3. from the user - handle <Esc> in Insert mode 2584 * get a character: 3. from the user - handle <Esc> in Insert mode
2631 */ 2585 */