vtgl

terminal emulator implemented in OpenGL
git clone anongit@rnpnr.xyz:vtgl.git
Log | Files | Refs | Feed | LICENSE

Commit: 11430fa3a841a123d3b8369a119971d58902b454
Parent: 806951a9deed6716eec91a919d01e70aafb84b8e
Author: Randy Palamar
Date:   Wed,  6 Nov 2024 08:10:16 -0700

use a Stream for selection copying

Diffstat:
Mvtgl.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; }