summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/edit.c2
-rw-r--r--src/globals.h18
-rw-r--r--src/libvterm/include/vterm.h1
-rw-r--r--src/libvterm/src/keyboard.c21
-rw-r--r--src/libvterm/src/state.c30
-rw-r--r--src/libvterm/src/vterm_internal.h1
-rw-r--r--src/map.c23
-rw-r--r--src/normal.c2
-rw-r--r--src/option.h1
-rw-r--r--src/optiondefs.h4
-rw-r--r--src/optionstr.c7
-rw-r--r--src/os_unix.c6
-rw-r--r--src/proto/term.pro2
-rw-r--r--src/term.c162
-rw-r--r--src/terminal.c31
-rw-r--r--src/testdir/gen_opt_test.vim2
-rw-r--r--src/testdir/keycode_check.json2
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h8
19 files changed, 295 insertions, 30 deletions
diff --git a/src/edit.c b/src/edit.c
index 2e6a98095..01e5cc2d3 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -330,7 +330,7 @@ edit(
// Disable modifyOtherKeys, keys with modifiers would cause exiting
// Insert mode.
- out_str(T_CTE);
+ out_str_t_TE();
}
/*
diff --git a/src/globals.h b/src/globals.h
index 9d70da6ca..a5e398209 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1377,6 +1377,24 @@ EXTERN int pending_end_reg_executing INIT(= 0);
// no longer be used.
EXTERN int seenModifyOtherKeys INIT(= FALSE);
+// The state for the Kitty keyboard protocol.
+typedef enum {
+ // Initially we have no clue if the protocol is on or off.
+ KKPS_INITIAL,
+ // Used when receiving the state and the flags are zero.
+ KKPS_OFF,
+ // Used when receiving the state and the flags are non-zero.
+ KKPS_ENABLED,
+ // Used after outputting t_KE when the state was KKPS_ENABLED. We do not
+ // really know if t_KE actually disabled the protocol, the following t_KI
+ // is expected to request the state, but the response may come only later.
+ KKPS_DISABLED,
+ // Used after outputting t_KE when the state was not KKPS_ENABLED.
+ KKPS_AFTER_T_KE,
+} kkpstate_T;
+
+EXTERN kkpstate_T kitty_protocol_state INIT(= KKPS_INITIAL);
+
EXTERN int no_mapping INIT(= FALSE); // currently no mapping allowed
EXTERN int no_zero_mapping INIT(= 0); // mapping zero not allowed
EXTERN int allow_keys INIT(= FALSE); // allow key codes when no_mapping
diff --git a/src/libvterm/include/vterm.h b/src/libvterm/include/vterm.h
index e5887c871..6a967dbdb 100644
--- a/src/libvterm/include/vterm.h
+++ b/src/libvterm/include/vterm.h
@@ -368,6 +368,7 @@ size_t vterm_output_get_buffer_remaining(const VTerm *vt);
size_t vterm_output_read(VTerm *vt, char *buffer, size_t len);
int vterm_is_modify_other_keys(VTerm *vt);
+int vterm_is_kitty_keyboard(VTerm *vt);
void vterm_keyboard_unichar(VTerm *vt, uint32_t c, VTermModifier mod);
void vterm_keyboard_key(VTerm *vt, VTermKey key, VTermModifier mod);
diff --git a/src/libvterm/src/keyboard.c b/src/libvterm/src/keyboard.c
index ffd831927..7a44670e7 100644
--- a/src/libvterm/src/keyboard.c
+++ b/src/libvterm/src/keyboard.c
@@ -10,6 +10,12 @@ int vterm_is_modify_other_keys(VTerm *vt)
return vt->state->mode.modify_other_keys;
}
+// VIM: added
+int vterm_is_kitty_keyboard(VTerm *vt)
+{
+ return vt->state->mode.kitty_keyboard;
+}
+
void vterm_keyboard_unichar(VTerm *vt, uint32_t c, VTermModifier mod)
{
@@ -19,6 +25,12 @@ void vterm_keyboard_unichar(VTerm *vt, uint32_t c, VTermModifier mod)
return;
}
+ // VIM: added kitty keyboard protocol support
+ if (vterm_is_kitty_keyboard(vt) && mod != 0) {
+ vterm_push_output_sprintf_ctrl(vt, C1_CSI, "%d;%du", c, mod+1);
+ return;
+ }
+
/* The shift modifier is never important for Unicode characters
* apart from Space
*/
@@ -166,8 +178,10 @@ void vterm_keyboard_key(VTerm *vt, VTermKey key, VTermModifier mod)
break;
case KEYCODE_TAB:
+ if (vterm_is_kitty_keyboard(vt) && mod != 0)
+ vterm_push_output_sprintf_ctrl(vt, C1_CSI, "9;%du", mod+1);
/* Shift-Tab is CSI Z but plain Tab is 0x09 */
- if(mod == VTERM_MOD_SHIFT)
+ else if(mod == VTERM_MOD_SHIFT)
vterm_push_output_sprintf_ctrl(vt, C1_CSI, "Z");
else if(mod & VTERM_MOD_SHIFT)
vterm_push_output_sprintf_ctrl(vt, C1_CSI, "1;%dZ", mod+1);
@@ -186,7 +200,10 @@ void vterm_keyboard_key(VTerm *vt, VTermKey key, VTermModifier mod)
case KEYCODE_LITERAL: case_LITERAL:
if (vterm_is_modify_other_keys(vt) && mod != 0)
vterm_push_output_sprintf_ctrl(vt, C1_CSI, "27;%d;%d~", mod+1, k.literal);
- else if(mod & (VTERM_MOD_SHIFT|VTERM_MOD_CTRL))
+ else if (vterm_is_kitty_keyboard(vt) && mod == 0 && k.literal == '\x1b')
+ vterm_push_output_sprintf_ctrl(vt, C1_CSI, "%du", k.literal);
+ else if ((vterm_is_kitty_keyboard(vt) && mod != 0)
+ || (mod & (VTERM_MOD_SHIFT|VTERM_MOD_CTRL)))
vterm_push_output_sprintf_ctrl(vt, C1_CSI, "%d;%du", k.literal, mod+1);
else
vterm_push_output_sprintf(vt, mod & VTERM_MOD_ALT ? ESC_S "%c" : "%c", k.literal);
diff --git a/src/libvterm/src/state.c b/src/libvterm/src/state.c
index 8aae7d146..33395e96a 100644
--- a/src/libvterm/src/state.c
+++ b/src/libvterm/src/state.c
@@ -1423,9 +1423,37 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha
}
break;
- case LEADER('>', 0x6d): // xterm resource modifyOtherKeys
+ case LEADER('>', 0x6d): // CSI > 4 ; Pv m xterm resource modifyOtherKeys
if (argcount == 2 && args[0] == 4)
+ {
+ // can't have both modify_other_keys and kitty_keyboard
+ state->mode.kitty_keyboard = 0;
+
state->mode.modify_other_keys = args[1] == 2;
+ }
+ break;
+
+ case LEADER('>', 0x75): // CSI > 1 u enable kitty keyboard protocol
+ if (argcount == 1 && args[0] == 1)
+ {
+ // can't have both modify_other_keys and kitty_keyboard
+ state->mode.modify_other_keys = 0;
+
+ state->mode.kitty_keyboard = 1;
+ }
+ break;
+
+ case LEADER('<', 0x75): // CSI < u disable kitty keyboard protocol
+ if (argcount <= 1)
+ state->mode.kitty_keyboard = 0;
+ break;
+
+ case LEADER('?', 0x75): // CSI ? u request kitty keyboard protocol state
+ if (argcount <= 1)
+ // TODO: this only uses the values zero and one. The protocol specifies
+ // more values, the progressive enhancement flags.
+ vterm_push_output_sprintf_ctrl(state->vt, C1_CSI, "?%du",
+ state->mode.kitty_keyboard);
break;
case 0x6e: // DSR - ECMA-48 8.3.35
diff --git a/src/libvterm/src/vterm_internal.h b/src/libvterm/src/vterm_internal.h
index 0e389d0b2..3e95611b4 100644
--- a/src/libvterm/src/vterm_internal.h
+++ b/src/libvterm/src/vterm_internal.h
@@ -130,6 +130,7 @@ struct VTermState
unsigned int bracketpaste:1;
unsigned int report_focus:1;
unsigned int modify_other_keys:1;
+ unsigned int kitty_keyboard:1;
} mode;
VTermEncodingInstance encoding[4], encoding_utf8;
diff --git a/src/map.c b/src/map.c
index 4dec9e76e..ee249c77a 100644
--- a/src/map.c
+++ b/src/map.c
@@ -312,8 +312,27 @@ list_mappings(
// Prevent mappings to be cleared while at the more prompt.
++map_locked;
- if (p_verbose > 0 && keyround == 1 && seenModifyOtherKeys)
- msg_puts(_("Seen modifyOtherKeys: true"));
+ if (p_verbose > 0 && keyround == 1)
+ {
+ if (seenModifyOtherKeys)
+ msg_puts(_("Seen modifyOtherKeys: true"));
+ if (kitty_protocol_state != KKPS_INITIAL)
+ {
+ char *name = _("Unknown");
+ switch (kitty_protocol_state)
+ {
+ case KKPS_INITIAL: break;
+ case KKPS_OFF: name = _("Off"); break;
+ case KKPS_ENABLED: name = _("On"); break;
+ case KKPS_DISABLED: name = _("Disabled"); break;
+ case KKPS_AFTER_T_KE: name = _("Cleared"); break;
+ }
+
+ char buf[200];
+ vim_snprintf(buf, sizeof(buf), _("Kitty keyboard protocol: %s"), name);
+ msg_puts(buf);
+ }
+ }
// need to loop over all global hash lists
for (int hash = 0; hash < 256 && !got_int; ++hash)
diff --git a/src/normal.c b/src/normal.c
index 5000f53e5..938ae718e 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -424,7 +424,7 @@ normal_cmd_get_more_chars(
// Disable bracketed paste and modifyOtherKeys here, we won't
// recognize the escape sequences with 'esckeys' off.
out_str(T_BD);
- out_str(T_CTE);
+ out_str_t_TE();
}
*cp = plain_vgetc();
diff --git a/src/option.h b/src/option.h
index eed12e837..6f2701344 100644
--- a/src/option.h
+++ b/src/option.h
@@ -698,6 +698,7 @@ EXTERN char_u *p_keymap; // 'keymap'
#endif
EXTERN char_u *p_kp; // 'keywordprg'
EXTERN char_u *p_km; // 'keymodel'
+EXTERN char_u *p_kpc; // 'keyprotocol'
#ifdef FEAT_LANGMAP
EXTERN char_u *p_langmap; // 'langmap'
EXTERN int p_lnr; // 'langnoremap'
diff --git a/src/optiondefs.h b/src/optiondefs.h
index 5b3860b61..0278b6061 100644
--- a/src/optiondefs.h
+++ b/src/optiondefs.h
@@ -1447,6 +1447,10 @@ static struct vimoption options[] =
{"keymodel", "km", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP,
(char_u *)&p_km, PV_NONE,
{(char_u *)"", (char_u *)0L} SCTX_INIT},
+ {"keyprotocol", "kpc", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP,
+ (char_u *)&p_kpc, PV_NONE,
+ {(char_u *)"kitty:kitty,foot:kitty,wezterm:kitty,xterm:mok2", (char_u *)0L}
+ SCTX_INIT},
{"keywordprg", "kp", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
(char_u *)&p_kp, PV_KP,
{
diff --git a/src/optionstr.c b/src/optionstr.c
index 9e9d18f0e..084b43870 100644
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -1663,6 +1663,13 @@ did_set_string_option(
}
}
+ // 'keyprotocol'
+ else if (varp == &p_kpc)
+ {
+ if (match_keyprotocol(NULL) == KEYPROTOCOL_FAIL)
+ errmsg = e_invalid_argument;
+ }
+
// 'mousemodel'
else if (varp == &p_mousem)
{
diff --git a/src/os_unix.c b/src/os_unix.c
index db57902dc..0540fc950 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -5348,9 +5348,9 @@ finished:
long delay_msec = 1;
if (tmode == TMODE_RAW)
- // possibly disables modifyOtherKeys, so that the system
- // can recognize CTRL-C
- out_str(T_CTE);
+ // Possibly disables modifyOtherKeys, so that the system
+ // can recognize CTRL-C.
+ out_str_t_TE();
/*
* Similar to the loop above, but only handle X events, no
diff --git a/src/proto/term.pro b/src/proto/term.pro
index 7ce14b921..b1c691d80 100644
--- a/src/proto/term.pro
+++ b/src/proto/term.pro
@@ -4,6 +4,7 @@ guicolor_T termgui_mch_get_rgb(guicolor_T color);
void init_term_props(int all);
void f_terminalprops(typval_T *argvars, typval_T *rettv);
void set_color_count(int nr);
+keyprot_T match_keyprotocol(char_u *term);
int set_termname(char_u *term);
void free_cur_term(void);
void getlinecol(long *cp, long *rp);
@@ -46,6 +47,7 @@ void win_new_shellsize(void);
void shell_resized(void);
void shell_resized_check(void);
void set_shellsize(int width, int height, int mustset);
+void out_str_t_TE(void);
void settmode(tmode_T tmode);
void starttermcap(void);
void stoptermcap(void);
diff --git a/src/term.c b/src/term.c
index bb1e283be..7f639dd57 100644
--- a/src/term.c
+++ b/src/term.c
@@ -587,6 +587,32 @@ static tcap_entry_T builtin_xterm[] = {
};
/*
+ * Additions for using modifyOtherKeys level 2. Same as what is used for
+ * xterm.
+ */
+static tcap_entry_T builtin_mok2[] = {
+ {(int)KS_CTI, "\033[>4;2m"},
+ {(int)KS_CTE, "\033[>4;m"},
+
+ {(int)KS_NAME, NULL} // end marker
+};
+
+/*
+ * Additions for using the Kitty keyboard protocol.
+ */
+static tcap_entry_T builtin_kitty[] = {
+ // t_TI enables the kitty keyboard protocol, requests the kitty keyboard
+ // protocol state and requests the version response.
+ {(int)KS_CTI, "\033[>1u\033[?u\033[>c"},
+
+ // t_TE also disabled modifyOtherKeys, because t_TI from xterm may already
+ // have been used.
+ {(int)KS_CTE, "\033[>4;m\033[<u"},
+
+ {(int)KS_NAME, NULL} // end marker
+};
+
+/*
* iris-ansi for Silicon Graphics machines.
*/
static tcap_entry_T builtin_iris_ansi[] = {
@@ -1494,26 +1520,22 @@ find_builtin_term(char_u *term)
}
/*
- * Parsing of the builtin termcap entries.
- * Caller should check if "term" is a valid builtin terminal name.
- * The terminal's name is not set, as this is already done in termcapinit().
+ * Apply entries from a builtin termcap.
*/
static void
-parse_builtin_tcap(char_u *term)
+apply_builtin_tcap(char_u *term, tcap_entry_T *entries, int overwrite)
{
- tcap_entry_T *p = find_builtin_term(term);
- if (p == NULL) // builtin term not found
- return;
-
int term_8bit = term_is_8bit(term);
- for ( ; p->bt_entry != (int)KS_NAME && p->bt_entry != BT_EXTRA_KEYS; ++p)
+ for (tcap_entry_T *p = entries;
+ p->bt_entry != (int)KS_NAME && p->bt_entry != BT_EXTRA_KEYS; ++p)
{
if ((int)p->bt_entry >= 0) // KS_xx entry
{
- // Only set the value if it wasn't set yet.
+ // Only set the value if it wasn't set yet or "overwrite" is TRUE.
if (term_strings[p->bt_entry] == NULL
- || term_strings[p->bt_entry] == empty_option)
+ || term_strings[p->bt_entry] == empty_option
+ || overwrite)
{
#ifdef FEAT_EVAL
int opt_idx = -1;
@@ -1557,13 +1579,26 @@ parse_builtin_tcap(char_u *term)
char_u name[2];
name[0] = KEY2TERMCAP0((int)p->bt_entry);
name[1] = KEY2TERMCAP1((int)p->bt_entry);
- if (find_termcode(name) == NULL)
+ if (find_termcode(name) == NULL || overwrite)
add_termcode(name, (char_u *)p->bt_string, term_8bit);
}
}
}
/*
+ * Parsing of the builtin termcap entries.
+ * Caller should check if "term" is a valid builtin terminal name.
+ * The terminal's name is not set, as this is already done in termcapinit().
+ */
+ static void
+parse_builtin_tcap(char_u *term)
+{
+ tcap_entry_T *entries = find_builtin_term(term);
+ if (entries != NULL)
+ apply_builtin_tcap(term, entries, FALSE);
+}
+
+/*
* Set number of colors.
* Store it as a number in t_colors.
* Store it as a string in T_CCO (using nr_colors[]).
@@ -1799,6 +1834,67 @@ report_default_term(char_u *term)
}
/*
+ * Parse the 'keyprotocol' option, match against "term" and return the protocol
+ * for the first matching entry.
+ * When "term" is NULL then compile all patterns to check for any errors.
+ * Returns KEYPROTOCOL_FAIL if a pattern cannot be compiled.
+ * Returns KEYPROTOCOL_NONE if there is no match.
+ */
+ keyprot_T
+match_keyprotocol(char_u *term)
+{
+ int len = (int)STRLEN(p_kpc) + 1;
+ char_u *buf = alloc(len);
+ if (buf == NULL)
+ return KEYPROTOCOL_FAIL;
+
+ keyprot_T ret = KEYPROTOCOL_FAIL;
+ char_u *p = p_kpc;
+ while (*p != NUL)
+ {
+ // Isolate one comma separated item.
+ (void)copy_option_part(&p, buf, len, ",");
+ char_u *colon = vim_strchr(buf, ':');
+ if (colon == NULL || colon == buf || colon[1] == NUL)
+ goto theend;
+ *colon = NUL;
+
+ keyprot_T prot;
+ if (STRCMP(colon + 1, "none") == 0)
+ prot = KEYPROTOCOL_NONE;
+ else if (STRCMP(colon + 1, "mok2") == 0)
+ prot = KEYPROTOCOL_MOK2;
+ else if (STRCMP(colon + 1, "kitty") == 0)
+ prot = KEYPROTOCOL_KITTY;
+ else
+ goto theend;
+
+ regmatch_T regmatch;
+ CLEAR_FIELD(regmatch);
+ regmatch.rm_ic = TRUE;
+ regmatch.regprog = vim_regcomp(buf, RE_MAGIC);
+ if (regmatch.regprog == NULL)
+ goto theend;
+
+ int match = term != NULL && vim_regexec(&regmatch, term, (colnr_T)0);
+ vim_regfree(regmatch.regprog);
+ if (match)
+ {
+ ret = prot;
+ goto theend;
+ }
+
+ }
+
+ // No match found, use "none".
+ ret = KEYPROTOCOL_NONE;
+
+theend:
+ vim_free(buf);
+ return ret;
+}
+
+/*
* Set terminal options for terminal "term".
* Return OK if terminal 'term' was found in a termcap, FAIL otherwise.
*
@@ -1924,6 +2020,15 @@ set_termname(char_u *term)
}
#endif
parse_builtin_tcap(term);
+
+ // Use the 'keyprotocol' option to adjust the t_TE and t_TI
+ // termcap entries if there is an entry maching "term".
+ keyprot_T kpc = match_keyprotocol(term);
+ if (kpc == KEYPROTOCOL_KITTY)
+ apply_builtin_tcap(term, builtin_kitty, TRUE);
+ else if (kpc == KEYPROTOCOL_MOK2)
+ apply_builtin_tcap(term, builtin_mok2, TRUE);
+
#ifdef FEAT_GUI
if (term_is_gui(term))
{
@@ -3562,6 +3667,25 @@ set_shellsize(int width, int height, int mustset)
}
/*
+ * Output T_CTE, the t_TE termcap entry, and handle expected effects.
+ * The code possibly disables modifyOtherKeys and the Kitty keyboard protocol.
+ */
+ void
+out_str_t_TE(void)
+{
+ out_str(T_CTE);
+
+ // 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.
+ if (kitty_protocol_state == KKPS_ENABLED
+ || kitty_protocol_state == KKPS_DISABLED)
+ kitty_protocol_state = KKPS_DISABLED;
+ else
+ kitty_protocol_state = KKPS_AFTER_T_KE;
+}
+
+/*
* Set the terminal to TMODE_RAW (for Normal mode) or TMODE_COOK (for external
* commands and Ex mode).
*/
@@ -3613,7 +3737,7 @@ settmode(tmode_T tmode)
if (tmode != TMODE_RAW)
{
out_str(T_BD); // disable bracketed paste mode
- out_str(T_CTE); // possibly disables modifyOtherKeys
+ out_str_t_TE(); // possibly disables modifyOtherKeys
}
else
{
@@ -3714,7 +3838,8 @@ stoptermcap(void)
out_flush();
termcap_active = FALSE;
cursor_on(); // just in case it is still off
- out_str(T_CTE); // stop "raw" mode
+ out_str_t_TE(); // stop "raw" mode, modifyOtherKeys and
+ // Kitty keyboard protocol
out_str(T_TE); // stop termcap mode
screen_start(); // don't know where cursor is now
out_flush();
@@ -5107,6 +5232,15 @@ handle_csi(
# endif
}
+ // Kitty keyboard protocol status response: CSI ? flags u
+ else if (first == '?' && argc == 1 && trail == 'u')
+ {
+ // 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;
+ *slen = csi_len;
+ }
+
// Check for a window position response from the terminal:
// {lead}3;{x};{y}t
else if (did_request_winpos && argc == 3 && arg[0] == 3
diff --git a/src/terminal.c b/src/terminal.c
index 64e6ad45d..fe82fa3fa 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -1587,6 +1587,13 @@ term_convert_key(term_T *term, int c, int modmask, char *buf)
if (modmask & (MOD_MASK_ALT | MOD_MASK_META))
mod |= VTERM_MOD_ALT;
+ // Ctrl-Shift-i may have the key "I" instead of "i", but for the kitty
+ // keyboard protocol should use "i". Applies to all ascii letters.
+ if (ASCII_ISUPPER(c)
+ && vterm_is_kitty_keyboard(curbuf->b_term->tl_vterm)
+ && mod == (VTERM_MOD_CTRL | VTERM_MOD_SHIFT))
+ c = TOLOWER_ASC(c);
+
/*
* Convert special keys to vterm keys:
* - Write keys to vterm: vterm_keyboard_key()
@@ -2182,6 +2189,19 @@ typedef enum {
static reduce_key_state_T no_reduce_key_state = NRKS_NONE;
+/*
+ * Return TRUE if the term is using modifyOtherKeys level 2 or the kitty
+ * keyboard protocol.
+ */
+ static int
+vterm_using_key_protocol(void)
+{
+ return curbuf->b_term != NULL
+ && curbuf->b_term->tl_vterm != NULL
+ && (vterm_is_modify_other_keys(curbuf->b_term->tl_vterm)
+ || vterm_is_kitty_keyboard(curbuf->b_term->tl_vterm));
+}
+
void
check_no_reduce_keys(void)
{
@@ -2191,9 +2211,10 @@ check_no_reduce_keys(void)
|| curbuf->b_term->tl_vterm == NULL)
return;
- if (vterm_is_modify_other_keys(curbuf->b_term->tl_vterm))
+ if (vterm_using_key_protocol())
{
- // "modify_other_keys" was enabled while waiting.
+ // "modify_other_keys" or kitty keyboard protocol was enabled while
+ // waiting.
no_reduce_key_state = NRKS_SET;
++no_reduce_keys;
}
@@ -2216,8 +2237,7 @@ term_vgetc()
ctrl_break_was_pressed = FALSE;
#endif
- if (curbuf->b_term->tl_vterm != NULL
- && vterm_is_modify_other_keys(curbuf->b_term->tl_vterm))
+ if (vterm_using_key_protocol())
{
++no_reduce_keys;
no_reduce_key_state = NRKS_SET;
@@ -2641,12 +2661,13 @@ raw_c_to_ctrl(int c)
/*
* When modify_other_keys is set then do the reverse of raw_c_to_ctrl().
+ * Also when the Kitty keyboard protocol is used.
* May set "mod_mask".
*/
static int
ctrl_to_raw_c(int c)
{
- if (c < 0x20 && vterm_is_modify_other_keys(curbuf->b_term->tl_vterm))
+ if (c < 0x20 && vterm_using_key_protocol())
{
mod_mask |= MOD_MASK_CTRL;
return c + '@';
diff --git a/src/testdir/gen_opt_test.vim b/src/testdir/gen_opt_test.vim
index dd5f73e43..7337217a3 100644
--- a/src/testdir/gen_opt_test.vim
+++ b/src/testdir/gen_opt_test.vim
@@ -113,6 +113,8 @@ let test_values = {
\ 'isprint': [['', '@', '@,48-52'], ['xxx', '@48']],
\ 'keymap': [['', 'accents'], ['xxx']],
\ 'keymodel': [['', 'startsel', 'startsel,stopsel'], ['xxx']],
+ \ 'keyprotocol': [['', 'xxx:none', 'yyy:mok2', 'zzz:kitty'],
+ \ [':none', 'xxx:', 'x:non', 'y:mok3', 'z:kittty']],
\ 'langmap': [['', 'xX', 'aA,bB'], ['xxx']],
\ 'lispoptions': [['', 'expr:0', 'expr:1'], ['xxx']],
\ 'listchars': [['', 'eol:x', 'eol:x,space:y'], ['xxx']],
diff --git a/src/testdir/keycode_check.json b/src/testdir/keycode_check.json
index 868c2a9f1..218859f34 100644
--- a/src/testdir/keycode_check.json
+++ b/src/testdir/keycode_check.json
@@ -1 +1 @@
-{"12xterm":{"Space":"20","version":"1b5b3e34313b3335363b3063","C-Tab":"1b5b32373b353b397e","A-Esc":"1b5b32373b333b32377e","C-Space":"1b5b32373b353b33327e","status":"","S-C-I":"1b5b32373b363b37337e","C-I":"1b5b32373b353b3130357e","S-Tab":"1b5b5a","Tab":"09","S-Space":"1b5b32373b323b33327e","A-Tab":"1b5b32373b333b397e","C-Esc":"1b5b32373b353b32377e","protocol":"mok2","A-Space":"1b5b32373b333b33327e","S-Esc":"1b","Esc":"1b"},"libvterm":{"Space":"20","version":"1b5b3e303b3130303b3063","C-Tab":"1b5b32373b353b397e","A-Esc":"1b5b32373b333b32377e","C-Space":"1b5b32373b353b33327e","status":"","S-C-I":"1b5b32373b363b37337e","C-I":"1b5b32373b353b3130357e","S-Tab":"1b5b5a","Tab":"09","resource":"","A-Tab":"1b5b32373b333b397e","S-Space":"1b5b32373b323b33327e","C-Esc":"1b5b32373b353b32377e","protocol":"mok2","A-Space":"1b5b32373b333b33327e","S-Esc":"1b","Esc":"1b"},"2kitty":{"Space":"20","version":"1b5b3e313b343030303b323163","C-Tab":"","A-Esc":"1b5b32373b313175","C-Space":"1b5b33323b3575","status":"1b5b3f3175","S-C-I":"1b5b3130353b3675","C-I":"1b5b3130353b3575","S-Tab":"1b5b393b3275","Tab":"09","S-Space":"20","A-Tab":"1b5b393b313175","C-Esc":"1b5b32373b3575","protocol":"kitty","A-Space":"1b5b33323b313175","S-Esc":"1b5b32373b3275","Esc":"1b5b323775"},"11xterm":{"Space":"20","version":"1b5b3e34313b3335363b3063","C-Tab":"09","A-Esc":"9b00","status":"","S-C-I":"09","C-I":"09","S-Tab":"1b5b5a","Tab":"09","S-Space":"20","A-Tab":"8900","C-Esc":"1b","protocol":"none","A-Space":"a000","S-Esc":"1b","Esc":"1b"}}
+{"31kitty":{"Space":"20","version":"1b5b3e313b343030303b323163","C-Tab":"","A-Esc":"1b5b32373b313175","C-Space":"1b5b33323b3575","status":"1b5b3f3175","S-C-I":"1b5b3130353b3675","C-I":"1b5b3130353b3575","S-Tab":"1b5b393b3275","Tab":"09","resource":"","A-Tab":"1b5b393b313175","S-Space":"20","C-Esc":"1b5b32373b3575","protocol":"kitty","A-Space":"1b5b33323b313175","S-Esc":"1b5b32373b3275","Esc":"1b5b323775"},"32libvterm":{"Space":"20","version":"1b5b3e303b3130303b3063","C-Tab":"1b5b393b3575","A-Esc":"1b5b32373b3375","C-Space":"1b5b33323b3575","status":"1b5b3f3175","S-C-I":"1b5b3130353b3675","C-I":"1b5b3130353b3575","S-Tab":"1b5b393b3275","Tab":"09","resource":"","A-Tab":"1b5b393b3375","S-Space":"1b5b33323b3275","C-Esc":"1b5b32373b3575","protocol":"kitty","A-Space":"1b5b33323b3375","S-Esc":"1b5b323775","Esc":"1b5b323775"},"22libvterm":{"Space":"20","version":"1b5b3e303b3130303b3063","C-Tab":"1b5b32373b353b397e","A-Esc":"1b5b32373b333b32377e","C-Space":"1b5b32373b353b33327e","status":"","S-C-I":"1b5b32373b363b37337e","C-I":"1b5b32373b353b3130357e","S-Tab":"1b5b5a","Tab":"09","resource":"","A-Tab":"1b5b32373b333b397e","S-Space":"1b5b32373b323b33327e","C-Esc":"1b5b32373b353b32377e","protocol":"mok2","A-Space":"1b5b32373b333b33327e","S-Esc":"1b","Esc":"1b"},"13kitty":{"Space":"20","version":"1b5b3e313b343030303b323163","C-Tab":"","A-Esc":"1b1b","status":"","S-C-I":"1b5b3130353b3675","C-I":"09","S-Tab":"1b5b5a","Tab":"09","resource":"","A-Tab":"1b09","S-Space":"20","C-Esc":"1b","protocol":"none","A-Space":"1b5b33323b313175","S-Esc":"1b","Esc":"1b"},"21xterm":{"Space":"20","version":"1b5b3e34313b3335363b3063","C-Tab":"1b5b32373b353b397e","A-Esc":"1b5b32373b333b32377e","C-Space":"1b5b32373b353b33327e","status":"","S-C-I":"1b5b32373b363b37337e","C-I":"1b5b32373b353b3130357e","S-Tab":"1b5b5a","Tab":"09","resource":"=30","A-Tab":"1b5b32373b333b397e","S-Space":"1b5b32373b323b33327e","C-Esc":"1b5b32373b353b32377e","protocol":"mok2","A-Space":"1b5b32373b333b33327e","S-Esc":"1b","Esc":"1b"},"12libvterm":{"Space":"20","version":"1b5b3e303b3130303b3063","C-Tab":"1b5b393b3575","A-Esc":"9b00","status":"","S-C-I":"1b5b5a","C-I":"09","S-Tab":"1b5b5a","Tab":"09","S-Space":"1b5b33323b3275","A-Tab":"8900","resource":"","C-Esc":"1b5b32373b3575","protocol":"none","A-Space":"a000","S-Esc":"1b","Esc":"1b"},"11xterm":{"Space":"20","version":"1b5b3e34313b3335363b3063","C-Tab":"09","A-Esc":"9b00","status":"","S-C-I":"09","C-I":"09","S-Tab":"1b5b5a","Tab":"09","S-Space":"20","A-Tab":"8900","C-Esc":"1b","protocol":"none","A-Space":"a000","S-Esc":"1b","Esc":"1b"}}
diff --git a/src/version.c b/src/version.c
index 42e7200ab..a96b11ada 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 930,
+/**/
929,
/**/
928,
diff --git a/src/vim.h b/src/vim.h
index 14630e601..67751ffbe 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -2257,6 +2257,14 @@ typedef enum {
ESTACK_SCRIPT,
} estack_arg_T;
+// Return value of match_keyprotocol()
+typedef enum {
+ KEYPROTOCOL_NONE,
+ KEYPROTOCOL_MOK2,
+ KEYPROTOCOL_KITTY,
+ KEYPROTOCOL_FAIL
+} keyprot_T;
+
// Flags for assignment functions.
#define ASSIGN_VAR 0 // ":var" (nothing special)
#define ASSIGN_FINAL 0x01 // ":final"