Re: [PATCH] Display extra headers for emacs-mua - cmd line option

2019-11-23 Thread Johan Parin

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

>From ed26005481d824c0f7b0518a934470e4c4231d0a Mon Sep 17 00:00:00 2001
From: Johan Parin 
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:" 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 sh

[PATCH] Display extra headers for emacs-mua - cmd line option

2019-11-22 Thread 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:" 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=se

[PATCH] Display extra headers for emacs-mua - return all headers

2019-11-22 Thread 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)

___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Display extra headers for emacs-mua 2 new patches

2019-11-22 Thread Johan Parin
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


___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] Display extra headers for emacs-mua - db config option

2019-11-21 Thread Johan Parin

Johan Parin  writes:

> Daniel Kahn Gillmor  writes:
>>
>> Is it that much worse to pass around the notmuch_database_t *?
>>
>
> It has a lot of code impact, it really propagates to a lot of
> places. For instance it also impacts the json and text api, because
> those need to have the same signatures as the json api. Also the
> database needs to be opened in places where it's currently not opened,
> such as in notmuch_search_command().
>

Here is a taste (not fully tested, but seems to work).

/Johan

>From 706a0f784a101b05ac82a462ff6c19c0cef550af Mon Sep 17 00:00:00 2001
From: Johan Parin 
Date: Sun, 17 Nov 2019 13:15:39 +0100
Subject: [PATCH] Display extra headers for emacs-mua - db config option

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

The extra header list is configured by the database config option
`show.extra_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

This version avoids the file global notmuch database variable in
notmuch-show.c by passing around the database pointer in a lot of
function calls.
---
 doc/man1/notmuch-config.rst |   6 ++
 notmuch-client.h|  12 ++--
 notmuch-config.c|   7 ++-
 notmuch-reply.c |  13 ++--
 notmuch-search.c|  29 ++---
 notmuch-show.c  | 114 
 sprinter-json.c |   3 +-
 sprinter-sexp.c |   3 +-
 sprinter-text.c |  10 +++-
 sprinter.h  |  12 ++--
 10 files changed, 155 insertions(+), 54 deletions(-)

diff --git a/doc/man1/notmuch-config.rst b/doc/man1/notmuch-config.rst
index 28487079..0eb59883 100644
--- a/doc/man1/notmuch-config.rst
+++ b/doc/man1/notmuch-config.rst
@@ -204,6 +204,12 @@ The available configuration items are described below.
 supported. See **notmuch-search-terms(7)** for a list of existing
 prefixes, and an explanation of probabilistic prefixes.
 
+**show.extra_headers**
+A list of extra headers that will be output by **notmuch show**
+with ``--format=sexp``, if present in the message.
+
+Default: empty list.
+
 **built_with.**
 Compile time feature . Current possibilities include
 "compact" (see **notmuch-compact(1)**) and "field_processor" (see
diff --git a/notmuch-client.h b/notmuch-client.h
index 74690054..d4402231 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -64,8 +64,10 @@ struct sprinter;
 struct notmuch_show_params;
 
 typedef struct notmuch_show_format {
-struct sprinter *(*new_sprinter)(const void *ctx, FILE *stream);
-notmuch_status_t (*part)(const void *ctx, struct sprinter *sprinter,
+struct sprinter *(*new_sprinter)(notmuch_database_t *notmuch,
+ const void *ctx, FILE *stream);
+notmuch_status_t (*part)(notmuch_database_t *notmuch,
+			 const void *ctx, struct sprinter *sprinter,
 			 struct mime_node *node, int indent,
 			 const struct notmuch_show_params *params);
 } notmuch_show_format_t;
@@ -227,12 +229,14 @@ notmuch_status_t
 show_one_part (const char *filename, int part);
 
 void
-format_part_sprinter (const void *ctx, struct sprinter *sp, mime_node_t *node,
+format_part_sprinter (notmuch_database_t *notmuch,
+		  const void *ctx, struct sprinter *sp, mime_node_t *node,
 		  bool output_body,
 		  bool include_html);
 
 void
-format_headers_sprinter (struct sprinter *sp, GMimeMessage *message,
+format_headers_sprinter (notmuch_database_t *notmuch,
+			 struct sprinter *sp, GMimeMessage *message,
 			 bool reply, const _notmuch_message_crypto_t *msg_crypto);
 
 typedef enum {
diff --git a/notmuch-config.c b/notmuch-config.c
index 1b079e85..6554ad9b 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -841,9 +841,10 @@ typedef struct config_key {
 
 static struct config_key
 config_key_table[] = {
-{ "index.decrypt",   true,   false,  NULL },
-{ "index.header.",   true,   true,   validate_field_name },
-{ "query.",  true,   true,   NULL },
+{ "index.decrypt",  true,   false,  NULL },
+{ "index.header.",  true,   true,   validate_field_name },
+{ "query.", true,   true,   NULL },
+{ "show.extra_headers", true,   false,  NULL }
 };
 
 static config_key_info_t *
diff --git a/notmuch-reply.c b/notmuch-reply.c
index 2c30f6f9..5d468c88 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -614,7 +614,8 @@ enum {
 };
 
 static int
-do_reply (notmuch_config_t *config,
+do_reply (notmuch_database_t *notmuch,
+	  notmuch_config_t *config,
 	  notmuch_query_t *query,
 	  notmuch_show_params_t *params,
 	  int format,
@@ -640,9 +641,9 @@ do_reply (notmuch_config_t *config,
 	}
 
 	i

Re: [PATCH] Display extra headers for emacs-mua - db config option

2019-11-21 Thread Johan Parin


Daniel Kahn Gillmor  writes:

>
> I'm a little weirded out by the move to a static notmuch_database_t
> *notmuch object.  Are we doing this because we don't want to pass
> around the database to internal functions?

Yes

> I know that the scope of nomtuch-show.c is basically "global scope",
> but i worry that it makes the code more difficult to read and
> maintain.
>

I agree it's not so nice with globals in general.

>
> Is it that much worse to pass around the notmuch_database_t *?
>

It has a lot of code impact, it really propagates to a lot of
places. For instance it also impacts the json and text api, because
those need to have the same signatures as the json api. Also the
database needs to be opened in places where it's currently not opened,
such as in notmuch_search_command().

I have started on such a patch and can certainly complete that if this
is the direction we want to move. I can warn you that there is a lot of
code changes (although they are cosmetic).


/Johan
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: Tests failing on master

2019-11-17 Thread Johan Parin


Johan Parin  writes:

> In order to be able to run some tests and since OS X Mojave only has
> bash 3.2, I installed a Kali vm, downloaded a fresh notmuch repo,
> installed the dependencies and did make test. Result:
>
> 1123/1128 tests passed.
> 3 broken tests failed as expected.
> 2 tests failed.
>

I tried on another machine running Ubuntu Server 18.04.3, and there all
1128 tests minus the broken ones passed.

Could the failures on Kali be related to me running as root?


/Johan
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Tests failing on master

2019-11-17 Thread Johan Parin


In order to be able to run some tests and since OS X Mojave only has
bash 3.2, I installed a Kali vm, downloaded a fresh notmuch repo,
installed the dependencies and did make test. Result:

1123/1128 tests passed.
3 broken tests failed as expected.
2 tests failed.

More details:

T050-new: Testing "notmuch new" in several variations
 FAIL   Xapian exception: read only files
--- T050-new.35.expected2019-11-17 10:05:48.060026443 +
+++ T050-new.35.output  2019-11-17 10:05:48.060026443 +
@@ -1 +1,17 @@
-A Xapian exception occurred opening database

T150-tagging: Testing "notmuch tag"
 FAIL   Xapian exception: read only files
--- T150-tagging.25.expected2019-11-17 10:05:57.536026481 +
+++ T150-tagging.25.output  2019-11-17 10:05:57.536026481 +
@@ -1 +1 @@
-A Xapian exception occurred opening database
+

Can anyone confirm / deny that this should occur on master?

I looked at the tests/README and installed the prerequisite packages,
and also downloaded the test databases.


/Johan
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] Display extra headers for emacs-mua - db config option

2019-11-16 Thread Johan Parin


This is another version of my attempt to get configurability on extra
headers to be displayed in the emacs MUA. It is a modification of a
previous patch where the extra headers returned by notmuch-show were
hard coded. In this version, the extra headers is configured by a
database config option `show.extra_headers'. As I see it the advantage
with this approach is:

- It gives full flexibility to choose any extra header to be
  displayed. The required steps are two (1) configure
  `show.extra_headers' in the db and (2) set `notmuch-message-headers'
  as desired.
- There is absolutely no performance concern.

The change is also very simple, low impact.

There is no API change (if that is considered a maintenance cost).

If a decision would later be taken to have format_headers_sprinter
return all headers, then users having adopted the configuration option
would still have the same functionality, albeit with an unused db config
entry.

I think this patch is complete, I also added an update to the config man
page. I guess this patch does not require updating the schemata (?)


/Johan
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] Display extra headers for emacs-mua - db config option

2019-11-16 Thread Johan Parin
Modify format_headers_sprinter so that it returns some additional headers in the
sexp, instead of a small fixed set of headers.

The extra header list is configured by the database config option
`show.extra_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
---
 doc/man1/notmuch-config.rst |  6 ++
 notmuch-config.c|  7 ---
 notmuch-show.c  | 41 -
 3 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/doc/man1/notmuch-config.rst b/doc/man1/notmuch-config.rst
index 28487079..0eb59883 100644
--- a/doc/man1/notmuch-config.rst
+++ b/doc/man1/notmuch-config.rst
@@ -204,6 +204,12 @@ The available configuration items are described below.
 supported. See **notmuch-search-terms(7)** for a list of existing
 prefixes, and an explanation of probabilistic prefixes.
 
+**show.extra_headers**
+A list of extra headers that will be output by **notmuch show**
+with ``--format=sexp``, if present in the message.
+
+Default: empty list.
+
 **built_with.**
 Compile time feature . Current possibilities include
 "compact" (see **notmuch-compact(1)**) and "field_processor" (see
diff --git a/notmuch-config.c b/notmuch-config.c
index 1b079e85..6554ad9b 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -841,9 +841,10 @@ typedef struct config_key {
 
 static struct config_key
 config_key_table[] = {
-{ "index.decrypt",   true,   false,  NULL },
-{ "index.header.",   true,   true,   validate_field_name },
-{ "query.",  true,   true,   NULL },
+{ "index.decrypt",  true,   false,  NULL },
+{ "index.header.",  true,   true,   validate_field_name },
+{ "query.", true,   true,   NULL },
+{ "show.extra_headers", true,   false,  NULL }
 };
 
 static config_key_info_t *
diff --git a/notmuch-show.c b/notmuch-show.c
index 21792a57..4c77468f 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -18,11 +18,16 @@
  * Author: Carl Worth 
  */
 
+#include 
+
 #include "notmuch-client.h"
 #include "gmime-filter-reply.h"
 #include "sprinter.h"
 #include "zlib-extra.h"
 
+static notmuch_database_t *notmuch = NULL;
+
+
 static const char *
 _get_tags_as_string (const void *ctx, notmuch_message_t *message)
 {
@@ -195,6 +200,38 @@ _is_from_line (const char *line)
return 0;
 }
 
+/* Output extra headers if configured with the `show.extra_headers'
+ * database configuration option
+ */
+void
+format_extra_headers_sprinter (sprinter_t *sp, GMimeMessage *message)
+{
+GMimeHeaderList *header_list;
+GMimeHeader *header;
+char *extra_headers, *tofree, *header_name;
+
+if (notmuch == NULL)
+   return;
+
+if (notmuch_database_get_config (notmuch, "show.extra_headers",
+&extra_headers) != NOTMUCH_STATUS_SUCCESS)
+   return;
+
+header_list  = g_mime_object_get_header_list (GMIME_OBJECT(message));
+
+tofree = extra_headers;
+while ( (header_name = strsep(&extra_headers, ";")) != 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 +290,9 @@ 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 
*/
+   format_extra_headers_sprinter (sp, message);
 }
 
 sp->end (sp);
@@ -1152,7 +1192,6 @@ static const notmuch_show_format_t *formatters[] = {
 int
 notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
 {
-notmuch_database_t *notmuch;
 notmuch_query_t *query;
 char *query_string;
 int opt_index, ret;
-- 
2.21.0 (Apple Git-122)

___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] Add --message-headers flag to notmuch-show

2019-11-12 Thread Johan Parin


Daniel Kahn Gillmor  writes:

> On Mon 2019-11-11 10:26:18 -0500, Daniel Kahn Gillmor wrote:
>>  - What is the specific use case for this? For example, can you identify
>>situations where different headers need to be emitted by different
>>users?  Even one motivating example would help others on this list
>>understand why they might want to care :)
>
> ah, sorry, i've just read
> id:20191109221358.4349-1-johan.pa...@gmail.com and its associated
> messages, so i can see that some of the questions i'm asking are
> already under discussion.
>
> I see that you just want user-agent and x-mailer for your own
> purposes.
>

Well that is just my current minimum requirements. I'm a mail nerd and I
always want to see what mua people are using, if present. And no, it is
not OK to have to hit 'V' and see all headers. There are way too many
garbage headers. You want to have the headers you are interested in to
be displayed automatically for every message in a nice readable fashion.

Someone else in this thread wanted Arhive-At; the bug reporter wanted
X-Github-Sender. Now that I think about it I definitely want
X-Face. Maybe List-Id. etc. It's really hard to predict what people
think is interesting, which is why configurability is needed.

I think this is quite basic functionality. All "nerdy" muas have it ;)
Gnus has it, mu4e has it etc. mutt seems to have some reasonable default
of at least displaying User-Agent. I think Thunderbird has it too. etc

> Maybe it would be worthwhile to propose that narrow, limited change as
> a simple patch, without configurability and see what it looks like?  I
> would personally be more likely to advocate for merging a patch that
> meets the specific needs of a notmuch user, and increase the
> configurability surface of notmuch.
>

I really don't think the configurability is expensive. The elisp code
base is already prepared for it with the notmuch-message-headers
variable. It's just that it's not working because notmuch-show.c only
exports a fixed set of headers. So it's a bug fix, really.

> If processing a couple of extra headers on a long thread is too
> expensive for some consumer, i'd suggest that is an optimization for
> the consumer to tackle.

I have implemented three variants:

a) notmuch-show.c exports all headers
b) notmuch-show.c exports a limited set of "interesting" headers. This
   patch should be modified to set the headers in the config file. I
   think this is a really good solution if you are concerned with
   performance in a)
c) notmuch-show.c exports headers specified with a command line arg,
   which is passed from the elisp based on `notmuch-message-headers'.

In all cases the actual headers displayed in the emacs mua is controlled
by `notmuch-message-headers'.

Personally I don't think there is any discernible performance impact
with any of these, and that any performance impact is dwarfed by the
GMime message parsing code and elisp display code. But if there is
concern with a, then b) and c) can be chosen which should have basically
zero performance impact.

I also don't think there is maintenance cost with any of these once it
is implemented so I don't see why we should not have configurability.

All of the patches need some polishing (and I noticed a functional issue
with "c). But if we can get consensus on an approach that is OK, then I
would be happy to continue perfecting it.

/Johan
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: Unread handling

2019-11-12 Thread Johan Parin


Teemu Likonen  writes:
>
> It seems to me that using search term tag:unread will help you. Try this
> in the *hello* buffer:
>
> z tag:unread
>
> You'll go directly to tree view and unread messages will show with
> normal colours and read messages with grey colour. Commands "n" and
> "p" will skip over read messages ("N" and "P" won't). You can
> configure saved searches to start with tree view.

Yes this is very good. Actually what I do now is

s tag:unread date:-2d..

which gives me almost what I want. Only downside is, completely unread
threads don't show up in the search view. Sometimes I want to go back
and read a read thread. But this can be solved by using flagged (or some
other tag). So now I have:

s ((tag:unread date:-2d..) or tag:flagged)

which works pretty well.

Thanks!

/Johan
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Unread handling

2019-11-10 Thread Johan Parin


I'm probably doing something wrong but I find myself frustrated with the
handling of unread in the emacs-mua.

In notmuch-search I found the default bold face for unread of
notmuch-search-unread-face not enough to make them stand out so I tried
something like

  (setq notmuch-search-line-faces
  '(("unread" . '(:foreground "SkyeBlue"))

which ought to work according to the doc, but did not work. Fortunately
however it works to define a new face with defface and use that.

  (setq notmuch-search-line-faces
'(("unread" . my/notmuch-unread-face)))

So that problem solved.

My real frustration lies in the thread view. Typically threads will be
partially read and I want to read only unread messages.

I find the show view confusing because I don't clearly see the message
boundaries. Also I always need to start with C-u M-RET to get an
overview of the thread. In this view the unread stand out a bit due to
the colorization of the unread tag, which is typically visible. I still
would like to be able to colorize the entire line or the author here,
for unread. Is it possible?

I'm trying instead to use the tree view, this seems to me the more
natural way to view threads. So I immediately do `Z' whenever I enter a
thread. I would like to have the option to enter tree view automatically
for a thread from the search buffer. Is it possible?

In tree view however, again I would like to colorize the unread
messages. Haven't found a way to do this and reading notmuch-tree.el it
seems it's not possible. Is there a way? Since I like to keep my window
to 80 chars the tag display is outside the visible area and I find
myself doing C-e to find the unread tags. This is very inconvenient.

Also I would like to navigate to the next unread message, and would
prefer the `n' binding to do that instead of go to next message. Haven't
found a binding for that.

Finally when entering the tree view I would like the first unread
message to automatically be shown.

I guess the above can be summarized as, I would like to have the option
to have a gnus-ish way of viewing threads.

Again, I'm probably doing something wrong and / or am missing some
possibilities here, it would be very interesting to hear others work
flow for thread reading.


/Johan
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] Fix format_headers_sprinter to return all headers (v2)

2019-11-10 Thread Johan Parin
David Edmondson  writes:

> On Saturday, 2019-11-09 at 23:13:58 +01, Johan Parin wrote: 
>
>> +const char* interesting_headers[] = { + "Maildir",
>> "Mailing-list", "Tags", "Attachments", "Signature", + "Decryption",
>> "User-agent", "X-Mailer"}; 
>
> It would be convenient to specify these in ~/.notmuch-config rather
> than hard-coding them (or specifying them as command line arguments).
>

I agree that is a better solution, maybe even better than using command
line args.

I can look into this as well. Will not have much time the next few days
though. 

/Johan
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] Add --message-headers flag to notmuch-show

2019-11-10 Thread Johan Parin


According to the proposal of Jani and Tomi I have made a new patch
version which adds a flag --message-headers to notmuch show. This is a
preliminary commit just to get general comments.

No doc updates here. Also there are probably a few style issues. And I
guess I should use talloc instead of malloc.

/Johan
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] Add --message-headers flag to notmuch-show

2019-11-10 Thread Johan Parin
Add a new flag --message-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.

By default only the following headers are output by notmuch show with
--format=sexp :

- From
- To
- Subject
- Cc
- Bcc
- Reply-To
- In-reply-to
- References
- Date

`From' is always output regardless of what is specified in
--message-headers.

See this bug report:

  https://notmuchmail.org/pipermail/notmuch/2017/026069.html

This commit does not include documentation updates.
---
 emacs/notmuch-query.el |   4 +-
 emacs/notmuch-tree.el  |   2 +
 notmuch-show.c | 138 +
 3 files changed, 104 insertions(+), 40 deletions(-)

diff --git a/emacs/notmuch-query.el b/emacs/notmuch-query.el
index 563e4acf..61c921a4 100644
--- a/emacs/notmuch-query.el
+++ b/emacs/notmuch-query.el
@@ -30,7 +30,9 @@ 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"
+   ,(concat "--message-headers="
+ (mapconcat #'identity notmuch-message-headers ",")
 (if notmuch-show-process-crypto
(setq args (append args '("--decrypt=true"
 (setq args (append args search-terms))
diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index c00315e8..1d793ec3 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -922,6 +922,8 @@ the same as for the function notmuch-tree."
 (let ((proc (notmuch-start-notmuch
 "notmuch-tree" (current-buffer) #'notmuch-tree-process-sentinel
 "show" "--body=false" "--format=sexp" "--format-version=4"
+ (concat "--message-headers="
+ (mapconcat #'identity notmuch-message-headers ","))
 message-arg search-args))
  ;; Use a scratch buffer to accumulate partial output.
  ;; This buffer will be killed by the sentinel, which
diff --git a/notmuch-show.c b/notmuch-show.c
index 21792a57..1658b66e 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -18,11 +18,31 @@
  * Author: Carl Worth 
  */
 
+#include 
+#include 
+
 #include "notmuch-client.h"
 #include "gmime-filter-reply.h"
 #include "sprinter.h"
 #include "zlib-extra.h"
 
+/* Max number of headers that can be output from
+ * format_headers_sprinter */
+#define MAX_PRINTABLE_MESSAGE_HEADERS 25
+
+/* Default list of header names to be printed by
+ * format_headers_sprinter */
+static const char *default_message_header_list[] = {
+"To", "Subject", "Cc", "Bcc", "Reply-To", "In-reply-to",
+"References", "Date"};
+
+/* List of header names to be printed by format_headers_sprinter */
+static char **message_header_list_p = (char **) default_message_header_list;
+
+static int message_header_list_len =
+sizeof(default_message_header_list) / sizeof(char *);
+
+
 static const char *
 _get_tags_as_string (const void *ctx, notmuch_message_t *message)
 {
@@ -48,6 +68,26 @@ _get_tags_as_string (const void *ctx, notmuch_message_t 
*message)
 return result;
 }
 
+/* Extract requested header names from the message-headers command
+ * line argument.
+ */
+static void
+extract_requested_headers (const char *opt_str)
+{
+int count = 0;
+char *tofree = strdup (opt_str);
+char *string = tofree;
+char *header_name;
+
+message_header_list_p = malloc(MAX_PRINTABLE_MESSAGE_HEADERS * sizeof(char 
*));
+while ((header_name = strsep(&string, ",")) != NULL &&
+  count < MAX_PRINTABLE_MESSAGE_HEADERS)
+   message_header_list_p[count++] = strdup(header_name);
+
+message_header_list_len = count;
+free(tofree);
+}
+
 /* Get a nice, single-line summary of message. */
 static const char *
 _get_one_line_summary (const void *ctx, notmuch_message_t *message)
@@ -202,57 +242,72 @@ format_headers_sprinter (sprinter_t *sp, GMimeMessage 
*message,
 /* Any changes to the JSON or S-Expression format should be
  * reflected in the file devel/schemata. */
 
-char *recipients_string;
-const char *reply_to_string;
 void *local = talloc_new (sp);
+GMimeHeaderList *header_list;
 
-sp->begin_map (sp);
+/* Not currently used */
+(void) reply;
 
-sp->map_key (sp, "Subject");
-if (msg_crypto && msg_crypto->payload_subject) {
-   sp->string (sp, msg_crypto->payload_subject);
-} else
-   sp->string (sp, g_mime_message_get_subject (message));
+sp->begin_map (sp);
 
 sp->map_key (sp, "From");
 sp->string (sp, g_mime_message_get_from_string (message));
 
-recipients_string = g_mime_message_get_address_string (message, 
GMIME_ADDRESS_TYPE_TO);
-if (recipients_string) {
-   sp->map_key (sp, "To");
-   

Re: [PATCH] Fix format_headers_sprinter to return all headers (v2)

2019-11-09 Thread Johan Parin


So this version only returns a fixed limited set of extra
headers. Hopefully this eliminates any concern for a performance
penalty. Of course it limits the usefulness of the
notmuch-message-headers variable.

/Johan
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] Fix format_headers_sprinter to return all headers (v2)

2019-11-09 Thread Johan Parin
Modify format_headers_sprinter so that it returns some additional headers in the
sexp, instead of a small fixed set of headers.

This version includes the following headers:

- Maildir
- Mailing-list
- Tags
- Attachments
- Signature
- Decryption
- User-agent
- X-Mailer

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

See this bug report:

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

diff --git a/notmuch-show.c b/notmuch-show.c
index 21792a57..86ddb491 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -205,6 +205,12 @@ format_headers_sprinter (sprinter_t *sp, GMimeMessage 
*message,
 char *recipients_string;
 const char *reply_to_string;
 void *local = talloc_new (sp);
+GMimeHeaderList *header_list;
+GMimeHeader *header;
+const char* interesting_headers[] = {
+   "Maildir", "Mailing-list", "Tags", "Attachments", "Signature",
+   "Decryption", "User-agent", "X-Mailer"};
+const int interesting_header_count = sizeof(interesting_headers) / 
sizeof(char *);
 
 sp->begin_map (sp);
 
@@ -255,6 +261,19 @@ format_headers_sprinter (sprinter_t *sp, GMimeMessage 
*message,
sp->string (sp, g_mime_message_get_date_string (sp, message));
 }
 
+header_list  = g_mime_object_get_header_list (GMIME_OBJECT(message));
+
+for (int i = 0; i < interesting_header_count; i++) {
+
+   header = g_mime_header_list_get_header(
+   header_list, interesting_headers[i]);
+   if (header == NULL)
+   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)

___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] Fix format_headers_sprinter to return all headers

2019-11-09 Thread Johan Parin


Jani Nikula  writes:

> On Sat, 09 Nov 2019, Johan Parin  wrote:
>> Modify format_headers_sprinter so that it returns all headers in the
>> sexp, instead of a fixed set of headers.
>
> I have to deal with plenty of long threads that already take a very
> long time to open in notmuch-emacs. How's this going to impact the
> emacs interface performance? For example the patch mail I'm replying
> to has more header content than body content. There are tons of
> headers that I can't imagine being useful to anyone.
>

How long are these threads may I ask? Would it be possible for you to
apply the patch and see if you see a noticable difference?

I have a hard time seeing that the C code would cause any noticable
performance impact, but perhaps the elisp. But my general understanding
of the code base is low, so I may be wrong.

I guess it's in the following type of code the performance concern lies?

(mapc (lambda (header)
(let* ((header-symbol (intern (concat ":" header)))
   (header-value (plist-get headers header-symbol)))
  (if (and header-value
   (not (string-equal "" header-value)))
  (notmuch-show-insert-header header header-value
  notmuch-message-headers)

Don't know how efficient plists are in general.

> I'm wondering if the right thing to do would be to make it possible to
> specify which additional headers to include in notmuch-show
> output. This would be based on notmuch-message-headers. We already
> have options to include/exclude body content and html parts for much
> the same reasons. (Though the command-line arguments for those are
> incoherent at best.)
>

This would be possible of course.

Another option I guess is to hard code some extra "interesting"
headers. But what is interesting is subjective and it is very nice to
have the flexibility to control this is in elisp.

mu4e has the customization variable `mu4e-view-fields', but it can only
take on values from a restricted list, namely:

:from :to :cc :subject :flags :date :maildir :mailing-list :tags
:attachments :signature :decryption :user-agent

So a compromise would be to restrict the returned headers to a list like
this. This of course is if we think the potential performance issue is
in the elisp.

Personally I would be content for the moment to be able to see
user-agent and x-mailer. But that's just me.

/Johan
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] Fix format_headers_sprinter to return all headers

2019-11-09 Thread 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 | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/notmuch-show.c b/notmuch-show.c
index 21792a57..9652ed09 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -205,6 +205,15 @@ format_headers_sprinter (sprinter_t *sp, GMimeMessage 
*message,
 char *recipients_string;
 const char *reply_to_string;
 void *local = talloc_new (sp);
+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"};
+const int special_header_count = sizeof(special_headers) / sizeof(char *);
+bool special;
 
 sp->begin_map (sp);
 
@@ -255,6 +264,24 @@ format_headers_sprinter (sprinter_t *sp, GMimeMessage 
*message,
sp->string (sp, g_mime_message_get_date_string (sp, message));
 }
 
+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 < special_header_count; 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)

___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch