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

patch: thread_pattern



Hello,

this patch enables mutt to match threads that contain messages matching
a certain pattern.

The .2 version was written by Thomas Glanzmann and uses a nicer syntax
than the .1 version from april.

Comments welcome.

http://www.df7cb.de/projects/mutt/thread_pattern/

Christoph
-- 
cb@xxxxxxxx | http://www.df7cb.de/
thread_pattern v2
-----------------
Christoph Berg <cb@xxxxxxxx>
Thomas Glanzmann <sithglan@xxxxxxxxxxxxxxxxxxxx>

This this the thread_pattern patch for mutt. It is meant to extend Nicolas
Rachinsky's threadcomplete patch [1], and so far, I've recycled his
match_threadcomplete function.

This patch allows to match (tag, limit, search...) mesages that are in threads
containing messages matching a certain pattern. The syntax for this is ~(...).
Examples:
  * all threads containing messages from you: ~(~P)
  * "interesting" threads: ~(!~D(!~R|~F|~P))

The patch homepage is at [2].

Bugs so far:
  * doesn't seem to work with pseudo threads yet (the threadcomplete patch
    does, I'll have to investigate this)

Things to think about/TODO:
  * support for matching sub-threads, parent matching (like the parent_match
    patch [3]), ancestor matching
  * include documentation patch.

Changelog:
  * v1 2004-04-09: First version.
  * v2 2004-08-24: Thomas updated the patch to use the nicer ~(...) syntax
    instead of the old <...> syntax, thanks.

References:
  [1] http://www.rachinsky.de/nicolas/mutt.html
  [3] http://www.df7cb.de/projects/mutt/
  [2] http://www.schrab.com/aaron/mutt/


Christoph Berg

----------------------------------

diff -Nru a/PATCHES b/PATCHES
--- a/PATCHES   2004-07-24 12:27:17 +02:00
+++ b/PATCHES   2004-08-22 02:01:52 +02:00
@@ -0,0 +1 @@
+patch-1.5.6+20040824.cb+tg.thread_pattern.2
diff -Nru a/mutt.h b/mutt.h
--- a/mutt.h    2004-07-24 12:27:21 +02:00
+++ b/mutt.h    2004-02-14 05:00:41 +01:00
@@ -211,6 +211,7 @@
   /* actions for mutt_pattern_comp/mutt_pattern_exec */
   M_AND,
   M_OR,
+  M_THREAD,
   M_TO,
   M_CC,
   M_COLLAPSED,
diff -Nru a/pattern.c b/pattern.c
--- a/pattern.c 2004-07-24 12:27:23 +02:00
+++ b/pattern.c 2004-08-24 14:20:55 +02:00
@@ -700,7 +700,7 @@
 pattern_t *mutt_pattern_comp (/* const */ char *s, int flags, BUFFER *err)
 {
   pattern_t *curlist = NULL;
-  pattern_t *tmp;
+  pattern_t *tmp, *tmp2;
   pattern_t *last = NULL;
   int not = 0;
   int alladdr = 0;
@@ -755,6 +755,39 @@
        alladdr = 0;
        break;
       case '~':
+       if (*(ps.dptr + 1) == '(') {
+               ps.dptr ++; /* skip ~ */
+               p = find_matching_paren (ps.dptr + 1);
+               if (*p != ')')
+               {
+                 snprintf (err->data, err->dsize, _("mismatched brackets: 
%s"), ps.dptr);
+                 mutt_pattern_free (&curlist);
+                 return NULL;
+               }
+               tmp = new_pattern ();
+               tmp->op = M_THREAD;
+               if (last)
+                 last->next = tmp;
+               else
+                 curlist = tmp;
+               last = tmp;
+               tmp->not ^= not;
+               tmp->alladdr |= alladdr;
+               not = 0;
+               alladdr = 0;
+               /* compile the sub-expression */
+               buf = mutt_substrdup (ps.dptr + 1, p);
+               if ((tmp2 = mutt_pattern_comp (buf, flags, err)) == NULL)
+               {
+                 FREE (&buf);
+                 mutt_pattern_free (&curlist);
+                 return NULL;
+               }
+               FREE (&buf);
+               tmp->child = tmp2;
+               ps.dptr = p + 1; /* restore location */
+               break;
+       }
        if (implicit && or)
        {
          /* A | B & C == (A | B) & C */
@@ -945,6 +978,30 @@
   return alladdr;
 }
 
+static int match_threadcomplete(struct pattern_t *pat, pattern_exec_flag 
flags, CONTEXT *ctx, THREAD *t,int left,int up,int right,int down)
+{
+  int a;
+  HEADER *h;
+
+  if(!t)
+    return 0;
+  h = t->message;
+  if(!h)
+    return 0;
+  if(mutt_pattern_exec(pat, flags, ctx, h))
+    return 1;
+
+  if(up && (a=match_threadcomplete(pat, flags, ctx, t->parent,1,1,1,0)))
+    return a;
+  if(right && t->parent && (a=match_threadcomplete(pat, flags, ctx, 
t->next,0,0,1,1)))
+    return a;
+  if(left && t->parent && (a=match_threadcomplete(pat, flags, ctx, 
t->prev,1,0,0,1)))
+    return a;
+  if(down && (a=match_threadcomplete(pat, flags, ctx, t->child,1,0,1,1)))
+    return a;
+  return 0;
+}
+
 /* flags
        M_MATCH_FULL_ADDRESS    match both personal and machine address */
 int
@@ -958,6 +1015,8 @@
       return (pat->not ^ (perform_and (pat->child, flags, ctx, h) > 0));
     case M_OR:
       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_ALL:
       return (!pat->not);
     case M_EXPIRED:

Attachment: signature.asc
Description: Digital signature