aboutsummaryrefslogtreecommitdiffstats
path: root/pw.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2023-06-09 00:22:33 -0700
committerKaz Kylheku <kaz@kylheku.com>2023-06-09 00:22:33 -0700
commiteb16b04f0e8f17471d4c1bec9611040747adfdbd (patch)
tree42f6ed983b996d8d14a6182c5a58bd8599caf4f5 /pw.c
parentd2ae79caf381389d5bda82b324ec82f980e4a6a8 (diff)
downloadpw-eb16b04f0e8f17471d4c1bec9611040747adfdbd.tar.gz
pw-eb16b04f0e8f17471d4c1bec9611040747adfdbd.tar.bz2
pw-eb16b04f0e8f17471d4c1bec9611040747adfdbd.zip
Feature: highlight numbers of triggering lines.
When a triggered snapshot is recorded, a flag is set in all the lines which matched the trigger patterns. Whenever highlighting is enabled, the line numbers of those lines are shown in inverse.
Diffstat (limited to 'pw.c')
-rw-r--r--pw.c48
1 files changed, 39 insertions, 9 deletions
diff --git a/pw.c b/pw.c
index b12c8de..ef0ccbd 100644
--- a/pw.c
+++ b/pw.c
@@ -90,6 +90,11 @@ enum status_flags {
stat_save = stat_susp | stat_lino | stat_hlite | stat_diff
};
+enum dstr_flags {
+ dstr_cmark = 0x0001, // committed trigger mark
+ dstr_tmark = 0x0002, // tentative trigger mark
+};
+
typedef enum execode {
exec_ok, exec_msg, exec_failed
} execode;
@@ -121,6 +126,7 @@ typedef struct grep {
typedef struct dstr {
int refs;
size_t len;
+ int flags;
char str[];
} dstr;
@@ -196,6 +202,7 @@ static size_t dslen(const char *str)
static char *dsgrow(char *str, size_t len)
{
dstr *ds = str ? dstr_of(str) : 0;
+ int flags = str ? ds->flags : 0;
size_t size = sizeof *ds + len + 1;
assert (ds == 0 || ds->refs == 1);
@@ -207,6 +214,7 @@ static char *dsgrow(char *str, size_t len)
panic("out of memory");
ds->refs = 1;
+ ds->flags = flags;
ds->len = len;
ds->str[len] = 0;
@@ -430,7 +438,8 @@ static int diff(const char *line, const char *dline, int dlen, int i)
static void drawline(pwstate *pw, const char *line, int lineno, char *dline)
{
- int olen = (int) dslen(line), len = olen, pos = 0;
+ const dstr *ds = dstr_of(line);
+ int olen = (int) ds->len, len = olen, pos = 0;
int dlen = dslen(dline);
int columns = pw->columns;
int vsplit1 = pw->vsplit1;
@@ -438,11 +447,12 @@ static void drawline(pwstate *pw, const char *line, int lineno, char *dline)
int vs2pos = pw->vs2pos;
int endmark = 0;
int hlpanel = (pw->stat & stat_hlite) != 0;
+ int hlineno = hlpanel && (ds->flags & dstr_cmark);
int hldiff = (pw->stat & stat_diff) != 0 && dline != 0;
int hlite = 0;
if (lineno >= 0)
- columns -= printf("%3d ", lineno);
+ with_hl (hlineno, 0, hlite, columns -= printf("%3d ", lineno));
if (vsplit1 > 0) {
if (len <= vsplit1) {
@@ -1480,37 +1490,57 @@ int main(int argc, char **argv)
int match = 1;
for (int i = 0; i < lim; i++) {
grep *gr = triglist[i];
- if (gr && !grexec(gr, pw.circbuf[i])) {
- match = 0;
- break;
+ if (gr) {
+ if (!grexec(gr, pw.circbuf[i])) {
+ match = 0;
+ break;
+ }
+ dstr_of(pw.circbuf[i])->flags |= dstr_tmark;
}
}
trig = match;
} else if ((pw.stat & (stat_htmode | stat_susp)) == stat_htmode) {
int match = 1;
- for (int j = pw.nlines- 1, i = 0; j >= 0 && i < maxtrig;
+ for (int j = pw.nlines - 1, i = 0; j >= 0 && i < maxtrig;
j--, i++)
{
grep *gr = triglist[i];
- if (gr && !grexec(gr, pw.circbuf[j])) {
- match = 0;
- break;
+ if (gr) {
+ if (!grexec(gr, pw.circbuf[j])) {
+ match = 0;
+ break;
+ }
+ dstr_of(pw.circbuf[j])->flags |= dstr_tmark;
}
}
trig = match;
}
if (trig) {
+ trig = 0;
if (tfreq == 0 || ++pw.tcount >= tfreq) {
pw.tcount = 0;
if (sncount == 0 || ++pw.sncount < sncount) {
pw.stat |= stat_trgrd;
+ trig = 1;
} else if (sncount) {
pw.stat |= stat_trgrd | stat_oneshot;
pw.sncount = 0;
+ trig = 1;
}
}
}
+
+ for (int i = 0; i < pw.nlines; i++) {
+ dstr *ds = dstr_of(pw.circbuf[i]);
+ int flags = ds->flags;
+ int addflag = trig ? dstr_cmark : 0;
+ if ((flags & dstr_tmark) != 0) {
+ flags |= addflag;
+ flags &= ~dstr_tmark;
+ ds->flags = flags;
+ }
+ }
} else {
pw.circbuf[pw.nlines++] = line;
if ((pw.stat & (stat_susp | stat_bkgnd)) == 0) {