On 31/05/2013 19:10, Shigio YAMAGUCHI wrote:
> On Fri, 31 May 2013 12:04:26 +0800
> Leo Liu <[email protected]> wrote:
>
>> I like the brief output from --result=grep. Unfortunately it is not easy
>> to identify the tag found in each line. It'd be nice if the matched tag
>> is coloured, for example, like 'grep' with '--color'.
>
> I have added the option to the TODO list.
> (http://www.gnu.org/software/global/plans.html)
Find attached a patch that adds -C (--color, --colour) to do it. It
uses GREP_COLORS (mt or ms) or GREP_COLOR to define the color; default
is bold red text. It only works with -g, whatever the output. The
Windows version will require ANSICON (ANSI32.dll), but I'll include
that in my binaries (global.exe with colour and fixed idutils and
--single-update, along with gtags.exe with fixed idutils are here:
http://global.adoxa.vze.com/global.zip).
The patch also fixes literal matching at the end of the file (-V
wasn't including the last line, nor did it properly test/display the
last line if it didn't have a newline).
--
Jason.
diff -urp global-6.2.8/global/global.c global-6.2-8/global/global.c
--- global-6.2.8/global/global.c 2013-02-28 21:21:06.000000000 +1000
+++ global-6.2-8/global/global.c 2013-06-28 18:06:43.374979000 +1000
@@ -24,6 +24,11 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef SLIST_ENTRY
+#endif
#include <ctype.h>
#include <stdio.h>
@@ -70,6 +75,7 @@ void encode(char *, int, const char *);
const char *localprefix; /**< local prefix */
int aflag; /* [option] */
int cflag; /* command */
+int Cflag; /* [option] */
int dflag; /* command */
int fflag; /* command */
int gflag; /* command */
@@ -144,6 +150,8 @@ help(void)
static struct option const long_options[] = {
{"absolute", no_argument, NULL, 'a'},
{"completion", no_argument, NULL, 'c'},
+ {"color", no_argument, NULL, 'C'},
+ {"colour", no_argument, NULL, 'C'},
{"definition", no_argument, NULL, 'd'},
{"regexp", required_argument, NULL, 'e'},
{"file", no_argument, NULL, 'f'},
@@ -336,7 +344,7 @@ main(int argc, char **argv)
int option_index = 0;
logging_arguments(argc, argv);
- while ((optchar = getopt_long(argc, argv,
"acde:ifgGIlL:noOpPqrstTuvVx", long_options, &option_index)) != EOF) {
+ while ((optchar = getopt_long(argc, argv,
"acCde:ifgGIlL:noOpPqrstTuvVx", long_options, &option_index)) != EOF) {
switch (optchar) {
case 0:
break;
@@ -347,6 +355,9 @@ main(int argc, char **argv)
cflag++;
setcom(optchar);
break;
+ case 'C':
+ Cflag++;
+ break;
case 'd':
dflag++;
break;
@@ -527,6 +538,16 @@ main(int argc, char **argv)
vflag = 0;
if (show_help)
help();
+ if (Cflag) {
+ if (Vflag)
+ Cflag = 0;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ else if (!(getenv("ANSICON") || LoadLibrary("ANSI32.dll")))
+ Cflag = 0;
+#endif
+ if (Cflag)
+ highlight_init();
+ }
argc -= optind;
argv += optind;
@@ -1253,7 +1279,8 @@ grep(const char *pattern, char *const *a
die("cannot open file '%s'.", path);
linenum = 0;
while ((buffer = strbuf_fgets(ib, fp, STRBUF_NOCRLF))
!= NULL) {
- int result = regexec(&preg, buffer, 0, 0, 0);
+ regmatch_t m;
+ int result = regexec(&preg, buffer, Cflag ? 1 :
0, &m, 0);
linenum++;
if ((!Vflag && result == 0) || (Vflag && result
!= 0)) {
count++;
@@ -1261,6 +1288,8 @@ grep(const char *pattern, char *const *a
convert_put_path(cv, path);
break;
} else {
+ if (Cflag)
+ buffer =
highlight(buffer, m.rm_so, m.rm_eo - m.rm_so);
convert_put_using(cv,
encoded_pattern, path, linenum, buffer,
(user_specified) ? NULL
: gp->dbop->lastdat);
}
diff -urp global-6.2.8/global/literal.c global-6.2-8/global/literal.c
--- global-6.2.8/global/literal.c 2013-02-28 21:21:06.000000000 +1000
+++ global-6.2-8/global/literal.c 2013-06-28 15:43:00.114756700 +1000
@@ -63,6 +63,7 @@ void cfail(void);
extern int iflag;
extern int Vflag;
+extern int Cflag;
extern void encode(char *, int, const char *);
#define MAXSIZ 6000
@@ -76,6 +77,7 @@ static struct words {
} w[MAXSIZ], *smax, *q;
static char encoded_pattern[IDENTLEN];
+static int patlen;
/**
* literal_comple: compile literal for search.
@@ -99,6 +101,10 @@ literal_comple(const char *pattern)
* construct fail links.
*/
cfail();
+ /*
+ * store length of pattern for possible highlight.
+ */
+ patlen = strlen(pattern);
}
/**
* literal_search: execute literal search
@@ -119,6 +125,7 @@ literal_search(CONVERT *cv, const char *
char *linep;
long lineno;
int f;
+ int start;
if ((f = open(file, O_BINARY)) < 0) {
warning("cannot open '%s'.", file);
@@ -156,9 +163,10 @@ literal_search(CONVERT *cv, const char *
linep = p = buf;
ccount = stb.st_size;
lineno = 1;
+ start = 0;
c = w;
for (;;) {
- if (--ccount <= 0)
+ if (--ccount < 0)
break;
nstate:
if (ccomp(c->inp, *p)) {
@@ -184,8 +192,9 @@ literal_search(CONVERT *cv, const char *
else goto nstate;
}
if (c->out) {
+ start = p - linep - patlen + 1;
while (*p++ != '\n') {
- if (--ccount <= 0)
+ if (--ccount < 0)
break;
}
if (Vflag)
@@ -195,19 +204,23 @@ literal_search(CONVERT *cv, const char *
goto finish;
} else {
STATIC_STRBUF(sb);
+ char *s;
strbuf_clear(sb);
strbuf_nputs(sb, linep, p - linep);
strbuf_unputc(sb, '\n');
strbuf_unputc(sb, '\r');
- convert_put_using(cv, encoded_pattern, file,
lineno, strbuf_value(sb), NULL);
+ s = strbuf_value(sb);
+ if (Cflag)
+ s = highlight(s, start, patlen);
+ convert_put_using(cv, encoded_pattern, file,
lineno, s, NULL);
}
nomatch: lineno++;
linep = p;
c = w;
continue;
}
- if (*p++ == '\n') {
+ if (*p++ == '\n' || ccount == 0) {
if (Vflag)
goto succeed;
else {
diff -urp global-6.2.8/global/manual.in global-6.2-8/global/manual.in
--- global-6.2.8/global/manual.in 2013-02-28 21:21:06.000000000 +1000
+++ global-6.2-8/global/manual.in 2013-06-28 17:23:39.282177300 +1000
@@ -28,7 +28,7 @@
@name{global} [-adGilnqrstTvx][-e] @arg{pattern}
@name{global} -c[diIoOPrsT] @arg{prefix}
@name{global} -f[adlnqrstvx][-L file-list] @arg{files}
- @name{global} -g[aGilnoOqtvVx][-L file-list][-e] @arg{pattern}
[@arg{files}]
+ @name{global} -g[aCGilnoOqtvVx][-L file-list][-e] @arg{pattern}
[@arg{files}]
@name{global} -I[ailnqtvx][-e] @arg{pattern}
@name{global} -P[aGilnoOqtvVx][-e] @arg{pattern}
@name{global} -p[qrv]
@@ -91,6 +91,11 @@
@begin_itemize
@item{@option{-a}, @option{--absolute}}
Print absolute path name. By default, print relative path name.
+ @item{@option{-C}, @option{--color}, @option{--colour}}
+ Use color to highlight the pattern within the line. The default
+ color is bold red text on current background; the environment
+ variable @var{GREP_COLORS} or @var{GREP_COLOR} defines it.
+ This option is only valid when the @option{-g} command is
specified.
@item{@option{-d}, @option{--definition}}
Print locations of object definitions.
@item{@option{--from-here} @arg{context}}
@@ -244,6 +249,11 @@
If this variable is set, the @option{-T} option is specified.
@item{@var{GTAGSBLANKENCODE}}
If this variable is set, the --encode=" <TAB>" option is
specified.
+ @item{@var{GREP_COLOR}}
+ The color to use for @option{-C}; @var{GREP_COLORS} has
precedence.
+ @item{@var{GREP_COLORS}}
+ The color (@arg{mt} or @arg{ms}) to use for @option{-C}; see
@xref{grep,1}.
+ The default is @arg{1;31}, which is bold red text on current
background.
@end_itemize
@CONFIGURATION
The following configuration variables affect the execution of
@name{global}:
diff -urp global-6.2.8/libutil/pathconvert.c global-6.2-8/libutil/pathconvert.c
--- global-6.2.8/libutil/pathconvert.c 2013-02-28 21:21:06.000000000 +1000
+++ global-6.2-8/libutil/pathconvert.c 2013-06-28 16:23:40.100315900 +1000
@@ -44,6 +44,7 @@
static unsigned char encode[256];
static int encoding;
static int newline = '\n';
+static const char *match_sgr = "1;31"; /* bold red text */
#define required_encode(c) encode[(unsigned char)c]
/**
@@ -443,3 +444,50 @@ convert_close(CONVERT *cv)
gpath_close();
free(cv);
}
+/**
+ * highlight: wrap an SGR sequence around characters in @a s.
+ *
+ * @param[in] s line of text
+ * @param[in] pos position to start highlight
+ * @param[in] len length of highlight
+ * @return highlighted text
+ */
+char *
+highlight(const char *s, int pos, int len)
+{
+ STATIC_STRBUF(sb);
+
+ strbuf_clear(sb);
+ strbuf_nputs(sb, s, pos);
+ strbuf_sprintf(sb, "\33[%sm", match_sgr);
+ strbuf_nputs(sb, s + pos, len);
+ strbuf_puts(sb, "\33[m");
+ strbuf_puts(sb, s + pos + len);
+ return strbuf_value(sb);
+}
+void
+highlight_init(void)
+{
+ STATIC_STRBUF(sb);
+ const char *sgr;
+
+ sgr = getenv("GREP_COLORS");
+ if (sgr) {
+ const char *part = strstr(sgr, "mt=");
+ if (!part)
+ part = strstr(sgr, "ms=");
+ if (part) {
+ const char *sep = strchr(part, ':');
+ if (!sep)
+ sep = strchr(part, '\0');
+ part += 3;
+ strbuf_nputs(sb, part, sep - part);
+ match_sgr = strbuf_value(sb);
+ }
+ }
+ else {
+ sgr = getenv("GREP_COLOR");
+ if (sgr)
+ match_sgr = sgr;
+ }
+}
diff -urp global-6.2.8/libutil/pathconvert.h global-6.2-8/libutil/pathconvert.h
--- global-6.2.8/libutil/pathconvert.h 2013-02-28 21:21:06.000000000 +1000
+++ global-6.2-8/libutil/pathconvert.h 2013-06-28 12:58:53.296479900 +1000
@@ -42,5 +42,7 @@ void convert_put(CONVERT *, const char *
void convert_put_path(CONVERT *, const char *);
void convert_put_using(CONVERT *, const char *, const char *, int, const char
*, const char *);
void convert_close(CONVERT *cv);
+char *highlight(const char *, int, int);
+void highlight_init(void);
#endif /* ! _PATHCONVERT_H_ */
_______________________________________________
Bug-global mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/bug-global