summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-11-24 13:27:36 +0000
committerBram Moolenaar <Bram@vim.org>2022-11-24 13:27:36 +0000
commit47f1fdc28c6839ec8f5aede631d3a870624767b6 (patch)
tree1dd79cb5559e0218262250e0b0fd36f99f945854
parent0b228cddc723af0c7ceb1cd73685b0b742f16713 (diff)
patch 9.0.0939: still using simplified mappings when using kitty protocolv9.0.0939
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.
-rw-r--r--runtime/doc/map.txt14
-rw-r--r--src/getchar.c13
-rw-r--r--src/structs.h2
-rw-r--r--src/term.c35
-rw-r--r--src/version.c2
5 files changed, 60 insertions, 6 deletions
diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt
index 19797b2267..e0c7106644 100644
--- a/runtime/doc/map.txt
+++ b/runtime/doc/map.txt
@@ -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.
diff --git a/src/getchar.c b/src/getchar.c
index e2474be0b1..fab721b6da 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -2456,6 +2456,17 @@ check_simplify_modifier(int max_offset)
}
/*
+ * 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.
* - When nothing mapped and typeahead has a character: return map_result_get.
@@ -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))
diff --git a/src/structs.h b/src/structs.h
index 1a7a46c193..111872d633 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -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
diff --git a/src/term.c b/src/term.c
index aa8dcbafa4..8a428338a8 100644
--- a/src/term.c
+++ b/src/term.c
@@ -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;
diff --git a/src/version.c b/src/version.c
index ca0ea28f7c..86f857e4ff 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 */
/**/
+ 939,
+/**/
938,
/**/
937,