tlbuf: do not limit the size of undo history - neatvi - [fork] simple vi-type editor with UTF-8 support
(HTM) git clone git://src.adamsgaard.dk/neatvi
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
(DIR) commit ffadc288805a68e944bc6739ca3831e2c120dca0
(DIR) parent 666a00bba9a47618652e7506425c865fabe8e365
(HTM) Author: Ali Gholami Rudi <ali@rudi.ir>
Date: Mon, 29 Jun 2015 18:49:28 +0430
lbuf: do not limit the size of undo history
Tested by Peter Aronoff <peter@aronoff.org>.
Diffstat:
M lbuf.c | 85 ++++++++++++++-----------------
1 file changed, 39 insertions(+), 46 deletions(-)
---
(DIR) diff --git a/lbuf.c b/lbuf.c
t@@ -19,12 +19,14 @@ struct lopt {
struct lbuf {
int mark[NMARKS]; /* mark lines */
int mark_off[NMARKS]; /* mark line offsets */
- struct lopt hist[128]; /* buffer history */
- int undo; /* current index into hist[] */
+ char **ln; /* buffer lines */
+ int ln_n; /* number of lines in ln[] */
+ int ln_sz; /* size of ln[] */
int useq; /* current operation sequence */
- char **ln; /* lines */
- int ln_n; /* number of lbuf in l[] */
- int ln_sz; /* size of l[] */
+ struct lopt *hist; /* buffer history */
+ int hist_sz; /* size of hist[] */
+ int hist_n; /* current history head in hist[] */
+ int hist_u; /* current undo head in hist[] */
int mod_new; /* clear modification marks */
int useq_zero; /* useq for lbuf_saved() */
int useq_last; /* useq before hist[] */
t@@ -53,8 +55,9 @@ void lbuf_free(struct lbuf *lb)
int i;
for (i = 0; i < lb->ln_n; i++)
free(lb->ln[i]);
- for (i = 0; i < LEN(lb->hist); i++)
+ for (i = 0; i < lb->hist_n; i++)
lopt_done(&lb->hist[i]);
+ free(lb->hist);
free(lb->ln);
free(lb);
}
t@@ -122,29 +125,28 @@ static void lbuf_delete(struct lbuf *lb, int beg, int end)
/* append undo/redo history */
static void lbuf_opt(struct lbuf *lb, int ins, int beg, int end)
{
- struct lopt *lo = &lb->hist[0];
- int n = LEN(lb->hist);
+ struct lopt *lo;
int i;
- if (lb->undo) {
- for (i = 0; i < lb->undo; i++)
- lopt_done(&lb->hist[i]);
- memmove(lb->hist + 1, lb->hist + lb->undo,
- (n - lb->undo) * sizeof(lb->hist[0]));
- memset(lb->hist + n - lb->undo + 1, 0,
- (lb->undo - 1) * sizeof(lb->hist[0]));
- } else {
- if (lb->hist[n - 1].buf)
- lb->useq_last = lb->hist[n - 1].seq;
- lopt_done(&lb->hist[n - 1]);
- memmove(lb->hist + 1, lb->hist, (n - 1) * sizeof(lb->hist[0]));
+ for (i = lb->hist_u; i < lb->hist_n; i++)
+ lopt_done(&lb->hist[i]);
+ lb->hist_n = lb->hist_u;
+ if (lb->hist_n == lb->hist_sz) {
+ int sz = lb->hist_sz + 128;
+ struct lopt *hist = malloc(sz * sizeof(hist[0]));
+ memcpy(hist, lb->hist, lb->hist_n * sizeof(hist[0]));
+ free(lb->hist);
+ lb->hist = hist;
+ lb->hist_sz = sz;
}
+ lo = &lb->hist[lb->hist_n];
+ lb->hist_n++;
+ lb->hist_u = lb->hist_n;
memset(lo, 0, sizeof(*lo));
lo->ins = ins;
lo->beg = beg;
lo->end = end;
lo->buf = lbuf_cp(lb, beg, end);
lo->seq = lb->useq;
- lb->undo = 0;
}
void lbuf_rd(struct lbuf *lbuf, int fd, int pos)
t@@ -224,12 +226,6 @@ int lbuf_jump(struct lbuf *lbuf, int mark, int *pos, int *off)
return 0;
}
-static struct lopt *lbuf_lopt(struct lbuf *lb, int i)
-{
- struct lopt *lo = &lb->hist[i];
- return i >= 0 && i < LEN(lb->hist) && lo->buf ? lo : NULL;
-}
-
static void lbuf_savemarks(struct lbuf *lb, struct lopt *lo)
{
int i;
t@@ -254,46 +250,43 @@ static void lbuf_loadmarks(struct lbuf *lb, struct lopt *lo)
int lbuf_undo(struct lbuf *lb)
{
- struct lopt *lo = lbuf_lopt(lb, lb->undo);
- int useq = lo ? lo->seq : 0;
- if (!lo)
+ int useq;
+ if (!lb->hist_u)
return 1;
+ useq = lb->hist[lb->hist_u - 1].seq;
lb->mod_new = 1;
- while (lo && lo->seq == useq) {
- lb->undo++;
+ while (lb->hist_u && lb->hist[lb->hist_u - 1].seq == useq) {
+ struct lopt *lo = &lb->hist[--(lb->hist_u)];
if (lo->ins)
lbuf_delete(lb, lo->beg, lo->end);
else
lbuf_insert(lb, lo->beg, lo->buf);
lbuf_loadmarks(lb, lo);
- lo = lbuf_lopt(lb, lb->undo);
}
return 0;
}
int lbuf_redo(struct lbuf *lb)
{
- struct lopt *lo = lbuf_lopt(lb, lb->undo - 1);
- int useq = lo ? lo->seq : 0;
- if (!lo)
+ int useq;
+ if (lb->hist_u == lb->hist_n)
return 1;
+ useq = lb->hist[lb->hist_u].seq;
lb->mod_new = 1;
- while (lo && lo->seq == useq) {
- lb->undo--;
+ while (lb->hist_u < lb->hist_n && lb->hist[lb->hist_u].seq == useq) {
+ struct lopt *lo = &lb->hist[lb->hist_u++];
if (lo->ins)
lbuf_insert(lb, lo->beg, lo->buf);
else
lbuf_delete(lb, lo->beg, lo->end);
lbuf_loadmarks(lb, lo);
- lo = lbuf_lopt(lb, lb->undo - 1);
}
return 0;
}
static int lbuf_seq(struct lbuf *lb)
{
- struct lopt *lo = lbuf_lopt(lb, lb->undo);
- return lo ? lo->seq : lb->useq_last;
+ return lb->hist_u ? lb->hist[lb->hist_u - 1].seq : lb->useq_last;
}
/* mark buffer as saved and, if clear, clear the undo history */
t@@ -301,10 +294,10 @@ void lbuf_saved(struct lbuf *lb, int clear)
{
int i;
if (clear) {
- for (i = 0; i < LEN(lb->hist); i++)
+ for (i = 0; i < lb->hist_n; i++)
lopt_done(&lb->hist[i]);
- memset(lb->hist, 0, sizeof(lb->hist));
- lb->undo = 0;
+ lb->hist_n = 0;
+ lb->hist_u = 0;
lb->useq_last = lb->useq;
}
lb->useq_zero = lbuf_seq(lb);
t@@ -314,8 +307,8 @@ void lbuf_saved(struct lbuf *lb, int clear)
/* was the file modified since the last lbuf_modreset() */
int lbuf_modified(struct lbuf *lb)
{
- struct lopt *lo = lbuf_lopt(lb, 0);
- if (!lb->undo && lo && !lo->mark)
+ struct lopt *lo = lb->hist_n ? &lb->hist[lb->hist_n - 1] : NULL;
+ if (lb->hist_u == lb->hist_n && lo && !lo->mark)
lbuf_savemarks(lb, lo);
lb->mod_new = 1;
lb->useq++;