commit - 31aa9f59f584734a946777192b4a2ba28f7fdb6c
commit + 174b3cdfa1168b20ec02e75e0161e5c802a05e85
blob - 895d05682bc4f894fe4911bee0909e6718614c07
blob + 4007f563f30d68620480edb1cc429007d24b2598
--- Makefile.am
+++ Makefile.am
ui.c \
url.c \
url.h \
+ utf8.c \
util.c \
wrap.c
blob - 2fca8a23aff5a367b4058ead948eed9814202332
blob + 319abdfb8a27f50215b9bbe4230af846808b62b9
--- telescope.h
+++ telescope.h
void ui_notify(const char*, ...) __attribute__((format(printf, 1, 2)));
void ui_end(void);
+/* utf.8 */
+char *utf8_nth(char*, size_t);
+size_t utf8_cplen(char*);
+size_t utf8_chwidth(uint32_t);
+size_t utf8_snwidth(const char*, size_t);
+size_t utf8_swidth(const char*);
+
/* util.c */
int mark_nonblock(int);
int has_prefix(const char*, const char*);
blob - 563538712e3edc8a5b57815f58ee4ec067a115c1
blob + bf812fbd3a8ba6fd7bfddf8740a956b0930cbec9
--- ui.c
+++ ui.c
if (vl == NULL || vl->line == NULL)
tab->s.curs_x = tab->s.line_x = 0;
else
- tab->s.line_x = MIN(tab->s.line_x, strlen(vl->line));
+ tab->s.curs_x = utf8_snwidth(vl->line, tab->s.line_x);
if (vl != NULL) {
prfx = line_prefixes[vl->parent->type].prfx1;
- tab->s.curs_x = tab->s.line_x + strlen(prfx);
+ tab->s.curs_x += utf8_swidth(prfx);
}
-
- wmove(body, tab->s.curs_y, tab->s.curs_x);
}
static void
vl = tab->s.current_line;
if (vl->line == NULL)
return;
- tab->s.line_x = body_cols;
+ tab->s.line_x = utf8_cplen(vl->line);
restore_cursor(tab);
}
print_vline(vl);
tab->s.current_line = TAILQ_PREV(tab->s.current_line, vhead, vlines);
+ restore_cursor(tab);
}
static void
vl = nth_line(tab, tab->s.line_off + body_lines-1);
wmove(body, body_lines-1, 0);
print_vline(vl);
+
+ restore_cursor(tab);
}
static void
redraw_modeline(tab);
redraw_minibuffer();
- restore_cursor(tab);
wrefresh(tabline);
wrefresh(modeline);
if (line == body_lines)
break;
}
+
+ wmove(body, tab->s.curs_y, tab->s.curs_x);
}
static void
blob - 341da330169c7050c05b46fbe6337da7c133f590
blob + a77cea6636e1e8fd8f3183ad8a30cb9d87518ddd
--- utf8.c
+++ utf8.c
* SOFTWARE.
*/
-#include "gmid.h"
+#include "telescope.h"
+#include <assert.h>
#include <stddef.h>
#include <stdint.h>
+#include <wchar.h>
#define UTF8_ACCEPT 0
#define UTF8_REJECT 1
};
static inline uint32_t
-utf8_decode(uint32_t* state, uint32_t* codep, uint8_t byte) {
+utf8_decode(uint32_t* restrict state, uint32_t* restrict codep, uint8_t byte) {
uint32_t type = utf8d[byte];
*codep = (*state != UTF8_ACCEPT) ?
return *state;
}
-/* for the iri parser. Modelled after printCodePoints */
-int
-valid_multibyte_utf8(struct parser *p)
-{
- uint32_t cp = 0, state = 0;
+
+/* end of the converter, utility functions ahead */
- for (; *p->iri; p->iri++)
- if (!utf8_decode(&state, &cp, *p->iri))
- break;
-
- /* reject the ASCII range */
- if (state || cp <= 0x7F) {
- /* XXX: do some error recovery? */
- if (state)
- p->err = "invalid UTF-8 character";
- return 0;
- }
- return 1;
-}
-
char *
utf8_nth(char *s, size_t n)
{
return s;
return NULL;
}
+
+size_t
+utf8_cplen(char *s)
+{
+ uint32_t cp = 0, state = 0;
+ size_t len;
+
+ len = 0;
+ for (; *s; ++s)
+ if (!utf8_decode(&state, &cp, *s))
+ len++;
+ return len;
+}
+
+/* returns only 0, 1 or 2. assumes sizeof(wchar_t) is 4 */
+size_t
+utf8_chwidth(uint32_t cp)
+{
+ /* XXX: if we're running on a platform where sizeof(wchar_t)
+ * == 2 what to do? The manpage for wcwidth and wcs isn't
+ * clear about the encoding, but if it's 16 bit wide I assume
+ * it must use UTF-16... right? */
+ assert(sizeof(wchar_t) == 4);
+
+ return wcwidth((wchar_t)cp);
+}
+
+/* NOTE: n is the number of codepoints, NOT the byte length. In
+ * other words, s MUST be NUL-terminated. */
+size_t
+utf8_snwidth(const char *s, size_t n)
+{
+ size_t i, tot;
+ uint32_t cp = 0, state = 0;
+
+ tot = 0;
+ for (i = 0; *s && i < n; ++s)
+ if (!utf8_decode(&state, &cp, *s)) {
+ i++;
+ tot += utf8_chwidth(cp);
+ }
+
+ return tot;
+}
+
+size_t
+utf8_swidth(const char *s)
+{
+ size_t tot;
+ uint32_t cp = 0, state = 0;
+
+ tot = 0;
+ for (; *s; ++s)
+ if (!utf8_decode(&state, &cp, *s))
+ tot += utf8_chwidth(cp);
+
+ return tot;
+}