]> git.pld-linux.org Git - packages/mutt.git/blame - mutt-cd.edit_threads.patch
- massive change: BR: openssl-devel >= 0.9.6m
[packages/mutt.git] / mutt-cd.edit_threads.patch
CommitLineData
9de0e450 1diff -pruN2 mutt-1.3.27.orig/thread.c mutt-1.3.27/thread.c
2--- mutt-1.3.27.orig/thread.c Wed Jan 16 21:43:59 2002
3+++ mutt-1.3.27/thread.c Wed Jan 23 22:26:56 2002
4@@ -1285,2 +1285,78 @@ HASH *mutt_make_subj_hash (CONTEXT *ctx)
5 return hash;
6 }
7+
8+static void clean_references (THREAD *brk, THREAD *cur)
9+{
10+ THREAD *p;
11+ LIST *ref = NULL;
12+ int done = 0;
13+
14+ for (; cur; cur = cur->next, done = 0)
15+ {
16+ /* parse subthread recursively */
17+ clean_references (brk, cur->child);
18+
19+ if (!cur->message)
20+ break; /* skip pseudo-message */
21+
22+ /* Looking for the first bad reference according to the new threading.
23+ * Optimal since Mutt stores the references in reverse order, and the
24+ * first loop should match immediatly for mails respecting RFC2822. */
25+ for (p = brk; !done && p; p = p->parent)
26+ for (ref = cur->message->env->references; p->message && ref; ref = ref->next)
27+ if (!mutt_strcasecmp (ref->data, p->message->env->message_id))
28+ {
29+ done = 1;
30+ break;
31+ }
32+
33+ if (done)
34+ {
35+ /* clearing the References: header from obsolete Message-Id(s) */
36+ mutt_free_list (&ref->next);
37+
38+ cur->message->refs_changed = cur->message->changed = 1;
39+ }
40+ }
41+}
42+
43+void mutt_break_thread (HEADER *hdr)
44+{
45+ mutt_free_list (&hdr->env->in_reply_to);
46+ mutt_free_list (&hdr->env->references);
47+ hdr->irt_changed = hdr->refs_changed = hdr->changed = 1;
48+
49+ clean_references (hdr->thread, hdr->thread->child);
50+}
51+
52+static int link_threads (HEADER *parent, HEADER *child, CONTEXT *ctx)
53+{
54+ if (child == parent)
55+ return 0;
56+
57+ mutt_break_thread (child);
58+
59+ child->env->in_reply_to = mutt_new_list ();
60+ child->env->in_reply_to->data = safe_strdup (parent->env->message_id);
61+
62+ mutt_set_flag (ctx, child, M_TAG, 0);
63+
64+ child->irt_changed = child->changed = 1;
65+ return 1;
66+}
67+
68+int mutt_link_threads (HEADER *cur, HEADER *last, CONTEXT *ctx)
69+{
70+ int i, changed = 0;
71+
72+ if (!last)
73+ {
74+ for (i = 0; i < ctx->vcount; i++)
75+ if (ctx->hdrs[Context->v2r[i]]->tagged)
76+ changed |= link_threads (cur, ctx->hdrs[Context->v2r[i]], ctx);
77+ }
78+ else
79+ changed = link_threads (cur, last, ctx);
80+
81+ return changed;
82+}
83diff -pruN2 mutt-1.3.27.orig/OPS mutt-1.3.27/OPS
84--- mutt-1.3.27.orig/OPS Tue Sep 11 12:50:50 2001
85+++ mutt-1.3.27/OPS Wed Jan 23 22:26:56 2002
86@@ -95,4 +95,5 @@ OP_LIST_REPLY "reply to specified mailin
87 OP_MACRO "execute a macro"
88 OP_MAIL "compose a new mail message"
89+OP_MAIN_BREAK_THREAD "break the thread in two"
90 OP_MAIN_CHANGE_FOLDER "open a different folder"
91 OP_MAIN_CHANGE_FOLDER_READONLY "open a different folder in read only mode"
92@@ -104,4 +105,5 @@ OP_MAIN_FIRST_MESSAGE "move to the first
93 OP_MAIN_LAST_MESSAGE "move to the last message"
94 OP_MAIN_LIMIT "show only messages matching a pattern"
95+OP_MAIN_LINK_THREADS "link tagged message to the current one"
96 OP_MAIN_NEXT_NEW "jump to the next new message"
97 OP_MAIN_NEXT_SUBTHREAD "jump to the next subthread"
98diff -pruN2 mutt-1.3.27.orig/copy.c mutt-1.3.27/copy.c
99--- mutt-1.3.27.orig/copy.c Mon Dec 3 11:17:57 2001
100+++ mutt-1.3.27/copy.c Wed Jan 23 22:26:56 2002
101@@ -92,4 +92,10 @@ mutt_copy_hdr (FILE *in, FILE *out, long
102 ascii_strncasecmp ("Lines:", buf, 6) == 0))
103 continue;
104+ if ((flags & CH_UPDATE_REFS) &&
105+ ascii_strncasecmp ("References:", buf, 11) == 0)
106+ continue;
107+ if ((flags & CH_UPDATE_IRT) &&
108+ ascii_strncasecmp ("In-Reply-To:", buf, 12) == 0)
109+ continue;
110 ignore = 0;
111 }
112@@ -168,4 +174,10 @@ mutt_copy_hdr (FILE *in, FILE *out, long
113 ascii_strncasecmp ("mime-version:", buf, 13) == 0))
114 continue;
115+ if ((flags & CH_UPDATE_REFS) &&
116+ ascii_strncasecmp ("References:", buf, 11) == 0)
117+ continue;
118+ if ((flags & CH_UPDATE_IRT) &&
119+ ascii_strncasecmp ("In-Reply-To:", buf, 12) == 0)
120+ continue;
121
122 /* Find x -- the array entry where this header is to be saved */
123@@ -277,4 +289,6 @@ mutt_copy_hdr (FILE *in, FILE *out, long
124 CH_XMIT ignore Lines: and Content-Length:
125 CH_WEED do header weeding
126+ CH_UPDATE_IRT update the In-Reply-To: header
127+ CH_UPDATE_REFS update the References: header
128
129 prefix
130@@ -286,4 +300,7 @@ mutt_copy_header (FILE *in, HEADER *h, F
131 {
132 char buffer[SHORT_STRING];
133+
134+ flags |= (h->irt_changed ? CH_UPDATE_IRT : 0)
135+ | (h->refs_changed ? CH_UPDATE_REFS : 0);
136
137 if (mutt_copy_hdr (in, out, h->offset, h->content->offset, flags, prefix) == -1)
138@@ -310,4 +327,47 @@ mutt_copy_header (FILE *in, HEADER *h, F
139 if ((flags & CH_NOSTATUS) == 0)
140 {
141+ if (h->irt_changed && h->env->in_reply_to)
142+ {
143+ LIST *listp = h->env->in_reply_to;
144+
145+ if (fputs ("In-Reply-To: ", out) == EOF)
146+ return (-1);
147+
148+ for (; listp; listp = listp->next)
149+ if ((fputs (listp->data, out) == EOF) || (fputc (' ', out) == EOF))
150+ return (-1);
151+
152+ if (fputc ('\n', out) == EOF)
153+ return (-1);
154+ }
155+
156+ if (h->refs_changed && h->env->references)
157+ {
158+ LIST *listp = h->env->references, *refs = NULL, *t;
159+
160+ if (fputs ("References: ", out) == EOF)
161+ return (-1);
162+
163+ /* Mutt stores references in reverse order, thus we create
164+ * a reordered refs list that we can put in the headers */
165+ for (; listp; listp = listp->next, refs = t)
166+ {
167+ t = (LIST *)safe_malloc (sizeof (LIST));
168+ t->data = listp->data;
169+ t->next = refs;
170+ }
171+
172+ for (; refs; refs = refs->next)
173+ if ((fputs (refs->data, out) == EOF) || (fputc (' ', out) == EOF))
174+ return (-1);
175+
176+ /* clearing refs from memory */
177+ for (t = refs; refs; refs = t->next, t = refs)
178+ safe_free ((void **)&refs);
179+
180+ if (fputc ('\n', out) == EOF)
181+ return (-1);
182+ }
183+
184 if (h->old || h->read)
185 {
186diff -pruN2 mutt-1.3.27.orig/curs_main.c mutt-1.3.27/curs_main.c
187--- mutt-1.3.27.orig/curs_main.c Wed Jan 16 21:43:58 2002
188+++ mutt-1.3.27/curs_main.c Wed Jan 23 22:26:56 2002
189@@ -878,4 +878,9 @@ int mutt_index_menu (void)
190 {
191 mutt_set_flag (Context, CURHDR, M_TAG, !CURHDR->tagged);
192+
193+ Context->last_tag = CURHDR->tagged ? CURHDR :
194+ ((Context->last_tag == CURHDR && !CURHDR->tagged)
195+ ? NULL : Context->last_tag);
196+
197 menu->redraw = REDRAW_STATUS;
198 if (option (OPTRESOLVE) && menu->current < Context->vcount - 1)
199@@ -1098,4 +1103,83 @@ int mutt_index_menu (void)
200 done = 1;
201 }
202+ break;
203+
204+ case OP_MAIN_BREAK_THREAD:
205+
206+ CHECK_MSGCOUNT;
207+ CHECK_VISIBLE;
208+ CHECK_READONLY;
209+
210+ if ((Sort & SORT_MASK) != SORT_THREADS)
211+ {
212+ mutt_error _("Threading is not enabled.");
213+ break;
214+ }
215+ if (Context->magic != M_MBOX && Context->magic != M_MMDF)
216+ {
217+ mutt_error _("break-thread: only for mbox and mmdf mailbox formats");
218+ break;
219+ }
220+
221+ {
222+ HEADER *oldcur = CURHDR;
223+
224+ mutt_break_thread (CURHDR);
225+ mutt_sort_headers (Context, 1);
226+ menu->current = oldcur->virtual;
227+ }
228+
229+ Context->changed = 1;
230+ mutt_message _("Thread broken");
231+
232+ if (menu->menu == MENU_PAGER)
233+ {
234+ op = OP_DISPLAY_MESSAGE;
235+ continue;
236+ }
237+ else
238+ menu->redraw |= REDRAW_INDEX;
239+
240+ break;
241+
242+ case OP_MAIN_LINK_THREADS:
243+
244+ CHECK_MSGCOUNT;
245+ CHECK_VISIBLE;
246+ CHECK_READONLY;
247+
248+ if ((Sort & SORT_MASK) != SORT_THREADS)
249+ mutt_error _("Threading is not enabled.");
250+ else if (Context->magic != M_MBOX && Context->magic != M_MMDF)
251+ mutt_error _("link-threads: only for mbox and mmdf mailbox formats");
252+ else if (!CURHDR->env->message_id)
253+ mutt_error _("No Message-ID: header available to link thread");
254+ else if (!tag && (!Context->last_tag || !Context->last_tag->tagged))
255+ mutt_error _("First, please tag a message to be linked here");
256+ else
257+ {
258+ HEADER *oldcur = CURHDR;
259+
260+ if (mutt_link_threads (CURHDR, tag ? NULL : Context->last_tag,
261+ Context))
262+ {
263+ mutt_sort_headers (Context, 1);
264+ menu->current = oldcur->virtual;
265+
266+ Context->changed = 1;
267+ mutt_message _("Threads linked");
268+ }
269+ else
270+ mutt_error _("No thread linked");
271+ }
272+
273+ if (menu->menu == MENU_PAGER)
274+ {
275+ op = OP_DISPLAY_MESSAGE;
276+ continue;
277+ }
278+ else
279+ menu->redraw |= REDRAW_STATUS | REDRAW_INDEX;
280+
281 break;
282
283diff -pruN2 mutt-1.3.27.orig/doc/manual.sgml.head mutt-1.3.27/doc/manual.sgml.head
284--- mutt-1.3.27.orig/doc/manual.sgml.head Sat Jan 12 12:35:43 2002
285+++ mutt-1.3.27/doc/manual.sgml.head Wed Jan 23 22:26:56 2002
286@@ -2116,6 +2116,38 @@ with large volume mailing lists easier b
287 uninteresting threads and quickly find topics of value.
288
289+<sect1>Editing threads
290+<p>
291+Mutt has the ability to dynamically restructure threads that are broken
292+either by misconfigured software or bad behaviour from some
293+correspondents. This allows to clean your mailboxes (<em/mbox/ and <em/mmdf/
294+formats) from these annoyances which make it hard to follow a discussion.
295+
296+<sect2>Linking threads
297+<p>
298+
299+Some mailers tend to "forget" to correctly set the "In-Reply-To:" and
300+"References:" headers when replying to a message. This results in broken
301+discussions because Mutt has not enough information to guess the correct
302+threading.
303+You can fix this by tagging the reply to a mail, then go onto this mail
304+and use the ``link-threads'' function (bound to & by default). The
305+reply will then be connected to its "parent" message.
306+
307+You can also connect multiple childs at once, tagging them and using the
308+tag-prefix command (';') or the auto_tag option.
309+
310+<sect2>Breaking threads
311+<p>
312+
313+On mailing lists, some people are in the bad habit of starting a new
314+discussion by hitting "reply" to any message from the list and changing
315+the subject to a totally unrelated one.
316+You can fix such threads by using the ``break-thread'' function (bound
317+by default to #), which will turn the subthread starting from the
318+current message into a whole different thread.
319+
320 <sect1>Delivery Status Notification (DSN) Support
321 <p>
322+
323 RFC1894 defines a set of MIME content types for relaying information
324 about the status of electronic mail messages. These can be thought of as
325diff -pruN2 mutt-1.3.27.orig/functions.h mutt-1.3.27/functions.h
326--- mutt-1.3.27.orig/functions.h Tue Sep 11 12:51:39 2001
327+++ mutt-1.3.27/functions.h Wed Jan 23 22:26:56 2002
328@@ -67,4 +67,5 @@ struct binding_t OpMain[] = {
329 { "create-alias", OP_CREATE_ALIAS, "a" },
330 { "bounce-message", OP_BOUNCE_MESSAGE, "b" },
331+ { "break-thread", OP_MAIN_BREAK_THREAD, "#" },
332 { "change-folder", OP_MAIN_CHANGE_FOLDER, "c" },
333 { "change-folder-readonly", OP_MAIN_CHANGE_FOLDER_READONLY, "\033c" },
334@@ -93,4 +94,5 @@ struct binding_t OpMain[] = {
335 { "previous-undeleted", OP_MAIN_PREV_UNDELETED, "k" },
336 { "limit", OP_MAIN_LIMIT, "l" },
337+ { "link-threads", OP_MAIN_LINK_THREADS, "&" },
338 { "list-reply", OP_LIST_REPLY, "L" },
339 { "mail", OP_MAIL, "m" },
340@@ -151,4 +153,5 @@ struct binding_t OpMain[] = {
341
342 struct binding_t OpPager[] = {
343+ { "break-thread", OP_MAIN_BREAK_THREAD, "#" },
344 { "create-alias", OP_CREATE_ALIAS, "a" },
345 { "bounce-message", OP_BOUNCE_MESSAGE, "b" },
346@@ -173,4 +176,5 @@ struct binding_t OpPager[] = {
347 { "previous-undeleted",OP_MAIN_PREV_UNDELETED, "k" },
348 { "previous-entry", OP_PREV_ENTRY, "K" },
349+ { "link-threads", OP_MAIN_LINK_THREADS, "&" },
350 { "list-reply", OP_LIST_REPLY, "L" },
351 { "redraw-screen", OP_REDRAW, "\014" },
352diff -pruN2 mutt-1.3.27.orig/mutt.h mutt-1.3.27/mutt.h
353--- mutt-1.3.27.orig/mutt.h Tue Jan 15 22:00:32 2002
354+++ mutt-1.3.27/mutt.h Wed Jan 23 22:26:56 2002
355@@ -82,4 +82,6 @@
356 #define CH_WEED_DELIVERED (1<<13) /* weed eventual Delivered-To headers */
357 #define CH_FORCE_FROM (1<<14) /* give CH_FROM precedence over CH_WEED? */
358+#define CH_UPDATE_IRT (1<<15) /* update In-Reply-To: */
359+#define CH_UPDATE_REFS (1<<16) /* update References: */
360
361 /* flags for mutt_enter_string() */
362@@ -629,4 +631,6 @@ typedef struct header
363 unsigned int threaded : 1; /* used for threading */
364 unsigned int display_subject : 1; /* used for threading */
365+ unsigned int irt_changed : 1; /* In-Reply-To changed to link/break threads */
366+ unsigned int refs_changed : 1; /* References changed to break thread */
367 unsigned int recip_valid : 1; /* is_recipient is valid */
368 unsigned int active : 1; /* message is not to be removed */
369@@ -728,4 +732,5 @@ typedef struct
370 pattern_t *limit_pattern; /* compiled limit pattern */
371 HEADER **hdrs;
372+ HEADER *last_tag; /* last tagged msg. used to link threads */
373 THREAD *tree; /* top of thread tree */
374 HASH *id_hash; /* hash table by msg id */
375diff -pruN2 mutt-1.3.27.orig/mx.c mutt-1.3.27/mx.c
376--- mutt-1.3.27.orig/mx.c Tue Jan 15 22:09:53 2002
377+++ mutt-1.3.27/mx.c Wed Jan 23 22:26:56 2002
378@@ -1163,4 +1163,6 @@ int mx_sync_mailbox (CONTEXT *ctx, int *
379 }
380 }
381+ else if (ctx->last_tag && ctx->last_tag->deleted)
382+ ctx->last_tag = NULL; /* reset last tagged msg now useless */
383 }
384
385diff -pruN2 mutt-1.3.27.orig/pager.c mutt-1.3.27/pager.c
386--- mutt-1.3.27.orig/pager.c Sun Jan 13 09:49:39 2002
387+++ mutt-1.3.27/pager.c Wed Jan 23 22:26:56 2002
388@@ -2436,4 +2436,9 @@ mutt_pager (const char *banner, const ch
389 CHECK_MODE(IsHeader (extra));
390 mutt_set_flag (Context, extra->hdr, M_TAG, !extra->hdr->tagged);
391+
392+ Context->last_tag = extra->hdr->tagged ? extra->hdr :
393+ ((Context->last_tag == extra->hdr && !extra->hdr->tagged)
394+ ? NULL : Context->last_tag);
395+
396 redraw = REDRAW_STATUS | REDRAW_INDEX;
397 if (option (OPTRESOLVE))
398diff -pruN2 mutt-1.3.27.orig/protos.h mutt-1.3.27/protos.h
399--- mutt-1.3.27.orig/protos.h Wed Jan 16 21:43:58 2002
400+++ mutt-1.3.27/protos.h Wed Jan 23 22:26:56 2002
401@@ -154,4 +154,5 @@ void mutt_block_signals_system (void);
402 void mutt_body_handler (BODY *, STATE *);
403 void mutt_bounce_message (FILE *fp, HEADER *, ADDRESS *);
404+void mutt_break_thread (HEADER *);
405 void mutt_buffy (char *, size_t);
406 void mutt_canonical_charset (char *, size_t, const char *);
407@@ -289,4 +290,5 @@ int mutt_is_subscribed_list (ADDRESS *);
408 int mutt_is_text_type (int, char *);
409 int mutt_is_valid_mailbox (const char *);
410+int mutt_link_threads (HEADER *, HEADER *, CONTEXT *);
411 int mutt_messages_in_thread (CONTEXT *, HEADER *, int);
412 int mutt_multi_choice (char *prompt, char *letters);
413diff -pruN mutt-1.3.27.orig/PATCHES mutt-1.3.27/PATCHES
414--- mutt-1.3.27.orig/PATCHES Mon Nov 26 20:16:52 2001
415+++ mutt-1.3.27/PATCHES Thu Dec 6 16:27:55 2001
416@@ -1,0 +1 @@
417+patch-1.3.27.cd.edit_threads.9.1
This page took 0.068546 seconds and 4 git commands to generate.