tex: last keyword for search and substitute - neatvi - [fork] simple vi-type ed… | |
git clone git://src.adamsgaard.dk/neatvi | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit c56b1c07c8afc6c7e7455f32c82c9b1f52ace59e | |
parent fe3f195e528e46ff0abcf91f31918fbd19942d37 | |
Author: Ali Gholami Rudi <[email protected]> | |
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(-) | |
--- | |
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); | |
} | |
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,… | |
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 *of… | |
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_find… | |
+ snprintf(vi_msg, sizeof(vi_msg), "\"%s\" not found\n", xfindkw… | |
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; | |
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; |