diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-10-07 16:12:37 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-10-07 16:12:37 +0200 |
commit | 4e2114e988f5d8635f2ad748be3cafcc44289138 (patch) | |
tree | d2f14c8854f0fec07b895f8277c49212873f382e | |
parent | f12f0022e6698831681f0931a4e7e5298f6ef0d8 (diff) | |
download | vim-git-4e2114e988f5d8635f2ad748be3cafcc44289138.tar.gz |
patch 8.2.1809: mapping some keys with Ctrl does not work properlyv8.2.1809
Problem: Mapping some keys with Ctrl does not work properly.
Solution: For terminal, GTK and Motif handle "@", "^" and "_" codes.
-rw-r--r-- | src/gui_gtk_x11.c | 7 | ||||
-rw-r--r-- | src/gui_x11.c | 3 | ||||
-rw-r--r-- | src/misc2.c | 26 | ||||
-rw-r--r-- | src/proto/misc2.pro | 1 | ||||
-rw-r--r-- | src/term.c | 9 | ||||
-rw-r--r-- | src/testdir/test_termcodes.vim | 18 | ||||
-rw-r--r-- | src/version.c | 2 |
7 files changed, 56 insertions, 10 deletions
diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c index ecd2d887f..2549aef77 100644 --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -1236,11 +1236,10 @@ key_press_event(GtkWidget *widget UNUSED, } else { - // <C-H> and <C-h> mean the same thing, always use "H" - if ((modifiers & MOD_MASK_CTRL) && ASCII_ISALPHA(key)) - key = TOUPPER_ASC(key); + // Some keys need adjustment when the Ctrl modifier is used. + key = may_adjust_key_for_ctrl(modifiers, key); - // May remove the shift modifier if it's included in the key. + // May remove the Shift modifier if it's included in the key. modifiers = may_remove_shift_modifier(modifiers, key); len = mb_char2bytes(key, string); diff --git a/src/gui_x11.c b/src/gui_x11.c index f1d9bf8e5..38f85d875 100644 --- a/src/gui_x11.c +++ b/src/gui_x11.c @@ -956,6 +956,9 @@ gui_x11_key_hit_cb( { len = mb_char2bytes(key, string); + // Some keys need adjustment when the Ctrl modifier is used. + key = may_adjust_key_for_ctrl(modifiers, key); + // Remove the SHIFT modifier for keys where it's already included, // e.g., '(', '!' and '*'. modifiers = may_remove_shift_modifier(modifiers, key); diff --git a/src/misc2.c b/src/misc2.c index 3781dd85d..b69714a8d 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -2947,6 +2947,32 @@ find_special_key( /* + * Some keys are used with Ctrl without Shift and are still expected to be + * mapped as if Shift was pressed: + * CTRL-2 is CTRL-@ + * CTRL-6 is CTRL-^ + * CTRL-- is CTRL-_ + * Also, <C-H> and <C-h> mean the same thing, always use "H". + * Returns the possibly adjusted key. + */ + int +may_adjust_key_for_ctrl(int modifiers, int key) +{ + if (modifiers & MOD_MASK_CTRL) + { + if (ASCII_ISALPHA(key)) + return TOUPPER_ASC(key); + if (key == '2') + return '@'; + if (key == '6') + return '^'; + if (key == '-') + return '_'; + } + return key; +} + +/* * Some keys already have Shift included, pass them as normal keys. * Not when Ctrl is also used, because <C-H> and <C-S-H> are different. * Also for <A-S-a> and <M-S-a>. diff --git a/src/proto/misc2.pro b/src/proto/misc2.pro index d55fc31c3..fc574038a 100644 --- a/src/proto/misc2.pro +++ b/src/proto/misc2.pro @@ -72,6 +72,7 @@ char_u *get_special_key_name(int c, int modifiers); int trans_special(char_u **srcp, char_u *dst, int flags, int *did_simplify); int special_to_buf(int key, int modifiers, int keycode, char_u *dst); int find_special_key(char_u **srcp, int *modp, int flags, int *did_simplify); +int may_adjust_key_for_ctrl(int modifiers, int key); int may_remove_shift_modifier(int modifiers, int key); int extract_modifiers(int key, int *modp, int simplify, int *did_simplify); int find_special_key_in_table(int c); diff --git a/src/term.c b/src/term.c index 4d32c043a..be6d531b9 100644 --- a/src/term.c +++ b/src/term.c @@ -4784,15 +4784,12 @@ handle_key_with_modifier( modifiers = decode_modifiers(arg[1]); + // Some keys need adjustment when the Ctrl modifier is used. + key = may_adjust_key_for_ctrl(modifiers, key); + // May remove the shift modifier if it's already included in the key. modifiers = may_remove_shift_modifier(modifiers, key); - // When used with Ctrl we always make a letter upper case, - // so that mapping <C-H> and <C-h> are the same. Typing - // <C-S-H> also uses "H" but modifier is different. - if ((modifiers & MOD_MASK_CTRL) && ASCII_ISALPHA(key)) - key = TOUPPER_ASC(key); - // insert modifiers with KS_MODIFIER new_slen = modifiers2keycode(modifiers, &key, string); diff --git a/src/testdir/test_termcodes.vim b/src/testdir/test_termcodes.vim index 91ccda8ca..7d7e2f098 100644 --- a/src/testdir/test_termcodes.vim +++ b/src/testdir/test_termcodes.vim @@ -2103,6 +2103,24 @@ endfunc func Test_mapping_works_with_ctrl() call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C', 5) call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C', 5) + + new + set timeoutlen=10 + + " CTRL-@ actually produces the code for CTRL-2, which is converted + call RunTest_mapping_mods('<C-@>', '2', function('GetEscCodeCSI27'), 5) + call RunTest_mapping_mods('<C-@>', '2', function('GetEscCodeCSIu'), 5) + + " CTRL-^ actually produces the code for CTRL-6, which is converted + call RunTest_mapping_mods('<C-^>', '6', function('GetEscCodeCSI27'), 5) + call RunTest_mapping_mods('<C-^>', '6', function('GetEscCodeCSIu'), 5) + + " CTRL-_ actually produces the code for CTRL--, which is converted + call RunTest_mapping_mods('<C-_>', '-', function('GetEscCodeCSI27'), 5) + call RunTest_mapping_mods('<C-_>', '-', function('GetEscCodeCSIu'), 5) + + bwipe! + set timeoutlen& endfunc func Test_mapping_works_with_shift_ctrl() diff --git a/src/version.c b/src/version.c index 678672784..9c4029fa7 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1809, +/**/ 1808, /**/ 1807, |