commit - db6fcbbe651bdf690df980ff1a4f73310b33dd87
commit + d5e0ee089932fa61ce56746c09c77019353d5614
blob - f037f5f80862c31a7ab21a42c9eb786c04e10776
blob + 5273190b7424f14ff5247c661d582ab711dfa994
--- configure.ac
+++ configure.ac
AC_MSG_ERROR([requires libtls])
])
+AC_CHECK_LIB(grapheme, grapheme_next_line_break_utf8, [], [
+ AC_MSG_ERROR([requires libgrapheme])
+])
+
case "$host_os" in
*openbsd*)
AC_CHECK_LIB([event], [event_init], [],
blob - 1c7a101b1280b8e8775b23e98b543b0df4b4cb88
blob + fcffadb7e89a7c3f8800eee0aacb3e232a4c4be0
--- include/telescope.h
+++ include/telescope.h
void empty_vlist(struct buffer*);
int wrap_one(struct buffer *, const char *, struct line *, size_t);
int wrap_text(struct buffer*, const char*, struct line*, size_t);
-int hardwrap_text(struct buffer*, struct line*, size_t);
int wrap_page(struct buffer *, int width);
#endif /* TELESCOPE_H */
blob - 338068315003a7f604337fc0f6c91a4b98a7739e
blob + 7c359d32f7211243d1f277da709a91db6df22fde
--- u/wrap.c
+++ u/wrap.c
#include "compat.h"
#include <ctype.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <grapheme.h>
+
#include "defaults.h"
#include "telescope.h"
#include "utf8.h"
-/*
- * Text wrapping
- * =============
- *
- * There's a simple text wrapping algorithm.
- *
- * 1. if it's a line in a pre-formatted block:
- * a. hard wrap.
- * b. repeat
- * 2. otherwise advance the line char by char.
- * 3. when ending the space, split the line at the last occurrence of
- * a "word separator" (i.e. " \t-") or at point if none.
- * 4. repeat
- *
- */
-
void
erase_buffer(struct buffer *buffer)
{
int
wrap_text(struct buffer *buffer, const char *prfx, struct line *l, size_t width)
{
- const char *separators = " \t-";
- const char *start, *end, *line, *lastsep, *lastchar, *space;
- uint32_t cp = 0, state = 0;
- size_t cur, prfxwidth, w;
+ const char *line, *space;
+ size_t ret, off, start, cur, prfxwidth;
int flags;
- if ((line = l->line) == NULL)
+ if ((line = l->line) == NULL || *line == '\0')
return push_line(buffer, l, NULL, 0, 0);
prfxwidth = utf8_swidth(prfx);
cur = prfxwidth;
- start = line;
- lastsep = NULL;
- lastchar = line;
+ start = 0;
flags = 0;
if (l->type == LINE_LINK && emojify_link &&
line = space + 1;
}
- for (; *line; line++) {
- if (utf8_decode(&state, &cp, *line))
- continue;
- w = utf8_chwidth(cp);
- if (cur + w > width) {
- end = lastsep == NULL
- ? utf8_next_cp((char*)lastchar)
- : utf8_next_cp((char*)lastsep);
- if (!push_line(buffer, l, start, end - start, flags))
- return 0;
- flags = L_CONTINUATION;
- start = end;
- cur = prfxwidth + utf8_swidth_between(start, lastchar);
- } else if (strchr(separators, *line) != NULL) {
- lastsep = line;
- }
-
- lastchar = utf8_prev_cp(line, l->line);
- cur += w;
- }
+ for (off = 0; line[off] != '\0'; off += ret) {
+ size_t t;
- return push_line(buffer, l, start, line - start, flags);
-}
+ ret = grapheme_next_line_break_utf8(&line[off], SIZE_MAX);
+ t = utf8_swidth_between(&line[off], &line[off + ret]);
-int
-hardwrap_text(struct buffer *buffer, struct line *l, size_t width)
-{
- const char *line, *start, *lastchar;
- int cont;
- uint32_t state = 0, cp = 0;
- size_t cur, w;
-
- if ((line = l->line) == NULL)
- return push_line(buffer, l, NULL, 0, 0);
-
- start = line;
- lastchar = line;
- cont = 0;
- cur = 0;
- for (; *line; line++) {
- if (utf8_decode(&state, &cp, *line))
+ if (cur + t <= width) {
+ cur += t;
continue;
- w = utf8_chwidth(cp);
- if (cur + w > width) {
- if (!push_line(buffer, l, start, lastchar-start, cont))
- return 0;
- cont = L_CONTINUATION;
- if (dont_wrap_pre)
- return 1;
- cur = 0;
- start = lastchar;
}
- lastchar = utf8_prev_cp(line, l->line);
- cur += w;
+ if (!push_line(buffer, l, &line[start], off - start, flags))
+ return 0;
+
+ flags = L_CONTINUATION;
+ start = off;
+ cur = t;
}
- return push_line(buffer, l, start, line - start, cont);
+ if (off != start)
+ return push_line(buffer, l, &line[start], off - start, flags);
+ return 0;
}
int
case LINE_QUOTE:
case LINE_PRE_START:
case LINE_PRE_END:
- wrap_text(buffer, prfx, l, MIN(fill_column, width));
- break;
case LINE_PRE_CONTENT:
case LINE_PATCH:
case LINE_PATCH_HDR:
case LINE_PATCH_HUNK_HDR:
case LINE_PATCH_ADD:
case LINE_PATCH_DEL:
- hardwrap_text(buffer, l, MIN(fill_column, width));
+ wrap_text(buffer, prfx, l, MIN(fill_column, width));
break;
case LINE_COMPL:
case LINE_COMPL_CURRENT: