[PATCH v6 6/7] cli: search: Add --output=count
Hi Tomi, On Mon, Nov 03 2014, Tomi Ollila wrote: > On Sun, Nov 02 2014, Michal Sojka wrote: > >> On 2. listopadu 2014 10:29:28 CET, Mark Walters > gmail.com> wrote: >>> >>>Hi >>> >>>On Sun, 02 Nov 2014, Michal Sojka wrote: On Sat, Nov 01 2014, Mark Walters wrote: > On Fri, 31 Oct 2014, Michal Sojka wrote: >> This output can be used with --output=recipients or --output=sender >> and in addition to the addresses, it prints how many times was each >> address encountered during search. > > Hi > > I have a couple comments on this patch. > >> --- >> completion/notmuch-completion.bash | 2 +- >> completion/notmuch-completion.zsh | 2 +- >> doc/man1/notmuch-search.rst| 9 +-- >> notmuch-search.c | 51 >>>-- >> 4 files changed, 52 insertions(+), 12 deletions(-) >> >> diff --git a/completion/notmuch-completion.bash >>>b/completion/notmuch-completion.bash >> index cfbd389..39cd829 100644 >> --- a/completion/notmuch-completion.bash >> +++ b/completion/notmuch-completion.bash >> @@ -294,7 +294,7 @@ _notmuch_search() >> return >> ;; >> --output) >> -COMPREPLY=( $( compgen -W "summary threads messages files >>>tags sender recipients" -- "${cur}" ) ) >> +COMPREPLY=( $( compgen -W "summary threads messages files >>>tags sender recipients count" -- "${cur}" ) ) >> return >> ;; >> --sort) >> diff --git a/completion/notmuch-completion.zsh >>>b/completion/notmuch-completion.zsh >> index 3e52a00..d7e5a5e 100644 >> --- a/completion/notmuch-completion.zsh >> +++ b/completion/notmuch-completion.zsh >> @@ -53,7 +53,7 @@ _notmuch_search() >> '--max-threads=[display only the first x threads from the >>>search results]:number of threads to show: ' \ >> '--first=[omit the first x threads from the search >>>results]:number of threads to omit: ' \ >> '--sort=[sort results]:sorting:((newest-first\:"reverse >>>chronological order" oldest-first\:"chronological order"))' \ >> -'--output=[select what to output]:output:((summary threads >>>messages files tags sender recipients))' >> +'--output=[select what to output]:output:((summary threads >>>messages files tags sender recipients count))' >> } >> >> _notmuch() >> diff --git a/doc/man1/notmuch-search.rst >>>b/doc/man1/notmuch-search.rst >> index 42f17e4..ec89200 100644 >> --- a/doc/man1/notmuch-search.rst >> +++ b/doc/man1/notmuch-search.rst >> @@ -96,9 +96,14 @@ Supported options for **search** include >> Like **sender** but for addresses from *To*, *Cc* and >> *Bcc* headers. >> >> +**count** >> +Can be used in combination with **sender** or >> +**recipients** to print the count of how many times was >> +the address encountered during search. >> + >> This option can be given multiple times to combine different >> -outputs. Currently, this is only supported for **sender** and >> -**recipients** outputs. >> +outputs. Currently, this is only supported for **sender**, >> +**recipients** and **count** outputs. > > It might be worth saying that the results will be slower if count is > specified. I wrote something like this in id:1414889400-30977-10-git-send-email-sojkam1 at fel.cvut.cz. > >> ``--sort=``\ (**newest-first**\ \|\ **oldest-first**) > > I think sort works as expected if count is not specified, but does >>>not > with count. Agreed. > Maybe count can be done by doing two passes? What do you mean by pass? >>> >>>I mean iterating through the messages twice: so the first time would >>>fill in the count in the hash map, and the second iteration would print >>>the addresses. >> >> That's what the patch does. Only the second time it iterates the hash. > > Sorry > > And we loose the order ? (or not ?) do we have "orderedhash" there... > I'd like to save the order What would be the use case? If you really want to preserve the order, we could save a sequence number in mailbox_t and sort the hash table entries before printing. But this could be implemented later and enabled by a special command line option. notmuch search --output=tags does not preserve order either. > (but that is not so important) -- but more importantly, are tests > robusts --- ah there is sort -n in the test... Yes. -Michal
[DRAFT PATCH] modified notmuch-emacs-mua
On Thu, Jul 10 2014, Tomi Ollila wrote: > Highlights: > > * notmuch-emacs-mua without arguments runs (notmuch-hello) > > * runs emacs(1) in case emacsclient(1) fails to connect to running emacs > > * takes -nw option > > * handles mailto: > > * --from option when sending non-mailto: way > > * -i includes file --body[= ]string inserts string Hi, Tomi. I think including an emacs CLI like this is probably a good idea. I might not use it myself, since I've already concocted one for my personal use, but I still think it's a good idea. The particular thing I'm interested in, though, is mailto: URL handling: > + mailto:*) > + oIFS=$IFS; IFS=; OPTARG="$*" IFS=$oIFS > + escape_optarg > + exec_mua "(progn (require 'notmuch) (browse-url-mail \"$OPTARG\"))" > + exit > +esac I have submitted multiple revisions of a patch that handles mailto: URLs in notmuch-mua.el: id:1334438868-17168-1-git-send-email-jrollins at finestructure.net It hasn't been accepted yet, though. I've tried browse-url-mail before, and it would be convenient to use it. However, used on it's own it has the problem that it doesn't open new message buffer in the "notmuch" way. For instance, I prefer my new notmuch buffers to appear in new frames. browse-url-mail doesn't respect this. Maybe it could be wrapped in a notmuch-mua-mailto function, or you could instead be using the function I submitted? I've been a bit out of touch for a while, so forgive me if anything has change that I'm not aware of. jamie. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 818 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20141103/7fe29127/attachment.pgp>
[PATCH v6 6/7] cli: search: Add --output=count
On Sun, Nov 02 2014, Michal Sojka wrote: > On 2. listopadu 2014 10:29:28 CET, Mark Walters gmail.com> wrote: >> >>Hi >> >>On Sun, 02 Nov 2014, Michal Sojka wrote: >>> On Sat, Nov 01 2014, Mark Walters wrote: On Fri, 31 Oct 2014, Michal Sojka wrote: > This output can be used with --output=recipients or --output=sender > and in addition to the addresses, it prints how many times was each > address encountered during search. Hi I have a couple comments on this patch. > --- > completion/notmuch-completion.bash | 2 +- > completion/notmuch-completion.zsh | 2 +- > doc/man1/notmuch-search.rst| 9 +-- > notmuch-search.c | 51 >>-- > 4 files changed, 52 insertions(+), 12 deletions(-) > > diff --git a/completion/notmuch-completion.bash >>b/completion/notmuch-completion.bash > index cfbd389..39cd829 100644 > --- a/completion/notmuch-completion.bash > +++ b/completion/notmuch-completion.bash > @@ -294,7 +294,7 @@ _notmuch_search() > return > ;; > --output) > - COMPREPLY=( $( compgen -W "summary threads messages files >>tags sender recipients" -- "${cur}" ) ) > + COMPREPLY=( $( compgen -W "summary threads messages files >>tags sender recipients count" -- "${cur}" ) ) > return > ;; > --sort) > diff --git a/completion/notmuch-completion.zsh >>b/completion/notmuch-completion.zsh > index 3e52a00..d7e5a5e 100644 > --- a/completion/notmuch-completion.zsh > +++ b/completion/notmuch-completion.zsh > @@ -53,7 +53,7 @@ _notmuch_search() > '--max-threads=[display only the first x threads from the >>search results]:number of threads to show: ' \ > '--first=[omit the first x threads from the search >>results]:number of threads to omit: ' \ > '--sort=[sort results]:sorting:((newest-first\:"reverse >>chronological order" oldest-first\:"chronological order"))' \ > -'--output=[select what to output]:output:((summary threads >>messages files tags sender recipients))' > +'--output=[select what to output]:output:((summary threads >>messages files tags sender recipients count))' > } > > _notmuch() > diff --git a/doc/man1/notmuch-search.rst >>b/doc/man1/notmuch-search.rst > index 42f17e4..ec89200 100644 > --- a/doc/man1/notmuch-search.rst > +++ b/doc/man1/notmuch-search.rst > @@ -96,9 +96,14 @@ Supported options for **search** include > Like **sender** but for addresses from *To*, *Cc* and > *Bcc* headers. > > + **count** > + Can be used in combination with **sender** or > + **recipients** to print the count of how many times was > + the address encountered during search. > + > This option can be given multiple times to combine different > - outputs. Currently, this is only supported for **sender** and > - **recipients** outputs. > + outputs. Currently, this is only supported for **sender**, > + **recipients** and **count** outputs. It might be worth saying that the results will be slower if count is specified. >>> >>> I wrote something like this in >>> id:1414889400-30977-10-git-send-email-sojkam1 at fel.cvut.cz. >>> > ``--sort=``\ (**newest-first**\ \|\ **oldest-first**) I think sort works as expected if count is not specified, but does >>not with count. >>> >>> Agreed. >>> Maybe count can be done by doing two passes? >>> >>> What do you mean by pass? >> >>I mean iterating through the messages twice: so the first time would >>fill in the count in the hash map, and the second iteration would print >>the addresses. > > That's what the patch does. Only the second time it iterates the hash. Sorry And we loose the order ? (or not ?) do we have "orderedhash" there... I'd like to save the order (but that is not so important) -- but more importantly, are tests robusts --- ah there is sort -n in the test... > > Michal Tomi > > -- > Odesl?no z m?ho telefonu pomoc? Kaiten Mail. Omluvte pros?m mou stru?nost. > ___ > notmuch mailing list > notmuch at notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v6 6/7] cli: search: Add --output=count
On Sun, Nov 02 2014, Michal Sojka sojk...@fel.cvut.cz wrote: On 2. listopadu 2014 10:29:28 CET, Mark Walters markwalters1...@gmail.com wrote: Hi On Sun, 02 Nov 2014, Michal Sojka sojk...@fel.cvut.cz wrote: On Sat, Nov 01 2014, Mark Walters wrote: On Fri, 31 Oct 2014, Michal Sojka sojk...@fel.cvut.cz wrote: This output can be used with --output=recipients or --output=sender and in addition to the addresses, it prints how many times was each address encountered during search. Hi I have a couple comments on this patch. --- completion/notmuch-completion.bash | 2 +- completion/notmuch-completion.zsh | 2 +- doc/man1/notmuch-search.rst| 9 +-- notmuch-search.c | 51 -- 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash index cfbd389..39cd829 100644 --- a/completion/notmuch-completion.bash +++ b/completion/notmuch-completion.bash @@ -294,7 +294,7 @@ _notmuch_search() return ;; --output) - COMPREPLY=( $( compgen -W summary threads messages files tags sender recipients -- ${cur} ) ) + COMPREPLY=( $( compgen -W summary threads messages files tags sender recipients count -- ${cur} ) ) return ;; --sort) diff --git a/completion/notmuch-completion.zsh b/completion/notmuch-completion.zsh index 3e52a00..d7e5a5e 100644 --- a/completion/notmuch-completion.zsh +++ b/completion/notmuch-completion.zsh @@ -53,7 +53,7 @@ _notmuch_search() '--max-threads=[display only the first x threads from the search results]:number of threads to show: ' \ '--first=[omit the first x threads from the search results]:number of threads to omit: ' \ '--sort=[sort results]:sorting:((newest-first\:reverse chronological order oldest-first\:chronological order))' \ -'--output=[select what to output]:output:((summary threads messages files tags sender recipients))' +'--output=[select what to output]:output:((summary threads messages files tags sender recipients count))' } _notmuch() diff --git a/doc/man1/notmuch-search.rst b/doc/man1/notmuch-search.rst index 42f17e4..ec89200 100644 --- a/doc/man1/notmuch-search.rst +++ b/doc/man1/notmuch-search.rst @@ -96,9 +96,14 @@ Supported options for **search** include Like **sender** but for addresses from *To*, *Cc* and *Bcc* headers. + **count** + Can be used in combination with **sender** or + **recipients** to print the count of how many times was + the address encountered during search. + This option can be given multiple times to combine different - outputs. Currently, this is only supported for **sender** and - **recipients** outputs. + outputs. Currently, this is only supported for **sender**, + **recipients** and **count** outputs. It might be worth saying that the results will be slower if count is specified. I wrote something like this in id:1414889400-30977-10-git-send-email-sojk...@fel.cvut.cz. ``--sort=``\ (**newest-first**\ \|\ **oldest-first**) I think sort works as expected if count is not specified, but does not with count. Agreed. Maybe count can be done by doing two passes? What do you mean by pass? I mean iterating through the messages twice: so the first time would fill in the count in the hash map, and the second iteration would print the addresses. That's what the patch does. Only the second time it iterates the hash. Sorry And we loose the order ? (or not ?) do we have orderedhash there... I'd like to save the order (but that is not so important) -- but more importantly, are tests robusts --- ah there is sort -n in the test... Michal Tomi -- Odesláno z mého telefonu pomocí Kaiten Mail. Omluvte prosím mou stručnost. ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [DRAFT PATCH] modified notmuch-emacs-mua
On Thu, Jul 10 2014, Tomi Ollila tomi.oll...@iki.fi wrote: Highlights: * notmuch-emacs-mua without arguments runs (notmuch-hello) * runs emacs(1) in case emacsclient(1) fails to connect to running emacs * takes -nw option * handles mailto: * --from option when sending non-mailto: way * -i includes file --body[= ]string inserts string Hi, Tomi. I think including an emacs CLI like this is probably a good idea. I might not use it myself, since I've already concocted one for my personal use, but I still think it's a good idea. The particular thing I'm interested in, though, is mailto: URL handling: + mailto:*) + oIFS=$IFS; IFS=; OPTARG=$* IFS=$oIFS + escape_optarg + exec_mua (progn (require 'notmuch) (browse-url-mail \$OPTARG\)) + exit +esac I have submitted multiple revisions of a patch that handles mailto: URLs in notmuch-mua.el: id:1334438868-17168-1-git-send-email-jroll...@finestructure.net It hasn't been accepted yet, though. I've tried browse-url-mail before, and it would be convenient to use it. However, used on it's own it has the problem that it doesn't open new message buffer in the notmuch way. For instance, I prefer my new notmuch buffers to appear in new frames. browse-url-mail doesn't respect this. Maybe it could be wrapped in a notmuch-mua-mailto function, or you could instead be using the function I submitted? I've been a bit out of touch for a while, so forgive me if anything has change that I'm not aware of. jamie. pgp9NjsOJTGDl.pgp Description: PGP signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v6 6/7] cli: search: Add --output=count
Hi Tomi, On Mon, Nov 03 2014, Tomi Ollila wrote: On Sun, Nov 02 2014, Michal Sojka sojk...@fel.cvut.cz wrote: On 2. listopadu 2014 10:29:28 CET, Mark Walters markwalters1...@gmail.com wrote: Hi On Sun, 02 Nov 2014, Michal Sojka sojk...@fel.cvut.cz wrote: On Sat, Nov 01 2014, Mark Walters wrote: On Fri, 31 Oct 2014, Michal Sojka sojk...@fel.cvut.cz wrote: This output can be used with --output=recipients or --output=sender and in addition to the addresses, it prints how many times was each address encountered during search. Hi I have a couple comments on this patch. --- completion/notmuch-completion.bash | 2 +- completion/notmuch-completion.zsh | 2 +- doc/man1/notmuch-search.rst| 9 +-- notmuch-search.c | 51 -- 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash index cfbd389..39cd829 100644 --- a/completion/notmuch-completion.bash +++ b/completion/notmuch-completion.bash @@ -294,7 +294,7 @@ _notmuch_search() return ;; --output) -COMPREPLY=( $( compgen -W summary threads messages files tags sender recipients -- ${cur} ) ) +COMPREPLY=( $( compgen -W summary threads messages files tags sender recipients count -- ${cur} ) ) return ;; --sort) diff --git a/completion/notmuch-completion.zsh b/completion/notmuch-completion.zsh index 3e52a00..d7e5a5e 100644 --- a/completion/notmuch-completion.zsh +++ b/completion/notmuch-completion.zsh @@ -53,7 +53,7 @@ _notmuch_search() '--max-threads=[display only the first x threads from the search results]:number of threads to show: ' \ '--first=[omit the first x threads from the search results]:number of threads to omit: ' \ '--sort=[sort results]:sorting:((newest-first\:reverse chronological order oldest-first\:chronological order))' \ -'--output=[select what to output]:output:((summary threads messages files tags sender recipients))' +'--output=[select what to output]:output:((summary threads messages files tags sender recipients count))' } _notmuch() diff --git a/doc/man1/notmuch-search.rst b/doc/man1/notmuch-search.rst index 42f17e4..ec89200 100644 --- a/doc/man1/notmuch-search.rst +++ b/doc/man1/notmuch-search.rst @@ -96,9 +96,14 @@ Supported options for **search** include Like **sender** but for addresses from *To*, *Cc* and *Bcc* headers. +**count** +Can be used in combination with **sender** or +**recipients** to print the count of how many times was +the address encountered during search. + This option can be given multiple times to combine different -outputs. Currently, this is only supported for **sender** and -**recipients** outputs. +outputs. Currently, this is only supported for **sender**, +**recipients** and **count** outputs. It might be worth saying that the results will be slower if count is specified. I wrote something like this in id:1414889400-30977-10-git-send-email-sojk...@fel.cvut.cz. ``--sort=``\ (**newest-first**\ \|\ **oldest-first**) I think sort works as expected if count is not specified, but does not with count. Agreed. Maybe count can be done by doing two passes? What do you mean by pass? I mean iterating through the messages twice: so the first time would fill in the count in the hash map, and the second iteration would print the addresses. That's what the patch does. Only the second time it iterates the hash. Sorry And we loose the order ? (or not ?) do we have orderedhash there... I'd like to save the order What would be the use case? If you really want to preserve the order, we could save a sequence number in mailbox_t and sort the hash table entries before printing. But this could be implemented later and enabled by a special command line option. notmuch search --output=tags does not preserve order either. (but that is not so important) -- but more importantly, are tests robusts --- ah there is sort -n in the test... Yes. -Michal ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v2 02/10] cli: search: Move more variables into search_context_t
Just refactoring, no functional changes. --- notmuch-search.c | 49 ++--- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/notmuch-search.c b/notmuch-search.c index 2c47b80..3d2012b 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -34,8 +34,18 @@ typedef enum { #define OUTPUT_ADDRESS_FLAGS (OUTPUT_SENDER | OUTPUT_RECIPIENTS) +typedef enum { +NOTMUCH_FORMAT_JSON, +NOTMUCH_FORMAT_TEXT, +NOTMUCH_FORMAT_TEXT0, +NOTMUCH_FORMAT_SEXP +} format_sel_t; + typedef struct { +notmuch_database_t *notmuch; +format_sel_t format_sel; sprinter_t *format; +notmuch_exclude_t exclude; notmuch_query_t *query; notmuch_sort_t sort; output_t output; @@ -413,14 +423,14 @@ do_search_messages (search_context_t *ctx) } static int -do_search_tags (notmuch_database_t *notmuch, - const search_context_t *ctx) +do_search_tags (const search_context_t *ctx) { notmuch_messages_t *messages = NULL; notmuch_tags_t *tags; const char *tag; sprinter_t *format = ctx-format; notmuch_query_t *query = ctx-query; +notmuch_database_t *notmuch = ctx-notmuch; /* should the following only special case if no excluded terms * specified? */ @@ -464,8 +474,9 @@ do_search_tags (notmuch_database_t *notmuch, int notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) { -notmuch_database_t *notmuch; search_context_t ctx = { + .format_sel = NOTMUCH_FORMAT_TEXT, + .exclude = NOTMUCH_EXCLUDE_TRUE, .sort = NOTMUCH_SORT_NEWEST_FIRST, .output = 0, .offset = 0, @@ -474,22 +485,14 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) }; char *query_str; int opt_index, ret; -notmuch_exclude_t exclude = NOTMUCH_EXCLUDE_TRUE; unsigned int i; -enum { - NOTMUCH_FORMAT_JSON, - NOTMUCH_FORMAT_TEXT, - NOTMUCH_FORMAT_TEXT0, - NOTMUCH_FORMAT_SEXP -} format_sel = NOTMUCH_FORMAT_TEXT; - notmuch_opt_desc_t options[] = { { NOTMUCH_OPT_KEYWORD, ctx.sort, sort, 's', (notmuch_keyword_t []){ { oldest-first, NOTMUCH_SORT_OLDEST_FIRST }, { newest-first, NOTMUCH_SORT_NEWEST_FIRST }, { 0, 0 } } }, - { NOTMUCH_OPT_KEYWORD, format_sel, format, 'f', + { NOTMUCH_OPT_KEYWORD, ctx.format_sel, format, 'f', (notmuch_keyword_t []){ { json, NOTMUCH_FORMAT_JSON }, { sexp, NOTMUCH_FORMAT_SEXP }, { text, NOTMUCH_FORMAT_TEXT }, @@ -505,7 +508,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) { files, OUTPUT_FILES }, { tags, OUTPUT_TAGS }, { 0, 0 } } }, -{ NOTMUCH_OPT_KEYWORD, exclude, exclude, 'x', +{ NOTMUCH_OPT_KEYWORD, ctx.exclude, exclude, 'x', (notmuch_keyword_t []){ { true, NOTMUCH_EXCLUDE_TRUE }, { false, NOTMUCH_EXCLUDE_FALSE }, { flag, NOTMUCH_EXCLUDE_FLAG }, @@ -530,7 +533,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) return EXIT_FAILURE; } -switch (format_sel) { +switch (ctx.format_sel) { case NOTMUCH_FORMAT_TEXT: ctx.format = sprinter_text_create (config, stdout); break; @@ -555,10 +558,10 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) notmuch_exit_if_unsupported_format (); if (notmuch_database_open (notmuch_config_get_database_path (config), - NOTMUCH_DATABASE_MODE_READ_ONLY, notmuch)) + NOTMUCH_DATABASE_MODE_READ_ONLY, ctx.notmuch)) return EXIT_FAILURE; -query_str = query_string_from_args (notmuch, argc-opt_index, argv+opt_index); +query_str = query_string_from_args (ctx.notmuch, argc-opt_index, argv+opt_index); if (query_str == NULL) { fprintf (stderr, Out of memory.\n); return EXIT_FAILURE; @@ -568,7 +571,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) return EXIT_FAILURE; } -ctx.query = notmuch_query_create (notmuch, query_str); +ctx.query = notmuch_query_create (ctx.notmuch, query_str); if (ctx.query == NULL) { fprintf (stderr, Out of memory\n); return EXIT_FAILURE; @@ -576,15 +579,15 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) notmuch_query_set_sort (ctx.query, ctx.sort); -if (exclude == NOTMUCH_EXCLUDE_FLAG ctx.output != OUTPUT_SUMMARY) { +if (ctx.exclude == NOTMUCH_EXCLUDE_FLAG ctx.output != OUTPUT_SUMMARY) { /* If we are not doing summary output there is nowhere to * print the excluded flag so fall
[PATCH v2 06/10] cli: Introduce notmuch address command
This moves address-related functionality from search command to the new address command. The implementation shares almost all code and some command line options. Options --offset and --limit were intentionally not included in the address command, because they refer to messages numbers, which users do not see in the output. This could confuse users because, for example, they could see more addresses in the output that what was specified with --limit. This functionality can be correctly reimplemented for addresses later. This was inspired by a patch from Jani Nikula. --- completion/notmuch-completion.bash | 42 ++- completion/notmuch-completion.zsh | 10 +++- doc/man1/notmuch-address.rst | 99 doc/man1/notmuch-search.rst| 20 +--- doc/man1/notmuch.rst | 7 +-- notmuch-client.h | 3 ++ notmuch-search.c | 101 + notmuch.c | 2 + 8 files changed, 228 insertions(+), 56 deletions(-) create mode 100644 doc/man1/notmuch-address.rst diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash index cfbd389..94ea2d5 100644 --- a/completion/notmuch-completion.bash +++ b/completion/notmuch-completion.bash @@ -294,7 +294,7 @@ _notmuch_search() return ;; --output) - COMPREPLY=( $( compgen -W summary threads messages files tags sender recipients -- ${cur} ) ) + COMPREPLY=( $( compgen -W summary threads messages files tags -- ${cur} ) ) return ;; --sort) @@ -320,6 +320,44 @@ _notmuch_search() esac } +_notmuch_address() +{ +local cur prev words cword split +_init_completion -s || return + +$split +case ${prev} in + --format) + COMPREPLY=( $( compgen -W json sexp text text0 -- ${cur} ) ) + return + ;; + --output) + COMPREPLY=( $( compgen -W sender recipients -- ${cur} ) ) + return + ;; + --sort) + COMPREPLY=( $( compgen -W newest-first oldest-first -- ${cur} ) ) + return + ;; + --exclude) + COMPREPLY=( $( compgen -W true false flag all -- ${cur} ) ) + return + ;; +esac + +! $split +case ${cur} in + -*) + local options=--format= --output= --sort= --exclude= + compopt -o nospace + COMPREPLY=( $(compgen -W $options -- ${cur}) ) + ;; + *) + _notmuch_search_terms + ;; +esac +} + _notmuch_show() { local cur prev words cword split @@ -393,7 +431,7 @@ _notmuch_tag() _notmuch() { -local _notmuch_commands=compact config count dump help insert new reply restore search setup show tag +local _notmuch_commands=compact config count dump help insert new reply restore search address setup show tag local arg cur prev words cword split # require bash-completion with _init_completion diff --git a/completion/notmuch-completion.zsh b/completion/notmuch-completion.zsh index 3e52a00..c606b75 100644 --- a/completion/notmuch-completion.zsh +++ b/completion/notmuch-completion.zsh @@ -10,6 +10,7 @@ _notmuch_commands() 'setup:interactively set up notmuch for first use' 'new:find and import any new message to the database' 'search:search for messages matching the search terms, display matching threads as results' +'address:get addresses from messages matching the given search terms' 'reply:constructs a reply template for a set of messages' 'show:show all messages matching the search terms' 'tag:add or remove tags for all messages matching the search terms' @@ -53,7 +54,14 @@ _notmuch_search() '--max-threads=[display only the first x threads from the search results]:number of threads to show: ' \ '--first=[omit the first x threads from the search results]:number of threads to omit: ' \ '--sort=[sort results]:sorting:((newest-first\:reverse chronological order oldest-first\:chronological order))' \ -'--output=[select what to output]:output:((summary threads messages files tags sender recipients))' +'--output=[select what to output]:output:((summary threads messages files tags))' +} + +_notmuch_address() +{ + _arguments -s : \ +'--sort=[sort results]:sorting:((newest-first\:reverse chronological order oldest-first\:chronological order))' \ +'--output=[select what to output]:output:((sender recipients))' } _notmuch() diff --git a/doc/man1/notmuch-address.rst b/doc/man1/notmuch-address.rst new file mode 100644 index 000..8109f11 --- /dev/null +++ b/doc/man1/notmuch-address.rst @@ -0,0 +1,99 @@ +=== +notmuch-address +=== + +SYNOPSIS + + +**notmuch** **address** [*option* ...] *search-term* ... + +DESCRIPTION +=== + +Search for messages matching the given
[PATCH v2 04/10] cli: search: Split notmuch_search_command to smaller functions
In the next commit, these functions will be used to share some functionality between search and address commands. --- notmuch-search.c | 155 ++- 1 file changed, 86 insertions(+), 69 deletions(-) diff --git a/notmuch-search.c b/notmuch-search.c index 6765a16..f115359 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -471,6 +471,89 @@ do_search_tags (const search_context_t *ctx) return 0; } +static int +_notmuch_search_prepare (search_context_t *ctx, notmuch_config_t *config, int argc, char *argv[]) +{ +char *query_str; +unsigned int i; + +switch (ctx-format_sel) { +case NOTMUCH_FORMAT_TEXT: + ctx-format = sprinter_text_create (config, stdout); + break; +case NOTMUCH_FORMAT_TEXT0: + if (ctx-output == OUTPUT_SUMMARY) { + fprintf (stderr, Error: --format=text0 is not compatible with --output=summary.\n); + return EXIT_FAILURE; + } + ctx-format = sprinter_text0_create (config, stdout); + break; +case NOTMUCH_FORMAT_JSON: + ctx-format = sprinter_json_create (config, stdout); + break; +case NOTMUCH_FORMAT_SEXP: + ctx-format = sprinter_sexp_create (config, stdout); + break; +default: + /* this should never happen */ + INTERNAL_ERROR(no output format selected); +} + +notmuch_exit_if_unsupported_format (); + +if (notmuch_database_open (notmuch_config_get_database_path (config), + NOTMUCH_DATABASE_MODE_READ_ONLY, ctx-notmuch)) + return EXIT_FAILURE; + +query_str = query_string_from_args (ctx-notmuch, argc, argv); +if (query_str == NULL) { + fprintf (stderr, Out of memory.\n); + return EXIT_FAILURE; +} +if (*query_str == '\0') { + fprintf (stderr, Error: notmuch search requires at least one search term.\n); + return EXIT_FAILURE; +} + +ctx-query = notmuch_query_create (ctx-notmuch, query_str); +if (ctx-query == NULL) { + fprintf (stderr, Out of memory\n); + return EXIT_FAILURE; +} + +notmuch_query_set_sort (ctx-query, ctx-sort); + +if (ctx-exclude == NOTMUCH_EXCLUDE_FLAG ctx-output != OUTPUT_SUMMARY) { + /* If we are not doing summary output there is nowhere to +* print the excluded flag so fall back on including the +* excluded messages. */ + fprintf (stderr, Warning: this output format cannot flag excluded messages.\n); + ctx-exclude = NOTMUCH_EXCLUDE_FALSE; +} + +if (ctx-exclude != NOTMUCH_EXCLUDE_FALSE) { + const char **search_exclude_tags; + size_t search_exclude_tags_length; + + search_exclude_tags = notmuch_config_get_search_exclude_tags + (config, search_exclude_tags_length); + for (i = 0; i search_exclude_tags_length; i++) + notmuch_query_add_tag_exclude (ctx-query, search_exclude_tags[i]); + notmuch_query_set_omit_excluded (ctx-query, ctx-exclude); +} + +return 0; +} + +static void +_notmuch_search_cleanup (search_context_t *ctx) +{ +notmuch_query_destroy (ctx-query); +notmuch_database_destroy (ctx-notmuch); + +talloc_free (ctx-format); +} + int notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) { @@ -484,9 +567,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) .dupe = -1, }; search_context_t *ctx = search_context; -char *query_str; int opt_index, ret; -unsigned int i; notmuch_opt_desc_t options[] = { { NOTMUCH_OPT_KEYWORD, ctx-sort, sort, 's', @@ -534,71 +615,10 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) return EXIT_FAILURE; } -switch (ctx-format_sel) { -case NOTMUCH_FORMAT_TEXT: - ctx-format = sprinter_text_create (config, stdout); - break; -case NOTMUCH_FORMAT_TEXT0: - if (ctx-output == OUTPUT_SUMMARY) { - fprintf (stderr, Error: --format=text0 is not compatible with --output=summary.\n); - return EXIT_FAILURE; - } - ctx-format = sprinter_text0_create (config, stdout); - break; -case NOTMUCH_FORMAT_JSON: - ctx-format = sprinter_json_create (config, stdout); - break; -case NOTMUCH_FORMAT_SEXP: - ctx-format = sprinter_sexp_create (config, stdout); - break; -default: - /* this should never happen */ - INTERNAL_ERROR(no output format selected); -} - -notmuch_exit_if_unsupported_format (); - -if (notmuch_database_open (notmuch_config_get_database_path (config), - NOTMUCH_DATABASE_MODE_READ_ONLY, ctx-notmuch)) +if (_notmuch_search_prepare (ctx, config, +argc - opt_index, argv + opt_index)) return EXIT_FAILURE; -query_str = query_string_from_args (ctx-notmuch, argc-opt_index, argv+opt_index); -if (query_str == NULL) { -
[PATCH v2 01/10] cli: search: Rename options to context
Just text replacement, no other changes. --- notmuch-search.c | 142 +++ 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/notmuch-search.c b/notmuch-search.c index 6345fb6..2c47b80 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -42,7 +42,7 @@ typedef struct { int offset; int limit; int dupe; -} search_options_t; +} search_context_t; typedef struct { const char *name; @@ -89,39 +89,39 @@ get_thread_query (notmuch_thread_t *thread, } static int -do_search_threads (search_options_t *opt) +do_search_threads (search_context_t *ctx) { notmuch_thread_t *thread; notmuch_threads_t *threads; notmuch_tags_t *tags; -sprinter_t *format = opt-format; +sprinter_t *format = ctx-format; time_t date; int i; -if (opt-offset 0) { - opt-offset += notmuch_query_count_threads (opt-query); - if (opt-offset 0) - opt-offset = 0; +if (ctx-offset 0) { + ctx-offset += notmuch_query_count_threads (ctx-query); + if (ctx-offset 0) + ctx-offset = 0; } -threads = notmuch_query_search_threads (opt-query); +threads = notmuch_query_search_threads (ctx-query); if (threads == NULL) return 1; format-begin_list (format); for (i = 0; -notmuch_threads_valid (threads) (opt-limit 0 || i opt-offset + opt-limit); +notmuch_threads_valid (threads) (ctx-limit 0 || i ctx-offset + ctx-limit); notmuch_threads_move_to_next (threads), i++) { thread = notmuch_threads_get (threads); - if (i opt-offset) { + if (i ctx-offset) { notmuch_thread_destroy (thread); continue; } - if (opt-output == OUTPUT_THREADS) { + if (ctx-output == OUTPUT_THREADS) { format-set_prefix (format, thread); format-string (format, notmuch_thread_get_thread_id (thread)); @@ -138,7 +138,7 @@ do_search_threads (search_options_t *opt) format-begin_map (format); - if (opt-sort == NOTMUCH_SORT_OLDEST_FIRST) + if (ctx-sort == NOTMUCH_SORT_OLDEST_FIRST) date = notmuch_thread_get_oldest_date (thread); else date = notmuch_thread_get_newest_date (thread); @@ -230,11 +230,11 @@ do_search_threads (search_options_t *opt) } static void -print_mailbox (const search_options_t *opt, const mailbox_t *mailbox) +print_mailbox (const search_context_t *ctx, const mailbox_t *mailbox) { const char *name = mailbox-name; const char *addr = mailbox-addr; -sprinter_t *format = opt-format; +sprinter_t *format = ctx-format; InternetAddress *ia = internet_address_mailbox_new (name, addr); char *name_addr; @@ -263,7 +263,7 @@ print_mailbox (const search_options_t *opt, const mailbox_t *mailbox) /* Print addresses from InternetAddressList. */ static void -process_address_list (const search_options_t *opt, InternetAddressList *list) +process_address_list (const search_context_t *ctx, InternetAddressList *list) { InternetAddress *address; int i; @@ -279,7 +279,7 @@ process_address_list (const search_options_t *opt, InternetAddressList *list) if (group_list == NULL) continue; - process_address_list (opt, group_list); + process_address_list (ctx, group_list); } else { InternetAddressMailbox *mailbox = INTERNET_ADDRESS_MAILBOX (address); mailbox_t mbx = { @@ -287,14 +287,14 @@ process_address_list (const search_options_t *opt, InternetAddressList *list) .addr = internet_address_mailbox_get_addr (mailbox), }; - print_mailbox (opt, mbx); + print_mailbox (ctx, mbx); } } } /* Print addresses from a message header. */ static void -process_address_header (const search_options_t *opt, const char *value) +process_address_header (const search_context_t *ctx, const char *value) { InternetAddressList *list; @@ -305,7 +305,7 @@ process_address_header (const search_options_t *opt, const char *value) if (list == NULL) return; -process_address_list (opt, list); +process_address_list (ctx, list); g_object_unref (list); } @@ -329,36 +329,36 @@ _count_filenames (notmuch_message_t *message) } static int -do_search_messages (search_options_t *opt) +do_search_messages (search_context_t *ctx) { notmuch_message_t *message; notmuch_messages_t *messages; notmuch_filenames_t *filenames; -sprinter_t *format = opt-format; +sprinter_t *format = ctx-format; int i; -if (opt-offset 0) { - opt-offset += notmuch_query_count_messages (opt-query); - if (opt-offset 0) - opt-offset = 0; +if (ctx-offset 0) { + ctx-offset += notmuch_query_count_messages (ctx-query); + if
[PATCH v2 00/10] notmuch address command
Hi all, this is v2 of notmuch address patchset. It obsoletes [1]. Don't be scared by the number of patches. Most of them are trivial refactoring. Patches 1-4 refactor the code so that notmuch search command is easier to split. Patch 5 is Jani's hierarchical command line parsing patch. Patch 6 splits search functionality to new address command. Patch 7 is minor refactoring. Patches 8-10 correspond to patches 5-7 in the original notmuch search --output=sender/recipients patch series [2]. Changes from v1: - Rebased to current master (conflicted with Jani's notmuch search --duplicate=N with --output=messages patch) - Fixed printing of false Unrecognized option error message in hierarchical command line parser. Regards, -Michal [1] id:1414889400-30977-1-git-send-email-sojk...@fel.cvut.cz [2] id:1414792441-29555-1-git-send-email-sojk...@fel.cvut.cz Jani Nikula (1): cli: add support for hierarchical command line option arrays Michal Sojka (9): cli: search: Rename options to context cli: search: Move more variables into search_context_t cli: search: Convert ctx. to ctx- cli: search: Split notmuch_search_command to smaller functions cli: Introduce notmuch address command cli: search: Convert --output to keyword argument cli: address: Do not output duplicate addresses cli: address: Add --output=count cli: address: Add --filter-by option to configure address filtering command-line-arguments.c | 16 +- command-line-arguments.h | 1 + completion/notmuch-completion.bash | 48 +++- completion/notmuch-completion.zsh | 11 +- doc/man1/notmuch-address.rst | 140 doc/man1/notmuch-search.rst| 21 +- doc/man1/notmuch.rst | 7 +- notmuch-client.h | 3 + notmuch-search.c | 454 + notmuch.c | 2 + test/T095-address.sh | 148 test/T097-address-filter-by.sh | 73 ++ 12 files changed, 751 insertions(+), 173 deletions(-) create mode 100644 doc/man1/notmuch-address.rst create mode 100755 test/T095-address.sh create mode 100755 test/T097-address-filter-by.sh -- 2.1.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v2 08/10] cli: address: Do not output duplicate addresses
This filters out duplicate addresses from address command output. It also also adds tests for the address command. The code here is an extended version of a patch from Jani Nikula. --- doc/man1/notmuch-address.rst | 2 +- notmuch-search.c | 40 - test/T095-address.sh | 100 +++ 3 files changed, 140 insertions(+), 2 deletions(-) create mode 100755 test/T095-address.sh diff --git a/doc/man1/notmuch-address.rst b/doc/man1/notmuch-address.rst index 8109f11..96512b7 100644 --- a/doc/man1/notmuch-address.rst +++ b/doc/man1/notmuch-address.rst @@ -11,7 +11,7 @@ DESCRIPTION === Search for messages matching the given search terms, and display the -addresses from them. +addresses from them. Duplicate addresses are filtered out. See **notmuch-search-terms(7)** for details of the supported syntax for search-terms. diff --git a/notmuch-search.c b/notmuch-search.c index 402e860..741702a 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -53,6 +53,7 @@ typedef struct { int offset; int limit; int dupe; +GHashTable *addresses; } search_context_t; typedef struct { @@ -240,6 +241,27 @@ do_search_threads (search_context_t *ctx) return 0; } +/* Returns TRUE iff name and addr is duplicate. */ +static notmuch_bool_t +is_duplicate (const search_context_t *ctx, const char *name, const char *addr) +{ +notmuch_bool_t duplicate; +char *key; + +key = talloc_asprintf (ctx-format, %s %s, name, addr); +if (! key) + return FALSE; + +duplicate = g_hash_table_lookup_extended (ctx-addresses, key, NULL, NULL); + +if (! duplicate) + g_hash_table_insert (ctx-addresses, key, NULL); +else + talloc_free (key); + +return duplicate; +} + static void print_mailbox (const search_context_t *ctx, const mailbox_t *mailbox) { @@ -274,7 +296,8 @@ print_mailbox (const search_context_t *ctx, const mailbox_t *mailbox) /* Print addresses from InternetAddressList. */ static void -process_address_list (const search_context_t *ctx, InternetAddressList *list) +process_address_list (const search_context_t *ctx, + InternetAddressList *list) { InternetAddress *address; int i; @@ -298,6 +321,9 @@ process_address_list (const search_context_t *ctx, InternetAddressList *list) .addr = internet_address_mailbox_get_addr (mailbox), }; + if (is_duplicate (ctx, mbx.name, mbx.addr)) + continue; + print_mailbox (ctx, mbx); } } @@ -321,6 +347,12 @@ process_address_header (const search_context_t *ctx, const char *value) g_object_unref (list); } +static void +_my_talloc_free_for_g_hash (void *ptr) +{ +talloc_free (ptr); +} + static int _count_filenames (notmuch_message_t *message) { @@ -669,8 +701,14 @@ notmuch_address_command (notmuch_config_t *config, int argc, char *argv[]) argc - opt_index, argv + opt_index)) return EXIT_FAILURE; +ctx-addresses = g_hash_table_new_full (g_str_hash, g_str_equal, + _my_talloc_free_for_g_hash, NULL); + ret = do_search_messages (ctx); +g_hash_table_unref (ctx-addresses); + + _notmuch_search_cleanup (ctx); return ret ? EXIT_FAILURE : EXIT_SUCCESS; diff --git a/test/T095-address.sh b/test/T095-address.sh new file mode 100755 index 000..8a256d2 --- /dev/null +++ b/test/T095-address.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash +test_description='notmuch address in several variants' +. ./test-lib.sh + +add_email_corpus + +test_begin_subtest --output=sender +notmuch address --output=sender '*' OUTPUT +cat EOF EXPECTED +François Boulogne boulogn...@gmail.com +Olivier Berger olivier.ber...@it-sudparis.eu +Chris Wilson ch...@chris-wilson.co.uk +Carl Worth cwo...@cworth.org +Alexander Botero-Lowry alex.boterolo...@gmail.com +Keith Packard kei...@keithp.com +Jjgod Jiang gzjj...@gmail.com +Rolland Santimano rollandsantim...@yahoo.com +Jan Janak j...@ryngle.com +Stewart Smith stew...@flamingspork.com +Lars Kellogg-Stedman l...@seas.harvard.edu +Alex Botero-Lowry alex.boterolo...@gmail.com +Ingmar Vanhassel ing...@exherbo.org +Aron Griffis agrif...@n01se.net +Adrian Perez de Castro ape...@igalia.com +Israel Herraiz i...@herraiz.org +Mikhail Gusarov dotted...@dottedmag.net +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest --output=sender --format=json +notmuch address --output=sender --format=json '*' OUTPUT +cat EOF EXPECTED +[{name: François Boulogne, address: boulogn...@gmail.com, name-addr: François Boulogne boulogn...@gmail.com}, +{name: Olivier Berger, address: olivier.ber...@it-sudparis.eu, name-addr: Olivier Berger olivier.ber...@it-sudparis.eu}, +{name: Chris Wilson, address: ch...@chris-wilson.co.uk, name-addr: Chris Wilson ch...@chris-wilson.co.uk}, +{name: Carl Worth, address: cwo...@cworth.org,
[PATCH v2 09/10] cli: address: Add --output=count
This output prints how many times was each address encountered during search. --- completion/notmuch-completion.bash | 2 +- completion/notmuch-completion.zsh | 2 +- doc/man1/notmuch-address.rst | 7 ++ notmuch-search.c | 49 -- test/T095-address.sh | 48 + 5 files changed, 99 insertions(+), 9 deletions(-) diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash index 94ea2d5..db152f3 100644 --- a/completion/notmuch-completion.bash +++ b/completion/notmuch-completion.bash @@ -332,7 +332,7 @@ _notmuch_address() return ;; --output) - COMPREPLY=( $( compgen -W sender recipients -- ${cur} ) ) + COMPREPLY=( $( compgen -W sender recipients count -- ${cur} ) ) return ;; --sort) diff --git a/completion/notmuch-completion.zsh b/completion/notmuch-completion.zsh index c606b75..8968562 100644 --- a/completion/notmuch-completion.zsh +++ b/completion/notmuch-completion.zsh @@ -61,7 +61,7 @@ _notmuch_address() { _arguments -s : \ '--sort=[sort results]:sorting:((newest-first\:reverse chronological order oldest-first\:chronological order))' \ -'--output=[select what to output]:output:((sender recipients))' +'--output=[select what to output]:output:((sender recipients count))' } _notmuch() diff --git a/doc/man1/notmuch-address.rst b/doc/man1/notmuch-address.rst index 96512b7..18473a7 100644 --- a/doc/man1/notmuch-address.rst +++ b/doc/man1/notmuch-address.rst @@ -48,6 +48,13 @@ Supported options for **address** include Output all addresses from the *To*, *Cc* and *Bcc* headers. + **count** + Print the count of how many times was the address + encountered during search. + + Note: With this option, addresses are printed only after + the whole search is finished. This may take long time. + ``--sort=``\ (**newest-first**\ \|\ **oldest-first**) This option can be used to present results in either chronological order (**oldest-first**) or reverse chronological diff --git a/notmuch-search.c b/notmuch-search.c index 741702a..d99e530 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -33,6 +33,7 @@ typedef enum { /* Address command */ OUTPUT_SENDER = 1 5, OUTPUT_RECIPIENTS = 1 6, +OUTPUT_COUNT = 1 7, } output_t; typedef enum { @@ -59,6 +60,7 @@ typedef struct { typedef struct { const char *name; const char *addr; +int count; } mailbox_t; /* Return two stable query strings that identify exactly the matched @@ -247,17 +249,24 @@ is_duplicate (const search_context_t *ctx, const char *name, const char *addr) { notmuch_bool_t duplicate; char *key; +mailbox_t *mailbox; key = talloc_asprintf (ctx-format, %s %s, name, addr); if (! key) return FALSE; -duplicate = g_hash_table_lookup_extended (ctx-addresses, key, NULL, NULL); +duplicate = g_hash_table_lookup_extended (ctx-addresses, key, NULL, (gpointer)mailbox); -if (! duplicate) - g_hash_table_insert (ctx-addresses, key, NULL); -else +if (! duplicate) { + mailbox = talloc (ctx-format, mailbox_t); + mailbox-name = talloc_strdup (mailbox, name); + mailbox-addr = talloc_strdup (mailbox, addr); + mailbox-count = 1; + g_hash_table_insert (ctx-addresses, key, mailbox); +} else { + mailbox-count++; talloc_free (key); +} return duplicate; } @@ -267,6 +276,7 @@ print_mailbox (const search_context_t *ctx, const mailbox_t *mailbox) { const char *name = mailbox-name; const char *addr = mailbox-addr; +int count = mailbox-count; sprinter_t *format = ctx-format; InternetAddress *ia = internet_address_mailbox_new (name, addr); char *name_addr; @@ -276,6 +286,10 @@ print_mailbox (const search_context_t *ctx, const mailbox_t *mailbox) name_addr = internet_address_to_string (ia, FALSE); if (format-is_text_printer) { + if (count 0) { + format-integer (format, count); + format-string (format, \t); + } format-string (format, name_addr); format-separator (format); } else { @@ -286,6 +300,10 @@ print_mailbox (const search_context_t *ctx, const mailbox_t *mailbox) format-string (format, addr); format-map_key (format, name-addr); format-string (format, name_addr); + if (count 0) { + format-map_key (format, count); + format-integer (format, count); + } format-end (format); format-separator (format); } @@ -294,7 +312,7 @@ print_mailbox (const search_context_t *ctx, const mailbox_t *mailbox) g_free (name_addr); } -/* Print addresses from InternetAddressList. */ +/* Print or prepare for printing
[PATCH v2 05/10] cli: add support for hierarchical command line option arrays
From: Jani Nikula j...@nikula.org NOTMUCH_OPT_INHERIT expects a notmuch_opt_desc_t * pointer in output_var. The Unrecognized option message was moved out of parse_option() to not be emitted twice or when parsing a non-inherited option. --- command-line-arguments.c | 16 +--- command-line-arguments.h | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/command-line-arguments.c b/command-line-arguments.c index c6f7269..de6b453 100644 --- a/command-line-arguments.c +++ b/command-line-arguments.c @@ -122,16 +122,18 @@ parse_position_arg (const char *arg_str, int pos_arg_index, */ notmuch_bool_t -parse_option (const char *arg, - const notmuch_opt_desc_t *options) { - -assert(arg); +parse_option (const char *_arg, const notmuch_opt_desc_t *options) +{ +assert(_arg); assert(options); -arg += 2; - +const char *arg = _arg + 2; /* _arg starts with -- */ const notmuch_opt_desc_t *try; for (try = options; try-opt_type != NOTMUCH_OPT_END; try++) { + if (try-opt_type == NOTMUCH_OPT_INHERIT + parse_option (_arg, try-output_var)) + return TRUE; + if (! try-name) continue; @@ -170,7 +172,6 @@ parse_option (const char *arg, /*UNREACHED*/ } } -fprintf (stderr, Unrecognized option: --%s\n, arg); return FALSE; } @@ -201,6 +202,7 @@ parse_arguments (int argc, char **argv, if (more_args) { opt_index++; } else { + fprintf (stderr, Unrecognized option: %s\n, argv[opt_index]); opt_index = -1; } diff --git a/command-line-arguments.h b/command-line-arguments.h index 6444129..309aaf2 100644 --- a/command-line-arguments.h +++ b/command-line-arguments.h @@ -5,6 +5,7 @@ enum notmuch_opt_type { NOTMUCH_OPT_END = 0, +NOTMUCH_OPT_INHERIT, /* another options table */ NOTMUCH_OPT_BOOLEAN, /* --verbose */ NOTMUCH_OPT_INT, /* --frob=8 */ NOTMUCH_OPT_KEYWORD, /* --format=raw|json|text */ -- 2.1.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v2 03/10] cli: search: Convert ctx. to ctx-
Mostly text replacement. --- notmuch-search.c | 81 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/notmuch-search.c b/notmuch-search.c index 3d2012b..6765a16 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -474,7 +474,7 @@ do_search_tags (const search_context_t *ctx) int notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) { -search_context_t ctx = { +search_context_t search_context = { .format_sel = NOTMUCH_FORMAT_TEXT, .exclude = NOTMUCH_EXCLUDE_TRUE, .sort = NOTMUCH_SORT_NEWEST_FIRST, @@ -483,23 +483,24 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) .limit = -1, /* unlimited */ .dupe = -1, }; +search_context_t *ctx = search_context; char *query_str; int opt_index, ret; unsigned int i; notmuch_opt_desc_t options[] = { - { NOTMUCH_OPT_KEYWORD, ctx.sort, sort, 's', + { NOTMUCH_OPT_KEYWORD, ctx-sort, sort, 's', (notmuch_keyword_t []){ { oldest-first, NOTMUCH_SORT_OLDEST_FIRST }, { newest-first, NOTMUCH_SORT_NEWEST_FIRST }, { 0, 0 } } }, - { NOTMUCH_OPT_KEYWORD, ctx.format_sel, format, 'f', + { NOTMUCH_OPT_KEYWORD, ctx-format_sel, format, 'f', (notmuch_keyword_t []){ { json, NOTMUCH_FORMAT_JSON }, { sexp, NOTMUCH_FORMAT_SEXP }, { text, NOTMUCH_FORMAT_TEXT }, { text0, NOTMUCH_FORMAT_TEXT0 }, { 0, 0 } } }, { NOTMUCH_OPT_INT, notmuch_format_version, format-version, 0, 0 }, - { NOTMUCH_OPT_KEYWORD_FLAGS, ctx.output, output, 'o', + { NOTMUCH_OPT_KEYWORD_FLAGS, ctx-output, output, 'o', (notmuch_keyword_t []){ { summary, OUTPUT_SUMMARY }, { threads, OUTPUT_THREADS }, { messages, OUTPUT_MESSAGES }, @@ -508,15 +509,15 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) { files, OUTPUT_FILES }, { tags, OUTPUT_TAGS }, { 0, 0 } } }, -{ NOTMUCH_OPT_KEYWORD, ctx.exclude, exclude, 'x', +{ NOTMUCH_OPT_KEYWORD, ctx-exclude, exclude, 'x', (notmuch_keyword_t []){ { true, NOTMUCH_EXCLUDE_TRUE }, { false, NOTMUCH_EXCLUDE_FALSE }, { flag, NOTMUCH_EXCLUDE_FLAG }, { all, NOTMUCH_EXCLUDE_ALL }, { 0, 0 } } }, - { NOTMUCH_OPT_INT, ctx.offset, offset, 'O', 0 }, - { NOTMUCH_OPT_INT, ctx.limit, limit, 'L', 0 }, - { NOTMUCH_OPT_INT, ctx.dupe, duplicate, 'D', 0 }, + { NOTMUCH_OPT_INT, ctx-offset, offset, 'O', 0 }, + { NOTMUCH_OPT_INT, ctx-limit, limit, 'L', 0 }, + { NOTMUCH_OPT_INT, ctx-dupe, duplicate, 'D', 0 }, { 0, 0, 0, 0, 0 } }; @@ -524,31 +525,31 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) if (opt_index 0) return EXIT_FAILURE; -if (! ctx.output) - ctx.output = OUTPUT_SUMMARY; +if (! ctx-output) + ctx-output = OUTPUT_SUMMARY; -if (ctx.output != OUTPUT_FILES ctx.output != OUTPUT_MESSAGES - ctx.dupe != -1) { +if (ctx-output != OUTPUT_FILES ctx-output != OUTPUT_MESSAGES + ctx-dupe != -1) { fprintf (stderr, Error: --duplicate=N is only supported with --output=files and --output=messages.\n); return EXIT_FAILURE; } -switch (ctx.format_sel) { +switch (ctx-format_sel) { case NOTMUCH_FORMAT_TEXT: - ctx.format = sprinter_text_create (config, stdout); + ctx-format = sprinter_text_create (config, stdout); break; case NOTMUCH_FORMAT_TEXT0: - if (ctx.output == OUTPUT_SUMMARY) { + if (ctx-output == OUTPUT_SUMMARY) { fprintf (stderr, Error: --format=text0 is not compatible with --output=summary.\n); return EXIT_FAILURE; } - ctx.format = sprinter_text0_create (config, stdout); + ctx-format = sprinter_text0_create (config, stdout); break; case NOTMUCH_FORMAT_JSON: - ctx.format = sprinter_json_create (config, stdout); + ctx-format = sprinter_json_create (config, stdout); break; case NOTMUCH_FORMAT_SEXP: - ctx.format = sprinter_sexp_create (config, stdout); + ctx-format = sprinter_sexp_create (config, stdout); break; default: /* this should never happen */ @@ -558,10 +559,10 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) notmuch_exit_if_unsupported_format (); if (notmuch_database_open (notmuch_config_get_database_path (config), -
[PATCH v2 07/10] cli: search: Convert --output to keyword argument
Now, when address related outputs are in a separate command, it makes no sense to combine multiple --output options in search command line. Using switch statement to handle different outputs is more readable than a series of if statements. --- doc/man1/notmuch-search.rst | 3 --- notmuch-search.c| 25 + 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/doc/man1/notmuch-search.rst b/doc/man1/notmuch-search.rst index 65df288..0cc2911 100644 --- a/doc/man1/notmuch-search.rst +++ b/doc/man1/notmuch-search.rst @@ -78,9 +78,6 @@ Supported options for **search** include by null characters (--format=text0), as a JSON array (--format=json), or as an S-Expression list (--format=sexp). - This option can be given multiple times to combine different - outputs. - ``--sort=``\ (**newest-first**\ \|\ **oldest-first**) This option can be used to present results in either chronological order (**oldest-first**) or reverse chronological diff --git a/notmuch-search.c b/notmuch-search.c index cbd84f5..402e860 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -593,7 +593,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) int opt_index, ret; notmuch_opt_desc_t options[] = { - { NOTMUCH_OPT_KEYWORD_FLAGS, ctx-output, output, 'o', + { NOTMUCH_OPT_KEYWORD, ctx-output, output, 'o', (notmuch_keyword_t []){ { summary, OUTPUT_SUMMARY }, { threads, OUTPUT_THREADS }, { messages, OUTPUT_MESSAGES }, @@ -607,13 +607,11 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) { 0, 0, 0, 0, 0 } }; +ctx-output = OUTPUT_SUMMARY; opt_index = parse_arguments (argc, argv, options, 1); if (opt_index 0) return EXIT_FAILURE; -if (! ctx-output) - ctx-output = OUTPUT_SUMMARY; - if (ctx-output != OUTPUT_FILES ctx-output != OUTPUT_MESSAGES ctx-dupe != -1) { fprintf (stderr, Error: --duplicate=N is only supported with --output=files and --output=messages.\n); @@ -624,17 +622,20 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) argc - opt_index, argv + opt_index)) return EXIT_FAILURE; -if (ctx-output == OUTPUT_SUMMARY || - ctx-output == OUTPUT_THREADS) +switch (ctx-output) { +case OUTPUT_SUMMARY: +case OUTPUT_THREADS: ret = do_search_threads (ctx); -else if (ctx-output == OUTPUT_MESSAGES || -ctx-output == OUTPUT_FILES) + break; +case OUTPUT_MESSAGES: +case OUTPUT_FILES: ret = do_search_messages (ctx); -else if (ctx-output == OUTPUT_TAGS) + break; +case OUTPUT_TAGS: ret = do_search_tags (ctx); -else { - fprintf (stderr, Error: the combination of outputs is not supported.\n); - ret = 1; + break; +default: + INTERNAL_ERROR (Unexpected output); } _notmuch_search_cleanup (ctx); -- 2.1.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v2 01/10] cli: search: Rename options to context
Michal Sojka sojk...@fel.cvut.cz writes: Just text replacement, no other changes. I agree that the actual change is trivial, but the commit message could/should hint why it is being done. ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v2 03/10] cli: search: Convert ctx. to ctx-
Michal Sojka sojk...@fel.cvut.cz writes: Mostly text replacement. Here I'd like to know why we are moving from a struct to a pointer to struct. It would be a bonus to hightlight any non text-replacement. ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v2 05/10] cli: add support for hierarchical command line option arrays
Michal Sojka sojk...@fel.cvut.cz writes: From: Jani Nikula j...@nikula.org NOTMUCH_OPT_INHERIT expects a notmuch_opt_desc_t * pointer in output_var. At the risk of bikeshedding, what about NOTMUCH_OPT_RECURSE instead of _INHERIT? ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v2 05/10] cli: add support for hierarchical command line option arrays
David Bremner da...@tethera.net writes: Michal Sojka sojk...@fel.cvut.cz writes: From: Jani Nikula j...@nikula.org NOTMUCH_OPT_INHERIT expects a notmuch_opt_desc_t * pointer in output_var. At the risk of bikeshedding, what about NOTMUCH_OPT_RECURSE instead of _INHERIT? Hrm. Now that I read the next patch, I retract my suggestion. d ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v2 06/10] cli: Introduce notmuch address command
Michal Sojka sojk...@fel.cvut.cz writes: +{ +local cur prev words cword split +_init_completion -s || return + +$split +case ${prev} in + --format) + COMPREPLY=( $( compgen -W json sexp text text0 -- ${cur} ) ) + return + ;; + --output) + COMPREPLY=( $( compgen -W sender recipients -- ${cur} ) ) + return + ;; + --sort) + COMPREPLY=( $( compgen -W newest-first oldest-first -- ${cur} ) ) + return + ;; + --exclude) + COMPREPLY=( $( compgen -W true false flag all -- ${cur} ) ) + return + ;; +esac + +! $split +case ${cur} in + -*) + local options=--format= --output= --sort= --exclude= + compopt -o nospace + COMPREPLY=( $(compgen -W $options -- ${cur}) ) + ;; + *) + _notmuch_search_terms + ;; +esac +} + I am reminded that we have no tests for shell completion stuff, which seems pretty fragile. + +``--format=``\ (**json**\ \|\ **sexp**\ \|\ **text**\ \|\ **text0**) +Presents the results in either JSON, S-Expressions, newline +character separated plain-text (default), or null character +separated plain-text (compatible with **xargs(1)** -0 option +where available). + +``--format-version=N`` +Use the specified structured output format version. This is +intended for programs that invoke **notmuch(1)** internally. If +omitted, the latest supported version will be used. + I wonder if at some point we should have a notmuch-output-formats.7 page. +``--exclude=(true|false|all|flag)`` +A message is called excluded if it matches at least one tag in +search.tag\_exclude that does not appear explicitly in the +search terms. This option specifies whether to omit excluded +messages in the search process. Similarly for excludes. I'm ok with the duplication for now, and I can see an argument for not making the user chase references. ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v2 08/10] cli: address: Do not output duplicate addresses
Michal Sojka sojk...@fel.cvut.cz writes: +/* Returns TRUE iff name and addr is duplicate. */ If you're revising this patch, it would be good to mention the side effect of this function. -process_address_list (const search_context_t *ctx, InternetAddressList *list) +process_address_list (const search_context_t *ctx, + InternetAddressList *list) It probably doesn't make any difference, but this looks like a needless whitespace change. This function definitely needs some comment / pointer to documention. And probably not to have _my in the name. +static void +_my_talloc_free_for_g_hash (void *ptr) +{ +talloc_free (ptr); +} + I don't understand the name of the next subtest +test_begin_subtest No --output +notmuch address --output=sender --output=recipients '*' OUTPUT +# Use EXPECTED from previous subtest +test_expect_equal_file OUTPUT EXPECTED + + +test_done nitpick, extra blank lines So, AIUI, this is all of the series proposed for 0.19. It looks close to OK to me, modulo some minor style nits. One anonymous commentator on IRC mentioned the use of module scope variables, I guess in patch 6/10. I'm not sure of a better solution, but it's true in a perfect world we wouldn't have module local state. d ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch