-diff -pruN2 mutt-1.3.27.orig/thread.c mutt-1.3.27/thread.c
---- mutt-1.3.27.orig/thread.c Wed Jan 16 21:43:59 2002
-+++ mutt-1.3.27/thread.c Wed Jan 23 22:26:56 2002
-@@ -1285,2 +1285,78 @@ HASH *mutt_make_subj_hash (CONTEXT *ctx)
- return hash;
- }
-+
-+static void clean_references (THREAD *brk, THREAD *cur)
-+{
-+ THREAD *p;
-+ LIST *ref = NULL;
-+ int done = 0;
-+
-+ for (; cur; cur = cur->next, done = 0)
-+ {
-+ /* parse subthread recursively */
-+ clean_references (brk, cur->child);
-+
-+ if (!cur->message)
-+ break; /* skip pseudo-message */
-+
-+ /* Looking for the first bad reference according to the new threading.
-+ * Optimal since Mutt stores the references in reverse order, and the
-+ * first loop should match immediatly for mails respecting RFC2822. */
-+ for (p = brk; !done && p; p = p->parent)
-+ for (ref = cur->message->env->references; p->message && ref; ref = ref->next)
-+ if (!mutt_strcasecmp (ref->data, p->message->env->message_id))
-+ {
-+ done = 1;
-+ break;
-+ }
-+
-+ if (done)
-+ {
-+ /* clearing the References: header from obsolete Message-Id(s) */
-+ mutt_free_list (&ref->next);
-+
-+ cur->message->refs_changed = cur->message->changed = 1;
-+ }
-+ }
-+}
-+
-+void mutt_break_thread (HEADER *hdr)
-+{
-+ mutt_free_list (&hdr->env->in_reply_to);
-+ mutt_free_list (&hdr->env->references);
-+ hdr->irt_changed = hdr->refs_changed = hdr->changed = 1;
-+
-+ clean_references (hdr->thread, hdr->thread->child);
-+}
-+
-+static int link_threads (HEADER *parent, HEADER *child, CONTEXT *ctx)
-+{
-+ if (child == parent)
-+ return 0;
-+
-+ mutt_break_thread (child);
-+
-+ child->env->in_reply_to = mutt_new_list ();
-+ child->env->in_reply_to->data = safe_strdup (parent->env->message_id);
-+
-+ mutt_set_flag (ctx, child, M_TAG, 0);
-+
-+ child->irt_changed = child->changed = 1;
-+ return 1;
-+}
-+
-+int mutt_link_threads (HEADER *cur, HEADER *last, CONTEXT *ctx)
-+{
-+ int i, changed = 0;
-+
-+ if (!last)
-+ {
-+ for (i = 0; i < ctx->vcount; i++)
-+ if (ctx->hdrs[Context->v2r[i]]->tagged)
-+ changed |= link_threads (cur, ctx->hdrs[Context->v2r[i]], ctx);
-+ }
-+ else
-+ changed = link_threads (cur, last, ctx);
-+
-+ return changed;
-+}
-diff -pruN2 mutt-1.3.27.orig/OPS mutt-1.3.27/OPS
---- mutt-1.3.27.orig/OPS Tue Sep 11 12:50:50 2001
-+++ mutt-1.3.27/OPS Wed Jan 23 22:26:56 2002
-@@ -95,4 +95,5 @@ OP_LIST_REPLY "reply to specified mailin
+diff -pruN mutt-1.5.5.1-orig/OPS mutt-1.5.5.1/OPS
+--- mutt-1.5.5.1-orig/OPS Wed Nov 5 10:41:31 2003
++++ mutt-1.5.5.1/OPS Tue Nov 11 02:52:33 2003
+@@ -96,6 +96,7 @@ OP_LAST_ENTRY "move to the last entry"
+ OP_LIST_REPLY "reply to specified mailing list"
OP_MACRO "execute a macro"
OP_MAIL "compose a new mail message"
+OP_MAIN_BREAK_THREAD "break the thread in two"
OP_MAIN_CHANGE_FOLDER "open a different folder"
OP_MAIN_CHANGE_FOLDER_READONLY "open a different folder in read only mode"
-@@ -104,4 +105,5 @@ OP_MAIN_FIRST_MESSAGE "move to the first
+ OP_MAIN_CLEAR_FLAG "clear a status flag from a message"
+@@ -105,6 +106,7 @@ OP_MAIN_FETCH_MAIL "retrieve mail from P
+ OP_MAIN_FIRST_MESSAGE "move to the first message"
OP_MAIN_LAST_MESSAGE "move to the last message"
OP_MAIN_LIMIT "show only messages matching a pattern"
+OP_MAIN_LINK_THREADS "link tagged message to the current one"
OP_MAIN_NEXT_NEW "jump to the next new message"
+ OP_MAIN_NEXT_NEW_THEN_UNREAD "jump to the next new or unread message"
OP_MAIN_NEXT_SUBTHREAD "jump to the next subthread"
-diff -pruN2 mutt-1.3.27.orig/copy.c mutt-1.3.27/copy.c
---- mutt-1.3.27.orig/copy.c Mon Dec 3 11:17:57 2001
-+++ mutt-1.3.27/copy.c Wed Jan 23 22:26:56 2002
-@@ -92,4 +92,10 @@ mutt_copy_hdr (FILE *in, FILE *out, long
+diff -pruN mutt-1.5.5.1-orig/acconfig.h mutt-1.5.5.1/acconfig.h
+--- mutt-1.5.5.1-orig/acconfig.h Tue Jan 21 11:50:49 2003
++++ mutt-1.5.5.1/acconfig.h Tue Nov 11 02:52:33 2003
+@@ -36,3 +36,7 @@
+ * all return values other than (size_t)(-1) as equivalent. */
+ #undef ICONV_NONTRANS
+
++/* Do you want to use the rethreading functions with IMAP
++ * (--enable-imap-edit-threads) */
++#undef IMAP_EDIT_THREADS
++
+diff -pruN mutt-1.5.5.1-orig/config.h.in mutt-1.5.5.1/config.h.in
+--- mutt-1.5.5.1-orig/config.h.in Tue Mar 4 08:50:34 2003
++++ mutt-1.5.5.1/config.h.in Tue Nov 11 02:52:33 2003
+@@ -531,3 +531,7 @@
+ * all return values other than (size_t)(-1) as equivalent. */
+ #undef ICONV_NONTRANS
+
++/* Do you want to use the rethreading functions with IMAP
++ * (--enable-imap-edit-threads) */
++#undef IMAP_EDIT_THREADS
++
+diff -pruN mutt-1.5.5.1-orig/configure mutt-1.5.5.1/configure
+--- mutt-1.5.5.1-orig/configure Wed Nov 5 21:00:06 2003
++++ mutt-1.5.5.1/configure Tue Nov 11 02:52:33 2003
+@@ -40,6 +40,8 @@ ac_help="$ac_help
+ ac_help="$ac_help
+ --with-gss[=PFX] Compile in GSSAPI authentication for IMAP"
+ ac_help="$ac_help
++ --enable-imap-edit-threads Enable editing threads support for IMAP"
++ac_help="$ac_help
+ --with-ssl[=PFX] Compile in SSL support for POP/IMAP"
+ ac_help="$ac_help
+ --with-nss[=PFX] Compile in SSL support for POP/IMAP via NSS"
+@@ -5383,6 +5385,23 @@ if test x$need_gss = xyes; then
+ else
+ USE_GSS_TRUE='#'
+ USE_GSS_FALSE=
++fi
++
++
++# Check whether --enable-imap-edit-threads or --disable-imap-edit-threads was given.
++if test "${enable_imap_edit_threads+set}" = set; then
++ enableval="$enable_imap_edit_threads"
++
++ if test "$enableval" = "yes"; then
++ if test "$need_imap" = "yes"; then
++ cat >> confdefs.h <<\EOF
++#define IMAP_EDIT_THREADS 1
++EOF
++
++ else
++ echo "configure: warning: IMAP support for edit_threads is only useful with IMAP support" 1>&2
++ fi
++fi
+ fi
+
+
+diff -pruN mutt-1.5.5.1-orig/configure.in mutt-1.5.5.1/configure.in
+--- mutt-1.5.5.1-orig/configure.in Wed Nov 5 21:00:05 2003
++++ mutt-1.5.5.1/configure.in Tue Nov 11 02:52:33 2003
+@@ -559,6 +559,16 @@ AM_CONDITIONAL(USE_GSS, test x$need_gss
+
+ dnl -- end imap dependencies --
+
++AC_ARG_ENABLE(imap-edit-threads, [ --enable-imap-edit-threads Enable editing threads support for IMAP],
++[
++ if test "$enableval" = "yes"; then
++ if test "$need_imap" = "yes"; then
++ AC_DEFINE(IMAP_EDIT_THREADS)
++ else
++ AC_MSG_WARN([IMAP support for edit_threads is only useful with IMAP support])
++ fi
++fi])
++
+ AC_ARG_WITH(ssl, [ --with-ssl[=PFX] Compile in SSL support for POP/IMAP],
+ [ if test "$with_ssl" != "no"
+ then
+diff -pruN mutt-1.5.5.1-orig/copy.c mutt-1.5.5.1/copy.c
+--- mutt-1.5.5.1-orig/copy.c Wed Nov 5 10:41:31 2003
++++ mutt-1.5.5.1/copy.c Tue Nov 11 02:52:33 2003
+@@ -95,6 +95,12 @@ mutt_copy_hdr (FILE *in, FILE *out, long
+ (ascii_strncasecmp ("Content-Length:", buf, 15) == 0 ||
ascii_strncasecmp ("Lines:", buf, 6) == 0))
continue;
+ if ((flags & CH_UPDATE_REFS) &&
+ continue;
ignore = 0;
}
-@@ -168,4 +174,10 @@ mutt_copy_hdr (FILE *in, FILE *out, long
+
+@@ -193,6 +199,12 @@ mutt_copy_hdr (FILE *in, FILE *out, long
+ ascii_strncasecmp ("type:", buf + 8, 5) == 0)) ||
ascii_strncasecmp ("mime-version:", buf, 13) == 0))
continue;
+ if ((flags & CH_UPDATE_REFS) &&
+ continue;
/* Find x -- the array entry where this header is to be saved */
-@@ -277,4 +289,6 @@ mutt_copy_hdr (FILE *in, FILE *out, long
+ if (flags & CH_REORDER)
+@@ -326,6 +338,8 @@ mutt_copy_hdr (FILE *in, FILE *out, long
CH_XMIT ignore Lines: and Content-Length:
CH_WEED do header weeding
+ CH_NOQFROM ignore ">From " line
+ CH_UPDATE_IRT update the In-Reply-To: header
+ CH_UPDATE_REFS update the References: header
prefix
-@@ -286,4 +300,7 @@ mutt_copy_header (FILE *in, HEADER *h, F
+ string to use if CH_PREFIX is set
+@@ -335,6 +349,9 @@ int
+ mutt_copy_header (FILE *in, HEADER *h, FILE *out, int flags, const char *prefix)
{
char buffer[SHORT_STRING];
+
+ | (h->refs_changed ? CH_UPDATE_REFS : 0);
if (mutt_copy_hdr (in, out, h->offset, h->content->offset, flags, prefix) == -1)
-@@ -310,4 +327,47 @@ mutt_copy_header (FILE *in, HEADER *h, F
+ return (-1);
+@@ -358,7 +375,56 @@ mutt_copy_header (FILE *in, HEADER *h, F
+ if (flags & CH_UPDATE)
+ {
if ((flags & CH_NOSTATUS) == 0)
++#ifdef IMAP_EDIT_THREADS
++#define NEW_ENV new_env
++#else
++#define NEW_ENV env
++#endif
{
-+ if (h->irt_changed && h->env->in_reply_to)
++ if (h->irt_changed && h->NEW_ENV->in_reply_to)
+ {
-+ LIST *listp = h->env->in_reply_to;
++ LIST *listp = h->NEW_ENV->in_reply_to;
+
+ if (fputs ("In-Reply-To: ", out) == EOF)
+ return (-1);
+ return (-1);
+ }
+
-+ if (h->refs_changed && h->env->references)
++ if (h->refs_changed && h->NEW_ENV->references)
+ {
-+ LIST *listp = h->env->references, *refs = NULL, *t;
++ LIST *listp = h->NEW_ENV->references, *refs = NULL, *t;
+
+ if (fputs ("References: ", out) == EOF)
+ return (-1);
+ if (fputc ('\n', out) == EOF)
+ return (-1);
+ }
++#undef NEW_ENV
+
if (h->old || h->read)
{
-diff -pruN2 mutt-1.3.27.orig/curs_main.c mutt-1.3.27/curs_main.c
---- mutt-1.3.27.orig/curs_main.c Wed Jan 16 21:43:58 2002
-+++ mutt-1.3.27/curs_main.c Wed Jan 23 22:26:56 2002
-@@ -878,4 +878,9 @@ int mutt_index_menu (void)
+ if (fputs ("Status: ", out) == EOF)
+diff -pruN mutt-1.5.5.1-orig/curs_main.c mutt-1.5.5.1/curs_main.c
+--- mutt-1.5.5.1-orig/curs_main.c Wed Nov 5 10:41:31 2003
++++ mutt-1.5.5.1/curs_main.c Tue Nov 11 02:52:33 2003
+@@ -930,6 +930,11 @@ CHECK_IMAP_ACL(IMAP_ACL_DELETE);
+ else
{
mutt_set_flag (Context, CURHDR, M_TAG, !CURHDR->tagged);
+
+
menu->redraw = REDRAW_STATUS;
if (option (OPTRESOLVE) && menu->current < Context->vcount - 1)
-@@ -1098,4 +1103,83 @@ int mutt_index_menu (void)
+ {
+@@ -1162,6 +1167,89 @@ CHECK_IMAP_ACL(IMAP_ACL_DELETE);
+ }
done = 1;
}
+ break;
+ CHECK_READONLY;
+
+ if ((Sort & SORT_MASK) != SORT_THREADS)
-+ {
+ mutt_error _("Threading is not enabled.");
-+ break;
-+ }
-+ if (Context->magic != M_MBOX && Context->magic != M_MMDF)
-+ {
-+ mutt_error _("break-thread: only for mbox and mmdf mailbox formats");
-+ break;
-+ }
+
-+ {
-+ HEADER *oldcur = CURHDR;
++#if defined (USE_IMAP) && ! defined (IMAP_EDIT_THREADS)
++ else if (Context->magic == M_IMAP)
++ mutt_error _("Compile Mutt with --enable-imap-edit-threads for break-thread support");
++#endif
++
++ else
++ {
++ {
++ HEADER *oldcur = CURHDR;
+
-+ mutt_break_thread (CURHDR);
-+ mutt_sort_headers (Context, 1);
-+ menu->current = oldcur->virtual;
-+ }
++ mutt_break_thread (CURHDR);
++ mutt_sort_headers (Context, 1);
++ menu->current = oldcur->virtual;
++ }
+
-+ Context->changed = 1;
-+ mutt_message _("Thread broken");
++ Context->changed = 1;
++ mutt_message _("Thread broken");
+
-+ if (menu->menu == MENU_PAGER)
-+ {
-+ op = OP_DISPLAY_MESSAGE;
-+ continue;
++ if (menu->menu == MENU_PAGER)
++ {
++ op = OP_DISPLAY_MESSAGE;
++ continue;
++ }
++ else
++ menu->redraw |= REDRAW_INDEX;
+ }
-+ else
-+ menu->redraw |= REDRAW_INDEX;
+
-+ break;
++ break;
+
+ case OP_MAIN_LINK_THREADS:
+
+
+ if ((Sort & SORT_MASK) != SORT_THREADS)
+ mutt_error _("Threading is not enabled.");
-+ else if (Context->magic != M_MBOX && Context->magic != M_MMDF)
-+ mutt_error _("link-threads: only for mbox and mmdf mailbox formats");
++
++#if defined (USE_IMAP) && ! defined (IMAP_EDIT_THREADS)
++ else if (Context->magic == M_IMAP)
++ mutt_error _("Compile Mutt with --enable-imap-edit-threads for link-threads support");
++#endif
++
+ else if (!CURHDR->env->message_id)
+ mutt_error _("No Message-ID: header available to link thread");
+ else if (!tag && (!Context->last_tag || !Context->last_tag->tagged))
+
break;
-diff -pruN2 mutt-1.3.27.orig/doc/manual.sgml.head mutt-1.3.27/doc/manual.sgml.head
---- mutt-1.3.27.orig/doc/manual.sgml.head Sat Jan 12 12:35:43 2002
-+++ mutt-1.3.27/doc/manual.sgml.head Wed Jan 23 22:26:56 2002
-@@ -2116,6 +2116,38 @@ with large volume mailing lists easier b
+ case OP_EDIT_TYPE:
+diff -pruN mutt-1.5.5.1-orig/doc/manual.sgml.head mutt-1.5.5.1/doc/manual.sgml.head
+--- mutt-1.5.5.1-orig/doc/manual.sgml.head Wed Nov 5 10:41:34 2003
++++ mutt-1.5.5.1/doc/manual.sgml.head Tue Nov 11 02:52:33 2003
+@@ -2170,8 +2170,43 @@ used a threaded news client, this is the
+ with large volume mailing lists easier because you can easily delete
uninteresting threads and quickly find topics of value.
+<sect1>Editing threads
+<p>
+Mutt has the ability to dynamically restructure threads that are broken
+either by misconfigured software or bad behaviour from some
-+correspondents. This allows to clean your mailboxes (<em/mbox/ and <em/mmdf/
-+formats) from these annoyances which make it hard to follow a discussion.
++correspondents. This allows to clean your mailboxes formats) from these
++annoyances which make it hard to follow a discussion.
++
++If you want to use these functions with IMAP, you need to compile Mutt
++with the <em/--enable-imap-edit-threads/ configure flag.
+
+<sect2>Linking threads
+<p>
+"References:" headers when replying to a message. This results in broken
+discussions because Mutt has not enough information to guess the correct
+threading.
-+You can fix this by tagging the reply to a mail, then go onto this mail
-+and use the ``link-threads'' function (bound to & by default). The
-+reply will then be connected to its "parent" message.
++You can fix this by tagging the reply, then moving to the parent message
++and using the ``link-threads'' function (bound to & by default). The
++reply will then be connected to this "parent" message.
+
+You can also connect multiple childs at once, tagging them and using the
+tag-prefix command (';') or the auto_tag option.
+
RFC1894 defines a set of MIME content types for relaying information
about the status of electronic mail messages. These can be thought of as
-diff -pruN2 mutt-1.3.27.orig/functions.h mutt-1.3.27/functions.h
---- mutt-1.3.27.orig/functions.h Tue Sep 11 12:51:39 2001
-+++ mutt-1.3.27/functions.h Wed Jan 23 22:26:56 2002
-@@ -67,4 +67,5 @@ struct binding_t OpMain[] = {
+ ``return receipts.'' Berkeley sendmail 8.8.x currently has some command
+diff -pruN mutt-1.5.5.1-orig/functions.h mutt-1.5.5.1/functions.h
+--- mutt-1.5.5.1-orig/functions.h Wed Nov 5 10:41:31 2003
++++ mutt-1.5.5.1/functions.h Tue Nov 11 02:52:33 2003
+@@ -69,6 +69,7 @@ struct binding_t OpGeneric[] = {
+ struct binding_t OpMain[] = {
{ "create-alias", OP_CREATE_ALIAS, "a" },
{ "bounce-message", OP_BOUNCE_MESSAGE, "b" },
+ { "break-thread", OP_MAIN_BREAK_THREAD, "#" },
{ "change-folder", OP_MAIN_CHANGE_FOLDER, "c" },
{ "change-folder-readonly", OP_MAIN_CHANGE_FOLDER_READONLY, "\033c" },
-@@ -93,4 +94,5 @@ struct binding_t OpMain[] = {
+ { "collapse-thread", OP_MAIN_COLLAPSE_THREAD, "\033v" },
+@@ -95,6 +96,7 @@ struct binding_t OpMain[] = {
+ { "next-undeleted", OP_MAIN_NEXT_UNDELETED, "j" },
{ "previous-undeleted", OP_MAIN_PREV_UNDELETED, "k" },
{ "limit", OP_MAIN_LIMIT, "l" },
+ { "link-threads", OP_MAIN_LINK_THREADS, "&" },
{ "list-reply", OP_LIST_REPLY, "L" },
{ "mail", OP_MAIL, "m" },
-@@ -151,4 +153,5 @@ struct binding_t OpMain[] = {
+ { "toggle-new", OP_TOGGLE_NEW, "N" },
+@@ -153,6 +155,7 @@ struct binding_t OpMain[] = {
+ };
struct binding_t OpPager[] = {
+ { "break-thread", OP_MAIN_BREAK_THREAD, "#" },
{ "create-alias", OP_CREATE_ALIAS, "a" },
{ "bounce-message", OP_BOUNCE_MESSAGE, "b" },
-@@ -173,4 +176,5 @@ struct binding_t OpPager[] = {
+ { "change-folder", OP_MAIN_CHANGE_FOLDER, "c" },
+@@ -175,6 +178,7 @@ struct binding_t OpPager[] = {
+ { "next-entry", OP_NEXT_ENTRY, "J" },
{ "previous-undeleted",OP_MAIN_PREV_UNDELETED, "k" },
{ "previous-entry", OP_PREV_ENTRY, "K" },
+ { "link-threads", OP_MAIN_LINK_THREADS, "&" },
{ "list-reply", OP_LIST_REPLY, "L" },
{ "redraw-screen", OP_REDRAW, "\014" },
-diff -pruN2 mutt-1.3.27.orig/mutt.h mutt-1.3.27/mutt.h
---- mutt-1.3.27.orig/mutt.h Tue Jan 15 22:00:32 2002
-+++ mutt-1.3.27/mutt.h Wed Jan 23 22:26:56 2002
-@@ -82,4 +82,6 @@
+ { "mail", OP_MAIL, "m" },
+diff -pruN mutt-1.5.5.1-orig/imap/imap.c mutt-1.5.5.1/imap/imap.c
+--- mutt-1.5.5.1-orig/imap/imap.c Wed Nov 5 10:41:36 2003
++++ mutt-1.5.5.1/imap/imap.c Tue Nov 11 02:52:33 2003
+@@ -980,9 +980,11 @@ int imap_sync_mailbox (CONTEXT* ctx, int
+ mutt_buffer_addstr (&cmd, "UID STORE ");
+ mutt_buffer_addstr (&cmd, uid);
+
+- /* if attachments have been deleted we delete the message and reupload
+- * it. This works better if we're expunging, of course. */
+- if (ctx->hdrs[n]->attach_del)
++ /* if the message has been rethreaded or attachments have been deleted
++ * we delete the message and reupload it.
++ * This works better if we're expunging, of course. */
++ if (ctx->hdrs[n]->refs_changed || ctx->hdrs[n]->irt_changed ||
++ ctx->hdrs[n]->attach_del)
+ {
+ dprint (3, (debugfile, "imap_sync_mailbox: Attachments to be deleted, falling back to _mutt_save_message\n"));
+ if (!appendctx)
+diff -pruN mutt-1.5.5.1-orig/main.c mutt-1.5.5.1/main.c
+--- mutt-1.5.5.1-orig/main.c Tue Mar 4 08:49:48 2003
++++ mutt-1.5.5.1/main.c Tue Nov 11 02:52:33 2003
+@@ -228,6 +228,12 @@ static void show_version (void)
+ "-USE_IMAP "
+ #endif
+
++#ifdef IMAP_EDIT_THREADS
++ "+IMAP_EDIT_THREADS "
++#else
++ "-IMAP_EDIT_THREADS "
++#endif
++
+ #ifdef USE_GSS
+ "+USE_GSS "
+ #else
+diff -pruN mutt-1.5.5.1-orig/mh.c mutt-1.5.5.1/mh.c
+--- mutt-1.5.5.1-orig/mh.c Wed Nov 5 10:41:32 2003
++++ mutt-1.5.5.1/mh.c Tue Nov 11 02:52:33 2003
+@@ -1220,7 +1220,7 @@ static int mh_sync_message (CONTEXT * ct
+ {
+ HEADER *h = ctx->hdrs[msgno];
+
+- if (h->attach_del)
++ if (h->attach_del || h->refs_changed || h->irt_changed)
+ if (mh_rewrite_message (ctx, msgno) != 0)
+ return -1;
+
+@@ -1231,9 +1231,9 @@ static int maildir_sync_message (CONTEXT
+ {
+ HEADER *h = ctx->hdrs[msgno];
+
+- if (h->attach_del)
++ if (h->attach_del || h->refs_changed || h->irt_changed)
+ {
+- /* when doing attachment deletion, fall back to the MH case. */
++ /* when doing attachment deletion/rethreading, fall back to the MH case. */
+ if (mh_rewrite_message (ctx, msgno) != 0)
+ return (-1);
+ }
+diff -pruN mutt-1.5.5.1-orig/mutt.h mutt-1.5.5.1/mutt.h
+--- mutt-1.5.5.1-orig/mutt.h Wed Nov 5 10:41:32 2003
++++ mutt-1.5.5.1/mutt.h Tue Nov 11 02:52:33 2003
+@@ -92,6 +92,8 @@
#define CH_WEED_DELIVERED (1<<13) /* weed eventual Delivered-To headers */
#define CH_FORCE_FROM (1<<14) /* give CH_FROM precedence over CH_WEED? */
-+#define CH_UPDATE_IRT (1<<15) /* update In-Reply-To: */
-+#define CH_UPDATE_REFS (1<<16) /* update References: */
+ #define CH_NOQFROM (1<<15) /* give CH_FROM precedence over CH_WEED? */
++#define CH_UPDATE_IRT (1<<16) /* update In-Reply-To: */
++#define CH_UPDATE_REFS (1<<17) /* update References: */
/* flags for mutt_enter_string() */
-@@ -629,4 +631,6 @@ typedef struct header
+ #define M_ALIAS 1 /* do alias "completion" by calling up the alias-menu */
+@@ -506,6 +508,7 @@ typedef struct list_t
+
+ #define mutt_new_list() safe_calloc (1, sizeof (LIST))
+ void mutt_free_list (LIST **);
++LIST *mutt_copy_list (LIST *);
+ int mutt_matches_ignore (const char *, LIST *);
+
+ /* add an element to a list */
+@@ -647,6 +650,8 @@ typedef struct header
+ unsigned int subject_changed : 1; /* used for threading */
unsigned int threaded : 1; /* used for threading */
unsigned int display_subject : 1; /* used for threading */
-+ unsigned int irt_changed : 1; /* In-Reply-To changed to link/break threads */
-+ unsigned int refs_changed : 1; /* References changed to break thread */
++ unsigned int irt_changed : 1; /* In-Reply-To changed to link/break threads */
++ unsigned int refs_changed : 1; /* References changed to break thread */
unsigned int recip_valid : 1; /* is_recipient is valid */
unsigned int active : 1; /* message is not to be removed */
-@@ -728,4 +732,5 @@ typedef struct
+ unsigned int trash : 1; /* message is marked as trashed on disk.
+@@ -687,6 +692,10 @@ typedef struct header
+ char *tree; /* character string to print thread tree */
+ struct thread *thread;
+
++#ifdef IMAP_EDIT_THREADS
++ ENVELOPE *new_env; /* envelope information for rethreading */
++#endif
++
+ #ifdef MIXMASTER
+ LIST *chain;
+ #endif
+@@ -752,6 +761,7 @@ typedef struct
+ char *pattern; /* limit pattern string */
pattern_t *limit_pattern; /* compiled limit pattern */
HEADER **hdrs;
+ HEADER *last_tag; /* last tagged msg. used to link threads */
THREAD *tree; /* top of thread tree */
HASH *id_hash; /* hash table by msg id */
-diff -pruN2 mutt-1.3.27.orig/mx.c mutt-1.3.27/mx.c
---- mutt-1.3.27.orig/mx.c Tue Jan 15 22:09:53 2002
-+++ mutt-1.3.27/mx.c Wed Jan 23 22:26:56 2002
-@@ -1163,4 +1163,6 @@ int mx_sync_mailbox (CONTEXT *ctx, int *
+ HASH *subj_hash; /* hash table by subject */
+diff -pruN mutt-1.5.5.1-orig/mx.c mutt-1.5.5.1/mx.c
+--- mutt-1.5.5.1-orig/mx.c Wed Nov 5 10:41:32 2003
++++ mutt-1.5.5.1/mx.c Tue Nov 11 02:52:33 2003
+@@ -1161,6 +1161,8 @@ int mx_sync_mailbox (CONTEXT *ctx, int *
+ ctx->deleted = 0;
}
}
+ else if (ctx->last_tag && ctx->last_tag->deleted)
+ ctx->last_tag = NULL; /* reset last tagged msg now useless */
}
-diff -pruN2 mutt-1.3.27.orig/pager.c mutt-1.3.27/pager.c
---- mutt-1.3.27.orig/pager.c Sun Jan 13 09:49:39 2002
-+++ mutt-1.3.27/pager.c Wed Jan 23 22:26:56 2002
-@@ -2436,4 +2436,9 @@ mutt_pager (const char *banner, const ch
+ /* really only for IMAP - imap_sync_mailbox results in a call to
+diff -pruN mutt-1.5.5.1-orig/pager.c mutt-1.5.5.1/pager.c
+--- mutt-1.5.5.1-orig/pager.c Wed Nov 5 10:41:32 2003
++++ mutt-1.5.5.1/pager.c Tue Nov 11 02:52:33 2003
+@@ -2481,6 +2481,11 @@ CHECK_IMAP_ACL(IMAP_ACL_WRITE);
+ case OP_TAG:
CHECK_MODE(IsHeader (extra));
mutt_set_flag (Context, extra->hdr, M_TAG, !extra->hdr->tagged);
+
+
redraw = REDRAW_STATUS | REDRAW_INDEX;
if (option (OPTRESOLVE))
-diff -pruN2 mutt-1.3.27.orig/protos.h mutt-1.3.27/protos.h
---- mutt-1.3.27.orig/protos.h Wed Jan 16 21:43:58 2002
-+++ mutt-1.3.27/protos.h Wed Jan 23 22:26:56 2002
-@@ -154,4 +154,5 @@ void mutt_block_signals_system (void);
+ {
+diff -pruN mutt-1.5.5.1-orig/protos.h mutt-1.5.5.1/protos.h
+--- mutt-1.5.5.1-orig/protos.h Wed Nov 5 10:41:33 2003
++++ mutt-1.5.5.1/protos.h Tue Nov 11 02:52:33 2003
+@@ -146,6 +146,7 @@ void mutt_block_signals (void);
+ void mutt_block_signals_system (void);
void mutt_body_handler (BODY *, STATE *);
- void mutt_bounce_message (FILE *fp, HEADER *, ADDRESS *);
+ int mutt_bounce_message (FILE *fp, HEADER *, ADDRESS *);
+void mutt_break_thread (HEADER *);
void mutt_buffy (char *, size_t);
+ int mutt_buffy_list (void);
void mutt_canonical_charset (char *, size_t, const char *);
-@@ -289,4 +290,5 @@ int mutt_is_subscribed_list (ADDRESS *);
- int mutt_is_text_type (int, char *);
+@@ -286,6 +287,7 @@ int mutt_is_list_recipient (int, ADDRESS
+ int mutt_is_subscribed_list (ADDRESS *);
+ int mutt_is_text_part (BODY *);
int mutt_is_valid_mailbox (const char *);
+int mutt_link_threads (HEADER *, HEADER *, CONTEXT *);
+ int mutt_lookup_mime_type (BODY *, const char *);
int mutt_messages_in_thread (CONTEXT *, HEADER *, int);
int mutt_multi_choice (char *prompt, char *letters);
-diff -pruN mutt-1.3.27.orig/PATCHES mutt-1.3.27/PATCHES
---- mutt-1.3.27.orig/PATCHES Mon Nov 26 20:16:52 2001
-+++ mutt-1.3.27/PATCHES Thu Dec 6 16:27:55 2001
+diff -pruN mutt-1.5.5.1-orig/thread.c mutt-1.5.5.1/thread.c
+--- mutt-1.5.5.1-orig/thread.c Wed Nov 5 10:41:34 2003
++++ mutt-1.5.5.1/thread.c Tue Nov 11 02:52:33 2003
+@@ -1333,3 +1333,105 @@ HASH *mutt_make_subj_hash (CONTEXT *ctx)
+
+ return hash;
+ }
++
++static void clean_references (THREAD *brk, THREAD *cur)
++{
++ THREAD *p;
++ LIST *ref = NULL;
++ int done = 0;
++
++ for (; cur; cur = cur->next, done = 0)
++ {
++ /* parse subthread recursively */
++ clean_references (brk, cur->child);
++
++ if (!cur->message)
++ break; /* skip pseudo-message */
++
++ /* Looking for the first bad reference according to the new threading.
++ * Optimal since Mutt stores the references in reverse order, and the
++ * first loop should match immediatly for mails respecting RFC2822. */
++ for (p = brk; !done && p; p = p->parent)
++ for (ref = cur->message->env->references; p->message && ref; ref = ref->next)
++ if (!mutt_strcasecmp (ref->data, p->message->env->message_id))
++ {
++ done = 1;
++ break;
++ }
++
++ if (done)
++ {
++ HEADER *h = cur->message;
++
++ /* clearing the References: header from obsolete Message-Id(s) */
++ mutt_free_list (&ref->next);
++
++#ifdef IMAP_EDIT_THREADS
++ if (h->new_env)
++ mutt_free_list (&h->new_env->references);
++ else
++ h->new_env = mutt_new_envelope ();
++
++ h->new_env->references = mutt_copy_list (h->env->references);
++#endif
++
++ h->refs_changed = h->changed = 1;
++ }
++ }
++}
++
++void mutt_break_thread (HEADER *hdr)
++{
++ mutt_free_list (&hdr->env->in_reply_to);
++ mutt_free_list (&hdr->env->references);
++ hdr->irt_changed = hdr->refs_changed = hdr->changed = 1;
++
++#ifdef IMAP_EDIT_THREADS
++ if (hdr->new_env)
++ {
++ mutt_free_list (&hdr->new_env->in_reply_to);
++ mutt_free_list (&hdr->new_env->references);
++ }
++ else
++ hdr->new_env = mutt_new_envelope ();
++#endif
++
++ clean_references (hdr->thread, hdr->thread->child);
++}
++
++static int link_threads (HEADER *parent, HEADER *child, CONTEXT *ctx)
++{
++ if (child == parent)
++ return 0;
++
++ mutt_break_thread (child);
++
++ child->env->in_reply_to = mutt_new_list ();
++ child->env->in_reply_to->data = safe_strdup (parent->env->message_id);
++
++#ifdef IMAP_EDIT_THREADS
++ child->new_env->in_reply_to = mutt_new_list ();
++ child->new_env->in_reply_to->data = safe_strdup (parent->env->message_id);
++#endif
++
++ mutt_set_flag (ctx, child, M_TAG, 0);
++
++ child->irt_changed = child->changed = 1;
++ return 1;
++}
++
++int mutt_link_threads (HEADER *cur, HEADER *last, CONTEXT *ctx)
++{
++ int i, changed = 0;
++
++ if (!last)
++ {
++ for (i = 0; i < ctx->vcount; i++)
++ if (ctx->hdrs[Context->v2r[i]]->tagged)
++ changed |= link_threads (cur, ctx->hdrs[Context->v2r[i]], ctx);
++ }
++ else
++ changed = link_threads (cur, last, ctx);
++
++ return changed;
++}
+diff -pruN mutt-1.5.5.1-orig/PATCHES mutt-1.5.5.1/PATCHES
+--- mutt-1.5.5.1-orig/PATCHES Tue Apr 15 15:18:34 2003
++++ mutt-1.5.5.1/PATCHES Tue Nov 11 02:52:33 2003
@@ -1,0 +1 @@
-+patch-1.3.27.cd.edit_threads.9.1
++patch-1.5.5.1.cd.edit_threads.9.5