diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 163 |
1 files changed, 155 insertions, 8 deletions
@@ -1,27 +1,174 @@ #include <stdio.h> #include <stdint.h> #include <stddef.h> +#include <ctype.h> +#include <err.h> #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> #define ARENA_IMPL +#define UTF8_IMPL #include "wrmr.h" #include "arena.h" #include "txt.h" +#include "vui.h" +#include "utf8.h" -int main(void) { - Arena a = arena_init(1L << 20); - Txt txt = { 0 }; - txt_open(&txt, "test.txt"); - txt_insert(&txt, txt.len, "wheeee", 6); - txt_delete(&txt, txt.len, 6); +Arena scratch = { 0 }; +Txt txt = { 0 }; +u32 cur = 0; + +int is_space(u32 c) { + return c <= 0x20 && c != 0; +} + +u32 move_word_back(Txt *t, u32 cur) { + TxtLoc l = txt_at(t, cur); + while (!txt_at_start(t,l)) { + TxtLoc n = txt_prev(t, l); + if (!is_space(txt_chr(t, n))) break; + l = n; + } + while (!txt_at_start(t,l)) { + TxtLoc n = txt_prev(t, l); + if (is_space(txt_chr(t, n))) break; + l = n; + } + return txt_ofs(t, l); +} + +u32 move_word_fwd(Txt *t, u32 cur) { + TxtLoc l = txt_at(t, cur); + while (!txt_at_end(t,l) && is_space(txt_chr(t, l))) l = txt_next(t, l); + while (!txt_at_end(t,l) && !is_space(txt_chr(t, l))) l = txt_next(t, l); + return txt_ofs(t, l); +} + +u32 move_char_back(Txt *t, u32 cur) { + while (cur > 0) { + cur--; + u8 c = txt_byte(t, txt_at(t, cur)); + if ((c & 0xc0) != 0x80) break; + } + return cur; +} + +u32 move_char_fwd(Txt *t, u32 cur) { + u8 b = txt_byte(t, txt_at(t, cur)); + u32 n = stdc_leading_ones(b); + if (cur + n >= t->len) return t->len; + return cur + n + !n; +} + +u32 del_between(Txt *t, u32 a, u32 b) { + if (b < a) { u32 t = a; a = b; b = t; } + //if (b - a > 10) TRAP(); + return txt_delete(t, b, b - a); +} + +/* main */ + +#define ODD_ATTR (FG_CYAN | BG_BLACK) +#define EVEN_ATTR (FG_WHITE | BG_BLACK) + +void draw(void *ctx) { + (void)ctx; +redraw:; + vui_clear(); + static int max_y = 0; + int x = 0, y = 0; + u32 ofs = 0; for (u32 i = 0; i < txt.ptbl.n; i++) { + Arena stk = scratch; TxtPiece *p = &txt.ptbl.v[i]; - printf("%u. %.*s\n", i, (int)p->n, txt.buf[p->buf].s + p->ofs); + const char *s = txt.buf[p->buf].s + p->ofs; + + u32 bufn = utf8_decode_len(s, p->n); + u32 *buf = new_arr(&scratch, u32, bufn); + utf8_decode(buf, s, bufn); + + VuiAttr a = i&1 ? ODD_ATTR : EVEN_ATTR; + vui_aprintf(-1, i, a, "%u, %u (%s)", p->ofs, p->n, p->buf == TXT_ADD ? "add" : "src"); + + for (u32 j = 0; j < bufn; j++) { + u32 c = buf[j]; + if (ofs == cur) vui_curs_pos(x, y - (max_y - LINES + 1)); + if (c != '\r' && c != '\n') { + vui_chra(x++, y - (max_y - LINES + 1), c, a); + } + if (c == '\n') { + x = 0; + y++; + } + ofs += UTF8_CP_LEN(c); + } + scratch = stk; + } + if (ofs == cur) vui_curs_pos(x, y - (max_y - LINES + 1)); + if (y > max_y) { + max_y = y; + goto redraw; + } + TxtLoc l = txt_at(&txt, cur); + u32 c = txt_chr(&txt, l); + vui_printf(-1, -1, "%u, %u - %02x (%c)", l.p, l.i, c, (c < 0x20 || c > 0x7e) ? ' ' : c); + u32 used = scratch.beg - scratch.start, max = scratch.end - scratch.start; + vui_printf(-1, -2, "scratch %.02f/%.02fk", used/1024.0, max/1024.0); +} + +int main(void) { + scratch = arena_init(1L << 20); + vui_init(); + vui_curs_vis(1); + vui_redraw_fn(draw); + if (txt_load(&txt, "test.txt")) err(1, "couldn't open file"); + cur = txt.len; + for (;;) { + scratch.beg = scratch.start; + draw(NULL); + vui_blit(); + u32 c = vui_key(); + switch (c) { + case KEY_ESC: + goto brk; + case KEY_BKSP: + cur = txt_delete_c(&txt, cur); + break; + case KEY_LEFT: + cur = move_char_back(&txt, cur); + break; + case KEY_LEFT | KEY_CTRL_BIT: + cur = move_word_back(&txt, cur); + break; + case KEY_RIGHT: + cur = move_char_fwd(&txt, cur); + break; + case KEY_RIGHT | KEY_CTRL_BIT: + cur = move_word_fwd(&txt, cur); + break; + case 0x17 /* ^W */: + cur = del_between(&txt, move_word_back(&txt, cur), cur); + break; + case 0x05 /* ^E */: + cur = del_between(&txt, cur, move_word_fwd(&txt, cur)); + break; + case 0x13 /* ^S */: + txt_save(&txt, "test.txt"); + txt_load(&txt, "test.txt"); + break; + case '\r': + cur = txt_insert_c(&txt, cur, '\n'); + break; + default: + if (c >= ' ' && c <= KEY_UTF8_MAX) cur = txt_insert_c(&txt, cur, c); + break; + } } - arena_free(&a); +brk: + vui_fini(); + arena_free(&scratch); return 0; } |
