* [PATCH 1/3] cli: add support for parsing multiple keyword arguments
@ 2014-09-06 12:53 Jani Nikula
2014-09-06 12:53 ` [PATCH 2/3] cli: add --output=address-{from, to, all} to notmuch search Jani Nikula
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Jani Nikula @ 2014-09-06 12:53 UTC (permalink / raw)
To: notmuch
This allows having multiple --foo=bar --foo=baz options on the command
line, with the corresponding values OR'd together.
---
command-line-arguments.c | 6 +++++-
command-line-arguments.h | 1 +
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/command-line-arguments.c b/command-line-arguments.c
index 844d6c3d18bf..c6f7269603cb 100644
--- a/command-line-arguments.c
+++ b/command-line-arguments.c
@@ -23,7 +23,10 @@ _process_keyword_arg (const notmuch_opt_desc_t *arg_desc, char next, const char
while (keywords->name) {
if (strcmp (arg_str, keywords->name) == 0) {
if (arg_desc->output_var) {
- *((int *)arg_desc->output_var) = keywords->value;
+ if (arg_desc->opt_type == NOTMUCH_OPT_KEYWORD_FLAGS)
+ *((int *)arg_desc->output_var) |= keywords->value;
+ else
+ *((int *)arg_desc->output_var) = keywords->value;
}
return TRUE;
}
@@ -152,6 +155,7 @@ parse_option (const char *arg,
switch (try->opt_type) {
case NOTMUCH_OPT_KEYWORD:
+ case NOTMUCH_OPT_KEYWORD_FLAGS:
return _process_keyword_arg (try, next, value);
case NOTMUCH_OPT_BOOLEAN:
return _process_boolean_arg (try, next, value);
diff --git a/command-line-arguments.h b/command-line-arguments.h
index de1734ad2fdb..085a4923b5fa 100644
--- a/command-line-arguments.h
+++ b/command-line-arguments.h
@@ -8,6 +8,7 @@ enum notmuch_opt_type {
NOTMUCH_OPT_BOOLEAN, /* --verbose */
NOTMUCH_OPT_INT, /* --frob=8 */
NOTMUCH_OPT_KEYWORD, /* --format=raw|json|text */
+ NOTMUCH_OPT_KEYWORD_FLAGS, /* the above with values OR'd together */
NOTMUCH_OPT_STRING, /* --file=/tmp/gnarf.txt */
NOTMUCH_OPT_POSITION /* notmuch dump pos_arg */
};
--
2.1.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/3] cli: add --output=address-{from, to, all} to notmuch search
2014-09-06 12:53 [PATCH 1/3] cli: add support for parsing multiple keyword arguments Jani Nikula
@ 2014-09-06 12:53 ` Jani Nikula
2014-09-06 13:35 ` Mark Walters
2014-09-06 12:53 ` [PATCH 3/3] cli: deduplicate addresses for --output=address-* Jani Nikula
2014-09-19 19:27 ` [PATCH 1/3] cli: add support for parsing multiple keyword arguments David Bremner
2 siblings, 1 reply; 10+ messages in thread
From: Jani Nikula @ 2014-09-06 12:53 UTC (permalink / raw)
To: notmuch
address-from prints reply-to or from, address-to prints to, cc, and
bcc, and address-all prints all of them.
---
notmuch-search.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 104 insertions(+), 9 deletions(-)
diff --git a/notmuch-search.c b/notmuch-search.c
index bc9be4593ecc..c84ecc31262c 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -23,11 +23,14 @@
#include "string-util.h"
typedef enum {
- OUTPUT_SUMMARY,
- OUTPUT_THREADS,
- OUTPUT_MESSAGES,
- OUTPUT_FILES,
- OUTPUT_TAGS
+ OUTPUT_SUMMARY = 1 << 0,
+ OUTPUT_THREADS = 1 << 1,
+ OUTPUT_MESSAGES = 1 << 2,
+ OUTPUT_FILES = 1 << 3,
+ OUTPUT_TAGS = 1 << 4,
+ OUTPUT_ADDRESS_FROM = 1 << 5,
+ OUTPUT_ADDRESS_TO = 1 << 6,
+ OUTPUT_ADDRESS_ALL = OUTPUT_ADDRESS_FROM | OUTPUT_ADDRESS_TO,
} output_t;
/* Return two stable query strings that identify exactly the matched
@@ -214,6 +217,66 @@ do_search_threads (sprinter_t *format,
return 0;
}
+static void
+print_address_list (sprinter_t *format, InternetAddressList *list)
+{
+ InternetAddress *address;
+ int i;
+
+ for (i = 0; i < internet_address_list_length (list); i++) {
+ address = internet_address_list_get_address (list, i);
+ if (INTERNET_ADDRESS_IS_GROUP (address)) {
+ InternetAddressGroup *group;
+ InternetAddressList *group_list;
+
+ group = INTERNET_ADDRESS_GROUP (address);
+ group_list = internet_address_group_get_members (group);
+ if (group_list == NULL)
+ continue;
+
+ print_address_list (format, group_list);
+ } else {
+ InternetAddressMailbox *mailbox;
+ const char *name;
+ const char *addr;
+ char *full_address;
+
+ mailbox = INTERNET_ADDRESS_MAILBOX (address);
+
+ name = internet_address_get_name (address);
+ addr = internet_address_mailbox_get_addr (mailbox);
+
+ if (name && *name)
+ full_address = talloc_asprintf (NULL, "%s <%s>", name, addr);
+ else
+ full_address = talloc_asprintf (NULL, "<%s>", addr);
+
+ if (!full_address)
+ break;
+
+ format->string (format, full_address);
+ format->separator (format);
+
+ talloc_free (full_address);
+ }
+ }
+}
+
+static void
+print_address_string (sprinter_t *format, const char *recipients)
+{
+ InternetAddressList *list;
+
+ if (recipients == NULL)
+ return;
+
+ list = internet_address_list_parse_string (recipients);
+ if (list == NULL)
+ return;
+
+ print_address_list (format, list);
+}
+
static int
do_search_messages (sprinter_t *format,
notmuch_query_t *query,
@@ -264,11 +327,33 @@ do_search_messages (sprinter_t *format,
notmuch_filenames_destroy( filenames );
- } else { /* output == OUTPUT_MESSAGES */
+ } else if (output == OUTPUT_MESSAGES) {
format->set_prefix (format, "id");
format->string (format,
notmuch_message_get_message_id (message));
format->separator (format);
+ } else {
+ if (output & OUTPUT_ADDRESS_FROM) {
+ const char *addrs;
+
+ addrs = notmuch_message_get_header (message, "reply-to");
+
+ if (addrs == NULL || *addrs == '\0')
+ addrs = notmuch_message_get_header (message, "from");
+
+ print_address_string (format, addrs);
+ }
+
+ if (output & OUTPUT_ADDRESS_TO) {
+ const char *hdrs[] = { "to", "cc", "bcc" };
+ const char *addrs;
+ size_t j;
+
+ for (j = 0; j < ARRAY_SIZE (hdrs); j++) {
+ addrs = notmuch_message_get_header (message, hdrs[j]);
+ print_address_string (format, addrs);
+ }
+ }
}
notmuch_message_destroy (message);
@@ -338,7 +423,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST;
sprinter_t *format = NULL;
int opt_index, ret;
- output_t output = OUTPUT_SUMMARY;
+ output_t output = 0;
int offset = 0;
int limit = -1; /* unlimited */
notmuch_exclude_t exclude = NOTMUCH_EXCLUDE_TRUE;
@@ -364,10 +449,12 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
{ "text0", NOTMUCH_FORMAT_TEXT0 },
{ 0, 0 } } },
{ NOTMUCH_OPT_INT, ¬much_format_version, "format-version", 0, 0 },
- { NOTMUCH_OPT_KEYWORD, &output, "output", 'o',
+ { NOTMUCH_OPT_KEYWORD_FLAGS, &output, "output", 'o',
(notmuch_keyword_t []){ { "summary", OUTPUT_SUMMARY },
{ "threads", OUTPUT_THREADS },
{ "messages", OUTPUT_MESSAGES },
+ { "address-from", OUTPUT_ADDRESS_FROM },
+ { "address-to", OUTPUT_ADDRESS_TO },
{ "files", OUTPUT_FILES },
{ "tags", OUTPUT_TAGS },
{ 0, 0 } } },
@@ -387,6 +474,9 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
if (opt_index < 0)
return EXIT_FAILURE;
+ if (! output)
+ output = OUTPUT_SUMMARY;
+
switch (format_sel) {
case NOTMUCH_FORMAT_TEXT:
format = sprinter_text_create (config, stdout);
@@ -453,18 +543,23 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
}
switch (output) {
- default:
case OUTPUT_SUMMARY:
case OUTPUT_THREADS:
ret = do_search_threads (format, query, sort, output, offset, limit);
break;
case OUTPUT_MESSAGES:
+ case OUTPUT_ADDRESS_FROM:
+ case OUTPUT_ADDRESS_TO:
+ case OUTPUT_ADDRESS_ALL:
case OUTPUT_FILES:
ret = do_search_messages (format, query, output, offset, limit, dupe);
break;
case OUTPUT_TAGS:
ret = do_search_tags (notmuch, format, query);
break;
+ default:
+ fprintf (stderr, "Error: the combination of outputs is not supported.\n");
+ ret = 1;
}
notmuch_query_destroy (query);
--
2.1.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/3] cli: deduplicate addresses for --output=address-*
2014-09-06 12:53 [PATCH 1/3] cli: add support for parsing multiple keyword arguments Jani Nikula
2014-09-06 12:53 ` [PATCH 2/3] cli: add --output=address-{from, to, all} to notmuch search Jani Nikula
@ 2014-09-06 12:53 ` Jani Nikula
2014-09-19 19:27 ` [PATCH 1/3] cli: add support for parsing multiple keyword arguments David Bremner
2 siblings, 0 replies; 10+ messages in thread
From: Jani Nikula @ 2014-09-06 12:53 UTC (permalink / raw)
To: notmuch
---
notmuch-search.c | 32 ++++++++++++++++++++++++++------
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/notmuch-search.c b/notmuch-search.c
index c84ecc31262c..c3ca3246bceb 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -218,7 +218,8 @@ do_search_threads (sprinter_t *format,
}
static void
-print_address_list (sprinter_t *format, InternetAddressList *list)
+print_address_list (sprinter_t *format, GHashTable *addrs,
+ InternetAddressList *list)
{
InternetAddress *address;
int i;
@@ -234,7 +235,7 @@ print_address_list (sprinter_t *format, InternetAddressList *list)
if (group_list == NULL)
continue;
- print_address_list (format, group_list);
+ print_address_list (format, addrs, group_list);
} else {
InternetAddressMailbox *mailbox;
const char *name;
@@ -246,6 +247,11 @@ print_address_list (sprinter_t *format, InternetAddressList *list)
name = internet_address_get_name (address);
addr = internet_address_mailbox_get_addr (mailbox);
+ if (g_hash_table_lookup_extended (addrs, addr, NULL, NULL))
+ continue;
+
+ g_hash_table_insert (addrs, talloc_strdup (NULL, addr), NULL);
+
if (name && *name)
full_address = talloc_asprintf (NULL, "%s <%s>", name, addr);
else
@@ -263,7 +269,7 @@ print_address_list (sprinter_t *format, InternetAddressList *list)
}
static void
-print_address_string (sprinter_t *format, const char *recipients)
+print_address_string (sprinter_t *format, GHashTable *addrs, const char *recipients)
{
InternetAddressList *list;
@@ -274,7 +280,13 @@ print_address_string (sprinter_t *format, const char *recipients)
if (list == NULL)
return;
- print_address_list (format, list);
+ print_address_list (format, addrs, list);
+}
+
+static void
+_my_talloc_free_for_g_hash (void *ptr)
+{
+ talloc_free (ptr);
}
static int
@@ -288,8 +300,13 @@ do_search_messages (sprinter_t *format,
notmuch_message_t *message;
notmuch_messages_t *messages;
notmuch_filenames_t *filenames;
+ GHashTable *addresses = NULL;
int i;
+ if (output & OUTPUT_ADDRESS_ALL)
+ addresses = g_hash_table_new_full (g_str_hash, g_str_equal,
+ _my_talloc_free_for_g_hash, NULL);
+
if (offset < 0) {
offset += notmuch_query_count_messages (query);
if (offset < 0)
@@ -341,7 +358,7 @@ do_search_messages (sprinter_t *format,
if (addrs == NULL || *addrs == '\0')
addrs = notmuch_message_get_header (message, "from");
- print_address_string (format, addrs);
+ print_address_string (format, addresses, addrs);
}
if (output & OUTPUT_ADDRESS_TO) {
@@ -351,7 +368,7 @@ do_search_messages (sprinter_t *format,
for (j = 0; j < ARRAY_SIZE (hdrs); j++) {
addrs = notmuch_message_get_header (message, hdrs[j]);
- print_address_string (format, addrs);
+ print_address_string (format, addresses, addrs);
}
}
}
@@ -359,6 +376,9 @@ do_search_messages (sprinter_t *format,
notmuch_message_destroy (message);
}
+ if (addresses)
+ g_hash_table_unref (addresses);
+
notmuch_messages_destroy (messages);
format->end (format);
--
2.1.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] cli: add --output=address-{from, to, all} to notmuch search
2014-09-06 12:53 ` [PATCH 2/3] cli: add --output=address-{from, to, all} to notmuch search Jani Nikula
@ 2014-09-06 13:35 ` Mark Walters
2014-09-06 16:41 ` [PATCH] cli: add --output=address-{from,to,all} " Jani Nikula
0 siblings, 1 reply; 10+ messages in thread
From: Mark Walters @ 2014-09-06 13:35 UTC (permalink / raw)
To: Jani Nikula, notmuch
On Sat, 06 Sep 2014, Jani Nikula <jani@nikula.org> wrote:
> address-from prints reply-to or from, address-to prints to, cc, and
> bcc, and address-all prints all of them.
Hi
I like these: thanks a lot for doing this.
Just one quick comment before I do an actual review:
> ---
> notmuch-search.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 104 insertions(+), 9 deletions(-)
>
> diff --git a/notmuch-search.c b/notmuch-search.c
> index bc9be4593ecc..c84ecc31262c 100644
> --- a/notmuch-search.c
> +++ b/notmuch-search.c
> @@ -23,11 +23,14 @@
> #include "string-util.h"
>
> typedef enum {
> - OUTPUT_SUMMARY,
> - OUTPUT_THREADS,
> - OUTPUT_MESSAGES,
> - OUTPUT_FILES,
> - OUTPUT_TAGS
> + OUTPUT_SUMMARY = 1 << 0,
> + OUTPUT_THREADS = 1 << 1,
> + OUTPUT_MESSAGES = 1 << 2,
> + OUTPUT_FILES = 1 << 3,
> + OUTPUT_TAGS = 1 << 4,
> + OUTPUT_ADDRESS_FROM = 1 << 5,
> + OUTPUT_ADDRESS_TO = 1 << 6,
> + OUTPUT_ADDRESS_ALL = OUTPUT_ADDRESS_FROM | OUTPUT_ADDRESS_TO,
> } output_t;
>
> /* Return two stable query strings that identify exactly the matched
> @@ -214,6 +217,66 @@ do_search_threads (sprinter_t *format,
> return 0;
> }
>
> +static void
> +print_address_list (sprinter_t *format, InternetAddressList *list)
> +{
> + InternetAddress *address;
> + int i;
> +
> + for (i = 0; i < internet_address_list_length (list); i++) {
> + address = internet_address_list_get_address (list, i);
> + if (INTERNET_ADDRESS_IS_GROUP (address)) {
> + InternetAddressGroup *group;
> + InternetAddressList *group_list;
> +
> + group = INTERNET_ADDRESS_GROUP (address);
> + group_list = internet_address_group_get_members (group);
> + if (group_list == NULL)
> + continue;
> +
> + print_address_list (format, group_list);
> + } else {
> + InternetAddressMailbox *mailbox;
> + const char *name;
> + const char *addr;
> + char *full_address;
> +
> + mailbox = INTERNET_ADDRESS_MAILBOX (address);
> +
> + name = internet_address_get_name (address);
> + addr = internet_address_mailbox_get_addr (mailbox);
> +
> + if (name && *name)
> + full_address = talloc_asprintf (NULL, "%s <%s>", name, addr);
> + else
> + full_address = talloc_asprintf (NULL, "<%s>", addr);
> +
> + if (!full_address)
> + break;
> +
> + format->string (format, full_address);
> + format->separator (format);
> +
> + talloc_free (full_address);
> + }
> + }
> +}
> +
> +static void
> +print_address_string (sprinter_t *format, const char *recipients)
> +{
> + InternetAddressList *list;
> +
> + if (recipients == NULL)
> + return;
> +
> + list = internet_address_list_parse_string (recipients);
> + if (list == NULL)
> + return;
> +
> + print_address_list (format, list);
> +}
> +
> static int
> do_search_messages (sprinter_t *format,
> notmuch_query_t *query,
> @@ -264,11 +327,33 @@ do_search_messages (sprinter_t *format,
>
> notmuch_filenames_destroy( filenames );
>
> - } else { /* output == OUTPUT_MESSAGES */
> + } else if (output == OUTPUT_MESSAGES) {
> format->set_prefix (format, "id");
> format->string (format,
> notmuch_message_get_message_id (message));
> format->separator (format);
> + } else {
> + if (output & OUTPUT_ADDRESS_FROM) {
> + const char *addrs;
> +
> + addrs = notmuch_message_get_header (message, "reply-to");
> +
> + if (addrs == NULL || *addrs == '\0')
> + addrs = notmuch_message_get_header (message, "from");
I would suggest adding a separate address-reply-to option. The main
reason is that we store from in the database so if you do from without
the reply-to it is *very* fast whereas with the reply-to notmuch has to
read every message to get the reply-to header. Even on a fully hot cache
this means that from alone is a factor of 10 faster than reply-to/from.
(If anyone wants to test this themselves just comment out the reply-to
and if lines above)
Best wishes
Mark
> +
> + print_address_string (format, addrs);
> + }
> +
> + if (output & OUTPUT_ADDRESS_TO) {
> + const char *hdrs[] = { "to", "cc", "bcc" };
> + const char *addrs;
> + size_t j;
> +
> + for (j = 0; j < ARRAY_SIZE (hdrs); j++) {
> + addrs = notmuch_message_get_header (message, hdrs[j]);
> + print_address_string (format, addrs);
> + }
> + }
> }
>
> notmuch_message_destroy (message);
> @@ -338,7 +423,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
> notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST;
> sprinter_t *format = NULL;
> int opt_index, ret;
> - output_t output = OUTPUT_SUMMARY;
> + output_t output = 0;
> int offset = 0;
> int limit = -1; /* unlimited */
> notmuch_exclude_t exclude = NOTMUCH_EXCLUDE_TRUE;
> @@ -364,10 +449,12 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
> { "text0", NOTMUCH_FORMAT_TEXT0 },
> { 0, 0 } } },
> { NOTMUCH_OPT_INT, ¬much_format_version, "format-version", 0, 0 },
> - { NOTMUCH_OPT_KEYWORD, &output, "output", 'o',
> + { NOTMUCH_OPT_KEYWORD_FLAGS, &output, "output", 'o',
> (notmuch_keyword_t []){ { "summary", OUTPUT_SUMMARY },
> { "threads", OUTPUT_THREADS },
> { "messages", OUTPUT_MESSAGES },
> + { "address-from", OUTPUT_ADDRESS_FROM },
> + { "address-to", OUTPUT_ADDRESS_TO },
> { "files", OUTPUT_FILES },
> { "tags", OUTPUT_TAGS },
> { 0, 0 } } },
> @@ -387,6 +474,9 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
> if (opt_index < 0)
> return EXIT_FAILURE;
>
> + if (! output)
> + output = OUTPUT_SUMMARY;
> +
> switch (format_sel) {
> case NOTMUCH_FORMAT_TEXT:
> format = sprinter_text_create (config, stdout);
> @@ -453,18 +543,23 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
> }
>
> switch (output) {
> - default:
> case OUTPUT_SUMMARY:
> case OUTPUT_THREADS:
> ret = do_search_threads (format, query, sort, output, offset, limit);
> break;
> case OUTPUT_MESSAGES:
> + case OUTPUT_ADDRESS_FROM:
> + case OUTPUT_ADDRESS_TO:
> + case OUTPUT_ADDRESS_ALL:
> case OUTPUT_FILES:
> ret = do_search_messages (format, query, output, offset, limit, dupe);
> break;
> case OUTPUT_TAGS:
> ret = do_search_tags (notmuch, format, query);
> break;
> + default:
> + fprintf (stderr, "Error: the combination of outputs is not supported.\n");
> + ret = 1;
> }
>
> notmuch_query_destroy (query);
> --
> 2.1.0
>
> _______________________________________________
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH] cli: add --output=address-{from,to,all} to notmuch search
2014-09-06 13:35 ` Mark Walters
@ 2014-09-06 16:41 ` Jani Nikula
2014-09-06 16:47 ` [PATCH] cli: add --output=address-{from, to, all} " Jani Nikula
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Jani Nikula @ 2014-09-06 16:41 UTC (permalink / raw)
To: notmuch
address-from prints reply-to or from, address-to prints to, cc, and
bcc, and address-all prints all of them.
---
notmuch-search.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 100 insertions(+), 9 deletions(-)
diff --git a/notmuch-search.c b/notmuch-search.c
index bc9be4593ecc..e7cf3d2a0fdf 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -23,11 +23,14 @@
#include "string-util.h"
typedef enum {
- OUTPUT_SUMMARY,
- OUTPUT_THREADS,
- OUTPUT_MESSAGES,
- OUTPUT_FILES,
- OUTPUT_TAGS
+ OUTPUT_SUMMARY = 1 << 0,
+ OUTPUT_THREADS = 1 << 1,
+ OUTPUT_MESSAGES = 1 << 2,
+ OUTPUT_FILES = 1 << 3,
+ OUTPUT_TAGS = 1 << 4,
+ OUTPUT_SENDER = 1 << 5,
+ OUTPUT_RECIPIENTS = 1 << 6,
+ OUTPUT_ADDRESSES = OUTPUT_SENDER | OUTPUT_RECIPIENTS,
} output_t;
/* Return two stable query strings that identify exactly the matched
@@ -214,6 +217,66 @@ do_search_threads (sprinter_t *format,
return 0;
}
+static void
+print_address_list (sprinter_t *format, InternetAddressList *list)
+{
+ InternetAddress *address;
+ int i;
+
+ for (i = 0; i < internet_address_list_length (list); i++) {
+ address = internet_address_list_get_address (list, i);
+ if (INTERNET_ADDRESS_IS_GROUP (address)) {
+ InternetAddressGroup *group;
+ InternetAddressList *group_list;
+
+ group = INTERNET_ADDRESS_GROUP (address);
+ group_list = internet_address_group_get_members (group);
+ if (group_list == NULL)
+ continue;
+
+ print_address_list (format, group_list);
+ } else {
+ InternetAddressMailbox *mailbox;
+ const char *name;
+ const char *addr;
+ char *full_address;
+
+ mailbox = INTERNET_ADDRESS_MAILBOX (address);
+
+ name = internet_address_get_name (address);
+ addr = internet_address_mailbox_get_addr (mailbox);
+
+ if (name && *name)
+ full_address = talloc_asprintf (NULL, "%s <%s>", name, addr);
+ else
+ full_address = talloc_asprintf (NULL, "<%s>", addr);
+
+ if (!full_address)
+ break;
+
+ format->string (format, full_address);
+ format->separator (format);
+
+ talloc_free (full_address);
+ }
+ }
+}
+
+static void
+print_address_string (sprinter_t *format, const char *recipients)
+{
+ InternetAddressList *list;
+
+ if (recipients == NULL)
+ return;
+
+ list = internet_address_list_parse_string (recipients);
+ if (list == NULL)
+ return;
+
+ print_address_list (format, list);
+}
+
static int
do_search_messages (sprinter_t *format,
notmuch_query_t *query,
@@ -264,11 +327,29 @@ do_search_messages (sprinter_t *format,
notmuch_filenames_destroy( filenames );
- } else { /* output == OUTPUT_MESSAGES */
+ } else if (output == OUTPUT_MESSAGES) {
format->set_prefix (format, "id");
format->string (format,
notmuch_message_get_message_id (message));
format->separator (format);
+ } else {
+ if (output & OUTPUT_SENDER) {
+ const char *addrs;
+
+ addrs = notmuch_message_get_header (message, "from");
+ print_address_string (format, addrs);
+ }
+
+ if (output & OUTPUT_RECIPIENTS) {
+ const char *hdrs[] = { "to", "cc", "bcc" };
+ const char *addrs;
+ size_t j;
+
+ for (j = 0; j < ARRAY_SIZE (hdrs); j++) {
+ addrs = notmuch_message_get_header (message, hdrs[j]);
+ print_address_string (format, addrs);
+ }
+ }
}
notmuch_message_destroy (message);
@@ -338,7 +419,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST;
sprinter_t *format = NULL;
int opt_index, ret;
- output_t output = OUTPUT_SUMMARY;
+ output_t output = 0;
int offset = 0;
int limit = -1; /* unlimited */
notmuch_exclude_t exclude = NOTMUCH_EXCLUDE_TRUE;
@@ -364,10 +445,12 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
{ "text0", NOTMUCH_FORMAT_TEXT0 },
{ 0, 0 } } },
{ NOTMUCH_OPT_INT, ¬much_format_version, "format-version", 0, 0 },
- { NOTMUCH_OPT_KEYWORD, &output, "output", 'o',
+ { NOTMUCH_OPT_KEYWORD_FLAGS, &output, "output", 'o',
(notmuch_keyword_t []){ { "summary", OUTPUT_SUMMARY },
{ "threads", OUTPUT_THREADS },
{ "messages", OUTPUT_MESSAGES },
+ { "sender", OUTPUT_SENDER },
+ { "recipients", OUTPUT_RECIPIENTS },
{ "files", OUTPUT_FILES },
{ "tags", OUTPUT_TAGS },
{ 0, 0 } } },
@@ -387,6 +470,9 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
if (opt_index < 0)
return EXIT_FAILURE;
+ if (! output)
+ output = OUTPUT_SUMMARY;
+
switch (format_sel) {
case NOTMUCH_FORMAT_TEXT:
format = sprinter_text_create (config, stdout);
@@ -453,18 +539,23 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
}
switch (output) {
- default:
case OUTPUT_SUMMARY:
case OUTPUT_THREADS:
ret = do_search_threads (format, query, sort, output, offset, limit);
break;
case OUTPUT_MESSAGES:
+ case OUTPUT_SENDER:
+ case OUTPUT_RECIPIENTS:
+ case OUTPUT_ADDRESSES:
case OUTPUT_FILES:
ret = do_search_messages (format, query, output, offset, limit, dupe);
break;
case OUTPUT_TAGS:
ret = do_search_tags (notmuch, format, query);
break;
+ default:
+ fprintf (stderr, "Error: the combination of outputs is not supported.\n");
+ ret = 1;
}
notmuch_query_destroy (query);
--
2.1.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] cli: add --output=address-{from, to, all} to notmuch search
2014-09-06 16:41 ` [PATCH] cli: add --output=address-{from,to,all} " Jani Nikula
@ 2014-09-06 16:47 ` Jani Nikula
2014-09-06 17:47 ` Mark Walters
2014-09-19 19:57 ` [PATCH] cli: add --output=address-{from,to,all} " David Bremner
2 siblings, 0 replies; 10+ messages in thread
From: Jani Nikula @ 2014-09-06 16:47 UTC (permalink / raw)
To: notmuch
On Sat, 06 Sep 2014, Jani Nikula <jani@nikula.org> wrote:
> address-from prints reply-to or from, address-to prints to, cc, and
> bcc, and address-all prints all of them.
*sigh* this was supposed to be:
---
cli: add --output=sender and --output=recipients to notmuch search
sender prints from, recipients prints to, cc, and bcc.
---
I don't have the time for this, and I'm rushing too much...
BR,
Jani.
> ---
> notmuch-search.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 100 insertions(+), 9 deletions(-)
>
> diff --git a/notmuch-search.c b/notmuch-search.c
> index bc9be4593ecc..e7cf3d2a0fdf 100644
> --- a/notmuch-search.c
> +++ b/notmuch-search.c
> @@ -23,11 +23,14 @@
> #include "string-util.h"
>
> typedef enum {
> - OUTPUT_SUMMARY,
> - OUTPUT_THREADS,
> - OUTPUT_MESSAGES,
> - OUTPUT_FILES,
> - OUTPUT_TAGS
> + OUTPUT_SUMMARY = 1 << 0,
> + OUTPUT_THREADS = 1 << 1,
> + OUTPUT_MESSAGES = 1 << 2,
> + OUTPUT_FILES = 1 << 3,
> + OUTPUT_TAGS = 1 << 4,
> + OUTPUT_SENDER = 1 << 5,
> + OUTPUT_RECIPIENTS = 1 << 6,
> + OUTPUT_ADDRESSES = OUTPUT_SENDER | OUTPUT_RECIPIENTS,
> } output_t;
>
> /* Return two stable query strings that identify exactly the matched
> @@ -214,6 +217,66 @@ do_search_threads (sprinter_t *format,
> return 0;
> }
>
> +static void
> +print_address_list (sprinter_t *format, InternetAddressList *list)
> +{
> + InternetAddress *address;
> + int i;
> +
> + for (i = 0; i < internet_address_list_length (list); i++) {
> + address = internet_address_list_get_address (list, i);
> + if (INTERNET_ADDRESS_IS_GROUP (address)) {
> + InternetAddressGroup *group;
> + InternetAddressList *group_list;
> +
> + group = INTERNET_ADDRESS_GROUP (address);
> + group_list = internet_address_group_get_members (group);
> + if (group_list == NULL)
> + continue;
> +
> + print_address_list (format, group_list);
> + } else {
> + InternetAddressMailbox *mailbox;
> + const char *name;
> + const char *addr;
> + char *full_address;
> +
> + mailbox = INTERNET_ADDRESS_MAILBOX (address);
> +
> + name = internet_address_get_name (address);
> + addr = internet_address_mailbox_get_addr (mailbox);
> +
> + if (name && *name)
> + full_address = talloc_asprintf (NULL, "%s <%s>", name, addr);
> + else
> + full_address = talloc_asprintf (NULL, "<%s>", addr);
> +
> + if (!full_address)
> + break;
> +
> + format->string (format, full_address);
> + format->separator (format);
> +
> + talloc_free (full_address);
> + }
> + }
> +}
> +
> +static void
> +print_address_string (sprinter_t *format, const char *recipients)
> +{
> + InternetAddressList *list;
> +
> + if (recipients == NULL)
> + return;
> +
> + list = internet_address_list_parse_string (recipients);
> + if (list == NULL)
> + return;
> +
> + print_address_list (format, list);
> +}
> +
> static int
> do_search_messages (sprinter_t *format,
> notmuch_query_t *query,
> @@ -264,11 +327,29 @@ do_search_messages (sprinter_t *format,
>
> notmuch_filenames_destroy( filenames );
>
> - } else { /* output == OUTPUT_MESSAGES */
> + } else if (output == OUTPUT_MESSAGES) {
> format->set_prefix (format, "id");
> format->string (format,
> notmuch_message_get_message_id (message));
> format->separator (format);
> + } else {
> + if (output & OUTPUT_SENDER) {
> + const char *addrs;
> +
> + addrs = notmuch_message_get_header (message, "from");
> + print_address_string (format, addrs);
> + }
> +
> + if (output & OUTPUT_RECIPIENTS) {
> + const char *hdrs[] = { "to", "cc", "bcc" };
> + const char *addrs;
> + size_t j;
> +
> + for (j = 0; j < ARRAY_SIZE (hdrs); j++) {
> + addrs = notmuch_message_get_header (message, hdrs[j]);
> + print_address_string (format, addrs);
> + }
> + }
> }
>
> notmuch_message_destroy (message);
> @@ -338,7 +419,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
> notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST;
> sprinter_t *format = NULL;
> int opt_index, ret;
> - output_t output = OUTPUT_SUMMARY;
> + output_t output = 0;
> int offset = 0;
> int limit = -1; /* unlimited */
> notmuch_exclude_t exclude = NOTMUCH_EXCLUDE_TRUE;
> @@ -364,10 +445,12 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
> { "text0", NOTMUCH_FORMAT_TEXT0 },
> { 0, 0 } } },
> { NOTMUCH_OPT_INT, ¬much_format_version, "format-version", 0, 0 },
> - { NOTMUCH_OPT_KEYWORD, &output, "output", 'o',
> + { NOTMUCH_OPT_KEYWORD_FLAGS, &output, "output", 'o',
> (notmuch_keyword_t []){ { "summary", OUTPUT_SUMMARY },
> { "threads", OUTPUT_THREADS },
> { "messages", OUTPUT_MESSAGES },
> + { "sender", OUTPUT_SENDER },
> + { "recipients", OUTPUT_RECIPIENTS },
> { "files", OUTPUT_FILES },
> { "tags", OUTPUT_TAGS },
> { 0, 0 } } },
> @@ -387,6 +470,9 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
> if (opt_index < 0)
> return EXIT_FAILURE;
>
> + if (! output)
> + output = OUTPUT_SUMMARY;
> +
> switch (format_sel) {
> case NOTMUCH_FORMAT_TEXT:
> format = sprinter_text_create (config, stdout);
> @@ -453,18 +539,23 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
> }
>
> switch (output) {
> - default:
> case OUTPUT_SUMMARY:
> case OUTPUT_THREADS:
> ret = do_search_threads (format, query, sort, output, offset, limit);
> break;
> case OUTPUT_MESSAGES:
> + case OUTPUT_SENDER:
> + case OUTPUT_RECIPIENTS:
> + case OUTPUT_ADDRESSES:
> case OUTPUT_FILES:
> ret = do_search_messages (format, query, output, offset, limit, dupe);
> break;
> case OUTPUT_TAGS:
> ret = do_search_tags (notmuch, format, query);
> break;
> + default:
> + fprintf (stderr, "Error: the combination of outputs is not supported.\n");
> + ret = 1;
> }
>
> notmuch_query_destroy (query);
> --
> 2.1.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] cli: add --output=address-{from, to, all} to notmuch search
2014-09-06 16:41 ` [PATCH] cli: add --output=address-{from,to,all} " Jani Nikula
2014-09-06 16:47 ` [PATCH] cli: add --output=address-{from, to, all} " Jani Nikula
@ 2014-09-06 17:47 ` Mark Walters
2014-09-19 19:57 ` [PATCH] cli: add --output=address-{from,to,all} " David Bremner
2 siblings, 0 replies; 10+ messages in thread
From: Mark Walters @ 2014-09-06 17:47 UTC (permalink / raw)
To: Jani Nikula, notmuch
On Sat, 06 Sep 2014, Jani Nikula <jani@nikula.org> wrote:
> address-from prints reply-to or from, address-to prints to, cc, and
> bcc, and address-all prints all of them.
This looks good to me. Obviously needs the new commit
message.
I think we should think about the deduplication possibilities but that
can be added later. My timings suggest that there is a 20 times speed up
in using this with --output=sender over calling notmuch show
--body=false --entire-thread=false.
If you want the to,cc then this version is only twice as fast as the
notmuch show version.
(All the above are with a hot cache: I expect bigger improvements with a
cold cache).
So this could well speed up dme's address completion patch
id:1409921969-65129-1-git-send-email-dme@dme.org by a factor of 20.
(The nevermore variants will not get such a big gain as they look at
to/cc rather than from)
Best wishes
Mark
> ---
> notmuch-search.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 100 insertions(+), 9 deletions(-)
>
> diff --git a/notmuch-search.c b/notmuch-search.c
> index bc9be4593ecc..e7cf3d2a0fdf 100644
> --- a/notmuch-search.c
> +++ b/notmuch-search.c
> @@ -23,11 +23,14 @@
> #include "string-util.h"
>
> typedef enum {
> - OUTPUT_SUMMARY,
> - OUTPUT_THREADS,
> - OUTPUT_MESSAGES,
> - OUTPUT_FILES,
> - OUTPUT_TAGS
> + OUTPUT_SUMMARY = 1 << 0,
> + OUTPUT_THREADS = 1 << 1,
> + OUTPUT_MESSAGES = 1 << 2,
> + OUTPUT_FILES = 1 << 3,
> + OUTPUT_TAGS = 1 << 4,
> + OUTPUT_SENDER = 1 << 5,
> + OUTPUT_RECIPIENTS = 1 << 6,
> + OUTPUT_ADDRESSES = OUTPUT_SENDER | OUTPUT_RECIPIENTS,
> } output_t;
>
> /* Return two stable query strings that identify exactly the matched
> @@ -214,6 +217,66 @@ do_search_threads (sprinter_t *format,
> return 0;
> }
>
> +static void
> +print_address_list (sprinter_t *format, InternetAddressList *list)
> +{
> + InternetAddress *address;
> + int i;
> +
> + for (i = 0; i < internet_address_list_length (list); i++) {
> + address = internet_address_list_get_address (list, i);
> + if (INTERNET_ADDRESS_IS_GROUP (address)) {
> + InternetAddressGroup *group;
> + InternetAddressList *group_list;
> +
> + group = INTERNET_ADDRESS_GROUP (address);
> + group_list = internet_address_group_get_members (group);
> + if (group_list == NULL)
> + continue;
> +
> + print_address_list (format, group_list);
> + } else {
> + InternetAddressMailbox *mailbox;
> + const char *name;
> + const char *addr;
> + char *full_address;
> +
> + mailbox = INTERNET_ADDRESS_MAILBOX (address);
> +
> + name = internet_address_get_name (address);
> + addr = internet_address_mailbox_get_addr (mailbox);
> +
> + if (name && *name)
> + full_address = talloc_asprintf (NULL, "%s <%s>", name, addr);
> + else
> + full_address = talloc_asprintf (NULL, "<%s>", addr);
> +
> + if (!full_address)
> + break;
> +
> + format->string (format, full_address);
> + format->separator (format);
> +
> + talloc_free (full_address);
> + }
> + }
> +}
> +
> +static void
> +print_address_string (sprinter_t *format, const char *recipients)
> +{
> + InternetAddressList *list;
> +
> + if (recipients == NULL)
> + return;
> +
> + list = internet_address_list_parse_string (recipients);
> + if (list == NULL)
> + return;
> +
> + print_address_list (format, list);
> +}
> +
> static int
> do_search_messages (sprinter_t *format,
> notmuch_query_t *query,
> @@ -264,11 +327,29 @@ do_search_messages (sprinter_t *format,
>
> notmuch_filenames_destroy( filenames );
>
> - } else { /* output == OUTPUT_MESSAGES */
> + } else if (output == OUTPUT_MESSAGES) {
> format->set_prefix (format, "id");
> format->string (format,
> notmuch_message_get_message_id (message));
> format->separator (format);
> + } else {
> + if (output & OUTPUT_SENDER) {
> + const char *addrs;
> +
> + addrs = notmuch_message_get_header (message, "from");
> + print_address_string (format, addrs);
> + }
> +
> + if (output & OUTPUT_RECIPIENTS) {
> + const char *hdrs[] = { "to", "cc", "bcc" };
> + const char *addrs;
> + size_t j;
> +
> + for (j = 0; j < ARRAY_SIZE (hdrs); j++) {
> + addrs = notmuch_message_get_header (message, hdrs[j]);
> + print_address_string (format, addrs);
> + }
> + }
> }
>
> notmuch_message_destroy (message);
> @@ -338,7 +419,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
> notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST;
> sprinter_t *format = NULL;
> int opt_index, ret;
> - output_t output = OUTPUT_SUMMARY;
> + output_t output = 0;
> int offset = 0;
> int limit = -1; /* unlimited */
> notmuch_exclude_t exclude = NOTMUCH_EXCLUDE_TRUE;
> @@ -364,10 +445,12 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
> { "text0", NOTMUCH_FORMAT_TEXT0 },
> { 0, 0 } } },
> { NOTMUCH_OPT_INT, ¬much_format_version, "format-version", 0, 0 },
> - { NOTMUCH_OPT_KEYWORD, &output, "output", 'o',
> + { NOTMUCH_OPT_KEYWORD_FLAGS, &output, "output", 'o',
> (notmuch_keyword_t []){ { "summary", OUTPUT_SUMMARY },
> { "threads", OUTPUT_THREADS },
> { "messages", OUTPUT_MESSAGES },
> + { "sender", OUTPUT_SENDER },
> + { "recipients", OUTPUT_RECIPIENTS },
> { "files", OUTPUT_FILES },
> { "tags", OUTPUT_TAGS },
> { 0, 0 } } },
> @@ -387,6 +470,9 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
> if (opt_index < 0)
> return EXIT_FAILURE;
>
> + if (! output)
> + output = OUTPUT_SUMMARY;
> +
> switch (format_sel) {
> case NOTMUCH_FORMAT_TEXT:
> format = sprinter_text_create (config, stdout);
> @@ -453,18 +539,23 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
> }
>
> switch (output) {
> - default:
> case OUTPUT_SUMMARY:
> case OUTPUT_THREADS:
> ret = do_search_threads (format, query, sort, output, offset, limit);
> break;
> case OUTPUT_MESSAGES:
> + case OUTPUT_SENDER:
> + case OUTPUT_RECIPIENTS:
> + case OUTPUT_ADDRESSES:
> case OUTPUT_FILES:
> ret = do_search_messages (format, query, output, offset, limit, dupe);
> break;
> case OUTPUT_TAGS:
> ret = do_search_tags (notmuch, format, query);
> break;
> + default:
> + fprintf (stderr, "Error: the combination of outputs is not supported.\n");
> + ret = 1;
> }
>
> notmuch_query_destroy (query);
> --
> 2.1.0
>
> _______________________________________________
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] cli: add support for parsing multiple keyword arguments
2014-09-06 12:53 [PATCH 1/3] cli: add support for parsing multiple keyword arguments Jani Nikula
2014-09-06 12:53 ` [PATCH 2/3] cli: add --output=address-{from, to, all} to notmuch search Jani Nikula
2014-09-06 12:53 ` [PATCH 3/3] cli: deduplicate addresses for --output=address-* Jani Nikula
@ 2014-09-19 19:27 ` David Bremner
2 siblings, 0 replies; 10+ messages in thread
From: David Bremner @ 2014-09-19 19:27 UTC (permalink / raw)
To: Jani Nikula, notmuch
Jani Nikula <jani@nikula.org> writes:
> This allows having multiple --foo=bar --foo=baz options on the command
> line, with the corresponding values OR'd together.
> ---
This looks OK. In hindsight I guess we could have had only keyword_flags
from the beginning, but I guess that would be pretty intrusive to change
at this point.
d
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] cli: add --output=address-{from,to,all} to notmuch search
2014-09-06 16:41 ` [PATCH] cli: add --output=address-{from,to,all} " Jani Nikula
2014-09-06 16:47 ` [PATCH] cli: add --output=address-{from, to, all} " Jani Nikula
2014-09-06 17:47 ` Mark Walters
@ 2014-09-19 19:57 ` David Bremner
2014-09-20 8:04 ` [PATCH] cli: add --output=address-{from, to, all} " Michal Sojka
2 siblings, 1 reply; 10+ messages in thread
From: David Bremner @ 2014-09-19 19:57 UTC (permalink / raw)
To: Jani Nikula, notmuch
Jani Nikula <jani@nikula.org> writes:
> + if (name && *name)
> + full_address = talloc_asprintf (NULL, "%s <%s>", name, addr);
> + else
> + full_address = talloc_asprintf (NULL, "<%s>", addr
Is there some reason not to use sprinter as a talloc context here?
> +
> + if (!full_address)
> + break;
Is the error here out of memory? Maybe an error message would be a good
idea.
Obviously the docs need to be updated as well, and ideally the tests. I
think Jani was hinting that he didn't want to be the person to do
that. Any volunteers?
d
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] cli: add --output=address-{from, to, all} to notmuch search
2014-09-19 19:57 ` [PATCH] cli: add --output=address-{from,to,all} " David Bremner
@ 2014-09-20 8:04 ` Michal Sojka
0 siblings, 0 replies; 10+ messages in thread
From: Michal Sojka @ 2014-09-20 8:04 UTC (permalink / raw)
To: David Bremner, Jani Nikula, notmuch
On Fri, Sep 19 2014, David Bremner wrote:
> Jani Nikula <jani@nikula.org> writes:
>
>> + if (name && *name)
>> + full_address = talloc_asprintf (NULL, "%s <%s>", name, addr);
>> + else
>> + full_address = talloc_asprintf (NULL, "<%s>", addr
>
> Is there some reason not to use sprinter as a talloc context here?
>
>> +
>> + if (!full_address)
>> + break;
>
> Is the error here out of memory? Maybe an error message would be a good
> idea.
>
>
> Obviously the docs need to be updated as well, and ideally the tests. I
> think Jani was hinting that he didn't want to be the person to do
> that. Any volunteers?
Yes, I'll look at that. It will probably take me a few days.
-Michal
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2014-09-20 8:04 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-06 12:53 [PATCH 1/3] cli: add support for parsing multiple keyword arguments Jani Nikula
2014-09-06 12:53 ` [PATCH 2/3] cli: add --output=address-{from, to, all} to notmuch search Jani Nikula
2014-09-06 13:35 ` Mark Walters
2014-09-06 16:41 ` [PATCH] cli: add --output=address-{from,to,all} " Jani Nikula
2014-09-06 16:47 ` [PATCH] cli: add --output=address-{from, to, all} " Jani Nikula
2014-09-06 17:47 ` Mark Walters
2014-09-19 19:57 ` [PATCH] cli: add --output=address-{from,to,all} " David Bremner
2014-09-20 8:04 ` [PATCH] cli: add --output=address-{from, to, all} " Michal Sojka
2014-09-06 12:53 ` [PATCH 3/3] cli: deduplicate addresses for --output=address-* Jani Nikula
2014-09-19 19:27 ` [PATCH 1/3] cli: add support for parsing multiple keyword arguments David Bremner
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).