| 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 */ |