0
0
mirror of https://github.com/vim/vim.git synced 2025-10-14 07:04:10 -04:00

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)
This commit is contained in:
zeertzjq
2023-05-06 16:22:04 +01:00
committed by Bram Moolenaar
parent 03ff1c2dde
commit 3ab3a86481
7 changed files with 61 additions and 34 deletions

View File

@@ -408,10 +408,6 @@ Note:
by <CR> in the {rhs} of the mapping definition. |Command-line| mode is never by <CR> in the {rhs} of the mapping definition. |Command-line| mode is never
entered. 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* 1.3 MAPPING AND MODES *:map-modes*
*mapmode-nvo* *mapmode-n* *mapmode-v* *mapmode-o* *mapmode-nvo* *mapmode-n* *mapmode-v* *mapmode-o*

View File

@@ -2894,8 +2894,7 @@ EXTERN char e_using_string_as_bool_str[]
#endif #endif
EXTERN char e_cmd_mapping_must_end_with_cr_before_second_cmd[] EXTERN char e_cmd_mapping_must_end_with_cr_before_second_cmd[]
INIT(= N_("E1136: <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[] // E1137 unused
INIT(= N_("E1137: <Cmd> mapping must not include %s key"));
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
EXTERN char e_using_bool_as_number[] EXTERN char e_using_bool_as_number[]
INIT(= N_("E1138: Using a Bool as a Number")); INIT(= N_("E1138: Using a Bool as a Number"));

View File

@@ -602,6 +602,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. * Append a character to the redo buffer.
* Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters. * Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters.
@@ -3941,14 +3961,6 @@ getcmdkeycmd(
if (c1 == K_ESC) if (c1 == K_ESC)
c1 = 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) if (got_int)
aborted = TRUE; aborted = TRUE;
@@ -3962,19 +3974,27 @@ getcmdkeycmd(
emsg(_(e_cmd_mapping_must_end_with_cr_before_second_cmd)); emsg(_(e_cmd_mapping_must_end_with_cr_before_second_cmd));
aborted = TRUE; aborted = TRUE;
} }
else if (IS_SPECIAL(c1)) else if (c1 == K_SNR)
{ {
if (c1 == K_SNR) ga_concat(&line_ga, (char_u *)"<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;
}
} }
else 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; cmod = 0;
} }

View File

@@ -3701,7 +3701,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
ResetRedobuff(); ResetRedobuff();
else else
{ {
AppendToRedobuffLit(repeat_cmdline, -1); AppendToRedobuffSpec(repeat_cmdline);
AppendToRedobuff(NL_STR); AppendToRedobuff(NL_STR);
VIM_CLEAR(repeat_cmdline); VIM_CLEAR(repeat_cmdline);
} }

View File

@@ -11,6 +11,7 @@ void saveRedobuff(save_redo_T *save_redo);
void restoreRedobuff(save_redo_T *save_redo); void restoreRedobuff(save_redo_T *save_redo);
void AppendToRedobuff(char_u *s); void AppendToRedobuff(char_u *s);
void AppendToRedobuffLit(char_u *str, int len); void AppendToRedobuffLit(char_u *str, int len);
void AppendToRedobuffSpec(char_u *s);
void AppendCharToRedobuff(int c); void AppendCharToRedobuff(int c);
void AppendNumberToRedobuff(long n); void AppendNumberToRedobuff(long n);
void stuffReadbuff(char_u *s); void stuffReadbuff(char_u *s);

View File

@@ -1001,10 +1001,6 @@ func Test_map_cmdkey()
call assert_fails('call feedkeys("\<F3>", "xt")', 'E1136:') call assert_fails('call feedkeys("\<F3>", "xt")', 'E1136:')
call assert_equal(0, x) 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 noremap <F3> <Cmd>let x = 3
call assert_fails('call feedkeys("\<F3>", "xt!")', 'E1255:') call assert_fails('call feedkeys("\<F3>", "xt!")', 'E1255:')
call assert_equal(0, x) call assert_equal(0, x)
@@ -1104,11 +1100,6 @@ func Test_map_cmdkey()
unmap <F3> unmap <F3>
unmap! <F3> unmap! <F3>
%bw! %bw!
" command line ending in "0" is handled without errors
onoremap ix <cmd>eval 0<cr>
call feedkeys('dix.', 'xt')
ounmap ix
endfunc endfunc
" text object enters visual mode " text object enters visual mode
@@ -1495,6 +1486,24 @@ func Test_map_cmdkey_redo()
call delete('Xcmdtext') call delete('Xcmdtext')
delfunc SelectDash delfunc SelectDash
ounmap i- 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 endfunc
func Test_map_script_cmd_restore() func Test_map_script_cmd_restore()

View File

@@ -695,6 +695,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1516,
/**/ /**/
1515, 1515,
/**/ /**/