tex: last keyword for search and substitute - 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 c56b1c07c8afc6c7e7455f32c82c9b1f52ace59e
 (DIR) parent fe3f195e528e46ff0abcf91f31918fbd19942d37
 (HTM) Author: Ali Gholami Rudi <ali@rudi.ir>
       Date:   Fri, 19 Jun 2015 10:32:25 +0430
       
       ex: last keyword for search and substitute
       
       Diffstat:
         M ex.c                                |      62 +++++++++++++++++++++++--------
         M vi.c                                |      26 ++++++++++++--------------
         M vi.h                                |       5 +++++
       
       3 files changed, 63 insertions(+), 30 deletions(-)
       ---
 (DIR) diff --git a/ex.c b/ex.c
       t@@ -7,8 +7,6 @@
        #include <unistd.h>
        #include "vi.h"
        
       -#define EXLEN                512
       -
        int xrow, xoff, xtop;                /* current row, column, and top row */
        int xquit;                        /* exit if set */
        int xvis;                        /* visual mode */
       t@@ -19,6 +17,8 @@ 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 */
       +int xfinddir = +1;                /* the last search direction */
        
        static struct buf {
                char ft[32];
       t@@ -109,7 +109,8 @@ static char *ex_loc(char *s, char *loc)
                                        *loc++ = *s++;
                                }
                        }
       -                *loc++ = *s++;
       +                if (*s)
       +                        *loc++ = *s++;
                }
                *loc = '\0';
                return s;
       t@@ -158,9 +159,9 @@ static int ex_search(char *pat)
                int dir = *pat == '/' ? 1 : -1;
                char *b = pat;
                char *e = b;
       -        char *re_kw[1];
       -        int i = xrow;
       +        char *pats[1];
                struct rset *re;
       +        int row;
                kw = sbuf_make();
                while (*++e) {
                        if (*e == *pat)
       t@@ -169,18 +170,24 @@ static int ex_search(char *pat)
                        if (*e == '\\' && e[1])
                                e++;
                }
       -        re_kw[0] = sbuf_buf(kw);
       -        re = rset_make(1, re_kw, xic ? RE_ICASE : 0);
       +        if (sbuf_len(kw))
       +                snprintf(xfindkwd, sizeof(xfindkwd), "%s", sbuf_buf(kw));
                sbuf_free(kw);
       +        if (!xfindkwd[0])
       +                return xrow;
       +        xfinddir = dir;
       +        pats[0] = xfindkwd;
       +        re = rset_make(1, pats, xic ? RE_ICASE : 0);
                if (!re)
       -                return i;
       -        while (i >= 0 && i < lbuf_len(xb)) {
       -                if (rset_find(re, lbuf_get(xb, i), 0, NULL, 0) >= 0)
       +                return 1;
       +        row = xrow + dir;
       +        while (row >= 0 && row < lbuf_len(xb)) {
       +                if (rset_find(re, lbuf_get(xb, row), 0, NULL, 0) >= 0)
                                break;
       -                i += dir;
       +                row += dir;
                }
                rset_free(re);
       -        return i;
       +        return row < 0 || row >= lbuf_len(xb) ? xrow : row;
        }
        
        static int ex_lineno(char *num)
       t@@ -467,6 +474,21 @@ static int ec_print(char *ec)
                for (i = beg; i < end; i++)
                        ex_print(lbuf_get(xb, i));
                xrow = end;
       +        xoff = 0;
       +        return 0;
       +}
       +
       +static int ec_null(char *ec)
       +{
       +        char loc[EXLEN];
       +        int beg, end;
       +        if (!xvis)
       +                return ec_print(ec);
       +        ex_loc(ec, loc);
       +        if (ex_region(loc, &beg, &end))
       +                return 1;
       +        xrow = MAX(beg, end - 1);
       +        xoff = 0;
                return 0;
        }
        
       t@@ -580,6 +602,7 @@ static int ec_substitute(char *ec)
                struct rset *re;
                int offs[32];
                int beg, end;
       +        char *pats[1];
                char *pat, *rep;
                char *s;
                int delim;
       t@@ -591,9 +614,15 @@ static int ec_substitute(char *ec)
                delim = (unsigned char) *s++;
                pat = readuntil(&s, delim);
                rep = readuntil(&s, delim);
       -        re = rset_make(1, &pat, xic ? RE_ICASE : 0);
       -        if (!re)
       +        if (pat[0])
       +                snprintf(xfindkwd, sizeof(xfindkwd), "%s", pat);
       +        free(pat);
       +        pats[0] = xfindkwd;
       +        re = rset_make(1, pats, xic ? RE_ICASE : 0);
       +        if (!re) {
       +                free(rep);
                        return 1;
       +        }
                for (i = beg; i < end; i++) {
                        char *ln = lbuf_get(xb, i);
                        struct sbuf *r = sbuf_make();
       t@@ -610,7 +639,6 @@ static int ec_substitute(char *ec)
                        sbuf_free(r);
                }
                rset_free(re);
       -        free(pat);
                free(rep);
                return 0;
        }
       t@@ -733,7 +761,7 @@ static struct excmd {
                {"ya", "yank", ec_yank},
                {"!", "!", ec_exec},
                {"make", "make", ec_make},
       -        {"", "", ec_print},
       +        {"", "", ec_null},
        };
        
        /* execute a single ex command */
       t@@ -748,6 +776,8 @@ void ex_command(char *ln)
                                break;
                        }
                }
       +        if (!xvis && !cmd[0])
       +                ec_print(ln);
                lbuf_modified(xb);
        }
        
 (DIR) diff --git a/vi.c b/vi.c
       t@@ -12,9 +12,7 @@
        #include <string.h>
        #include "vi.h"
        
       -char vi_msg[512];                /* current message */
       -static char vi_findlast[256];        /* the last searched keyword */
       -static int vi_finddir;                /* the last search direction */
       +static char vi_msg[EXLEN];        /* current message */
        static char vi_charlast[8];        /* the last character searched via f, t, F, or T */
        static int vi_charcmd;                /* the character finding command */
        static int vi_arg1, vi_arg2;        /* the first and second arguments */
       t@@ -213,21 +211,21 @@ static int vi_search(int cmd, int cnt, int *row, int *off)
                        char *kw = vi_prompt(sign, &vi_kmap);
                        if (!kw)
                                return 1;
       -                vi_finddir = cmd == '/' ? +1 : -1;
       +                xfinddir = cmd == '/' ? +1 : -1;
                        if (kw[0])
       -                        snprintf(vi_findlast, sizeof(vi_findlast), "%s", kw);
       -                if (strchr(vi_findlast, cmd)) {
       -                        soff = strchr(vi_findlast, cmd) + 1;
       -                        *strchr(vi_findlast, cmd) = '\0';
       +                        snprintf(xfindkwd, sizeof(xfindkwd), "%s", kw);
       +                if (strchr(xfindkwd, cmd)) {
       +                        soff = strchr(xfindkwd, cmd) + 1;
       +                        *strchr(xfindkwd, cmd) = '\0';
                        }
                        free(kw);
                }
       -        dir = cmd == 'N' ? -vi_finddir : vi_finddir;
       -        if (!vi_findlast[0] || !lbuf_len(xb))
       +        dir = cmd == 'N' ? -xfinddir : xfinddir;
       +        if (!xfindkwd[0] || !lbuf_len(xb))
                        return 1;
                o = *off;
                for (i = 0; i < cnt; i++) {
       -                if (lbuf_search(xb, vi_findlast, dir, &r, &o, &len)) {
       +                if (lbuf_search(xb, xfindkwd, dir, &r, &o, &len)) {
                                failed = 1;
                                break;
                        }
       t@@ -248,7 +246,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", vi_findlast);
       +                snprintf(vi_msg, sizeof(vi_msg), "\"%s\" not found\n", xfindkwd);
                return failed;
        }
        
       t@@ -490,9 +488,9 @@ static int vi_motion(int *row, int *off)
                case TK_CTL('a'):
                        if (!(cs = vi_curword(xb, *row, *off)))
                                return -1;
       -                strcpy(vi_findlast, cs);
       +                strcpy(xfindkwd, cs);
                        free(cs);
       -                vi_finddir = +1;
       +                xfinddir = +1;
                        if (vi_search('n', cnt, row, off))
                                return -1;
                        break;
 (DIR) diff --git a/vi.h b/vi.h
       t@@ -185,3 +185,8 @@ extern int xai;
        extern int xdir;
        extern int xshape;
        extern int xorder;
       +
       +#define EXLEN                512        /* ex line length */
       +
       +extern char xfindkwd[EXLEN];
       +extern int xfinddir;