aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/grab.15
-rw-r--r--src/grab.c33
2 files changed, 31 insertions, 7 deletions
diff --git a/man/grab.1 b/man/grab.1
index e73307b..b2d3edd 100644
--- a/man/grab.1
+++ b/man/grab.1
@@ -212,6 +212,9 @@ The keys are as follows:
.Bl -tag -compact
.It fn
filenames prefixing any content line.
+.It ln
+line- and column-numbers,
+as well as byte offsets when reporting the location of a match.
.It ma
text matched by a
.Sq g
@@ -223,7 +226,7 @@ separators inserted between filenames and content lines.
.El
.Pp
The default value is
-.Sq fn=35,ma=01;31,se=36
+.Sq fn=35,ln=32,ma=01;31,se=36
.It Ev NO_COLOR
Do not display any colored output when set to a non-empty string,
even if the standard-output is a terminal.
diff --git a/src/grab.c b/src/grab.c
index 2a643f4..bc86b8d 100644
--- a/src/grab.c
+++ b/src/grab.c
@@ -37,6 +37,7 @@
#define EEARLY "Input string terminated prematurely"
#define DEFCOL_FN "35"
+#define DEFCOL_LN "32"
#define DEFCOL_MA "01;31"
#define DEFCOL_SE "36"
@@ -51,7 +52,7 @@ struct ops {
};
struct sv {
- char *p;
+ char *bp, *p;
size_t len;
};
@@ -288,6 +289,7 @@ grab(struct ops ops, FILE *stream, const char *filename)
warn("fread: %s", filename);
else {
struct sv sv = {
+ .bp = chars.buf,
.p = chars.buf,
.len = chars.len,
};
@@ -331,7 +333,11 @@ cmdx(struct sv sv, struct ops ops, size_t i, const char *filename)
if (regexec(&op.pat, sv.p, 1, &rm, REG_STARTEND) == REG_NOMATCH)
break;
- nsv = (struct sv){.p = sv.p + rm.rm_so, .len = rm.rm_eo - rm.rm_so};
+ nsv = (struct sv){
+ .bp = sv.bp,
+ .p = sv.p + rm.rm_so,
+ .len = rm.rm_eo - rm.rm_so,
+ };
if (i + 1 == ops.len)
putm(nsv, nullptr, filename);
else
@@ -367,6 +373,7 @@ cmdy(struct sv sv, struct ops ops, size_t i, const char *filename)
if (prev.rm_so || prev.rm_eo || rm.rm_so) {
nsv = (struct sv){
+ .bp = sv.bp,
.p = sv.p + prev.rm_eo,
.len = rm.rm_so - prev.rm_eo,
};
@@ -387,6 +394,7 @@ cmdy(struct sv sv, struct ops ops, size_t i, const char *filename)
if (prev.rm_eo < rm.rm_eo) {
struct sv nsv = {
+ .bp = sv.bp,
.p = sv.p + rm.rm_so,
.len = rm.rm_eo - rm.rm_so,
};
@@ -400,19 +408,21 @@ cmdy(struct sv sv, struct ops ops, size_t i, const char *filename)
void
putm(struct sv sv, regmatch_t *rm, const char *filename)
{
- static const char *fn, *ma, *se;
+ static const char *fn, *ln, *ma, *se;
if (cflag && !fn) {
char *optstr;
if ((optstr = env_or_default("GRAB_COLORS", nullptr))) {
enum {
OPT_FN,
+ OPT_LN,
OPT_MA,
OPT_SE,
};
/* clang-format off */
static char *const tokens[] = {
[OPT_FN] = "fn",
+ [OPT_LN] = "ln",
[OPT_MA] = "ma",
[OPT_SE] = "se",
nullptr
@@ -426,6 +436,10 @@ putm(struct sv sv, regmatch_t *rm, const char *filename)
if (sgrvalid(val))
fn = val;
break;
+ case OPT_LN:
+ if (sgrvalid(val))
+ fn = val;
+ break;
case OPT_MA:
if (sgrvalid(val))
ma = val;
@@ -443,6 +457,8 @@ putm(struct sv sv, regmatch_t *rm, const char *filename)
if (!fn)
fn = DEFCOL_FN;
+ if (!ln)
+ ln = DEFCOL_LN;
if (!ma)
ma = DEFCOL_MA;
if (!se)
@@ -450,11 +466,16 @@ putm(struct sv sv, regmatch_t *rm, const char *filename)
}
if (fflag || filecnt > 1) {
+ char sep = zflag ? '\0' : ':';
if (cflag) {
- printf("\33[%sm%s\33[%sm%c\33[0m", fn, filename, se,
- zflag ? '\0' : ':');
+ printf("\33[%sm%s\33[0m" /* filename */
+ "\33[%sm%c\33[0m" /* separator */
+ "\33[%sm%td\33[0m" /* byte offset */
+ "\33[%sm%c\33[0m" /* separator */
+ ,
+ fn, filename, se, sep, ln, sv.p - sv.bp, se, sep);
} else
- printf("%s%c", filename, zflag ? '\0' : ':');
+ printf("%s%c", filename, sep);
}
if (rm) {
fwrite(sv.p, 1, rm->rm_so, stdout);