ref: f2f73e37b78000a2a8e3f33a301e82f60b801284
parent: 36eb12125b97b4a1ab153e4a8f94dd83ed1f7eb5
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Tue Feb 18 17:32:32 EST 2020
plan9: piping through shell commands
--- a/plan9.c
+++ b/plan9.c
@@ -189,12 +189,101 @@
return false;
}
+static Glyph
+fieldget(int x, int y)
+{
+ if (x < field.width && y < field.height && x >= 0 && y >= 0)
+ return field.buffer[x + field.width*y];
+
+ return 0;
+}
+
static void
+selpasteb(Biobuf *b)
+{
+ char *s;
+ int cols, rows, i, n;
+
+ for (cols = rows = 0; (s = Brdstr(b, '\n', 1)) != nil;) {
+ if ((n = Blinelen(b)) > cols)
+ cols = MIN(n, field.width-sel.min.x);
+ if (sel.min.y+rows < field.height) {
+ for (i = 0; i < n; i++)
+ if (s[i] == ' ')
+ s[i] = '.';
+ memmove(&field.buffer[sel.min.x + field.width*(sel.min.y+rows)], s, MIN(n, field.width-sel.min.x));
+ rows++;
+ }
+ free(s);
+ }
+ sel.max.x = sel.min.x + MAX(0, cols-1);
+ sel.max.y = sel.min.y + MAX(0, rows-1);
+ if (sel.max.x < cur.x)
+ cur.x = sel.max.x;
+ if (sel.max.y < cur.y)
+ cur.y = sel.max.y;
+}
+
+static char *shellcmd;
+
+static void
+runshell(void *x)
+{
+ int *p;
+
+ p = x;
+ dup(p[0], 0); close(p[0]); close(p[1]);
+ dup(p[3], 1); close(p[3]); close(p[2]);
+ dup(open("/dev/null", OWRITE), 2);
+ procexecl(nil, "/bin/rc", "rc", "-c", shellcmd, nil);
+ threadexits("exec: %r");
+}
+
+static void
+shellpipe(char *s)
+{
+ Biobuf *in, *out;
+ int x, y, p[4];
+ Glyph g;
+
+ shellcmd = s;
+ pipe(p);
+ pipe(p+2);
+ procrfork(runshell, p, 4096, RFFDG);
+ close(p[0]);
+ close(p[3]);
+ out = Bfdopen(p[1], OWRITE);
+ in = Bfdopen(p[2], OREAD);
+ for (y = sel.min.y; y <= sel.max.y; y++) {
+ for (x = sel.min.x; x <= sel.max.x; x++) {
+ if ((g = fieldget(x, y)) == '.')
+ g = ' ';
+ Bputc(out, g);
+ }
+ Bputc(out, '\n');
+ }
+ Bterm(out);
+ selpasteb(in);
+ Bterm(in);
+}
+
+static void
command(char *s)
{
char *a;
int x;
+ if (s[0] == ',') {
+ cur = ZP;
+ sel = Rect(0, 0, field.width, field.height);
+ s++;
+ }
+
+ if (s[0] == '|') {
+ shellpipe(s+1);
+ return;
+ }
+
if ((a = strchr(s, ':')) != nil)
*a++ = 0;
@@ -578,15 +667,6 @@
}
}
-static Glyph
-fieldget(int x, int y)
-{
- if (x < field.width && y < field.height && x >= 0 && y >= 0)
- return field.buffer[x + field.width*y];
-
- return 0;
-}
-
static void
selset(Rune key)
{
@@ -632,27 +712,9 @@
selpaste(void)
{
Biobuf *b;
- char *s;
- int cols, rows, n;
- if ((b = Bopen("/dev/snarf", OREAD)) != nil) {
- for (cols = rows = 0; (s = Brdstr(b, '\n', 1)) != nil;) {
- if ((n = Blinelen(b)) > cols)
- cols = MIN(n, field.width-sel.min.x);
- if (sel.min.y+rows < field.height) {
- memmove(&field.buffer[sel.min.x + field.width*(sel.min.y+rows)], s, MIN(n, field.width-sel.min.x));
- rows++;
- }
- free(s);
- }
- sel.max.x = sel.min.x + MAX(0, cols-1);
- sel.max.y = sel.min.y + MAX(0, rows-1);
- if (sel.max.x < cur.x)
- cur.x = sel.max.x;
- if (sel.max.y < cur.y)
- cur.y = sel.max.y;
- Bterm(b);
- }
+ if ((b = Bopen("/dev/snarf", OREAD)) != nil)
+ selpasteb(b);
}
static Point