diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-08-01 14:04:55 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2022-08-01 21:54:18 +0800 |
commit | 6963c2bdcd3cc2a2f0466b23152e80fc0d037a2c (patch) | |
tree | 6f59c3dbb1e255f1727257bd46cf945a2976f200 | |
parent | 5c72640bc2b60a018ccfcf18bca809b635f250f6 (diff) | |
download | rneovim-6963c2bdcd3cc2a2f0466b23152e80fc0d037a2c.tar.gz rneovim-6963c2bdcd3cc2a2f0466b23152e80fc0d037a2c.tar.bz2 rneovim-6963c2bdcd3cc2a2f0466b23152e80fc0d037a2c.zip |
vim-patch:8.2.0815: maparg() does not provide enough information for mapset()
Problem: maparg() does not provide enough information for mapset().
Solution: Add "lhsraw" and "lhsrawalt" items. Drop "simplified"
https://github.com/vim/vim/commit/9c65253fe702ea010afec11aa971acd542c35de2
vim-patch:9.0.0127: unused variable
Problem: Unused variable.
Solution: Remove the variable. (closes vim/vim#10829)
https://github.com/vim/vim/commit/e95f22f63a1871b91e5508088e5ae4905ce28cd7
-rw-r--r-- | runtime/doc/builtin.txt | 18 | ||||
-rw-r--r-- | src/nvim/mapping.c | 71 | ||||
-rw-r--r-- | src/nvim/testdir/test_maparg.vim | 48 | ||||
-rw-r--r-- | test/functional/legacy/075_maparg_spec.lua | 59 | ||||
-rw-r--r-- | test/functional/vimscript/map_functions_spec.lua | 2 |
5 files changed, 88 insertions, 110 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 994f1ab7f5..e2a8e098d2 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -295,7 +295,7 @@ maparg({name} [, {mode} [, {abbr} [, {dict}]]]) rhs of mapping {name} in mode {mode} mapcheck({name} [, {mode} [, {abbr}]]) String check for mappings matching {name} -mapset({name}, {mode}, {abbr}, {dict} +mapset({mode}, {abbr}, {dict}) none restore mapping from |maparg()| result match({expr}, {pat} [, {start} [, {count}]]) Number position where {pat} matches in {expr} @@ -4752,7 +4752,10 @@ maparg({name} [, {mode} [, {abbr} [, {dict}]]]) *maparg()* When {dict} is there and it is |TRUE| return a dictionary containing all the information of the mapping with the following items: - "lhs" The {lhs} of the mapping. + "lhs" The {lhs} of the mapping as it would be typed + "lhsraw" The {lhs} of the mapping as raw bytes + "lhsrawalt" The {lhs} of the mapping as raw bytes, alternate + form, only present when it differs from "lhsraw" "rhs" The {rhs} of the mapping as typed. "silent" 1 for a |:map-silent| mapping, else 0. "noremap" 1 if the {rhs} of the mapping is not remappable. @@ -4770,7 +4773,6 @@ maparg({name} [, {mode} [, {abbr} [, {dict}]]]) *maparg()* "lnum" The line number in "sid", zero if unknown. "nowait" Do not wait for other, longer mappings. (|:map-<nowait>|). - "simplified" The dictionary can be used to restore a mapping with |mapset()|. @@ -4822,8 +4824,8 @@ mapcheck({name} [, {mode} [, {abbr}]]) *mapcheck()* mapset({mode}, {abbr}, {dict}) *mapset()* Restore a mapping from a dictionary returned by |maparg()|. - {name}, {mode} and {abbr} should be the same as for the call - to |maparg()|. + {mode} and {abbr} should be the same as for the call to + |maparg()|. *E460* {mode} is used to define the mode in which the mapping is set, not the "mode" entry in {dict}. Example for saving and restoring a mapping: > @@ -4831,7 +4833,11 @@ mapset({mode}, {abbr}, {dict}) *mapset()* nnoremap K somethingelse ... call mapset('n', 0, save_map) -< +< Note that if you are going to replace a map in several modes, + e.g. with `:map!`, you need to save the mapping for all of + them, since they can differe. + + match({expr}, {pat} [, {start} [, {count}]]) *match()* When {expr} is a |List| then this returns the index of the first item where {pat} matches. Each item is used as a diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c index 3613849a73..cbbe07635f 100644 --- a/src/nvim/mapping.c +++ b/src/nvim/mapping.c @@ -1993,9 +1993,9 @@ void f_hasmapto(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// @param mp The maphash that contains the mapping information /// @param buffer_value The "buffer" value /// @param compatible True for compatible with old maparg() dict -static void mapblock_fill_dict(dict_T *const dict, const mapblock_T *const mp, long buffer_value, - bool compatible) - FUNC_ATTR_NONNULL_ALL +static void mapblock_fill_dict(dict_T *const dict, const mapblock_T *const mp, + const char *lhsrawalt, long buffer_value, bool compatible) + FUNC_ATTR_NONNULL_ARG(1, 2) { char *const lhs = str2special_save((const char *)mp->m_keys, compatible, !compatible); @@ -2027,6 +2027,11 @@ static void mapblock_fill_dict(dict_T *const dict, const mapblock_T *const mp, l tv_dict_add_allocated_str(dict, S_LEN("desc"), xstrdup(mp->m_desc)); } tv_dict_add_allocated_str(dict, S_LEN("lhs"), lhs); + tv_dict_add_str(dict, S_LEN("lhsraw"), (const char *)mp->m_keys); + if (lhsrawalt != NULL) { + // Also add the value for the simplified entry. + tv_dict_add_str(dict, S_LEN("lhsrawalt"), lhsrawalt); + } tv_dict_add_nr(dict, S_LEN("noremap"), noremap_value); tv_dict_add_nr(dict, S_LEN("script"), mp->m_noremap == REMAP_SCRIPT ? 1 : 0); tv_dict_add_nr(dict, S_LEN("expr"), mp->m_expr ? 1 : 0); @@ -2039,23 +2044,10 @@ static void mapblock_fill_dict(dict_T *const dict, const mapblock_T *const mp, l tv_dict_add_nr(dict, S_LEN("replace_keycodes"), 1); } tv_dict_add_allocated_str(dict, S_LEN("mode"), mapmode); - tv_dict_add_nr(dict, S_LEN("simplified"), mp->m_simplified ? 1 : 0); } static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) { - char *keys_buf = NULL; - char_u *alt_keys_buf = NULL; - bool did_simplify = false; - char_u *rhs; - LuaRef rhs_lua; - int mode; - bool abbr = false; - bool get_dict = false; - mapblock_T *mp = NULL; - int buffer_local; - int flags = REPTERM_FROM_PART | REPTERM_DO_LT; - // Return empty string for failure. rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; @@ -2065,8 +2057,11 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) return; } - char buf[NUMBUFLEN]; const char *which; + char buf[NUMBUFLEN]; + bool abbr = false; + bool get_dict = false; + if (argvars[1].v_type != VAR_UNKNOWN) { which = tv_get_string_buf_chk(&argvars[1], buf); if (argvars[2].v_type != VAR_UNKNOWN) { @@ -2082,13 +2077,19 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) return; } - mode = get_map_mode((char **)&which, 0); + char *keys_buf = NULL; + char_u *alt_keys_buf = NULL; + bool did_simplify = false; + const int flags = REPTERM_FROM_PART | REPTERM_DO_LT; + const int mode = get_map_mode((char **)&which, 0); char_u *keys_simplified - = (char_u *)replace_termcodes(keys, - STRLEN(keys), &keys_buf, flags, &did_simplify, + = (char_u *)replace_termcodes(keys, STRLEN(keys), &keys_buf, flags, &did_simplify, CPO_TO_CPO_FLAGS); - rhs = check_map(keys_simplified, mode, exact, false, abbr, &mp, &buffer_local, &rhs_lua); + mapblock_T *mp = NULL; + int buffer_local; + LuaRef rhs_lua; + char_u *rhs = check_map(keys_simplified, mode, exact, false, abbr, &mp, &buffer_local, &rhs_lua); if (did_simplify) { // When the lhs is being simplified the not-simplified keys are // preferred for printing, like in do_map(). @@ -2117,7 +2118,8 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) tv_dict_alloc_ret(rettv); if (mp != NULL && (rhs != NULL || rhs_lua != LUA_NOREF)) { // Return a dictionary. - mapblock_fill_dict(rettv->vval.v_dict, mp, buffer_local, true); + mapblock_fill_dict(rettv->vval.v_dict, mp, did_simplify ? (char *)keys_simplified : NULL, + buffer_local, true); } } @@ -2141,13 +2143,11 @@ void f_mapset(typval_T *argvars, typval_T *rettv, FunPtr fptr) // Get the values in the same order as above in get_maparg(). char *lhs = tv_dict_get_string(d, "lhs", false); - if (lhs == NULL) { - emsg(_("E99: lhs entry missing in mapset() dict argument")); - return; - } + char *lhsraw = tv_dict_get_string(d, "lhsraw", false); + char *lhsrawalt = tv_dict_get_string(d, "lhsrawalt", false); char *rhs = tv_dict_get_string(d, "rhs", false); - if (rhs == NULL) { - emsg(_("E99: rhs entry missing in mapset() dict argument")); + if (lhs == NULL || lhsraw == NULL || rhs == NULL) { + emsg(_("E460: entries missing in mapset() dict argument")); return; } char *orig_rhs = rhs; @@ -2180,19 +2180,18 @@ void f_mapset(typval_T *argvars, typval_T *rettv, FunPtr fptr) abbr_table = &curbuf->b_first_abbr; } // mode from the dict is not used - bool simplified = tv_dict_get_number(d, "simplified") != 0; // Delete any existing mapping for this lhs and mode. char_u *arg = vim_strsave((char_u *)lhs); do_map(1, arg, mode, is_abbr); // TODO: refactor this later xfree(arg); - char *keys_buf = NULL; - char *keys = replace_termcodes(lhs, STRLEN(lhs), &keys_buf, REPTERM_FROM_PART | REPTERM_DO_LT, - NULL, CPO_TO_CPO_FLAGS); - map_add(curbuf, map_table, abbr_table, (char_u *)keys, &args, noremap, mode, is_abbr, sid, lnum, - simplified); - xfree(keys_buf); + if (lhsrawalt != NULL) { + map_add(curbuf, map_table, abbr_table, (char_u *)lhsrawalt, &args, noremap, mode, is_abbr, + sid, lnum, true); + } + map_add(curbuf, map_table, abbr_table, (char_u *)lhsraw, &args, noremap, mode, is_abbr, + sid, lnum, false); } /// "maparg()" function @@ -2623,7 +2622,7 @@ ArrayOf(Dictionary) keymap_array(String mode, buf_T *buf, bool from_lua) } // Check for correct mode if (int_mode & current_maphash->m_mode) { - mapblock_fill_dict(dict, current_maphash, buffer_value, false); + mapblock_fill_dict(dict, current_maphash, NULL, buffer_value, false); Object api_dict = vim_to_object((typval_T[]) { { .v_type = VAR_DICT, .vval.v_dict = dict } }); if (from_lua) { diff --git a/src/nvim/testdir/test_maparg.vim b/src/nvim/testdir/test_maparg.vim index 6fea66b7c6..abbee7db95 100644 --- a/src/nvim/testdir/test_maparg.vim +++ b/src/nvim/testdir/test_maparg.vim @@ -17,24 +17,28 @@ func Test_maparg() vnoremap <script> <buffer> <expr> <silent> bar isbar call assert_equal("is<F4>foo", maparg('foo<C-V>')) call assert_equal({'silent': 0, 'noremap': 0, 'script': 0, 'lhs': 'foo<C-V>', + \ 'lhsraw': "foo\x80\xfc\x04V", 'lhsrawalt': "foo\x16", \ 'mode': ' ', 'nowait': 0, 'expr': 0, 'sid': sid, 'lnum': lnum + 1, - \ 'simplified': 1, 'rhs': 'is<F4>foo', 'buffer': 0}, + \ 'rhs': 'is<F4>foo', 'buffer': 0}, \ maparg('foo<C-V>', '', 0, 1)) - call assert_equal({'silent': 1, 'noremap': 1, 'script': 1, 'lhs': 'bar', 'mode': 'v', + call assert_equal({'silent': 1, 'noremap': 1, 'script': 1, 'lhs': 'bar', + \ 'lhsraw': 'bar', 'mode': 'v', \ 'nowait': 0, 'expr': 1, 'sid': sid, 'lnum': lnum + 2, - \ 'simplified': 0, 'rhs': 'isbar', 'buffer': 1}, + \ 'rhs': 'isbar', 'buffer': 1}, \ 'bar'->maparg('', 0, 1)) let lnum = expand('<sflnum>') map <buffer> <nowait> foo bar - call assert_equal({'silent': 0, 'noremap': 0, 'script': 0, 'lhs': 'foo', 'mode': ' ', + call assert_equal({'silent': 0, 'noremap': 0, 'script': 0, 'lhs': 'foo', + \ 'lhsraw': 'foo', 'mode': ' ', \ 'nowait': 1, 'expr': 0, 'sid': sid, 'lnum': lnum + 1, 'rhs': 'bar', - \ 'simplified': 0, 'buffer': 1}, + \ 'buffer': 1}, \ maparg('foo', '', 0, 1)) let lnum = expand('<sflnum>') tmap baz foo - call assert_equal({'silent': 0, 'noremap': 0, 'script': 0, 'lhs': 'baz', 'mode': 't', + call assert_equal({'silent': 0, 'noremap': 0, 'script': 0, 'lhs': 'baz', + \ 'lhsraw': 'baz', 'mode': 't', \ 'nowait': 0, 'expr': 0, 'sid': sid, 'lnum': lnum + 1, 'rhs': 'foo', - \ 'simplified': 0, 'buffer': 0}, + \ 'buffer': 0}, \ maparg('baz', 't', 0, 1)) map abc x<char-114>x @@ -213,7 +217,6 @@ func Test_mapset() call assert_equal('one<CR>two', getline(1)) iunmap K - let &cpo = cpo_save " Test literal <CR> using CTRL-V inoremap K one<CR>two @@ -235,8 +238,35 @@ func Test_mapset() iunmap K let &cpo = cpo_save - bwipe! endfunc +func Check_ctrlb_map(d, check_alt) + call assert_equal('<C-B>', a:d.lhs) + if a:check_alt + call assert_equal("\x80\xfc\x04B", a:d.lhsraw) + call assert_equal("\x02", a:d.lhsrawalt) + else + call assert_equal("\x02", a:d.lhsraw) + endif +endfunc + +func Test_map_restore() + " Test restoring map with alternate keycode + nmap <C-B> back + let d = maparg('<C-B>', 'n', 0, 1) + call Check_ctrlb_map(d, 1) + let dsimp = maparg("\x02", 'n', 0, 1) + call Check_ctrlb_map(dsimp, 0) + nunmap <C-B> + call mapset('n', 0, d) + let d = maparg('<C-B>', 'n', 0, 1) + call Check_ctrlb_map(d, 1) + let dsimp = maparg("\x02", 'n', 0, 1) + call Check_ctrlb_map(dsimp, 0) + + nunmap <C-B> + +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/test/functional/legacy/075_maparg_spec.lua b/test/functional/legacy/075_maparg_spec.lua deleted file mode 100644 index ad6c190104..0000000000 --- a/test/functional/legacy/075_maparg_spec.lua +++ /dev/null @@ -1,59 +0,0 @@ --- Tests for maparg(). --- Also test utf8 map with a 0x80 byte. - -local helpers = require('test.functional.helpers')(after_each) -local clear, feed = helpers.clear, helpers.feed -local command, expect = helpers.command, helpers.expect -local poke_eventloop = helpers.poke_eventloop - -describe('maparg()', function() - setup(clear) - - it('is working', function() - command('set cpo-=<') - - -- Test maparg() with a string result - command('map foo<C-V> is<F4>foo') - command('vnoremap <script> <buffer> <expr> <silent> bar isbar') - command([[call append('$', maparg('foo<C-V>'))]]) - command([[call append('$', string(maparg('foo<C-V>', '', 0, 1)))]]) - command([[call append('$', string(maparg('bar', '', 0, 1)))]]) - command('map <buffer> <nowait> foo bar') - command([[call append('$', string(maparg('foo', '', 0, 1)))]]) - command('map abc x<char-114>x') - command([[call append('$', maparg('abc'))]]) - command('map abc y<S-char-114>y') - command([[call append('$', maparg('abc'))]]) - feed('Go<esc>:<cr>') - poke_eventloop() - - -- Outside of the range, minimum - command('inoremap <Char-0x1040> a') - command([[execute "normal a\u1040\<Esc>"]]) - - -- Inside of the range, minimum - command('inoremap <Char-0x103f> b') - command([[execute "normal a\u103f\<Esc>"]]) - - -- Inside of the range, maximum - command('inoremap <Char-0xf03f> c') - command([[execute "normal a\uf03f\<Esc>"]]) - - -- Outside of the range, maximum - command('inoremap <Char-0xf040> d') - command([[execute "normal a\uf040\<Esc>"]]) - - -- Remove empty line - command('1d') - - -- Assert buffer contents. - expect([[ - is<F4>foo - {'lnum': 0, 'script': 0, 'silent': 0, 'noremap': 0, 'lhs': 'foo<C-V>', 'mode': ' ', 'nowait': 0, 'expr': 0, 'sid': 0, 'rhs': 'is<F4>foo', 'buffer': 0} - {'lnum': 0, 'script': 1, 'silent': 1, 'noremap': 1, 'lhs': 'bar', 'mode': 'v', 'nowait': 0, 'expr': 1, 'sid': 0, 'rhs': 'isbar', 'buffer': 1} - {'lnum': 0, 'script': 0, 'silent': 0, 'noremap': 0, 'lhs': 'foo', 'mode': ' ', 'nowait': 1, 'expr': 0, 'sid': 0, 'rhs': 'bar', 'buffer': 1} - xrx - yRy - abcd]]) - end) -end) diff --git a/test/functional/vimscript/map_functions_spec.lua b/test/functional/vimscript/map_functions_spec.lua index 275c72d212..15d4d41ac1 100644 --- a/test/functional/vimscript/map_functions_spec.lua +++ b/test/functional/vimscript/map_functions_spec.lua @@ -13,6 +13,7 @@ describe('maparg()', function() local foo_bar_map_table = { lhs='foo', + lhsraw='foo', script=0, silent=0, rhs='bar', @@ -141,6 +142,7 @@ describe('maparg()', function() local function acmap(lhs, rhs) return { lhs = ac(lhs), + lhsraw = ac(lhs), rhs = ac(rhs), buffer = 0, |