tlbuf: report buffer modification - neatvi - [fork] simple vi-type editor with UTF-8 support
HTML git clone git://src.adamsgaard.dk/neatvi
DIR Log
DIR Files
DIR Refs
DIR README
---
DIR commit 767af123ec819e4a76c8570293c75cdfe456ead6
DIR parent 195dc5459fae177fba03ed32db9e0e1dd57fb972
HTML Author: Ali Gholami Rudi <ali@rudi.ir>
Date: Thu, 4 Jun 2015 10:37:54 +0430
lbuf: report buffer modification
Diffstat:
M ex.c | 12 +++++++-----
M lbuf.c | 51 +++++++++++++++++++++-----------
M vi.c | 9 ++++++---
M vi.h | 4 ++--
4 files changed, 49 insertions(+), 27 deletions(-)
---
DIR diff --git a/ex.c b/ex.c
t@@ -200,12 +200,12 @@ static void ec_edit(char *ec)
if (fd >= 0) {
lbuf_rd(xb, fd, 0);
close(fd);
- snprintf(msg, sizeof(msg), "\"%s\" %d lines [r]\n",
+ snprintf(msg, sizeof(msg), "\"%s\" %d lines [r]\n",
xpath, lbuf_len(xb));
ex_show(msg);
}
xrow = MAX(0, MIN(xrow, lbuf_len(xb) - 1));
- lbuf_undofree(xb);
+ lbuf_saved(xb, 1);
}
static void ec_read(char *ec)
t@@ -224,7 +224,7 @@ static void ec_read(char *ec)
lbuf_rd(xb, fd, lbuf_len(xb) ? end : 0);
close(fd);
xrow = end + lbuf_len(xb) - n;
- snprintf(msg, sizeof(msg), "\"%s\" %d lines [r]\n",
+ snprintf(msg, sizeof(msg), "\"%s\" %d lines [r]\n",
path, lbuf_len(xb) - n);
ex_show(msg);
}
t@@ -251,9 +251,11 @@ static void ec_write(char *ec)
if (fd >= 0) {
lbuf_wr(xb, fd, beg, end);
close(fd);
- snprintf(msg, sizeof(msg), "\"%s\" %d lines [w]\n",
+ snprintf(msg, sizeof(msg), "\"%s\" %d lines [w]\n",
path, end - beg);
ex_show(msg);
+ if (!strcmp(xpath, path))
+ lbuf_saved(xb, 0);
}
if (!strcmp("wq", cmd))
ec_quit("wq");
t@@ -542,7 +544,7 @@ void ex_command(char *ln)
break;
}
}
- lbuf_undomark(xb);
+ lbuf_modified(xb);
}
/* ex main loop */
DIR diff --git a/lbuf.c b/lbuf.c
t@@ -24,7 +24,9 @@ struct lbuf {
char **ln; /* lines */
int ln_n; /* number of lbuf in l[] */
int ln_sz; /* size of l[] */
- int mark_mod; /* clear modification marks */
+ int mod_new; /* clear modification marks */
+ int useq_zero; /* useq for lbuf_saved() */
+ int useq_last; /* useq before hist[] */
};
struct lbuf *lbuf_make(void)
t@@ -86,11 +88,11 @@ static void lbuf_insert(struct lbuf *lb, int pos, char *s)
if (lb->mark[i] >= pos)
lb->mark[i] += lbuf_len(lb) - lb_len;
end = beg + lbuf_len(lb) - lb_len;
- if (lb->mark_mod || lb->mark['['] < 0 || lb->mark['['] > beg)
+ if (lb->mod_new || lb->mark['['] < 0 || lb->mark['['] > beg)
lbuf_mark(lb, '[', beg, 0);
- if (lb->mark_mod || lb->mark[']'] < 0 || lb->mark[']'] < end - 1)
+ if (lb->mod_new || lb->mark[']'] < 0 || lb->mark[']'] < end - 1)
lbuf_mark(lb, ']', end - 1, 0);
- lb->mark_mod = 0;
+ lb->mod_new = 0;
}
/* low-level deletion */
t@@ -104,11 +106,11 @@ static void lbuf_delete(struct lbuf *lb, int beg, int end)
for (i = 0; i < LEN(lb->mark); i++) /* updating marks */
if (lb->mark[i] > beg)
lb->mark[i] = MAX(beg, lb->mark[i] + beg - end);
- if (lb->mark_mod || lb->mark['['] < 0 || lb->mark['['] > beg)
+ if (lb->mod_new || lb->mark['['] < 0 || lb->mark['['] > beg)
lbuf_mark(lb, '[', beg, 0);
- if (lb->mark_mod || lb->mark[']'] < 0 || lb->mark[']'] < beg)
+ if (lb->mod_new || lb->mark[']'] < 0 || lb->mark[']'] < beg)
lbuf_mark(lb, ']', beg, 0);
- lb->mark_mod = 0;
+ lb->mod_new = 0;
}
/* append undo/redo history */
t@@ -125,6 +127,8 @@ static void lbuf_opt(struct lbuf *lb, int ins, int beg, int end)
for (i = n - lb->undo + 1; i < n; i++)
lb->hist[i].buf = NULL;
} else {
+ if (lb->hist[n - 1].buf)
+ lb->useq_last = lb->hist[n - 1].seq;
free(lb->hist[n - 1].buf);
memmove(lb->hist + 1, lb->hist, (n - 1) * sizeof(lb->hist[0]));
}
t@@ -221,7 +225,7 @@ int lbuf_undo(struct lbuf *lb)
int useq = lo ? lo->seq : 0;
if (!lo)
return 1;
- lb->mark_mod = 1;
+ lb->mod_new = 1;
while (lo && lo->seq == useq) {
lb->undo++;
if (lo->ins)
t@@ -239,7 +243,7 @@ int lbuf_redo(struct lbuf *lb)
int useq = lo ? lo->seq : 0;
if (!lo)
return 1;
- lb->mark_mod = 1;
+ lb->mod_new = 1;
while (lo && lo->seq == useq) {
lb->undo--;
if (lo->ins)
t@@ -251,17 +255,30 @@ int lbuf_redo(struct lbuf *lb)
return 0;
}
-void lbuf_undofree(struct lbuf *lb)
+static int lbuf_seq(struct lbuf *lb)
+{
+ struct lopt *lo = lbuf_lopt(lb, lb->undo);
+ return lo ? lo->seq : lb->useq_last;
+}
+
+/* mark buffer as saved and, if clear, clear the undo history */
+void lbuf_saved(struct lbuf *lb, int clear)
{
int i;
- for (i = 0; i < LEN(lb->hist); i++)
- free(lb->hist[i].buf);
- memset(lb->hist, 0, sizeof(lb->hist));
- lb->undo = 0;
+ if (clear) {
+ for (i = 0; i < LEN(lb->hist); i++)
+ free(lb->hist[i].buf);
+ memset(lb->hist, 0, sizeof(lb->hist));
+ lb->undo = 0;
+ lb->useq_last = lb->useq;
+ }
+ lb->useq_zero = lbuf_seq(lb);
}
-void lbuf_undomark(struct lbuf *lbuf)
+/* was the file modified since the last lbuf_modreset() */
+int lbuf_modified(struct lbuf *lb)
{
- lbuf->mark_mod = 1;
- lbuf->useq++;
+ lb->mod_new = 1;
+ lb->useq++;
+ return lbuf_seq(lb) != lb->useq_zero;
}
DIR diff --git a/vi.c b/vi.c
t@@ -877,8 +877,11 @@ static int vi_scrollbackward(int cnt)
static void vc_status(void)
{
int col = vi_off2col(xb, xrow, xoff);
- snprintf(vi_msg, sizeof(vi_msg), "\"%s\" line %d of %d, col %d\n",
- xpath[0] ? xpath : "unnamed", xrow + 1, lbuf_len(xb),
+ snprintf(vi_msg, sizeof(vi_msg),
+ "\"%s\"%c %d lines L%d C%d\n",
+ xpath[0] ? xpath : "unnamed",
+ lbuf_modified(xb) ? '*' : ' ',
+ lbuf_len(xb), xrow + 1,
ren_cursor(lbuf_get(xb, xrow), col) + 1);
}
t@@ -1190,7 +1193,7 @@ static void vi(void)
vi_drawmsg();
term_pos(xrow - xtop, led_pos(lbuf_get(xb, xrow),
ren_cursor(lbuf_get(xb, xrow), xcol)));
- lbuf_undomark(xb);
+ lbuf_modified(xb);
}
term_pos(xrows, 0);
term_kill();
DIR diff --git a/vi.h b/vi.h
t@@ -19,8 +19,8 @@ void lbuf_mark(struct lbuf *lbuf, int mark, int pos, int off);
int lbuf_jump(struct lbuf *lbuf, int mark, int *pos, int *off);
int lbuf_undo(struct lbuf *lbuf);
int lbuf_redo(struct lbuf *lbuf);
-void lbuf_undomark(struct lbuf *lbuf);
-void lbuf_undofree(struct lbuf *lbuf);
+int lbuf_modified(struct lbuf *lb);
+void lbuf_saved(struct lbuf *lb, int clear);
int lbuf_indents(struct lbuf *lb, int r);
int lbuf_eol(struct lbuf *lb, int r);
/* motions */