aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/tui/termkey
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/tui/termkey')
-rw-r--r--src/nvim/tui/termkey/driver-csi.c57
-rw-r--r--src/nvim/tui/termkey/driver-csi.h2
-rw-r--r--src/nvim/tui/termkey/driver-ti.c6
-rw-r--r--src/nvim/tui/termkey/driver-ti.h2
-rw-r--r--src/nvim/tui/termkey/termkey-internal.h2
-rw-r--r--src/nvim/tui/termkey/termkey.c55
-rw-r--r--src/nvim/tui/termkey/termkey.h6
-rw-r--r--src/nvim/tui/termkey/termkey_defs.h9
8 files changed, 82 insertions, 57 deletions
diff --git a/src/nvim/tui/termkey/driver-csi.c b/src/nvim/tui/termkey/driver-csi.c
index 28c7eaccfd..d427be50ff 100644
--- a/src/nvim/tui/termkey/driver-csi.c
+++ b/src/nvim/tui/termkey/driver-csi.c
@@ -1,11 +1,10 @@
#include <assert.h>
-#include <stdio.h>
+#include <stdint.h>
#include <string.h>
#include "nvim/memory.h"
#include "nvim/tui/termkey/driver-csi.h"
#include "nvim/tui/termkey/termkey-internal.h"
-#include "nvim/tui/termkey/termkey.h"
#include "nvim/tui/termkey/termkey_defs.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -32,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;
@@ -104,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,9 +195,11 @@ static TermKeyResult handle_csi_u(TermKey *tk, TermKeyKey *key, int cmd, TermKey
return TERMKEY_RES_ERROR;
}
- if (nsubparams > 0 && subparam != 1) {
- // Not a press event. Ignore for now
- return TERMKEY_RES_NONE;
+ if (nsubparams > 0) {
+ key->event = parse_key_event(subparam);
+ if (key->event == TERMKEY_EVENT_UNKNOWN) {
+ return TERMKEY_RES_NONE;
+ }
}
key->modifiers = args[1] - 1;
@@ -308,6 +327,12 @@ TermKeyResult termkey_interpret_mouse(TermKey *tk, const TermKeyKey *key, TermKe
btn = code + 4 - 64;
break;
+ case 128:
+ case 129:
+ *event = drag ? TERMKEY_MOUSE_DRAG : TERMKEY_MOUSE_PRESS;
+ btn = code + 8 - 128;
+ break;
+
default:
*event = TERMKEY_MOUSE_UNKNOWN;
}
@@ -419,6 +444,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)
{
@@ -529,7 +568,7 @@ TermKeyResult termkey_interpret_csi_param(TermKeyCsiParam param, int *paramp, in
if (c == ':') {
if (length == 0) {
*paramp = arg;
- } else {
+ } else if (subparams != NULL) {
subparams[length - 1] = arg;
}
@@ -544,7 +583,7 @@ TermKeyResult termkey_interpret_csi_param(TermKeyCsiParam param, int *paramp, in
if (length == 0) {
*paramp = arg;
- } else {
+ } else if (subparams != NULL) {
subparams[length - 1] = arg;
}
diff --git a/src/nvim/tui/termkey/driver-csi.h b/src/nvim/tui/termkey/driver-csi.h
index 0abd8b5c2e..644cc9d58b 100644
--- a/src/nvim/tui/termkey/driver-csi.h
+++ b/src/nvim/tui/termkey/driver-csi.h
@@ -1,6 +1,6 @@
#pragma once
-#include "nvim/tui/termkey/termkey_defs.h"
+#include "nvim/tui/termkey/termkey_defs.h" // IWYU pragma: keep
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "tui/termkey/driver-csi.h.generated.h"
diff --git a/src/nvim/tui/termkey/driver-ti.c b/src/nvim/tui/termkey/driver-ti.c
index 745ee9902f..e402f93e93 100644
--- a/src/nvim/tui/termkey/driver-ti.c
+++ b/src/nvim/tui/termkey/driver-ti.c
@@ -1,16 +1,16 @@
-#include <ctype.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
-#include <sys/types.h>
#include <unibilium.h>
+#include <uv.h>
#include "nvim/memory.h"
#include "nvim/tui/termkey/driver-ti.h"
#include "nvim/tui/termkey/termkey-internal.h"
-#include "nvim/tui/termkey/termkey.h"
+#include "nvim/tui/termkey/termkey_defs.h"
#ifndef _WIN32
# include <unistd.h>
diff --git a/src/nvim/tui/termkey/driver-ti.h b/src/nvim/tui/termkey/driver-ti.h
index df9bd72d5b..6dbcb11344 100644
--- a/src/nvim/tui/termkey/driver-ti.h
+++ b/src/nvim/tui/termkey/driver-ti.h
@@ -1,6 +1,6 @@
#pragma once
-#include "nvim/tui/termkey/termkey_defs.h"
+#include "nvim/tui/termkey/termkey_defs.h" // IWYU pragma: keep
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "tui/termkey/driver-ti.h.generated.h"
diff --git a/src/nvim/tui/termkey/termkey-internal.h b/src/nvim/tui/termkey/termkey-internal.h
index 107591f950..97fae939c5 100644
--- a/src/nvim/tui/termkey/termkey-internal.h
+++ b/src/nvim/tui/termkey/termkey-internal.h
@@ -47,7 +47,7 @@ struct TermKey {
int canonflags;
unsigned char *buffer;
size_t buffstart; // First offset in buffer
- size_t buffcount; // NUMBER of entires valid in buffer
+ size_t buffcount; // NUMBER of entries valid in buffer
size_t buffsize; // Total malloc'ed size
size_t hightide; // Position beyond buffstart at which peekkey() should next start
// normally 0, but see also termkey_interpret_csi
diff --git a/src/nvim/tui/termkey/termkey.c b/src/nvim/tui/termkey/termkey.c
index e6440118f3..eabde2f9f7 100644
--- a/src/nvim/tui/termkey/termkey.c
+++ b/src/nvim/tui/termkey/termkey.c
@@ -1,9 +1,9 @@
#include <ctype.h>
#include <errno.h>
-#include <stdbool.h>
#include <stdio.h>
#include <string.h>
+#include "nvim/macros_defs.h"
#include "nvim/mbyte.h"
#include "nvim/memory.h"
#include "nvim/tui/termkey/driver-csi.h"
@@ -13,9 +13,10 @@
#include "nvim/tui/termkey/termkey_defs.h"
#ifndef _WIN32
-# include <poll.h>
-# include <strings.h>
-# include <unistd.h>
+// Include these directly instead of <termios.h> which is system-dependent. #31704
+# include <poll.h> // IWYU pragma: keep
+# include <strings.h> // IWYU pragma: keep
+# include <unistd.h> // IWYU pragma: keep
#else
# include <io.h>
#endif
@@ -633,40 +634,13 @@ static void eat_bytes(TermKey *tk, size_t count)
tk->buffcount -= count;
}
-// TODO(dundargoc): we should be able to replace this with utf_char2bytes from mbyte.c
int fill_utf8(int codepoint, char *str)
{
- int nbytes = utf_char2len(codepoint);
-
+ int nbytes = utf_char2bytes(codepoint, str);
str[nbytes] = 0;
-
- // This is easier done backwards
- int b = nbytes;
- while (b > 1) {
- b--;
- str[b] = (char)0x80 | (codepoint & 0x3f);
- codepoint >>= 6;
- }
-
- switch (nbytes) {
- case 1:
- str[0] = (codepoint & 0x7f); break;
- case 2:
- str[0] = (char)0xc0 | (codepoint & 0x1f); break;
- case 3:
- str[0] = (char)0xe0 | (codepoint & 0x0f); break;
- case 4:
- str[0] = (char)0xf0 | (codepoint & 0x07); break;
- case 5:
- str[0] = (char)0xf8 | (codepoint & 0x03); break;
- case 6:
- str[0] = (char)0xfc | (codepoint & 0x01); break;
- }
-
return nbytes;
}
-#define UTF8_INVALID 0xFFFD
static TermKeyResult parse_utf8(const unsigned char *bytes, size_t len, int *cp, size_t *nbytep)
{
unsigned nbytes;
@@ -680,7 +654,7 @@ static TermKeyResult parse_utf8(const unsigned char *bytes, size_t len, int *cp,
return TERMKEY_RES_KEY;
} else if (b0 < 0xc0) {
// Starts with a continuation byte - that's not right
- *cp = UTF8_INVALID;
+ *cp = UNICODE_INVALID;
*nbytep = 1;
return TERMKEY_RES_KEY;
} else if (b0 < 0xe0) {
@@ -699,7 +673,7 @@ static TermKeyResult parse_utf8(const unsigned char *bytes, size_t len, int *cp,
nbytes = 6;
*cp = b0 & 0x01;
} else {
- *cp = UTF8_INVALID;
+ *cp = UNICODE_INVALID;
*nbytep = 1;
return TERMKEY_RES_KEY;
}
@@ -713,7 +687,7 @@ static TermKeyResult parse_utf8(const unsigned char *bytes, size_t len, int *cp,
cb = bytes[b];
if (cb < 0x80 || cb >= 0xc0) {
- *cp = UTF8_INVALID;
+ *cp = UNICODE_INVALID;
*nbytep = b;
return TERMKEY_RES_KEY;
}
@@ -724,14 +698,14 @@ static TermKeyResult parse_utf8(const unsigned char *bytes, size_t len, int *cp,
// Check for overlong sequences
if ((int)nbytes > utf_char2len(*cp)) {
- *cp = UTF8_INVALID;
+ *cp = UNICODE_INVALID;
}
// Check for UTF-16 surrogates or invalid *cps
if ((*cp >= 0xD800 && *cp <= 0xDFFF)
|| *cp == 0xFFFE
|| *cp == 0xFFFF) {
- *cp = UTF8_INVALID;
+ *cp = UNICODE_INVALID;
}
*nbytep = nbytes;
@@ -833,6 +807,9 @@ static TermKeyResult peekkey(TermKey *tk, TermKeyKey *key, int force, size_t *nb
return TERMKEY_RES_ERROR;
}
+ // Press is the default event type.
+ key->event = TERMKEY_EVENT_PRESS;
+
#ifdef DEBUG
fprintf(stderr, "getkey(force=%d): buffer ", force);
print_buffer(tk);
@@ -958,9 +935,9 @@ static TermKeyResult peekkey_simple(TermKey *tk, TermKeyKey *key, int force, siz
if (res == TERMKEY_RES_AGAIN && force) {
// There weren't enough bytes for a complete UTF-8 sequence but caller
// demands an answer. About the best thing we can do here is eat as many
- // bytes as we have, and emit a UTF8_INVALID. If the remaining bytes
+ // bytes as we have, and emit a UNICODE_INVALID. If the remaining bytes
// arrive later, they'll be invalid too.
- codepoint = UTF8_INVALID;
+ codepoint = UNICODE_INVALID;
*nbytep = tk->buffcount;
res = TERMKEY_RES_KEY;
}
diff --git a/src/nvim/tui/termkey/termkey.h b/src/nvim/tui/termkey/termkey.h
index 21ed141346..5cf9894cac 100644
--- a/src/nvim/tui/termkey/termkey.h
+++ b/src/nvim/tui/termkey/termkey.h
@@ -1,9 +1,9 @@
#pragma once
-#include <stdint.h>
-#include <stdlib.h>
+#include <stdint.h> // IWYU pragma: keep
+#include <stdlib.h> // IWYU pragma: keep
-#include "nvim/tui/termkey/termkey_defs.h"
+#include "nvim/tui/termkey/termkey_defs.h" // IWYU pragma: keep
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "tui/termkey/termkey.h.generated.h"
diff --git a/src/nvim/tui/termkey/termkey_defs.h b/src/nvim/tui/termkey/termkey_defs.h
index 7c218ba7c2..87d3f63447 100644
--- a/src/nvim/tui/termkey/termkey_defs.h
+++ b/src/nvim/tui/termkey/termkey_defs.h
@@ -123,6 +123,13 @@ typedef enum {
TERMKEY_MOUSE_RELEASE,
} TermKeyMouseEvent;
+typedef enum {
+ TERMKEY_EVENT_UNKNOWN,
+ TERMKEY_EVENT_PRESS,
+ TERMKEY_EVENT_REPEAT,
+ TERMKEY_EVENT_RELEASE,
+} TermKeyEvent;
+
enum {
TERMKEY_KEYMOD_SHIFT = 1 << 0,
TERMKEY_KEYMOD_ALT = 1 << 1,
@@ -163,6 +170,8 @@ typedef struct {
int modifiers;
+ TermKeyEvent event;
+
// Any Unicode character can be UTF-8 encoded in no more than 6 bytes, plus
// terminating NUL
char utf8[7];