summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-10-07 16:12:37 +0200
committerBram Moolenaar <Bram@vim.org>2020-10-07 16:12:37 +0200
commit4e2114e988f5d8635f2ad748be3cafcc44289138 (patch)
treed2f14c8854f0fec07b895f8277c49212873f382e
parentf12f0022e6698831681f0931a4e7e5298f6ef0d8 (diff)
downloadvim-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.c7
-rw-r--r--src/gui_x11.c3
-rw-r--r--src/misc2.c26
-rw-r--r--src/proto/misc2.pro1
-rw-r--r--src/term.c9
-rw-r--r--src/testdir/test_termcodes.vim18
-rw-r--r--src/version.c2
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,