Commit Diff
Diff:
ab33b604325fbc2681cc43df16dd6bc97c4699fd
bd4a08a74023593128f1f6fac9e0f4a093a8441f
Commit:
bd4a08a74023593128f1f6fac9e0f4a093a8441f
Tree:
d63ecd679638c2fd17a6f3d8edda0dcd6ec950e0
Author:
Omar Polo <op@omarpolo.com>
Date:
Mon Nov 7 18:18:53 2022 UTC
Message:
start to refactor the rendering

Previously each vline (visual line) had a full copy of its associated
string, this changes it so it only slices a part of the parent line.
Reduces significantly the memory usage.

This actually worsen the emojify-link glitch reported by Freezr after
the some recent refactoring in the wrapping code. Not a big deal since
I'm about to restructure the whole rendering bit by bit (hopefully!)
commit - ab33b604325fbc2681cc43df16dd6bc97c4699fd
commit + bd4a08a74023593128f1f6fac9e0f4a093a8441f
blob - 2854b26f492bf692171735a33230c519c4799aba
blob + b1c1869a631091efc16c273c6ad6e09c2b747f10
--- cmd.c
+++ cmd.c
@@ -110,15 +110,10 @@ cmd_forward_char(struct buffer *buffer)
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
@@ -129,7 +124,7 @@ cmd_backward_paragraph(struct buffer *buffer)
message("No previous paragraph");
return;
}
- } while (buffer->current_line->line != NULL ||
+ } while (buffer->current_line->len != 0 ||
buffer->current_line->parent->type != LINE_TEXT);
}
@@ -141,7 +136,7 @@ cmd_forward_paragraph(struct buffer *buffer)
message("No next paragraph");
return;
}
- } while (buffer->current_line->line != NULL ||
+ } while (buffer->current_line->len != 0 ||
buffer->current_line->parent->type != LINE_TEXT);
}
@@ -157,9 +152,9 @@ cmd_move_end_of_line(struct buffer *buffer)
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
@@ -707,13 +702,14 @@ cmd_mini_delete_char(struct buffer *buffer)
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);
@@ -726,17 +722,17 @@ cmd_mini_delete_backward_char(struct buffer *buffer)
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--;
@@ -747,12 +743,14 @@ cmd_mini_kill_line(struct buffer *buffer)
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);
@@ -764,7 +762,7 @@ cmd_mini_kill_whole_line(struct buffer *buffer)
GUARD_READ_ONLY();
minibuffer_taint_hist();
- *buffer->current_line->line = '\0';
+ *buffer->current_line->parent->line = '\0';
buffer->cpoff = 0;
}
@@ -817,7 +815,7 @@ cmd_mini_previous_history_element(struct buffer *buffe
}
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);
}
}
@@ -841,7 +839,7 @@ cmd_mini_next_history_element(struct buffer *buffer)
}
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
@@ -114,7 +114,9 @@ struct vline {
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
@@ -25,6 +25,7 @@ size_t utf8_chwidth(uint32_t);
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
@@ -217,7 +217,7 @@ minibuffer_taint_hist(void)
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
@@ -232,7 +232,8 @@ minibuffer_self_insert(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;
@@ -527,7 +528,7 @@ enter_minibuffer(void (*self_insert_fn)(void), void (*
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
@@ -129,6 +129,18 @@ utf8_cplen(char *s)
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
@@ -64,7 +64,6 @@ empty_vlist(struct buffer *buffer)
TAILQ_FOREACH_SAFE(vl, &buffer->head, vlines, t) {
TAILQ_REMOVE(&buffer->head, vl, vlines);
- free(vl->line);
free(vl);
}
}
@@ -89,14 +88,12 @@ push_line(struct buffer *buffer, struct line *l, const
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);
@@ -125,7 +122,7 @@ wrap_text(struct buffer *buffer, const char *prfx, str
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
@@ -60,7 +60,7 @@ static void line_prefix_and_text(struct vline *, cha
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 *);
@@ -214,13 +214,15 @@ restore_curs_x(struct buffer *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)
@@ -456,13 +458,15 @@ line_prefix_and_text(struct vline *vl, char *buf, size
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;
@@ -472,8 +476,11 @@ line_prefix_and_text(struct vline *vl, char *buf, size
*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);
@@ -491,6 +498,7 @@ line_prefix_and_text(struct vline *vl, char *buf, size
}
*prfx_ret = buf;
+ *text_len = INT_MAX;
}
static inline void
@@ -546,7 +554,7 @@ print_vline(int off, int width, WINDOW *window, struct
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];
@@ -556,7 +564,8 @@ print_vline(int off, int width, WINDOW *window, struct
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++)
@@ -568,7 +577,7 @@ print_vline(int off, int width, WINDOW *window, struct
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);
@@ -913,6 +922,7 @@ do_redraw_minibuffer(void)
struct buffer *cmplbuf, *buffer;
size_t off_y, off_x = 0;
const char *start, *c;
+ char *line;
cmplbuf = &ministate.compl.buffer;
buffer = &ministate.buffer;
@@ -935,7 +945,8 @@ do_redraw_minibuffer(void)
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);
}
Omar Polo