Re: [PATCH] doc: tweak hook configuration documentation.

2021-07-30 Thread Hannu Hartikainen
LGTM, but because there is an empty line after `**database.hook_dir**`
that section has different indentation than others in the generated
manpage. Might as well fix that too. See snippet below, from a rendered
manpage on my machine.

Hannu

---
   database.backup_dir
  Directory to store tag dumps when upgrading database.

  History: this configuration value was  introduced  in
  notmuch 0.32.

  Default:  A  sibling directory of the Xapian database
  called backups.

   database.hook_dir
  Directory containing hooks run by notmuch  commands.  See
  notmuch-hooks(5).

  History:  this configuration value was introduced in not???
  much 0.32.

  Default: See HOOKS, below.___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


Re: Early preview of s-expression based query parser

2021-07-29 Thread Hannu Hartikainen
On Tue, 13 Jul 2021 21:02:28 -0300, David Bremner  wrote:
> Feedback of any kind is welcome, but particularly on UI / UX
> issues. You can get a pretty good idea of the supported syntax by
> looking at the tests.

I read through the commits and it looks good to me implementation-wise.

I'm probably not the most experienced lisper around so take my ideas
with a grain of salt. I did work professionally on a Clojure codebase
for a couple of years and I've written a bunch of small programs in
Racket but that's pretty much it.

But looking at the sexp parser and the implementation of logical
connectors I can't help but think that isn't this patchset implementing
a tiny subset of a lisp? And wouldn't a full embedded lisp be much, much
more powerful?

I'd at least consider embedding something like s7 [0] or Janet [1],
writing bindings for enough Xapian functionality, and then writing the
rest in the lisp itself. That way you'd get a more powerful and
extensible sexp implementation, and you'd implement most of it in a much
more ergonomic language.

Of course I don't really know Xapian and I'm not sure of the design
goals of this sexp parser, but my experience with HoneySQL [2] tells me
that building queries with a lisp from lisp data structures can be
unbelievably powerful.

Hannu

[0]: https://ccrma.stanford.edu/software/snd/snd/s7.html
[1]: https://janet-lang.org/
[2]: https://github.com/seancorfield/honeysql
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


Re: Yet another revision of --format=pretty

2021-07-13 Thread Hannu Hartikainen
On Mon, 12 Jul 2021 20:19:37 -0300, David Bremner  wrote:
> The main thing I was worried about was the vim interface and Felipe
> confirmed that it does not use text format at all. There are no doubt
> user scripts out there that will have to be adjusted, so it would have
> to be a long-ish deprecation, but we've done that before.

Cool!

> I guess the question for you is if the format will still be useful for
> you if we need to include _some_ metadata in order to replace use cases
> for text format? I'm thinking of potentially a couple of X-Notmuch-*
> headers. But that in itself is another design discussion.

I'm fine with that. There also *could* be a way to configure which
headers are displayed; Tomi suggested that the colors should be
configurable, and I think configuring pairs of header+color would be one
option of implementing that. But I need to dogfood some more before I
can confidently say what I like best.

> I think having some quick mail pager for search results makes sense. I'm
> not sure how far in the direction of MH we should go, but we can look at
> each potential change as it arrives.

I'd never heard of MH before. I'll need to try it out :) (For those not
familiar, it can be found at https://www.nongnu.org/nmh/ .) It sounds
philosophically like what I want from a CLI mail client. But then again
I really don't need much. I'm writing this message with this shell
function (and Neovim) and I think it's good enough. :)

nr() {
draft=$(mktemp $HOME/draft-)
$notmuch reply $1 > "$draft" || return
nvim -c 'set filetype=mail' "$draft" || return
cat "$draft"
echo
echo "Press ENTER to send (Ctrl-C to cancel)"
read || return
cat "$draft" | msmtp -t || return
rm "$draft"
}

Hannu
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


Re: [PATCH v3 1/2] cli/show: add --format=pretty

2021-07-13 Thread Hannu Hartikainen
Thanks for reviewing the patch!

On Tue, 13 Jul 2021 07:24:43 -0300, David Bremner  wrote:
> David Bremner  writes:
> > I don't know what g_mime_message_get_message_id will return if there is
> > no message-id, but that case can and does arise. 

It returns null and the printing function prints out `(null)` IIRC so
it's not a crash (I checked that), but good point nonetheless.

> I expect that would require somehow making the notmuch_database_t object
> available inside the sprinter. We want this for at least one other
> feature request (configurable headers in json / sexpr output), so it's
> not as much of a "waste" of effort as it might seem at first.

That's good to know. I was afraid of making big changes for no reason. I
think I had a version that added a function parameter but thought it's
too ugly and complicated to submit.

> The options are adding extra arguments to functions and stashing a
> copy of the pointer in some struct (perhaps the sprinter struct).

I'll see if I find a good way to do the latter when I have time. Thanks
for the pointers!

Hannu
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 2/2] cli/show: add color for --format=pretty

2021-07-12 Thread Hannu Hartikainen
The arguments `--color` and `--no-color` allow setting color explicitly
on or off when using `--format=pretty`. The default is to use color iff
stdout is a TTY.
---
 NEWS  |  4 +++-
 doc/man1/notmuch-show.rst |  9 -
 notmuch-client.h  |  1 +
 notmuch-show.c| 15 +++
 4 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index 57826734..ac6f 100644
--- a/NEWS
+++ b/NEWS
@@ -6,7 +6,9 @@ CLI
 
 `notmuch show` now has `--format=pretty`, optimized for reading plain
 text emails on the command line. It only shows the most important
-headers and plain text parts.
+headers and plain text parts. The output is colored if the output is a
+TTY or.  Alternatively, `--color` and `--no-color` can be used to set
+color explicitly on or off.
 
 Emacs
 -
diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst
index c68f0b2b..d1faf8fe 100644
--- a/doc/man1/notmuch-show.rst
+++ b/doc/man1/notmuch-show.rst
@@ -49,7 +49,8 @@ Supported options for **show** include
**pretty**
  The plain-text parts of all matching messages are printed in a
  format optimized for readability. Only the most important
- headers are displayed.
+ headers are displayed. Color is used if the output is to a TTY
+ unless ``--color`` or ``--no-color`` is used explicitly.
 
**json**
  The output is formatted with Javascript Object Notation
@@ -221,6 +222,12 @@ Supported options for **show** include
"text/html" parts, no part with content type "text/html" is included
in the output.
 
+.. option:: --color
+
+   Use colored output for formats that support that (currently only
+   ``--format=pretty``). By default, color is used if the output
+   goes to a TTY. To disable color, use ``--no-color``.
+
 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
diff --git a/notmuch-client.h b/notmuch-client.h
index 8227fea4..c4f7cfd6 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -78,6 +78,7 @@ typedef struct notmuch_show_params {
 int part;
 _notmuch_crypto_t crypto;
 bool include_html;
+bool color;
 GMimeStream *out_stream;
 } notmuch_show_params_t;
 
diff --git a/notmuch-show.c b/notmuch-show.c
index 69b1e697..a67bd698 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -617,14 +617,21 @@ format_part_pretty (const void *ctx, sprinter_t *sp, 
mime_node_t *node,
 GMimeContentType *content_type = g_mime_object_get_content_type (meta);
 GMimeStream *stream = params->out_stream;
 int i;
+bool color = params->color;
 
 if (GMIME_IS_MESSAGE (node->part)) {
GMimeMessage *message = GMIME_MESSAGE (node->part);
char *recipients_string;
char *date_string;
 
+   if (color)
+   g_mime_stream_printf (stream, "\e[36m");
g_mime_stream_printf (stream, "Subject: %s\n", 
g_mime_message_get_subject (message));
+   if (color)
+   g_mime_stream_printf (stream, "\e[33m");
g_mime_stream_printf (stream, "From: %s\n", 
g_mime_message_get_from_string (message));
+   if (color)
+   g_mime_stream_printf (stream, "\e[31m");
recipients_string = g_mime_message_get_address_string (message, 
GMIME_ADDRESS_TYPE_TO);
if (recipients_string)
g_mime_stream_printf (stream, "To: %s\n", recipients_string);
@@ -634,9 +641,15 @@ format_part_pretty (const void *ctx, sprinter_t *sp, 
mime_node_t *node,
g_mime_stream_printf (stream, "Cc: %s\n", recipients_string);
g_free (recipients_string);
date_string = g_mime_message_get_date_string (node, message);
+   if (color)
+   g_mime_stream_printf (stream, "\e[35m");
g_mime_stream_printf (stream, "Date: %s\n", date_string);
+   if (color)
+   g_mime_stream_printf (stream, "\e[32m");
g_mime_stream_printf (stream, "Message-ID: <%s>\n\n", 
g_mime_message_get_message_id (
  message));
+   if (color)
+   g_mime_stream_printf (stream, "\e[0m");
 }
 
 if (GMIME_IS_PART (node->part) &&
@@ -1294,6 +1307,7 @@ notmuch_show_command (notmuch_database_t *notmuch, int 
argc, char *argv[])
.part = -1,
.omit_excluded = true,
.output_body = true,
+   .color = isatty (fileno (stdout)),
.crypto = { .decrypt = NOTMUCH_DECRYPT_AUTO },
 };
 int format = NOTMUCH_FORMAT_NOT_SPECIFIED;
@@ -1333,6 +1347,7 @@ notmuch_show_command (notmuch_database_t *notmuch, int 
argc, char *argv[])
{ .opt_bool = , .name = "verify" },
{ .opt_bool = _body, .name = "body" },
{ .opt_bool = _html, .name = "include-html" },
+   { .opt_bool = , .name = "color" },
{ .opt_inherit = notmuch_shared_options },
{ }
 };
-- 
2.32.0
___
notmuch mailing list -- 

[PATCH v3 1/2] cli/show: add --format=pretty

2021-07-12 Thread Hannu Hartikainen
This commit adds the display format `pretty`. It only shows the most
important headers, similarly to `--format=text`, and only displays
plaintext parts (ie. text/* but not text/html). However, compared to
`--format=text` the output is kept as close to raw as possible.

The rationale for this feature is twofold:

1. It is useful to be able to view messages in as human-friendly format
   as possible.
2. The same format should still be machine-readable, too.

The email format is mostly human-readable as is. The things difficult
for a human eye are the huge amount of headers that are common these
days and telling different messages apart when there are many.

While human readability is the main goal, another design goal was that
piping the output to `git am` works, at least for individual messages
sent with `git send-email`. This way the format is suitable to be used
as the default, both for reading and piping output to other commands.
---
 NEWS   |  7 
 completion/notmuch-completion.bash |  2 +-
 completion/zsh/_notmuch|  2 +-
 doc/man1/notmuch-show.rst  |  7 +++-
 notmuch-show.c | 54 ++
 test/T520-show.sh  | 32 ++
 6 files changed, 101 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 3e776009..57826734 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,13 @@
 Notmuch 0.33 (UNRELEASED)
 =
 
+CLI
+---
+
+`notmuch show` now has `--format=pretty`, optimized for reading plain
+text emails on the command line. It only shows the most important
+headers and plain text parts.
+
 Emacs
 -
 
diff --git a/completion/notmuch-completion.bash 
b/completion/notmuch-completion.bash
index 15425697..86cbbcdc 100644
--- a/completion/notmuch-completion.bash
+++ b/completion/notmuch-completion.bash
@@ -514,7 +514,7 @@ _notmuch_show()
return
;;
--format)
-   COMPREPLY=( $( compgen -W "text json sexp mbox raw" -- "${cur}" ) )
+   COMPREPLY=( $( compgen -W "text pretty json sexp mbox raw" -- 
"${cur}" ) )
return
;;
--exclude|--body)
diff --git a/completion/zsh/_notmuch b/completion/zsh/_notmuch
index e920f10b..5cc386e2 100644
--- a/completion/zsh/_notmuch
+++ b/completion/zsh/_notmuch
@@ -237,7 +237,7 @@ _notmuch_search() {
 _notmuch_show() {
   _arguments -S \
 '--entire-thread=[output entire threads]:show thread:(true false)' \
-'--format=[set output format]:output format:(text json sexp mbox raw)' \
+'--format=[set output format]:output format:(text pretty json sexp mbox 
raw)' \
 '--format-version=[set output format version]:format version: ' \
 '--part=[output a single decoded mime part]:part number: ' \
 '--verify[verify signed MIME parts]' \
diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst
index 64639174..c68f0b2b 100644
--- a/doc/man1/notmuch-show.rst
+++ b/doc/man1/notmuch-show.rst
@@ -34,7 +34,7 @@ Supported options for **show** include
the matching messages. For ``--format=json`` and ``--format=sexp``
this defaults to true. For other formats, this defaults to false.
 
-.. option:: --format=(text|json|sexp|mbox|raw)
+.. option:: --format=(text|pretty|json|sexp|mbox|raw)
 
**text** (default for messages)
  The default plain-text format has all text-content MIME parts
@@ -46,6 +46,11 @@ Supported options for **show** include
  '}'), to either open or close the component. For a multipart
  MIME message, these parts will be nested.
 
+   **pretty**
+ The plain-text parts of all matching messages are printed in a
+ format optimized for readability. Only the most important
+ headers are displayed.
+
**json**
  The output is formatted with Javascript Object Notation
  (JSON). This format is more robust than the text format for
diff --git a/notmuch-show.c b/notmuch-show.c
index c8f1a40f..69b1e697 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -606,6 +606,52 @@ format_part_text (const void *ctx, sprinter_t *sp, 
mime_node_t *node,
 return NOTMUCH_STATUS_SUCCESS;
 }
 
+static notmuch_status_t
+format_part_pretty (const void *ctx, sprinter_t *sp, mime_node_t *node,
+   int indent, const notmuch_show_params_t *params)
+{
+/* The disposition and content-type metadata are associated with
+ * the envelope for message parts */
+GMimeObject *meta = node->envelope_part ? (
+   GMIME_OBJECT (node->envelope_part) ) : node->part;
+GMimeContentType *content_type = g_mime_object_get_content_type (meta);
+GMimeStream *stream = params->out_stream;
+int i;
+
+if (GMIME_IS_MESSAGE (node->part)) {
+   GMimeMessage *message = GMIME_MESSAGE (node->part);
+   char *recipients_string;
+   char *date_string;
+
+   g_mime_stream_printf (stream, "Subject: %s\n", 
g_mime_message_get_subject (message));
+   g_mime_stream_printf (stream, "From: %s\n", 

Yet another revision of --format=pretty

2021-07-12 Thread Hannu Hartikainen
I was hoping for more discussion about the supported formats. Alas,
there has been none. I'm still posting another revision addressing the
review comment that the color implementation should be in its own
commit.

In my personal opinion this output format is better than `--format=text`
both for humans and machines. I might consider deprecating `text` now,
making `pretty` the default later, and then much later removing `text`
altogether. But I don't know the users and if there would be politics
involved in such a change.

As I said before, if this is a non-goal for notmuch, I can understand
this change being unwanted. Still, I'd like some discussion on the
matter. But maybe most readers of this list don't care either way?

Hannu

PS. I was smarter this time and didn't make this patch a reply to the
earlier ones. Hopefully I got the References: header right.

___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


Re: [PATCH] replace references to freenode with references to libera

2021-07-07 Thread Hannu Hartikainen
LGTM.

Hannu
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


Re: [PATCH] cli/show: add --format=pretty

2021-07-05 Thread Hannu Hartikainen
Hi!

Thanks for starting discussion on the matter. Do feel free to tell me if
I have the completely wrong idea about project goals.

On Sun, 04 Jul 2021 11:38:45 -0300, David Bremner  wrote:
> This is not really directed at Hannu, but at the notmuch community. As
> you can imagine I'm not super enthusiastic an every growing number of
> output formats to maintain.

I can appreciate that. I've maintained open source software before and I
know people come up with the weirdest feature requests that simply don't
fit the scenario I'm building the software for. If this text format that
I personally like to use isn't good for the project, it definitely
should not be merged.

What do you see as the mission statement for notmuch-cli? I'd like to
make it ergonomic enough to be usable without a MUA, and it's really
close already. But if notmuch-cli is meant to be something completely
different I might just have my own set of patches or consider starting
my own project.

> One thing the old format did not do, but a generically useful on the
> command-line format probably should is deal with signature verification
> and decryption. There is obviously potential for visual spoofing, but
> maybe color can help.

I'm pretty sure you can embed ANSI escapes in email and
they'll be displayed by `notmuch show` as color in a typical terminal.
Not sure if anyone should be worried about attacks specifically against
notmuch users, though.

> In my experience, notmuch show --format=raw works pretty well
> for this. There was an issue with encoded line endings but that is fixed
> in git 2.32. What advantage does this new format bring for patches?

--format=pretty is not any better than --format=raw for use with git-am
but the point is that it's as good. I have the shell alias ns="notmuch
show --format=pretty" and I can use something like `ns tag:unread` for
reading and `ns id:some-id | git am` for applying patches. I personally
really, really like simple things that work for multiple purposes.

For human consumption the pretty format is nicer than the raw format,
and it also supports showing multiple messages.

Hannu
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


Re: [PATCH v2] cli/show: add --format=pretty

2021-07-04 Thread Hannu Hartikainen
Thanks for the review!

On Sun, 04 Jul 2021 12:40:59 +0300, Tomi Ollila  wrote:
> The code looks good to me, just that these "hardcoded" color values gives
> me a bit of suspicion...

That's true and I do think the colors could eventually be configurable,
but right now I don't know how the configuration should work. Should it
be a palette, should each header have a configurable color (and should
the displayed headers be configurable too) etc. It's easy to make this
hugely bloated so I'll avoid going there until I have a clear idea of a
good, minimal approach.

> the colors look OK when background is dark (black). on light background
> (white) color 33 (yellow), color 36 (cyan) and color 32 (green) are
> somewhat hard to read (in decreasing hardness)...

Most terminals have user-configurable colors so I don't think this is a
showstopper. But as I said, yes, it would be best to make the colors
configurable.

> I did not try to apply this and see how those looks like when displaying
> real emails (no setup on this machine for now...)

Here's a screenshot: https://i.imgur.com/7dlP7lt.png

I'm happy to receive any suggestions but I think it's best to stay with
the original 3-bit spec (SGR codes 30-37, or in practice 31-36: red,
green, yellow, blue, magenta, cyan) if the values are hardcoded. Those
are most widely supported.

> One option would be to first send this without color support and then
> add *configurable* color support -- I don't know which way is better
> but as a rewiever that would be easier to accept...

That's an excellent idea! I'll post PATCH v3 later. I don't really want
to try real feature detection because some terminals have weird corner
cases with their ANSI sequence support. `isatty` is what other CLI tools
tend to use as default AFAIK.

Hannu
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v2] cli/show: add --format=pretty

2021-07-02 Thread Hannu Hartikainen
The rationale for this feature is twofold:

1. It is useful to be able to view messages in as human-friendly format
   as possible.
2. The same format should still be machine-readable, too.

The email format is mostly human-readable as is. The things difficult
for a human eye are the huge amount of headers that are common these
days and telling different messages apart when there are many.

This commit adds the display format `pretty`. It recognizes if the
output is a TTY and if so, applies coloring to headers. This turns out
to be a good visual message separator. Additionally it only shows the
most important headers, similarly to `--format=text`, and only displays
plaintext parts (ie. text/* but not text/html).

While human readability is the main goal, another design goal was that
piping the output to `git am` works, at least for individual messages
sent with `git send-email`.
---

I wrote a v2 of this patch. I've been dogfooding for a while now and
wanted a couple of enhancements, and also had learned about the notmuch
test harness. The differences to the first version are:

- add a unit test
- show Message-ID, making replying etc. much easier
- print a newline after each part, which helps a lot with messages that
  do not end in a newline

I'm using this as a daily driver and am happy with it.

 NEWS   |  7 
 completion/notmuch-completion.bash |  2 +-
 completion/zsh/_notmuch|  2 +-
 doc/man1/notmuch-show.rst  |  8 +++-
 notmuch-show.c | 67 ++
 test/T520-show.sh  | 32 ++
 6 files changed, 115 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 3e776009..f5142ff1 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,13 @@
 Notmuch 0.33 (UNRELEASED)
 =
 
+CLI
+---
+
+`notmuch show` now has `--format=pretty`, optimized for reading plain
+text emails on the command line. It only shows the most important
+headers and plain text parts and uses colors for headers.
+
 Emacs
 -
 
diff --git a/completion/notmuch-completion.bash 
b/completion/notmuch-completion.bash
index 15425697..86cbbcdc 100644
--- a/completion/notmuch-completion.bash
+++ b/completion/notmuch-completion.bash
@@ -514,7 +514,7 @@ _notmuch_show()
return
;;
--format)
-   COMPREPLY=( $( compgen -W "text json sexp mbox raw" -- "${cur}" ) )
+   COMPREPLY=( $( compgen -W "text pretty json sexp mbox raw" -- 
"${cur}" ) )
return
;;
--exclude|--body)
diff --git a/completion/zsh/_notmuch b/completion/zsh/_notmuch
index e920f10b..5cc386e2 100644
--- a/completion/zsh/_notmuch
+++ b/completion/zsh/_notmuch
@@ -237,7 +237,7 @@ _notmuch_search() {
 _notmuch_show() {
   _arguments -S \
 '--entire-thread=[output entire threads]:show thread:(true false)' \
-'--format=[set output format]:output format:(text json sexp mbox raw)' \
+'--format=[set output format]:output format:(text pretty json sexp mbox 
raw)' \
 '--format-version=[set output format version]:format version: ' \
 '--part=[output a single decoded mime part]:part number: ' \
 '--verify[verify signed MIME parts]' \
diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst
index fc6bec62..1fe4dcc7 100644
--- a/doc/man1/notmuch-show.rst
+++ b/doc/man1/notmuch-show.rst
@@ -34,7 +34,7 @@ Supported options for **show** include
the matching messages. For ``--format=json`` and ``--format=sexp``
this defaults to true. For other formats, this defaults to false.
 
-.. option:: --format=(text|json|sexp|mbox|raw)
+.. option:: --format=(text|pretty|json|sexp|mbox|raw)
 
**text** (default for messages)
  The default plain-text format has all text-content MIME parts
@@ -46,6 +46,12 @@ Supported options for **show** include
  '}'), to either open or close the component. For a multipart
  MIME message, these parts will be nested.
 
+   **pretty**
+ The plain-text parts of all matching messages are printed in a
+ format optimized for readability. Only the most important
+ headers are displayed. If the output is to a TTY, the headers
+ are colored.
+
**json**
  The output is formatted with Javascript Object Notation
  (JSON). This format is more robust than the text format for
diff --git a/notmuch-show.c b/notmuch-show.c
index 232557d5..c417ec00 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -606,6 +606,65 @@ format_part_text (const void *ctx, sprinter_t *sp, 
mime_node_t *node,
 return NOTMUCH_STATUS_SUCCESS;
 }
 
+static notmuch_status_t
+format_part_pretty (const void *ctx, sprinter_t *sp, mime_node_t *node,
+   int indent, const notmuch_show_params_t *params)
+{
+/* The disposition and content-type metadata are associated with
+ * the envelope for message parts */
+GMimeObject *meta = node->envelope_part ? (
+   GMIME_OBJECT (node->envelope_part) ) : node->part;
+   

[PATCH v2 2/2] lib: consider all instances of Delivered-To header

2021-07-02 Thread Hannu Hartikainen
When using notmuch-reply and guessing the From: address from
Delivered-To headers, I had the wrong address chosen today. This was
because the messages from the notmuch list contain these headers in this
order:

Delivered-To: hannu.hartikai...@gmail.com
...
Delivered-To: ha...@hrtk.in

In my .notmuch-config I have the following configuration:

primary_email=ha...@hrtk.in
other_email=hannu.hartikai...@gmail.com;...

Before this change, notmuch-reply would guess From: @gmail.com because
that is the first Delivered-To header present. After the change, the
primary address is chosen as I would expect.
---
 lib/message-file.c | 13 +
 notmuch-reply.c|  7 +--
 test/T220-reply.sh |  1 -
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/lib/message-file.c b/lib/message-file.c
index 647ccf3a..68f646a4 100644
--- a/lib/message-file.c
+++ b/lib/message-file.c
@@ -291,11 +291,16 @@ _notmuch_message_file_get_header (notmuch_message_file_t 
*message,
 if (value)
return value;
 
-if (strcasecmp (header, "received") == 0) {
+if (strcasecmp (header, "received") == 0 ||
+   strcasecmp (header, "delivered-to") == 0) {
/*
-* The Received: header is special. We concatenate all
-* instances of the header as we use this when analyzing the
-* path the mail has taken from sender to recipient.
+* The Received: header is special. We concatenate all instances of the
+* header as we use this when analyzing the path the mail has taken
+* from sender to recipient.
+*
+* Similarly, multiple instances of Delivered-To may be present. We
+* concatenate them so the one with highest priority may be picked (eg.
+* primary_email before other_email).
 */
decoded = _notmuch_message_file_get_combined_header (message, header);
 } else {
diff --git a/notmuch-reply.c b/notmuch-reply.c
index 08140799..ebb621e0 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -464,8 +464,8 @@ guess_from_in_received_by (notmuch_database_t *notmuch, 
const char *received)
  * (last Received: header added) and try to extract from them
  * indications to which email address this message was delivered.
  *
- * The Received: header is special in our get_header function and is
- * always concatenated.
+ * The Received: header is among special ones in our get_header function
+ * and is always concatenated.
  *
  * Return the address that was found, if any, and NULL otherwise.
  */
@@ -499,6 +499,9 @@ guess_from_in_received_headers (notmuch_message_t *message)
  * headers: Envelope-To, X-Original-To, and Delivered-To (searched in
  * that order).
  *
+ * The Delivered-To: header is among special ones in our get_header
+ * function and is always concatenated.
+ *
  * Return the address that was found, if any, and NULL otherwise.
  */
 static const char *
diff --git a/test/T220-reply.sh b/test/T220-reply.sh
index 9f711a04..2db36fef 100755
--- a/test/T220-reply.sh
+++ b/test/T220-reply.sh
@@ -246,7 +246,6 @@ On Tue, 05 Jan 2010 15:43:56 -, Sender 
 wrote:
 OK"
 
 test_begin_subtest "From guessing: multiple Delivered-To"
-test_subtest_known_broken
 add_message '[from]="Sender "' \
'[to]="Recipient "' \
'[subject]="From guessing"' \
-- 
2.32.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v2 1/2] reply: add test for multiple Delivered-To headers

2021-07-02 Thread Hannu Hartikainen
Add a known broken subtest for guessing From: correctly when there are
multiple Delivered-To: headers. The address configured as primary_email
should get picked.
---
 test/T220-reply.sh | 23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/test/T220-reply.sh b/test/T220-reply.sh
index b6d8f42a..9f711a04 100755
--- a/test/T220-reply.sh
+++ b/test/T220-reply.sh
@@ -245,6 +245,27 @@ On Tue, 05 Jan 2010 15:43:56 -, Sender 
 wrote:
 > From guessing
 OK"
 
+test_begin_subtest "From guessing: multiple Delivered-To"
+test_subtest_known_broken
+add_message '[from]="Sender "' \
+   '[to]="Recipient "' \
+   '[subject]="From guessing"' \
+   '[date]="Tue, 05 Jan 2010 15:43:56 -"' \
+   '[body]="From guessing"' \
+   '[header]="Delivered-To: test_suite_ot...@notmuchmail.org
+Delivered-To: test_su...@notmuchmail.org"'
+
+output=$(notmuch reply id:${gen_msg_id} 2>&1 && echo OK)
+test_expect_equal "$output" "From: Notmuch Test Suite 

+Subject: Re: From guessing
+To: Sender , Recipient 
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -, Sender  wrote:
+> From guessing
+OK"
+
 test_begin_subtest "Reply with RFC 2047-encoded headers"
 add_message '[subject]="=?iso-8859-1?q?=e0=df=e7?="' \
'[from]="=?utf-8?q?=e2=98=83?= "' \
@@ -281,7 +302,7 @@ test_expect_equal_json "$output" '
 "crypto": {},
 "date_relative": "2010-01-05",
 "excluded": false,
-"filename": ["'${MAIL_DIR}'/msg-014"],
+"filename": ["'${MAIL_DIR}'/msg-015"],
 "headers": {
 "Date": "Tue, 05 Jan 2010 15:43:56 +",
 "From": "\u2603 ",
-- 
2.32.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


Re: [PATCH] lib: consider all instances of Delivered-To header

2021-06-28 Thread Hannu Hartikainen
Thanks for the review! Please consider the patch obsolete, I'll submit a
v2 later with the comments addressed.

On Sat, 26 Jun 2021 14:36:23 -0300, David Bremner  wrote:
> Hannu Hartikainen  writes:
> > +* Similarly, multiple instances of Delivered-To may be present. We
> > +* concatenate them so the one with highest priority may be picked.
> >  */
> 
> Highest priority seems a bit vague here. Do you mean most recent?

I mean that the address configured as `primary_email` is chosen over
those configured as `other_email` if both are present. Basically, let
`user_address_in_string` in notmuch-reply.c do its thing. AFAICT the
addresses in `other_email` are checked in sequence so the first matching
one is chosen, ie. they also have a priority. Not sure if that is
intended and documented or if it could change later, so I didn't want to
go into specifics in the comment.

> The idiomatic (for notmuch) thing to do for a bug fix is first to add a
> test with "test_subtest_known_broken", then to remove that line in the
> commit you fix the bug.

So it's best to have a commit with only the (broken) test first as
opposed to adding the fix and the test in the same commit? Ok, I'll do
that.

Hannu
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


Re: [PATCH] lib: consider all instances of Delivered-To header

2021-06-23 Thread Hannu Hartikainen
On Wed, 23 Jun 2021 12:58:33 +0200, Michael J Gruber  wrote:
> Is an address from a received header (still) preferred over one from a
> delivered-to, or does the order of headers in the mail envelope play a
> role?

In my understanding the From: address is looked up in the following
steps (each step may have their own internal priorizing logic):

1. To, Cc, Bcc, Reply-To, From
2. Envelope-To
3. X-Original-To
4. Delivered-To
5. Received (for)
6. Received (by)
7. configured primary address

Obviously the patch doesn't touch this logic; it only affects the
handling of multiple Delivered-To headers.

Hannu
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH] lib: consider all instances of Delivered-To header

2021-06-23 Thread Hannu Hartikainen
When using notmuch-reply and guessing the From: address from
Delivered-To headers, I had the wrong address chosen today. This was
because the messages from the notmuch list contain these headers in this
order:

Delivered-To: hannu.hartikai...@gmail.com
...
Delivered-To: ha...@hrtk.in

In my .notmuch-config I have the following configuration:

primary_email=ha...@hrtk.in
other_email=hannu.hartikai...@gmail.com;...

Before this change, notmuch-reply would guess From: @gmail.com because
that is the first Delivered-To header present. After the change, the
primary address is chosen as I would expect.
---
 lib/message-file.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/lib/message-file.c b/lib/message-file.c
index 647ccf3a..7e8ea09c 100644
--- a/lib/message-file.c
+++ b/lib/message-file.c
@@ -291,11 +291,15 @@ _notmuch_message_file_get_header (notmuch_message_file_t 
*message,
 if (value)
return value;
 
-if (strcasecmp (header, "received") == 0) {
+if (strcasecmp (header, "received") == 0 ||
+strcasecmp (header, "delivered-to") == 0) {
/*
-* The Received: header is special. We concatenate all
-* instances of the header as we use this when analyzing the
-* path the mail has taken from sender to recipient.
+* The Received: header is special. We concatenate all instances of the
+* header as we use this when analyzing the path the mail has taken
+* from sender to recipient.
+*
+* Similarly, multiple instances of Delivered-To may be present. We
+* concatenate them so the one with highest priority may be picked.
 */
decoded = _notmuch_message_file_get_combined_header (message, header);
 } else {
-- 
2.32.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH] cli/show: add --color/--no-color

2021-06-22 Thread Hannu Hartikainen
These arguments allow setting color explicitly on or off when using
`--format=pretty`. The default is still to use color iff stdout is a
TTY.
---

I got a reply off-list to my previous patch (cli/show: add
--format=pretty) about explicitly enabling color (for use with $PAGER).
It's quite a minor addition so I just implemented it. IMHO this warrants
its own commit; it's a separate feature from --format=pretty. But I'm ok
with squashing these together if that's considered better.

Of course, with an explicit --color command-line argument in one command
for one purpose, one could reasonably ask if other commands should
support colored output as well. What do you all think?

 doc/man1/notmuch-show.rst | 6 ++
 notmuch-client.h  | 1 +
 notmuch-show.c| 4 +++-
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst
index 1fe4dcc7..e61000a6 100644
--- a/doc/man1/notmuch-show.rst
+++ b/doc/man1/notmuch-show.rst
@@ -209,6 +209,12 @@ Supported options for **show** include
"text/html" parts, no part with content type "text/html" is included
in the output.
 
+.. option:: --color
+
+   Use colored output for formats that support that (currently only
+   ``--format=pretty``). By default, color is used if the output
+   goes to a TTY. To disable color, use ``--no-color``.
+
 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
diff --git a/notmuch-client.h b/notmuch-client.h
index 8227fea4..c4f7cfd6 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -78,6 +78,7 @@ typedef struct notmuch_show_params {
 int part;
 _notmuch_crypto_t crypto;
 bool include_html;
+bool color;
 GMimeStream *out_stream;
 } notmuch_show_params_t;
 
diff --git a/notmuch-show.c b/notmuch-show.c
index fe3b753e..6274a99a 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -612,7 +612,7 @@ format_part_pretty (const void *ctx, sprinter_t *sp, 
mime_node_t *node,
 GMimeContentType *content_type = g_mime_object_get_content_type (meta);
 GMimeStream *stream = params->out_stream;
 int i;
-bool color = isatty (fileno (stdout));
+bool color = params->color;
 
 if (GMIME_IS_MESSAGE (node->part)) {
GMimeMessage *message = GMIME_MESSAGE (node->part);
@@ -1300,6 +1300,7 @@ notmuch_show_command (notmuch_database_t *notmuch, int 
argc, char *argv[])
.part = -1,
.omit_excluded = true,
.output_body = true,
+   .color = isatty (fileno (stdout)),
.crypto = { .decrypt = NOTMUCH_DECRYPT_AUTO },
 };
 int format = NOTMUCH_FORMAT_NOT_SPECIFIED;
@@ -1334,6 +1335,7 @@ notmuch_show_command (notmuch_database_t *notmuch, int 
argc, char *argv[])
{ .opt_bool = , .name = "verify" },
{ .opt_bool = _body, .name = "body" },
{ .opt_bool = _html, .name = "include-html" },
+   { .opt_bool = , .name = "color" },
{ .opt_inherit = notmuch_shared_options },
{ }
 };
-- 
2.32.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH] cli/show: add --format=pretty

2021-06-19 Thread Hannu Hartikainen
The rationale for this feature is twofold:

1. It is useful to be able to view messages in as human-friendly format
   as possible.
2. The same format should still be machine-readable, too.

The email format is mostly human-readable as is. The things difficult
for a human eye are the huge amount of headers that are common these
days and telling different messages apart when there are many.

This commit adds the display format `pretty`. It recognizes if the
output is a TTY and if so, applies coloring to headers. This turns out
to be a good visual message separator. Additionally it only shows the
most important headers, similarly to `--format=text`, and only displays
plaintext parts (ie. text/* but not text/html).

While human readability is the main goal, another design goal was that
piping the output to `git am` works, at least for individual messages
sent with `git send-email`.
---

I'm a new Notmuch user and have been trying out different MUAs. And
reading email directly with Notmuch feels easier to me than adding to my
cognitive load with something like Mutt. At least when I want to read
something specific that Notmuch queries are well suited for.

This is my first (but possibly not last) patch aimed at enhancing the
usability of the Notmuch CLI. Any and all feedback is welcome!

 NEWS   |  7 
 completion/notmuch-completion.bash |  2 +-
 completion/zsh/_notmuch|  2 +-
 doc/man1/notmuch-show.rst  |  8 +++-
 notmuch-show.c | 65 ++
 5 files changed, 81 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 538ec168..d099bd69 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,13 @@
 Notmuch 0.33 (UNRELEASED)
 =
 
+CLI
+---
+
+`notmuch show` now has `--format=pretty`, optimized for reading plain
+text emails on the command line. It only shows the most important
+headers and plain text parts and uses colors for headers.
+
 Emacs
 -
 
diff --git a/completion/notmuch-completion.bash 
b/completion/notmuch-completion.bash
index 15425697..86cbbcdc 100644
--- a/completion/notmuch-completion.bash
+++ b/completion/notmuch-completion.bash
@@ -514,7 +514,7 @@ _notmuch_show()
return
;;
--format)
-   COMPREPLY=( $( compgen -W "text json sexp mbox raw" -- "${cur}" ) )
+   COMPREPLY=( $( compgen -W "text pretty json sexp mbox raw" -- 
"${cur}" ) )
return
;;
--exclude|--body)
diff --git a/completion/zsh/_notmuch b/completion/zsh/_notmuch
index e920f10b..5cc386e2 100644
--- a/completion/zsh/_notmuch
+++ b/completion/zsh/_notmuch
@@ -237,7 +237,7 @@ _notmuch_search() {
 _notmuch_show() {
   _arguments -S \
 '--entire-thread=[output entire threads]:show thread:(true false)' \
-'--format=[set output format]:output format:(text json sexp mbox raw)' \
+'--format=[set output format]:output format:(text pretty json sexp mbox 
raw)' \
 '--format-version=[set output format version]:format version: ' \
 '--part=[output a single decoded mime part]:part number: ' \
 '--verify[verify signed MIME parts]' \
diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst
index fc6bec62..1fe4dcc7 100644
--- a/doc/man1/notmuch-show.rst
+++ b/doc/man1/notmuch-show.rst
@@ -34,7 +34,7 @@ Supported options for **show** include
the matching messages. For ``--format=json`` and ``--format=sexp``
this defaults to true. For other formats, this defaults to false.
 
-.. option:: --format=(text|json|sexp|mbox|raw)
+.. option:: --format=(text|pretty|json|sexp|mbox|raw)
 
**text** (default for messages)
  The default plain-text format has all text-content MIME parts
@@ -46,6 +46,12 @@ Supported options for **show** include
  '}'), to either open or close the component. For a multipart
  MIME message, these parts will be nested.
 
+   **pretty**
+ The plain-text parts of all matching messages are printed in a
+ format optimized for readability. Only the most important
+ headers are displayed. If the output is to a TTY, the headers
+ are colored.
+
**json**
  The output is formatted with Javascript Object Notation
  (JSON). This format is more robust than the text format for
diff --git a/notmuch-show.c b/notmuch-show.c
index bdb87321..fe3b753e 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -601,6 +601,63 @@ format_part_text (const void *ctx, sprinter_t *sp, 
mime_node_t *node,
 return NOTMUCH_STATUS_SUCCESS;
 }
 
+static notmuch_status_t
+format_part_pretty (const void *ctx, sprinter_t *sp, mime_node_t *node,
+   int indent, const notmuch_show_params_t *params)
+{
+/* The disposition and content-type metadata are associated with
+ * the envelope for message parts */
+GMimeObject *meta = node->envelope_part ? (
+   GMIME_OBJECT (node->envelope_part) ) : node->part;
+GMimeContentType *content_type =