URI:
       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 */