diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-05-07 10:52:18 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-05-07 10:52:18 -0700 |
commit | a9484ec7c9e91a28d13db7351f5db6970433a857 (patch) | |
tree | 8f2ac9ba0fa48fda3f2e93f8d549a6f62ced9762 | |
parent | 7567f548a7de8ac4d81168c975a7b248b8734bb9 (diff) | |
download | pw-a9484ec7c9e91a28d13db7351f5db6970433a857.tar.gz pw-a9484ec7c9e91a28d13db7351f5db6970433a857.tar.bz2 pw-a9484ec7c9e91a28d13db7351f5db6970433a857.zip |
New feature: trigger frequency and snapshot count.
-rw-r--r-- | pw.1 | 47 | ||||
-rw-r--r-- | pw.c | 67 |
2 files changed, 103 insertions, 11 deletions
@@ -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" @@ -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; |