tlbuf: store marks for each modification more compactly - neatvi - [fork] simpl… | |
git clone git://src.adamsgaard.dk/neatvi | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit 9c04d34f7e9c3f9478e69744e40e2e8b70c8e9a6 | |
parent cfcaaf89225f9e1f28dffa447668a4b2437f4586 | |
Author: Ali Gholami Rudi <[email protected]> | |
Date: Fri, 20 Nov 2015 19:34:51 +0330 | |
lbuf: store marks for each modification more compactly | |
This also improves the position of modification marks ('[ and ']) | |
and cursor position after undo and redo. | |
Diffstat: | |
M lbuf.c | 58 ++++++++++++++++++++++-------… | |
1 file changed, 41 insertions(+), 17 deletions(-) | |
--- | |
diff --git a/lbuf.c b/lbuf.c | |
t@@ -5,13 +5,14 @@ | |
#include <unistd.h> | |
#include "vi.h" | |
-#define NMARKS 128 | |
+#define NMARKS 32 | |
/* line operations */ | |
struct lopt { | |
char *ins; /* inserted text */ | |
char *del; /* deleted text */ | |
int pos, n_ins, n_del; /* modification location */ | |
+ int pos_off; /* cursor line offset */ | |
int seq; /* operation number */ | |
int *mark, *mark_off; /* saved marks */ | |
}; | |
t@@ -72,6 +73,31 @@ static void lbuf_loadmark(struct lbuf *lb, struct lopt *lo,… | |
} | |
} | |
+static int markidx(int mark) | |
+{ | |
+ if (islower(mark)) | |
+ return mark - 'a'; | |
+ if (mark == '*') | |
+ return 'z' - 'a' + 1; | |
+ if (mark == '[') | |
+ return 'z' - 'a' + 2; | |
+ if (mark == ']') | |
+ return 'z' - 'a' + 3; | |
+ return -1; | |
+} | |
+ | |
+static void lbuf_savepos(struct lbuf *lb, struct lopt *lo) | |
+{ | |
+ if (lb->mark[markidx('*')] >= 0) | |
+ lo->pos_off = lb->mark_off[markidx('*')]; | |
+} | |
+ | |
+static void lbuf_loadpos(struct lbuf *lb, struct lopt *lo) | |
+{ | |
+ lb->mark[markidx('*')] = lo->pos; | |
+ lb->mark_off[markidx('*')] = lo->pos_off; | |
+} | |
+ | |
void lbuf_free(struct lbuf *lb) | |
{ | |
int i; | |
t@@ -128,7 +154,7 @@ static void lbuf_replace(struct lbuf *lb, char *s, int pos… | |
lb->mark[i] = pos + n_ins - 1; | |
} | |
lbuf_mark(lb, '[', pos, 0); | |
- lbuf_mark(lb, ']', pos + n_ins - n_del, 0); | |
+ lbuf_mark(lb, ']', pos + (n_ins ? n_ins - 1 : 0), 0); | |
} | |
static int uc_newlines(char *s) | |
t@@ -165,10 +191,10 @@ static void lbuf_opt(struct lbuf *lb, char *buf, int pos… | |
lo->n_ins = buf ? uc_newlines(buf) : 0; | |
lo->ins = buf ? uc_dup(buf) : NULL; | |
lo->seq = lb->useq; | |
- for (i = 0; i < LEN(lb->mark); i++) | |
+ lbuf_savepos(lb, lo); | |
+ for (i = 0; i < 'z' - 'a' + 1; i++) | |
if (lb->mark[i] >= pos && lb->mark[i] < pos + n_del) | |
- if (isalpha(i)) | |
- lbuf_savemark(lb, lo, i); | |
+ lbuf_savemark(lb, lo, i); | |
} | |
void lbuf_rd(struct lbuf *lbuf, int fd, int beg, int end) | |
t@@ -226,19 +252,20 @@ int lbuf_len(struct lbuf *lb) | |
void lbuf_mark(struct lbuf *lbuf, int mark, int pos, int off) | |
{ | |
- if (mark >= NMARKS) | |
- return; | |
- lbuf->mark[mark] = pos; | |
- lbuf->mark_off[mark] = off; | |
+ if (markidx(mark) >= 0) { | |
+ lbuf->mark[markidx(mark)] = pos; | |
+ lbuf->mark_off[markidx(mark)] = off; | |
+ } | |
} | |
int lbuf_jump(struct lbuf *lbuf, int mark, int *pos, int *off) | |
{ | |
- if (mark >= NMARKS || lbuf->mark[mark] < 0) | |
+ int mk = markidx(mark); | |
+ if (mk < 0 || lbuf->mark[mk] < 0) | |
return 1; | |
- *pos = lbuf->mark[mark]; | |
+ *pos = lbuf->mark[mk]; | |
if (off) | |
- *off = lbuf->mark_off[mark]; | |
+ *off = lbuf->mark_off[mk]; | |
return 0; | |
} | |
t@@ -251,7 +278,7 @@ int lbuf_undo(struct lbuf *lb) | |
while (lb->hist_u && lb->hist[lb->hist_u - 1].seq == useq) { | |
struct lopt *lo = &lb->hist[--(lb->hist_u)]; | |
lbuf_replace(lb, lo->del, lo->pos, lo->n_ins); | |
- lbuf_loadmark(lb, lo, '*'); | |
+ lbuf_loadpos(lb, lo); | |
for (i = 0; i < LEN(lb->mark); i++) | |
lbuf_loadmark(lb, lo, i); | |
} | |
t@@ -267,7 +294,7 @@ int lbuf_redo(struct lbuf *lb) | |
while (lb->hist_u < lb->hist_n && lb->hist[lb->hist_u].seq == useq) { | |
struct lopt *lo = &lb->hist[lb->hist_u++]; | |
lbuf_replace(lb, lo->ins, lo->pos, lo->n_del); | |
- lbuf_loadmark(lb, lo, '*'); | |
+ lbuf_loadpos(lb, lo); | |
} | |
return 0; | |
} | |
t@@ -295,9 +322,6 @@ 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 = lb->hist_n ? &lb->hist[lb->hist_n - 1] : NULL; | |
- if (lb->hist_u == lb->hist_n && lo && !lo->mark) | |
- lbuf_savemark(lb, lo, '*'); | |
lb->useq++; | |
return lbuf_seq(lb) != lb->useq_zero; | |
} |