Mercurial > vim
changeset 5035:1cf89d38aa76 v7.3.1261
updated for version 7.3.1261
Problem: A buffer-local language mapping from a keymap stops a global
insert mode mapping from working. (Ron Aaron)
Solution: Do not wait for more characters to be typed only when the mapping
was defined with <nowait>.
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Sat, 29 Jun 2013 13:58:31 +0200 |
parents | 08e325ff4a8a |
children | 99268315fa88 |
files | runtime/doc/map.txt src/eval.c src/getchar.c src/testdir/test75.in src/testdir/test75.ok src/version.c |
diffstat | 6 files changed, 50 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/runtime/doc/map.txt +++ b/runtime/doc/map.txt @@ -159,9 +159,9 @@ type "a", then "bar" will get inserted. 1.2 SPECIAL ARGUMENTS *:map-arguments* -"<buffer>", "<silent>", "<special>", "<script>", "<expr>" and "<unique>" can -be used in any order. They must appear right after the command, before any -other arguments. +"<buffer>", "<nowait>", "<silent>", "<special>", "<script>", "<expr>" and +"<unique>" can be used in any order. They must appear right after the +command, before any other arguments. *:map-local* *:map-<buffer>* *E224* *E225* If the first argument to one of these commands is "<buffer>" the mapping will @@ -169,7 +169,9 @@ be effective in the current buffer only. :map <buffer> ,w /[.,;]<CR> Then you can map ",w" to something else in another buffer: > :map <buffer> ,w /[#&!]<CR> -The local buffer mappings are used before the global ones. +The local buffer mappings are used before the global ones. See <nowait> below +to make a short local mapping not taking effect when a longer global one +exists. The "<buffer>" argument can also be used to clear mappings: > :unmap <buffer> ,w :mapclear <buffer> @@ -177,6 +179,14 @@ Local mappings are also cleared when a b unloaded. Just like local option values. Also see |map-precedence|. + *:map-<nowait>* *:map-nowait* +When defining a buffer-local mapping for "," there may be a global mapping +that starts with ",". Then you need to type another character for Vim to know +whether to use the "," mapping or the longer one. To avoid this add the +<nowait> argument. Then the mapping will be used when it matches, Vim does +not wait for more characters to be typed. However, if the characters were +already type they are used. + *:map-<silent>* *:map-silent* To define a mapping which will not be echoed on the command line, add "<silent>" as the first argument. Example: >
--- a/src/eval.c +++ b/src/eval.c @@ -13735,6 +13735,7 @@ get_maparg(argvars, rettv, exact) dict_add_nr_str(dict, "silent", mp->m_silent ? 1L : 0L, NULL); dict_add_nr_str(dict, "sid", (long)mp->m_script_ID, NULL); dict_add_nr_str(dict, "buffer", (long)buffer_local, NULL); + dict_add_nr_str(dict, "nowait", mp->m_nowait ? 1L : 0L, NULL); dict_add_nr_str(dict, "mode", 0L, mapmode); vim_free(lhs);
--- a/src/getchar.c +++ b/src/getchar.c @@ -1924,7 +1924,6 @@ vgetorpeek(advance) mapblock_T *mp; #ifdef FEAT_LOCALMAP mapblock_T *mp2; - int expecting_global_mappings; #endif mapblock_T *mp_match; int mp_match_len = 0; @@ -2106,9 +2105,9 @@ vgetorpeek(advance) /* First try buffer-local mappings. */ mp = curbuf->b_maphash[MAP_HASH(local_State, c1)]; mp2 = maphash[MAP_HASH(local_State, c1)]; - expecting_global_mappings = (mp && mp2); if (mp == NULL) { + /* There are no buffer-local mappings. */ mp = mp2; mp2 = NULL; } @@ -2130,16 +2129,6 @@ vgetorpeek(advance) #endif (mp = mp->m_next)) { -#ifdef FEAT_LOCALMAP - if (expecting_global_mappings && mp2 == NULL) - { - /* This is the first global mapping. If we've - * got a complete buffer-local match, use it. */ - if (mp_match) - break; - expecting_global_mappings = FALSE; - } -#endif /* * Only consider an entry if the first character * matches and it is for the current state. @@ -2215,7 +2204,8 @@ vgetorpeek(advance) if (keylen > typebuf.tb_len) { - if (!timedout) + if (!timedout && !(mp_match != NULL + && mp_match->m_nowait)) { /* break at a partly match */ keylen = KEYLEN_PART_MAP; @@ -3207,6 +3197,7 @@ do_map(maptype, arg, mode, abbrev) mapblock_T **abbr_table; mapblock_T **map_table; int unique = FALSE; + int nowait = FALSE; int silent = FALSE; int special = FALSE; #ifdef FEAT_EVAL @@ -3225,7 +3216,8 @@ do_map(maptype, arg, mode, abbrev) else noremap = REMAP_YES; - /* Accept <buffer>, <silent>, <expr> <script> and <unique> in any order. */ + /* Accept <buffer>, <nowait>, <silent>, <expr> <script> and <unique> in + * any order. */ for (;;) { #ifdef FEAT_LOCALMAP @@ -3242,6 +3234,16 @@ do_map(maptype, arg, mode, abbrev) #endif /* + * Check for "<nowait>": don't wait for more characters. + */ + if (STRNCMP(keys, "<nowait>", 8) == 0) + { + keys = skipwhite(keys + 8); + nowait = TRUE; + continue; + } + + /* * Check for "<silent>": don't echo commands. */ if (STRNCMP(keys, "<silent>", 8) == 0) @@ -3607,6 +3609,7 @@ do_map(maptype, arg, mode, abbrev) 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; #ifdef FEAT_EVAL @@ -3695,6 +3698,7 @@ do_map(maptype, arg, mode, abbrev) } mp->m_keylen = (int)STRLEN(mp->m_keys); mp->m_noremap = noremap; + mp->m_nowait = nowait; mp->m_silent = silent; mp->m_mode = mode; #ifdef FEAT_EVAL @@ -4173,6 +4177,11 @@ set_context_in_map_cmd(xp, cmd, arg, for arg = skipwhite(arg + 8); continue; } + if (STRNCMP(arg, "<nowait>", 8) == 0) + { + arg = skipwhite(arg + 8); + continue; + } if (STRNCMP(arg, "<silent>", 8) == 0) { arg = skipwhite(arg + 8); @@ -4229,7 +4238,7 @@ ExpandMappings(regmatch, num_file, file) { count = 0; - for (i = 0; i < 5; ++i) + for (i = 0; i < 6; ++i) { if (i == 0) p = (char_u *)"<silent>"; @@ -4245,6 +4254,8 @@ ExpandMappings(regmatch, num_file, file) else if (i == 4 && !expand_buffer) p = (char_u *)"<buffer>"; #endif + else if (i == 5) + p = (char_u *)"<nowait>"; else continue; @@ -4857,6 +4868,8 @@ makemap(fd, buf) return FAIL; if (buf != NULL && fputs(" <buffer>", fd) < 0) return FAIL; + if (mp->m_nowait && fputs(" <nowait>", fd) < 0) + return FAIL; if (mp->m_silent && fputs(" <silent>", fd) < 0) return FAIL; #ifdef FEAT_EVAL
--- a/src/testdir/test75.in +++ b/src/testdir/test75.in @@ -9,6 +9,8 @@ STARTTEST :call append('$', maparg('foo<C-V>')) :call append('$', string(maparg('foo<C-V>', '', 0, 1))) :call append('$', string(maparg('bar', '', 0, 1))) +:map <buffer> <nowait> foo bar +:call append('$', string(maparg('foo', '', 0, 1))) :" :map abc x<char-114>x :call append('$', maparg('abc'))
--- a/src/testdir/test75.ok +++ b/src/testdir/test75.ok @@ -1,5 +1,6 @@ is<F4>foo -{'silent': 0, 'noremap': 0, 'lhs': 'foo<C-V>', 'mode': ' ', 'expr': 0, 'sid': 0, 'rhs': 'is<F4>foo', 'buffer': 0} -{'silent': 1, 'noremap': 1, 'lhs': 'bar', 'mode': 'v', 'expr': 1, 'sid': 0, 'rhs': 'isbar', 'buffer': 1} +{'silent': 0, 'noremap': 0, 'lhs': 'foo<C-V>', 'mode': ' ', 'nowait': 0, 'expr': 0, 'sid': 0, 'rhs': 'is<F4>foo', 'buffer': 0} +{'silent': 1, 'noremap': 1, 'lhs': 'bar', 'mode': 'v', 'nowait': 0, 'expr': 1, 'sid': 0, 'rhs': 'isbar', 'buffer': 1} +{'silent': 0, 'noremap': 0, 'lhs': 'foo', 'mode': ' ', 'nowait': 1, 'expr': 0, 'sid': 0, 'rhs': 'bar', 'buffer': 1} xrx yRy