git: f50cda551150 - stable/13 - ls(1): Allow LSCOLORS to specify an underline

From: Piotr Pawel Stefaniak <pstef_at_FreeBSD.org>
Date: Sat, 26 Mar 2022 13:43:02 UTC
The branch stable/13 has been updated by pstef:

URL: https://cgit.FreeBSD.org/src/commit/?id=f50cda551150dd1292548be2e0b2b052ec24613a

commit f50cda551150dd1292548be2e0b2b052ec24613a
Author:     Cameron Katri <me@cameronkatri.com>
AuthorDate: 2021-09-19 11:36:41 +0000
Commit:     Piotr Pawel Stefaniak <pstef@FreeBSD.org>
CommitDate: 2022-03-26 13:18:19 +0000

    ls(1): Allow LSCOLORS to specify an underline
    
    Allows capitalizing the background color character to enable an
    underline instead of bold, capitalizing the foreground color char will
    still do bold.
    
    Differential Revision:  https://reviews.freebsd.org/D30547
    
    (cherry picked from commit 97c31821eb0b1180778ad2da660a1778c2cb4b62)
---
 bin/ls/extern.h |  1 +
 bin/ls/ls.1     | 19 +++++++++++--------
 bin/ls/ls.c     |  2 ++
 bin/ls/print.c  | 21 ++++++++++++++++-----
 4 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/bin/ls/extern.h b/bin/ls/extern.h
index 8dab2bcc9d8c..247c2c4a1d5b 100644
--- a/bin/ls/extern.h
+++ b/bin/ls/extern.h
@@ -66,6 +66,7 @@ extern	char	*ansi_bgcol;
 extern	char	*ansi_coloff;
 extern	char	*attrs_off;
 extern	char	*enter_bold;
+extern	char	*enter_underline;
 
 extern int	 colorflag;
 extern bool	 explicitansi;
diff --git a/bin/ls/ls.1 b/bin/ls/ls.1
index 8510ca609cda..ef412dd2927d 100644
--- a/bin/ls/ls.1
+++ b/bin/ls/ls.1
@@ -740,6 +740,7 @@ where
 is the foreground color and
 .Ar b
 is the background color.
+When the background color is capitalized, the text will underlined.
 .Pp
 The color designators are as follows:
 .Pp
@@ -761,23 +762,25 @@ cyan
 .It Sy h
 light grey
 .It Sy A
-bold black, usually shows up as dark grey
+bold or underlined black, usually shows up as dark grey
 .It Sy B
-bold red
+bold or underlined red
 .It Sy C
-bold green
+bold or underlined green
 .It Sy D
-bold brown, usually shows up as yellow
+bold or underlined brown, usually shows up as yellow
 .It Sy E
-bold blue
+bold or underlined blue
 .It Sy F
-bold magenta
+bold or underlined magenta
 .It Sy G
-bold cyan
+bold or underlined cyan
 .It Sy H
-bold light grey; looks like bright white
+bold or underlined light grey; looks like bright white
 .It Sy x
 default foreground or background
+.It Sy X
+default foreground or background, with an underline or bold
 .El
 .Pp
 Note that the above are standard
diff --git a/bin/ls/ls.c b/bin/ls/ls.c
index 92575711251d..8a30dd326b4e 100644
--- a/bin/ls/ls.c
+++ b/bin/ls/ls.c
@@ -159,6 +159,7 @@ char *ansi_fgcol;		/* ANSI sequence to set foreground colour */
 char *ansi_coloff;		/* ANSI sequence to reset colours */
 char *attrs_off;		/* ANSI sequence to turn off attributes */
 char *enter_bold;		/* ANSI sequence to set color to bold mode */
+char *enter_underline;		/* ANSI sequence to enter underline mode */
 #endif
 
 static int rval;
@@ -485,6 +486,7 @@ main(int argc, char *argv[])
 			ansi_bgcol = tgetstr("AB", &bp);
 			attrs_off = tgetstr("me", &bp);
 			enter_bold = tgetstr("md", &bp);
+			enter_underline = tgetstr("us", &bp);
 
 			/* To switch colours off use 'op' if
 			 * available, otherwise use 'oc', or
diff --git a/bin/ls/print.c b/bin/ls/print.c
index 9a537418f7b9..bbe5c6f8a6f6 100644
--- a/bin/ls/print.c
+++ b/bin/ls/print.c
@@ -106,7 +106,8 @@ static const char *defcolors = "exfxcxdxbxegedabagacad";
 /* colors for file types */
 static struct {
 	int	num[2];
-	int	bold;
+	bool	bold;
+	bool	underline;
 } colors[C_NUMCOLORS];
 #endif
 
@@ -548,6 +549,8 @@ printcolor_termcap(Colors c)
 
 	if (colors[c].bold)
 		tputs(enter_bold, 1, putch);
+	if (colors[c].underline)
+		tputs(enter_underline, 1, putch);
 
 	if (colors[c].num[0] != -1) {
 		ansiseq = tgoto(ansi_fgcol, 0, colors[c].num[0]);
@@ -569,6 +572,8 @@ printcolor_ansi(Colors c)
 
 	if (colors[c].bold)
 		printf("1");
+	if (colors[c].underline)
+		printf(";4");
 	if (colors[c].num[0] != -1)
 		printf(";3%d", colors[c].num[0]);
 	if (colors[c].num[1] != -1)
@@ -666,7 +671,8 @@ parsecolors(const char *cs)
 		cs = "";	/* LSCOLORS not set */
 	len = strlen(cs);
 	for (i = 0; i < (int)C_NUMCOLORS; i++) {
-		colors[i].bold = 0;
+		colors[i].bold = false;
+		colors[i].underline = false;
 
 		if (len <= 2 * (size_t)i) {
 			c[0] = defcolors[2 * i];
@@ -689,10 +695,15 @@ parsecolors(const char *cs)
 				colors[i].num[j] = c[j] - 'a';
 			else if (c[j] >= 'A' && c[j] <= 'H') {
 				colors[i].num[j] = c[j] - 'A';
-				colors[i].bold = 1;
-			} else if (tolower((unsigned char)c[j]) == 'x')
+				if (j == 1)
+					colors[i].underline = true;
+				else
+					colors[i].bold = true;
+			} else if (tolower((unsigned char)c[j]) == 'x') {
+				if (j == 1 && c[j] == 'X')
+					colors[i].underline = true;
 				colors[i].num[j] = -1;
-			else {
+			} else {
 				warnx("invalid character '%c' in LSCOLORS"
 				    " env var", c[j]);
 				colors[i].num[j] = -1;