Przeglądaj źródła

Adding start of a editor

Vinicius Teshima 8 miesięcy temu
rodzic
commit
3b70f93268
1 zmienionych plików z 572 dodań i 0 usunięć
  1. 572 0
      src/ed.c

+ 572 - 0
src/ed.c

@@ -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 ------ */