unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* Display extra headers for emacs-mua 2 new patches
@ 2019-11-22 23:07 Johan Parin
  2019-11-22 23:07 ` [PATCH] Display extra headers for emacs-mua - cmd line option Johan Parin
  2019-11-22 23:07 ` [PATCH] Display extra headers for emacs-mua - return all headers Johan Parin
  0 siblings, 2 replies; 4+ messages in thread
From: Johan Parin @ 2019-11-22 23:07 UTC (permalink / raw)
  To: notmuch

This is a refinement of my first two submissions, cleaned up and also
working with reply, which the first versions were not:

1) notmuch-show returns all headers
2) notmuch-show returns extra headers configured by a command line
option, which is passed from the emacs mua.

As for the second, I changed the command line option to specify extra
headers instead of the full set of headers. This is a lot easier,
since some headers have special treatment in format_headers_sprinter,
and it is also called from reply.

This patch is very similar to the one storing the option in the
database and using a global database pointer, except that elisp is
added to pass the command line flag.

There is still one global used in notmuch-show.c in order to pass down
the command line argument. This really is necessary since changing the
signature of format_headers_sprinter is not really feasible as shown
by the patch which passed around the database pointer.

I hope that having this global is more acceptable than having a
global database pointer.

So in summary, the patch variants I have submitted:

a) notmuch-show.c returns all headers in message.
   Con: There are concerns about potential performance impact
b) notmuch-show.c returns extra headers as configured in database.
   Con: Uses a file global database pointer in notmuch-show.c
c) notmuch-show.c returns extra headers as specified by a command line
   flag. This flag is set by the emacs-mua based on
   notmuch-message-headers if that differs from the default list.

I don't see any con with c) really.

I have only concerned myself with sexp output since I personally use
the emacs-mua. But I think modification for the other formats can be
done as a later step.

/Johan

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH] Display extra headers for emacs-mua - cmd line option
  2019-11-22 23:07 Display extra headers for emacs-mua 2 new patches Johan Parin
@ 2019-11-22 23:07 ` Johan Parin
  2019-11-23  9:44   ` Johan Parin
  2019-11-22 23:07 ` [PATCH] Display extra headers for emacs-mua - return all headers Johan Parin
  1 sibling, 1 reply; 4+ messages in thread
From: Johan Parin @ 2019-11-22 23:07 UTC (permalink / raw)
  To: notmuch; +Cc: Johan Parin

Add a new flag --extra-headers to notmuch show, in order to let the
user specify displayed headers using `notmuch-message-headers' in the
emacs mua.

The flag will impact which headers are output in
format_headers_sprinter.

The emacs mua will generate the --extra-headers flag based on
notmuch-message-headers.

See this bug report:

  https://notmuchmail.org/pipermail/notmuch/2017/026069.html
---
 doc/man1/notmuch-show.rst |  7 +++++++
 emacs/notmuch-lib.el      | 14 ++++++++++++++
 emacs/notmuch-query.el    |  9 ++++++++-
 emacs/notmuch-show.el     | 10 ----------
 emacs/notmuch-tree.el     | 16 +++++++++++-----
 notmuch-show.c            | 38 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 78 insertions(+), 16 deletions(-)

diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst
index becd3e79..9f61acce 100644
--- a/doc/man1/notmuch-show.rst
+++ b/doc/man1/notmuch-show.rst
@@ -190,6 +190,13 @@ Supported options for **show** include
     "text/html" parts, no part with content type "text/html" is included
     in the output.
 
+``--extra-headers=header[,header...]``
+    A comma separated list of extra headers that will be output by
+    **notmuch show** with ``--format=sexp``, if present in the
+    message.
+
+    Default: empty list.
+
 A common use of **notmuch show** is to display a single thread of email
 messages. For this, use a search term of "thread:<thread-id>" as can be
 seen in the first column of output from the **notmuch search** command.
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 8acad267..50dfb743 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -148,6 +148,20 @@ For example, if you wanted to remove an \"inbox\" tag and add an
   :group 'notmuch-search
   :group 'notmuch-show)
 
+(defconst notmuch-default-message-headers
+  '("Subject" "To" "Cc" "Date")
+  "Default set of headers to be displayed when showing a message")
+
+(defcustom notmuch-message-headers notmuch-default-message-headers
+  "Headers that should be shown in a message, in this order.
+
+For an open message, all of these headers will be made visible
+according to `notmuch-message-headers-visible' or can be toggled
+with `notmuch-show-toggle-visibility-headers'. For a closed message,
+only the first header in the list will be visible."
+  :type '(repeat string)
+  :group 'notmuch-show)
+
 (defvar notmuch-common-keymap
   (let ((map (make-sparse-keymap)))
     (define-key map "?" 'notmuch-help)
diff --git a/emacs/notmuch-query.el b/emacs/notmuch-query.el
index 563e4acf..c834a6d8 100644
--- a/emacs/notmuch-query.el
+++ b/emacs/notmuch-query.el
@@ -30,7 +30,14 @@ A thread is a forest or list of trees. A tree is a two element
 list where the first element is a message, and the second element
 is a possibly empty forest of replies.
 "
-  (let ((args '("show" "--format=sexp" "--format-version=4")))
+  ;; (let ((args '("show" "--format=sexp" "--format-version=4")))
+  (let ((extra-headers
+	  (cl-set-difference notmuch-message-headers notmuch-default-message-headers
+			     :test #'string=))
+	(args '("show" "--format=sexp" "--format-version=4")))
+    (when extra-headers
+      (nconc args (list (concat "--extra-headers="
+				(mapconcat #'identity extra-headers ",")))))
     (if notmuch-show-process-crypto
 	(setq args (append args '("--decrypt=true"))))
     (setq args (append args search-terms))
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index e13ca3d7..069f0184 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -53,16 +53,6 @@
 (declare-function notmuch-read-query "notmuch" (prompt))
 (declare-function notmuch-draft-resume "notmuch-draft" (id))
 
-(defcustom notmuch-message-headers '("Subject" "To" "Cc" "Date")
-  "Headers that should be shown in a message, in this order.
-
-For an open message, all of these headers will be made visible
-according to `notmuch-message-headers-visible' or can be toggled
-with `notmuch-show-toggle-visibility-headers'. For a closed message,
-only the first header in the list will be visible."
-  :type '(repeat string)
-  :group 'notmuch-show)
-
 (defcustom notmuch-message-headers-visible t
   "Should the headers be visible by default?
 
diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index c00315e8..4f97e632 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -915,14 +915,20 @@ the same as for the function notmuch-tree."
   (let* ((search-args (concat basic-query
 		       (if query-context (concat " and (" query-context ")"))
 		       ))
-	 (message-arg "--entire-thread"))
+	 (message-arg "--entire-thread")
+	 (extra-headers
+	  (cl-set-difference notmuch-message-headers notmuch-default-message-headers
+			     :test #'string=))
+	 (args '("notmuch-tree" (current-buffer) #'notmuch-tree-process-sentinel
+		  "show" "--body=false" "--format=sexp" "--format-version=4")))
+    (when extra-headers
+      (nconc args (list (concat "--extra-headers="
+				(mapconcat #'identity extra-headers ",")))))
+    (nconc args search-args)
     (if (equal (car (process-lines notmuch-command "count" search-args)) "0")
 	(setq search-args basic-query))
     (notmuch-tag-clear-cache)
-    (let ((proc (notmuch-start-notmuch
-		 "notmuch-tree" (current-buffer) #'notmuch-tree-process-sentinel
-		 "show" "--body=false" "--format=sexp" "--format-version=4"
-		 message-arg search-args))
+    (let ((proc (apply #'notmuch-start-notmuch args))
 	  ;; Use a scratch buffer to accumulate partial output.
 	  ;; This buffer will be killed by the sentinel, which
 	  ;; should be called no matter how the process dies.
diff --git a/notmuch-show.c b/notmuch-show.c
index 21792a57..1935c4ab 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -18,11 +18,20 @@
  * Author: Carl Worth <cworth@cworth.org>
  */
 
+#include <string.h>
+#include <stdlib.h>
+
 #include "notmuch-client.h"
 #include "gmime-filter-reply.h"
 #include "sprinter.h"
 #include "zlib-extra.h"
 
+
+/* Extra headers to be output by format_headers_sprinter, if present
+ * in message */
+static const char* extra_headers = NULL;
+
+
 static const char *
 _get_tags_as_string (const void *ctx, notmuch_message_t *message)
 {
@@ -195,6 +204,30 @@ _is_from_line (const char *line)
 	return 0;
 }
 
+/* Output extra headers if specifoed by --extra-headers */
+void
+format_extra_headers_sprinter (sprinter_t *sp, GMimeMessage *message)
+{
+    GMimeHeaderList *header_list;
+    GMimeHeader *header;
+    char *str = strdup(extra_headers);
+    char *tofree = str;
+    char *header_name;
+
+    header_list  = g_mime_object_get_header_list (GMIME_OBJECT(message));
+
+    while ( (header_name = strsep(&str, ",")) != NULL) {
+
+	header = g_mime_header_list_get_header (header_list, header_name);
+	if (header == NULL)
+	    continue;
+
+	sp->map_key (sp, g_mime_header_get_name(header));
+	sp->string (sp, g_mime_header_get_value(header));
+    }
+    free (tofree);
+}
+
 void
 format_headers_sprinter (sprinter_t *sp, GMimeMessage *message,
 			 bool reply, const _notmuch_message_crypto_t *msg_crypto)
@@ -253,6 +286,10 @@ format_headers_sprinter (sprinter_t *sp, GMimeMessage *message,
     } else {
 	sp->map_key (sp, "Date");
 	sp->string (sp, g_mime_message_get_date_string (sp, message));
+
+	/* Output extra headers the user has configured in the database, if any */
+	if (extra_headers != NULL)
+	    format_extra_headers_sprinter (sp, message);
     }
 
     sp->end (sp);
@@ -1193,6 +1230,7 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
 	{ .opt_bool = &params.output_body, .name = "body" },
 	{ .opt_bool = &params.include_html, .name = "include-html" },
 	{ .opt_inherit = notmuch_shared_options },
+	{ .opt_string = &extra_headers, .name = "extra-headers" },
 	{ }
     };
 
-- 
2.21.0 (Apple Git-122)

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH] Display extra headers for emacs-mua - return all headers
  2019-11-22 23:07 Display extra headers for emacs-mua 2 new patches Johan Parin
  2019-11-22 23:07 ` [PATCH] Display extra headers for emacs-mua - cmd line option Johan Parin
@ 2019-11-22 23:07 ` Johan Parin
  1 sibling, 0 replies; 4+ messages in thread
From: Johan Parin @ 2019-11-22 23:07 UTC (permalink / raw)
  To: notmuch; +Cc: Johan Parin

Modify format_headers_sprinter so that it returns all headers in the
sexp, instead of a fixed set of headers.

This is required in order for the elisp variable
`notmuch-message-headers' to work.

See this bug report:

  https://notmuchmail.org/pipermail/notmuch/2017/026069.html
---
 notmuch-show.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/notmuch-show.c b/notmuch-show.c
index 21792a57..6bd1cf73 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -255,6 +255,37 @@ format_headers_sprinter (sprinter_t *sp, GMimeMessage *message,
 	sp->string (sp, g_mime_message_get_date_string (sp, message));
     }
 
+    if (!reply) {
+	GMimeHeaderList *header_list;
+	GMimeHeader *header;
+	int header_count;
+	/* Headers requiring some special treatment in formatting */
+	const char* special_headers[] = {
+	    "Subject", "From", "To", "Cc", "Bcc", "Reply-To", "In-reply-to",
+	    "References", "Date"};
+	bool special;
+
+	header_list  = g_mime_object_get_header_list (GMIME_OBJECT(message));
+	header_count = g_mime_header_list_get_count(header_list);
+
+	for (int i = 0; i < header_count; i++) {
+	    header = g_mime_header_list_get_header_at(header_list, i);
+
+	    special = false;
+	    for (int k = 0; k < (int)ARRAY_SIZE(special_headers); k++)
+		if (!STRNCMP_LITERAL(g_mime_header_get_name(header),
+				     special_headers[k])) {
+		    special = true;
+		    break;
+		}
+	    if (special)
+		continue;
+
+	    sp->map_key (sp, g_mime_header_get_name(header));
+	    sp->string (sp, g_mime_header_get_value(header));
+	}
+    }
+
     sp->end (sp);
     talloc_free (local);
 }
-- 
2.21.0 (Apple Git-122)

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] Display extra headers for emacs-mua - cmd line option
  2019-11-22 23:07 ` [PATCH] Display extra headers for emacs-mua - cmd line option Johan Parin
@ 2019-11-23  9:44   ` Johan Parin
  0 siblings, 0 replies; 4+ messages in thread
From: Johan Parin @ 2019-11-23  9:44 UTC (permalink / raw)
  To: notmuch

[-- Attachment #1: Type: text/plain, Size: 163 bytes --]


The elisp was a little buggy. Here is another version which should
hopefully be 100% working. Also cleaned up and aligned style to the
surrounding code.

/Johan


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Display-extra-headers-for-emacs-mua-cmd-line-option.patch --]
[-- Type: text/x-patch, Size: 8433 bytes --]

From ed26005481d824c0f7b0518a934470e4c4231d0a Mon Sep 17 00:00:00 2001
From: Johan Parin <johan.parin@gmail.com>
Date: Fri, 22 Nov 2019 23:06:14 +0100
Subject: [PATCH] Display extra headers for emacs-mua - cmd line option

Add a new flag --extra-headers to notmuch show, in order to let the
user specify displayed headers using `notmuch-message-headers' in the
emacs mua.

The flag will impact which headers are output in
format_headers_sprinter.

The emacs mua will generate the --extra-headers flag based on
notmuch-message-headers.

See this bug report:

  https://notmuchmail.org/pipermail/notmuch/2017/026069.html
---
 doc/man1/notmuch-show.rst |  7 +++++++
 emacs/notmuch-lib.el      | 26 ++++++++++++++++++++++++++
 emacs/notmuch-query.el    |  5 ++++-
 emacs/notmuch-show.el     | 10 ----------
 emacs/notmuch-tree.el     | 13 ++++++++-----
 notmuch-show.c            | 38 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 83 insertions(+), 16 deletions(-)

diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst
index becd3e79..9f61acce 100644
--- a/doc/man1/notmuch-show.rst
+++ b/doc/man1/notmuch-show.rst
@@ -190,6 +190,13 @@ Supported options for **show** include
     "text/html" parts, no part with content type "text/html" is included
     in the output.
 
+``--extra-headers=header[,header...]``
+    A comma separated list of extra headers that will be output by
+    **notmuch show** with ``--format=sexp``, if present in the
+    message.
+
+    Default: empty list.
+
 A common use of **notmuch show** is to display a single thread of email
 messages. For this, use a search term of "thread:<thread-id>" as can be
 seen in the first column of output from the **notmuch search** command.
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 8acad267..4609a63a 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -148,6 +148,20 @@ For example, if you wanted to remove an \"inbox\" tag and add an
   :group 'notmuch-search
   :group 'notmuch-show)
 
+(defconst notmuch-default-message-headers
+  '("Subject" "To" "Cc" "Date")
+  "Default set of headers to be displayed when showing a message")
+
+(defcustom notmuch-message-headers notmuch-default-message-headers
+  "Headers that should be shown in a message, in this order.
+
+For an open message, all of these headers will be made visible
+according to `notmuch-message-headers-visible' or can be toggled
+with `notmuch-show-toggle-visibility-headers'. For a closed message,
+only the first header in the list will be visible."
+  :type '(repeat string)
+  :group 'notmuch-show)
+
 (defvar notmuch-common-keymap
   (let ((map (make-sparse-keymap)))
     (define-key map "?" 'notmuch-help)
@@ -1017,6 +1031,18 @@ region if the region is active, or both `point' otherwise."
       (list (region-beginning) (region-end))
     (list (point) (point))))
 
+(defun notmuch-show-build-extra-headers-arg ()
+  "Build the --extra-headers arg to notmuch-show
+
+Returns the argument as a string if relevant, otherwise NIL
+"
+  (let ((extra-headers
+	 (cl-set-difference notmuch-message-headers notmuch-default-message-headers
+			    :test #'string=)))
+    (if extra-headers
+	(concat "--extra-headers="
+		(mapconcat #'identity extra-headers ",")))))
+    
 (define-obsolete-function-alias
     'notmuch-search-interactive-region
     'notmuch-interactive-region
diff --git a/emacs/notmuch-query.el b/emacs/notmuch-query.el
index 563e4acf..03ba90ea 100644
--- a/emacs/notmuch-query.el
+++ b/emacs/notmuch-query.el
@@ -30,7 +30,10 @@ A thread is a forest or list of trees. A tree is a two element
 list where the first element is a message, and the second element
 is a possibly empty forest of replies.
 "
-  (let ((args '("show" "--format=sexp" "--format-version=4")))
+  (let ((extra-headers-arg (notmuch-show-build-extra-headers-arg))
+	(args '("show" "--format=sexp" "--format-version=4")))
+    (if extra-headers-arg
+	(setq args (append args (list extra-headers-arg))))
     (if notmuch-show-process-crypto
 	(setq args (append args '("--decrypt=true"))))
     (setq args (append args search-terms))
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index e13ca3d7..069f0184 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -53,16 +53,6 @@
 (declare-function notmuch-read-query "notmuch" (prompt))
 (declare-function notmuch-draft-resume "notmuch-draft" (id))
 
-(defcustom notmuch-message-headers '("Subject" "To" "Cc" "Date")
-  "Headers that should be shown in a message, in this order.
-
-For an open message, all of these headers will be made visible
-according to `notmuch-message-headers-visible' or can be toggled
-with `notmuch-show-toggle-visibility-headers'. For a closed message,
-only the first header in the list will be visible."
-  :type '(repeat string)
-  :group 'notmuch-show)
-
 (defcustom notmuch-message-headers-visible t
   "Should the headers be visible by default?
 
diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index c00315e8..939c77a9 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -915,14 +915,17 @@ the same as for the function notmuch-tree."
   (let* ((search-args (concat basic-query
 		       (if query-context (concat " and (" query-context ")"))
 		       ))
-	 (message-arg "--entire-thread"))
+	 (message-arg "--entire-thread")
+	 (extra-headers-arg (notmuch-show-build-extra-headers-arg))
+	 (args `("notmuch-tree" ,(current-buffer) ,#'notmuch-tree-process-sentinel
+		  "show" "--body=false" "--format=sexp" "--format-version=4")))
+    (if extra-headers-arg
+	(setq args (append args (list extra-headers-arg))))
+    (setq args (append args (list search-args)))
     (if (equal (car (process-lines notmuch-command "count" search-args)) "0")
 	(setq search-args basic-query))
     (notmuch-tag-clear-cache)
-    (let ((proc (notmuch-start-notmuch
-		 "notmuch-tree" (current-buffer) #'notmuch-tree-process-sentinel
-		 "show" "--body=false" "--format=sexp" "--format-version=4"
-		 message-arg search-args))
+    (let ((proc (apply #'notmuch-start-notmuch args))
 	  ;; Use a scratch buffer to accumulate partial output.
 	  ;; This buffer will be killed by the sentinel, which
 	  ;; should be called no matter how the process dies.
diff --git a/notmuch-show.c b/notmuch-show.c
index 21792a57..1935c4ab 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -18,11 +18,20 @@
  * Author: Carl Worth <cworth@cworth.org>
  */
 
+#include <string.h>
+#include <stdlib.h>
+
 #include "notmuch-client.h"
 #include "gmime-filter-reply.h"
 #include "sprinter.h"
 #include "zlib-extra.h"
 
+
+/* Extra headers to be output by format_headers_sprinter, if present
+ * in message */
+static const char* extra_headers = NULL;
+
+
 static const char *
 _get_tags_as_string (const void *ctx, notmuch_message_t *message)
 {
@@ -195,6 +204,30 @@ _is_from_line (const char *line)
 	return 0;
 }
 
+/* Output extra headers if specifoed by --extra-headers */
+void
+format_extra_headers_sprinter (sprinter_t *sp, GMimeMessage *message)
+{
+    GMimeHeaderList *header_list;
+    GMimeHeader *header;
+    char *str = strdup(extra_headers);
+    char *tofree = str;
+    char *header_name;
+
+    header_list  = g_mime_object_get_header_list (GMIME_OBJECT(message));
+
+    while ( (header_name = strsep(&str, ",")) != NULL) {
+
+	header = g_mime_header_list_get_header (header_list, header_name);
+	if (header == NULL)
+	    continue;
+
+	sp->map_key (sp, g_mime_header_get_name(header));
+	sp->string (sp, g_mime_header_get_value(header));
+    }
+    free (tofree);
+}
+
 void
 format_headers_sprinter (sprinter_t *sp, GMimeMessage *message,
 			 bool reply, const _notmuch_message_crypto_t *msg_crypto)
@@ -253,6 +286,10 @@ format_headers_sprinter (sprinter_t *sp, GMimeMessage *message,
     } else {
 	sp->map_key (sp, "Date");
 	sp->string (sp, g_mime_message_get_date_string (sp, message));
+
+	/* Output extra headers the user has configured in the database, if any */
+	if (extra_headers != NULL)
+	    format_extra_headers_sprinter (sp, message);
     }
 
     sp->end (sp);
@@ -1193,6 +1230,7 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
 	{ .opt_bool = &params.output_body, .name = "body" },
 	{ .opt_bool = &params.include_html, .name = "include-html" },
 	{ .opt_inherit = notmuch_shared_options },
+	{ .opt_string = &extra_headers, .name = "extra-headers" },
 	{ }
     };
 
-- 
2.21.0 (Apple Git-122)


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-11-23  9:44 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-22 23:07 Display extra headers for emacs-mua 2 new patches Johan Parin
2019-11-22 23:07 ` [PATCH] Display extra headers for emacs-mua - cmd line option Johan Parin
2019-11-23  9:44   ` Johan Parin
2019-11-22 23:07 ` [PATCH] Display extra headers for emacs-mua - return all headers Johan Parin

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).