tvi: % motion - neatvi - [fork] simple vi-type editor with UTF-8 support
 (HTM) git clone git://src.adamsgaard.dk/neatvi
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
 (DIR) commit 5266f5c8be4e977eaac06ea4a978d13c9b378d28
 (DIR) parent 881d54517a9ce3a460cbfbf53c3efc323abd04d4
 (HTM) Author: Ali Gholami Rudi <ali@rudi.ir>
       Date:   Wed, 10 Jun 2015 14:47:38 +0430
       
       vi: % motion
       
       Diffstat:
         M mot.c                               |      29 +++++++++++++++++++++++++++++
         M vi.c                                |      19 ++++++++++++++++---
         M vi.h                                |       1 +
       
       3 files changed, 46 insertions(+), 3 deletions(-)
       ---
 (DIR) diff --git a/mot.c b/mot.c
       t@@ -184,3 +184,32 @@ int lbuf_wordend(struct lbuf *lb, int big, int dir, int *row, int *off)
                        return 1;
                return 0;
        }
       +
       +/* move to the matching character */
       +int lbuf_pair(struct lbuf *lb, int *row, int *off)
       +{
       +        int r = *row, o = *off;
       +        char *ln = lbuf_get(lb, *row);
       +        char *pairs = "()[]{}";
       +        int p;                        /* index for pairs[] */
       +        int dep = 1;                /* parenthesis depth */
       +        if (!ln || !ln[o])
       +                return 1;
       +        while (!strchr(pairs, ln[o]))
       +                if (!ln[++o])
       +                        return 1;
       +        p = strchr(pairs, ln[o]) - pairs;
       +        while (!lbuf_next(lb, (p & 1) ? -1 : +1, &r, &o)) {
       +                int c = (unsigned char) lbuf_chr(lb, r, o)[0];
       +                if (c == pairs[p ^ 1])
       +                        dep--;
       +                if (c == pairs[p])
       +                        dep++;
       +                if (!dep) {
       +                        *row = r;
       +                        *off = o;
       +                        return 0;
       +                }
       +        }
       +        return 1;
       +}
 (DIR) diff --git a/vi.c b/vi.c
       t@@ -279,6 +279,12 @@ static int vi_motionln(int *row, int cmd)
                                *row = MAX(0, MIN(*row + cnt - 1, lbuf_len(xb) - 1));
                                break;
                        }
       +                if (c == '%' && (vi_arg1 || vi_arg2)) {
       +                        if (cnt > 100)
       +                                return -1;
       +                        *row = MAX(0, lbuf_len(xb) - 1) * cnt / 100;
       +                        break;
       +                }
                        vi_back(c);
                        return 0;
                }
       t@@ -480,6 +486,10 @@ static int vi_motion(int *row, int *off)
                        *row = mark_row;
                        *off = mark_off;
                        break;
       +        case '%':
       +                if (lbuf_pair(xb, row, off))
       +                        return -1;
       +                break;
                default:
                        vi_back(mv);
                        return 0;
       t@@ -733,7 +743,7 @@ static int vc_motion(int cmd)
                if (r1 == r2 && o1 > o2)
                        swap(&o1, &o2);
                o1 = ren_noeol(lbuf_get(xb, r1), o1);
       -        if (!lnmode && strchr("fFtTeE", mv))
       +        if (!lnmode && strchr("fFtTeE%", mv))
                        if (o2 < lbuf_eol(xb, r2))
                                o2 = ren_noeol(lbuf_get(xb, r2), o2) + 1;
                if (cmd == 'y')
       t@@ -793,8 +803,10 @@ static int vc_put(int cmd)
                int lnmode;
                char *buf = reg_get(vi_ybuf, &lnmode);
                int i;
       -        if (!buf)
       +        if (!buf) {
       +                snprintf(vi_msg, sizeof(vi_msg), "yank buffer empty\n");
                        return 1;
       +        }
                if (lnmode) {
                        struct sbuf *sb = sbuf_make();
                        for (i = 0; i < cnt; i++)
       t@@ -982,7 +994,8 @@ static void vi(void)
                                vi_ybuf = vi_yankbuf();
                        mv = vi_motion(&nrow, &noff);
                        if (mv > 0) {
       -                        if (strchr("\'`GHML/?{}[]nN", mv)) {
       +                        if (strchr("\'`GHML/?{}[]nN", mv) ||
       +                                        (mv == '%' && noff < 0)) {
                                        lbuf_mark(xb, '\'', xrow, xoff);
                                        lbuf_mark(xb, '`', xrow, xoff);
                                }
 (DIR) diff --git a/vi.h b/vi.h
       t@@ -30,6 +30,7 @@ int lbuf_paragraphbeg(struct lbuf *lb, int dir, int *row, int *off);
        int lbuf_sectionbeg(struct lbuf *lb, int dir, int *row, int *off);
        int lbuf_wordbeg(struct lbuf *lb, int big, int dir, int *row, int *off);
        int lbuf_wordend(struct lbuf *lb, int big, int dir, int *row, int *off);
       +int lbuf_pair(struct lbuf *lb, int *row, int *off);
        
        /* string buffer, variable-sized string */
        struct sbuf *sbuf_make(void);