tex: reading from and writing to commands - neatvi - [fork] simple vi-type editor with UTF-8 support
git clone git://src.adamsgaard.dk/neatvi
Log
Files
Refs
README
---
commit 0225a76aa55a2d0dae9ac2a6d98f9c19de3b52c2
parent 1a71c8b9dd2cf614712d7ebdab0c8a8f0f624a22
Author: Ali Gholami Rudi 
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 arguments */
 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 command */
+
+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 */