aboutsummaryrefslogtreecommitdiffstats
path: root/mail/mutt-devel/files/extra-patch-edit-threads
diff options
context:
space:
mode:
Diffstat (limited to 'mail/mutt-devel/files/extra-patch-edit-threads')
-rw-r--r--mail/mutt-devel/files/extra-patch-edit-threads604
1 files changed, 0 insertions, 604 deletions
diff --git a/mail/mutt-devel/files/extra-patch-edit-threads b/mail/mutt-devel/files/extra-patch-edit-threads
deleted file mode 100644
index b1695240c98d..000000000000
--- a/mail/mutt-devel/files/extra-patch-edit-threads
+++ /dev/null
@@ -1,604 +0,0 @@
-diff -Nru a/PATCHES b/PATCHES
---- a/PATCHES
-+++ b/PATCHES
-@@ -0,0 +1 @@
-+patch-1.5.7.tg.edit_threads.1
-diff -Nru a/OPS b/OPS
---- a/OPS 2005-01-29 17:07:15 +01:00
-+++ b/OPS 2005-01-29 17:07:15 +01:00
-@@ -96,6 +96,7 @@
- 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"
- OP_MAIN_CLEAR_FLAG "clear a status flag from a message"
-@@ -105,6 +106,7 @@
- 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"
---- /dev/null Sun Feb 13 11:16:10 2005
-+++ b/acconfig.h Sun Feb 13 11:15:44 2005
-@@ -0,0 +1,4 @@
-+/* Do you want to use the rethreading functions with IMAP
-+ * (--enable-imap-edit-threads) */
-+#undef IMAP_EDIT_THREADS
-+
-diff -Nru a/configure.in b/configure.in
---- a/configure.in.orig Mon Mar 14 08:30:21 2005
-+++ b/configure.in Mon Mar 14 08:33:05 2005
-@@ -566,6 +566,16 @@
- AM_CONDITIONAL(USE_GSS, test x$need_gss = xyes)
-
- 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, AC_HELP_STRING([--with-ssl[=PFX]], [Compile in SSL support for POP/IMAP]),
- [ if test "$with_ssl" != "no"
-diff -Nru a/copy.c b/copy.c
---- a/copy.c 2005-01-29 17:07:15 +01:00
-+++ b/copy.c 2005-01-29 17:07:15 +01:00
-@@ -95,6 +95,12 @@
- (ascii_strncasecmp ("Content-Length:", buf, 15) == 0 ||
- ascii_strncasecmp ("Lines:", buf, 6) == 0))
- continue;
-+ if ((flags & CH_UPDATE_REFS) &&
-+ ascii_strncasecmp ("References:", buf, 11) == 0)
-+ continue;
-+ if ((flags & CH_UPDATE_IRT) &&
-+ ascii_strncasecmp ("In-Reply-To:", buf, 12) == 0)
-+ continue;
- ignore = 0;
- }
-
-@@ -193,6 +199,12 @@
- ascii_strncasecmp ("type:", buf + 8, 5) == 0)) ||
- ascii_strncasecmp ("mime-version:", buf, 13) == 0))
- continue;
-+ if ((flags & CH_UPDATE_REFS) &&
-+ ascii_strncasecmp ("References:", buf, 11) == 0)
-+ continue;
-+ if ((flags & CH_UPDATE_IRT) &&
-+ ascii_strncasecmp ("In-Reply-To:", buf, 12) == 0)
-+ continue;
-
- /* Find x -- the array entry where this header is to be saved */
- if (flags & CH_REORDER)
-@@ -326,6 +338,8 @@
- 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
- string to use if CH_PREFIX is set
-@@ -335,6 +349,9 @@
- mutt_copy_header (FILE *in, HEADER *h, FILE *out, int flags, const char *prefix)
- {
- char buffer[SHORT_STRING];
-+
-+ flags |= (h->irt_changed ? CH_UPDATE_IRT : 0)
-+ | (h->refs_changed ? CH_UPDATE_REFS : 0);
-
- if (mutt_copy_hdr (in, out, h->offset, h->content->offset, flags, prefix) == -1)
- return (-1);
-@@ -358,7 +375,56 @@
- 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->NEW_ENV->in_reply_to)
-+ {
-+ LIST *listp = h->NEW_ENV->in_reply_to;
-+
-+ if (fputs ("In-Reply-To: ", out) == EOF)
-+ return (-1);
-+
-+ for (; listp; listp = listp->next)
-+ if ((fputs (listp->data, out) == EOF) || (fputc (' ', out) == EOF))
-+ return (-1);
-+
-+ if (fputc ('\n', out) == EOF)
-+ return (-1);
-+ }
-+
-+ if (h->refs_changed && h->NEW_ENV->references)
-+ {
-+ LIST *listp = h->NEW_ENV->references, *refs = NULL, *t;
-+
-+ if (fputs ("References: ", out) == EOF)
-+ return (-1);
-+
-+ /* Mutt stores references in reverse order, thus we create
-+ * a reordered refs list that we can put in the headers */
-+ for (; listp; listp = listp->next, refs = t)
-+ {
-+ t = (LIST *)safe_malloc (sizeof (LIST));
-+ t->data = listp->data;
-+ t->next = refs;
-+ }
-+
-+ for (; refs; refs = refs->next)
-+ if ((fputs (refs->data, out) == EOF) || (fputc (' ', out) == EOF))
-+ return (-1);
-+
-+ /* clearing refs from memory */
-+ for (t = refs; refs; refs = t->next, t = refs)
-+ safe_free ((void **)&refs);
-+
-+ if (fputc ('\n', out) == EOF)
-+ return (-1);
-+ }
-+#undef NEW_ENV
-+
- if (h->old || h->read)
- {
- if (fputs ("Status: ", out) == EOF)
-diff -Nru a/curs_main.c b/curs_main.c
---- a/curs_main.c 2005-01-29 17:07:15 +01:00
-+++ b/curs_main.c 2005-01-29 17:07:15 +01:00
-@@ -930,6 +930,11 @@
- else
- {
- mutt_set_flag (Context, CURHDR, M_TAG, !CURHDR->tagged);
-+
-+ Context->last_tag = CURHDR->tagged ? CURHDR :
-+ ((Context->last_tag == CURHDR && !CURHDR->tagged)
-+ ? NULL : Context->last_tag);
-+
- menu->redraw = REDRAW_STATUS;
- if (option (OPTRESOLVE) && menu->current < Context->vcount - 1)
- {
-@@ -1165,6 +1170,89 @@
- }
- done = 1;
- }
-+ break;
-+
-+ case OP_MAIN_BREAK_THREAD:
-+
-+ CHECK_MSGCOUNT;
-+ CHECK_VISIBLE;
-+ CHECK_READONLY;
-+
-+ if ((Sort & SORT_MASK) != SORT_THREADS)
-+ mutt_error _("Threading is not enabled.");
-+
-+#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;
-+ }
-+
-+ Context->changed = 1;
-+ mutt_message _("Thread broken");
-+
-+ if (menu->menu == MENU_PAGER)
-+ {
-+ op = OP_DISPLAY_MESSAGE;
-+ continue;
-+ }
-+ else
-+ menu->redraw |= REDRAW_INDEX;
-+ }
-+
-+ break;
-+
-+ case OP_MAIN_LINK_THREADS:
-+
-+ CHECK_MSGCOUNT;
-+ CHECK_VISIBLE;
-+ CHECK_READONLY;
-+
-+ if ((Sort & SORT_MASK) != SORT_THREADS)
-+ mutt_error _("Threading is not enabled.");
-+
-+#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))
-+ mutt_error _("First, please tag a message to be linked here");
-+ else
-+ {
-+ HEADER *oldcur = CURHDR;
-+
-+ if (mutt_link_threads (CURHDR, tag ? NULL : Context->last_tag,
-+ Context))
-+ {
-+ mutt_sort_headers (Context, 1);
-+ menu->current = oldcur->virtual;
-+
-+ Context->changed = 1;
-+ mutt_message _("Threads linked");
-+ }
-+ else
-+ mutt_error _("No thread linked");
-+ }
-+
-+ if (menu->menu == MENU_PAGER)
-+ {
-+ op = OP_DISPLAY_MESSAGE;
-+ continue;
-+ }
-+ else
-+ menu->redraw |= REDRAW_STATUS | REDRAW_INDEX;
-+
- break;
-
- case OP_EDIT_TYPE:
-diff -Nru a/doc/manual.sgml.head b/doc/manual.sgml.head
---- a/doc/manual.sgml.head 2005-01-29 17:07:15 +01:00
-+++ b/doc/manual.sgml.head 2005-01-29 17:07:15 +01:00
-@@ -2322,8 +2322,43 @@
- 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 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>
-+
-+Some mailers tend to "forget" to correctly set the "In-Reply-To:" and
-+"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, 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.
-+
-+<sect2>Breaking threads
-+<p>
-+
-+On mailing lists, some people are in the bad habit of starting a new
-+discussion by hitting "reply" to any message from the list and changing
-+the subject to a totally unrelated one.
-+You can fix such threads by using the ``break-thread'' function (bound
-+by default to #), which will turn the subthread starting from the
-+current message into a whole different thread.
-+
- <sect1>Delivery Status Notification (DSN) Support
- <p>
-+
- RFC1894 defines a set of MIME content types for relaying information
- about the status of electronic mail messages. These can be thought of as
- ``return receipts.'' Berkeley sendmail 8.8.x currently has some command
-diff -Nru a/functions.h b/functions.h
---- a/functions.h 2005-01-29 17:07:15 +01:00
-+++ b/functions.h 2005-01-29 17:07:15 +01:00
-@@ -69,6 +69,7 @@
- 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" },
- { "collapse-thread", OP_MAIN_COLLAPSE_THREAD, "\033v" },
-@@ -95,6 +96,7 @@
- { "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" },
- { "toggle-new", OP_TOGGLE_NEW, "N" },
-@@ -153,6 +155,7 @@
- };
-
- struct binding_t OpPager[] = {
-+ { "break-thread", OP_MAIN_BREAK_THREAD, "#" },
- { "create-alias", OP_CREATE_ALIAS, "a" },
- { "bounce-message", OP_BOUNCE_MESSAGE, "b" },
- { "change-folder", OP_MAIN_CHANGE_FOLDER, "c" },
-@@ -175,6 +178,7 @@
- { "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" },
- { "mail", OP_MAIL, "m" },
-diff -Nru a/imap/imap.c b/imap/imap.c
---- a/imap/imap.c 2005-01-29 17:07:15 +01:00
-+++ b/imap/imap.c 2005-01-29 17:07:15 +01:00
-@@ -983,9 +983,11 @@
- 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 -Nru a/main.c b/main.c
---- a/main.c 2005-01-29 17:07:15 +01:00
-+++ b/main.c 2005-01-29 17:07:15 +01:00
-@@ -235,6 +235,12 @@
- "-USE_IMAP "
- #endif
-
-+#ifdef IMAP_EDIT_THREADS
-+ "+IMAP_EDIT_THREADS "
-+#else
-+ "-IMAP_EDIT_THREADS "
-+#endif
-+
- #ifdef USE_GSS
- "+USE_GSS "
- #else
-diff -Nru a/mh.c b/mh.c
---- a/mh.c 2005-01-29 17:07:15 +01:00
-+++ b/mh.c 2005-01-29 17:07:15 +01:00
-@@ -1326,7 +1326,7 @@
- {
- 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;
-
-@@ -1337,9 +1337,9 @@
- {
- 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 -Nru a/mutt.h b/mutt.h
---- a/mutt.h 2005-01-29 17:07:15 +01:00
-+++ b/mutt.h 2005-01-29 17:07:15 +01:00
-@@ -96,6 +96,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_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() */
- #define M_ALIAS 1 /* do alias "completion" by calling up the alias-menu */
-@@ -542,6 +544,7 @@
- #define mutt_new_rx_list() safe_calloc (1, sizeof (RX_LIST))
- #define mutt_new_spam_list() safe_calloc (1, sizeof (SPAM_LIST))
- void mutt_free_list (LIST **);
-+LIST *mutt_copy_list (LIST *);
- void mutt_free_rx_list (RX_LIST **);
- void mutt_free_spam_list (SPAM_LIST **);
- int mutt_matches_ignore (const char *, LIST *);
-@@ -699,6 +702,8 @@
- 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 recip_valid : 1; /* is_recipient is valid */
- unsigned int active : 1; /* message is not to be removed */
- unsigned int trash : 1; /* message is marked as trashed on disk.
-@@ -739,6 +744,10 @@
- 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
-@@ -803,6 +812,7 @@
- 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 */
- HASH *subj_hash; /* hash table by subject */
-diff -Nru a/mx.c b/mx.c
---- a/mx.c 2005-01-29 17:07:15 +01:00
-+++ b/mx.c 2005-01-29 17:07:15 +01:00
-@@ -1161,6 +1161,8 @@
- ctx->deleted = 0;
- }
- }
-+ else if (ctx->last_tag && ctx->last_tag->deleted)
-+ ctx->last_tag = NULL; /* reset last tagged msg now useless */
- }
-
- /* really only for IMAP - imap_sync_mailbox results in a call to
-diff -Nru a/pager.c b/pager.c
---- a/pager.c 2005-01-29 17:07:15 +01:00
-+++ b/pager.c 2005-01-29 17:07:15 +01:00
-@@ -2492,6 +2492,11 @@
- case OP_TAG:
- CHECK_MODE(IsHeader (extra));
- mutt_set_flag (Context, extra->hdr, M_TAG, !extra->hdr->tagged);
-+
-+ Context->last_tag = extra->hdr->tagged ? extra->hdr :
-+ ((Context->last_tag == extra->hdr && !extra->hdr->tagged)
-+ ? NULL : Context->last_tag);
-+
- redraw = REDRAW_STATUS | REDRAW_INDEX;
- if (option (OPTRESOLVE))
- {
-diff -Nru a/protos.h b/protos.h
---- a/protos.h 2005-01-29 17:07:15 +01:00
-+++ b/protos.h 2005-01-29 17:07:15 +01:00
-@@ -161,6 +161,7 @@
- void mutt_block_signals_system (void);
- void mutt_body_handler (BODY *, STATE *);
- 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 *);
-@@ -302,6 +303,7 @@
- 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_match_rx_list (const char *, RX_LIST *);
- int mutt_match_spam_list (const char *, SPAM_LIST *, char *, int);
-diff -Nru a/thread.c b/thread.c
---- a/thread.c 2005-01-29 17:07:15 +01:00
-+++ b/thread.c 2005-01-29 17:07:15 +01:00
-@@ -1340,3 +1340,105 @@
-
- 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;
-+}