git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Phillip Wood <phillip.wood123@gmail.com>
To: Felipe Contreras <felipe.contreras@gmail.com>, git@vger.kernel.org
Cc: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
	"Leah Neukirchen" <leah@vuxu.org>, "Jeff King" <peff@peff.net>,
	"Junio C Hamano" <gitster@pobox.com>,
	"Randall S. Becker" <rsbecker@nexbridge.com>
Subject: Re: [PATCH v4] help: colorize man pages
Date: Thu, 20 May 2021 10:26:03 +0100	[thread overview]
Message-ID: <842221d6-51c4-e08a-4299-c4efb8bf1dcb@gmail.com> (raw)
In-Reply-To: <20210520040725.133848-1-felipe.contreras@gmail.com>

On 20/05/2021 05:07, Felipe Contreras wrote:
> We already colorize tools traditionally not colorized by default, like
> diff and grep. Let's do the same for man.

I think there is a distinction between 'diff' and 'grep' where we are 
generating the content and help where we are running man - I would 
expect a man page to look the same whether it is displayed by 'man git 
foo' or 'git help foo'

> Our man pages don't contain many useful colors (just blue links),
> moreover, many people have groff SGR disabled, so they don't see any
> colors with man pages.
> 
> We can set the LESS variable to render bold, underlined, and standout
> text with colors in the less pager.
> 
> Bold is rendered as red, underlined as blue, and standout (prompt and
> highlighted search) as inverse magenta.
> 
> Obviously this only works when the less pager is used.
> 
> If the user has already set the LESS variable in his/her environment,
> that is respected, and nothing changes.

However if they have specified the colors they would like by using the 
LESS_TERMCAP_xx environment variables that the previous versions of this 
patch used their choice is overridden by this new patch.

I've got LESS_TERMCAP_xx set and running
	LESS='Dd+r$Du+b$Ds' man git add
changes the output colors

> A new color configuration is added: `color.man` for the people that want
> to turn this feature off, otherwise `color.ui` is respected.
> Additionally, if color.pager is not enabled, this is disregarded.
> 
> Normally check_auto_color() would check the value of `color.pager`, but
> in this particular case it's not git the one executing the pager, but

s/git the one/git is not/

Best Wishes

Phillip

> man. Therefore we need to check pager_use_color ourselves.
> 
> Also--unlike other color.* configurations--color.man=always does not
> make any sense here; `git help` is always run for a tty (it would be very
> strange for a user to do `git help $page > output`, but in fact, that
> works automatically [probably thanks to less being smart], we don't even
> need to check if stdout is a tty, but just to be consistent we do). So
> it's simply a boolean in our case.
> 
> Moreover, just to be painstakingly comprehensive with people who have
> color-aversion; we honour NO_COLOR [1].
> 
> So, in order for this change to have any effect:
> 
>   1. The user must use less
>   2. Not have the LESS variable set
>   3. Have color.ui enabled
>   4. Not have color.pager disabled
>   5. Not have color.man disabled
>   6. Not have NO_COLOR set
>   7. Not have git with stdout directed to a file
> 
> Fortunately the vast majority of our users meet all of the above, and
> anybody who doesn't would not be affected negatively (plus very likely
> comprises a very tiny minority).
> 
> [1] https://no-color.org/
> 
> Suggested-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> Comments-by: Jeff King <peff@peff.net>
> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> ---
> Range-diff against v3:
> 1:  db93bf432b ! 1:  7249785014 help: colorize man pages
>      @@ Metadata
>        ## Commit message ##
>           help: colorize man pages
>       
>      +    We already colorize tools traditionally not colorized by default, like
>      +    diff and grep. Let's do the same for man.
>      +
>           Our man pages don't contain many useful colors (just blue links),
>           moreover, many people have groff SGR disabled, so they don't see any
>           colors with man pages.
>       
>      -    We can set LESS_TERMCAP variables to render bold and underlined text
>      -    with colors in the pager; a common trick[1].
>      +    We can set the LESS variable to render bold, underlined, and standout
>      +    text with colors in the less pager.
>       
>      -    Bold is rendered as red, underlined as blue, and standout (messages and
>      +    Bold is rendered as red, underlined as blue, and standout (prompt and
>           highlighted search) as inverse magenta.
>       
>      -    This only works when the pager is less.
>      +    Obviously this only works when the less pager is used.
>       
>      -    If the user already has LESS_TERMCAP variables set in his/her
>      -    environment, those are respected and not overwritten.
>      +    If the user has already set the LESS variable in his/her environment,
>      +    that is respected, and nothing changes.
>       
>           A new color configuration is added: `color.man` for the people that want
>      -    to turn this feature off, otherwise `color.ui` is respected, and in
>      -    addition color.pager needs to be turned on.
>      +    to turn this feature off, otherwise `color.ui` is respected.
>      +    Additionally, if color.pager is not enabled, this is disregarded.
>       
>           Normally check_auto_color() would check the value of `color.pager`, but
>           in this particular case it's not git the one executing the pager, but
>           man. Therefore we need to check pager_use_color ourselves.
>       
>      -    Also, unlike other color.* configurations, color.man=always does not
>      -    make any sense; git help is always run for a tty (it would be very
>      +    Also--unlike other color.* configurations--color.man=always does not
>      +    make any sense here; `git help` is always run for a tty (it would be very
>           strange for a user to do `git help $page > output`, but in fact, that
>           works automatically [probably thanks to less being smart], we don't even
>           need to check if stdout is a tty, but just to be consistent we do). So
>           it's simply a boolean in our case.
>       
>      -    So in order for this to have an effect:
>      +    Moreover, just to be painstakingly comprehensive with people who have
>      +    color-aversion; we honour NO_COLOR [1].
>      +
>      +    So, in order for this change to have any effect:
>       
>            1. The user must use less
>      -     2. Not have the same LESS_TERMCAP variables set
>      +     2. Not have the LESS variable set
>            3. Have color.ui enabled
>      -     4. Have color.pager enabled
>      +     4. Not have color.pager disabled
>            5. Not have color.man disabled
>      -     6. Run git with stdout on a tty
>      +     6. Not have NO_COLOR set
>      +     7. Not have git with stdout directed to a file
>       
>      -    Otherwise the current behavior remains.
>      +    Fortunately the vast majority of our users meet all of the above, and
>      +    anybody who doesn't would not be affected negatively (plus very likely
>      +    comprises a very tiny minority).
>       
>      -    [1] https://unix.stackexchange.com/questions/119/colors-in-man-pages/147
>      +    [1] https://no-color.org/
>       
>           Suggested-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
>           Comments-by: Jeff King <peff@peff.net>
>      @@ builtin/help.c: static void exec_man_konqueror(const char *path, const char *pag
>       +	if (!man_color || !want_color(GIT_COLOR_UNKNOWN) || !pager_use_color)
>       +		return;
>       +
>      ++	/* See: https://no-color.org/ */
>      ++	if (getenv("NO_COLOR"))
>      ++		return;
>      ++
>       +	/* Disable groff colors */
>       +	setenv("GROFF_NO_SGR", "1", 0);
>       +
>      -+	/* Bold */
>      -+	setenv("LESS_TERMCAP_md", GIT_COLOR_BOLD_RED, 0);
>      -+	setenv("LESS_TERMCAP_me", GIT_COLOR_RESET, 0);
>      -+
>      -+	/* Underline */
>      -+	setenv("LESS_TERMCAP_us", GIT_COLOR_BLUE GIT_COLOR_UNDERLINE, 0);
>      -+	setenv("LESS_TERMCAP_ue", GIT_COLOR_RESET, 0);
>      -+
>      -+	/* Standout */
>      -+	setenv("LESS_TERMCAP_so", GIT_COLOR_MAGENTA GIT_COLOR_REVERSE, 0);
>      -+	setenv("LESS_TERMCAP_se", GIT_COLOR_RESET, 0);
>      ++	/* Add red to bold, blue to underline, and magenta to standout */
>      ++	/* No visual information is lost */
>      ++	setenv("LESS", "Dd+r$Du+b$Ds", 0);
>       +}
>       +
>        static void exec_man_man(const char *path, const char *page)
>      @@ builtin/help.c: static int git_help_config(const char *var, const char *value, v
>        }
>        
>        static struct cmdnames main_cmds, other_cmds;
>      -
>      - ## color.h ##
>      -@@ color.h: struct strbuf;
>      - #define GIT_COLOR_FAINT		"\033[2m"
>      - #define GIT_COLOR_FAINT_ITALIC	"\033[2;3m"
>      - #define GIT_COLOR_REVERSE	"\033[7m"
>      -+#define GIT_COLOR_UNDERLINE	"\033[4m"
>      -
>      - /* A special value meaning "no color selected" */
>      - #define GIT_COLOR_NIL "NIL"
> 
>   Documentation/config/color.txt |  5 +++++
>   builtin/help.c                 | 28 +++++++++++++++++++++++++++-
>   2 files changed, 32 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/config/color.txt b/Documentation/config/color.txt
> index d5daacb13a..11278b7f72 100644
> --- a/Documentation/config/color.txt
> +++ b/Documentation/config/color.txt
> @@ -126,6 +126,11 @@ color.interactive.<slot>::
>   	or `error`, for four distinct types of normal output from
>   	interactive commands.
>   
> +color.man::
> +	This flag can be used to disable the automatic colorizaton of man
> +	pages when using the less pager. It's activated only when color.ui
> +	allows it, and also when color.pager is on. (`true` by default).
> +
>   color.pager::
>   	A boolean to enable/disable colored output when the pager is in
>   	use (default is true).
> diff --git a/builtin/help.c b/builtin/help.c
> index bb339f0fc8..298d97cc39 100644
> --- a/builtin/help.c
> +++ b/builtin/help.c
> @@ -11,6 +11,7 @@
>   #include "config-list.h"
>   #include "help.h"
>   #include "alias.h"
> +#include "color.h"
>   
>   #ifndef DEFAULT_HELP_FORMAT
>   #define DEFAULT_HELP_FORMAT "man"
> @@ -43,6 +44,7 @@ static int verbose = 1;
>   static unsigned int colopts;
>   static enum help_format help_format = HELP_FORMAT_NONE;
>   static int exclude_guides;
> +static int man_color = 1;
>   static struct option builtin_help_options[] = {
>   	OPT_BOOL('a', "all", &show_all, N_("print all available commands")),
>   	OPT_HIDDEN_BOOL(0, "exclude-guides", &exclude_guides, N_("exclude guides")),
> @@ -253,10 +255,29 @@ static void exec_man_konqueror(const char *path, const char *page)
>   	}
>   }
>   
> +static void colorize_man(void)
> +{
> +	if (!man_color || !want_color(GIT_COLOR_UNKNOWN) || !pager_use_color)
> +		return;
> +
> +	/* See: https://no-color.org/ */
> +	if (getenv("NO_COLOR"))
> +		return;
> +
> +	/* Disable groff colors */
> +	setenv("GROFF_NO_SGR", "1", 0);
> +
> +	/* Add red to bold, blue to underline, and magenta to standout */
> +	/* No visual information is lost */
> +	setenv("LESS", "Dd+r$Du+b$Ds", 0);
> +}
> +
>   static void exec_man_man(const char *path, const char *page)
>   {
>   	if (!path)
>   		path = "man";
> +
> +	colorize_man();
>   	execlp(path, "man", page, (char *)NULL);
>   	warning_errno(_("failed to exec '%s'"), path);
>   }
> @@ -264,6 +285,7 @@ static void exec_man_man(const char *path, const char *page)
>   static void exec_man_cmd(const char *cmd, const char *page)
>   {
>   	struct strbuf shell_cmd = STRBUF_INIT;
> +	colorize_man();
>   	strbuf_addf(&shell_cmd, "%s %s", cmd, page);
>   	execl(SHELL_PATH, SHELL_PATH, "-c", shell_cmd.buf, (char *)NULL);
>   	warning(_("failed to exec '%s'"), cmd);
> @@ -371,8 +393,12 @@ static int git_help_config(const char *var, const char *value, void *cb)
>   	}
>   	if (starts_with(var, "man."))
>   		return add_man_viewer_info(var, value);
> +	if (!strcmp(var, "color.man")) {
> +		man_color = git_config_bool(var, value);
> +		return 0;
> +	}
>   
> -	return git_default_config(var, value, cb);
> +	return git_color_default_config(var, value, cb);
>   }
>   
>   static struct cmdnames main_cmds, other_cmds;
> 

  reply	other threads:[~2021-05-20  9:29 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-20  4:07 [PATCH v4] help: colorize man pages Felipe Contreras
2021-05-20  9:26 ` Phillip Wood [this message]
2021-05-20 13:58   ` Felipe Contreras
2021-05-20 15:13     ` Phillip Wood
2021-05-20 15:59       ` Felipe Contreras
2021-05-20 18:00         ` Phillip Wood
2021-05-21 17:43           ` Felipe Contreras
2021-05-21  5:06   ` Junio C Hamano
2021-05-21  8:44     ` Jeff King
2021-05-21 18:01       ` Felipe Contreras
2021-05-21 20:26         ` Jeff King
2021-05-21 21:40           ` Felipe Contreras
2021-05-22  9:55             ` Jeff King
2021-05-22 12:43               ` Philip Oakley
2021-05-22 20:53                 ` Felipe Contreras
2021-05-22 20:49               ` Felipe Contreras
2021-05-21 17:54     ` Felipe Contreras
2021-05-20 14:39 ` Leah Neukirchen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=842221d6-51c4-e08a-4299-c4efb8bf1dcb@gmail.com \
    --to=phillip.wood123@gmail.com \
    --cc=avarab@gmail.com \
    --cc=felipe.contreras@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=leah@vuxu.org \
    --cc=peff@peff.net \
    --cc=phillip.wood@dunelm.org.uk \
    --cc=rsbecker@nexbridge.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).