diff options
-rw-r--r-- | Documentation/config.txt | 20 | ||||
-rw-r--r-- | builtin-grep.c | 25 | ||||
-rw-r--r-- | grep.c | 64 | ||||
-rw-r--r-- | grep.h | 3 |
4 files changed, 78 insertions, 34 deletions
diff --git a/Documentation/config.txt b/Documentation/config.txt index 7103172ed..d6e4a3e0c 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -683,9 +683,23 @@ 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.match:: - Use customized color for matches. The value of this variable - may be specified as in color.branch.<slot>. +color.grep.<slot>:: + Use customized color for grep colorization. `<slot>` specifies which + part of the line to use the specified color, and is one of ++ +-- +`filename`;; + filename prefix (when not using `-h`) +`linenumber`;; + line number prefix (when using `-n`) +`match`;; + matching text +`separator`;; + separators between fields on a line (`:`, `-`, and `=`) + and between hunks (`--`) +-- ++ +The values of these variables may be specified as in color.branch.<slot>. color.interactive:: When set to `always`, always use colors for interactive prompts diff --git a/builtin-grep.c b/builtin-grep.c index dcc3d4841..09c2f4913 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -289,6 +289,7 @@ static int wait_all(void) static int grep_config(const char *var, const char *value, void *cb) { struct grep_opt *opt = cb; + char *color = NULL; switch (userdiff_config(var, value)) { case 0: break; @@ -296,17 +297,24 @@ static int grep_config(const char *var, const char *value, void *cb) default: return 0; } - if (!strcmp(var, "color.grep")) { + if (!strcmp(var, "color.grep")) opt->color = git_config_colorbool(var, value, -1); - return 0; - } - if (!strcmp(var, "color.grep.match")) { + else if (!strcmp(var, "color.grep.filename")) + color = opt->color_filename; + else if (!strcmp(var, "color.grep.linenumber")) + color = opt->color_lineno; + else if (!strcmp(var, "color.grep.match")) + color = opt->color_match; + else if (!strcmp(var, "color.grep.separator")) + color = opt->color_sep; + else + return git_color_default_config(var, value, cb); + if (color) { if (!value) return config_error_nonbool(var); - color_parse(value, var, opt->color_match); - return 0; + color_parse(value, var, color); } - return git_color_default_config(var, value, cb); + return 0; } /* @@ -871,7 +879,10 @@ int cmd_grep(int argc, const char **argv, const char *prefix) opt.regflags = REG_NEWLINE; opt.max_depth = -1; + strcpy(opt.color_filename, ""); + strcpy(opt.color_lineno, ""); strcpy(opt.color_match, GIT_COLOR_BOLD_RED); + strcpy(opt.color_sep, GIT_COLOR_CYAN); opt.color = -1; git_config(grep_config, &opt); if (opt.color == -1) @@ -270,9 +270,28 @@ static int word_char(char ch) return isalnum(ch) || ch == '_'; } +static void output_color(struct grep_opt *opt, const void *data, size_t size, + const char *color) +{ + if (opt->color && color && color[0]) { + opt->output(opt, color, strlen(color)); + opt->output(opt, data, size); + opt->output(opt, GIT_COLOR_RESET, strlen(GIT_COLOR_RESET)); + } else + opt->output(opt, data, size); +} + +static void output_sep(struct grep_opt *opt, char sign) +{ + if (opt->null_following_name) + opt->output(opt, "\0", 1); + else + output_color(opt, &sign, 1, opt->color_sep); +} + static void show_name(struct grep_opt *opt, const char *name) { - opt->output(opt, name, strlen(name)); + output_color(opt, name, strlen(name), opt->color_filename); opt->output(opt, opt->null_following_name ? "\0" : "\n", 1); } @@ -510,31 +529,30 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol, const char *name, unsigned lno, char sign) { int rest = eol - bol; - char sign_str[1]; - sign_str[0] = sign; if (opt->pre_context || opt->post_context) { if (opt->last_shown == 0) { - if (opt->show_hunk_mark) - opt->output(opt, "--\n", 3); - else + if (opt->show_hunk_mark) { + output_color(opt, "--", 2, opt->color_sep); + opt->output(opt, "\n", 1); + } else opt->show_hunk_mark = 1; - } else if (lno > opt->last_shown + 1) - opt->output(opt, "--\n", 3); + } else if (lno > opt->last_shown + 1) { + output_color(opt, "--", 2, opt->color_sep); + opt->output(opt, "\n", 1); + } } opt->last_shown = lno; - if (opt->null_following_name) - sign_str[0] = '\0'; if (opt->pathname) { - opt->output(opt, name, strlen(name)); - opt->output(opt, sign_str, 1); + output_color(opt, name, strlen(name), opt->color_filename); + output_sep(opt, sign); } if (opt->linenum) { char buf[32]; snprintf(buf, sizeof(buf), "%d", lno); - opt->output(opt, buf, strlen(buf)); - opt->output(opt, sign_str, 1); + output_color(opt, buf, strlen(buf), opt->color_lineno); + output_sep(opt, sign); } if (opt->color) { regmatch_t match; @@ -548,12 +566,9 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol, break; opt->output(opt, bol, match.rm_so); - opt->output(opt, opt->color_match, - strlen(opt->color_match)); - opt->output(opt, bol + match.rm_so, - (int)(match.rm_eo - match.rm_so)); - opt->output(opt, GIT_COLOR_RESET, - strlen(GIT_COLOR_RESET)); + output_color(opt, bol + match.rm_so, + match.rm_eo - match.rm_so, + opt->color_match); bol += match.rm_eo; rest -= match.rm_eo; eflags = REG_NOTBOL; @@ -823,7 +838,8 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name, return 1; if (binary_match_only) { opt->output(opt, "Binary file ", 12); - opt->output(opt, name, strlen(name)); + output_color(opt, name, strlen(name), + opt->color_filename); opt->output(opt, " matches\n", 9); return 1; } @@ -882,9 +898,9 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name, */ if (opt->count && count) { char buf[32]; - opt->output(opt, name, strlen(name)); - snprintf(buf, sizeof(buf), "%c%u\n", - opt->null_following_name ? '\0' : ':', count); + output_color(opt, name, strlen(name), opt->color_filename); + output_sep(opt, ':'); + snprintf(buf, sizeof(buf), "%u\n", count); opt->output(opt, buf, strlen(buf)); } return !!last_hit; @@ -84,7 +84,10 @@ struct grep_opt { int color; int max_depth; int funcname; + char color_filename[COLOR_MAXLEN]; + char color_lineno[COLOR_MAXLEN]; char color_match[COLOR_MAXLEN]; + char color_sep[COLOR_MAXLEN]; int regflags; unsigned pre_context; unsigned post_context; |