tex: store search keywords and ex commands in ex buffers - 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 d2e85a01607d64b873e6db1e667f8583c0b5aced
 (DIR) parent 8d920bf3b193961749c1490708fd135167f74a59
 (HTM) Author: Ali Gholami Rudi <ali@rudi.ir>
       Date:   Thu, 25 Feb 2016 09:07:10 +0330
       
       ex: store search keywords and ex commands in ex buffers
       
       Diffstat:
         M ex.c                                |      44 ++++++++++++++++++++++---------
         M vi.c                                |      16 +++++++---------
         M vi.h                                |       8 +++-----
       
       3 files changed, 41 insertions(+), 27 deletions(-)
       ---
 (DIR) diff --git a/ex.c b/ex.c
       t@@ -19,9 +19,9 @@ int xled = 1;                        /* use the line editor */
        int xdir = +1;                        /* current direction context */
        int xshape = 1;                        /* perform letter shaping */
        int xorder = 1;                        /* change the order of characters */
       -char xfindkwd[EXLEN];                /* the last searched keyword */
       -char xfindrep[EXLEN];                /* the last replacement */
       -int xfinddir = +1;                /* the last search direction */
       +static char xfindkwd[EXLEN];        /* the last searched keyword */
       +static char xfindrep[EXLEN];        /* the last replacement */
       +static int xfinddir;                /* the last search direction */
        static char *xkmap = "en";        /* the current keymap */
        static char xkmap2[8] = "fa";        /* the alternate keymap */
        
       t@@ -191,15 +191,32 @@ static char *ex_line(char *s, char *ln)
                return *s ? s + 1 : s;
        }
        
       +/* the previous search keyword */
       +int ex_kwd(char **kwd, int *dir)
       +{
       +        if (kwd)
       +                *kwd = xfindkwd;
       +        if (dir)
       +                *dir = xfinddir;
       +        return xfinddir == 0;
       +}
       +
       +/* set the previous search keyword */
       +void ex_kwdset(char *kwd, int dir)
       +{
       +        snprintf(xfindkwd, sizeof(xfindkwd), "%s", kwd);
       +        reg_put('/', kwd, 0);
       +        xfinddir = dir;
       +}
       +
        static int ex_search(char *pat)
        {
                struct sbuf *kw;
       -        int dir = *pat == '/' ? 1 : -1;
                char *b = pat;
                char *e = b;
                char *pats[1];
                struct rset *re;
       -        int row;
       +        int dir, row;
                kw = sbuf_make();
                while (*++e) {
                        if (*e == *pat)
       t@@ -209,12 +226,10 @@ static int ex_search(char *pat)
                                e++;
                }
                if (sbuf_len(kw))
       -                snprintf(xfindkwd, sizeof(xfindkwd), "%s", sbuf_buf(kw));
       +                ex_kwdset(sbuf_buf(kw), *pat == '/' ? 1 : -1);
                sbuf_free(kw);
       -        if (!xfindkwd[0])
       +        if (!ex_kwd(&pats[0], &dir))
                        return xrow;
       -        xfinddir = dir;
       -        pats[0] = xfindkwd;
                re = rset_make(1, pats, xic ? RE_ICASE : 0);
                if (!re)
                        return 1;
       t@@ -644,7 +659,7 @@ static int ec_substitute(char *ec)
                s = ex_argeol(ec);
                pat = re_read(&s);
                if (pat && pat[0])
       -                snprintf(xfindkwd, sizeof(xfindkwd), "%s", pat);
       +                ex_kwdset(pat, +1);
                if (pat && *s) {
                        s--;
                        rep = re_read(&s);
       t@@ -653,7 +668,8 @@ static int ec_substitute(char *ec)
                        rep = uc_dup(pat ? "" : xfindrep);
                snprintf(xfindrep, sizeof(xfindrep), "%s", rep);
                free(pat);
       -        pats[0] = xfindkwd;
       +        if (ex_kwd(&pats[0], NULL))
       +                return 1;
                re = rset_make(1, pats, xic ? RE_ICASE : 0);
                if (!re) {
                        free(rep);
       t@@ -749,9 +765,10 @@ static int ec_glob(char *ec)
                s = ex_argeol(ec);
                pat = re_read(&s);
                if (pat && pat[0])
       -                snprintf(xfindkwd, sizeof(xfindkwd), "%s", pat);
       +                ex_kwdset(pat, +1);
                free(pat);
       -        pats[0] = xfindkwd;
       +        if (ex_kwd(&pats[0], NULL))
       +                return 1;
                if (!(re = rset_make(1, pats, xic ? RE_ICASE : 0)))
                        return 1;
                i = beg;
       t@@ -902,6 +919,7 @@ void ex_command(char *ln)
        {
                ex_exec(ln);
                lbuf_modified(xb);
       +        reg_put(':', ln, 0);
        }
        
        /* ex main loop */
 (DIR) diff --git a/vi.c b/vi.c
       t@@ -238,6 +238,7 @@ static int vi_findchar(struct lbuf *lb, char *cs, int cmd, int n, int *row, int 
        
        static int vi_search(int cmd, int cnt, int *row, int *off)
        {
       +        char *kwd;
                int r = *row;
                int o = *off;
                int failed = 0;
       t@@ -256,9 +257,7 @@ static int vi_search(int cmd, int cnt, int *row, int *off)
                        free(kw);
                        kw = sbuf_buf(sb);
                        if ((re = re_read(&kw))) {
       -                        xfinddir = cmd == '/' ? +1 : -1;
       -                        if (re[0])
       -                                snprintf(xfindkwd, sizeof(xfindkwd), "%s", re);
       +                        ex_kwdset(re[0] ? re : NULL, cmd == '/' ? +1 : -1);
                                while (isspace(*kw))
                                        kw++;
                                vi_soset = !!kw[0];
       t@@ -267,12 +266,12 @@ static int vi_search(int cmd, int cnt, int *row, int *off)
                        }
                        sbuf_free(sb);
                }
       -        dir = cmd == 'N' ? -xfinddir : xfinddir;
       -        if (!xfindkwd[0] || !lbuf_len(xb))
       +        if (!lbuf_len(xb) || ex_kwd(&kwd, &dir))
                        return 1;
       +        dir = cmd == 'N' ? -dir : dir;
                o = *off;
                for (i = 0; i < cnt; i++) {
       -                if (lbuf_search(xb, xfindkwd, dir, &r, &o, &len)) {
       +                if (lbuf_search(xb, kwd, dir, &r, &o, &len)) {
                                failed = 1;
                                break;
                        }
       t@@ -291,7 +290,7 @@ static int vi_search(int cmd, int cnt, int *row, int *off)
                        }
                }
                if (failed)
       -                snprintf(vi_msg, sizeof(vi_msg), "\"%s\" not found\n", xfindkwd);
       +                snprintf(vi_msg, sizeof(vi_msg), "\"%s\" not found\n", kwd);
                return failed;
        }
        
       t@@ -533,9 +532,8 @@ static int vi_motion(int *row, int *off)
                case TK_CTL('a'):
                        if (!(cs = vi_curword(xb, *row, *off)))
                                return -1;
       -                strcpy(xfindkwd, cs);
       +                ex_kwdset(cs, +1);
                        free(cs);
       -                xfinddir = +1;
                        if (vi_search('n', cnt, row, off))
                                return -1;
                        break;
 (DIR) diff --git a/vi.h b/vi.h
       t@@ -145,7 +145,10 @@ char *ex_filetype(void);
        char **ex_kmap(void);
        char *ex_kmapalt(void);
        struct lbuf *ex_lbuf(void);
       +int ex_kwd(char **kwd, int *dir);
       +void ex_kwdset(char *kwd, int dir);
        
       +#define EXLEN        512                /* ex line length */
        #define xb         ex_lbuf()
        
        /* process management */
       t@@ -195,8 +198,3 @@ extern int xdir;
        extern int xshape;
        extern int xorder;
        extern int xhl;
       -
       -#define EXLEN                512        /* ex line length */
       -
       -extern char xfindkwd[EXLEN];
       -extern int xfinddir;