From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Subject: [PATCH] git-grep: add --color to highlight matches
Date: Sat, 24 May 2008 11:31:19 +0700 [thread overview]
Message-ID: <20080524043118.GA23118@laptop> (raw)
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-grep.txt | 4 +++
builtin-grep.c | 6 +++-
grep.c | 62 +++++++++++++++++++++++++++++++++++++++++---
grep.h | 1 +
4 files changed, 68 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt
index a97f055..20ef098 100644
--- a/Documentation/git-grep.txt
+++ b/Documentation/git-grep.txt
@@ -16,6 +16,7 @@ SYNOPSIS
[-F | --fixed-strings] [-n]
[-l | --files-with-matches] [-L | --files-without-match]
[-c | --count] [--all-match]
+ [--color]
[-A <post-context>] [-B <pre-context>] [-C <context>]
[-f <file>] [-e] <pattern>
[--and|--or|--not|(|)|-e <pattern>...] [<tree>...]
@@ -85,6 +86,9 @@ OPTIONS
Instead of showing every matched line, show the number of
lines that match.
+--color::
+ Show colored matches.
+
-[ABC] <context>::
Show `context` trailing (`A` -- after), or leading (`B`
-- before), or both (`C` -- context) lines, and place a
diff --git a/builtin-grep.c b/builtin-grep.c
index ef29910..118ec32 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -386,7 +386,7 @@ static int grep_cache(struct grep_opt *opt, const char **paths, int cached)
* we grep through the checked-out files. It tends to
* be a lot more optimized
*/
- if (!cached) {
+ if (!cached && !opt->color) {
hit = external_grep(opt, paths, cached);
if (hit >= 0)
return hit;
@@ -708,6 +708,10 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
opt.relative = 0;
continue;
}
+ if (!strcmp("--color", arg)) {
+ opt.color = 1;
+ continue;
+ }
if (!strcmp("--", arg)) {
/* later processing wants to have this at argv[1] */
argv--;
diff --git a/grep.c b/grep.c
index f67d671..7cc05b0 100644
--- a/grep.c
+++ b/grep.c
@@ -247,7 +247,10 @@ static int fixmatch(const char *pattern, char *line, regmatch_t *match)
}
}
-static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol, char *eol, enum grep_context ctx)
+static int match_one_pattern_1(struct grep_opt *opt, struct grep_pat *p,
+ char *bol, char *eol,
+ enum grep_context ctx, int eflags,
+ int *rm_so, int *rm_eo)
{
int hit = 0;
int at_true_bol = 1;
@@ -261,7 +264,7 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol
if (!opt->fixed) {
regex_t *exp = &p->regexp;
hit = !regexec(exp, bol, ARRAY_SIZE(pmatch),
- pmatch, 0);
+ pmatch, eflags);
}
else {
hit = !fixmatch(p->pattern, bol, pmatch);
@@ -298,9 +301,20 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol
goto again;
}
}
+ if (hit) {
+ if (rm_so)
+ *rm_so = pmatch[0].rm_so;
+ if (rm_eo)
+ *rm_eo = pmatch[0].rm_eo;
+ }
return hit;
}
+static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol, char *eol, enum grep_context ctx)
+{
+ return match_one_pattern_1(opt, p, bol, eol, ctx, 0, NULL, NULL);
+}
+
static int match_expr_eval(struct grep_opt *o,
struct grep_expr *x,
char *bol, char *eol,
@@ -365,6 +379,42 @@ static int match_line(struct grep_opt *opt, char *bol, char *eol,
return 0;
}
+static void show_line_colored(struct grep_opt *opt, char *bol, char *eol,
+ const char *name, unsigned lno, char sign)
+{
+ struct grep_pat *p;
+ int rm_so, rm_eo, eflags = 0;
+ int ch;
+
+ if (opt->pathname)
+ printf("%s%c", name, sign);
+ if (opt->linenum)
+ printf("%d%c", lno, sign);
+
+ ch = *eol;
+ *eol = 0;
+ while (bol < eol) {
+ for (p = opt->pattern_list; p; p = p->next) {
+ if (match_one_pattern_1(opt, p, bol, eol, GREP_CONTEXT_BODY, eflags, &rm_so, &rm_eo))
+ break;
+ }
+
+ /* No match, break the loop */
+ if (!p ||
+ (rm_so < 0) || (eol - bol) <= rm_so ||
+ (rm_eo < 0) || (eol - bol) < rm_eo)
+ break;
+
+ printf("%.*s\033[31m\033[1m%.*s\033[m",
+ rm_so, bol,
+ rm_eo-rm_so, bol+rm_so);
+ bol += rm_eo;
+ eflags = REG_NOTBOL;
+ }
+ printf("%s\n", bol);
+ *eol = ch;
+}
+
static int grep_buffer_1(struct grep_opt *opt, const char *name,
char *buf, unsigned long size, int collect_hits)
{
@@ -466,8 +516,12 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
}
if (last_shown && lno != last_shown + 1)
printf(hunk_mark);
- if (!opt->count)
- show_line(opt, bol, eol, name, lno, ':');
+ if (!opt->count) {
+ if (opt->color)
+ show_line_colored(opt, bol, eol, name, lno, ':');
+ else
+ show_line(opt, bol, eol, name, lno, ':');
+ }
last_shown = last_hit = lno;
}
else if (last_hit &&
diff --git a/grep.h b/grep.h
index d252dd2..979f7d0 100644
--- a/grep.h
+++ b/grep.h
@@ -68,6 +68,7 @@ struct grep_opt {
unsigned extended:1;
unsigned relative:1;
unsigned pathname:1;
+ unsigned color:1;
int regflags;
unsigned pre_context;
unsigned post_context;
--
1.5.5.GIT
next reply other threads:[~2008-05-24 4:32 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-05-24 4:31 Nguyễn Thái Ngọc Duy [this message]
2008-05-24 8:28 ` [PATCH] git-grep: add --color to highlight matches Jakub Narebski
2008-05-24 9:20 ` Nguyen Thai Ngoc Duy
2008-05-24 10:59 ` Jakub Narebski
2008-05-26 8:55 ` Andreas Ericsson
2008-05-26 10:16 ` Johannes Schindelin
2008-05-26 10:57 ` Nguyen Thai Ngoc Duy
2008-05-26 11:00 ` Johannes Schindelin
2008-05-26 11:07 ` Nguyen Thai Ngoc Duy
2008-05-26 11:29 ` Johannes Schindelin
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080524043118.GA23118@laptop \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
/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.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.