diff options
author | Jeff King <peff@peff.net> | 2014-01-16 23:24:50 -0500 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2014-01-17 11:17:45 -0800 |
commit | 425729a45fb3a99efbd627258ab1b782bb69d5f4 (patch) | |
tree | 74f07e250fdaa353100c491f574b486a50e54ac6 | |
parent | f545750c690880de6ec74280a2c703983a0834fc (diff) | |
download | git-jk/color-for-more-pagers.tar.gz |
pager: disable colors for some known-bad configurationsjk/color-for-more-pagers
Some pagers do not like the ANSI colors we print. It used to
be that one had to opt into the colors, and you would
usually check your pager config at the same time. These
days, we turn on color.ui by default, meaning that some
users may see broken "git log" from the start, before they
have configured anything. They can fix it by turning off
"color.pager", but we should try to make things work
out-of-the-box as much as possible.
The common cause of this is that the user is using "less" or
"more", has setup its config variable in the environment (so
that we do not override it), but has not included "R" in
their config.
For other pagers, we simply continue to guess that the pager
can handle it. This is compatible with the current behavior
(and will keep exotic things like "diff-highlight | less"
working without further config). The downside is that other
random pagers may break.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | cache.h | 3 | ||||
-rw-r--r-- | color.c | 2 | ||||
-rw-r--r-- | config.c | 2 | ||||
-rw-r--r-- | environment.c | 2 | ||||
-rw-r--r-- | pager.c | 45 |
5 files changed, 50 insertions, 4 deletions
@@ -1215,7 +1215,8 @@ static inline ssize_t write_str_in_full(int fd, const char *str) extern void setup_pager(void); extern const char *pager_program; extern int pager_in_use(void); -extern int pager_use_color; +extern int pager_use_color_config; +extern int pager_use_color(void); extern int term_columns(void); extern int decimal_width(int); extern int check_pager_config(const char *cmd); @@ -184,7 +184,7 @@ static int check_auto_color(void) { if (color_stdout_is_tty < 0) color_stdout_is_tty = isatty(1); - if (color_stdout_is_tty || (pager_in_use() && pager_use_color)) { + if (color_stdout_is_tty || (pager_in_use() && pager_use_color())) { char *term = getenv("TERM"); if (term && strcmp(term, "dumb")) return 1; @@ -991,7 +991,7 @@ int git_default_config(const char *var, const char *value, void *dummy) return git_default_advice_config(var, value); if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) { - pager_use_color = git_config_bool(var,value); + pager_use_color_config = git_config_bool(var,value); return 0; } diff --git a/environment.c b/environment.c index 3c76905b9f..5cd642fcb3 100644 --- a/environment.c +++ b/environment.c @@ -39,7 +39,7 @@ size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT; size_t delta_base_cache_limit = 16 * 1024 * 1024; unsigned long big_file_threshold = 512 * 1024 * 1024; const char *pager_program; -int pager_use_color = 1; +int pager_use_color_config = -1; const char *editor_program; const char *askpass_program; const char *excludes_file; @@ -184,3 +184,48 @@ int check_pager_config(const char *cmd) pager_program = c.value; return c.want; } + +static int pager_can_handle_color(void) +{ + const char *pager = git_pager(1); + + /* + * If it's less, we automatically set "R" and can handle color, + * unless the user already has a "LESS" variable that does not + * include "R". + */ + if (!strcmp(pager, "less")) { + const char *x = getenv("LESS"); + return !x || !!strchr(x, 'R'); + } + + if (!strcmp(pager, "more")) { +#ifdef PAGER_MORE_UNDERSTANDS_R + /* + * An advanced "more" that knows "R" is in the same boat as + * "less". + */ + const char *x = getenv("MORE"); + return !x || !!strchr(x, 'R'); +#else + /* + * For a more primitive "more", just assume that it will pass + * through the control codes verbatim. + */ + return 1; +#endif + } + + /* + * Otherwise, we don't recognize it. Guess that it can probably handle + * color. This matches what we have done historically. + */ + return 1; +} + +int pager_use_color(void) +{ + if (pager_use_color_config < 0) + pager_use_color_config = pager_can_handle_color(); + return pager_use_color_config; +} |