diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-04-30 12:09:30 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-04-30 12:09:30 -0700 |
commit | 768533744141f9570e1323c65751881e53d891a7 (patch) | |
tree | b84e8ec9138effaa55b2627e08bb9f9663ad4c36 /pw.c | |
parent | 05be2ff6723ed696479737050d9654c97e7f8818 (diff) | |
download | pw-768533744141f9570e1323c65751881e53d891a7.tar.gz pw-768533744141f9570e1323c65751881e53d891a7.tar.bz2 pw-768533744141f9570e1323c65751881e53d891a7.zip |
New feature: multi-line triggering.
Diffstat (limited to 'pw.c')
-rw-r--r-- | pw.c | 115 |
1 files changed, 85 insertions, 30 deletions
@@ -23,6 +23,8 @@ #define ESC 27 #define DEL 127 +#define min(a, b) ((a) < (b) ? (a) : (b)) + #ifdef __GNUC__ #define printf_attr(fmtpos, vargpos) __attribute__ ((format (printf, \ fmtpos, vargpos))) @@ -64,8 +66,10 @@ static int regex_flags = 0; static char **snapshot; static int snaplines; -static char *trigpat; -static regex_t trigex; + +#define maxtrig 100 +static char *trigpat[maxtrig]; +static regex_t trigex[maxtrig]; static grep grepstack[maxgrep]; static int ngrep; @@ -296,10 +300,21 @@ static void drawstatus(int columns, unsigned stat, char *cmd) } } - if ((stat & stat_htmode)) - ptr += snprintf(ptr, end - ptr, "TRIG (/%s) ", trigpat); - else if ((stat & stat_ttmode)) - ptr += snprintf(ptr, end - ptr, "TRIG (?%s) ", trigpat); + if ((stat & (stat_htmode | stat_ttmode))) { + ptr += snprintf(ptr, end - ptr, "TRIG%c (", + (stat & stat_htmode) ? '/' : '?'); + for (int i = 0, first = 1; i < maxtrig; i++) { + if (trigpat[i]) { + if (!first) + ptr += snprintf(ptr, end - ptr, ", "); + if (i > 0) + ptr += snprintf(ptr, end - ptr, "[%d]", i + 1); + ptr += snprintf(ptr, end - ptr, "%s", trigpat[i]); + first = 0; + } + } + ptr += snprintf(ptr, end - ptr, ") "); + } if ((stat & stat_susp)) ptr += snprintf(ptr, end - ptr, "SUSPENDED "); @@ -716,17 +731,32 @@ int main(int argc, char **argv) } } if (line) { - if ((stat & stat_htmode)) - if (regexec(&trigex, line, 0, NULL, 0) == 0) - stat |= stat_trgrd; if (nlines == maxlines) { dsdrop(circbuf[0]); memmove(circbuf, circbuf + 1, (nlines - 1) * sizeof *circbuf); circbuf[nlines - 1] = line; stat |= stat_dirty; - if ((stat & stat_ttmode)) - if (regexec(&trigex, circbuf[0], 0, NULL, 0) == 0) + if ((stat & stat_ttmode)) { + int lim = min(maxtrig, nlines); + int trig = 1; + for (int i = 0; i < lim; i++) + if (trigpat[i] && regexec(&trigex[i], circbuf[i], 0, NULL, 0) != 0) { + trig = 0; + break; + } + if (trig) stat |= stat_trgrd; + } else if ((stat & stat_htmode)) { + int trig = 1; + for (int j = nlines - 1, i = 0; j >= 0 && i < maxtrig; j--, i++) { + if (trigpat[i] && regexec(&trigex[i], circbuf[j], 0, NULL, 0) != 0) { + trig = 0; + break; + } + } + if (trig) + stat |= stat_trgrd; + } } else { circbuf[nlines++] = line; if ((stat & stat_susp) == 0) { @@ -944,6 +974,8 @@ int main(int argc, char **argv) break; case CR: case ctrl('c'): if (ch == CR) { + unsigned trig = (cmdcount == UINT_MAX || cmdcount == 0 + ? 0 : cmdcount - 1); if (cmdbuf[1]) { unsigned *pnhist = (kbd_state == kbd_colon ? &ncmdhist : &npathist); @@ -960,38 +992,61 @@ int main(int argc, char **argv) } } - if (kbd_state == kbd_trig) { - if (trigpat) { - regfree(&trigex); - dsdrop(trigpat); - trigpat = 0; - } - stat &= ~(stat_htmode | stat_ttmode); - } - if (kbd_state == kbd_colon && cmdbuf[1]) { execute(cmdbuf, &stat); if (cmdbuf[0] != 0) { kbd_state = kbd_result; break; } - } else if (cmdbuf[1]) { + } else if (kbd_state == kbd_trig && (int) trig < maxlines && trig < maxtrig) { int err; - trigpat = dsdup(cmdbuf + 1); - if ((err = regcomp(&trigex, trigpat, - regex_flags | REG_NOSUB))) - { - regerror(err, &trigex, cmdbuf, sizeof cmdbuf); + char *pat = dsdup(cmdbuf + 1); + regex_t regex; + + if (*pat && (err = regcomp(®ex, pat, regex_flags | REG_NOSUB))) { + regerror(err, ®ex, cmdbuf, sizeof cmdbuf); if (columns < (int) sizeof cmdbuf - 1) cmdbuf[columns] = 0; kbd_state = kbd_result; - dsdrop(trigpat); - trigpat = 0; - break; + } else { + if ((cmdbuf[0] == '/' && (stat & stat_ttmode)) || + (cmdbuf[0] == '?' && (stat & stat_htmode))) + { + for (int i = 0; i < maxtrig; i++) { + if (trigpat[i]) { + regfree(&trigex[i]); + dsdrop(trigpat[i]); + trigpat[i] = 0; + } + } + } + + if (trigpat[trig]) { + regfree(&trigex[trig]); + dsdrop(trigpat[trig]); + trigpat[trig] = 0; + } + + if (*pat) { + regfree(®ex); + regcomp(&trigex[trig], pat, regex_flags | REG_NOSUB); + trigpat[trig] = dsdup(pat); + } + } + dsdrop(pat); + } + + if (kbd_state == kbd_trig) { + stat &= ~(stat_htmode | stat_ttmode); + for (int i = 0; i < maxtrig; i++) { + if (trigpat[i]) { + stat |= (cmdbuf[0] == '/' ? stat_htmode : stat_ttmode); + break; + } } - stat |= (cmdbuf[0] == '/' ? stat_htmode : stat_ttmode); } } + kbd_state = kbd_cmd; curcmd = 0; cmdcount = UINT_MAX; |