tlbuf: store marks for each modification more compactly - neatvi - [fork] simple vi-type editor with UTF-8 support
git clone git://src.adamsgaard.dk/neatvi
Log
Files
Refs
README
---
commit 9c04d34f7e9c3f9478e69744e40e2e8b70c8e9a6
parent cfcaaf89225f9e1f28dffa447668a4b2437f4586
Author: Ali Gholami Rudi 
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 
 #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, int m)
         }
 }
 
+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, int n_del)
                         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, int n_del)
         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;
 }