aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Anders <greg@gpanders.com>2024-12-31 12:16:25 -0600
committerGitHub <noreply@github.com>2024-12-31 12:16:25 -0600
commitb5cb69f8a4a310fb3f18e79bcf5c7ed41d635a48 (patch)
treed8ee38a615937377f1fd9f4a4fb067f234672480
parenta389dc2f950ef89492dfc2d8334e421d2252cddf (diff)
downloadrneovim-b5cb69f8a4a310fb3f18e79bcf5c7ed41d635a48.tar.gz
rneovim-b5cb69f8a4a310fb3f18e79bcf5c7ed41d635a48.tar.bz2
rneovim-b5cb69f8a4a310fb3f18e79bcf5c7ed41d635a48.zip
fix(tui): handle key events for arrow and function keys (#31804)
Arrow and function keys do not use CSI u with the kitty keyboard protocol. For example, the Up arrow key uses CSI A, and the function keys use a variety of different CSI sequences. Until now, termkey only parsed subparams used by key events for CSI u sequences. The result being that any key which did not use CSI u (e.g. arrow and function keys) was being emitted twice by termkey since it was not recognizing the separate press and release events. This commit makes termkey also parse subparams for other key sequences so that the release key events do not send duplicate keys.
-rw-r--r--src/nvim/tui/termkey/driver-csi.c50
-rw-r--r--src/nvim/tui/termkey/termkey_defs.h1
2 files changed, 37 insertions, 14 deletions
diff --git a/src/nvim/tui/termkey/driver-csi.c b/src/nvim/tui/termkey/driver-csi.c
index 3f54c874d1..9741ec72b9 100644
--- a/src/nvim/tui/termkey/driver-csi.c
+++ b/src/nvim/tui/termkey/driver-csi.c
@@ -31,11 +31,20 @@ static TermKeyResult handle_csi_ss3_full(TermKey *tk, TermKeyKey *key, int cmd,
if (nparams > 1 && params[1].param != NULL) {
int arg = 0;
- result = termkey_interpret_csi_param(params[1], &arg, NULL, NULL);
+ int subparam = 0;
+ size_t nsubparams = 1;
+ result = termkey_interpret_csi_param(params[1], &arg, &subparam, &nsubparams);
if (result != TERMKEY_RES_KEY) {
return result;
}
+ if (nsubparams > 0) {
+ key->event = parse_key_event(subparam);
+ if (key->event == TERMKEY_EVENT_UNKNOWN) {
+ return TERMKEY_RES_NONE;
+ }
+ }
+
key->modifiers = arg - 1;
} else {
key->modifiers = 0;
@@ -103,11 +112,20 @@ static TermKeyResult handle_csifunc(TermKey *tk, TermKeyKey *key, int cmd, TermK
int args[3];
if (nparams > 1 && params[1].param != NULL) {
- result = termkey_interpret_csi_param(params[1], &args[1], NULL, NULL);
+ int subparam = 0;
+ size_t nsubparams = 1;
+ result = termkey_interpret_csi_param(params[1], &args[1], &subparam, &nsubparams);
if (result != TERMKEY_RES_KEY) {
return result;
}
+ if (nsubparams > 0) {
+ key->event = parse_key_event(subparam);
+ if (key->event == TERMKEY_EVENT_UNKNOWN) {
+ return TERMKEY_RES_NONE;
+ }
+ }
+
key->modifiers = args[1] - 1;
} else {
key->modifiers = 0;
@@ -178,18 +196,8 @@ static TermKeyResult handle_csi_u(TermKey *tk, TermKeyKey *key, int cmd, TermKey
}
if (nsubparams > 0) {
- switch (subparam) {
- case 1:
- key->event = TERMKEY_EVENT_PRESS;
- break;
- case 2:
- key->event = TERMKEY_EVENT_REPEAT;
- break;
- case 3:
- key->event = TERMKEY_EVENT_RELEASE;
- break;
- default:
- // Invalid event
+ key->event = parse_key_event(subparam);
+ if (key->event == TERMKEY_EVENT_UNKNOWN) {
return TERMKEY_RES_NONE;
}
}
@@ -430,6 +438,20 @@ TermKeyResult termkey_interpret_modereport(TermKey *tk, const TermKeyKey *key, i
#define CHARAT(i) (tk->buffer[tk->buffstart + (i)])
+static TermKeyEvent parse_key_event(int n)
+{
+ switch (n) {
+ case 1:
+ return TERMKEY_EVENT_PRESS;
+ case 2:
+ return TERMKEY_EVENT_REPEAT;
+ case 3:
+ return TERMKEY_EVENT_RELEASE;
+ default:
+ return TERMKEY_EVENT_UNKNOWN;
+ }
+}
+
static TermKeyResult parse_csi(TermKey *tk, size_t introlen, size_t *csi_len,
TermKeyCsiParam params[], size_t *nargs, unsigned *commandp)
{
diff --git a/src/nvim/tui/termkey/termkey_defs.h b/src/nvim/tui/termkey/termkey_defs.h
index 09d3a5615a..87d3f63447 100644
--- a/src/nvim/tui/termkey/termkey_defs.h
+++ b/src/nvim/tui/termkey/termkey_defs.h
@@ -124,6 +124,7 @@ typedef enum {
} TermKeyMouseEvent;
typedef enum {
+ TERMKEY_EVENT_UNKNOWN,
TERMKEY_EVENT_PRESS,
TERMKEY_EVENT_REPEAT,
TERMKEY_EVENT_RELEASE,