mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 8.2.0916: mapping with partly modifyOtherKeys code does not work
Problem: Mapping with partly modifyOtherKeys code does not work. Solution: If there is no mapping with a separate modifier include the modifier in the key and then try mapping again. (closes #6200)
This commit is contained in:
@@ -1609,7 +1609,7 @@ decodeModifyOtherKeys(int c)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
mod_mask = decode_modifiers(arg[!form]);
|
mod_mask = decode_modifiers(arg[!form]);
|
||||||
c = merge_modifyOtherKeys(arg[form]);
|
c = merge_modifyOtherKeys(arg[form], &mod_mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1582,15 +1582,15 @@ updatescript(int c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert "c" plus "mod_mask" to merge the effect of modifyOtherKeys into the
|
* Convert "c" plus "modifiers" to merge the effect of modifyOtherKeys into the
|
||||||
* character.
|
* character.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
merge_modifyOtherKeys(int c_arg)
|
merge_modifyOtherKeys(int c_arg, int *modifiers)
|
||||||
{
|
{
|
||||||
int c = c_arg;
|
int c = c_arg;
|
||||||
|
|
||||||
if (mod_mask & MOD_MASK_CTRL)
|
if (*modifiers & MOD_MASK_CTRL)
|
||||||
{
|
{
|
||||||
if ((c >= '`' && c <= 0x7f) || (c >= '@' && c <= '_'))
|
if ((c >= '`' && c <= 0x7f) || (c >= '@' && c <= '_'))
|
||||||
c &= 0x1f;
|
c &= 0x1f;
|
||||||
@@ -1612,13 +1612,13 @@ merge_modifyOtherKeys(int c_arg)
|
|||||||
c = DEL;
|
c = DEL;
|
||||||
#endif
|
#endif
|
||||||
if (c != c_arg)
|
if (c != c_arg)
|
||||||
mod_mask &= ~MOD_MASK_CTRL;
|
*modifiers &= ~MOD_MASK_CTRL;
|
||||||
}
|
}
|
||||||
if ((mod_mask & (MOD_MASK_META | MOD_MASK_ALT))
|
if ((*modifiers & (MOD_MASK_META | MOD_MASK_ALT))
|
||||||
&& c >= 0 && c <= 127)
|
&& c >= 0 && c <= 127)
|
||||||
{
|
{
|
||||||
c += 0x80;
|
c += 0x80;
|
||||||
mod_mask &= ~(MOD_MASK_META|MOD_MASK_ALT);
|
*modifiers &= ~(MOD_MASK_META|MOD_MASK_ALT);
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -1866,7 +1866,7 @@ vgetc(void)
|
|||||||
// cases they are put back in the typeahead buffer.
|
// cases they are put back in the typeahead buffer.
|
||||||
vgetc_mod_mask = mod_mask;
|
vgetc_mod_mask = mod_mask;
|
||||||
vgetc_char = c;
|
vgetc_char = c;
|
||||||
c = merge_modifyOtherKeys(c);
|
c = merge_modifyOtherKeys(c, &mod_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -2254,6 +2254,44 @@ at_ctrl_x_key(void)
|
|||||||
return vim_is_ctrl_x_key(c);
|
return vim_is_ctrl_x_key(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if typebuf.tb_buf[] contains a modifer plus key that can be changed
|
||||||
|
* into just a key, apply that.
|
||||||
|
* Check from typebuf.tb_buf[typebuf.tb_off] to typebuf.tb_buf[typebuf.tb_off
|
||||||
|
* + "max_offset"].
|
||||||
|
* Return the length of the replaced bytes, zero if nothing changed.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
check_simplify_modifier(int max_offset)
|
||||||
|
{
|
||||||
|
int offset;
|
||||||
|
char_u *tp;
|
||||||
|
|
||||||
|
for (offset = 0; offset < max_offset; ++offset)
|
||||||
|
{
|
||||||
|
if (offset + 3 >= typebuf.tb_len)
|
||||||
|
break;
|
||||||
|
tp = typebuf.tb_buf + typebuf.tb_off + offset;
|
||||||
|
if (tp[0] == K_SPECIAL && tp[1] == KS_MODIFIER)
|
||||||
|
{
|
||||||
|
int modifier = tp[2];
|
||||||
|
int new_c = merge_modifyOtherKeys(tp[3], &modifier);
|
||||||
|
|
||||||
|
if (new_c != tp[3] && modifier == 0)
|
||||||
|
{
|
||||||
|
char_u new_string[MB_MAXBYTES];
|
||||||
|
int len = mb_char2bytes(new_c, new_string);
|
||||||
|
|
||||||
|
if (put_string_in_typebuf(offset, 4, new_string, len,
|
||||||
|
NULL, 0, 0) == FAIL)
|
||||||
|
return -1;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle mappings in the typeahead buffer.
|
* Handle mappings in the typeahead buffer.
|
||||||
* - When something was mapped, return map_result_retry for recursive mappings.
|
* - When something was mapped, return map_result_retry for recursive mappings.
|
||||||
@@ -2519,6 +2557,11 @@ handle_mapping(
|
|||||||
if (keylen == 0 && save_keylen == KEYLEN_PART_KEY)
|
if (keylen == 0 && save_keylen == KEYLEN_PART_KEY)
|
||||||
keylen = KEYLEN_PART_KEY;
|
keylen = KEYLEN_PART_KEY;
|
||||||
|
|
||||||
|
// If no termcode matched, try to include the modifier into the
|
||||||
|
// key. This for when modifyOtherKeys is working.
|
||||||
|
if (keylen == 0)
|
||||||
|
keylen = check_simplify_modifier(max_mlen + 1);
|
||||||
|
|
||||||
// When getting a partial match, but the last characters were not
|
// When getting a partial match, but the last characters were not
|
||||||
// typed, don't wait for a typed character to complete the
|
// typed, don't wait for a typed character to complete the
|
||||||
// termcode. This helps a lot when a ":normal" command ends in an
|
// termcode. This helps a lot when a ":normal" command ends in an
|
||||||
|
@@ -37,7 +37,7 @@ void openscript(char_u *name, int directly);
|
|||||||
void close_all_scripts(void);
|
void close_all_scripts(void);
|
||||||
int using_script(void);
|
int using_script(void);
|
||||||
void before_blocking(void);
|
void before_blocking(void);
|
||||||
int merge_modifyOtherKeys(int c_arg);
|
int merge_modifyOtherKeys(int c_arg, int *modifiers);
|
||||||
int vgetc(void);
|
int vgetc(void);
|
||||||
int safe_vgetc(void);
|
int safe_vgetc(void);
|
||||||
int plain_vgetc(void);
|
int plain_vgetc(void);
|
||||||
|
@@ -68,6 +68,7 @@ int get_termcode_len(int idx);
|
|||||||
void del_termcode(char_u *name);
|
void del_termcode(char_u *name);
|
||||||
void set_mouse_topline(win_T *wp);
|
void set_mouse_topline(win_T *wp);
|
||||||
int is_mouse_topline(win_T *wp);
|
int is_mouse_topline(win_T *wp);
|
||||||
|
int put_string_in_typebuf(int offset, int slen, char_u *string, int new_slen, char_u *buf, int bufsize, int *buflen);
|
||||||
int decode_modifiers(int n);
|
int decode_modifiers(int n);
|
||||||
int check_termcode(int max_offset, char_u *buf, int bufsize, int *buflen);
|
int check_termcode(int max_offset, char_u *buf, int bufsize, int *buflen);
|
||||||
void term_get_fg_color(char_u *r, char_u *g, char_u *b);
|
void term_get_fg_color(char_u *r, char_u *g, char_u *b);
|
||||||
|
@@ -4251,7 +4251,7 @@ is_mouse_topline(win_T *wp)
|
|||||||
* Remove "slen" bytes.
|
* Remove "slen" bytes.
|
||||||
* Returns FAIL for error.
|
* Returns FAIL for error.
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
put_string_in_typebuf(
|
put_string_in_typebuf(
|
||||||
int offset,
|
int offset,
|
||||||
int slen,
|
int slen,
|
||||||
@@ -4342,7 +4342,7 @@ modifiers2keycode(int modifiers, int *key, char_u *string)
|
|||||||
/*
|
/*
|
||||||
* Check if typebuf.tb_buf[] contains a terminal key code.
|
* Check if typebuf.tb_buf[] contains a terminal key code.
|
||||||
* Check from typebuf.tb_buf[typebuf.tb_off] to typebuf.tb_buf[typebuf.tb_off
|
* Check from typebuf.tb_buf[typebuf.tb_off] to typebuf.tb_buf[typebuf.tb_off
|
||||||
* + max_offset].
|
* + "max_offset"].
|
||||||
* Return 0 for no match, -1 for partial match, > 0 for full match.
|
* Return 0 for no match, -1 for partial match, > 0 for full match.
|
||||||
* Return KEYLEN_REMOVED when a key code was deleted.
|
* Return KEYLEN_REMOVED when a key code was deleted.
|
||||||
* With a match, the match is removed, the replacement code is inserted in
|
* With a match, the match is removed, the replacement code is inserted in
|
||||||
|
@@ -1222,6 +1222,23 @@ func RunTest_mapping_shift(key, func)
|
|||||||
endif
|
endif
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_modifyOtherKeys_mapped()
|
||||||
|
set timeoutlen=10
|
||||||
|
imap ' <C-W>
|
||||||
|
imap <C-W><C-A> c-a
|
||||||
|
call setline(1, '')
|
||||||
|
|
||||||
|
" single quote is turned into single byte CTRL-W
|
||||||
|
" CTRL-A is added with a separate modifier, and needs to be simplified before
|
||||||
|
" the mapping can match.
|
||||||
|
call feedkeys("a'" .. GetEscCodeCSI27('A', 5) .. "\<Esc>", 'Lx!')
|
||||||
|
call assert_equal('c-a', getline(1))
|
||||||
|
|
||||||
|
iunmap '
|
||||||
|
iunmap <C-W><C-A>
|
||||||
|
set timeoutlen&
|
||||||
|
endfunc
|
||||||
|
|
||||||
func RunTest_mapping_works_with_shift(func)
|
func RunTest_mapping_works_with_shift(func)
|
||||||
new
|
new
|
||||||
set timeoutlen=10
|
set timeoutlen=10
|
||||||
|
@@ -754,6 +754,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 */
|
||||||
|
/**/
|
||||||
|
916,
|
||||||
/**/
|
/**/
|
||||||
915,
|
915,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user