summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorWormHeamer2025-12-28 04:19:59 -0500
committerWormHeamer2025-12-28 04:19:59 -0500
commit615601fb355709d611d18f878f77c993c312f6aa (patch)
tree5fb32e00c201944f9c77308da1ab9bee443bdf7c /main.c
parent9f4310c24ca39284ad768a82d368e749b18fd76c (diff)
lots of features & bugfixes both
Diffstat (limited to 'main.c')
-rw-r--r--main.c179
1 files changed, 145 insertions, 34 deletions
diff --git a/main.c b/main.c
index 3862625..3f171ad 100644
--- a/main.c
+++ b/main.c
@@ -69,62 +69,149 @@ u32 del_between(Txt *t, u32 a, u32 b) {
return txt_delete(t, b, b - a);
}
+TxtLoc next_newline(Txt *t, TxtLoc l) {
+ do l = txt_next(t, l);
+ while (!txt_at_end(t, l) && txt_byte(t, l) != '\n');
+ return l;
+}
+
+TxtLoc prev_newline(Txt *t, TxtLoc l) {
+ do l = txt_prev(t, l);
+ while (!txt_at_start(t, l) && txt_byte(t, l) != '\n');
+ return l;
+}
+
+TxtLoc start_of_line(Txt *t, TxtLoc l) {
+ l = prev_newline(t, l);
+ if (!txt_at_start(t,l) && txt_byte(t, l) == '\n') l = txt_next(t, l);
+ return l;
+}
+
+TxtLoc prev_line(Txt *t, TxtLoc l) {
+ TxtLoc start = start_of_line(t, l);
+ u32 n = 0;
+ for (TxtLoc tmp = start; txt_before(tmp, l); txt_chr_next(t, &tmp)) n++;
+ TxtLoc start_up = start_of_line(t, txt_prev(t, start));
+ while (n--) {
+ if (txt_chr_next(t, &start_up) == '\n') {
+ start_up = txt_prev(t, start_up);
+ break;
+ }
+ }
+ return start_up;
+}
+
+TxtLoc next_line(Txt *t, TxtLoc l) {
+ TxtLoc start = start_of_line(t, l);
+ u32 n = 0;
+ for (TxtLoc tmp = start; txt_before(tmp, l); txt_chr_next(t, &tmp)) n++;
+ TxtLoc start_dn = txt_byte(t, l) == '\n' ? txt_next(t, l) : txt_next(t, next_newline(t, l));
+ while (n--) {
+ if (txt_chr_next(t, &start_dn) == '\n') {
+ start_dn = txt_prev(t, start_dn);
+ break;
+ }
+ }
+ return start_dn;
+}
+
+u32 move_line_up(Txt *t, u32 cur) {
+ return txt_ofs(t, prev_line(t, txt_at(t, cur)));
+}
+
+u32 move_line_down(Txt *t, u32 cur) {
+ return txt_ofs(t, next_line(t, txt_at(t, cur)));
+}
+
+int empty_line(Txt *t, TxtLoc l) {
+ return txt_byte(t, start_of_line(t, l)) == '\n';
+}
+
+TxtLoc next_par(Txt *t, TxtLoc l) {
+ while (!txt_at_end(t, l) && empty_line(t, l)) l = next_line(t, l);
+ while (!txt_at_end(t, l) && !empty_line(t, l)) l = next_line(t, l);
+ return l;
+}
+
+TxtLoc prev_par(Txt *t, TxtLoc l) {
+ while (!txt_at_start(t, l) && empty_line(t, l)) l = prev_line(t, l);
+ while (!txt_at_start(t, l) && !empty_line(t, l)) l = prev_line(t, l);
+ return l;
+}
+
+u32 move_par_up(Txt *t, u32 cur) {
+ return txt_ofs(t, prev_par(t, txt_at(t, cur)));
+}
+
+u32 move_par_down(Txt *t, u32 cur) {
+ return txt_ofs(t, next_par(t, txt_at(t, cur)));
+}
+
/* main */
#define ODD_ATTR (FG_CYAN | BG_BLACK)
#define EVEN_ATTR (FG_WHITE | BG_BLACK)
+void find_view_window(Txt *t, u32 curs, TxtLoc *start, TxtLoc *end) {
+ TxtLoc l = txt_at(t, curs);
+ u32 n = LINES;
+ u32 u = LINES / 2;
+ TxtLoc a = l;
+ for (u32 i = 0; i < u; i++) a = prev_newline(t, a);
+ TxtLoc b = a;
+ while (!txt_at_end(t, b) && n--) b = next_newline(t, b);
+ if (!txt_at_start(t,a) && txt_byte(t,a) == '\n') a = txt_next(t, a);
+ *start = a;
+ *end = b;
+}
+
void draw(void *ctx) {
(void)ctx;
-redraw:;
vui_clear();
- static int max_y = 0;
int x = 0, y = 0;
- u32 ofs = 0;
+ TxtLoc start, end;
+ find_view_window(&txt, cur, &start, &end);
+
+ vui_aprintf(-1, 0, ODD_ATTR, "%u pieces", txt.ptbl.n);
for (u32 i = 0; i < txt.ptbl.n; i++) {
- Arena stk = scratch;
TxtPiece *p = &txt.ptbl.v[i];
- 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;
+ vui_aprintf(-1, i+1, a, "%u, %u (%s)", p->ofs, p->n, p->buf == TXT_ADD ? "add" : "src");
}
+
TxtLoc l = txt_at(&txt, cur);
+ int cur_found = 0;
+ vui_printf(-1, -3, "(%u.%u)-(%u.%u)", start.p, start.i, end.p, end.i);
+ while (txt_before(start, end)) {
+ if (l.p == start.p && l.i == start.i) {
+ cur_found = 1;
+ vui_curs_pos(x, y);
+ }
+ u32 c = txt_chr_next(&txt, &start);
+ if (c == '\n') {
+ x = 0;
+ y++;
+ } else if (c) {
+ vui_chr(x++, y, c);
+ }
+ }
+ ASSERT(start.i <= txt.ptbl.v[start.p].n);
+ vui_printf(-1, -4, "end(%u.%u)", start.p, start.i);
+ if (!cur_found) vui_curs_pos(x, y);
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) {
+int main(int argc, const char **argv) {
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");
+ const char *path = "test.txt";
+ if (argc > 1) path = argv[1];
+ if (txt_load(&txt, path)) err(1, "couldn't open file");
cur = txt.len;
for (;;) {
scratch.beg = scratch.start;
@@ -149,6 +236,30 @@ int main(void) {
case KEY_RIGHT | KEY_CTRL_BIT:
cur = move_word_fwd(&txt, cur);
break;
+ case KEY_UP:
+ cur = move_line_up(&txt, cur);
+ break;
+ case KEY_DOWN:
+ cur = move_line_down(&txt, cur);
+ break;
+ case KEY_UP | KEY_CTRL_BIT:
+ cur = move_par_up(&txt, cur);
+ break;
+ case KEY_DOWN | KEY_CTRL_BIT:
+ cur = move_par_down(&txt, cur);
+ break;
+ case KEY_PGUP:
+ for (u32 i = 0; i < LINES; i += 3) cur = move_line_up(&txt, cur);
+ break;
+ case KEY_PGDN:
+ for (u32 i = 0; i < LINES; i += 3) cur = move_line_down(&txt, cur);
+ break;
+ case KEY_HOME:
+ cur = txt_ofs(&txt, start_of_line(&txt, txt_at(&txt, cur)));
+ break;
+ case KEY_END:
+ cur = txt_ofs(&txt, next_newline(&txt, txt_at(&txt, cur)));
+ break;
case 0x17 /* ^W */:
cur = del_between(&txt, move_word_back(&txt, cur), cur);
break;
@@ -156,8 +267,8 @@ int main(void) {
cur = del_between(&txt, cur, move_word_fwd(&txt, cur));
break;
case 0x13 /* ^S */:
- txt_save(&txt, "test.txt");
- txt_load(&txt, "test.txt");
+ txt_save(&txt, path);
+ //txt_load(&txt, "test.txt");
break;
case '\r':
cur = txt_insert_c(&txt, cur, '\n');