With the attached patch, I propose to enable the colored output by
default in PG13.
For those who don't like color output, I also add support for the
environment variable NO_COLOR, which is an emerging standard for turning
off color across different software packages (https://no-color.org/).
Of course, you can also continue to use the PG_COLOR variable.
I have looked around how other packages do the automatic color
detection. It's usually a combination of mysterious termcap stuff and
slightly less mysterious matching of the TERM variable against a list of
known terminal types. I figured we can skip the termcap stuff and still
get really good coverage in practice, so that's what I did.
I have also added a documentation appendix to explain all of this.
(Perhaps we should now remove the repetitive mention of the PG_COLOR
variable in each man page, but I haven't done that in this patch.)
I'm aware of the pending patch to improve color support on Windows.
I'll check that one out as well, but it appears to be orthogonal to this
one.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
From 58ca7359728959ccc9d7e96d6fbeb324714e9317 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
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 @@
+<!-- doc/src/sgml/color.sgml -->
+
+<appendix id="color">
+ <title>Color Support</title>
+
+ <indexterm zone="color">
+ <primary>color</primary>
+ </indexterm>
+
+ <para>
+ Most programs in the PostgreSQL package can produce colorized console
+ output. This appendix describes how that is configured.
+ </para>
+
+ <sect1 id="color-when">
+ <title>When Color is Used</title>
+
+ <para>
+ The decision whether to use colorized output is made according to the
+ following procedure:
+
+ <orderedlist>
+ <listitem>
+ <para>
+ If the environment variable
+ <envar>PG_COLOR</envar><indexterm><primary>PG_COLOR</primary></indexterm>
+ is set:
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>
+ If the value is <literal>always</literal>, then color is used.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If the value is <literal>auto</literal> and the standard error stream
+ is associated with a terminal device, then color is used.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Otherwise, color is not used.
+ </para>
+ </listitem>
+ </orderedlist>
+ </listitem>
+
+ <listitem>
+ <para>
+ If the environment variable <envar>NO_COLOR</envar> is set, then color
+ is not used. See <ulink url="https://no-color.org/"/> for more
+ information about this.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If the environment variable <envar>TERM</envar> 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.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Otherwise, color is not used.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+ </sect1>
+
+ <sect1 id="color-which">
+ <title>Configuring the Colors</title>
+
+ <para>
+ The actual colors to be used are configured using the environment variable
+ <envar>PG_COLORS</envar><indexterm><primary>PG_COLORS</primary></indexterm>
+ (note plural). The value is a colon-separated list of
+
<literal><replaceable>key</replaceable>=<replaceable>value</replaceable></literal>
+ 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.
+ </para>
+
+ <para>
+ The default value is <literal>error=01;31:warning=01;35:locus=01</literal>.
+ </para>
+
+ <tip>
+ <para>
+ This color specification format is also used by other software packages
+ such as <productname>GCC</productname>, <productname>GNU
+ coreutils</productname>, and <productname>GNU grep</productname>.
+ </para>
+ </tip>
+ </sect1>
+</appendix>
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 @@
<!ENTITY limits SYSTEM "limits.sgml">
<!ENTITY acronyms SYSTEM "acronyms.sgml">
+<!ENTITY color SYSTEM "color.sgml">
<!ENTITY features-supported SYSTEM "features-supported.sgml">
<!ENTITY features-unsupported SYSTEM "features-unsupported.sgml">
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 @@ <title>Appendixes</title>
&docguide;
&limits;
&acronyms;
+ &color;
</part>
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