summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2021-01-15 15:42:56 -0500
committerJune McEnroe <june@causal.agency>2021-01-15 15:43:57 -0500
commitd38e6c5ec0bea10965b978ecc1fa9f792702c395 (patch)
treee62a17e7e97262dbfa233ac2df7a6a10a70dd1b7
parentUse a temp directory in source-filter to preserve name (diff)
downloadsrc-d38e6c5ec0bea10965b978ecc1fa9f792702c395.tar.gz
src-d38e6c5ec0bea10965b978ecc1fa9f792702c395.zip
Automatically pipe hilex ANSI output to PAGER
-rw-r--r--bin/hilex.c40
-rw-r--r--bin/man1/hilex.117
2 files changed, 55 insertions, 2 deletions
diff --git a/bin/hilex.c b/bin/hilex.c
index 58a2ad30..5bf7e9a6 100644
--- a/bin/hilex.c
+++ b/bin/hilex.c
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/wait.h>
 #include <sysexits.h>
 #include <unistd.h>
 
@@ -94,6 +95,43 @@ enum Option {
 typedef void Header(const char *opts[]);
 typedef void Output(const char *opts[], enum Class class, const char *text);
 
+static bool tty;
+static void ansiHeader(const char *opts[]) {
+	(void)opts;
+	if (!(tty = isatty(STDOUT_FILENO))) return;
+	const char *shell = getenv("SHELL");
+	const char *pager = getenv("PAGER");
+	if (!shell) shell = "/bin/sh";
+	if (!pager) pager = "less";
+	setenv("LESS", "FRX", 0);
+
+	int rw[2];
+	int error = pipe(rw);
+	if (error) err(EX_OSERR, "pipe");
+
+	pid_t pid = fork();
+	if (pid < 0) err(EX_OSERR, "fork");
+	if (!pid) {
+		dup2(rw[0], STDIN_FILENO);
+		close(rw[0]);
+		close(rw[1]);
+		execl(shell, shell, "-c", pager, NULL);
+		err(EX_CONFIG, "%s", shell);
+	}
+	dup2(rw[1], STDOUT_FILENO);
+	close(rw[0]);
+	close(rw[1]);
+	setlinebuf(stdout);
+}
+
+static void ansiFooter(const char *opts[]) {
+	(void)opts;
+	if (!tty) return;
+	int status;
+	fclose(stdout);
+	wait(&status);
+}
+
 static const char *SGR[ClassCap] = {
 	[Keyword] = "37",
 	[Macro]   = "32",
@@ -250,7 +288,7 @@ static const struct Formatter {
 	Output *format;
 	Header *footer;
 } Formatters[] = {
-	{ "ansi", NULL, ansiFormat, NULL },
+	{ "ansi", ansiHeader, ansiFormat, ansiFooter },
 	{ "debug", NULL, debugFormat, NULL },
 	{ "html", htmlHeader, htmlFormat, htmlFooter },
 	{ "irc", ircHeader, ircFormat, NULL },
diff --git a/bin/man1/hilex.1 b/bin/man1/hilex.1
index b742b063..ace0b8cf 100644
--- a/bin/man1/hilex.1
+++ b/bin/man1/hilex.1
@@ -1,4 +1,4 @@
-.Dd January 13, 2021
+.Dd January 15, 2021
 .Dt HILEX 1
 .Os
 .
@@ -64,6 +64,12 @@ input lexer if one cannot be inferred.
 .Bl -tag -width Ds
 .It Cm ansi
 Output ANSI terminal control sequences.
+If standard output is a terminal,
+output is piped to
+.Ev PAGER
+with
+.Ev LESS=FRX
+if it is not already set.
 .
 .It Cm html
 Output HTML
@@ -181,3 +187,12 @@ Inferred for
 .Pa *.txt
 files.
 .El
+.
+.Sh ENVIRONMENT
+.Bl -tag -width "PAGER"
+.It Ev PAGER
+The command to pipe ANSI output to
+if standard output is a terminal.
+The default is
+.Ev PAGER=less .
+.El