tex: ! command - neatvi - [fork] simple vi-type editor with UTF-8 support
 (HTM) git clone git://src.adamsgaard.dk/neatvi
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
 (DIR) commit 7c82b9f9d2c4c6196b90f7679d255d903e639ccc
 (DIR) parent b597ca3b8a3bbcc866143c6a90a75c178493445d
 (HTM) Author: Ali Gholami Rudi <ali@rudi.ir>
       Date:   Fri,  5 Jun 2015 16:01:28 +0430
       
       ex: ! command
       
       Diffstat:
         M cmd.c                               |      32 ++++++++++++++++++++++++++++++-
         M ex.c                                |      22 ++++++++++++++++++++--
         M vi.h                                |       1 +
       
       3 files changed, 52 insertions(+), 3 deletions(-)
       ---
 (DIR) diff --git a/cmd.c b/cmd.c
       t@@ -1,4 +1,5 @@
        #include <poll.h>
       +#include <signal.h>
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
       t@@ -52,7 +53,7 @@ static int cmd_make(char **argv, int *ifd, int *ofd)
        char *cmd_pipe(char *cmd, char *s)
        {
                char *argv[] = {"/bin/sh", "-c", cmd, NULL};
       -        struct pollfd fds[2];
       +        struct pollfd fds[3];
                struct sbuf *sb;
                char buf[512];
                int ifd = 0, ofd = 0;
       t@@ -66,6 +67,8 @@ char *cmd_pipe(char *cmd, char *s)
                fds[0].events = POLLIN;
                fds[1].fd = ifd;
                fds[1].events = POLLOUT;
       +        fds[2].fd = 0;
       +        fds[2].events = POLLIN;
                while ((fds[0].fd >= 0 || fds[1].fd >= 0) && poll(fds, 3, 200) >= 0) {
                        if (fds[0].revents & POLLIN) {
                                int ret = read(fds[0].fd, buf, sizeof(buf));
       t@@ -85,7 +88,34 @@ char *cmd_pipe(char *cmd, char *s)
                        } else if (fds[1].revents & (POLLERR | POLLHUP | POLLNVAL)) {
                                fds[1].fd = -1;
                        }
       +                if (fds[2].revents & POLLIN) {
       +                        int ret = read(fds[2].fd, buf, sizeof(buf));
       +                        int i;
       +                        for (i = 0; i < ret; i++)
       +                                if ((unsigned char) buf[i] == TK_CTL('c'))
       +                                        kill(pid, SIGINT);
       +                } else if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) {
       +                        fds[2].fd = -1;
       +                }
                }
       +        close(ifd);
       +        close(ofd);
                waitpid(pid, NULL, 0);
                return sbuf_done(sb);
        }
       +
       +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();
       +        return 0;
       +}
 (DIR) diff --git a/ex.c b/ex.c
       t@@ -30,7 +30,7 @@ static char *ex_loc(char *s, char *loc)
        {
                while (*s == ':' || isspace((unsigned char) *s))
                        s++;
       -        while (*s && !isalpha((unsigned char) *s) && *s != '=') {
       +        while (*s && !isalpha((unsigned char) *s) && *s != '=' && *s != '!') {
                        if (*s == '\'')
                                *loc++ = *s++;
                        if (*s == '/' || *s == '?') {
       t@@ -55,9 +55,11 @@ static char *ex_cmd(char *s, char *cmd)
                s = ex_loc(s, cmd);
                while (isspace((unsigned char) *s))
                        s++;
       -        while (isalpha((unsigned char) *s) || *s == '=' || *s == '!')
       +        while (isalpha((unsigned char) *s))
                        if ((*cmd++ = *s++) == 'k' && cmd == cmd0 + 1)
                                break;
       +        if (*s == '!' || *s == '=')
       +                *cmd++ = *s++;
                *cmd = '\0';
                return s;
        }
       t@@ -494,6 +496,20 @@ static int ec_substitute(char *ec)
                return 0;
        }
        
       +static int ec_exec(char *ec)
       +{
       +        char cmd[EXLEN];
       +        return cmd_exec(ex_cmd(ec, cmd));
       +}
       +
       +static int ec_make(char *ec)
       +{
       +        char cmd[EXLEN];
       +        char make[EXLEN];
       +        sprintf(make, "make %s", ex_cmd(ec, cmd));
       +        return cmd_exec(make);
       +}
       +
        static struct option {
                char *abbr;
                char *name;
       t@@ -582,6 +598,8 @@ static struct excmd {
                {"se", "set", ec_set},
                {"s", "substitute", ec_substitute},
                {"ya", "yank", ec_yank},
       +        {"!", "!", ec_exec},
       +        {"make", "make", ec_make},
                {"", "", ec_print},
        };
        
 (DIR) diff --git a/vi.h b/vi.h
       t@@ -138,6 +138,7 @@ void ex_show(char *msg);
        
        /* process management */
        char *cmd_pipe(char *cmd, char *s);
       +int cmd_exec(char *cmd);
        
        /* syntax highlighting */
        #define SYN_BD                0x100