svn commit: r337956 - in head: . bin/ls
Kyle Evans
kevans at FreeBSD.org
Fri Aug 17 04:15:53 UTC 2018
Author: kevans
Date: Fri Aug 17 04:15:51 2018
New Revision: 337956
URL: https://svnweb.freebsd.org/changeset/base/337956
Log:
ls(1): Add --color=when
--color may be set to one of: 'auto', 'always', and 'never'.
'auto' is the default behavior- output colors only if -G or COLORTERM are
set, and only if stdout is a tty.
'always' is a new behavior- output colors always. termcap(5) will be
consulted unless TERM is unset or not a recognized terminal, in which case
ls(1) will fall back to explicitly outputting ANSI escape sequences.
'never' to turn off any environment variable and -G usage.
Reviewed by: cem, 0mp (both modulo last-minute manpage changes
Differential Revision: https://reviews.freebsd.org/D16741
Modified:
head/UPDATING
head/bin/ls/extern.h
head/bin/ls/ls.1
head/bin/ls/ls.c
head/bin/ls/print.c
head/bin/ls/util.c
Modified: head/UPDATING
==============================================================================
--- head/UPDATING Fri Aug 17 04:11:10 2018 (r337955)
+++ head/UPDATING Fri Aug 17 04:15:51 2018 (r337956)
@@ -35,9 +35,9 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
ls(1) now respects the COLORTERM environment variable used in other
systems and software to indicate that a colored terminal is both
supported and desired. If ls(1) is suddenly emitting colors, they may
- be disabled again by removing the unwanted COLORTERM from your
- environment. The ls(1) specific CLICOLOR may not be observed in a
- future release.
+ be disabled again by either removing the unwanted COLORTERM from your
+ environment, or using `ls --color=never`. The ls(1) specific CLICOLOR
+ may not be observed in a future release.
20180808:
The default pager for most commands has been changed to "less". To
Modified: head/bin/ls/extern.h
==============================================================================
--- head/bin/ls/extern.h Fri Aug 17 04:11:10 2018 (r337955)
+++ head/bin/ls/extern.h Fri Aug 17 04:15:51 2018 (r337956)
@@ -32,6 +32,8 @@
* $FreeBSD$
*/
+#include <stdbool.h>
+
int acccmp(const FTSENT *, const FTSENT *);
int revacccmp(const FTSENT *, const FTSENT *);
int birthcmp(const FTSENT *, const FTSENT *);
@@ -64,5 +66,12 @@ extern char *ansi_bgcol;
extern char *ansi_coloff;
extern char *attrs_off;
extern char *enter_bold;
+
+extern int colorflag;
+extern bool explicitansi;
+
+#define COLORFLAG_NEVER 0
+#define COLORFLAG_AUTO 1
+#define COLORFLAG_ALWAYS 2
#endif
extern int termwidth;
Modified: head/bin/ls/ls.1
==============================================================================
--- head/bin/ls/ls.1 Fri Aug 17 04:11:10 2018 (r337955)
+++ head/bin/ls/ls.1 Fri Aug 17 04:15:51 2018 (r337956)
@@ -32,7 +32,7 @@
.\" @(#)ls.1 8.7 (Berkeley) 7/29/94
.\" $FreeBSD$
.\"
-.Dd August 8, 2018
+.Dd August 16, 2018
.Dt LS 1
.Os
.Sh NAME
@@ -41,6 +41,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,
+.Op Fl -color Ns = Ns Ar when
.Op Fl D Ar format
.Op Ar
.Sh DESCRIPTION
@@ -210,6 +211,47 @@ This option is not defined in
.St -p1003.1-2001 .
.It Fl c
Use time when file status was last changed for sorting or printing.
+.It Fl -color Ns = Ns Ar when
+Output colored escape sequences based on
+.Ar when ,
+which may be set to either
+.Cm always ,
+.Cm auto
+(default), or
+.Cm never .
+.Pp
+.Cm always
+will make
+.Nm
+always output color.
+If
+.Ev TERM
+is unset or set to an invalid terminal, then
+.Nm
+will fall back to explicit
+.Tn ANSI
+escape sequences without the help of
+.Xr termcap 5 .
+.Cm always
+is the default if
+.Fl -color
+is specified without an argument.
+.Pp
+.Cm auto
+will make
+.Nm
+output escape sequences based on
+.Xr termcap 5 ,
+but only if
+.Dv stdout
+is a tty and either the
+.Fl G
+flag is specified or the
+.Ev COLORTERM
+environment variable is set and not empty.
+.Pp
+.Cm never
+will disable color regardless of environment variables.
.It Fl d
Directories are listed as plain files (not searched recursively).
.It Fl f
@@ -620,7 +662,10 @@ Colorization
is silently disabled if the output is not directed to a terminal
unless the
.Ev CLICOLOR_FORCE
-variable is defined.
+variable is defined or
+.Fl -color
+is set to
+.Dq always .
.It Ev CLICOLOR_FORCE
Color sequences are normally disabled if the output is not directed to
a terminal.
Modified: head/bin/ls/ls.c
==============================================================================
--- head/bin/ls/ls.c Fri Aug 17 04:11:10 2018 (r337955)
+++ head/bin/ls/ls.c Fri Aug 17 04:15:51 2018 (r337956)
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
#include <err.h>
#include <errno.h>
#include <fts.h>
+#include <getopt.h>
#include <grp.h>
#include <inttypes.h>
#include <limits.h>
@@ -99,6 +100,16 @@ static void display(const FTSENT *, FTSENT *, int);
static int mastercmp(const FTSENT * const *, const FTSENT * const *);
static void traverse(int, char **, int);
+#define COLOR_OPT (CHAR_MAX + 1)
+
+static const struct option long_opts[] =
+{
+#ifdef COLORLS
+ {"color", optional_argument, NULL, COLOR_OPT},
+#endif
+ {NULL, no_argument, NULL, 0}
+};
+
static void (*printfcn)(const DISPLAY *);
static int (*sortfcn)(const FTSENT *, const FTSENT *);
@@ -140,10 +151,10 @@ static int f_stream; /* stream the output, separate w
static int f_timesort; /* sort by time vice name */
int f_type; /* add type character for non-regular files */
static int f_whiteout; /* show whiteout entries */
-
#ifdef COLORLS
+ int colorflag = COLORFLAG_AUTO; /* passed in colorflag */
int f_color; /* add type in color for non-regular files */
-
+ bool explicitansi; /* Explicit ANSI sequences, no termcap(5) */
char *ansi_bgcol; /* ANSI sequence to set background colour */
char *ansi_fgcol; /* ANSI sequence to set foreground colour */
char *ansi_coloff; /* ANSI sequence to reset colours */
@@ -176,6 +187,19 @@ do_color_from_env(void)
(isatty(STDOUT_FILENO) || getenv("CLICOLOR_FORCE")));
}
+static bool
+do_color(void)
+{
+
+#ifdef COLORLS
+ if (colorflag == COLORFLAG_NEVER)
+ return (false);
+ else if (colorflag == COLORFLAG_ALWAYS)
+ return (true);
+#endif
+ return (do_color_from_env());
+}
+
int
main(int argc, char *argv[])
{
@@ -187,7 +211,7 @@ main(int argc, char *argv[])
#ifdef COLORLS
char termcapbuf[1024]; /* termcap definition buffer */
char tcapbuf[512]; /* capability buffer */
- char *bp = tcapbuf;
+ char *bp = tcapbuf, *term;
#endif
(void)setlocale(LC_ALL, "");
@@ -215,8 +239,9 @@ main(int argc, char *argv[])
fts_options = FTS_PHYSICAL;
if (getenv("LS_SAMESORT"))
f_samesort = 1;
- while ((ch = getopt(argc, argv,
- "1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,")) != -1) {
+ while ((ch = getopt_long(argc, argv,
+ "+1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,", long_opts,
+ NULL)) != -1) {
switch (ch) {
/*
* The -1, -C, -x and -l options all override each other so
@@ -379,6 +404,19 @@ main(int argc, char *argv[])
case 'y':
f_samesort = 1;
break;
+#ifdef COLORLS
+ case COLOR_OPT:
+ if (optarg == NULL || strcmp(optarg, "always") == 0)
+ colorflag = COLORFLAG_ALWAYS;
+ else if (strcmp(optarg, "auto") == 0)
+ colorflag = COLORFLAG_AUTO;
+ else if (strcmp(optarg, "never") == 0)
+ colorflag = COLORFLAG_NEVER;
+ else
+ errx(2, "unsupported --color value '%s' (must be always, auto, or never)",
+ optarg);
+ break;
+#endif
default:
case '?':
usage();
@@ -391,10 +429,14 @@ main(int argc, char *argv[])
if (!f_listdot && getuid() == (uid_t)0 && !f_noautodot)
f_listdot = 1;
- /* Enabling of colours is conditional on the environment. */
- if (do_color_from_env())
+ /*
+ * Enabling of colours is conditional on the environment in conjunction
+ * with the --color and -G arguments, if supplied.
+ */
+ if (do_color()) {
#ifdef COLORLS
- if (tgetent(termcapbuf, getenv("TERM")) == 1) {
+ if ((term = getenv("TERM")) != NULL &&
+ tgetent(termcapbuf, term) == 1) {
ansi_fgcol = tgetstr("AF", &bp);
ansi_bgcol = tgetstr("AB", &bp);
attrs_off = tgetstr("me", &bp);
@@ -408,10 +450,19 @@ main(int argc, char *argv[])
ansi_coloff = tgetstr("oc", &bp);
if (ansi_fgcol && ansi_bgcol && ansi_coloff)
f_color = 1;
+ } else if (colorflag == COLORFLAG_ALWAYS) {
+ /*
+ * If we're *always* doing color but we don't have
+ * a functional TERM supplied, we'll fallback to
+ * outputting raw ANSI sequences.
+ */
+ f_color = 1;
+ explicitansi = true;
}
#else
warnx("color support not compiled in");
#endif /*COLORLS*/
+ }
#ifdef COLORLS
if (f_color) {
Modified: head/bin/ls/print.c
==============================================================================
--- head/bin/ls/print.c Fri Aug 17 04:11:10 2018 (r337955)
+++ head/bin/ls/print.c Fri Aug 17 04:15:51 2018 (r337956)
@@ -73,6 +73,8 @@ static void printtime(time_t);
static int printtype(u_int);
static void printsize(size_t, off_t);
#ifdef COLORLS
+static void endcolor_termcap(int);
+static void endcolor_ansi(void);
static void endcolor(int);
static int colortype(mode_t);
#endif
@@ -540,7 +542,7 @@ writech(int c)
}
static void
-printcolor(Colors c)
+printcolor_termcap(Colors c)
{
char *ansiseq;
@@ -560,10 +562,53 @@ printcolor(Colors c)
}
static void
-endcolor(int sig)
+printcolor_ansi(Colors c)
{
+
+ printf("\033[");
+
+ if (colors[c].bold)
+ printf("1");
+ if (colors[c].num[0] != -1)
+ printf(";3%d", colors[c].num[0]);
+ if (colors[c].num[1] != -1)
+ printf(";4%d", colors[c].num[1]);
+ printf("m");
+}
+
+static void
+printcolor(Colors c)
+{
+
+ if (explicitansi)
+ printcolor_ansi(c);
+ else
+ printcolor_termcap(c);
+}
+
+static void
+endcolor_termcap(int sig)
+{
+
tputs(ansi_coloff, 1, sig ? writech : putch);
tputs(attrs_off, 1, sig ? writech : putch);
+}
+
+static void
+endcolor_ansi(void)
+{
+
+ printf("\33[m");
+}
+
+static void
+endcolor(int sig)
+{
+
+ if (explicitansi)
+ endcolor_ansi();
+ else
+ endcolor_termcap(sig);
}
static int
Modified: head/bin/ls/util.c
==============================================================================
--- head/bin/ls/util.c Fri Aug 17 04:11:10 2018 (r337955)
+++ head/bin/ls/util.c Fri Aug 17 04:15:51 2018 (r337956)
@@ -227,7 +227,7 @@ usage(void)
{
(void)fprintf(stderr,
#ifdef COLORLS
- "usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
+ "usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [--color=when] [-D format]"
#else
"usage: ls [-ABCFHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
#endif
More information about the svn-src-head
mailing list