Commit Diff


commit - 174b3cdfa1168b20ec02e75e0161e5c802a05e85
commit + 8947c1f29122ab2e506b2bb723a4fc92bd9d3a59
blob - 319abdfb8a27f50215b9bbe4230af846808b62b9
blob + 404312ec0aba8b3eca9ca668466fb8ffe6e5b933
--- telescope.h
+++ telescope.h
@@ -255,6 +255,8 @@ void		 ui_notify(const char*, ...) __attribute__((form
 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
@@ -117,6 +117,7 @@ static void		 bp_select(void);
 
 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*);
@@ -139,7 +140,7 @@ static void		 switch_to_tab(struct tab*);
 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;
@@ -1079,37 +1080,62 @@ current_tab(void)
 	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, &current_map->m, keymaps) {
blob - a77cea6636e1e8fd8f3183ad8a30cb9d87518ddd
blob + 127fbb5153f75ff8a6135564ac27df0b9d7ae17c
--- utf8.c
+++ utf8.c
@@ -48,7 +48,7 @@ static const uint8_t utf8d[] = {
 	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];
 
@@ -63,6 +63,28 @@ utf8_decode(uint32_t* restrict state, uint32_t* restri
 
 /* 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)
 {