]> granicus.if.org Git - neomutt/commitdiff
Add ~<() and ~>() immediate parent/children patterns. (closes #3144)
authorKevin McCarthy <kevin@8t8.us>
Thu, 6 Jul 2017 02:09:51 +0000 (19:09 -0700)
committerKevin McCarthy <kevin@8t8.us>
Thu, 6 Jul 2017 02:09:51 +0000 (19:09 -0700)
Thanks to Jeremie Le Hen for the original patch, and for his
persistence in getting this feature merged.

doc/manual.xml.head
doc/muttrc.man.head
mutt.h
pattern.c

index a77cd069c38565cc6c080e10a737e7298f7477f1..1767f980828fc6be7e95d12c58e428f13cfcbcd1 100644 (file)
@@ -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>~&lt;(<emphasis>PATTERN</emphasis>)</entry><entry>messages
+whose immediate parent matches <emphasis>PATTERN</emphasis>,
+e.g. replies to your messages: ~&lt;(~P)</entry></row>
+<row><entry>~&gt;(<emphasis>PATTERN</emphasis>)</entry><entry>messages
+having an immediate child matching <emphasis>PATTERN</emphasis>,
+e.g. messages you replied to: ~&gt;(~P)</entry></row>
 </tbody>
 </tgroup>
 </table>
index 97d2b3ebe94d766eea0b26325dfcbd353db69dc4..e501c040eea8a6a88aaf817e5df2ea5209d09e07 100644 (file)
@@ -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
diff --git a/mutt.h b/mutt.h
index be42ebd191febb6be787bfcd279545481bde9091..50684fc7d30f24811d9afae429e2c140d88b5847 100644 (file)
--- a/mutt.h
+++ b/mutt.h
@@ -206,6 +206,8 @@ enum
   MUTT_AND,
   MUTT_OR,
   MUTT_THREAD,
+  MUTT_PARENT,
+  MUTT_CHILDREN,
   MUTT_TO,
   MUTT_CC,
   MUTT_COLLAPSED,
index 1729fe3da23e7c59a434e92b86ccd3f9bdcc3edf..f788b2e93b9ecd0eb24de969667279520162292c 100644 (file)
--- a/pattern.c
+++ b/pattern.c
@@ -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: