]> granicus.if.org Git - vim/commitdiff
patch 8.2.1809: mapping some keys with Ctrl does not work properly v8.2.1809
authorBram Moolenaar <Bram@vim.org>
Wed, 7 Oct 2020 14:12:37 +0000 (16:12 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 7 Oct 2020 14:12:37 +0000 (16:12 +0200)
Problem:    Mapping some keys with Ctrl does not work properly.
Solution:   For terminal, GTK and Motif handle "@", "^" and "_" codes.

src/gui_gtk_x11.c
src/gui_x11.c
src/misc2.c
src/proto/misc2.pro
src/term.c
src/testdir/test_termcodes.vim
src/version.c

index ecd2d887fc9e863523c589abfe698722b51d62ef..2549aef779093e42e3d50f8444e265ad0379ed8e 100644 (file)
@@ -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);
index f1d9bf8e5877fa4d07ee2a508b3200f9f388d96d..38f85d875ea187435304058de18c1550c1e0661f 100644 (file)
@@ -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);
index 3781dd85d291192b71da383cca979f5063c0c2aa..b69714a8da09b43a5b6a82a9a9854dc095f59210 100644 (file)
@@ -2946,6 +2946,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.
index d55fc31c399577767e3b03307a633716e52f3041..fc574038a92a4cbe18c51c4530a2bd00082db347 100644 (file)
@@ -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);
index 4d32c043a32d3792290f2980f7619c420a90d2e8..be6d531b97191f61e261e62c1f7e461996fc6d48 100644 (file)
@@ -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);
 
index 91ccda8ca9f1953fe50976edecdd6bd4b34e20c4..7d7e2f098738b09d8e0a16d3f0b5c865b9e91f27 100644 (file)
@@ -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()
index 67867278497294c2f11984979f5929f1d6e8cceb..9c4029fa7f7e3ef8c06a66d5c34733021f7dc5da 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1809,
 /**/
     1808,
 /**/