tex: mark the region before executing glob commands - neatvi - [fork] simple vi… | |
git clone git://src.adamsgaard.dk/neatvi | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit 57077e595860fb487d95316fc8dfc41df965342f | |
parent d3b961346505dc8b1be900ce63a5a593f2ff9895 | |
Author: Ali Gholami Rudi <[email protected]> | |
Date: Thu, 30 Jun 2016 10:52:06 +0430 | |
ex: mark the region before executing glob commands | |
Diffstat: | |
M ex.c | 45 ++++++++++++++++++++---------… | |
M lbuf.c | 85 ++++++++++++++++++-----------… | |
M vi.h | 1 + | |
3 files changed, 79 insertions(+), 52 deletions(-) | |
--- | |
diff --git a/ex.c b/ex.c | |
t@@ -185,14 +185,6 @@ static char *ex_argeol(char *ec) | |
return s; | |
} | |
-static char *ex_line(char *s, char *ln) | |
-{ | |
- while (*s && *s != '|' && *s != '\n') | |
- *ln++ = *s++; | |
- *ln = '\0'; | |
- return *s ? s + 1 : s; | |
-} | |
- | |
/* the previous search keyword */ | |
int ex_kwd(char **kwd, int *dir) | |
{ | |
t@@ -825,18 +817,22 @@ static int ec_glob(char *ec) | |
return 1; | |
if (!(re = rset_make(1, pats, xic ? RE_ICASE : 0))) | |
return 1; | |
+ for (i = beg + 1; i < end; i++) | |
+ lbuf_glob(xb, i, 1); | |
i = beg; | |
- while (i < end) { | |
+ while (i < lbuf_len(xb)) { | |
char *ln = lbuf_get(xb, i); | |
if ((rset_find(re, ln, LEN(offs) / 2, offs, 0) < 0) == not) { | |
- int len = lbuf_len(xb); | |
xrow = i; | |
- ex_exec(s); | |
- i = xrow; | |
- end += lbuf_len(xb) - len; | |
+ if (ex_exec(s)) | |
+ break; | |
+ i = MIN(i, xrow); | |
} | |
- i++; | |
+ while (i < lbuf_len(xb) && !lbuf_glob(xb, i, 0)) | |
+ i++; | |
} | |
+ for (i = 0; i < lbuf_len(xb); i++) | |
+ lbuf_glob(xb, i, 0); | |
rset_free(re); | |
return 0; | |
} | |
t@@ -945,6 +941,21 @@ static struct excmd { | |
{"", "", ec_null}, | |
}; | |
+/* read an ex command and its arguments from src into dst */ | |
+static void ex_line(int (*ec)(char *s), char *dst, char **src) | |
+{ | |
+ if (!ec || ec != ec_glob) { | |
+ while (**src && **src != '|' && **src != '\n') | |
+ *dst++ = *(*src)++; | |
+ *dst = '\0'; | |
+ if (**src) | |
+ (*src)++; | |
+ } else { /* the rest of the line for :g */ | |
+ strcpy(dst, *src); | |
+ *src = strchr(*src, '\0'); | |
+ } | |
+} | |
+ | |
/* execute a single ex command */ | |
static int ex_exec(char *ln) | |
{ | |
t@@ -953,17 +964,19 @@ static int ex_exec(char *ln) | |
int i; | |
int ret = 0; | |
while (*ln) { | |
- ln = ex_line(ln, ec); | |
- ex_cmd(ec, cmd); | |
+ ex_cmd(ln, cmd); | |
for (i = 0; i < LEN(excmds); i++) { | |
if (!strcmp(excmds[i].abbr, cmd) || | |
!strcmp(excmds[i].name, cmd)) { | |
+ ex_line(excmds[i].ec, ec, &ln); | |
ret = excmds[i].ec(ec); | |
break; | |
} | |
} | |
if (!xvis && !cmd[0]) | |
ret = ec_print(ec); | |
+ if (i == LEN(excmds)) | |
+ ex_line(NULL, ec, &ln); | |
} | |
return ret; | |
} | |
diff --git a/lbuf.c b/lbuf.c | |
t@@ -23,6 +23,7 @@ struct lbuf { | |
int mark[NMARKS]; /* mark lines */ | |
int mark_off[NMARKS]; /* mark line offsets */ | |
char **ln; /* buffer lines */ | |
+ char *ln_glob; /* line global mark */ | |
int ln_n; /* number of lines in ln[] */ | |
int ln_sz; /* size of ln[] */ | |
int useq; /* current operation sequence */ | |
t@@ -110,48 +111,61 @@ void lbuf_free(struct lbuf *lb) | |
lopt_done(&lb->hist[i]); | |
free(lb->hist); | |
free(lb->ln); | |
+ free(lb->ln_glob); | |
free(lb); | |
} | |
-/* insert a line at pos */ | |
-static void lbuf_insertline(struct lbuf *lb, int pos, char *s) | |
+static int linelength(char *s) | |
{ | |
- if (lb->ln_n == lb->ln_sz) { | |
+ char *r = strchr(s, '\n'); | |
+ return r ? r - s + 1 : strlen(s); | |
+} | |
+ | |
+static int linecount(char *s) | |
+{ | |
+ int n; | |
+ for (n = 0; s && *s; n++) | |
+ s += linelength(s); | |
+ return n; | |
+} | |
+ | |
+ | |
+/* low-level line replacement */ | |
+static void lbuf_replace(struct lbuf *lb, char *s, int pos, int n_del) | |
+{ | |
+ int n_ins = linecount(s); | |
+ int i; | |
+ while (lb->ln_n + n_ins - n_del >= lb->ln_sz) { | |
int nsz = lb->ln_sz + 512; | |
char **nln = malloc(nsz * sizeof(nln[0])); | |
+ char *nln_glob = malloc(nsz * sizeof(nln_glob[0])); | |
memcpy(nln, lb->ln, lb->ln_n * sizeof(lb->ln[0])); | |
+ memcpy(nln_glob, lb->ln_glob, lb->ln_n * sizeof(lb->ln_glob[0]… | |
free(lb->ln); | |
+ free(lb->ln_glob); | |
lb->ln = nln; | |
+ lb->ln_glob = nln_glob; | |
lb->ln_sz = nsz; | |
} | |
- memmove(lb->ln + pos + 1, lb->ln + pos, | |
- (lb->ln_n - pos) * sizeof(lb->ln[0])); | |
- lb->ln_n++; | |
- lb->ln[pos] = s; | |
-} | |
- | |
-/* low-level replacement */ | |
-static void lbuf_replace(struct lbuf *lb, char *s, int pos, int n_del) | |
-{ | |
- char *r, *n; | |
- int n_ins = 0; | |
- int i; | |
for (i = 0; i < n_del; i++) | |
free(lb->ln[pos + i]); | |
- memmove(lb->ln + pos, lb->ln + pos + n_del, | |
+ memmove(lb->ln + pos + n_ins, lb->ln + pos + n_del, | |
(lb->ln_n - pos - n_del) * sizeof(lb->ln[0])); | |
- lb->ln_n -= n_del; | |
- while (s && *s) { | |
- r = strchr(s, '\n'); | |
- if (!r) /* no eol */ | |
- r = strchr(s, '\0'); | |
- n = malloc(r - s + 2); | |
- memcpy(n, s, r - s); | |
- n[r - s + 0] = '\n'; | |
- n[r - s + 1] = '\0'; | |
- lbuf_insertline(lb, pos + n_ins++, n); | |
- s = *r ? r + 1 : r; | |
+ memmove(lb->ln_glob + pos + n_ins, lb->ln_glob + pos + n_del, | |
+ (lb->ln_n - pos - n_del) * sizeof(lb->ln_glob[0])); | |
+ lb->ln_n += n_ins - n_del; | |
+ for (i = 0; i < n_ins; i++) { | |
+ int l = s ? linelength(s) : 0; | |
+ int l_nonl = l - (s[l - 1] == '\n'); | |
+ char *n = malloc(l_nonl + 2); | |
+ memcpy(n, s, l_nonl); | |
+ n[l_nonl + 0] = '\n'; | |
+ n[l_nonl + 1] = '\0'; | |
+ lb->ln[pos + i] = n; | |
+ s += l; | |
} | |
+ for (i = n_del; i < n_ins; i++) | |
+ lb->ln_glob[pos + i] = 0; | |
for (i = 0; i < LEN(lb->mark); i++) { /* updating marks */ | |
if (!s && lb->mark[i] >= pos && lb->mark[i] < pos + n_del) | |
lb->mark[i] = -1; | |
t@@ -164,14 +178,6 @@ static void lbuf_replace(struct lbuf *lb, char *s, int po… | |
lbuf_mark(lb, ']', pos + (n_ins ? n_ins - 1 : 0), 0); | |
} | |
-static int uc_newlines(char *s) | |
-{ | |
- int n; | |
- for (n = 0; (s = strchr(s, '\n')); n++) | |
- s++; | |
- return n; | |
-} | |
- | |
/* append undo/redo history */ | |
static void lbuf_opt(struct lbuf *lb, char *buf, int pos, int n_del) | |
{ | |
t@@ -195,7 +201,7 @@ static void lbuf_opt(struct lbuf *lb, char *buf, int pos, … | |
lo->pos = pos; | |
lo->n_del = n_del; | |
lo->del = n_del ? lbuf_cp(lb, pos, pos + n_del) : NULL; | |
- lo->n_ins = buf ? uc_newlines(buf) : 0; | |
+ lo->n_ins = buf ? linecount(buf) : 0; | |
lo->ins = buf ? uc_dup(buf) : NULL; | |
lo->seq = lb->useq; | |
lbuf_savepos(lb, lo); | |
t@@ -344,3 +350,10 @@ int lbuf_modified(struct lbuf *lb) | |
lb->useq++; | |
return lbuf_seq(lb) != lb->useq_zero; | |
} | |
+ | |
+int lbuf_glob(struct lbuf *lb, int pos, int v) | |
+{ | |
+ int o = lb->ln_glob[pos]; | |
+ lb->ln_glob[pos] = v; | |
+ return o; | |
+} | |
diff --git a/vi.h b/vi.h | |
t@@ -22,6 +22,7 @@ int lbuf_modified(struct lbuf *lb); | |
void lbuf_saved(struct lbuf *lb, int clear); | |
int lbuf_indents(struct lbuf *lb, int r); | |
int lbuf_eol(struct lbuf *lb, int r); | |
+int lbuf_glob(struct lbuf *lb, int pos, int v); | |
/* motions */ | |
int lbuf_findchar(struct lbuf *lb, char *cs, int cmd, int n, int *r, int *o); | |
int lbuf_search(struct lbuf *lb, char *kw, int dir, int *r, int *o, int *len); |