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;