]> granicus.if.org Git - vim/commitdiff
patch 9.0.0939: still using simplified mappings when using kitty protocol v9.0.0939
authorBram Moolenaar <Bram@vim.org>
Thu, 24 Nov 2022 13:27:36 +0000 (13:27 +0000)
committerBram Moolenaar <Bram@vim.org>
Thu, 24 Nov 2022 13:27:36 +0000 (13:27 +0000)
Problem:    Still using simplified mappings when using the kitty keyboard
            protocol.
Solution:   Use the kitty_protocol_state value to decide whether to use
            simplified mappings.  Improve how seenModifyOtherKeys is set and
            reset.

runtime/doc/map.txt
src/getchar.c
src/structs.h
src/term.c
src/version.c

index 19797b2267c139fe060474fba3a3ed67437f5c3e..e0c7106644ddb7ebff9dd89160e5c293b93cc2b6 100644 (file)
@@ -971,13 +971,18 @@ using other applications but not when inside Vim.
 Xterm and a few other terminals can be put in a mode where keys with modifiers
 are sent with a special escape code.  Vim recognizes these codes and can then
 make a difference between CTRL-H and Backspace, even when Backspace sends the
-character 8.  And many more special keys.
+character 8.  And many more special keys, such as Tab and CTRL-I, which cannot
+be mapped separately otherwise.
 
 For xterm modifyOtherKeys is enabled in the builtin termcap entry.  If this is
 not used you can enable modifyOtherKeys with these lines in your vimrc: >
       let &t_TI = "\<Esc>[>4;2m"
       let &t_TE = "\<Esc>[>4;m"
 
+This sets modifyOtherKeys to level 2.  Note that modifyOtherKeys level 1 does
+not work.  Some terminals do not support level 2 and then send key codes that
+Vim will not be able to correctly recognize.
+
 In case the modifyOtherKeys mode causes problems you can disable it: >
       let &t_TI = ""
       let &t_TE = ""
@@ -1001,10 +1006,15 @@ spots an escape sequence that must have been created by it.  To see if Vim
 detected such an escape sequence use `:verbose map`, the first line will then
 show "Seen modifyOtherKeys: true" (possibly translated).
 
+This automatic detection depends on receiving an escape code starting with 
+"<1b>[27;".  This is the normal way xterm sends these key codes.  However, if
+the *formatOtherKeys* resource is set another form is used that is not
+recognized, therefore you must not set formatOtherKeys.
+
 A known side effect is that in Insert mode the raw escape sequence is inserted
 after the CTRL-V key.  This can be used to check whether modifyOtherKeys is
 enabled: In Insert mode type CTRL-SHIFT-V CTRL-V, if you get one byte then
-modifyOtherKeys is off, if you get <1b>27;5;118~ then it is on.
+modifyOtherKeys is off, if you get <1b>[27;5;118~ then it is on.
 
 When the 'esckeys' option is off, then modifyOtherKeys will be disabled in
 Insert mode to avoid every key with a modifier causing Insert mode to end.
index e2474be0b1a9de6844cf45a90134681d8d170d49..fab721b6dafa3d833b686690575a6d82fd67bd52 100644 (file)
@@ -2455,6 +2455,17 @@ check_simplify_modifier(int max_offset)
     return 0;
 }
 
+/*
+ * Return TRUE if the terminal sends modifiers with various keys.  This is when
+ * modifyOtherKeys level 2 is enabled or the kitty keyboard protocol is
+ * enabled.
+ */
+    static int
+key_protocol_enabled(void)
+{
+    return seenModifyOtherKeys || kitty_protocol_state == KKPS_ENABLED;
+}
+
 /*
  * Handle mappings in the typeahead buffer.
  * - When something was mapped, return map_result_retry for recursive mappings.
@@ -2564,7 +2575,7 @@ handle_mapping(
            // Skip ":lmap" mappings if keys were mapped.
            if (mp->m_keys[0] == tb_c1
                    && (mp->m_mode & local_State)
-                   && !(mp->m_simplified && seenModifyOtherKeys
+                   && !(mp->m_simplified && key_protocol_enabled()
                                                     && typebuf.tb_maplen == 0)
                    && ((mp->m_mode & MODE_LANGMAP) == 0
                                                    || typebuf.tb_maplen == 0))
index 1a7a46c193f738d82e80613ebe275783f8113e4d..111872d63342259a2f4dfb5b3647044f759dd9d2 100644 (file)
@@ -1264,7 +1264,7 @@ struct mapblock
     int                m_keylen;       // strlen(m_keys)
     int                m_mode;         // valid mode
     int                m_simplified;   // m_keys was simplified, do not use this map
-                               // if seenModifyOtherKeys is TRUE
+                               // if key_protocol_enabled() returns TRUE
     int                m_noremap;      // if non-zero no re-mapping for m_str
     char       m_silent;       // <silent> used, don't echo commands
     char       m_nowait;       // <nowait> used
index aa8dcbafa45dc0ada82da1cb80b4057f0c4b9a46..8a428338a84fbec648d7ac1fe1362582307ff86b 100644 (file)
@@ -3675,9 +3675,16 @@ out_str_t_TE(void)
 {
     out_str(T_CTE);
 
+    // The seenModifyOtherKeys flag is not reset here.  We do expect t_TE to
+    // disable modifyOtherKeys, but there is no way to detect it's enabled
+    // again after the following t_TI.  We assume that when seenModifyOtherKeys
+    // was set before it will still be valid.
+
     // When the kitty keyboard protocol is enabled we expect t_TE to disable
     // it.  Remembering that it was detected to be enabled is useful in some
     // situations.
+    // The following t_TI is expected to request the state and then
+    // kitty_protocol_state will be set again.
     if (kitty_protocol_state == KKPS_ENABLED
            || kitty_protocol_state == KKPS_DISABLED)
        kitty_protocol_state = KKPS_DISABLED;
@@ -5050,9 +5057,22 @@ handle_key_with_modifier(
     int            modifiers;
     char_u  string[MAX_KEY_CODE_LEN + 1];
 
+    // Only set seenModifyOtherKeys for the "{lead}27;" code to avoid setting
+    // it for terminals using the kitty keyboard protocol.  Xterm sends
+    // the form ending in "u" when the formatOtherKeys resource is set.  We do
+    // not support this.
+    //
+    // Do not set seenModifyOtherKeys if there was a positive response at any
+    // time from requesting the kitty keyboard protocol state, these are not
+    // expected to support modifyOtherKeys level 2.
+    //
     // Do not set seenModifyOtherKeys for kitty, it does send some sequences
     // like this but does not have the modifyOtherKeys feature.
-    if (term_props[TPR_KITTY].tpr_status != TPR_YES)
+    if (trail != 'u'
+           && (kitty_protocol_state == KKPS_INITIAL
+               || kitty_protocol_state == KKPS_OFF
+               || kitty_protocol_state == KKPS_AFTER_T_KE)
+           && term_props[TPR_KITTY].tpr_status != TPR_YES)
        seenModifyOtherKeys = TRUE;
 
     if (trail == 'u')
@@ -5237,7 +5257,18 @@ handle_csi(
     {
        // The protocol has various "progressive enhancement flags" values, but
        // we only check for zero and non-zero here.
-       kitty_protocol_state = arg[0] == '0' ? KKPS_OFF : KKPS_ENABLED;
+       if (arg[0] == '0')
+       {
+           kitty_protocol_state = KKPS_OFF;
+       }
+       else
+       {
+           kitty_protocol_state = KKPS_ENABLED;
+
+           // Reset seenModifyOtherKeys just in case some key combination has
+           // been seen that set it before we get the status response.
+           seenModifyOtherKeys = FALSE;
+       }
 
        key_name[0] = (int)KS_EXTRA;
        key_name[1] = (int)KE_IGNORE;
index ca0ea28f7cbba44b4dfe6b94e031b6cbe525b492..86f857e4ff6d2eff9ba4bf9fa173aeb80ed8fdd4 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    939,
 /**/
     938,
 /**/