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:
@@ -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*
|
||||||
|
@@ -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"));
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
@@ -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()
|
||||||
|
@@ -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,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user