summaryrefslogtreecommitdiff
path: root/mail/mutt-devel/files/patch-threadcomplete
blob: 6034ece2bd99af11eddd4e930fc067c8acd7fe5c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
diff -Nru a/PATCHES b/PATCHES
--- PATCHES
+++ PATCHES
@@ -0,0 +1 @@
+patch-1.5.6+20040904.tg.mutt-thread.3
diff -Nru a/doc/manual.sgml.head b/doc/manual.sgml.head
--- doc/manual.sgml.head.orig	Fri Feb  4 08:15:50 2005
+++ doc/manual.sgml.head	Fri Feb  4 08:19:51 2005
@@ -1903,6 +1903,8 @@
 ~z [MIN]-[MAX]  messages with a size in the range MIN to MAX *)
 ~=              duplicated messages (see $duplicate_threads)
 ~$              unreferenced messages (requires threaded view)
+~(PATTERN)      messages in threads containing messages matching a certain
+                pattern, e.g. all threads containing messages from you: ~(~P)
 </verb></tscreen>
 
 Where EXPR, USER, ID, and SUBJECT are 
diff -Nru a/mutt.h b/mutt.h
--- mutt.h	2004-07-24 12:27:21 +02:00
+++ mutt.h	2004-09-04 12:36:18 +02: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
--- pattern.c	2004-07-24 12:27:23 +02:00
+++ pattern.c	2004-09-04 12:37:52 +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,29 @@
   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)
+    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 +1014,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:
--- doc/manual.sgml.head.orig2	Mon Sep  6 09:24:16 2004
+++ doc/manual.sgml.head	Mon Sep  6 09:25:41 2004
@@ -1773,6 +1773,8 @@
 messages:
 
 <tscreen><verb>
+~a              messages in threads that contain at least one tagged message;
+                this is the same as ~(~T) [see below for ~(..)]
 ~A              all messages
 ~b EXPR         messages which contain EXPR in the message body
 ~B EXPR         messages which contain EXPR in the whole message
--- mutt.h.orig2	Mon Sep  6 09:24:17 2004
+++ mutt.h	Mon Sep  6 09:27:04 2004
@@ -212,6 +212,7 @@
   M_LIMIT,
   M_EXPIRED,
   M_SUPERSEDED,
+  M_THREADCOMPLETE,
 
   /* actions for mutt_pattern_comp/mutt_pattern_exec */
   M_AND,
--- pattern.c.orig2	Sun Feb 13 09:05:57 2005
+++ pattern.c	Sun Feb 13 09:08:06 2005
@@ -48,6 +48,7 @@
 }
 Flags[] =
 {
+  { 'a', M_THREADCOMPLETE,	0,		NULL },
   { 'A', M_ALL,			0,		NULL },
   { 'b', M_BODY,		M_FULL_MSG,	eat_regexp },
   { 'B', M_WHOLE_MSG,		M_FULL_MSG,	eat_regexp },
@@ -1085,6 +1086,16 @@
 					pat->alladdr, 2, h->env->to, h->env->cc)));
     case M_LIST:
       return (pat->not ^ (h->env && mutt_is_list_recipient (pat->alladdr, h->env->to, h->env->cc)));
+    case M_THREADCOMPLETE:
+      { static pattern_t tmp;
+        static short pattern_set = 0;
+        if(! pattern_set) {
+          memset (&tmp, 0, sizeof (tmp));
+          tmp.op = M_TAG;
+          pattern_set = 1;
+        }
+        return (pat->not ^ (h->env && match_threadcomplete(&tmp, flags, ctx, h->thread, 1, 1, 1, 1)));
+      } 
     case M_PERSONAL_RECIP:
       return (pat->not ^ (h->env && match_user (pat->alladdr, h->env->to, h->env->cc)));
     case M_PERSONAL_FROM: