<<< Date Index >>>     <<< Thread Index >>>

[PATCH] Parent match



Hi,

Attached you will find a patch introducing a new match pattern: =().
Thanks to this pattern you can match the parent message of messages
matching the inner pattern.

I needed this pattern because I went offline for a while with a great
bunch of mails to read and I used mutt to copy a snapshot of my maildir
into a mailbox on my thumbdrive.  Back online, I performed the reverse
process, copying all the mails from the mailbox to the maildir.  The
problem was that original email was still unread while the duplicate one
that has been copied to and fro was read.  With the current match
patterns available in mutt it was not possible, whereas with this patch
I could use: =(~= !~N)

I chose =() because it didn't shuffle the code too much, albeit I
thought that ^() would have been easier to remember.  If you prefer this
second form, I can manage to send another patch.

Do you think this patch can be merged within the main trunk?

Thank you for reading.
Best regards,
-- 
Jeremie Le Hen
diff -urp mutt-1.5.18/doc/muttrc.man.head 
mutt-1.5.18-parent_match/doc/muttrc.man.head
--- mutt-1.5.18/doc/muttrc.man.head     2008-01-28 03:20:21.000000000 +0100
+++ mutt-1.5.18-parent_match/doc/muttrc.man.head        2008-11-13 
12:01:32.000000000 +0100
@@ -577,6 +577,9 @@ unreferenced message (requries threaded 
 .TP
 ~(PATTERN)
 messages in threads containing messages matching a certain pattern, e.g. all 
threads containing messages from you: ~(~P)
+.TP
+=(PATTERN)
+parent message of messages matching a certain pattern, e.g. all parent 
messages havind duplicates messages: =(~=)
 .PD 1
 .DT
 .PP
diff -urp mutt-1.5.18/mutt.h mutt-1.5.18-parent_match/mutt.h
--- mutt-1.5.18/mutt.h  2008-01-30 05:26:50.000000000 +0100
+++ mutt-1.5.18-parent_match/mutt.h     2008-11-12 14:28:07.000000000 +0100
@@ -212,6 +212,7 @@ enum
   M_AND,
   M_OR,
   M_THREAD,
+  M_PARENT,
   M_TO,
   M_CC,
   M_COLLAPSED,
diff -urp mutt-1.5.18/pattern.c mutt-1.5.18-parent_match/pattern.c
--- mutt-1.5.18/pattern.c       2008-01-30 05:26:51.000000000 +0100
+++ mutt-1.5.18-parent_match/pattern.c  2008-11-13 12:31:48.000000000 +0100
@@ -782,6 +782,7 @@ pattern_t *mutt_pattern_comp (/* const *
   int alladdr = 0;
   int or = 0;
   int implicit = 1;    /* used to detect logical AND operator */
+  int operator;
   struct pattern_flags *entry;
   char *p;
   char *buf;
@@ -835,6 +836,7 @@ pattern_t *mutt_pattern_comp (/* const *
       case '~':
        if (*(ps.dptr + 1) == '(') 
         {
+         operator = *ps.dptr;
          ps.dptr ++; /* skip ~ */
          p = find_matching_paren (ps.dptr + 1);
          if (*p != ')')
@@ -844,7 +846,10 @@ pattern_t *mutt_pattern_comp (/* const *
            return NULL;
          }
          tmp = new_pattern ();
-         tmp->op = M_THREAD;
+         if (operator == '=')
+           tmp->op = M_PARENT;
+         else
+           tmp->op = M_THREAD;
          if (last)
            last->next = tmp;
          else
@@ -1087,6 +1092,29 @@ static int match_threadcomplete(struct p
   return 0;
 }
 
+static int match_directchilds(struct pattern_t *pat, pattern_exec_flag flags, 
CONTEXT *ctx, THREAD *t)
+{
+  HEADER *h;
+
+  /* Not sure this is needed, but harmless anyway */
+  if (!t)
+    return 0;
+  if (!t->child)
+    return 0;
+  t = t->child;
+  /* Not sure this is needed, but harmless anyway */
+  while (t->prev)
+    t = t->prev;
+  while (t) {
+    h = t->message;
+    if(h)
+      if(mutt_pattern_exec(pat, flags, ctx, h))
+       return 1;
+    t = t->next;
+  }
+  return 0;
+}
+
 /* flags
        M_MATCH_FULL_ADDRESS    match both personal and machine address */
 int
@@ -1100,6 +1128,8 @@ mutt_pattern_exec (struct pattern_t *pat
       return (pat->not ^ (perform_or (pat->child, flags, ctx, h) > 0));
     case M_THREAD:
       return (pat->not ^ match_threadcomplete(pat->child, flags, ctx, 
h->thread, 1, 1, 1, 1));
+    case M_PARENT:
+      return (pat->not ^ match_directchilds(pat->child, flags, ctx, 
h->thread));
     case M_ALL:
       return (!pat->not);
     case M_EXPIRED: