diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-10-13 16:43:39 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-10-13 16:43:39 +0200 |
commit | 459fd785e4a8d044147a3f83a5fca8748528aa84 (patch) | |
tree | 52c679e08a445bac0f650bff4d8118d6eb190d7b /src | |
parent | 171a921b51101c1261040d28a8147c8829b675d3 (diff) |
patch 8.1.2145: cannot map <C-H> when modifyOtherKeys is enabledv8.1.2145
Problem: Cannot map <C-H> when modifyOtherKeys is enabled.
Solution: Add the <C-H> mapping twice, both with modifier and as 0x08. Use
only the first one when modifyOtherKeys has been detected.
Diffstat (limited to 'src')
-rw-r--r-- | src/eval.c | 3 | ||||
-rw-r--r-- | src/getchar.c | 5 | ||||
-rw-r--r-- | src/globals.h | 4 | ||||
-rw-r--r-- | src/gui_mac.c | 6 | ||||
-rw-r--r-- | src/gui_w32.c | 2 | ||||
-rw-r--r-- | src/highlight.c | 3 | ||||
-rw-r--r-- | src/if_ole.cpp | 2 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/map.c | 616 | ||||
-rw-r--r-- | src/menu.c | 3 | ||||
-rw-r--r-- | src/misc2.c | 57 | ||||
-rw-r--r-- | src/option.c | 2 | ||||
-rw-r--r-- | src/proto/misc2.pro | 6 | ||||
-rw-r--r-- | src/proto/term.pro | 2 | ||||
-rw-r--r-- | src/structs.h | 2 | ||||
-rw-r--r-- | src/term.c | 45 | ||||
-rw-r--r-- | src/terminal.c | 10 | ||||
-rw-r--r-- | src/testdir/test_termcodes.vim | 92 | ||||
-rw-r--r-- | src/usercmd.c | 2 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim.h | 6 |
21 files changed, 535 insertions, 337 deletions
diff --git a/src/eval.c b/src/eval.c index 0fe8fd34aa..ace1e013f5 100644 --- a/src/eval.c +++ b/src/eval.c @@ -3526,7 +3526,8 @@ get_string_tv(char_u **arg, typval_T *rettv, int evaluate) break; /* Special key, e.g.: "\<C-W>" */ - case '<': extra = trans_special(&p, name, TRUE, TRUE); + case '<': extra = trans_special(&p, name, TRUE, TRUE, + TRUE, NULL); if (extra != 0) { name += extra; diff --git a/src/getchar.c b/src/getchar.c index 0e4e3c3157..475bfca8e1 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -52,7 +52,7 @@ static int typeahead_char = 0; /* typeahead char that's not flushed */ */ static int block_redo = FALSE; -static int KeyNoremap = 0; /* remapping flags */ +static int KeyNoremap = 0; // remapping flags /* * Variables used by vgetorpeek() and flush_buffers(). @@ -1771,7 +1771,7 @@ vgetc(void) if (!no_reduce_keys) { // A modifier was not used for a mapping, apply it to ASCII - // keys. + // keys. Shift would already have been applied. if ((mod_mask & MOD_MASK_CTRL) && ((c >= '`' && c <= 0x7f) || (c >= '@' && c <= '_'))) @@ -2240,6 +2240,7 @@ handle_mapping( // Skip ":lmap" mappings if keys were mapped. if (mp->m_keys[0] == tb_c1 && (mp->m_mode & local_State) + && !(mp->m_simplified && seenModifyOtherKeys) && ((mp->m_mode & LANGMAP) == 0 || typebuf.tb_maplen == 0)) { #ifdef FEAT_LANGMAP diff --git a/src/globals.h b/src/globals.h index d790c82e78..014fca2ad4 100644 --- a/src/globals.h +++ b/src/globals.h @@ -1002,6 +1002,10 @@ EXTERN int ex_no_reprint INIT(= FALSE); // no need to print after z or p EXTERN int reg_recording INIT(= 0); // register for recording or zero EXTERN int reg_executing INIT(= 0); // register being executed or zero +// Set when a modifyOtherKeys sequence was seen, then simplified mappings will +// no longer be used. +EXTERN int seenModifyOtherKeys INIT(= FALSE); + EXTERN int no_mapping INIT(= FALSE); // currently no mapping allowed EXTERN int no_zero_mapping INIT(= 0); // mapping zero not allowed EXTERN int allow_keys INIT(= FALSE); // allow key codes when no_mapping diff --git a/src/gui_mac.c b/src/gui_mac.c index b43ed8506f..185cdee28e 100644 --- a/src/gui_mac.c +++ b/src/gui_mac.c @@ -2177,7 +2177,8 @@ gui_mac_unicode_key_event( key_char = simplify_key(key_char, (int *)&vimModifiers); /* Interpret META, include SHIFT, etc. */ - key_char = extract_modifiers(key_char, (int *)&vimModifiers); + key_char = extract_modifiers(key_char, (int *)&vimModifiers, + TRUE, NULL); if (key_char == CSI) key_char = K_CSI; @@ -4772,7 +4773,8 @@ gui_mch_add_menu_item(vimmenu_T *menu, int idx) char_u *p_actext; p_actext = menu->actext; - key = find_special_key(&p_actext, &modifiers, FALSE, FALSE, FALSE); + key = find_special_key(&p_actext, &modifiers, FALSE, FALSE, FALSE, + TRUE, NULL); if (*p_actext != 0) key = 0; /* error: trailing text */ /* find_special_key() returns a keycode with as many of the diff --git a/src/gui_w32.c b/src/gui_w32.c index 61b09e1395..ae47873e4e 100644 --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -850,7 +850,7 @@ _OnSysChar( modifiers &= ~MOD_MASK_SHIFT; /* Interpret the ALT key as making the key META, include SHIFT, etc. */ - ch = extract_modifiers(ch, &modifiers); + ch = extract_modifiers(ch, &modifiers, TRUE, NULL); if (ch == CSI) ch = K_CSI; diff --git a/src/highlight.c b/src/highlight.c index 0fdd93a267..1333362dbd 100644 --- a/src/highlight.c +++ b/src/highlight.c @@ -1417,7 +1417,8 @@ do_highlight( */ for (p = arg, off = 0; off < 100 - 6 && *p; ) { - len = trans_special(&p, buf + off, FALSE, FALSE); + len = trans_special(&p, buf + off, FALSE, FALSE, + TRUE, NULL); if (len > 0) // recognized special char off += len; else // copy as normal char diff --git a/src/if_ole.cpp b/src/if_ole.cpp index cb643e5461..34ce232660 100644 --- a/src/if_ole.cpp +++ b/src/if_ole.cpp @@ -330,7 +330,7 @@ CVim::SendKeys(BSTR keys) } /* Translate key codes like <Esc> */ - str = replace_termcodes((char_u *)buffer, &ptr, FALSE, TRUE, FALSE); + str = replace_termcodes((char_u *)buffer, &ptr, REPTERM_DO_LT, NULL); /* If ptr was set, then a new buffer was allocated, * so we can free the old one. diff --git a/src/main.c b/src/main.c index 33ac89c097..5545cc48a6 100644 --- a/src/main.c +++ b/src/main.c @@ -4339,7 +4339,7 @@ server_to_input_buf(char_u *str) * <lt> sequence is recognised - needed for a real backslash. */ p_cpo = (char_u *)"Bk"; - str = replace_termcodes((char_u *)str, &ptr, FALSE, TRUE, FALSE); + str = replace_termcodes((char_u *)str, &ptr, REPTERM_DO_LT, NULL); p_cpo = cpo_save; if (*ptr != NUL) /* trailing CTRL-V results in nothing */ @@ -256,18 +256,15 @@ do_map( char_u *p; int n; int len = 0; // init for GCC - char_u *newstr; int hasarg; int haskey; - int did_it = FALSE; - int did_local = FALSE; - int round; + int do_print; + int keyround; char_u *keys_buf = NULL; + char_u *alt_keys_buf = NULL; char_u *arg_buf = NULL; int retval = 0; int do_backslash; - int hash; - int new_hash; mapblock_T **abbr_table; mapblock_T **map_table; int unique = FALSE; @@ -277,6 +274,7 @@ do_map( #ifdef FEAT_EVAL int expr = FALSE; #endif + int did_simplify = FALSE; int noremap; char_u *orig_rhs; @@ -375,6 +373,7 @@ do_map( rhs = p; hasarg = (*rhs != NUL); haskey = (*keys != NUL); + do_print = !haskey || (maptype != 1 && !hasarg); // check for :unmap without argument if (maptype == 1 && !haskey) @@ -389,373 +388,427 @@ do_map( // replace_termcodes() may move the result to allocated memory, which // needs to be freed later (*keys_buf and *arg_buf). // replace_termcodes() also removes CTRL-Vs and sometimes backslashes. + // If something like <C-H> is simplified to 0x08 then mark it as simplified + // and also add a n entry with a modifier, which will work when + // modifyOtherKeys is working. if (haskey) - keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, special); + { + char_u *new_keys; + int flags = REPTERM_FROM_PART | REPTERM_DO_LT; + + if (special) + flags |= REPTERM_SPECIAL; + new_keys = replace_termcodes(keys, &keys_buf, flags, &did_simplify); + if (did_simplify) + (void)replace_termcodes(keys, &alt_keys_buf, + flags | REPTERM_NO_SIMPLIFY, NULL); + keys = new_keys; + } orig_rhs = rhs; if (hasarg) { if (STRICMP(rhs, "<nop>") == 0) // "<Nop>" means nothing rhs = (char_u *)""; else - rhs = replace_termcodes(rhs, &arg_buf, FALSE, TRUE, special); + rhs = replace_termcodes(rhs, &arg_buf, + REPTERM_DO_LT | (special ? REPTERM_SPECIAL : 0), NULL); } - // check arguments and translate function keys - if (haskey) + /* + * The following is done twice if we have two versions of keys: + * "alt_keys_buf" is not NULL. + */ + for (keyround = 1; keyround <= 2; ++keyround) { - len = (int)STRLEN(keys); - if (len > MAXMAPLEN) // maximum length of MAXMAPLEN chars + int did_it = FALSE; + int did_local = FALSE; + int round; + int hash; + int new_hash; + + if (keyround == 2) { - retval = 1; - goto theend; + if (alt_keys_buf == NULL) + break; + keys = alt_keys_buf; } + else if (alt_keys_buf != NULL && do_print) + // when printing always use the not-simplified map + keys = alt_keys_buf; - if (abbrev && maptype != 1) + // check arguments and translate function keys + if (haskey) { - // If an abbreviation ends in a keyword character, the - // rest must be all keyword-char or all non-keyword-char. - // Otherwise we won't be able to find the start of it in a - // vi-compatible way. - if (has_mbyte) + len = (int)STRLEN(keys); + if (len > MAXMAPLEN) // maximum length of MAXMAPLEN chars { - int first, last; - int same = -1; - - first = vim_iswordp(keys); - last = first; - p = keys + (*mb_ptr2len)(keys); - n = 1; - while (p < keys + len) - { - ++n; // nr of (multi-byte) chars - last = vim_iswordp(p); // type of last char - if (same == -1 && last != first) - same = n - 1; // count of same char type - p += (*mb_ptr2len)(p); - } - if (last && n > 2 && same >= 0 && same < n - 1) + retval = 1; + goto theend; + } + + if (abbrev && maptype != 1) + { + // If an abbreviation ends in a keyword character, the + // rest must be all keyword-char or all non-keyword-char. + // Otherwise we won't be able to find the start of it in a + // vi-compatible way. + if (has_mbyte) { - retval = 1; - goto theend; + int first, last; + int same = -1; + + first = vim_iswordp(keys); + last = first; + p = keys + (*mb_ptr2len)(keys); + n = 1; + while (p < keys + len) + { + ++n; // nr of (multi-byte) chars + last = vim_iswordp(p); // type of last char + if (same == -1 && last != first) + same = n - 1; // count of same char type + p += (*mb_ptr2len)(p); + } + if (last && n > 2 && same >= 0 && same < n - 1) + { + retval = 1; + goto theend; + } } - } - else if (vim_iswordc(keys[len - 1])) // ends in keyword char + else if (vim_iswordc(keys[len - 1])) + // ends in keyword char for (n = 0; n < len - 2; ++n) if (vim_iswordc(keys[n]) != vim_iswordc(keys[len - 2])) { retval = 1; goto theend; } - // An abbreviation cannot contain white space. - for (n = 0; n < len; ++n) - if (VIM_ISWHITE(keys[n])) - { - retval = 1; - goto theend; - } + // An abbreviation cannot contain white space. + for (n = 0; n < len; ++n) + if (VIM_ISWHITE(keys[n])) + { + retval = 1; + goto theend; + } + } } - } - if (haskey && hasarg && abbrev) // if we will add an abbreviation - no_abbr = FALSE; // reset flag that indicates there are + if (haskey && hasarg && abbrev) // if we will add an abbreviation + no_abbr = FALSE; // reset flag that indicates there are // no abbreviations - if (!haskey || (maptype != 1 && !hasarg)) - msg_start(); + if (do_print) + msg_start(); - // Check if a new local mapping wasn't already defined globally. - if (map_table == curbuf->b_maphash && haskey && hasarg && maptype != 1) - { - // need to loop over all global hash lists - for (hash = 0; hash < 256 && !got_int; ++hash) + // Check if a new local mapping wasn't already defined globally. + if (map_table == curbuf->b_maphash && haskey && hasarg && maptype != 1) { - if (abbrev) - { - if (hash != 0) // there is only one abbreviation list - break; - mp = first_abbr; - } - else - mp = maphash[hash]; - for ( ; mp != NULL && !got_int; mp = mp->m_next) + // need to loop over all global hash lists + for (hash = 0; hash < 256 && !got_int; ++hash) { - // check entries with the same mode - if ((mp->m_mode & mode) != 0 - && mp->m_keylen == len - && unique - && STRNCMP(mp->m_keys, keys, (size_t)len) == 0) + if (abbrev) { - if (abbrev) - semsg(_("E224: global abbreviation already exists for %s"), - mp->m_keys); - else - semsg(_("E225: global mapping already exists for %s"), - mp->m_keys); - retval = 5; - goto theend; + if (hash != 0) // there is only one abbreviation list + break; + mp = first_abbr; + } + else + mp = maphash[hash]; + for ( ; mp != NULL && !got_int; mp = mp->m_next) + { + // check entries with the same mode + if ((mp->m_mode & mode) != 0 + && mp->m_keylen == len + && unique + && STRNCMP(mp->m_keys, keys, (size_t)len) == 0) + { + if (abbrev) + semsg(_( + "E224: global abbreviation already exists for %s"), + mp->m_keys); + else + semsg(_( + "E225: global mapping already exists for %s"), + mp->m_keys); + retval = 5; + goto theend; + } } } } - } - // When listing global mappings, also list buffer-local ones here. - if (map_table != curbuf->b_maphash && !hasarg && maptype != 1) - { - // need to loop over all global hash lists - for (hash = 0; hash < 256 && !got_int; ++hash) + // When listing global mappings, also list buffer-local ones here. + if (map_table != curbuf->b_maphash && !hasarg && maptype != 1) { - if (abbrev) - { - if (hash != 0) // there is only one abbreviation list - break; - mp = curbuf->b_first_abbr; - } - else - mp = curbuf->b_maphash[hash]; - for ( ; mp != NULL && !got_int; mp = mp->m_next) + // need to loop over all global hash lists + for (hash = 0; hash < 256 && !got_int; ++hash) { - // check entries with the same mode - if ((mp->m_mode & mode) != 0) + if (abbrev) { - if (!haskey) // show all entries - { - showmap(mp, TRUE); - did_local = TRUE; - } - else + if (hash != 0) // there is only one abbreviation list + break; + mp = curbuf->b_first_abbr; + } + else + mp = curbuf->b_maphash[hash]; + for ( ; mp != NULL && !got_int; mp = mp->m_next) + { + // check entries with the same mode + if ((mp->m_mode & mode) != 0) { - n = mp->m_keylen; - if (STRNCMP(mp->m_keys, keys, - (size_t)(n < len ? n : len)) == 0) + if (!haskey) // show all entries { showmap(mp, TRUE); did_local = TRUE; } + else + { + n = mp->m_keylen; + if (STRNCMP(mp->m_keys, keys, + (size_t)(n < len ? n : len)) == 0) + { + showmap(mp, TRUE); + did_local = TRUE; + } + } } } } } - } - // Find an entry in the maphash[] list that matches. - // For :unmap we may loop two times: once to try to unmap an entry with a - // matching 'from' part, a second time, if the first fails, to unmap an - // entry with a matching 'to' part. This was done to allow ":ab foo bar" - // to be unmapped by typing ":unab foo", where "foo" will be replaced by - // "bar" because of the abbreviation. - for (round = 0; (round == 0 || maptype == 1) && round <= 1 - && !did_it && !got_int; ++round) - { - // need to loop over all hash lists - for (hash = 0; hash < 256 && !got_int; ++hash) + // Find an entry in the maphash[] list that matches. + // For :unmap we may loop two times: once to try to unmap an entry with + // a matching 'from' part, a second time, if the first fails, to unmap + // an entry with a matching 'to' part. This was done to allow ":ab foo + // bar" to be unmapped by typing ":unab foo", where "foo" will be + // replaced by "bar" because of the abbreviation. + for (round = 0; (round == 0 || maptype == 1) && round <= 1 + && !did_it && !got_int; ++round) { - if (abbrev) + // need to loop over all hash lists + for (hash = 0; hash < 256 && !got_int; ++hash) { - if (hash > 0) // there is only one abbreviation list - break; - mpp = abbr_table; - } - else - mpp = &(map_table[hash]); - for (mp = *mpp; mp != NULL && !got_int; mp = *mpp) - { - - if (!(mp->m_mode & mode)) // skip entries with wrong mode + if (abbrev) { - mpp = &(mp->m_next); - continue; - } - if (!haskey) // show all entries - { - showmap(mp, map_table != maphash); - did_it = TRUE; + if (hash > 0) // there is only one abbreviation list + break; + mpp = abbr_table; } - else // do we have a match? + else + mpp = &(map_table[hash]); + for (mp = *mpp; mp != NULL && !got_int; mp = *mpp) { - if (round) // second round: Try unmap "rhs" string + + if (!(mp->m_mode & mode)) // skip entries with wrong mode { - n = (int)STRLEN(mp->m_str); - p = mp->m_str; + mpp = &(mp->m_next); + continue; } - else + if (!haskey) // show all entries { - n = mp->m_keylen; - p = mp->m_keys; + showmap(mp, map_table != maphash); + did_it = TRUE; } - if (STRNCMP(p, keys, (size_t)(n < len ? n : len)) == 0) + else // do we have a match? { - if (maptype == 1) // delete entry + if (round) // second round: Try unmap "rhs" string { - // Only accept a full match. For abbreviations we - // ignore trailing space when matching with the - // "lhs", since an abbreviation can't have - // trailing space. - if (n != len && (!abbrev || round || n > len + n = (int)STRLEN(mp->m_str); + p = mp->m_str; + } + else + { + n = mp->m_keylen; + p = mp->m_keys; + } + if (STRNCMP(p, keys, (size_t)(n < len ? n : len)) == 0) + { + if (maptype == 1) + { + // Delete entry. + // Only accept a full match. For abbreviations + // we ignore trailing space when matching with + // the "lhs", since an abbreviation can't have + // trailing space. + if (n != len && (!abbrev || round || n > len || *skipwhite(keys + n) != NUL)) + { + mpp = &(mp->m_next); + continue; + } + // We reset the indicated mode bits. If nothing + // is left the entry is deleted below. + mp->m_mode &= ~mode; + did_it = TRUE; // remember we did something + } + else if (!hasarg) // show matching entry + { + showmap(mp, map_table != maphash); + did_it = TRUE; + } + else if (n != len) // new entry is ambiguous { mpp = &(mp->m_next); continue; } - // We reset the indicated mode bits. If nothing is - // left the entry is deleted below. - mp->m_mode &= ~mode; - did_it = TRUE; // remember we did something - } - else if (!hasarg) // show matching entry - { - showmap(mp, map_table != maphash); - did_it = TRUE; - } - else if (n != len) // new entry is ambiguous - { - mpp = &(mp->m_next); - continue; - } - else if (unique) - { - if (abbrev) - semsg(_("E226: abbreviation already exists for %s"), - p); + else if (unique) + { + if (abbrev) + semsg(_( + "E226: abbreviation already exists for %s"), + p); + else + semsg(_( + "E227: mapping already exists for %s"), + p); + retval = 5; + goto theend; + } else - semsg(_("E227: mapping already exists for %s"), p); - retval = 5; - goto theend; - } - else // new rhs for existing entry - { - mp->m_mode &= ~mode; // remove mode bits - if (mp->m_mode == 0 && !did_it) // reuse entry { - newstr = vim_strsave(rhs); - if (newstr == NULL) + // new rhs for existing entry + mp->m_mode &= ~mode; // remove mode bits + if (mp->m_mode == 0 && !did_it) // reuse entry { - retval = 4; // no mem - goto theend; - } - vim_free(mp->m_str); - mp->m_str = newstr; - vim_free(mp->m_orig_str); - mp->m_orig_str = vim_strsave(orig_rhs); - mp->m_noremap = noremap; - mp->m_nowait = nowait; - mp->m_silent = silent; - mp->m_mode = mode; + char_u *newstr = vim_strsave(rhs); + + if (newstr == NULL) + { + retval = 4; // no mem + goto theend; + } + vim_free(mp->m_str); + mp->m_str = newstr; + vim_free(mp->m_orig_str); + mp->m_orig_str = vim_strsave(orig_rhs); + mp->m_noremap = noremap; + mp->m_nowait = nowait; + mp->m_silent = silent; + mp->m_mode = mode; + mp->m_simplified = + did_simplify && keyround == 1; #ifdef FEAT_EVAL - mp->m_expr = expr; - mp->m_script_ctx = current_sctx; - mp->m_script_ctx.sc_lnum += sourcing_lnum; + mp->m_expr = expr; + mp->m_script_ctx = current_sctx; + mp->m_script_ctx.sc_lnum += sourcing_lnum; #endif - did_it = TRUE; + did_it = TRUE; + } + } + if (mp->m_mode == 0) // entry can be deleted + { + map_free(mpp); + continue; // continue with *mpp } - } - if (mp->m_mode == 0) // entry can be deleted - { - map_free(mpp); - continue; // continue with *mpp - } - // May need to put this entry into another hash list. - new_hash = MAP_HASH(mp->m_mode, mp->m_keys[0]); - if (!abbrev && new_hash != hash) - { - *mpp = mp->m_next; - mp->m_next = map_table[new_hash]; - map_table[new_hash] = mp; + // May need to put this entry into another hash + // list. + new_hash = MAP_HASH(mp->m_mode, mp->m_keys[0]); + if (!abbrev && new_hash != hash) + { + *mpp = mp->m_next; + mp->m_next = map_table[new_hash]; + map_table[new_hash] = mp; - continue; // continue with *mpp + continue; // continue with *mpp + } } } + mpp = &(mp->m_next); } - mpp = &(mp->m_next); } } - } - if (maptype == 1) // delete entry - { - if (!did_it) - retval = 2; // no match - else if (*keys == Ctrl_C) + if (maptype == 1) { - // If CTRL-C has been unmapped, reuse it for Interrupting. - if (map_table == curbuf->b_maphash) - curbuf->b_mapped_ctrl_c &= ~mode; - else - mapped_ctrl_c &= ~mode; + // delete entry + if (!did_it) + retval = 2; // no match + else if (*keys == Ctrl_C) + { + // If CTRL-C has been unmapped, reuse it for Interrupting. + if (map_table == curbuf->b_maphash) + curbuf->b_mapped_ctrl_c &= ~mode; + else + mapped_ctrl_c &= ~mode; + } + continue; } - goto theend; - } - if (!haskey || !hasarg) // print entries - { - if (!did_it && !did_local) + if (!haskey || !hasarg) { - if (abbrev) - msg(_("No abbreviation found")); - else - msg(_("No mapping found")); + // print entries + if (!did_it && !did_local) + { + if (abbrev) + msg(_("No abbreviation found")); + else + msg(_("No mapping found")); + } + goto theend; // listing finished } - goto theend; // listing finished - } - if (did_it) // have added the new entry already - goto theend; + if (did_it) + continue; // have added the new entry already - // Get here when adding a new entry to the maphash[] list or abbrlist. - mp = ALLOC_ONE(mapblock_T); - if (mp == NULL) - { - retval = 4; // no mem - goto theend; - } + // Get here when adding a new entry to the maphash[] list or abbrlist. + mp = ALLOC_ONE(mapblock_T); + if (mp == NULL) + { + retval = 4; // no mem + goto theend; + } - // If CTRL-C has been mapped, don't always use it for Interrupting. - if (*keys == Ctrl_C) - { - if (map_table == curbuf->b_maphash) - curbuf->b_mapped_ctrl_c |= mode; - else - mapped_ctrl_c |= mode; - } + // If CTRL-C has been mapped, don't always use it for Interrupting. + if (*keys == Ctrl_C) + { + if (map_table == curbuf->b_maphash) + curbuf->b_mapped_ctrl_c |= mode; + else + mapped_ctrl_c |= mode; + } - mp->m_keys = vim_strsave(keys); - mp->m_str = vim_strsave(rhs); - mp->m_orig_str = vim_strsave(orig_rhs); - if (mp->m_keys == NULL || mp->m_str == NULL) - { - vim_free(mp->m_keys); - vim_free(mp->m_str); - vim_free(mp->m_orig_str); - vim_free(mp); - retval = 4; // no mem - goto theend; - } - mp->m_keylen = (int)STRLEN(mp->m_keys); - mp->m_noremap = noremap; - mp->m_nowait = nowait; - mp->m_silent = silent; - mp->m_mode = mode; + mp->m_keys = vim_strsave(keys); + mp->m_str = vim_strsave(rhs); + mp->m_orig_str = vim_strsave(orig_rhs); + if (mp->m_keys == NULL || mp->m_str == NULL) + { + vim_free(mp->m_keys); + vim_free(mp->m_str); + vim_free(mp->m_orig_str); + vim_free(mp); + retval = 4; // no mem + goto theend; + } + mp->m_keylen = (int)STRLEN(mp->m_keys); + mp->m_noremap = noremap; + mp->m_nowait = nowait; + mp->m_silent = silent; + mp->m_mode = mode; + mp->m_simplified = did_simplify && keyround == 1; #ifdef FEAT_EVAL - mp->m_expr = expr; - mp->m_script_ctx = current_sctx; - mp->m_script_ctx.sc_lnum += sourcing_lnum; + mp->m_expr = expr; + mp->m_script_ctx = current_sctx; + mp->m_script_ctx.sc_lnum += sourcing_lnum; #endif - // add the new entry in front of the abbrlist or maphash[] list - if (abbrev) - { - mp->m_next = *abbr_table; - *abbr_table = mp; - } - else - { - n = MAP_HASH(mp->m_mode, mp->m_keys[0]); - mp->m_next = map_table[n]; - map_table[n] = mp; + // add the new entry in front of the abbrlist or maphash[] list + if (abbrev) + { + mp->m_next = *abbr_table; + *abbr_table = mp; + } + else + { + n = MAP_HASH(mp->m_mode, mp->m_keys[0]); + mp->m_next = map_table[n]; + map_table[n] = mp; + } } theend: vim_free(keys_buf); + vim_free(alt_keys_buf); vim_free(arg_buf); return retval; } @@ -934,7 +987,7 @@ map_to_exists(char_u *str, char_u *modechars, int abbr) char_u *buf; int retval; - rhs = replace_termcodes(str, &buf, FALSE, TRUE, FALSE); + rhs = replace_termcodes(str, &buf, REPTERM_DO_LT, NULL); retval = map_to_exists_mode(rhs, mode_str2flags(modechars), abbr); vim_free(buf); @@ -2036,7 +2089,8 @@ get_maparg(typval_T *argvars, typval_T *rettv, int exact) mode = get_map_mode(&which, 0); - keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, FALSE); + keys = replace_termcodes(keys, &keys_buf, + REPTERM_FROM_PART | REPTERM_DO_LT, NULL); rhs = check_map(keys, mode, exact, FALSE, abbr, &mp, &buffer_local); vim_free(keys_buf); diff --git a/src/menu.c b/src/menu.c index 4096a0571c..e55cab6758 100644 --- a/src/menu.c +++ b/src/menu.c @@ -372,7 +372,8 @@ ex_menu( else if (modes & MENU_TIP_MODE) map_buf = NULL; /* Menu tips are plain text. */ else - map_to = replace_termcodes(map_to, &map_buf, FALSE, TRUE, special); + map_to = replace_termcodes(map_to, &map_buf, + REPTERM_DO_LT | (special ? REPTERM_SPECIAL : 0), NULL); menuarg.modes = modes; #ifdef FEAT_TOOLBAR menuarg.iconfile = icon; diff --git a/src/misc2.c b/src/misc2.c index 3261437db2..67fa8b5eed 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -2696,12 +2696,15 @@ trans_special( char_u **srcp, char_u *dst, int keycode, // prefer key code, e.g. K_DEL instead of DEL - int in_string) // TRUE when inside a double quoted string + int in_string, // TRUE when inside a double quoted string + int simplify, // simplify <C-H> and <A-x> + int *did_simplify) // found <C-H> or <A-x> { int modifiers = 0; int key; - key = find_special_key(srcp, &modifiers, keycode, FALSE, in_string); + key = find_special_key(srcp, &modifiers, keycode, FALSE, in_string, + simplify, did_simplify); if (key == 0) return 0; @@ -2753,9 +2756,11 @@ special_to_buf(int key, int modifiers, int keycode, char_u *dst) find_special_key( char_u **srcp, int *modp, - int keycode, /* p |