This lists header prefixes to leave folded in the original state when
$weed is enabled.

This provides the ability to selectively show headers, such as spam
headers, with their original folding, which may be more readable than
unfolded in a wide terminal.

This also fixes a potential bug where a header missing a newline was
passing p=NULL as the end parameter to write_one_header().  Since that
function does start and end comparisons, I can only assume that this
never actually happens.
---
I haven't had a chance yet to review and test this patch much.  This is
just an early look for feedback.

The init.h may not apply cleanly because I reordered the commands to
group "un" commands with their opposites in an earlier patch, which I
haven't committed yet.

 doc/manual.xml.head | 85 +++++++++++++++++++++++++++++++++++++++++++++
 doc/muttrc.man.head | 14 ++++++--
 globals.h           |  1 +
 init.h              |  2 ++
 sendlib.c           | 49 +++++++++++++++++++++-----
 5 files changed, 141 insertions(+), 10 deletions(-)

diff --git a/doc/manual.xml.head b/doc/manual.xml.head
index ecb07077..31829956 100644
--- a/doc/manual.xml.head
+++ b/doc/manual.xml.head
@@ -3485,6 +3485,23 @@ line can be manipulated with 
<command>ignore/unignore</command> and
 <command>hdr_order/unhdr_order</command> commands.
 </para>
 
+<para>
+Mutt has two modes for displaying the headers.  When <link
+linkend="weed">$weed</link> is set (the default), or toggled on via
+<literal>&lt;display-toggle-weed&gt;</literal>, mutt unfolds and then
+refolds header lines using <link linkend="wrap">$wrap</link> as
+described above.  Furthermore, the following sections will be applied,
+allowing the selection and ordering of headers, and the ability to
+leave certain headers folded as they were in the original email.
+</para>
+
+<para>
+When <link linkend="weed">$weed</link> is unset, or toggled off via
+<literal>&lt;display-toggle-weed&gt;</literal>, mutt will display all
+headers as they appear in the original email (but still subject to
+being folded at the width of your terminal).  None of the following
+sections are applied.
+</para>
 </sect2>
 
 <sect2 id="ignore">
@@ -3602,6 +3619,52 @@ hdr_order From Date: From: To: Cc: Subject:
 </screen>
 </example>
 
+</sect2>
+
+<sect2 id="hdr-leave-folded">
+<title>Leaving Displayed Headers Folded</title>
+
+<para>Usage:</para>
+
+<cmdsynopsis>
+<command>hdr_leave_folded</command>
+<arg choice="plain">
+<replaceable class="parameter">header</replaceable>
+</arg>
+<arg choice="opt" rep="repeat">
+<replaceable class="parameter">header</replaceable>
+</arg>
+
+<command>unhdr_leave_folded</command>
+<group choice="req">
+<arg choice="plain">
+<replaceable>*</replaceable>
+</arg>
+<arg choice="plain" rep="repeat">
+<replaceable>header</replaceable>
+</arg>
+</group>
+</cmdsynopsis>
+
+<para>
+With the <command>hdr_leave_folded</command> command you can specify a
+list of headers to leave folded, as in the original email.  This can be useful
+for certain headers that are more readable as generated in the original email,
+such as spam headers.
+</para>
+
+<para>
+<quote><command>unhdr_leave_folded</command> *</quote> will clear all previous
+headers from the list, thus defaulting all headers to being unfolded.
+</para>
+
+<example id="ex-hdr-leave-folded">
+<title>Setting headers to leave folded</title>
+<screen>
+hdr_leave_folded x-spam-report
+</screen>
+</example>
+
 </sect2>
 </sect1>
 
@@ -11894,6 +11957,28 @@ The following are the commands understood by Mutt:
 </cmdsynopsis>
 </listitem>
 
+<listitem>
+<cmdsynopsis>
+<command><link linkend="hdr-leave-folded">hdr_leave_folded</link></command>
+<arg choice="plain">
+<replaceable class="parameter">header</replaceable>
+</arg>
+<arg choice="opt" rep="repeat">
+<replaceable class="parameter">header</replaceable>
+</arg>
+
+<command><link linkend="hdr-leave-folded">unhdr_leave_folded</link></command>
+<group choice="req">
+<arg choice="plain">
+<replaceable>*</replaceable>
+</arg>
+<arg choice="plain" rep="repeat">
+<replaceable>header</replaceable>
+</arg>
+</group>
+</cmdsynopsis>
+</listitem>
+
 <listitem>
 <cmdsynopsis>
 <command><link linkend="hdr-order">hdr_order</link></command>
diff --git a/doc/muttrc.man.head b/doc/muttrc.man.head
index 2da0d950..2e9c558b 100644
--- a/doc/muttrc.man.head
+++ b/doc/muttrc.man.head
@@ -325,7 +325,8 @@ attributes to objects.
 [\fBun\fP]\fBignore\fP \fIpattern\fP [ \fIpattern\fP ... ]
 The \fBignore\fP command permits you to specify header fields which
 you usually don't wish to see.  Any header field whose tag
-\fIbegins\fP with an \(lqignored\(rq pattern will be ignored.
+\fIbegins\fP with an \(lqignored\(rq pattern will be ignored,
+when $weed is set.
 .IP
 The \fBunignore\fP command permits you to define exceptions from
 the above mentioned list of ignored headers.
@@ -387,7 +388,16 @@ user-defined headers.
 .TP
 \fBhdr_order\fP \fIheader1\fP \fIheader2\fP [ ... ]
 With this command, you can specify an order in which mutt will
-attempt to present headers to you when viewing messages.
+attempt to present headers to you when viewing messages with
+$weed set.
+.
+.TP
+[\fBun\fP]\fBhdr_leave_folded\fP \fIheader1\fP \fIheader2\fP [ ... ]
+With this command, you can specify headers that mutt will leave
+folded, as they were in the original email, when viewing
+messages with $weed set.
+.IP
+The \fBunhdr_leave_folded\fP command removes headers from the list.
 .
 .TP
 \fBsave-hook\fP [\fB!\fP]\fIpattern\fP \fIfilename\fP
diff --git a/globals.h b/globals.h
index 0675348f..1bd4aa41 100644
--- a/globals.h
+++ b/globals.h
@@ -197,6 +197,7 @@ WHERE LIST *InlineAllow;
 WHERE LIST *InlineExclude;
 WHERE LIST *RootAllow;
 WHERE LIST *RootExclude;
+WHERE LIST *HeaderLeaveFoldedList;
 WHERE LIST *HeaderOrderList;
 WHERE LIST *Ignore;
 WHERE LIST *MailtoAllow;
diff --git a/init.h b/init.h
index 29d54b34..cce9dda1 100644
--- a/init.h
+++ b/init.h
@@ -5069,6 +5069,8 @@ const struct command_t Commands[] = {
 #endif
   { "group",            parse_group,            {.l=MUTT_GROUP} },
   { "ungroup",          parse_group,            {.l=MUTT_UNGROUP} },
+  { "hdr_leave_folded", parse_list,             {.p=&HeaderLeaveFoldedList} },
+  { "unhdr_leave_folded", parse_unlist,         {.p=&HeaderLeaveFoldedList} },
   { "hdr_order",        parse_list,             {.p=&HeaderOrderList} },
   { "unhdr_order",      parse_unlist,           {.p=&HeaderOrderList} },
 #ifdef HAVE_ICONV
diff --git a/sendlib.c b/sendlib.c
index a700d500..f7ef10e6 100644
--- a/sendlib.c
+++ b/sendlib.c
@@ -2067,7 +2067,7 @@ static int fold_one_header (FILE *fp, const char *tag, 
const char *value,
   return 0;
 }
 
-static char *unfold_header (char *s)
+static void unfold_header (char *s)
 {
   char *p = s, *q = s;
 
@@ -2092,8 +2092,6 @@ static char *unfold_header (char *s)
   }
   if (q)
     *q = 0;
-
-  return s;
 }
 
 static int write_one_header (FILE *fp, int pfxw, int max, int wraplen,
@@ -2179,12 +2177,25 @@ int mutt_write_one_header (FILE *fp, const char *tag, 
const char *value,
                            const char *pfx, int wraplen, int flags)
 {
   char *p = (char *)value, *last, *line;
-  int max = 0, w, rc = -1;
+  int max = 0, w, rc = -1, delay_unfold = 0;
   int pfxw = mutt_strwidth (pfx);
   char *v = safe_strdup (value);
+  BUFFER *header_buf = NULL;
 
-  if (!(flags & CH_DISPLAY) || option (OPTWEED))
-    v = unfold_header (v);
+  if (!(flags & CH_DISPLAY))
+    unfold_header (v);
+  else if (option (OPTWEED))
+  {
+    if (!HeaderLeaveFoldedList)
+      unfold_header (v);
+    else if (tag)
+    {
+      if (!mutt_matches_ignore (tag, HeaderLeaveFoldedList))
+        unfold_header (v);
+    }
+    else
+      delay_unfold = 1;
+  }
 
   /* when not displaying, use sane wrap value */
   if (!(flags & CH_DISPLAY))
@@ -2217,6 +2228,7 @@ int mutt_write_one_header (FILE *fp, const char *tag, 
const char *value,
     }
   }
 
+  header_buf = mutt_buffer_pool_get ();
   p = last = line = (char *)v;
   while (p && *p)
   {
@@ -2236,7 +2248,15 @@ int mutt_write_one_header (FILE *fp, const char *tag, 
const char *value,
     line = ++p;
     if (*p != ' ' && *p != '\t')
     {
-      if (write_one_header (fp, pfxw, max, wraplen, pfx, last, p, flags) < 0)
+      mutt_buffer_substrcpy (header_buf, last, p);
+      if (delay_unfold &&
+          !mutt_matches_ignore (mutt_b2s (header_buf), HeaderLeaveFoldedList))
+      {
+        unfold_header (header_buf->data);
+        mutt_buffer_fix_dptr (header_buf);
+      }
+      if (write_one_header (fp, pfxw, max, wraplen, pfx,
+                            header_buf->data, header_buf->dptr, flags) < 0)
         goto out;
       last = p;
       max = 0;
@@ -2244,12 +2264,25 @@ int mutt_write_one_header (FILE *fp, const char *tag, 
const char *value,
   }
 
   if (last && *last)
-    if (write_one_header (fp, pfxw, max, wraplen, pfx, last, p, flags) < 0)
+  {
+    mutt_buffer_strcpy (header_buf, last);
+    if (!p)
+      mutt_buffer_addch (header_buf, '\n');
+    if (delay_unfold &&
+        !mutt_matches_ignore (mutt_b2s (header_buf), HeaderLeaveFoldedList))
+    {
+      unfold_header (header_buf->data);
+      mutt_buffer_fix_dptr (header_buf);
+    }
+    if (write_one_header (fp, pfxw, max, wraplen, pfx,
+                          header_buf->data, header_buf->dptr, flags) < 0)
       goto out;
+  }
 
   rc = 0;
 
 out:
+  mutt_buffer_pool_release (&header_buf);
   FREE (&v);
   return rc;
 }
-- 
2.53.0

Reply via email to