sim

the sim text editor
git clone git://ssnf.xyz/sim
Log | Files | Refs | README

commit a554e40db6f29fea69199f66dfa5fd2ed7e94b4e
parent 8a7cc7b412399d329790f80d496921b933bb4edc
Author: ssnf <ssnf@ssnf.xyz>
Date:   Sun, 15 Aug 2021 15:49:29 +0000

implemented frame functionality

Diffstat:
Msim.c | 206+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 191 insertions(+), 15 deletions(-)

diff --git a/sim.c b/sim.c @@ -5,16 +5,32 @@ #include "sim.h" -void die(char*, ...); -void* emalloc(ulong); -void* erealloc(void*, ulong); -void move(int); -void quit(int); +typedef struct { + Address* a; + ushort dot; + ushort n; + ushort size; +} Frame; -File file[FILECOUNT]; -File* f; -Window w; -uchar refresh; +void die(char*, ...); +void* emalloc(ulong); +void* erealloc(void*, ulong); +static void blind_reader(Frame* fr, Posn p0); +static void blind_writer(ushort line, ushort offset, ushort top, ushort bot); +static void fr_add(Frame* fr, Posn p0, Posn p1); +static void fr_close(Frame* fr); +static void fr_init(Frame* fr); +static void fr_insert(Frame* p, Frame* q, ushort n); +static void fr_insure(Frame* fr, ushort n); +static void fr_update(); +static void fr_zero(Frame*); +static void move(int); +static void quit(int); + +static Frame frame; +static File* f; +static File file[FILECOUNT]; +static Window w; #include "config.h" @@ -63,23 +79,181 @@ erealloc(void* p, ulong n) return p; } +static void +blind_reader(Frame* fr, Posn p0) +{ + Posn p1; + uint wx; + + p1 = p0; + do { + for (wx = 0; wx < w.wx && p1 < f->s->n - 1;) { + switch (f->s->s[p1]) { + case '\t': + wx += 4 - (wx % 4); + break; + case '\n': + goto endloop; + default: + ++wx; + } + if (wx < w.wx) + ++p1; + if (wx >= w.wx) { + if (f->s->s[p1] == '\t') + ++p1; + if (f->s->s[p1 + 1] == '\n') + ++p1; + } + } + endloop: + fr_add(fr, p0, p1); + p0 = ++p1; + } while (p1 < f->s->n - 1 && f->s->s[p1 - 1] != '\n'); +} + +static void +blind_writer(ushort line, ushort offset, ushort top, ushort bot) +{ + ushort i, o; + + o = frame.n - 1; + i = 0; + if (offset >= top) + i = offset - top + 1; + if (frame.n - offset > bot) + o = offset + bot - 1; + printf(CSI "%uH", line - offset); + fwrite(&f->s->s[frame.a[i].p0], frame.a[o].p1 - frame.a[i].p0, 1, stdout); +} + +static void +fr_add(Frame* fr, Posn p0, Posn p1) +{ + fr_insure(fr, fr->n + 1); + fr->a[fr->n].p0 = p0; + fr->a[fr->n].p1 = p1; + ++fr->n; +} + +static void +fr_close(Frame* fr) +{ + free(fr->a); +} + +static void +fr_init(Frame* fr) +{ + fr->a = emalloc(32 * sizeof(*fr->a)); + fr->dot = 0; + fr->n = 0; + fr->size = 32; +} + +static void +fr_insert(Frame* p, Frame* q, ushort n) +{ + fr_insure(p, p->n + q->n); + memmove(p->a + n + q->n, p->a + n, (p->n - n) * sizeof(*p->a)); + memmove(p->a + n, q->a, q->n * sizeof(*p->a)); + p->n += q->n; +} + +static void +fr_insure(Frame* fr, ushort n) +{ + if (n > fr->size) { + fr->size += n + (32 - (n % 32)); + fr->a = erealloc(fr->a, fr->size * sizeof(*fr->a)); + } +} + +static void +fr_update() +{ + Frame fr; + Posn p0, p1; + ushort half; + + half = w.wy >> 1; + if (!f->s->n) { + printf(ED); + goto status; + } + if (!frame.n || f->dot.p1 > frame.a[frame.n - 1].p1 || f->dot.p1 < frame.a[0].p0 || frame.n - frame.dot < half || frame.dot < half) { + fr_zero(&frame); + for (p0 = f->dot.p1; p0; --p0) + if (f->s->s[p0 - 1] == '\n') + break; + if ((p1 = p0)) { + fr_init(&fr); + for (--p1; p1 && frame.n < w.wy;) { + for (;p1 && f->s->s[p1 - 1] != '\n'; --p1); + blind_reader(&fr, p1); + if ((p1 = fr.a[0].p0)) + --p1; + fr_insert(&frame, &fr, 0); + fr_zero(&fr); + } + fr_close(&fr); + } + for (p1 = p0; p1 < f->s->n - 1 && frame.n < 2 * w.wy;) { + blind_reader(&frame, p1); + p1 = frame.a[frame.n - 1].p1 + 1; + } + for (;f->dot.p1 > frame.a[frame.dot].p1; ++frame.dot); + goto full_update; + } + if (f->dot.p1 > frame.a[frame.dot].p1 || f->dot.p1 < frame.a[frame.dot].p0) { + for (;f->dot.p1 > frame.a[frame.dot].p1; ++frame.dot); + for (;f->dot.p1 < frame.a[frame.dot].p0; --frame.dot); + goto full_update; + } + status: + printf(CSI "%uH" "%lu 0x%02x", w.wy, f->dot.p1, f->s->s[f->dot.p1]); + for (p0 = frame.a[frame.dot].p0, p1 = 1; p0 < f->dot.p1; ++p0) { + if (f->s->s[p0] == '\t') + p1 += 5 - (p1 % 4); + else + ++p1; + } + printf(CSI "%u;%luH", half, p1); + return; + full_update: + printf(ED); + blind_writer(half, frame.dot, half, half + (w.wy % 2)); + goto status; +} + +static void +fr_zero(Frame* fr) +{ + fr->n = 0; + fr->dot = 0; +} + void move(int arg) { switch (arg) { case Left: - if (f->dot.p0) - f->dot.p1 = --f->dot.p0; + if (f->dot.p1) + f->dot.p0 = --f->dot.p1; break; case Right: - if (f->dot.p0 < f->s->n) - f->dot.p1 = ++f->dot.p0; + if (f->dot.p1 + 1 < f->s->n) + f->dot.p0 = ++f->dot.p1; break; case Up: - for (;f->dot.p0 && f->s->s[f->dot.p0 - 1] != '\n'; f->dot.p1 = --f->dot.p0); + if (f->dot.p1) + for (;--f->dot.p1, f->dot.p1 && f->s->s[f->dot.p1] != '\n';); + f->dot.p0 = f->dot.p1; break; case Down: - for (;f->dot.p0 < f->s->n && f->s->s[f->dot.p0] != '\n'; f->dot.p1 = ++f->dot.p0); + if (f->dot.p1 + 1 < f->s->n) + for (;++f->dot.p1, f->dot.p1 + 1 < f->s->n && f->s->s[f->dot.p1 - 1] != '\n';); + f->dot.p0 = f->dot.p1; break; }; } @@ -98,6 +272,7 @@ main(int argc, char* argv[]) uchar c; win_init(); + fr_init(&frame); for (i = 0; i < FILECOUNT; ++i) file_init(&file[i]); f = &file[0]; @@ -107,6 +282,7 @@ main(int argc, char* argv[]) } for (;;) { win_query(&w); + fr_update(); c = fgetc(stdin); for (i = 0; i < LENGTH(keys); ++i) { if (keys[i].key == c) {