commit - ab33b604325fbc2681cc43df16dd6bc97c4699fd
commit + bd4a08a74023593128f1f6fac9e0f4a093a8441f
blob - 2854b26f492bf692171735a33230c519c4799aba
blob + b1c1869a631091efc16c273c6ad6e09c2b747f10
--- cmd.c
+++ cmd.c
void
cmd_forward_char(struct buffer *buffer)
{
- size_t len = 0;
-
if (buffer->current_line == NULL)
return;
-
- if (buffer->current_line->line != NULL)
- len = utf8_cplen(buffer->current_line->line);
- if (++buffer->cpoff > len)
- buffer->cpoff = len;
+ if (buffer->current_line->cplen > buffer->cpoff)
+ buffer->cpoff++;
}
void
message("No previous paragraph");
return;
}
- } while (buffer->current_line->line != NULL ||
+ } while (buffer->current_line->len != 0 ||
buffer->current_line->parent->type != LINE_TEXT);
}
message("No next paragraph");
return;
}
- } while (buffer->current_line->line != NULL ||
+ } while (buffer->current_line->len != 0 ||
buffer->current_line->parent->type != LINE_TEXT);
}
struct vline *vl;
vl = buffer->current_line;
- if (vl == NULL || vl->line == NULL)
+ if (vl == NULL)
return;
- buffer->cpoff = utf8_cplen(vl->line);
+ buffer->cpoff = vl->cplen;
}
void
void
cmd_mini_delete_char(struct buffer *buffer)
{
- char *c, *n;
+ char *line, *c, *n;
GUARD_READ_ONLY();
minibuffer_taint_hist();
- c = utf8_nth(buffer->current_line->line, buffer->cpoff);
+ line = buffer->current_line->parent->line + buffer->current_line->from;
+ c = utf8_nth(line, buffer->cpoff);
if (*c == '\0')
return;
n = utf8_next_cp(c);
void
cmd_mini_delete_backward_char(struct buffer *buffer)
{
- char *c, *p, *start;
+ char *line, *c, *p;
GUARD_READ_ONLY();
minibuffer_taint_hist();
- c = utf8_nth(buffer->current_line->line, buffer->cpoff);
- start = buffer->current_line->line;
- if (c == start)
+ line = buffer->current_line->parent->line + buffer->current_line->from;
+ c = utf8_nth(line, buffer->cpoff);
+ if (c == line)
return;
- p = utf8_prev_cp(c-1, start);
+ p = utf8_prev_cp(c-1, line);
memmove(p, c, strlen(c)+1);
buffer->cpoff--;
void
cmd_mini_kill_line(struct buffer *buffer)
{
- char *c;
+ char *line, *c;
GUARD_READ_ONLY();
minibuffer_taint_hist();
- c = utf8_nth(buffer->current_line->line, buffer->cpoff);
+
+ line = buffer->current_line->parent->line + buffer->current_line->from;
+ c = utf8_nth(line, buffer->cpoff);
*c = '\0';
recompute_completions(0);
GUARD_READ_ONLY();
minibuffer_taint_hist();
- *buffer->current_line->line = '\0';
+ *buffer->current_line->parent->line = '\0';
buffer->cpoff = 0;
}
}
if (ministate.hist_cur != NULL) {
- buffer->current_line->line = ministate.hist_cur->h;
+ buffer->current_line->parent->line = ministate.hist_cur->h;
recompute_completions(0);
}
}
}
if (ministate.hist_cur != NULL) {
- buffer->current_line->line = ministate.hist_cur->h;
+ buffer->current_line->parent->line = ministate.hist_cur->h;
recompute_completions(0);
}
}
blob - 8793d03eda3d404e665223439754a4253e93b1e3
blob + f8af6a1ebae1f826a846270292e2c6071ea7e54c
--- include/telescope.h
+++ include/telescope.h
struct vline {
struct line *parent;
- char *line;
+ size_t from;
+ size_t len;
+ size_t cplen;
int flags;
TAILQ_ENTRY(vline) vlines;
};
blob - 8f05942c15dbe9f9e528175f4043bb86791acb67
blob + 2c6273046d618fe14d98dc139adee0409a99cf42
--- include/utf8.h
+++ include/utf8.h
size_t utf8_encode(uint32_t, char*);
char *utf8_nth(char*, size_t);
size_t utf8_cplen(char*);
+size_t utf8_ncplen(const char *, size_t);
size_t utf8_chwidth(uint32_t);
size_t utf8_snwidth(const char*, size_t);
size_t utf8_swidth(const char*);
blob - a386f9e2a59d33470142e32733c51808f8ac17bc
blob + aca82a24187775201b6e0deb3994b792c18c9099
--- minibuffer.c
+++ minibuffer.c
strlcpy(ministate.buf, ministate.hist_cur->h, sizeof(ministate.buf));
ministate.hist_cur = NULL;
- ministate.buffer.current_line->line = ministate.buf;
+ ministate.buffer.current_line->parent->line = ministate.buf;
}
void
return;
len = utf8_encode(thiskey.cp, tmp);
- c = utf8_nth(ministate.buffer.current_line->line, ministate.buffer.cpoff);
+ c = utf8_nth(ministate.buffer.current_line->parent->line,
+ ministate.buffer.cpoff);
if (c + len > ministate.buf + sizeof(ministate.buf) - 1)
return;
ministate.abortfn = abortfn;
memset(ministate.buf, 0, sizeof(ministate.buf));
ministate.buffer.current_line = &ministate.vline;
- ministate.buffer.current_line->line = ministate.buf;
+ ministate.buffer.current_line->parent->line = ministate.buf;
ministate.buffer.cpoff = 0;
strlcpy(ministate.buf, "", sizeof(ministate.prompt));
blob - 8e6dd746aea8a63e569114dfec05728e7205b391
blob + 4adfaa3b7a6413ca9bb67aa3bfe386ea6e8aa9f7
--- u/utf8.c
+++ u/utf8.c
len = 0;
for (; *s; ++s)
+ if (!decode(&state, &cp, *s))
+ len++;
+ return len;
+}
+
+size_t
+utf8_ncplen(const char *s, size_t slen)
+{
+ uint32_t cp = 0, state = 0;
+ size_t len = 0;
+
+ for (; slen > 0 && *s; ++s, --slen)
if (!decode(&state, &cp, *s))
len++;
return len;
blob - ce6dcfb01915c498fe54b1eb3d6d22c4b205dca9
blob + d86351e71dc259ed782b0251ba92d069e6cc4f82
--- u/wrap.c
+++ u/wrap.c
TAILQ_FOREACH_SAFE(vl, &buffer->head, vlines, t) {
TAILQ_REMOVE(&buffer->head, vl, vlines);
- free(vl->line);
free(vl);
}
}
if ((vl = calloc(1, sizeof(*vl))) == NULL)
return 0;
- if (len != 0 && (vl->line = calloc(1, len+1)) == NULL) {
- free(vl);
- return 0;
- }
-
vl->parent = l;
- if (len != 0)
- memcpy(vl->line, buf, len);
+ if (len != 0) {
+ vl->from = buf - l->line;
+ vl->len = len;
+ vl->cplen = utf8_ncplen(buf, vl->len);
+ }
vl->flags = flags;
TAILQ_INSERT_TAIL(&buffer->head, vl, vlines);
if (l->type == LINE_LINK && emojify_link &&
emojied_line(l->line, &space)) {
- prfxwidth = utf8_swidth_between(l->line, space);
+ prfxwidth = utf8_swidth_between(l->line, space);
cur = prfxwidth;
line = space + 1;
}
blob - a7027a900ad35ef00aa79dd94069de4f2190e7fe
blob + eebb8a986913e785c7ad8f3a30e521e1a221e69a
--- ui.c
+++ ui.c
static void handle_resize_nodelay(int, short, void*);
static void handle_download_refresh(int, short, void *);
static void rearrange_windows(void);
-static void line_prefix_and_text(struct vline *, char *, size_t, const char **, const char **);
+static void line_prefix_and_text(struct vline *, char *, size_t, const char **, const char **, int *);
static void print_vline(int, int, WINDOW*, struct vline*);
static void redraw_tabline(void);
static void redraw_window(WINDOW *, int, int, int, int, struct buffer *);
const char *prfx, *text;
vl = buffer->current_line;
- if (vl == NULL || vl->line == NULL)
+ if (vl == NULL || vl->len == 0)
buffer->curs_x = buffer->cpoff = 0;
else if (vl->parent->data != NULL) {
text = vl->parent->data;
buffer->curs_x = utf8_snwidth(text + 1, buffer->cpoff) + 1;
- } else
- buffer->curs_x = utf8_snwidth(vl->line, buffer->cpoff);
+ } else {
+ text = vl->parent->line + vl->from;
+ buffer->curs_x = utf8_snwidth(text, buffer->cpoff);
+ }
/* small hack: don't olivetti-mode the download pane */
if (buffer != &downloadwin)
static void
line_prefix_and_text(struct vline *vl, char *buf, size_t len,
- const char **prfx_ret, const char **text_ret)
+ const char **prfx_ret, const char **text_ret, int *text_len)
{
int type, i, cont, width;
char *space, *t;
- if ((*text_ret = vl->line) == NULL)
+ if (vl->len == 0) {
*text_ret = "";
+ *text_len = 0;
+ }
cont = vl->flags & L_CONTINUATION;
type = vl->parent->type;
*prfx_ret = line_prefixes[type].prfx2;
space = vl->parent->data;
- if (!emojify_link || type != LINE_LINK || space == NULL)
+ if (!emojify_link || type != LINE_LINK || space == NULL) {
+ *text_ret = vl->parent->line + vl->from;
+ *text_len = MIN(INT_MAX, vl->len);
return;
+ }
if (cont) {
memset(buf, 0, len);
}
*prfx_ret = buf;
+ *text_len = INT_MAX;
}
static inline void
char emojibuf[41] = {0};
const char *text, *prfx;
struct line_face *f;
- int i, left, x, y;
+ int i, left, x, y, textlen;
f = &line_faces[vl->parent->type];
if (vl->parent->type == LINE_FRINGE && fringe_ignore_offset)
off = 0;
- line_prefix_and_text(vl, emojibuf, sizeof(emojibuf), &prfx, &text);
+ line_prefix_and_text(vl, emojibuf, sizeof(emojibuf), &prfx,
+ &text, &textlen);
wattr_on(window, body_face.left, NULL);
for (i = 0; i < off; i++)
wattr_off(window, f->prefix, NULL);
wattr_on(window, f->text, NULL);
- wprintw(window, "%s", text);
+ wprintw(window, "%.*s", textlen, text);
print_vline_descr(width, window, vl);
wattr_off(window, f->text, NULL);
struct buffer *cmplbuf, *buffer;
size_t off_y, off_x = 0;
const char *start, *c;
+ char *line;
cmplbuf = &ministate.compl.buffer;
buffer = &ministate.buffer;
start = ministate.hist_cur != NULL
? ministate.hist_cur->h
: ministate.buf;
- c = utf8_nth(buffer->current_line->line, buffer->cpoff);
+ line = buffer->current_line->parent->line + buffer->current_line->from;
+ c = utf8_nth(line, buffer->cpoff);
while (utf8_swidth_between(start, c) > (size_t)COLS/2) {
start = utf8_next_cp(start);
}