Here is a version that's a bit easier on the eyes, lacking the magic
constants, implicit order dependencies and needless string copies of the
original.

-- 
Please *no* private copies of mailing list or newsgroup messages.
Rule 420: All persons more than eight miles high to leave the court.
diff --git a/globals.h b/globals.h
index 57fa497..22ff445 100644
--- a/globals.h
+++ b/globals.h
@@ -52,6 +52,7 @@ WHERE char *EscChar;
 WHERE char *FolderFormat;
 WHERE char *ForwFmt;
 WHERE char *Fqdn;
+WHERE char *Fromchars;
 WHERE char *HdrFmt;
 WHERE char *HistFile;
 WHERE char *Homedir;
diff --git a/hdrline.c b/hdrline.c
index 21adc28..dfb31fc 100644
--- a/hdrline.c
+++ b/hdrline.c
@@ -56,7 +56,7 @@ int mutt_is_subscribed_list (ADDRESS *addr)
  * return 1.  Otherwise, simply return 0.
  */
 static int
-check_for_mailing_list (ADDRESS *adr, char *pfx, char *buf, int buflen)
+check_for_mailing_list (ADDRESS *adr, const char *pfx, char *buf, int buflen)
 {
   for (; adr; adr = adr->next)
   {
@@ -103,30 +103,76 @@ static int first_mailing_list (char *buf, size_t buflen, ADDRESS *a)
   return 0;
 }
 
+enum {
+  DISP_TO,
+  DISP_CC,
+  DISP_BCC,
+  DISP_FROM,
+  DISP_NUM
+};
+
+static const char* make_from_prefix(int disp, char short_prefix[2])
+{
+  static const char* long_prefixes[DISP_NUM] = {
+    [DISP_TO] = "To ",
+    [DISP_CC] = "Cc ",
+    [DISP_BCC] = "Bcc ",
+    [DISP_FROM] = ""
+  };
+
+  if (Fromchars == NULL || *Fromchars == '\0')
+    return long_prefixes[disp];
+  else if (strlen(Fromchars) <= disp) {
+    short_prefix[0] = ' ';
+    short_prefix[1] = '\0';
+    return short_prefix;
+  }
+  else if (Fromchars[disp] == '\r')
+    return "";
+  short_prefix[0] =  Fromchars[disp];
+  short_prefix[1] = '\0';
+  return short_prefix;
+}
+
 static void make_from (ENVELOPE *hdr, char *buf, size_t len, int do_lists)
 {
-  int me;
+  int me, disp;
+  const char* prefix;
+  char short_prefix[2];
+  ADDRESS* name_hdr[DISP_NUM] = {
+    [DISP_TO] = hdr->to,
+    [DISP_CC] = hdr->cc,
+    [DISP_BCC] = hdr->bcc,
+    [DISP_FROM] = hdr->from
+  };
 
   me = mutt_addr_is_user (hdr->from);
 
   if (do_lists || me)
   {
-    if (check_for_mailing_list (hdr->to, "To ", buf, len))
+    prefix = make_from_prefix(DISP_TO, short_prefix);
+    if (check_for_mailing_list (hdr->to, prefix, buf, len))
       return;
-    if (check_for_mailing_list (hdr->cc, "Cc ", buf, len))
+    prefix = make_from_prefix(DISP_CC, short_prefix);
+    if (check_for_mailing_list (hdr->cc, prefix, buf, len))
       return;
   }
 
   if (me && hdr->to)
-    snprintf (buf, len, "To %s", mutt_get_name (hdr->to));
+    disp = DISP_TO;
   else if (me && hdr->cc)
-    snprintf (buf, len, "Cc %s", mutt_get_name (hdr->cc));
+    disp = DISP_CC;
   else if (me && hdr->bcc)
-    snprintf (buf, len, "Bcc %s", mutt_get_name (hdr->bcc));
+    disp = DISP_BCC;
   else if (hdr->from)
-    strfcpy (buf, mutt_get_name (hdr->from), len);
-  else
-    *buf = 0;
+    disp = DISP_FROM;
+  else {
+    *buf = '\0';
+    return;
+  }
+
+  prefix = make_from_prefix(disp, short_prefix);
+  snprintf (buf, len, "%s%s", prefix, mutt_get_name (name_hdr[disp]));
 }
 
 static void make_from_addr (ENVELOPE *hdr, char *buf, size_t len, int do_lists)
diff --git a/init.h b/init.h
index 0adf360..8d94425 100644
--- a/init.h
+++ b/init.h
@@ -871,6 +871,29 @@ struct option_t MuttVars[] = {
   ** .pp
   ** This setting defaults to the contents of the environment variable \fC$$$EMAIL\fP.
   */
+  { "from_chars",		DT_STR,	 R_BOTH, UL &Fromchars, UL 0 },
+  /*
+  ** .pp
+  ** Controls the character used to prefix the %F and %L fields in the
+  ** index.  The first character is the one used when the mail is
+  ** written by you and has a To address, or has a known mailing list in
+  ** the To address.  The second is used when the mail is written by you
+  ** and has a Cc address, or has a known mailing list in the Cc
+  ** address.  The third is used when the mail is written by you and has
+  ** a Bcc address.  Lastly, the fourth character is used to prefix the
+  ** field in all remaining cases.
+  ** .pp
+  ** If this is empty or unset (default), the traditional long "To ",
+  ** "Cc " and "Bcc " prefixes are used.  If set but too short to
+  ** include a character for a particular case, a single space will be
+  ** prepended to the field.  To prevent any prefix at all from being
+  ** added in a particular case, use the special value CR (aka ^M)
+  ** for the corresponding character.
+  ** .pp
+  ** This slightly odd interface is necessitated by mutt's handling of
+  ** string variables; one cannot tell a variable that is unset from one
+  ** that is set to the empty string.
+  */
   { "gecos_mask",	DT_RX,	 R_NONE, UL &GecosMask, UL "^[^,]*" },
   /*
   ** .pp

Reply via email to