|
|
@@ -0,0 +1,572 @@
|
|
|
+#include <stdio.h>
|
|
|
+#include <stdlib.h>
|
|
|
+#include <unistd.h>
|
|
|
+#include <string.h>
|
|
|
+#include <stdbool.h>
|
|
|
+#include <sys/ioctl.h>
|
|
|
+
|
|
|
+#include <termios.h>
|
|
|
+
|
|
|
+#define IMP
|
|
|
+#include "./file.h"
|
|
|
+#include "./path.h"
|
|
|
+
|
|
|
+enum m {
|
|
|
+ MN = 0,
|
|
|
+ ME,
|
|
|
+ MI,
|
|
|
+ MV
|
|
|
+};
|
|
|
+
|
|
|
+/* ------ START struct b Defs ------ */
|
|
|
+
|
|
|
+enum be {
|
|
|
+ BE_OK = 0,
|
|
|
+ BE_FILE_DOES_NOT_EXIST,
|
|
|
+ BE_FAILED_READ_FILE
|
|
|
+};
|
|
|
+
|
|
|
+const char *be2cs(enum be be);
|
|
|
+
|
|
|
+struct l {
|
|
|
+ uint64_t s;
|
|
|
+ uint64_t e;
|
|
|
+ uint64_t n;
|
|
|
+};
|
|
|
+
|
|
|
+struct b {
|
|
|
+ struct str fp;
|
|
|
+ struct str fn;
|
|
|
+ struct {
|
|
|
+ char *d;
|
|
|
+ uint64_t s;
|
|
|
+ uint64_t c;
|
|
|
+ } b;
|
|
|
+ struct {
|
|
|
+ struct l *d;
|
|
|
+ uint64_t s;
|
|
|
+ uint64_t c;
|
|
|
+ } ls;
|
|
|
+ uint64_t c;
|
|
|
+ enum m m;
|
|
|
+};
|
|
|
+
|
|
|
+struct b bc(const char *fp, enum be *e);
|
|
|
+struct b bd(struct b b);
|
|
|
+
|
|
|
+struct b bfl(struct b b);
|
|
|
+struct l bcl(struct b b);
|
|
|
+
|
|
|
+struct b bmcu(struct b b);
|
|
|
+struct b bmcd(struct b b);
|
|
|
+struct b bmcr(struct b b);
|
|
|
+struct b bmcl(struct b b);
|
|
|
+
|
|
|
+void _bse(enum be *e, enum be e_);
|
|
|
+
|
|
|
+/* ------ END struct b Defs ------ */
|
|
|
+
|
|
|
+/* ------ START struct a Defs ------ */
|
|
|
+
|
|
|
+enum ee {
|
|
|
+ EE_OK = 0,
|
|
|
+ EE_NULL_ARGS
|
|
|
+};
|
|
|
+
|
|
|
+struct e {
|
|
|
+ struct {
|
|
|
+ struct b *d;
|
|
|
+ uint64_t s;
|
|
|
+ uint64_t c;
|
|
|
+ } bs;
|
|
|
+ struct b *cb;
|
|
|
+ bool r;
|
|
|
+};
|
|
|
+
|
|
|
+struct e ec(void);
|
|
|
+struct e ed(struct e e);
|
|
|
+
|
|
|
+void epcb(struct e e);
|
|
|
+
|
|
|
+struct e escb(struct e e, struct b *b, enum ee *err);
|
|
|
+bool ecbp(struct e e, struct b *b);
|
|
|
+
|
|
|
+struct e eab(struct e e, struct b b);
|
|
|
+
|
|
|
+void _ese(enum ee *e, enum ee e_);
|
|
|
+
|
|
|
+/* ------ END struct a Defs ------ */
|
|
|
+
|
|
|
+struct {
|
|
|
+ int32_t r;
|
|
|
+ int32_t c;
|
|
|
+} TS = {0};
|
|
|
+struct {
|
|
|
+ char *d;
|
|
|
+ uint64_t s;
|
|
|
+ uint64_t c;
|
|
|
+} WB = {0};
|
|
|
+
|
|
|
+void w(const char *t);
|
|
|
+void ws(struct str s);
|
|
|
+void c2r(int32_t r);
|
|
|
+void s(void);
|
|
|
+
|
|
|
+void* c(size_t s);
|
|
|
+#define C(var, size) \
|
|
|
+ var = calloc(size, 1); \
|
|
|
+ if ( var == NULL ) { \
|
|
|
+ fprintf(stderr, "%s:%d: Failed to calloc: BUY MORE MEMORY!\n", __FILE__, __LINE__); \
|
|
|
+ exit(EXIT_FAILURE); \
|
|
|
+ } \
|
|
|
+
|
|
|
+int
|
|
|
+main(int argc, const char *argv[])
|
|
|
+{
|
|
|
+ struct termios tbak;
|
|
|
+ struct termios tnew;
|
|
|
+ const char *filepath = "Makefile";
|
|
|
+ struct winsize ws = {0};
|
|
|
+ enum be be;
|
|
|
+ struct b b = {0};
|
|
|
+ struct e e = {0};
|
|
|
+
|
|
|
+ e = ec();
|
|
|
+
|
|
|
+ ioctl(1, TIOCGWINSZ, &ws);
|
|
|
+ TS.r = ws.ws_row;
|
|
|
+ TS.c = ws.ws_col;
|
|
|
+
|
|
|
+ tcgetattr(0, &tbak);
|
|
|
+
|
|
|
+ tnew = tbak;
|
|
|
+ tnew.c_lflag = (tcflag_t) (((int) tbak.c_lflag) & (~ (ICANON | ECHO)));
|
|
|
+ tnew.c_cc[VMIN] = 1;
|
|
|
+ tnew.c_cc[VTIME] = 0;
|
|
|
+ tcsetattr(0, TCSANOW, &tnew);
|
|
|
+
|
|
|
+ b = bc(filepath, &be);
|
|
|
+ if ( be != BE_OK ) {
|
|
|
+ printf("Failed to create buffer: %s", be2cs(be));
|
|
|
+ exit(EXIT_FAILURE);
|
|
|
+ }
|
|
|
+
|
|
|
+ e = eab(e, b);
|
|
|
+
|
|
|
+ w("\x1B[?47h");
|
|
|
+
|
|
|
+ w("\x1B[2J");
|
|
|
+ w("\x1B[1;1H");
|
|
|
+ w("\x1B[1;1H");
|
|
|
+ s();
|
|
|
+
|
|
|
+ while ( e.r == true ) {
|
|
|
+ char bu[5] = {0};
|
|
|
+
|
|
|
+ w("\x1B[2J");
|
|
|
+ epcb(e);
|
|
|
+ s();
|
|
|
+ /* There is smears when moving up and down */
|
|
|
+ /* I need to change the arch TB **should** work like an graphic buffer */
|
|
|
+ /* Unless i want to clear the screen no every frame */
|
|
|
+ read(0, bu, 5);
|
|
|
+
|
|
|
+ switch ( bu[0] ) {
|
|
|
+ case 'q':
|
|
|
+ e.r = false;
|
|
|
+ continue;
|
|
|
+ case '\x1B':
|
|
|
+ if ( bu[1] != '[' ) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ switch ( bu[2] ) {
|
|
|
+ case 'A': *e.cb = bmcu(*e.cb); break;
|
|
|
+ case 'B': *e.cb = bmcd(*e.cb); break;
|
|
|
+ case 'C': *e.cb = bmcr(*e.cb); break;
|
|
|
+ case 'D': *e.cb = bmcl(*e.cb); break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /* printf("\n%3d | %3d | %3d | %3d\n", bu[0], bu[1], bu[2], bu[3]); */
|
|
|
+ };
|
|
|
+
|
|
|
+ e = ed(e);
|
|
|
+
|
|
|
+ /*c2r(TS.r);
|
|
|
+ w("\x1B[31m");
|
|
|
+ w("Mode Line");
|
|
|
+ w("\x1B[0m");*/
|
|
|
+
|
|
|
+ w("\x1B[?47l");
|
|
|
+ s();
|
|
|
+
|
|
|
+ tcsetattr(0, TCSANOW, &tbak);
|
|
|
+ (void) argc; (void) argv;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+w(const char *t)
|
|
|
+{
|
|
|
+ struct str s = {0};
|
|
|
+ s = str_from_cstr(t, strlen(t));
|
|
|
+ ws(s);
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+ws(struct str s)
|
|
|
+{
|
|
|
+ if ( WB.d == NULL ) {
|
|
|
+ WB.c = (uint64_t) (TS.r * TS.c) + 10;
|
|
|
+ C(WB.d, WB.c);
|
|
|
+ WB.s = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( WB.s + s.size >= WB.c ) {
|
|
|
+ WB.c *= 2;
|
|
|
+ WB.d = realloc(WB.d, WB.c);
|
|
|
+ }
|
|
|
+
|
|
|
+ memcpy(WB.d + WB.s, s.data, s.size);
|
|
|
+ WB.s += s.size;
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+c2r(int32_t r)
|
|
|
+{
|
|
|
+ char b[64] = {0};
|
|
|
+ sprintf(b, "\033[%d;1H", r);
|
|
|
+ w(b);
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+s(void)
|
|
|
+{
|
|
|
+ if ( WB.s == 0 || WB.d == NULL ) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ write(1, WB.d, WB.s);
|
|
|
+ memset(WB.d, 0, WB.c);
|
|
|
+ WB.s = 0;
|
|
|
+}
|
|
|
+
|
|
|
+void *
|
|
|
+c(size_t s)
|
|
|
+{
|
|
|
+ void *ptr = NULL;
|
|
|
+ ptr = calloc(s, 1);
|
|
|
+ if ( ptr == NULL ) {
|
|
|
+ fprintf(stderr, "Failed to calloc: BUY MORE MEMORY!\n");
|
|
|
+ exit(EXIT_FAILURE);
|
|
|
+ }
|
|
|
+ return ptr;
|
|
|
+}
|
|
|
+
|
|
|
+/* ------ START struct b Funcs ------ */
|
|
|
+
|
|
|
+struct b
|
|
|
+bc(const char *fp, enum be *e)
|
|
|
+{
|
|
|
+ struct b ept = {0};
|
|
|
+ struct b b = {0};
|
|
|
+ enum file_err fe;
|
|
|
+
|
|
|
+ b.fp = str_from_cstr(fp, strlen(fp));
|
|
|
+
|
|
|
+ if ( path_exists(b.fp) == false ) {
|
|
|
+ _bse(e, BE_FILE_DOES_NOT_EXIST);
|
|
|
+ return ept;
|
|
|
+ }
|
|
|
+
|
|
|
+ b.fn = path_dirname(b.fp);
|
|
|
+
|
|
|
+ b.b.d = (char *) file_read_all(b.fp.data, &b.b.s, &fe);
|
|
|
+ if ( fe != FILE_ERR_OK ) {
|
|
|
+ _bse(e, BE_FAILED_READ_FILE);
|
|
|
+ return ept;
|
|
|
+ }
|
|
|
+
|
|
|
+ b.b.c = b.b.s;
|
|
|
+
|
|
|
+ b = bfl(b);
|
|
|
+
|
|
|
+ _bse(e, BE_OK);
|
|
|
+ return b;
|
|
|
+}
|
|
|
+
|
|
|
+struct b
|
|
|
+bd(struct b b)
|
|
|
+{
|
|
|
+ struct b ept = {0};
|
|
|
+ free(b.b.d);
|
|
|
+ free(b.ls.d);
|
|
|
+ return ept;
|
|
|
+}
|
|
|
+
|
|
|
+struct b
|
|
|
+bfl(struct b b)
|
|
|
+{
|
|
|
+ uint64_t i = 0;
|
|
|
+ struct l l1 = {0};
|
|
|
+
|
|
|
+ if ( b.ls.d == NULL ) {
|
|
|
+ b.ls.c = 16;
|
|
|
+ b.ls.d = calloc(b.ls.c, sizeof(*b.ls.d));
|
|
|
+ }
|
|
|
+
|
|
|
+ for ( i = 0; i < b.b.s; ++i ) {
|
|
|
+ if ( b.b.d[i] == '\n' ) {
|
|
|
+ l1.e = i;
|
|
|
+
|
|
|
+ if ( b.ls.s + 1 >= b.ls.c ) {
|
|
|
+ b.ls.c *= 2;
|
|
|
+ b.ls.d = realloc(b.ls.d, b.ls.c * sizeof(*b.ls.d));
|
|
|
+ }
|
|
|
+
|
|
|
+ l1.n = b.ls.s;
|
|
|
+ b.ls.d[b.ls.s++] = l1;
|
|
|
+
|
|
|
+ l1.s = ++i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return b;
|
|
|
+}
|
|
|
+
|
|
|
+struct l
|
|
|
+bcl(struct b b)
|
|
|
+{
|
|
|
+ uint64_t i = 0;
|
|
|
+ struct l l = {0};
|
|
|
+
|
|
|
+ for ( i = 0; i < b.ls.s; ++i ) {
|
|
|
+ l = b.ls.d[i];
|
|
|
+
|
|
|
+ if ( b.c >= l.s && b.c <= l.e ) {
|
|
|
+ return l;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return l;
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+_bse(enum be *e, enum be e_)
|
|
|
+{
|
|
|
+ if ( e == NULL ) return;
|
|
|
+ *e = e_;
|
|
|
+}
|
|
|
+
|
|
|
+struct b
|
|
|
+bmcu(struct b b)
|
|
|
+{
|
|
|
+ struct l cl = {0};
|
|
|
+ struct l nl = {0};
|
|
|
+ uint64_t co = 0;
|
|
|
+
|
|
|
+ if ( b.c == 0 ) {
|
|
|
+ return b;
|
|
|
+ }
|
|
|
+
|
|
|
+ cl = bcl(b);
|
|
|
+
|
|
|
+ if ( cl.n == 0 ) {
|
|
|
+ return b;
|
|
|
+ }
|
|
|
+
|
|
|
+ nl = b.ls.d[cl.n-1];
|
|
|
+
|
|
|
+ co = b.c - cl.s;
|
|
|
+ if ( co > nl.e ) {
|
|
|
+ b.c = nl.e;
|
|
|
+ } else {
|
|
|
+ b.c = nl.s + co;
|
|
|
+ }
|
|
|
+
|
|
|
+ return b;
|
|
|
+}
|
|
|
+
|
|
|
+struct b
|
|
|
+bmcd(struct b b)
|
|
|
+{
|
|
|
+ struct l cl = {0};
|
|
|
+ struct l nl = {0};
|
|
|
+ uint64_t co = 0;
|
|
|
+
|
|
|
+ if ( b.c >= b.b.s ) {
|
|
|
+ b.c = b.b.s-1;
|
|
|
+ return b;
|
|
|
+ }
|
|
|
+
|
|
|
+ cl = bcl(b);
|
|
|
+
|
|
|
+ if ( cl.n == b.ls.s ) {
|
|
|
+ return b;
|
|
|
+ }
|
|
|
+
|
|
|
+ nl = b.ls.d[cl.n+1];
|
|
|
+
|
|
|
+ co = b.c - cl.s;
|
|
|
+ if ( co > nl.e ) {
|
|
|
+ b.c = nl.e;
|
|
|
+ } else {
|
|
|
+ b.c = nl.s + co;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( b.c >= b.b.s ) {
|
|
|
+ b.c = b.b.s-1;
|
|
|
+ return b;
|
|
|
+ }
|
|
|
+
|
|
|
+ return b;
|
|
|
+}
|
|
|
+
|
|
|
+struct b
|
|
|
+bmcr(struct b b)
|
|
|
+{
|
|
|
+ if ( b.c + 1 >= b.b.s ) {
|
|
|
+ b.c = b.b.s - 1;
|
|
|
+ return b;
|
|
|
+ }
|
|
|
+
|
|
|
+ b.c++;
|
|
|
+
|
|
|
+ return b;
|
|
|
+}
|
|
|
+
|
|
|
+struct b
|
|
|
+bmcl(struct b b)
|
|
|
+{
|
|
|
+ if ( b.c == 0 ) {
|
|
|
+ return b;
|
|
|
+ }
|
|
|
+
|
|
|
+ b.c--;
|
|
|
+
|
|
|
+ return b;
|
|
|
+}
|
|
|
+
|
|
|
+const char *
|
|
|
+be2cs(enum be be)
|
|
|
+{
|
|
|
+ switch ( be ) {
|
|
|
+ case BE_OK: return "BE_OK";
|
|
|
+ case BE_FILE_DOES_NOT_EXIST: return "BE_FILE_DOES_NOT_EXIST";
|
|
|
+ case BE_FAILED_READ_FILE: return "BE_FAILED_READ_FILE";
|
|
|
+ }
|
|
|
+
|
|
|
+ return "Invalid BE Error";
|
|
|
+}
|
|
|
+
|
|
|
+/* ------ END struct b Funcs ------ */
|
|
|
+
|
|
|
+/* ------ START struct a Funcs ------ */
|
|
|
+
|
|
|
+struct e
|
|
|
+ec(void)
|
|
|
+{
|
|
|
+ struct e e = {0};
|
|
|
+
|
|
|
+ e.r = true;
|
|
|
+
|
|
|
+ return e;
|
|
|
+}
|
|
|
+
|
|
|
+struct e
|
|
|
+ed(struct e e)
|
|
|
+{
|
|
|
+ struct e ept = {0};
|
|
|
+ size_t i = 0;
|
|
|
+
|
|
|
+ for ( i = 0; i < e.bs.s; ++i ) {
|
|
|
+ e.bs.d[i] = bd(e.bs.d[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ free(e.bs.d);
|
|
|
+
|
|
|
+ return ept;
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+epcb(struct e e)
|
|
|
+{
|
|
|
+ uint64_t i = 0;
|
|
|
+ uint64_t r = 0;
|
|
|
+ struct b *b = e.cb;
|
|
|
+ struct str s = {0};
|
|
|
+ struct l cl = {0};
|
|
|
+
|
|
|
+ s = str_from_cstr(b->b.d, b->b.s);
|
|
|
+
|
|
|
+ cl = bcl(*b);
|
|
|
+
|
|
|
+ /* TODO: There are missing lines */
|
|
|
+ for ( i = cl.n; i < b->ls.s; ++i ) {
|
|
|
+ struct l l = b->ls.d[i];
|
|
|
+
|
|
|
+ c2r((int32_t) r++);
|
|
|
+
|
|
|
+ ws(str_slice(s, l.s, l.e));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+struct e
|
|
|
+escb(struct e e, struct b *b, enum ee *err)
|
|
|
+{
|
|
|
+ if ( b == NULL ) {
|
|
|
+ _ese(err, EE_NULL_ARGS);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ecbp(e, b) == false ) {
|
|
|
+ e = eab(e, *b);
|
|
|
+ e.cb = &e.bs.d[e.bs.s-1];
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ e.cb = b;
|
|
|
+
|
|
|
+exit:
|
|
|
+ _ese(err, EE_OK);
|
|
|
+ return e;
|
|
|
+}
|
|
|
+
|
|
|
+bool
|
|
|
+ecbp(struct e e, struct b *b)
|
|
|
+{
|
|
|
+ size_t i = 0;
|
|
|
+
|
|
|
+ for ( i = 0; i < e.bs.s; ++i ) {
|
|
|
+ if ( &e.bs.d[i] == b ) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+struct e
|
|
|
+eab(struct e e, struct b b)
|
|
|
+{
|
|
|
+ if ( e.bs.s + 1 >= e.bs.c ) {
|
|
|
+ e.bs.c *= 2;
|
|
|
+ e.bs.d = realloc(e.bs.d, e.bs.c * sizeof(*e.bs.d));
|
|
|
+ }
|
|
|
+
|
|
|
+ e.bs.d[e.bs.s++] = b;
|
|
|
+
|
|
|
+ if ( e.bs.s == 1 ) {
|
|
|
+ e.cb = &e.bs.d[0];
|
|
|
+ }
|
|
|
+
|
|
|
+ return e;
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+_ese(enum ee *e, enum ee e_)
|
|
|
+{
|
|
|
+ if ( e != NULL ) {
|
|
|
+ *e = e_;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* ------ END struct a Funcs ------ */
|