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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).