summary refs log tree commit diff
path: root/bin
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-02-17 14:38:11 -0500
committerJune McEnroe <june@causal.agency>2019-02-17 14:38:11 -0500
commitbacacf6678168f3b3d0657c4fbbcac0edcb5c799 (patch)
tree1e364bcc3c44422065acbbf4a6b27192203e0377 /bin
parentAlways split spans after newlines (diff)
downloadsrc-bacacf6678168f3b3d0657c4fbbcac0edcb5c799.tar.gz
src-bacacf6678168f3b3d0657c4fbbcac0edcb5c799.zip
Add line numbers to hi
Renames previous -n option to -m to stay consistent with cat -n.
Prefixing lines with line numbers affects where the first tab indent
ends up relative to the text above it. Not sure if it's worth fixing
somehow.
Diffstat (limited to 'bin')
-rw-r--r--bin/hi.c19
-rw-r--r--bin/man1/hi.111
2 files changed, 22 insertions, 8 deletions
diff --git a/bin/hi.c b/bin/hi.c
index ca62aa16..b3584b10 100644
--- a/bin/hi.c
+++ b/bin/hi.c
@@ -41,7 +41,8 @@ typedef unsigned Set;
 	X(Format)  \
 	X(Interp)  \
 	X(Comment) \
-	X(Todo)
+	X(Todo)    \
+	X(Line)
 
 enum Class {
 #define X(class) class,
@@ -361,6 +362,7 @@ static const enum SGR ANSIStyle[ClassLen][3] = {
 	[Interp]  = { SGRYellow },
 	[Comment] = { SGRBlue },
 	[Todo]    = { SGRBlue, SGRBoldOn, SGRBoldOff },
+	[Line]    = { SGRRed },
 };
 
 static void
@@ -474,6 +476,7 @@ static const char *HTMLStyle[ClassLen] = {
 	[Interp]   = "color: olive;",
 	[Comment]  = "color: navy;",
 	[Todo]     = "color: navy; font-weight: bold;",
+	[Line]     = "color: maroon;",
 };
 
 static void htmlTabSize(const char *tab) {
@@ -613,9 +616,10 @@ int main(int argc, char *argv[]) {
 	struct Language lang = {0};
 	struct Format format = Formats[0];
 	const char *opts[OptionLen] = {0};
+	bool number = false;
 
 	int opt;
-	while (0 < (opt = getopt(argc, argv, "cf:l:n:o:"))) {
+	while (0 < (opt = getopt(argc, argv, "cf:l:m:no:"))) {
 		switch (opt) {
 			break; case 'c': check(); return EX_OK;
 			break; case 'f': {
@@ -628,7 +632,8 @@ int main(int argc, char *argv[]) {
 					errx(EX_USAGE, "no such language %s", optarg);
 				}
 			}
-			break; case 'n': name = optarg;
+			break; case 'm': name = optarg;
+			break; case 'n': number = true;
 			break; case 'o': {
 				enum Option key;
 				char *keystr, *valstr;
@@ -685,9 +690,15 @@ int main(int argc, char *argv[]) {
 
 	highlight(lang, hi, str);
 
-	if (format.header) format.header(opts);
 	size_t run = 0;
+	size_t line = 0;
+	if (format.header) format.header(opts);
 	for (size_t i = 0; i < len; i += run) {
+		if (number && (!i || str[i - 1] == '\n')) {
+			char num[sizeof("9999 ")];
+			snprintf(num, sizeof(num), "%4zu ", ++line);
+			format.output(opts, Line, num, sizeof(num) - 1);
+		}
 		for (run = 1; i + run < len; ++run) {
 			if (hi[i + run] != hi[i]) break;
 			if (str[i + run - 1] == '\n') break;
diff --git a/bin/man1/hi.1 b/bin/man1/hi.1
index c48fa796..afe0fe0c 100644
--- a/bin/man1/hi.1
+++ b/bin/man1/hi.1
@@ -1,4 +1,4 @@
-.Dd February 12, 2019
+.Dd February 17, 2019
 .Dt HI 1
 .Os
 .
@@ -8,9 +8,10 @@
 .
 .Sh SYNOPSIS
 .Nm
+.Op Fl n
 .Op Fl f Ar format
 .Op Fl l Ar lang
-.Op Fl n Ar name
+.Op Fl m Ar name
 .Op Fl o Ar opts
 .Op Ar file
 .Nm
@@ -33,9 +34,11 @@ Compile all regular expressions and exit.
 Set the output format.
 .It Fl l Ar lang
 Set the input language.
-.It Fl n Ar name
+.It Fl m Ar name
 Override the name used
 to infer the input language.
+.It Fl n
+Output line numbers.
 .It Fl o Ar opts
 Set output format options.
 .Ar opts
@@ -111,7 +114,7 @@ name.
 If no input language is set with
 .Fl l ,
 it may be inferred from the name set by
-.Fl n
+.Fl m
 or from the provided
 .Ar file
 name.