| 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… |