tex: reading from and writing to commands - neatvi - [fork] simple vi-type edit… | |
git clone git://src.adamsgaard.dk/neatvi | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit 0225a76aa55a2d0dae9ac2a6d98f9c19de3b52c2 | |
parent 1a71c8b9dd2cf614712d7ebdab0c8a8f0f624a22 | |
Author: Ali Gholami Rudi <[email protected]> | |
Date: Tue, 16 Jun 2015 10:01:19 +0430 | |
ex: reading from and writing to commands | |
":r !cmd" and ":w !cmd". | |
Diffstat: | |
M cmd.c | 42 ++++++++++++++++-------------… | |
M ex.c | 81 +++++++++++++++++++++--------… | |
M vi.c | 31 +++++++++++++++++++++++++++++… | |
M vi.h | 3 ++- | |
4 files changed, 110 insertions(+), 47 deletions(-) | |
--- | |
diff --git a/cmd.c b/cmd.c | |
t@@ -50,24 +50,30 @@ static int cmd_make(char **argv, int *ifd, int *ofd) | |
return pid; | |
} | |
-char *cmd_pipe(char *cmd, char *s) | |
+/* execute a command; process input if iproc and process output if oproc */ | |
+char *cmd_pipe(char *cmd, char *ibuf, int iproc, int oproc) | |
{ | |
char *argv[] = {"/bin/sh", "-c", cmd, NULL}; | |
struct pollfd fds[3]; | |
- struct sbuf *sb; | |
+ struct sbuf *sb = NULL; | |
char buf[512]; | |
- int ifd = 0, ofd = 0; | |
- int slen = strlen(s); | |
+ int ifd = -1, ofd = -1; | |
+ int slen = iproc ? strlen(ibuf) : 0; | |
int nw = 0; | |
- int pid = cmd_make(argv, &ifd, &ofd); | |
+ int pid = cmd_make(argv, iproc ? &ifd : NULL, oproc ? &ofd : NULL); | |
if (pid <= 0) | |
return NULL; | |
- sb = sbuf_make(); | |
+ if (oproc) | |
+ sb = sbuf_make(); | |
+ if (!iproc) { | |
+ signal(SIGINT, SIG_IGN); | |
+ term_done(); | |
+ } | |
fds[0].fd = ofd; | |
fds[0].events = POLLIN; | |
fds[1].fd = ifd; | |
fds[1].events = POLLOUT; | |
- fds[2].fd = 0; | |
+ fds[2].fd = iproc ? 0 : -1; | |
fds[2].events = POLLIN; | |
while ((fds[0].fd >= 0 || fds[1].fd >= 0) && poll(fds, 3, 200) >= 0) { | |
if (fds[0].revents & POLLIN) { | |
t@@ -80,7 +86,7 @@ char *cmd_pipe(char *cmd, char *s) | |
fds[0].fd = -1; | |
} | |
if (fds[1].revents & POLLOUT) { | |
- int ret = write(fds[1].fd, s + nw, slen - nw); | |
+ int ret = write(fds[1].fd, ibuf + nw, slen - nw); | |
if (ret > 0) | |
nw += ret; | |
if (ret <= 0 || nw == slen) | |
t@@ -101,21 +107,17 @@ char *cmd_pipe(char *cmd, char *s) | |
close(ifd); | |
close(ofd); | |
waitpid(pid, NULL, 0); | |
- return sbuf_done(sb); | |
+ if (!iproc) { | |
+ term_init(); | |
+ signal(SIGINT, SIG_DFL); | |
+ } | |
+ if (oproc) | |
+ return sbuf_done(sb); | |
+ return NULL; | |
} | |
int cmd_exec(char *cmd) | |
{ | |
- char *argv[] = {"/bin/sh", "-c", cmd, NULL}; | |
- int pid = cmd_make(argv, NULL, NULL); | |
- if (pid <= 0) | |
- return 1; | |
- signal(SIGINT, SIG_IGN); | |
- term_done(); | |
- printf("\n"); | |
- waitpid(pid, NULL, 0); | |
- printf("[terminated]\n"); | |
- getchar(); | |
- term_init(); | |
+ cmd_pipe(cmd, NULL, 0, 0); | |
return 0; | |
} | |
diff --git a/ex.c b/ex.c | |
t@@ -143,6 +143,15 @@ static char *ex_arg(char *s, char *arg) | |
return s; | |
} | |
+static char *ex_argeol(char *ec) | |
+{ | |
+ char arg[EXLEN]; | |
+ char *s = ex_cmd(ec, arg); | |
+ while (isspace((unsigned char) *s)) | |
+ s++; | |
+ return s; | |
+} | |
+ | |
static int ex_search(char *pat) | |
{ | |
struct sbuf *kw; | |
t@@ -324,23 +333,32 @@ static int ec_read(char *ec) | |
{ | |
char arg[EXLEN], loc[EXLEN]; | |
char msg[128]; | |
- char *path; | |
- int fd; | |
int beg, end; | |
+ char *path; | |
+ char *obuf; | |
int n = lbuf_len(xb); | |
ex_arg(ec, arg); | |
ex_loc(ec, loc); | |
path = arg[0] ? arg : ex_path(); | |
- fd = open(path, O_RDONLY); | |
- if (fd < 0) { | |
- ex_show("read failed\n"); | |
- return 1; | |
- } | |
if (ex_region(loc, &beg, &end)) | |
return 1; | |
- lbuf_rd(xb, fd, lbuf_len(xb) ? end : 0); | |
- close(fd); | |
- xrow = end + lbuf_len(xb) - n; | |
+ if (arg[0] == '!') { | |
+ if (ex_expand(arg, ex_argeol(ec))) | |
+ return 1; | |
+ obuf = cmd_pipe(arg + 1, NULL, 0, 1); | |
+ if (obuf) | |
+ lbuf_put(xb, MIN(xrow + 1, lbuf_len(xb)), obuf); | |
+ free(obuf); | |
+ } else { | |
+ int fd = open(path, O_RDONLY); | |
+ if (fd < 0) { | |
+ ex_show("read failed\n"); | |
+ return 1; | |
+ } | |
+ lbuf_rd(xb, fd, lbuf_len(xb) ? end : 0); | |
+ close(fd); | |
+ } | |
+ xrow = end + lbuf_len(xb) - n - 1; | |
snprintf(msg, sizeof(msg), "\"%s\" %d lines [r]\n", | |
path, lbuf_len(xb) - n); | |
ex_show(msg); | |
t@@ -352,8 +370,8 @@ static int ec_write(char *ec) | |
char cmd[EXLEN], arg[EXLEN], loc[EXLEN]; | |
char msg[128]; | |
char *path; | |
+ char *ibuf; | |
int beg, end; | |
- int fd; | |
ex_cmd(ec, cmd); | |
ex_arg(ec, arg); | |
ex_loc(ec, loc); | |
t@@ -364,13 +382,22 @@ static int ec_write(char *ec) | |
beg = 0; | |
end = lbuf_len(xb); | |
} | |
- fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600); | |
- if (fd < 0) { | |
- ex_show("write failed\n"); | |
- return 1; | |
+ if (arg[0] == '!') { | |
+ if (ex_expand(arg, ex_argeol(ec))) | |
+ return 1; | |
+ ibuf = lbuf_cp(xb, beg, end); | |
+ ex_print(NULL); | |
+ cmd_pipe(arg + 1, ibuf, 1, 0); | |
+ free(ibuf); | |
+ } else { | |
+ int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600); | |
+ if (fd < 0) { | |
+ ex_show("write failed\n"); | |
+ return 1; | |
+ } | |
+ lbuf_wr(xb, fd, beg, end); | |
+ close(fd); | |
} | |
- lbuf_wr(xb, fd, beg, end); | |
- close(fd); | |
snprintf(msg, sizeof(msg), "\"%s\" %d lines [w]\n", | |
path, end - beg); | |
ex_show(msg); | |
t@@ -437,7 +464,7 @@ static int ec_print(char *ec) | |
if (ex_region(loc, &beg, &end)) | |
return 1; | |
for (i = beg; i < end; i++) | |
- ex_show(lbuf_get(xb, i)); | |
+ ex_print(lbuf_get(xb, i)); | |
xrow = end; | |
return 0; | |
} | |
t@@ -504,7 +531,7 @@ static int ec_lnum(char *ec) | |
if (ex_region(loc, &beg, &end)) | |
return 1; | |
sprintf(msg, "%d\n", end); | |
- ex_show(msg); | |
+ ex_print(msg); | |
return 0; | |
} | |
t@@ -589,24 +616,28 @@ static int ec_substitute(char *ec) | |
static int ec_exec(char *ec) | |
{ | |
- char cmd[EXLEN]; | |
char arg[EXLEN]; | |
ex_modifiedbuffer(NULL); | |
- if (ex_expand(arg, ex_cmd(ec, cmd))) | |
+ if (ex_expand(arg, ex_argeol(ec))) | |
return 1; | |
- return cmd_exec(arg); | |
+ ex_print(NULL); | |
+ if (cmd_exec(arg)) | |
+ return 1; | |
+ return 0; | |
} | |
static int ec_make(char *ec) | |
{ | |
- char cmd[EXLEN]; | |
char arg[EXLEN]; | |
char make[EXLEN]; | |
ex_modifiedbuffer(NULL); | |
- if (ex_expand(arg, ex_cmd(ec, cmd))) | |
+ if (ex_expand(arg, ex_argeol(ec))) | |
return 1; | |
sprintf(make, "make %s", arg); | |
- return cmd_exec(make); | |
+ ex_print(NULL); | |
+ if (cmd_exec(make)) | |
+ return 1; | |
+ return 0; | |
} | |
static struct option { | |
diff --git a/vi.c b/vi.c | |
t@@ -21,6 +21,16 @@ static int vi_arg1, vi_arg2; /* the first and second… | |
static int vi_ybuf; /* current yank buffer */ | |
static char *vi_kmap; /* current insertion keymap */ | |
static int vi_pcol; /* the column requested by | command */ | |
+static int vi_printed; /* ex_print() calls since the last comma… | |
+ | |
+static void vi_wait(void) | |
+{ | |
+ if (vi_printed > 1) { | |
+ free(ex_read("[enter to continue]")); | |
+ vi_msg[0] = '\0'; | |
+ } | |
+ vi_printed = 0; | |
+} | |
static void vi_drawmsg(void) | |
{ | |
t@@ -77,6 +87,7 @@ static char *vi_prompt(char *msg, char **kmap) | |
return led_prompt(msg, "", kmap); | |
} | |
+/* read an ex input line */ | |
char *ex_read(char *msg) | |
{ | |
struct sbuf *sb; | |
t@@ -97,6 +108,7 @@ char *ex_read(char *msg) | |
return sbuf_done(sb); | |
} | |
+/* show an ex message */ | |
void ex_show(char *msg) | |
{ | |
if (xvis) { | |
t@@ -109,6 +121,22 @@ void ex_show(char *msg) | |
} | |
} | |
+/* print an ex output line */ | |
+void ex_print(char *line) | |
+{ | |
+ if (xvis) { | |
+ vi_printed += line ? 1 : 2; | |
+ if (line) | |
+ snprintf(vi_msg, sizeof(vi_msg), "%s", line); | |
+ if (line) | |
+ led_print(line, -1); | |
+ term_chr('\n'); | |
+ } else { | |
+ if (line) | |
+ ex_show(line); | |
+ } | |
+} | |
+ | |
static int vi_yankbuf(void) | |
{ | |
int c = vi_read(); | |
t@@ -680,7 +708,7 @@ static void vi_pipe(int r1, int r2) | |
if (!cmd) | |
return; | |
text = lbuf_cp(xb, r1, r2 + 1); | |
- rep = cmd_pipe(cmd, text); | |
+ rep = cmd_pipe(cmd, text, 1, 1); | |
if (rep) { | |
lbuf_rm(xb, r1, r2 + 1); | |
lbuf_put(xb, r1, rep); | |
t@@ -1210,6 +1238,7 @@ static void vi(void) | |
xoff = ren_noeol(lbuf_get(xb, xrow), xoff); | |
if (redraw) | |
xcol = vi_off2col(xb, xrow, xoff); | |
+ vi_wait(); | |
if (redraw || xtop != otop) | |
vi_draw(xcol); | |
if (vi_msg[0]) | |
diff --git a/vi.h b/vi.h | |
t@@ -136,6 +136,7 @@ int led_pos(char *s, int pos); | |
void ex(void); | |
void ex_command(char *cmd); | |
char *ex_read(char *msg); | |
+void ex_print(char *line); | |
void ex_show(char *msg); | |
void ex_init(char **files); | |
void ex_done(void); | |
t@@ -146,7 +147,7 @@ struct lbuf *ex_lbuf(void); | |
#define xb ex_lbuf() | |
/* process management */ | |
-char *cmd_pipe(char *cmd, char *s); | |
+char *cmd_pipe(char *cmd, char *s, int iproc, int oproc); | |
int cmd_exec(char *cmd); | |
/* syntax highlighting */ |