tvi: restore '*' mark in undo and redo commands - neatvi - [fork] simple vi-typ… | |
git clone git://src.adamsgaard.dk/neatvi | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit dfba674ea99270a05c441a32a22f2c0ee93b829f | |
parent 767af123ec819e4a76c8570293c75cdfe456ead6 | |
Author: Ali Gholami Rudi <[email protected]> | |
Date: Thu, 4 Jun 2015 23:33:19 +0430 | |
vi: restore '*' mark in undo and redo commands | |
Diffstat: | |
M lbuf.c | 52 +++++++++++++++++++++++++++--… | |
M vi.c | 7 +++---- | |
2 files changed, 49 insertions(+), 10 deletions(-) | |
--- | |
diff --git a/lbuf.c b/lbuf.c | |
t@@ -12,6 +12,7 @@ struct lopt { | |
int ins; /* insertion operation if non-zero */ | |
int beg, end; | |
int seq; /* operation number */ | |
+ int *mark, *mark_off; /* saved marks */ | |
}; | |
/* line buffers */ | |
t@@ -39,13 +40,20 @@ struct lbuf *lbuf_make(void) | |
return lb; | |
} | |
+static void lopt_done(struct lopt *lo) | |
+{ | |
+ free(lo->buf); | |
+ free(lo->mark); | |
+ free(lo->mark_off); | |
+} | |
+ | |
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++) | |
- free(lb->hist[i].buf); | |
+ lopt_done(&lb->hist[i]); | |
free(lb->ln); | |
free(lb); | |
} | |
t@@ -121,17 +129,18 @@ static void lbuf_opt(struct lbuf *lb, int ins, int beg, … | |
int i; | |
if (lb->undo) { | |
for (i = 0; i < lb->undo; i++) | |
- free(lb->hist[i].buf); | |
+ lopt_done(&lb->hist[i]); | |
memmove(lb->hist + 1, lb->hist + lb->undo, | |
(n - lb->undo) * sizeof(lb->hist[0])); | |
- for (i = n - lb->undo + 1; i < n; i++) | |
- lb->hist[i].buf = NULL; | |
+ 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; | |
- free(lb->hist[n - 1].buf); | |
+ lopt_done(&lb->hist[n - 1]); | |
memmove(lb->hist + 1, lb->hist, (n - 1) * sizeof(lb->hist[0])); | |
} | |
+ memset(lo, 0, sizeof(*lo)); | |
lo->ins = ins; | |
lo->beg = beg; | |
lo->end = end; | |
t@@ -163,6 +172,8 @@ void lbuf_rm(struct lbuf *lb, int beg, int end) | |
{ | |
if (end > lb->ln_n) | |
end = lb->ln_n; | |
+ if (beg == end) | |
+ return; | |
lbuf_opt(lb, 0, beg, end); | |
lbuf_delete(lb, beg, end); | |
} | |
t@@ -170,6 +181,8 @@ void lbuf_rm(struct lbuf *lb, int beg, int end) | |
void lbuf_put(struct lbuf *lb, int pos, char *s) | |
{ | |
int lb_len = lbuf_len(lb); | |
+ if (!*s) | |
+ return; | |
lbuf_insert(lb, pos, s); | |
lbuf_opt(lb, 1, pos, pos + lbuf_len(lb) - lb_len); | |
} | |
t@@ -219,6 +232,28 @@ static struct lopt *lbuf_lopt(struct lbuf *lb, int i) | |
return i >= 0 && i < LEN(lb->hist) && lo->buf ? lo : NULL; | |
} | |
+static void lbuf_savemarks(struct lbuf *lb, struct lopt *lo) | |
+{ | |
+ int i; | |
+ lo->mark = malloc(sizeof(lb->mark)); | |
+ lo->mark_off = malloc(sizeof(lb->mark_off)); | |
+ for (i = 0; i < LEN(lb->mark); i++) | |
+ lo->mark[i] = -1; | |
+ lo->mark['*'] = lb->mark['*']; | |
+ lo->mark_off['*'] = lb->mark_off['*']; | |
+} | |
+ | |
+static void lbuf_loadmarks(struct lbuf *lb, struct lopt *lo) | |
+{ | |
+ int i; | |
+ for (i = 0; lo->mark && i < LEN(lb->mark); i++) { | |
+ if (lo->mark[i] >= 0) { | |
+ lb->mark[i] = lo->mark[i]; | |
+ lb->mark_off[i] = lo->mark_off[i]; | |
+ } | |
+ } | |
+} | |
+ | |
int lbuf_undo(struct lbuf *lb) | |
{ | |
struct lopt *lo = lbuf_lopt(lb, lb->undo); | |
t@@ -232,6 +267,7 @@ int lbuf_undo(struct lbuf *lb) | |
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; | |
t@@ -250,6 +286,7 @@ int lbuf_redo(struct lbuf *lb) | |
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; | |
t@@ -267,7 +304,7 @@ void lbuf_saved(struct lbuf *lb, int clear) | |
int i; | |
if (clear) { | |
for (i = 0; i < LEN(lb->hist); i++) | |
- free(lb->hist[i].buf); | |
+ lopt_done(&lb->hist[i]); | |
memset(lb->hist, 0, sizeof(lb->hist)); | |
lb->undo = 0; | |
lb->useq_last = lb->useq; | |
t@@ -278,6 +315,9 @@ 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) | |
+ lbuf_savemarks(lb, lo); | |
lb->mod_new = 1; | |
lb->useq++; | |
return lbuf_seq(lb) != lb->useq_zero; | |
diff --git a/vi.c b/vi.c | |
t@@ -990,6 +990,7 @@ static void vi(void) | |
int z, g; | |
if (c <= 0) | |
continue; | |
+ lbuf_mark(xb, '*', xrow, xoff); | |
switch (c) { | |
case TK_CTL('b'): | |
if (vi_scrollbackward(MAX(1, vi_arg1) * (xrows… | |
t@@ -1020,8 +1021,7 @@ static void vi(void) | |
break; | |
case 'u': | |
if (!lbuf_undo(xb)) { | |
- lbuf_jump(xb, '[', &xrow, &xoff); | |
- xoff = lbuf_indents(xb, xrow); | |
+ lbuf_jump(xb, '*', &xrow, &xoff); | |
redraw = 1; | |
} else { | |
snprintf(vi_msg, sizeof(vi_msg), "undo… | |
t@@ -1029,8 +1029,7 @@ static void vi(void) | |
break; | |
case TK_CTL('r'): | |
if (!lbuf_redo(xb)) { | |
- lbuf_jump(xb, '[', &xrow, &xoff); | |
- xoff = lbuf_indents(xb, xrow); | |
+ lbuf_jump(xb, '*', &xrow, &xoff); | |
redraw = 1; | |
} else { | |
snprintf(vi_msg, sizeof(vi_msg), "redo… |