tvi: escaped delimiters in regular expressions - neatvi - [fork] simple vi-type… | |
git clone git://src.adamsgaard.dk/neatvi | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit a162543d7ef56e666d8436be42e9180a4864a4e5 | |
parent 31e7e13a90023abeac92914774c31721ae0c22d9 | |
Author: Ali Gholami Rudi <[email protected]> | |
Date: Fri, 1 Jan 2016 09:49:33 +0330 | |
vi: escaped delimiters in regular expressions | |
Diffstat: | |
M ex.c | 27 ++++----------------------- | |
M rset.c | 18 ++++++++++++++++++ | |
M vi.c | 34 +++++++++++++++++++----------… | |
M vi.h | 1 + | |
4 files changed, 44 insertions(+), 36 deletions(-) | |
--- | |
diff --git a/ex.c b/ex.c | |
t@@ -627,22 +627,6 @@ static int ec_mark(char *ec) | |
return 0; | |
} | |
-static char *readuntil(char **src, int delim) | |
-{ | |
- struct sbuf *sbuf = sbuf_make(); | |
- char *s = *src; | |
- /* reading the pattern */ | |
- while (*s && *s != delim) { | |
- if (s[0] == '\\' && s[1]) | |
- sbuf_chr(sbuf, (unsigned char) *s++); | |
- sbuf_chr(sbuf, (unsigned char) *s++); | |
- } | |
- if (*s) /* skipping the delimiter */ | |
- s++; | |
- *src = s; | |
- return sbuf_done(sbuf); | |
-} | |
- | |
static int ec_substitute(char *ec) | |
{ | |
char loc[EXLEN]; | |
t@@ -652,15 +636,14 @@ static int ec_substitute(char *ec) | |
char *pats[1]; | |
char *pat, *rep; | |
char *s; | |
- int delim; | |
int i; | |
ex_loc(ec, loc); | |
if (ex_region(loc, &beg, &end)) | |
return 1; | |
s = ex_argeol(ec); | |
- delim = (unsigned char) *s++; | |
- pat = readuntil(&s, delim); | |
- rep = readuntil(&s, delim); | |
+ pat = re_read(&s); | |
+ s--; | |
+ rep = re_read(&s); | |
if (pat[0]) | |
snprintf(xfindkwd, sizeof(xfindkwd), "%s", pat); | |
free(pat); | |
t@@ -751,7 +734,6 @@ static int ec_glob(char *ec) | |
int beg, end, not; | |
char *pats[1]; | |
char *pat, *s; | |
- int delim; | |
int i; | |
ex_cmd(ec, cmd); | |
ex_loc(ec, loc); | |
t@@ -759,8 +741,7 @@ static int ec_glob(char *ec) | |
return 1; | |
not = strchr(cmd, '!') || cmd[0] == 'v'; | |
s = ex_argeol(ec); | |
- delim = (unsigned char) *s++; | |
- pat = readuntil(&s, delim); | |
+ pat = re_read(&s); | |
if (pat[0]) | |
snprintf(xfindkwd, sizeof(xfindkwd), "%s", pat); | |
free(pat); | |
diff --git a/rset.c b/rset.c | |
t@@ -117,3 +117,21 @@ void rset_free(struct rset *rs) | |
free(rs->grp); | |
free(rs); | |
} | |
+ | |
+/* read a regular expression enclosed in a delimiter */ | |
+char *re_read(char **src) | |
+{ | |
+ struct sbuf *sbuf = sbuf_make(); | |
+ char *s = *src; | |
+ int delim = (unsigned char) *s++; | |
+ if (!delim) | |
+ return NULL; | |
+ while (*s && *s != delim) { | |
+ if (s[0] == '\\' && s[1]) | |
+ if (*(++s) != delim) | |
+ sbuf_chr(sbuf, '\\'); | |
+ sbuf_chr(sbuf, (unsigned char) *s++); | |
+ } | |
+ *src = *s ? s + 1 : s; | |
+ return sbuf_done(sbuf); | |
+} | |
diff --git a/vi.c b/vi.c | |
t@@ -20,6 +20,7 @@ static int vi_ybuf; /* current yank buffer */ | |
static int vi_pcol; /* the column requested by | command */ | |
static int vi_printed; /* ex_print() calls since the last comma… | |
static int vi_scroll; /* scroll amount for ^f and ^d*/ | |
+static int vi_soset, vi_so; /* search offset; 1 in "/kw/1" */ | |
static void vi_wait(void) | |
{ | |
t@@ -213,20 +214,29 @@ static int vi_search(int cmd, int cnt, int *row, int *of… | |
int failed = 0; | |
int len = 0; | |
int i, dir; | |
- char *soff = ""; | |
if (cmd == '/' || cmd == '?') { | |
char sign[4] = {cmd}; | |
+ struct sbuf *sb; | |
char *kw = vi_prompt(sign, ex_kmap()); | |
+ char *re; | |
if (!kw) | |
return 1; | |
- xfinddir = cmd == '/' ? +1 : -1; | |
- if (kw[0]) | |
- snprintf(xfindkwd, sizeof(xfindkwd), "%s", kw); | |
- if (strchr(xfindkwd, cmd)) { | |
- soff = strchr(xfindkwd, cmd) + 1; | |
- *strchr(xfindkwd, cmd) = '\0'; | |
- } | |
+ sb = sbuf_make(); | |
+ sbuf_chr(sb, cmd); | |
+ sbuf_str(sb, kw); | |
free(kw); | |
+ kw = sbuf_buf(sb); | |
+ if ((re = re_read(&kw))) { | |
+ xfinddir = cmd == '/' ? +1 : -1; | |
+ if (re[0]) | |
+ snprintf(xfindkwd, sizeof(xfindkwd), "%s", re); | |
+ while (isspace(*kw)) | |
+ kw++; | |
+ vi_soset = !!kw[0]; | |
+ vi_so = atoi(kw); | |
+ free(re); | |
+ } | |
+ sbuf_free(sb); | |
} | |
dir = cmd == 'N' ? -xfinddir : xfinddir; | |
if (!xfindkwd[0] || !lbuf_len(xb)) | |
t@@ -243,14 +253,12 @@ static int vi_search(int cmd, int cnt, int *row, int *of… | |
if (!failed) { | |
*row = r; | |
*off = o; | |
- while (soff[0] && isspace((unsigned char) soff[0])) | |
- soff++; | |
- if (soff[0]) { | |
+ if (vi_soset) { | |
*off = -1; | |
- if (*row + atoi(soff) < 0 || *row + atoi(soff) >= lbuf… | |
+ if (*row + vi_so < 0 || *row + vi_so >= lbuf_len(xb)) | |
failed = 1; | |
else | |
- *row += atoi(soff); | |
+ *row += vi_so; | |
} | |
} | |
if (failed) | |
diff --git a/vi.h b/vi.h | |
t@@ -51,6 +51,7 @@ void sbuf_cut(struct sbuf *s, int len); | |
struct rset *rset_make(int n, char **pat, int flg); | |
int rset_find(struct rset *re, char *s, int n, int *grps, int flg); | |
void rset_free(struct rset *re); | |
+char *re_read(char **src); | |
/* rendering lines */ | |
int *ren_position(char *s); |