aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/config.txt12
-rw-r--r--builtin-grep.c36
-rw-r--r--grep.h1
3 files changed, 48 insertions, 1 deletions
diff --git a/Documentation/config.txt b/Documentation/config.txt
index b75dada9c..4d42bff71 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -553,9 +553,19 @@ color.grep::
`never`), never. When set to `true` or `auto`, use color only
when the output is written to the terminal. Defaults to `false`.
+color.grep.external::
+ The string value of this variable is passed to an external 'grep'
+ command as a command line option if match highlighting is turned
+ on. If set to an empty string, no option is passed at all,
+ turning off coloring for external 'grep' calls; this is the default.
+ For GNU grep, set it to `--color=always` to highlight matches even
+ when a pager is used.
+
color.grep.match::
Use customized color for matches. The value of this variable
- may be specified as in color.branch.<slot>.
+ may be specified as in color.branch.<slot>. It is passed using
+ the environment variables 'GREP_COLOR' and 'GREP_COLORS' when
+ calling an external 'grep'.
color.interactive::
When set to `always`, always use colors for interactive prompts
diff --git a/builtin-grep.c b/builtin-grep.c
index e2c0f0161..9e7e766a4 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -30,6 +30,10 @@ static int grep_config(const char *var, const char *value, void *cb)
opt->color = git_config_colorbool(var, value, -1);
return 0;
}
+ if (!strcmp(var, "grep.color.external") ||
+ !strcmp(var, "color.grep.external")) {
+ return git_config_string(&(opt->color_external), var, value);
+ }
if (!strcmp(var, "grep.color.match") ||
!strcmp(var, "color.grep.match")) {
if (!value)
@@ -287,6 +291,21 @@ static int flush_grep(struct grep_opt *opt,
return status;
}
+static void grep_add_color(struct strbuf *sb, const char *escape_seq)
+{
+ size_t orig_len = sb->len;
+
+ while (*escape_seq) {
+ if (*escape_seq == 'm')
+ strbuf_addch(sb, ';');
+ else if (*escape_seq != '\033' && *escape_seq != '[')
+ strbuf_addch(sb, *escape_seq);
+ escape_seq++;
+ }
+ if (sb->len > orig_len && sb->buf[sb->len - 1] == ';')
+ strbuf_setlen(sb, sb->len - 1);
+}
+
static int external_grep(struct grep_opt *opt, const char **paths, int cached)
{
int i, nr, argc, hit, len, status;
@@ -357,6 +376,23 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
push_arg("-e");
push_arg(p->pattern);
}
+ if (opt->color) {
+ struct strbuf sb = STRBUF_INIT;
+
+ grep_add_color(&sb, opt->color_match);
+ setenv("GREP_COLOR", sb.buf, 1);
+
+ strbuf_reset(&sb);
+ strbuf_addstr(&sb, "mt=");
+ grep_add_color(&sb, opt->color_match);
+ strbuf_addstr(&sb, ":sl=:cx=:fn=:ln=:bn=:se=");
+ setenv("GREP_COLORS", sb.buf, 1);
+
+ strbuf_release(&sb);
+
+ if (opt->color_external && strlen(opt->color_external) > 0)
+ push_arg(opt->color_external);
+ }
hit = 0;
argc = nr;
diff --git a/grep.h b/grep.h
index 73b33ab07..a67005de6 100644
--- a/grep.h
+++ b/grep.h
@@ -80,6 +80,7 @@ struct grep_opt {
unsigned null_following_name:1;
int color;
char color_match[COLOR_MAXLEN];
+ const char *color_external;
int regflags;
unsigned pre_context;
unsigned post_context;