Commit: 11430fa3a841a123d3b8369a119971d58902b454
Parent: 806951a9deed6716eec91a919d01e70aafb84b8e
Author: Randy Palamar
Date: Wed, 6 Nov 2024 08:10:16 -0700
use a Stream for selection copying
Diffstat:
M | vtgl.c | | | 89 | ++++++++++++++++++++++++++++++++++++++----------------------------------------- |
1 file changed, 43 insertions(+), 46 deletions(-)
diff --git a/vtgl.c b/vtgl.c
@@ -455,6 +455,44 @@ mouse_to_cell_space(Term *t, v2 mouse)
}
static void
+stream_push_selection(Stream *s, TermView *tv, Range sel, u32 term_width)
+{
+ iv2 curs = sel.start;
+ iv2 end = sel.end;
+
+ s->errors |= !is_valid_range(sel);
+ if (s->errors) return;
+
+ /* NOTE: do full rows first */
+ u32 last_non_space_idx = 0;
+ for (; curs.y < end.y; curs.y++) {
+ for (; curs.x < term_width; curs.x++) {
+ Cell c = tv->fb.rows[curs.y][curs.x];
+ if (c.bg & ATTR_WDUMMY)
+ continue;
+ stream_push_s8(s, utf8_encode(c.cp));
+ if (!ISSPACE(c.cp))
+ last_non_space_idx = s->widx;
+ }
+ s->widx = last_non_space_idx;
+ stream_push_byte(s, '\n');
+ curs.x = 0;
+ }
+
+ /* NOTE: do the last row */
+ for (; curs.x <= end.x; curs.x++) {
+ Cell c = tv->fb.rows[curs.y][curs.x];
+ if (c.bg & ATTR_WDUMMY)
+ continue;
+ stream_push_s8(s, utf8_encode(c.cp));
+ if (!ISSPACE(c.cp))
+ last_non_space_idx = s->widx;
+ }
+ s->widx = last_non_space_idx;
+ stream_push_byte(s, '\n');
+}
+
+static void
update_selection(Term *t)
{
Selection *sel = &t->selection;
@@ -511,53 +549,12 @@ update_selection(Term *t)
KEYBIND_FN(copy)
{
- if (!is_valid_range(t->selection.range))
- return 1;
-
- TermView *tv = t->views + t->view_idx;
- Range sel = t->selection.range;
- iv2 curs = sel.start;
- iv2 end = sel.end;
- i32 buf_curs = 0;
-
- /* NOTE: super piggy but we are only holding onto it for the function duration */
- Arena arena = t->arena_for_frame;
- size buf_size = 1 * MEGABYTE;
- char *buf = alloc(&arena, char, buf_size);
-
- /* NOTE: do full rows first */
- u32 last_non_space_idx = 0;
- for (; curs.y < end.y; curs.y++) {
- for (; curs.x < t->size.w && buf_curs != buf_size; curs.x++) {
- Cell c = tv->fb.rows[curs.y][curs.x];
- if (c.bg & ATTR_WDUMMY)
- continue;
- s8 enc = utf8_encode(c.cp);
- for (size i = 0; i < enc.len && buf_curs != buf_size; i++)
- buf[buf_curs++] = enc.data[i];
- if (!ISSPACE(c.cp))
- last_non_space_idx = buf_curs;
- }
- buf[last_non_space_idx + 1] = '\n';
- buf_curs = last_non_space_idx + 2;
- curs.x = 0;
- }
-
- /* NOTE: do the last row */
- for (; curs.x <= end.x && buf_curs != buf_size; curs.x++) {
- Cell c = tv->fb.rows[curs.y][curs.x];
- if (c.bg & ATTR_WDUMMY)
- continue;
- s8 enc = utf8_encode(c.cp);
- for (size i = 0; i < enc.len && buf_curs != buf_size; i++)
- buf[buf_curs++] = enc.data[i];
- if (!ISSPACE(c.cp))
- last_non_space_idx = buf_curs;
- }
+ Stream buf = arena_stream(t->arena_for_frame);
+ stream_push_selection(&buf, t->views + t->view_idx, t->selection.range, t->size.w);
+ stream_push_byte(&buf, 0);
- CLAMP(buf_curs, 0, buf_size - 1);
- buf[buf_curs] = 0;
- glfwSetClipboardString(0, buf);
+ if (!buf.errors)
+ glfwSetClipboardString(0, (c8 *)buf.buf);
return 1;
}