Skip to content

Commit

Permalink
grep: Colorize filename, line number, and separator
Browse files Browse the repository at this point in the history
Colorize the filename, line number, and separator in git grep output, as
GNU grep does.  The colors are customizable through color.grep.<slot>.
The default is to only color the separator (in cyan), since this gives
the biggest legibility increase without overwhelming the user with
colors.  GNU grep also defaults cyan for the separator, but defaults to
magenta for the filename and to green for the line number, as well.

There is one difference from GNU grep: When a binary file matches
without -a, GNU grep does not color the <file> in "Binary file <file>
matches", but we do.

Like GNU grep, if --null is given, the null separators are not colored.

For config.txt, use a a sub-list to describe the slots, rather than
a single paragraph with parentheses, since this is much more readable.

Remove the cast to int for `rm_eo - rm_so` since it is not necessary.

Signed-off-by: Mark Lodato <lodatom@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Mark Lodato authored and Junio C Hamano committed Mar 8, 2010
1 parent 758df17 commit 55f638b
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 34 deletions.
20 changes: 17 additions & 3 deletions Documentation/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
25 changes: 18 additions & 7 deletions builtin-grep.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,24 +289,32 @@ 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;
case -1: return -1;
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;
}

/*
Expand Down Expand Up @@ -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)
Expand Down
64 changes: 40 additions & 24 deletions grep.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions grep.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 55f638b

Please sign in to comment.