aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-05-07 10:52:18 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-05-07 10:52:18 -0700
commita9484ec7c9e91a28d13db7351f5db6970433a857 (patch)
tree8f2ac9ba0fa48fda3f2e93f8d549a6f62ced9762
parent7567f548a7de8ac4d81168c975a7b248b8734bb9 (diff)
downloadpw-a9484ec7c9e91a28d13db7351f5db6970433a857.tar.gz
pw-a9484ec7c9e91a28d13db7351f5db6970433a857.tar.bz2
pw-a9484ec7c9e91a28d13db7351f5db6970433a857.zip
New feature: trigger frequency and snapshot count.
-rw-r--r--pw.147
-rw-r--r--pw.c67
2 files changed, 103 insertions, 11 deletions
diff --git a/pw.1 b/pw.1
index 2966e1f..a596249 100644
--- a/pw.1
+++ b/pw.1
@@ -621,6 +621,53 @@ of whether they were compiled as ERE or BRE.
Any other command string results in a brief error message.
+.IP "\fB:f\fP \fIinteger\fP"
+Capture a triggered snapshot only once every
+.I integer
+times the trigger event occurs If
+.I integer
+is 0 or 1, then trigger on every matching event.
+
+When
+.I integer
+is 1 or more,
+.I pw
+counts the number of trigger events which occur. Only when the counter reaches
+the specified value is a snapshot taken; and then the counter is reset to zero.
+
+There is an internal difference between the value 0 and 1 in that
+0 disables the feature: no counting takes place.
+
+.IP "\fB:c\fP [\fIinteger\fP]"
+Limit the number of trigger-driven captures to the count specified by
+.IR integer ,
+after which capture is automatically suspended, as if by the
+.B Space
+command.
+
+If
+.IR integer
+is omitted, then the count of snapshots is reset to zero, without
+affecting the configuration that was previously specified by a
+.B :c
+command with an argument.
+
+If
+.IR integer
+is zero, then the counting mode is disabled; capture does not suspend
+regardless of how many capture events occur.
+
+Note that capture events are counted, not trigger events.
+Thus, if the capture frequency is reduced using the
+.B :f
+command, then the ignored trigger events are not counted.
+
+When the required number of captures is taken, and capture is suspended,
+the trigger count is reset to zero. Thus when the
+.B Enter
+command is used to resume capture, the same number of capture events
+will have to occur again before the next automatic suspension.
+
.SH OPTIONS
.IP "\fB-i\fP \fIreal\fP"
diff --git a/pw.c b/pw.c
index 6dd5d1e..260a07d 100644
--- a/pw.c
+++ b/pw.c
@@ -79,6 +79,7 @@ enum status_flags {
stat_lino = 0x0100, // render line numbers
stat_bkgnd = 0x0200, // running in the background
stat_hlite = 0x0400, // running in the background
+ stat_oneshot = 0x0800, // running in the background
};
typedef struct pwstate {
@@ -89,6 +90,7 @@ typedef struct pwstate {
int hist;
int columns;
unsigned stat;
+ int sncount, tcount;
char *curcmd, *savedcmd;
char cmdbuf[cmdsize];
} pwstate;
@@ -121,6 +123,8 @@ static grep grepstack[maxgrep];
static int ngrep;
static grep *triglist[maxtrig];
+static int sncount;
+static int tfreq;
static char **cmdhist;
static int ncmdhist;
@@ -548,7 +552,9 @@ static void redraw(pwstate *pw)
updln = 1;
for (int i = 0; i < pw->nlines; i++)
snapshot[0][i] = dsref(pw->circbuf[i]);
- pw->stat &= ~(stat_dirty | stat_trgrd);
+ if ((pw->stat & stat_oneshot))
+ pw->stat |= stat_susp;
+ pw->stat &= ~(stat_dirty | stat_trgrd | stat_oneshot);
updln = 1;
} else if ((pw->stat & stat_force)) {
pw->stat &= ~stat_force;
@@ -760,6 +766,34 @@ static void execute(pwstate *pw, char *cmd)
case 'B':
regex_flags = 0;
break;
+ case 'c':
+ if (arg[0] == 0) {
+ pw->sncount = 0;
+ } else {
+ char *err = 0;
+ int val = getznn(arg, &err);
+ if (val < 0)
+ snprintf(cmd, cmdsize, "bad trigger count: %s", err);
+ else
+ sncount = val;
+ dsdrop(err);
+ }
+ break;
+ case 'f':
+ if (arg[0] == 0) {
+ sprintf(cmd, "frequency argument required!");
+ break;
+ }
+ {
+ char *err = 0;
+ int val = getznn(arg, &err);
+ if (val < 0)
+ snprintf(cmd, cmdsize, "bad trigger freq: %s", err);
+ else
+ tfreq = val;
+ dsdrop(err);
+ }
+ break;
default:
sprintf(cmd, "bad command");
break;
@@ -1079,36 +1113,47 @@ int main(int argc, char **argv)
}
if (line) {
if (pw.nlines == maxlines) {
+ int trig = 0;
dsdrop(pw.circbuf[0]);
memmove(pw.circbuf, pw.circbuf + 1,
(pw.nlines - 1) * sizeof *pw.circbuf);
pw.circbuf[pw.nlines - 1] = line;
pw.stat |= stat_dirty;
- if ((pw.stat & stat_ttmode)) {
+ if ((pw.stat & (stat_ttmode | stat_susp)) == stat_ttmode) {
int lim = min(maxtrig, pw.nlines);
- int trig = 1;
+ int match = 1;
for (int i = 0; i < lim; i++) {
grep *gr = triglist[i];
if (gr && !grexec(gr, pw.circbuf[i])) {
- trig = 0;
+ match = 0;
break;
}
}
- if (trig)
- pw.stat |= stat_trgrd;
- } else if ((pw.stat & stat_htmode)) {
- int trig = 1;
+ 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;
j--, i++)
{
grep *gr = triglist[i];
if (gr && !grexec(gr, pw.circbuf[j])) {
- trig = 0;
+ match = 0;
break;
}
}
- if (trig)
- pw.stat |= stat_trgrd;
+ trig = match;
+ }
+
+ if (trig) {
+ if (tfreq == 0 || ++pw.tcount >= tfreq) {
+ pw.tcount = 0;
+ if (sncount == 0 || ++pw.sncount < sncount) {
+ pw.stat |= stat_trgrd;
+ } else if (sncount) {
+ pw.stat |= stat_trgrd | stat_oneshot;
+ pw.sncount = 0;
+ }
+ }
}
} else {
pw.circbuf[pw.nlines++] = line;