diff options
| author | WormHeamer | 2026-01-02 00:22:17 -0500 |
|---|---|---|
| committer | WormHeamer | 2026-01-02 00:22:17 -0500 |
| commit | 8fa897bdfdfef633e669cd980d856ea05ef83022 (patch) | |
| tree | d20162d8fe8cf8343a53cb63c5ead463c7f4033c | |
| parent | cff961a844962fcd61ee04bbe67777d442d0c76f (diff) | |
undo/redo
| -rw-r--r-- | txt.c | 43 | ||||
| -rw-r--r-- | txt.h | 27 |
2 files changed, 64 insertions, 6 deletions
@@ -258,6 +258,49 @@ void txt_free(Txt *t) { free(t->ptbl.v); } +void txt_hist_push(Txt *t, TxtLoc cur) { + if (t->hist.n > 0) { + TxtPieceTbl *pt = &t->hist.v[t->hist.i]; + if (t->ptbl.n == pt->n && !memcmp(pt->v, t->ptbl.v, sizeof(TxtPiece) * pt->n)) { + t->hist.cur[t->hist.i] = cur; + return; + } + } + if (t->hist.i + 1 < t->hist.n) t->hist.n = t->hist.i + 1; + if (t->hist.n == TXT_HIST_MAX) { + free(t->hist.v[0].v); + MOVE(&t->hist.v[0], &t->hist.v[1], TXT_HIST_MAX - 1); + t->hist.i--; + t->hist.n--; + } + if (t->hist.i + 1 == t->hist.n) t->hist.i++; + DA_FIT(&t->hist.v[t->hist.i], t->ptbl.n); + memcpy(t->hist.v[t->hist.i].v, t->ptbl.v, sizeof(TxtPiece) * t->ptbl.n); + t->hist.v[t->hist.i].n = t->ptbl.n; + t->hist.cur[t->hist.i] = cur; + t->hist.n++; +} + +int txt_hist_fwd(Txt *t, TxtLoc *cur) { + if (t->hist.i + 1 >= t->hist.n) return 0; + t->hist.i++; + t->ptbl.n = t->hist.v[t->hist.i].n; + DA_FIT(&t->ptbl, t->ptbl.n); + memcpy(t->ptbl.v, t->hist.v[t->hist.i].v, sizeof(TxtPiece) * t->ptbl.n); + *cur = t->hist.cur[t->hist.i]; + return 1; +} + +int txt_hist_back(Txt *t, TxtLoc *cur) { + if (t->hist.i == 0) return 0; + t->hist.i--; + t->ptbl.n = t->hist.v[t->hist.i].n; + DA_FIT(&t->ptbl, t->ptbl.n); + memcpy(t->ptbl.v, t->hist.v[t->hist.i].v, sizeof(TxtPiece) * t->ptbl.n); + *cur = t->hist.cur[t->hist.i]; + return 1; +} + Str txt_collect_range(TxtLoc lo, TxtLoc hi, Arena *a) { DYNARR(char) buf = { 0 }; while (lo.p < hi.p) { @@ -5,6 +5,8 @@ #include "arena.h" #include "str.h" +#define TXT_HIST_MAX 32 + typedef enum : u8 { TXT_SRC, TXT_ADD @@ -20,18 +22,27 @@ typedef struct { u32 n, c; } TxtBuf; +typedef DYNARR(TxtPiece) TxtPieceTbl; + +typedef struct { + struct Txt *t; + u32 p, i; +} TxtLoc; + typedef struct { - DYNARR(TxtPiece) ptbl; + TxtPieceTbl v[TXT_HIST_MAX]; + TxtLoc cur[TXT_HIST_MAX]; + u32 i, n; +} TxtHist; + +typedef struct Txt { + TxtPieceTbl ptbl; + TxtHist hist; TxtBuf buf[2]; u32 len; int dirty; } Txt; -typedef struct { - Txt *t; - u32 p, i; -} TxtLoc; - /* text buffer manipulation */ TxtLoc txt_split_piece(TxtLoc l); @@ -43,6 +54,10 @@ int txt_load(Txt *b, const char *path); int txt_save(Txt *b, const char *path); void txt_free(Txt *b); +void txt_hist_push(Txt *t, TxtLoc cur); +int txt_hist_fwd(Txt *t, TxtLoc *cur); +int txt_hist_back(Txt *t, TxtLoc *cur); + Str txt_collect_range(TxtLoc lo, TxtLoc hi, Arena *a); u32 txt_read_chunk(TxtLoc *lo, TxtLoc hi, char *buf, u32 sz); Str txt_next_chunk(TxtLoc *l); |
