From 58ca7359728959ccc9d7e96d6fbeb324714e9317 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 31 Dec 2019 11:20:21 +0100 Subject: [PATCH] Use colors by default Refine the system by which it is decided whether colored output it used. Besides the PG_COLOR environment variable previously in use, we now also observe the NO_COLORS environment variable. Furthermore, if neither of these are set, we check whether the terminal supports colors using the TERM environment variable and use colors automatically if so. Also add a documentation appendix that explains who this works and how the individual colors can be configured. --- doc/src/sgml/color.sgml | 102 +++++++++++++++++++++++++++++++++++++ doc/src/sgml/filelist.sgml | 1 + doc/src/sgml/postgres.sgml | 1 + src/common/logging.c | 41 +++++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 doc/src/sgml/color.sgml diff --git a/doc/src/sgml/color.sgml b/doc/src/sgml/color.sgml new file mode 100644 index 0000000000..f1697230e5 --- /dev/null +++ b/doc/src/sgml/color.sgml @@ -0,0 +1,102 @@ + + + + Color Support + + + color + + + + Most programs in the PostgreSQL package can produce colorized console + output. This appendix describes how that is configured. + + + + When Color is Used + + + The decision whether to use colorized output is made according to the + following procedure: + + + + + If the environment variable + PG_COLORPG_COLOR + is set: + + + + + + If the value is always, then color is used. + + + + + + If the value is auto and the standard error stream + is associated with a terminal device, then color is used. + + + + + + Otherwise, color is not used. + + + + + + + + If the environment variable NO_COLOR is set, then color + is not used. See for more + information about this. + + + + + + If the environment variable TERM is set to a terminal + type that is recognized to support color and the standard error stream + is associated with a terminal device, then color is used. + + + + + + Otherwise, color is not used. + + + + + + + + Configuring the Colors + + + The actual colors to be used are configured using the environment variable + PG_COLORSPG_COLORS + (note plural). The value is a colon-separated list of + key=value + pairs. The keys specify what the color is to be used for. The values are + SGR (Select Graphic Rendition) specifications, which are interpreted by the + terminal. + + + + The default value is error=01;31:warning=01;35:locus=01. + + + + + This color specification format is also used by other software packages + such as GCC, GNU + coreutils, and GNU grep. + + + + diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml index 3da2365ea9..1043d0f7ab 100644 --- a/doc/src/sgml/filelist.sgml +++ b/doc/src/sgml/filelist.sgml @@ -170,6 +170,7 @@ + diff --git a/doc/src/sgml/postgres.sgml b/doc/src/sgml/postgres.sgml index e59cba7997..1f7bd32878 100644 --- a/doc/src/sgml/postgres.sgml +++ b/doc/src/sgml/postgres.sgml @@ -278,6 +278,7 @@ Appendixes &docguide; &limits; &acronyms; + &color; diff --git a/src/common/logging.c b/src/common/logging.c index 895da7150e..9b0c67046f 100644 --- a/src/common/logging.c +++ b/src/common/logging.c @@ -32,6 +32,37 @@ static const char *sgr_locus = NULL; #define ANSI_ESCAPE_FMT "\x1b[%sm" #define ANSI_ESCAPE_RESET "\x1b[0m" + +#define str_starts_with(str, substr) (strncmp(str, substr, strlen(substr)) == 0) +#define str_ends_with(str, substr) (strcmp(str + strlen(str) - strlen(substr), substr) == 0) + +static bool +terminal_supports_color(void) +{ + const char *term_env = getenv("TERM"); + + if (!term_env) + return false; + else if (strcmp(term_env, "ansi") == 0) + return true; + else if (strcmp(term_env, "cygwin") == 0) + return true; + else if (strcmp(term_env, "linux") == 0) + return true; + else if (str_starts_with(term_env, "rxvt")) + return true; + else if (str_starts_with(term_env, "screen")) + return true; + else if (str_starts_with(term_env, "xterm")) + return true; + else if (str_starts_with(term_env, "vt100")) + return true; + else if (str_ends_with(term_env, "color")) + return true; + else + return false; +} + /* * This should be called before any output happens. */ @@ -53,6 +84,16 @@ pg_logging_init(const char *argv0) (strcmp(pg_color_env, "auto") == 0 && isatty(fileno(stderr)))) log_color = true; } + else if (getenv("NO_COLOR")) + { + /* see https://no-color.org/ */ + log_color = false; + } + else + { + log_color = isatty(fileno(stderr)) && + terminal_supports_color(); + } if (log_color) { -- 2.24.1