diff options
author | Kevin McCarthy <kevin@8t8.us> | 2017-07-05 19:09:51 -0700 |
---|---|---|
committer | Kevin McCarthy <kevin@8t8.us> | 2017-07-05 19:09:51 -0700 |
commit | 272bd7bca43ba5b63436d68824fd3e810ba640f1 (patch) | |
tree | 018a2d2589a03ba6024b0c1622f72fb59f45479d | |
parent | 277d309307d8bb3570f609742071179f05e94150 (diff) |
Add ~<() and ~>() immediate parent/children patterns. (closes #3144)
Thanks to Jeremie Le Hen for the original patch, and for his
persistence in getting this feature merged.
-rw-r--r-- | doc/manual.xml.head | 6 | ||||
-rw-r--r-- | doc/muttrc.man.head | 6 | ||||
-rw-r--r-- | mutt.h | 2 | ||||
-rw-r--r-- | pattern.c | 38 |
4 files changed, 50 insertions, 2 deletions
diff --git a/doc/manual.xml.head b/doc/manual.xml.head index a77cd069..1767f980 100644 --- a/doc/manual.xml.head +++ b/doc/manual.xml.head @@ -5213,6 +5213,12 @@ shows several ways to select messages. <row><entry>~(<emphasis>PATTERN</emphasis>)</entry><entry>messages in threads containing messages matching <emphasis>PATTERN</emphasis>, e.g. all threads containing messages from you: ~(~P)</entry></row> +<row><entry>~<(<emphasis>PATTERN</emphasis>)</entry><entry>messages +whose immediate parent matches <emphasis>PATTERN</emphasis>, +e.g. replies to your messages: ~<(~P)</entry></row> +<row><entry>~>(<emphasis>PATTERN</emphasis>)</entry><entry>messages +having an immediate child matching <emphasis>PATTERN</emphasis>, +e.g. messages you replied to: ~>(~P)</entry></row> </tbody> </tgroup> </table> diff --git a/doc/muttrc.man.head b/doc/muttrc.man.head index 97d2b3eb..e501c040 100644 --- a/doc/muttrc.man.head +++ b/doc/muttrc.man.head @@ -622,6 +622,12 @@ unreferenced message (requires threaded view) .TP ~(PATTERN) messages in threads containing messages matching a certain pattern, e.g. all threads containing messages from you: ~(~P) +.TP +~<(PATTERN) +messages whose immediate parent matches PATTERN, e.g. replies to your messages: ~<(~P) +.TP +~>(PATTERN) +messages having an immediate child matching PATTERN, e.g. messages you replied to: ~>(~P) .PD 1 .DT .PP @@ -206,6 +206,8 @@ enum MUTT_AND, MUTT_OR, MUTT_THREAD, + MUTT_PARENT, + MUTT_CHILDREN, MUTT_TO, MUTT_CC, MUTT_COLLAPSED, @@ -784,6 +784,7 @@ pattern_t *mutt_pattern_comp (/* const */ char *s, int flags, BUFFER *err) int or = 0; int implicit = 1; /* used to detect logical AND operator */ int isalias = 0; + short thread_op; const struct pattern_flags *entry; char *p; char *buf; @@ -846,9 +847,18 @@ pattern_t *mutt_pattern_comp (/* const */ char *s, int flags, BUFFER *err) mutt_pattern_free (&curlist); return NULL; } + thread_op = 0; if (*(ps.dptr + 1) == '(') + thread_op = MUTT_THREAD; + else if ((*(ps.dptr + 1) == '<') && (*(ps.dptr + 2) == '(')) + thread_op = MUTT_PARENT; + else if ((*(ps.dptr + 1) == '>') && (*(ps.dptr + 2) == '(')) + thread_op = MUTT_CHILDREN; + if (thread_op) { - ps.dptr ++; /* skip ~ */ + ps.dptr++; /* skip ~ */ + if (thread_op == MUTT_PARENT || thread_op == MUTT_CHILDREN) + ps.dptr++; p = find_matching_paren (ps.dptr + 1); if (*p != ')') { @@ -857,7 +867,7 @@ pattern_t *mutt_pattern_comp (/* const */ char *s, int flags, BUFFER *err) return NULL; } tmp = new_pattern (); - tmp->op = MUTT_THREAD; + tmp->op = thread_op; if (last) last->next = tmp; else @@ -1108,6 +1118,26 @@ static int match_threadcomplete(struct pattern_t *pat, pattern_exec_flag flags, return 0; } +static int match_threadparent(struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, THREAD *t) +{ + if (!t || !t->parent || !t->parent->message) + return 0; + + return mutt_pattern_exec(pat, flags, ctx, t->parent->message, NULL); +} + +static int match_threadchildren(struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, THREAD *t) +{ + if (!t || !t->child) + return 0; + + for (t = t->child; t; t = t->next) + if (t->message && mutt_pattern_exec(pat, flags, ctx, t->message, NULL)) + return 1; + + return 0; +} + /* Sets a value in the pattern_cache_t cache entry. * Normalizes the "true" value to 2. */ @@ -1148,6 +1178,10 @@ mutt_pattern_exec (struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, return (pat->not ^ (perform_or (pat->child, flags, ctx, h, cache) > 0)); case MUTT_THREAD: return (pat->not ^ match_threadcomplete(pat->child, flags, ctx, h->thread, 1, 1, 1, 1)); + case MUTT_PARENT: + return (pat->not ^ match_threadparent(pat->child, flags, ctx, h->thread)); + case MUTT_CHILDREN: + return (pat->not ^ match_threadchildren(pat->child, flags, ctx, h->thread)); case MUTT_ALL: return (!pat->not); case MUTT_EXPIRED: |