[PATCH] Add (un)hdr_leave_folded commands.

"Kevin J. McCarthy" <[email protected]>
Newsgroups gmane.mail.mutt.devel
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.