commit - 174b3cdfa1168b20ec02e75e0161e5c802a05e85
commit + 8947c1f29122ab2e506b2bb723a4fc92bd9d3a59
blob - 319abdfb8a27f50215b9bbe4230af846808b62b9
blob + 404312ec0aba8b3eca9ca668466fb8ffe6e5b933
--- telescope.h
+++ telescope.h
void ui_end(void);
/* utf.8 */
+uint32_t utf8_decode(uint32_t*restrict, uint32_t*restrict, uint8_t);
+void utf8_encode(uint32_t, char*);
char *utf8_nth(char*, size_t);
size_t utf8_cplen(char*);
size_t utf8_chwidth(uint32_t);
blob - bf812fbd3a8ba6fd7bfddf8740a956b0930cbec9
blob + ac2a27eb58345f3820fc77fe3e629e65c662714e
--- ui.c
+++ ui.c
static struct vline *nth_line(struct tab*, size_t);
static struct tab *current_tab(void);
+static int readkey(void);
static void dispatch_stdio(int, short, void*);
static void handle_clear_minibuf(int, short, void*);
static void handle_resize(int, short, void*);
static struct tab *new_tab(const char*);
static void usage(void);
-static struct { int meta, key; } thiskey;
+static struct { short meta; int key; uint32_t cp; } thiskey;
static WINDOW *tabline, *body, *modeline, *minibuf;
static int body_lines, body_cols;
abort();
}
-static void
-dispatch_stdio(int fd, short ev, void *d)
+static int
+readkey(void)
{
- struct keymap *k;
- const char *keyname;
- char tmp[2] = {0};
+ uint32_t state = 0;
- thiskey.key = wgetch(body);
- if (thiskey.key == ERR)
- return;
- if (thiskey.key == 27) {
- /* TODO: make escape-time customizable */
+ if ((thiskey.key = wgetch(body)) == ERR)
+ return 0;
- thiskey.meta = 1;
+ thiskey.meta = thiskey.key == 27;
+ if (thiskey.meta) {
thiskey.key = wgetch(body);
if (thiskey.key == ERR || thiskey.key == 27) {
thiskey.meta = 0;
thiskey.key = 27;
}
- } else
- thiskey.meta = 0;
+ }
+
+ thiskey.cp = 0;
+ if ((unsigned int)thiskey.key < UINT8_MAX) {
+ while (1) {
+ if (!utf8_decode(&state, &thiskey.cp, (uint8_t)thiskey.key))
+ break;
+ if ((thiskey.key = wgetch(body)) == ERR) {
+ message("Error decoding user input");
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+static void
+dispatch_stdio(int fd, short ev, void *d)
+{
+ struct keymap *k;
+ const char *keyname;
+ char tmp[5] = {0};
+
+ if (!readkey())
+ return;
+
if (keybuf[0] != '\0')
strlcat(keybuf, " ", sizeof(keybuf));
if (thiskey.meta)
strlcat(keybuf, "M-", sizeof(keybuf));
- if ((keyname = unkbd(thiskey.key)) != NULL)
- strlcat(keybuf, keyname, sizeof(keybuf));
- else {
- tmp[0] = thiskey.key;
+ if (thiskey.cp != 0) {
+ utf8_encode(thiskey.cp, tmp);
strlcat(keybuf, tmp, sizeof(keybuf));
+ } else {
+ if ((keyname = unkbd(thiskey.key)) != NULL)
+ strlcat(keybuf, keyname, sizeof(keybuf));
+ else {
+ tmp[0] = thiskey.key;
+ strlcat(keybuf, tmp, sizeof(keybuf));
+ }
}
TAILQ_FOREACH(k, ¤t_map->m, keymaps) {
blob - a77cea6636e1e8fd8f3183ad8a30cb9d87518ddd
blob + 127fbb5153f75ff8a6135564ac27df0b9d7ae17c
--- utf8.c
+++ utf8.c
1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
};
-static inline uint32_t
+uint32_t
utf8_decode(uint32_t* restrict state, uint32_t* restrict codep, uint8_t byte) {
uint32_t type = utf8d[byte];
/* end of the converter, utility functions ahead */
+/* encode cp in s. s must be at least 4 bytes wide */
+void
+utf8_encode(uint32_t cp, char *s)
+{
+ if (cp <= 0x7F) {
+ *s = (uint8_t)cp;
+ } else if (cp <= 0x7FF) {
+ s[1] = (uint8_t)(( cp & 0x3F ) + 0x80);
+ s[0] = (uint8_t)(((cp >> 6) & 0x1F) + 0xC0);
+ } else if (cp <= 0xFFFF) {
+ s[2] = (uint8_t)(( cp & 0x3F) + 0x80);
+ s[1] = (uint8_t)(((cp >> 6) & 0x3F) + 0x80);
+ s[0] = (uint8_t)(((cp >> 12) & 0x0F) + 0xE0);
+ } else if (cp <= 0x10FFFF) {
+ s[3] = (uint8_t)(( cp & 0x3F) + 0x80);
+ s[2] = (uint8_t)(((cp >> 6) & 0x3F) + 0x80);
+ s[1] = (uint8_t)(((cp >> 12) & 0x3F) + 0x80);
+ s[0] = (uint8_t)(((cp >> 18) & 0x07) + 0xF0);
+ } else
+ s[0] = '\0';
+}
+
char *
utf8_nth(char *s, size_t n)
{