Revamp extended keys support to more closely match xterm and support

mode 2 as well as mode 1. From Stanislav Kljuhhin (GitHub issue 4038).

This changes tmux to always request mode 2 from parent terminal, change
to an unambiguous internal representation of keys, and adds an option
(extended-keys-format) to control the format similar to the xterm(1)
formatOtherKeys resource.
This commit is contained in:
nicm
2024-08-21 04:17:09 +00:00
parent de6bce057a
commit c7e61a01e5
12 changed files with 238 additions and 136 deletions

View File

@ -56,12 +56,47 @@ static const struct {
{ "PPage", KEYC_PPAGE|KEYC_IMPLIED_META },
{ "PageUp", KEYC_PPAGE|KEYC_IMPLIED_META },
{ "PgUp", KEYC_PPAGE|KEYC_IMPLIED_META },
{ "Tab", '\011' },
{ "BTab", KEYC_BTAB },
{ "Space", ' ' },
{ "BSpace", KEYC_BSPACE },
{ "Enter", '\r' },
{ "Escape", '\033' },
/*
* C0 control characters, with the exception of Tab, Enter,
* and Esc, should never appear as keys. We still render them,
* so to be able to spot them in logs in case of an abnormality.
*/
{ "[NUL]", C0_NUL },
{ "[SOH]", C0_SOH },
{ "[STX]", C0_STX },
{ "[ETX]", C0_ETX },
{ "[EOT]", C0_EOT },
{ "[ENQ]", C0_ENQ },
{ "[ASC]", C0_ASC },
{ "[BEL]", C0_BEL },
{ "[BS]", C0_BS },
{ "Tab", C0_HT },
{ "[LF]", C0_LF },
{ "[VT]", C0_VT },
{ "[FF]", C0_FF },
{ "Enter", C0_CR },
{ "[SO]", C0_SO },
{ "[SI]", C0_SI },
{ "[DLE]", C0_DLE },
{ "[DC1]", C0_DC1 },
{ "[DC2]", C0_DC2 },
{ "[DC3]", C0_DC3 },
{ "[DC4]", C0_DC4 },
{ "[NAK]", C0_NAK },
{ "[SYN]", C0_SYN },
{ "[ETB]", C0_ETB },
{ "[CAN]", C0_CAN },
{ "[EM]", C0_EM },
{ "[SUB]", C0_SUB },
{ "Escape", C0_ESC },
{ "[FS]", C0_FS },
{ "[GS]", C0_GS },
{ "[RS]", C0_RS },
{ "[US]", C0_US },
/* Arrow keys. */
{ "Up", KEYC_UP|KEYC_CURSOR|KEYC_IMPLIED_META },
@ -206,7 +241,6 @@ key_string_get_modifiers(const char **string)
key_code
key_string_lookup_string(const char *string)
{
static const char *other = "!#()+,-.0123456789:;<=>'\r\t\177`/";
key_code key, modifiers;
u_int u, i;
struct utf8_data ud, *udp;
@ -281,26 +315,6 @@ key_string_lookup_string(const char *string)
key &= ~KEYC_IMPLIED_META;
}
/* Convert the standard control keys. */
if (key <= 127 &&
(modifiers & KEYC_CTRL) &&
strchr(other, key) == NULL &&
key != 9 &&
key != 13 &&
key != 27) {
if (key >= 97 && key <= 122)
key -= 96;
else if (key >= 64 && key <= 95)
key -= 64;
else if (key == 32)
key = 0;
else if (key == 63)
key = 127;
else
return (KEYC_UNKNOWN);
modifiers &= ~KEYC_CTRL;
}
return (key|modifiers);
}
@ -324,10 +338,6 @@ key_string_lookup_key(key_code key, int with_flags)
goto out;
}
/* Display C-@ as C-Space. */
if ((key & (KEYC_MASK_KEY|KEYC_MASK_MODIFIERS)) == 0)
key = ' '|KEYC_CTRL;
/* Fill in the modifiers. */
if (key & KEYC_CTRL)
strlcat(out, "C-", sizeof out);
@ -427,13 +437,8 @@ key_string_lookup_key(key_code key, int with_flags)
goto out;
}
/* Check for standard or control key. */
if (key <= 32) {
if (key == 0 || key > 26)
xsnprintf(tmp, sizeof tmp, "C-%c", (int)(64 + key));
else
xsnprintf(tmp, sizeof tmp, "C-%c", (int)(96 + key));
} else if (key >= 32 && key <= 126) {
/* Printable ASCII keys. */
if (key > 32 && key <= 126) {
tmp[0] = key;
tmp[1] = '\0';
} else if (key == 127)
@ -460,8 +465,6 @@ out:
strlcat(out, "I", sizeof out);
if (saved & KEYC_BUILD_MODIFIERS)
strlcat(out, "B", sizeof out);
if (saved & KEYC_EXTENDED)
strlcat(out, "E", sizeof out);
if (saved & KEYC_SENT)
strlcat(out, "S", sizeof out);
strlcat(out, "]", sizeof out);