Introduction
Introduction Statistics Contact Development Disclaimer Help
tcmd: execute shell commands - neatvi - [fork] simple vi-type editor with UTF-8…
git clone git://src.adamsgaard.dk/neatvi
Log
Files
Refs
README
---
commit 58191346a45866137a12738b1b82b31f40a673aa
parent 6e9f030b017fe128151501d6c0bad0c6e72a8c73
Author: Ali Gholami Rudi <[email protected]>
Date: Fri, 15 May 2015 14:20:23 +0430
cmd: execute shell commands
Diffstat:
M Makefile | 2 +-
A cmd.c | 91 +++++++++++++++++++++++++++++…
M vi.c | 42 +++++++++++++++++++++++++----…
M vi.h | 3 +++
4 files changed, 129 insertions(+), 9 deletions(-)
---
diff --git a/Makefile b/Makefile
t@@ -2,7 +2,7 @@ CC = cc
CFLAGS = -Wall -O2
LDFLAGS =
-OBJS = vi.o ex.o lbuf.o sbuf.o ren.o dir.o reg.o led.o uc.o term.o rset.o
+OBJS = vi.o ex.o lbuf.o sbuf.o ren.o dir.o reg.o led.o uc.o term.o rset.o cmd.o
all: vi
%.o: %.c
diff --git a/cmd.c b/cmd.c
t@@ -0,0 +1,91 @@
+#include <poll.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include "vi.h"
+
+static int cmd_make(char **argv, int *ifd, int *ofd)
+{
+ int pid;
+ int pipefds0[2];
+ int pipefds1[2];
+ if (ifd)
+ pipe(pipefds0);
+ if (ofd)
+ pipe(pipefds1);
+ if (!(pid = fork())) {
+ if (ifd) { /* setting up stdin */
+ close(0);
+ dup(pipefds0[0]);
+ close(pipefds0[1]);
+ close(pipefds0[0]);
+ }
+ if (ofd) { /* setting up stdout */
+ close(1);
+ dup(pipefds1[1]);
+ close(pipefds1[0]);
+ close(pipefds1[1]);
+ }
+ execvp(argv[0], argv);
+ exit(1);
+ }
+ if (ifd)
+ close(pipefds0[0]);
+ if (ofd)
+ close(pipefds1[1]);
+ if (pid < 0) {
+ if (ifd)
+ close(pipefds0[1]);
+ if (ofd)
+ close(pipefds1[0]);
+ return -1;
+ }
+ if (ifd)
+ *ifd = pipefds0[1];
+ if (ofd)
+ *ofd = pipefds1[0];
+ return pid;
+}
+
+char *cmd_pipe(char *cmd, char *s)
+{
+ char *argv[] = {"/bin/sh", "-c", cmd, NULL};
+ struct pollfd fds[2];
+ struct sbuf *sb;
+ char buf[512];
+ int ifd = 0, ofd = 0;
+ int slen = strlen(s);
+ int nw = 0;
+ int pid = cmd_make(argv, &ifd, &ofd);
+ if (pid <= 0)
+ return NULL;
+ sb = sbuf_make();
+ fds[0].fd = ofd;
+ fds[0].events = POLLIN;
+ fds[1].fd = ifd;
+ fds[1].events = POLLOUT;
+ 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));
+ if (ret > 0)
+ sbuf_mem(sb, buf, ret);
+ if (ret < 0)
+ close(fds[0].fd);
+ } else if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) {
+ fds[0].fd = -1;
+ }
+ if (fds[1].revents & POLLOUT) {
+ int ret = write(fds[1].fd, s + nw, slen - nw);
+ if (ret > 0)
+ nw += ret;
+ if (ret <= 0 || nw == slen)
+ close(fds[1].fd);
+ } else if (fds[1].revents & (POLLERR | POLLHUP | POLLNVAL)) {
+ fds[1].fd = -1;
+ }
+ }
+ waitpid(pid, NULL, 0);
+ return sbuf_done(sb);
+}
diff --git a/vi.c b/vi.c
t@@ -62,6 +62,13 @@ static char *vi_char(void)
return TK_INT(key) ? NULL : led_keymap(key);
}
+static char *vi_prompt(char *msg)
+{
+ term_pos(xrows, led_pos(msg, 0));
+ term_kill();
+ return led_prompt(msg, "");
+}
+
static int vi_yankbuf(void)
{
int c = vi_read();
t@@ -189,10 +196,8 @@ static int vi_search(int cmd, int cnt, int *row, int *col)
char *off = "";
if (cmd == '/' || cmd == '?') {
char sign[4] = {cmd};
- char *kw;
- term_pos(xrows, led_pos(sign, 0));
- term_kill();
- if (!(kw = led_prompt(sign, "")))
+ char *kw = vi_prompt(sign);
+ if (!kw)
return 1;
vi_finddir = cmd == '/' ? +1 : -1;
if (kw[0])
t@@ -332,7 +337,7 @@ static int vi_motionln(int *row, int cmd)
break;
default:
if (c == cmd) {
- *row = MIN(*row + cnt - 1, lbuf_len(xb) - 1);
+ *row = MAX(0, MIN(*row + cnt - 1, lbuf_len(xb) - 1));
break;
}
vi_back(c);
t@@ -667,6 +672,26 @@ static void vi_change(int r1, int c1, int r2, int c2, int…
free(post);
}
+static void vi_pipe(int r1, int c1, int r2, int c2, int lnmode, int closed)
+{
+ char *text;
+ char *rep;
+ char *cmd = vi_prompt("!");
+ if (!cmd)
+ return;
+ if (r2 < r1)
+ swap(&r1, &r2);
+ text = lbuf_cp(xb, r1, r2 + 1);
+ rep = cmd_pipe(cmd, text);
+ if (rep) {
+ lbuf_rm(xb, r1, r2 + 1);
+ lbuf_put(xb, r1, rep);
+ }
+ free(cmd);
+ free(text);
+ free(rep);
+}
+
static int vc_motion(int cmd)
{
int r1 = xrow, r2 = xrow; /* region rows */
t@@ -698,6 +723,8 @@ static int vc_motion(int cmd)
vi_delete(r1, c1, r2, c2, lnmode, closed);
if (cmd == 'c')
vi_change(r1, c1, r2, c2, lnmode, closed);
+ if (cmd == '!')
+ vi_pipe(r1, c1, r2, c2, lnmode, closed);
return 0;
}
t@@ -950,9 +977,7 @@ static void vi(void)
redraw = 1;
break;
case ':':
- term_pos(xrows, led_pos(":", 0));
- term_kill();
- ln = led_prompt(":", "");
+ ln = vi_prompt(":");
if (ln && ln[0]) {
ex_command(ln);
redraw = 1;
t@@ -964,6 +989,7 @@ static void vi(void)
case 'c':
case 'd':
case 'y':
+ case '!':
if (!vc_motion(c))
redraw = 1;
break;
diff --git a/vi.h b/vi.h
t@@ -119,6 +119,9 @@ int led_pos(char *s, int pos);
void ex(void);
void ex_command(char *cmd);
+/* process management */
+char *cmd_pipe(char *cmd, char *s);
+
/* global variables */
extern int xvis;
extern struct lbuf *xb;
You are viewing proxied material from mx1.adamsgaard.dk. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.