commit bb5fd5b9fcff1364b2bea20ebaaa8ae3436a32f7
parent f64e0f22830ca6712d361e889d61275bf417ba95
Author: Renev Pavel <an2qzavok@gmail.com>
Date: Sun, 27 Nov 2022 13:09:56 +0000
src/tabul: a tsv editor
Diffstat:
2 files changed, 164 insertions(+), 0 deletions(-)
diff --git a/src/tabul/mkfile b/src/tabul/mkfile
@@ -0,0 +1,5 @@
+</$objtype/mkfile
+TARG=tabul
+OFILES=tabul.$O
+BIN=/$objtype/bin
+</sys/src/cmd/mkone
diff --git a/src/tabul/tabul.c b/src/tabul/tabul.c
@@ -0,0 +1,159 @@
+/*
+ Simple graphical editor for tsv files
+*/
+
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+// #include <String.h>
+#include <thread.h>
+#include <draw.h>
+// #include <keyboard.h>
+#include <mouse.h>
+
+typedef struct Ed Ed;
+
+struct Ed {
+ Ed *prev;
+ int x;
+ int y;
+ char *s;
+};
+
+Ed *head;
+
+Image *bord, *text, *bg, *curbg;
+Rectangle cell, cells, edit;
+Point cur;
+Mousectl *mctl;
+Mouse mv;
+int rv[2];
+
+Ed *
+ed(Ed *parent, int x, int y, char *s)
+{
+ Ed *e = malloc(sizeof(Ed));
+ *e = (Ed){parent, x, y, s};
+ return e;
+}
+
+/*
+void
+freeed(Ed *e)
+{
+ if (e != nil) {
+ free(e->s);
+ free(e);
+ }
+}
+*/
+
+void
+loadfile(char *file)
+{
+ char *s, *args[64];
+ int n, x, y = 0;
+ Biobuf *b = Bopen(file, OREAD);
+ if (b == nil) sysfatal("loadfile: %r");
+
+ while( (s = Brdstr(b, '\n', 1)) != nil ) {
+ n = getfields(s, args, 64, 0, "\t");
+ for (x = 0; x < n; x++) {
+ head = ed(head, x, y, args[x]);
+ };
+ y++;
+ }
+ Bterm(b);
+}
+
+void
+savefile(char *)
+{
+ // find max xy in ed list
+ // alloc char * array of the max xy size
+ // loop through eds and apply ed's xy to array xy
+ // print array to file, adding tabs and newlines as necessary
+}
+
+void
+drawcell(int x, int y)
+{
+ Ed *ep;
+ Image *cellbg = bg;
+ if ((x == cur.x) && (y == cur.y)) cellbg = curbg;
+ Rectangle r = rectaddpt(cell, addpt(Pt(x * cell.max.x, y * cell.max.y), cells.min));
+ draw(screen, r, bord, nil, ZP);
+ draw(screen, insetrect(r, 1), cellbg, nil, ZP);
+ for (ep = head; ep != nil; ep = ep->prev) {
+ if ((ep->x == x) && (ep->y == y)) {
+ stringn(screen, addpt(r.min, Pt(3, 3)), text, ZP, font, ep->s, 8);
+ break;
+ }
+ }
+}
+
+void
+resize(void)
+{
+ edit = Rpt(
+ screen->r.min,
+ Pt(screen->r.max.x, screen->r.min.y + font->height + 2)
+ );
+ cells = Rpt(
+ addpt(screen->r.min, Pt(0, Dy(edit))),
+ screen->r.max
+ );
+}
+
+void
+colors(void)
+{
+ bord = display->black;
+ text = display->black;
+ bg = display->white;
+ curbg = allocimage(display, Rect(0,0,1,1), XRGB32, 1, 0xffffaaff);
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s [tsv file]\n", argv0);
+}
+
+void
+threadmain(int argc, char **argv)
+{
+ int x, y;
+ ARGBEGIN {
+ default: usage();
+ } ARGEND;
+ if (argc == 1) loadfile(argv[0]);
+ if (initdraw(nil, nil, "tabul") == 0) sysfatal("%r");
+ colors();
+ mctl = initmouse(0, screen);
+ cell = Rect(0, 0, stringwidth(font, "0") * 8 + 6, font->height + 6);
+ resize();
+ draw(screen, edit, curbg, nil, ZP);
+ for (x = 0; x < 10; x++) for (y = 0; y < 24; y++)
+ drawcell(x, y);
+ flushimage(display, 1);
+ Alt alts[] = {
+ {mctl->c, &mv, CHANRCV},
+ {mctl->resizec, rv, CHANRCV},
+ {0, 0, CHANEND},
+ };
+ for(;;){
+ switch(alt(alts)) {
+ case 0: /* mouse */
+ break;
+ case 1: /* resize */
+ if (getwindow(display, Refnone) < 0) sysfatal("%r");
+ resize();
+ draw(screen, edit, curbg, nil, ZP);
+ for (x = 0; x < 10; x++) for (y = 0; y < 24; y++)
+ drawcell(x, y);
+ flushimage(display, 1);
+ break;
+ }
+ }
+}