tex: ! command - neatvi - [fork] simple vi-type editor with UTF-8 support | |
git clone git://src.adamsgaard.dk/neatvi | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit 7c82b9f9d2c4c6196b90f7679d255d903e639ccc | |
parent b597ca3b8a3bbcc866143c6a90a75c178493445d | |
Author: Ali Gholami Rudi <[email protected]> | |
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(-) | |
--- | |
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; | |
+} | |
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}, | |
}; | |
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 |