shithub: orca

Download patch

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