Index: OPS
===================================================================
RCS file: /home/roessler/cvs/mutt/OPS,v
retrieving revision 3.7
diff -u -r3.7 OPS
--- foo/OPS	24 Jul 2005 16:51:38 -0000	3.7
+++ bar/OPS	6 Oct 2005 17:06:50 -0000
@@ -56,6 +56,7 @@
 OP_DISPLAY_ADDRESS "display full address of sender"
 OP_DISPLAY_HEADERS "display message and toggle header weeding"
 OP_DISPLAY_MESSAGE "display a message"
+OP_EDIT_LABEL "add, change, or delete a message's label"
 OP_EDIT_MESSAGE "edit the raw message"
 OP_EDITOR_BACKSPACE "delete the char in front of the cursor"
 OP_EDITOR_BACKWARD_CHAR "move the cursor one character to the left"
Index: PATCHES
===================================================================
RCS file: /home/roessler/cvs/mutt/PATCHES,v
retrieving revision 3.6
diff -u -r3.6 PATCHES
--- foo/PATCHES	9 Dec 2002 17:44:54 -0000	3.6
+++ bar/PATCHES	6 Oct 2005 17:06:50 -0000
@@ -0,0 +1 @@
+patch-1.5.11.dgc.xlabel_ext.7
Index: copy.c
===================================================================
RCS file: /home/roessler/cvs/mutt/copy.c,v
retrieving revision 3.26
diff -u -r3.26 copy.c
--- foo/copy.c	29 Sep 2005 23:02:49 -0000	3.26
+++ bar/copy.c	6 Oct 2005 17:06:50 -0000
@@ -108,6 +108,10 @@
 	ignore = 0;
       }
 
+      if (flags & CH_UPDATE_LABEL &&
+	  mutt_strncasecmp ("X-Label:", buf, 8) == 0)
+	continue;
+
       if (!ignore && fputs (buf, out) == EOF)
 	return (-1);
     }
@@ -475,6 +479,15 @@
       fprintf (out, "Lines: %d\n", h->lines);
   }
 
+  if (flags & CH_UPDATE_LABEL && h->xlabel_changed)
+  {
+    h->xlabel_changed = 0;
+    if (h->env->x_label != NULL)
+      if (fprintf(out, "X-Label: %s\n", h->env->x_label) !=
+		  10 + strlen(h->env->x_label))
+        return -1;
+  }
+
   if ((flags & CH_NONEWLINE) == 0)
   {
     if (flags & CH_PREFIX)
@@ -556,6 +569,9 @@
       _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix), Context, hdr, 0);
   }
 
+  if (hdr->xlabel_changed)
+    chflags |= CH_UPDATE_LABEL;
+
   if ((flags & M_CM_NOHEADER) == 0)
   {
     if (flags & M_CM_PREFIX)
Index: curs_main.c
===================================================================
RCS file: /home/roessler/cvs/mutt/curs_main.c,v
retrieving revision 3.34
diff -u -r3.34 curs_main.c
--- foo/curs_main.c	4 Oct 2005 04:29:09 -0000	3.34
+++ bar/curs_main.c	6 Oct 2005 17:06:50 -0000
@@ -1945,6 +1945,21 @@
 	menu->redraw = REDRAW_FULL;
 	break;
 
+      case OP_EDIT_LABEL:
+
+	CHECK_MSGCOUNT;
+	CHECK_READONLY;
+	rc = mutt_label_message(tag ? NULL : CURHDR);
+	if (rc > 0) {
+	  Context->changed = 1;
+	  menu->redraw = REDRAW_FULL;
+	  mutt_message ("%d label%s changed.", rc, rc == 1 ? "" : "s");
+	}
+	else {
+	  mutt_message _("No labels changed.");
+	}
+	break;
+
       case OP_LIST_REPLY:
 
 	CHECK_ATTACH;
Index: functions.h
===================================================================
RCS file: /home/roessler/cvs/mutt/functions.h,v
retrieving revision 3.12
diff -u -r3.12 functions.h
--- foo/functions.h	17 Sep 2005 20:46:10 -0000	3.12
+++ bar/functions.h	6 Oct 2005 17:06:51 -0000
@@ -82,6 +82,7 @@
   { "delete-thread",		OP_DELETE_THREAD,		"\004" },
   { "delete-subthread",		OP_DELETE_SUBTHREAD,		"\033d" },
   { "edit",			OP_EDIT_MESSAGE,		"e" },
+  { "edit-label",		OP_EDIT_LABEL,			"y" },
   { "edit-type",		OP_EDIT_TYPE,			"\005" },
   { "forward-message",		OP_FORWARD_MESSAGE,		"f" },
   { "flag-message",		OP_FLAG_MESSAGE,		"F" },
@@ -166,6 +167,7 @@
   { "delete-thread",	OP_DELETE_THREAD,		"\004" },
   { "delete-subthread",	OP_DELETE_SUBTHREAD,		"\033d" },
   { "edit",		OP_EDIT_MESSAGE,		"e" },
+  { "edit-label",	OP_EDIT_LABEL,			"y" },
   { "edit-type",	OP_EDIT_TYPE,			"\005" },
   { "forward-message",	OP_FORWARD_MESSAGE,		"f" },
   { "flag-message",	OP_FLAG_MESSAGE,		"F" },
Index: headers.c
===================================================================
RCS file: /home/roessler/cvs/mutt/headers.c,v
retrieving revision 3.8
diff -u -r3.8 headers.c
--- foo/headers.c	17 Sep 2005 20:46:10 -0000	3.8
+++ bar/headers.c	6 Oct 2005 17:06:51 -0000
@@ -205,3 +205,59 @@
     }
   }
 }
+
+/*
+ * dgc: Add an X-Label: field.
+ */
+static int label_message(HEADER *hdr, char *new)
+{
+	if (hdr == NULL)
+		return 0;
+	if (hdr->env->x_label == NULL && new == NULL)
+		return 0;
+	if (hdr->env->x_label != NULL && new != NULL &&
+			strcmp(hdr->env->x_label, new) == 0)
+		return 0;
+	if (hdr->env->x_label != NULL)
+		FREE(&hdr->env->x_label);
+	if (new == NULL)
+		hdr->env->x_label = NULL;
+	else
+		hdr->env->x_label = safe_strdup(new);
+	return hdr->changed = hdr->xlabel_changed = 1;
+}
+
+int mutt_label_message(HEADER *hdr)
+{
+	char buf[LONG_STRING], *new;
+	int i;
+	int changed;
+
+	*buf = '\0';
+	if (hdr != NULL && hdr->env->x_label != NULL) {
+		strncpy(buf, hdr->env->x_label, LONG_STRING);
+	}
+
+	mutt_get_field("Label: ", buf, sizeof(buf), M_CLEAR);
+	new = buf;
+	SKIPWS(new);
+	if (*new == '\0')
+		new = NULL;
+
+	changed = 0;
+	if (hdr != NULL) {
+		changed += label_message(hdr, new);
+	} else {
+#define HDR_OF(index)	Context->hdrs[Context->v2r[(index)]]
+		for (i = 0; i < Context->vcount; ++i) {
+			if (HDR_OF(i)->tagged)
+				if (label_message(HDR_OF(i), new)) {
+					++changed;
+					mutt_set_flag(Context, HDR_OF(i),
+						M_TAG, 0);
+				}
+		}
+	}
+
+	return changed;
+}
Index: mh.c
===================================================================
RCS file: /home/roessler/cvs/mutt/mh.c,v
retrieving revision 3.29
diff -u -r3.29 mh.c
--- foo/mh.c	17 Sep 2005 20:46:10 -0000	3.29
+++ bar/mh.c	6 Oct 2005 17:06:51 -0000
@@ -1382,7 +1382,7 @@
 {
   HEADER *h = ctx->hdrs[msgno];
 
-  if (h->attach_del || 
+  if (h->attach_del || h->xlabel_changed ||
       (h->env && (h->env->refs_changed || h->env->irt_changed)))
     if (mh_rewrite_message (ctx, msgno) != 0)
       return -1;
@@ -1394,7 +1394,7 @@
 {
   HEADER *h = ctx->hdrs[msgno];
 
-  if (h->attach_del || 
+  if (h->attach_del || h->xlabel_changed ||
       (h->env && (h->env->refs_changed || h->env->irt_changed)))
   {
     /* when doing attachment deletion/rethreading, fall back to the MH case. */
@@ -1503,6 +1503,7 @@
       }
     }
     else if (ctx->hdrs[i]->changed || ctx->hdrs[i]->attach_del ||
+	     ctx->hdrs[i]->xlabel_changed ||
 	     (ctx->magic == M_MAILDIR
 	      && (option (OPTMAILDIRTRASH) || ctx->hdrs[i]->trash)
 	      && (ctx->hdrs[i]->deleted != ctx->hdrs[i]->trash)))
Index: pager.c
===================================================================
RCS file: /home/roessler/cvs/mutt/pager.c,v
retrieving revision 3.29
diff -u -r3.29 pager.c
--- foo/pager.c	4 Oct 2005 05:24:00 -0000	3.29
+++ bar/pager.c	6 Oct 2005 17:06:51 -0000
@@ -2658,6 +2658,18 @@
 	redraw = REDRAW_FULL;
 	break;
 
+     case OP_EDIT_LABEL:
+        CHECK_MODE(IsHeader (extra));
+        rc = mutt_label_message(extra->hdr);
+        if (rc > 0) {
+          Context->changed = 1;
+          redraw = REDRAW_FULL;
+          mutt_message ("%d label%s changed.", rc, rc == 1 ? "" : "s");
+        }
+        else {
+          mutt_message _("No labels changed.");
+        }
+        break;
 
       case OP_MAIL_KEY:
         if (!(WithCrypto & APPLICATION_PGP))
Index: protos.h
===================================================================
RCS file: /home/roessler/cvs/mutt/protos.h,v
retrieving revision 3.39
diff -u -r3.39 protos.h
--- foo/protos.h	4 Oct 2005 06:05:39 -0000	3.39
+++ bar/protos.h	6 Oct 2005 17:06:51 -0000
@@ -181,6 +181,7 @@
 void mutt_edit_content_type (HEADER *, BODY *, FILE *);
 void mutt_edit_file (const char *, const char *);
 void mutt_edit_headers (const char *, const char *, HEADER *, char *, size_t);
+int mutt_label_message (HEADER *);
 void mutt_curses_error (const char *, ...);
 void mutt_curses_message (const char *, ...);
 void mutt_enter_command (void);
Index: doc/manual.xml.head
===================================================================
RCS file: /home/roessler/cvs/mutt/doc/manual.xml.head,v
retrieving revision 3.13
diff -u -r3.13 manual.xml.head
--- foo/doc/manual.xml.head	5 Oct 2005 19:24:40 -0000	3.13
+++ bar/doc/manual.xml.head	6 Oct 2005 17:06:51 -0000
@@ -4019,6 +4019,12 @@
 </para>
 
 <para>
+You can change or delete the ``X-Label:'' field within Mutt using the
+``edit-label'' command, bound to the ``y'' key by default.  This works
+for tagged messages, too.
+</para>
+
+<para>
 Lastly, Mutt has the ability to <link linkend="sort">sort</link> the mailbox into
 <link linkend="threads">threads</link>.  A thread is a group of messages which all relate to the same
 subject.  This is usually organized into a tree-like structure where a
Index: imap/imap.c
===================================================================
RCS file: /home/roessler/cvs/mutt/imap/imap.c,v
retrieving revision 3.44
diff -u -r3.44 imap.c
--- foo/imap/imap.c	22 Sep 2005 03:09:49 -0000	3.44
+++ bar/imap/imap.c	6 Oct 2005 17:06:51 -0000
@@ -1058,7 +1058,7 @@
   /* save status changes */
   for (n = 0; n < ctx->msgcount; n++)
   {
-    if (ctx->hdrs[n]->active && ctx->hdrs[n]->changed)
+    if (ctx->hdrs[n]->active && (ctx->hdrs[n]->changed || ctx->hdrs[n]->xlabel_changed))
     {
       mutt_message (_("Saving message status flags... [%d/%d]"), n+1,
         ctx->msgcount);
@@ -1066,8 +1066,9 @@
       /* 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. */
+      /* AFAICT (dgc) we need to do this for header changes, too. */
       if ((ctx->hdrs[n]->env && (ctx->hdrs[n]->env->refs_changed || ctx->hdrs[n]->env->irt_changed)) ||
-	  ctx->hdrs[n]->attach_del)
+	  ctx->hdrs[n]->attach_del || ctx->hdrs[n]->xlabel_changed)
       {
 	dprint (3, (debugfile, "imap_sync_mailbox: Attachments to be deleted, falling back to _mutt_save_message\n"));
 	if (!appendctx)
@@ -1078,6 +1079,7 @@
 	}
 	else
 	  _mutt_save_message (ctx->hdrs[n], appendctx, 1, 0, 0);
+        ctx->hdrs[n]->xlabel_changed = 0;
       }
 
       if (imap_sync_message (idata, ctx->hdrs[n], &cmd, &err_continue) < 0)
Index: mutt.h
===================================================================
RCS file: /home/roessler/cvs/mutt/mutt.h,v
retrieving revision 3.60
diff -u -r3.60 mutt.h
--- foo/mutt.h	4 Oct 2005 06:05:39 -0000	3.60
+++ bar/mutt.h	6 Oct 2005 17:09:40 -0000
@@ -92,6 +92,7 @@
 #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: */
+#define CH_UPDATE_LABEL	(1<<18) /* update X-Label: from hdr->env->x_label? */
 
 /* flags for mutt_enter_string() */
 #define  M_ALIAS   1      /* do alias "completion" by calling up the alias-menu */
@@ -716,6 +717,7 @@
 					 * This flag is used by the maildir_trash
 					 * option.
 					 */
+  unsigned int xlabel_changed : 1;	/* editable - used for syncing */
   
   /* timezone of the sender of this message */
   unsigned int zhours : 5;
