commit 2c0741197de27a503bbd11b2f97bd8d53218611e
parent e40a241de1201c089d999bfc5b38194cb815b073
Author: hhvn <dev@hhvn.uk>
Date: Wed, 23 Mar 2022 17:52:32 +0000
Search displayed text with /grep
Diffstat:
5 files changed, 58 insertions(+), 17 deletions(-)
diff --git a/src/commands.c b/src/commands.c
@@ -314,11 +314,15 @@ struct Command commands[] = {
{"grep", command_grep, 0, {
"usage: /grep [-iE] [regex]",
"Search selected buffer",
- " -i: case insensitive",
- " -E: posix extended regex",
- "If no argument supplied, clears previous search",
- "Searches are also cleared after selecting another buffer",
- "See also config variables: regex.extended and regex.icase", NULL}},
+ " -i case insensitive",
+ " -E posix extended regex",
+ " -raw search raw message rather than displayed text",
+ "Displays any lines that match the regex in the current buffer,",
+ "unless -raw is specified. For convenience, all whitespace is",
+ "squeezed down to one space.",
+ "If no argument is supplied, clears previous search.",
+ "Searches are also cleared after selecting another buffer.",
+ "See also variables: regex.extended and regex.icase", NULL}},
{"clear", command_clear, 0, {
"usage: /clear [-tmp] [-err] [-serr] [-log]",
"Clear selected buffer of messages.",
@@ -1433,12 +1437,14 @@ COMMAND(
command_grep) {
struct History *p;
regex_t re;
- int regopt = 0, ret;
- char errbuf[1024];
- enum { opt_extended, opt_icase };
+ size_t i;
+ int regopt = 0, ret, raw = 0;
+ char errbuf[1024], *s;
+ enum { opt_extended, opt_icase, opt_raw };
static struct CommandOpts opts[] = {
{"E", CMD_NARG, opt_extended},
{"i", CMD_NARG, opt_icase},
+ {"raw", CMD_NARG, opt_raw},
{NULL, 0, 0},
};
@@ -1458,6 +1464,9 @@ command_grep) {
case opt_icase:
regopt |= REG_ICASE;
break;
+ case opt_raw:
+ raw = 1;
+ break;
}
}
@@ -1478,11 +1487,42 @@ command_grep) {
/* Get oldest, but don't set p to NULL */
for (p = selected.history->history; p && p->next; p = p->next);
- /* Traverse until we hit a message generated by us */
+ /* Traverse until we hit a message already generated by /grep */
for (; p && !(p->options & HIST_GREP); p = p->prev) {
- /* TODO: matching ui_format result by default,
- * option for matching raw */
- if (regexec(&re, p->raw, 0, NULL, 0) == 0)
+ if (!raw && !p->format)
+ p->format = estrdup(ui_hformat(&windows[Win_main], p));
+ if (!raw && !p->rformat) {
+ p->rformat = emalloc(strlen(p->format) + 1);
+ /* since only one or zero characters are added to
+ * rformat for each char in format, and both are the
+ * same sie, there is no need to expand rformat or
+ * truncate it. */
+ for (i = 0, s = p->format; s && *s; s++) {
+ switch (*s) {
+ case 2: case 9: case 15: case 18: case 21:
+ break;
+ case 3:
+ if (*s && isdigit(*(s+1)))
+ s += 1;
+ if (*s && isdigit(*(s+1)))
+ s += 1;
+ if (*s && *(s+1) == ',' && isdigit(*(s+2)))
+ s += 2;
+ else
+ break; /* break here to avoid needing to check back for comma in next if */
+ if (isdigit(*(s+1)))
+ s += 1;
+ break;
+ case '\n': case ' ':
+ while (*(s+1) == ' ')
+ s++;
+ /* fallthrough */
+ default:
+ p->rformat[i++] = *s != '\n' ? *s : ' ';
+ }
+ }
+ }
+ if (regexec(&re, raw ? p->raw : p->rformat, 0, NULL, 0) == 0)
hist_addp(selected.history, p, p->activity, p->options | HIST_GREP | HIST_TMP);
}
diff --git a/src/hist.c b/src/hist.c
@@ -38,6 +38,7 @@ hist_free(struct History *history) {
}
pfree(&history->raw);
pfree(&history->format);
+ pfree(&history->rformat);
pfree(&history);
}
@@ -66,7 +67,7 @@ hist_create(struct HistInfo *histinfo, struct Nick *from, char *msg,
new->activity = activity;
new->raw = estrdup(msg);
new->_params = new->params = param_create(msg);
- new->format = NULL;
+ new->rformat = new->format = NULL;
new->options = options;
new->origin = histinfo;
diff --git a/src/mem.c b/src/mem.c
@@ -114,4 +114,3 @@ wctos(wchar_t *str) {
wcstombs(ret, str, len);
return ret;
}
-
diff --git a/src/struct.h b/src/struct.h
@@ -69,6 +69,7 @@ struct History {
char **_params; /* contains all params, free from here */
char **params; /* contains params without perfix, don't free */
char *format; /* cached ui_format */
+ char *rformat; /* cached format without mirc codes */
struct HistInfo *origin;
struct Nick *from;
struct History *next;
diff --git a/src/ui.c b/src/ui.c
@@ -863,10 +863,10 @@ ui_redraw(void) {
* or format.* settings are changed. */
if (selected.history) {
for (p = selected.history->history; p; p = p->next) {
- if (p->format) {
+ if (p->format)
pfree(&p->format);
- p->format = NULL;
- }
+ if (p->rformat)
+ pfree(&p->rformat);
}
}
}