Mercurial > vim
changeset 32369:ffbae151e462 v9.0.1516
patch 9.0.1516: cannot use special keys in <Cmd> mapping
Commit: https://github.com/vim/vim/commit/3ab3a864814f903da8a158c01820e4fbe1013c08
Author: zeertzjq <zeertzjq@outlook.com>
Date: Sat May 6 16:22:04 2023 +0100
patch 9.0.1516: cannot use special keys in <Cmd> mapping
Problem: Cannot use special keys in <Cmd> mapping.
Solution: Do allow for special keys in <Cmd> and <ScriptCmd> mappings.
(closes #12326)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 06 May 2023 17:30:03 +0200 |
parents | 2992e4adb0da |
children | f3abbfef6f19 |
files | runtime/doc/map.txt src/errors.h src/getchar.c src/ops.c src/proto/getchar.pro src/testdir/test_mapping.vim src/version.c |
diffstat | 7 files changed, 61 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/runtime/doc/map.txt +++ b/runtime/doc/map.txt @@ -408,10 +408,6 @@ Note: by <CR> in the {rhs} of the mapping definition. |Command-line| mode is never entered. - *E1137* -<Cmd> and <ScriptCmd> commands can have only normal characters and cannot -contain special characters like function keys. - 1.3 MAPPING AND MODES *:map-modes* *mapmode-nvo* *mapmode-n* *mapmode-v* *mapmode-o*
--- a/src/errors.h +++ b/src/errors.h @@ -2894,8 +2894,7 @@ EXTERN char e_using_string_as_bool_str[] #endif EXTERN char e_cmd_mapping_must_end_with_cr_before_second_cmd[] INIT(= N_("E1136: <Cmd> mapping must end with <CR> before second <Cmd>")); -EXTERN char e_cmd_mapping_must_not_include_str_key[] - INIT(= N_("E1137: <Cmd> mapping must not include %s key")); +// E1137 unused #ifdef FEAT_EVAL EXTERN char e_using_bool_as_number[] INIT(= N_("E1138: Using a Bool as a Number"));
--- a/src/getchar.c +++ b/src/getchar.c @@ -603,6 +603,26 @@ AppendToRedobuffLit( } /* + * Append "s" to the redo buffer, leaving 3-byte special key codes unmodified + * and escaping other K_SPECIAL and CSI bytes. + */ + void +AppendToRedobuffSpec(char_u *s) +{ + while (*s != NUL) + { + if (*s == K_SPECIAL && s[1] != NUL && s[2] != NUL) + { + // insert special key literally + add_buff(&redobuff, s, 3L); + s += 3; + } + else + add_char_buff(&redobuff, mb_cptr2char_adv(&s)); + } +} + +/* * Append a character to the redo buffer. * Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters. */ @@ -3941,14 +3961,6 @@ getcmdkeycmd( if (c1 == K_ESC) c1 = ESC; } - if (c1 == Ctrl_V) - { - // CTRL-V is followed by octal, hex or other characters, reverses - // what AppendToRedobuffLit() does. - ++no_reduce_keys; // don't merge modifyOtherKeys - c1 = get_literal(TRUE); - --no_reduce_keys; - } if (got_int) aborted = TRUE; @@ -3962,19 +3974,27 @@ getcmdkeycmd( emsg(_(e_cmd_mapping_must_end_with_cr_before_second_cmd)); aborted = TRUE; } - else if (IS_SPECIAL(c1)) + else if (c1 == K_SNR) { - if (c1 == K_SNR) - ga_concat(&line_ga, (char_u *)"<SNR>"); - else - { - semsg(e_cmd_mapping_must_not_include_str_key, - get_special_key_name(c1, cmod)); - aborted = TRUE; - } + ga_concat(&line_ga, (char_u *)"<SNR>"); } else - ga_append(&line_ga, c1); + { + if (cmod != 0) + { + ga_append(&line_ga, K_SPECIAL); + ga_append(&line_ga, KS_MODIFIER); + ga_append(&line_ga, cmod); + } + if (IS_SPECIAL(c1)) + { + ga_append(&line_ga, K_SPECIAL); + ga_append(&line_ga, K_SECOND(c1)); + ga_append(&line_ga, K_THIRD(c1)); + } + else + ga_append(&line_ga, c1); + } cmod = 0; }
--- a/src/ops.c +++ b/src/ops.c @@ -3701,7 +3701,7 @@ do_pending_operator(cmdarg_T *cap, int o ResetRedobuff(); else { - AppendToRedobuffLit(repeat_cmdline, -1); + AppendToRedobuffSpec(repeat_cmdline); AppendToRedobuff(NL_STR); VIM_CLEAR(repeat_cmdline); }
--- a/src/proto/getchar.pro +++ b/src/proto/getchar.pro @@ -11,6 +11,7 @@ void saveRedobuff(save_redo_T *save_redo void restoreRedobuff(save_redo_T *save_redo); void AppendToRedobuff(char_u *s); void AppendToRedobuffLit(char_u *str, int len); +void AppendToRedobuffSpec(char_u *s); void AppendCharToRedobuff(int c); void AppendNumberToRedobuff(long n); void stuffReadbuff(char_u *s);
--- a/src/testdir/test_mapping.vim +++ b/src/testdir/test_mapping.vim @@ -1001,10 +1001,6 @@ func Test_map_cmdkey() call assert_fails('call feedkeys("\<F3>", "xt")', 'E1136:') call assert_equal(0, x) - noremap <F3> <Cmd><F3>let x = 2<CR> - call assert_fails('call feedkeys("\<F3>", "xt")', 'E1137:') - call assert_equal(0, x) - noremap <F3> <Cmd>let x = 3 call assert_fails('call feedkeys("\<F3>", "xt!")', 'E1255:') call assert_equal(0, x) @@ -1104,11 +1100,6 @@ func Test_map_cmdkey() unmap <F3> unmap! <F3> %bw! - - " command line ending in "0" is handled without errors - onoremap ix <cmd>eval 0<cr> - call feedkeys('dix.', 'xt') - ounmap ix endfunc " text object enters visual mode @@ -1495,6 +1486,24 @@ func Test_map_cmdkey_redo() call delete('Xcmdtext') delfunc SelectDash ounmap i- + + new + call setline(1, 'aaa bbb ccc ddd') + + " command can contain special keys + onoremap ix <Cmd>let g:foo ..= '…'<Bar>normal! <C-Right><CR> + let g:foo = '' + call feedkeys('0dix.', 'xt') + call assert_equal('……', g:foo) + call assert_equal('ccc ddd', getline(1)) + unlet g:foo + + " command line ending in "0" is handled without errors + onoremap ix <Cmd>eval 0<CR> + call feedkeys('dix.', 'xt') + + ounmap ix + bwipe! endfunc func Test_map_script_cmd_restore()