[WIP 2/2] cli: search: multithread
--- notmuch-search.c | 19 +++ 1 files changed, 19 insertions(+), 0 deletions(-) diff --git a/notmuch-search.c b/notmuch-search.c index f6061e4..2fa4231 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -436,6 +436,9 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) int offset = 0; int limit = -1; /* unlimited */ notmuch_bool_t no_exclude = FALSE; +notmuch_bool_t secondary_search = FALSE; +char *secondary_search_terms = NULL; +notmuch_ss_conjunction_t ss_conjunction = NOTMUCH_SECONDARY_SEARCH_NONE; unsigned int i; enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT } @@ -458,6 +461,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) { "tags", OUTPUT_TAGS }, { 0, 0 } } }, { NOTMUCH_OPT_BOOLEAN, _exclude, "no-exclude", 'd', 0 }, + { NOTMUCH_OPT_BOOLEAN, _search, "secondary-search", 'd', 0 }, { NOTMUCH_OPT_INT, , "offset", 'O', 0 }, { NOTMUCH_OPT_INT, , "limit", 'L', 0 }, { 0, 0, 0, 0, 0 } @@ -478,6 +482,18 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) break; } +if (secondary_search && argc-opt_index >= 2 ) { + if (strcmp (argv[argc - 2], ":AND:") == 0) + ss_conjunction = NOTMUCH_SECONDARY_SEARCH_AND; + if (strcmp (argv[argc - 2], ":AND_NOT:") == 0) + ss_conjunction = NOTMUCH_SECONDARY_SEARCH_AND_NOT; + + if (ss_conjunction != NOTMUCH_SECONDARY_SEARCH_NONE) { + secondary_search_terms = argv[argc - 1]; + argc -= 2; + } +} + config = notmuch_config_open (ctx, NULL, NULL); if (config == NULL) return 1; @@ -505,6 +521,9 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) notmuch_query_set_sort (query, sort); +if (secondary_search_terms) + notmuch_query_set_secondary_search (query, secondary_search_terms, ss_conjunction); + if (!no_exclude) { const char **search_exclude_tags; size_t search_exclude_tags_length; -- 1.7.9.1
[WIP 1/2] lib: multithread
--- lib/notmuch.h | 12 lib/query.cc | 46 +- 2 files changed, 57 insertions(+), 1 deletions(-) diff --git a/lib/notmuch.h b/lib/notmuch.h index babd208..22dd69e 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -445,6 +445,18 @@ typedef enum { NOTMUCH_SORT_UNSORTED } notmuch_sort_t; +/* Values for notmuch_query_secondary_search_conjunction */ +typedef enum { +NOTMUCH_SECONDARY_SEARCH_NONE, +NOTMUCH_SECONDARY_SEARCH_AND, +NOTMUCH_SECONDARY_SEARCH_AND_NOT +} notmuch_ss_conjunction_t; + +void +notmuch_query_set_secondary_search (notmuch_query_t *query, + const char *secondary_search_terms, + notmuch_ss_conjunction_t conjunction); + /* Return the query_string of this query. See notmuch_query_create. */ const char * notmuch_query_get_query_string (notmuch_query_t *query); diff --git a/lib/query.cc b/lib/query.cc index 68ac1e4..0faef51 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -26,6 +26,8 @@ struct _notmuch_query { notmuch_database_t *notmuch; const char *query_string; +const char *secondary_search_terms; +notmuch_ss_conjunction_t ss_conjunction; notmuch_sort_t sort; notmuch_string_list_t *exclude_terms; notmuch_bool_t omit_excluded_messages; @@ -92,6 +94,8 @@ notmuch_query_create (notmuch_database_t *notmuch, query->exclude_terms = _notmuch_string_list_create (query); +query->secondary_search_terms = NULL; + query->omit_excluded_messages = FALSE; return query; @@ -122,6 +126,15 @@ notmuch_query_get_sort (notmuch_query_t *query) } void +notmuch_query_set_secondary_search (notmuch_query_t *query, + const char *secondary_search_terms, + notmuch_ss_conjunction_t conjunction) +{ +query->secondary_search_terms = talloc_strdup (query, secondary_search_terms); +query->ss_conjunction = conjunction; +} + +void notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag) { char *term = talloc_asprintf (query, "%s%s", _find_prefix ("tag"), tag); @@ -454,6 +467,36 @@ notmuch_query_destroy (notmuch_query_t *query) talloc_free (query); } +/* This function tests whether the thread containing document with id + * seed_doc_id satisfies the secondary search terms of query.*/ +notmuch_bool_t +notmuch_thread_test_secondary_search (notmuch_query_t *query, unsigned int seed_doc_id) +{ +int count; +notmuch_message_t *seed_message; +const char *thread_id; +char *thread_id_query_string; +notmuch_query_t *thread_id_query; + +if (!query->secondary_search_terms) return TRUE; +seed_message = _notmuch_message_create (query, query->notmuch, seed_doc_id, NULL); + +thread_id = notmuch_message_get_thread_id (seed_message); +thread_id_query_string = talloc_asprintf (query, "thread:%s and %s", + thread_id, + query->secondary_search_terms); +thread_id_query = notmuch_query_create (query->notmuch, thread_id_query_string); +count = notmuch_query_count_messages (thread_id_query); +switch (query->ss_conjunction) { +case NOTMUCH_SECONDARY_SEARCH_AND: + return (count > 0); +case NOTMUCH_SECONDARY_SEARCH_AND_NOT: + return (count == 0); +default: + return TRUE; +} +} + notmuch_bool_t notmuch_threads_valid (notmuch_threads_t *threads) { @@ -462,7 +505,8 @@ notmuch_threads_valid (notmuch_threads_t *threads) while (threads->doc_id_pos < threads->doc_ids->len) { doc_id = g_array_index (threads->doc_ids, unsigned int, threads->doc_id_pos); - if (_notmuch_doc_id_set_contains (>match_set, doc_id)) + if (_notmuch_doc_id_set_contains (>match_set, doc_id) && + notmuch_thread_test_secondary_search (threads->query, doc_id)) break; threads->doc_id_pos++; -- 1.7.9.1
[WIP 0/2] Thread based searching
This is very definitely only a work in progress but there have been several requests for this or something similar on irc. It implements a very crude form of thread based search: the user can ask for all the threads that have a message matching the primary query and have a (possibly different) message matching a secondary query. For example notmuch search --secondary-search from:A :AND: from:B returns all threads that have a message from A and a message from B. Similarly it allows the user to say "and not" on a thread based way. For example notmuch search --secondary-search from:A :AND_NOT: tag:mute returns all threads that have a message from A and no message with tag:mute. Anything allowing queries of this form is going to have to do some parsing of the query (rather than leaving this to xapian). To keep things as simple as possible this version only tries parsing of this form if passed --secondary-search and it assumes the last command line argument is the entire secondary search (so any complex secondary search should be independently quoted) and that the penultimate command line argument is either :AND: or :AND_NOT: for thread based "and" or thread based "and not" respectively. Finally, the two queries do play a different role even in the :AND: case. The threads returned are exactly those that match the primary query in (the order that would normally give) just filtered by containing a message matching the secondary query. Thus a search for query_a :AND query_b and a search for query_b :AND: query_a return threads in different orders, and one may be much faster than the other. At the moment this is purely lib and cli (ie no emacs interface). It is also not heavily tested and interactions with excludes or anything unusual could easily give strange results. Anyway I am just posting this in case anyone is interested. Best wishes Mark Mark Walters (2): lib: multithread cli: search: multithread lib/notmuch.h| 12 lib/query.cc | 46 +- notmuch-search.c | 19 +++ 3 files changed, 76 insertions(+), 1 deletions(-) -- 1.7.9.1
[alot] announcing v0.3
Hi everyone! I have just released version 0.3 of my terminal GUI `alot`; You can get a tarball here [0]. This release features many bugfixes, a revised config syntax and a fairly complete user and API manual [1]. Detailed usage updates since v0.21: * revised config syntax! * config file validation, better feedback on malformed configs * themes read from separate files in their own (validated) syntax * complete mailcap compatibility * user manual * direct addressbook type that parses `abook`s contacts * completion for multiple recipients via AbooksCompleter * completion for optional command parameter * generate and set a Message-ID header when constructing mails * add User-Agent header by default * add sent and saved draft mails to the notmuch index and add custom tags * guess file encodings with libmagic * new thread mode command: "remove" to delete messages from the index * new thread mode command: "editnew" e.g. to continue drafts (bound to 'n') * new thread mode command: "togglesource" to display raw messages (bound to 'h') * virtual "Tags" header for print and pipeto commands via --add_tags parameter * much improved pipeto command in thread mode * --spawn parameter for reply,forward,compose,editnew in thread mode * --no-flush parameter for delayed flushing in tag,untag,toggletags commands * make "signature as attachment" configurable; --omit_signature parameter for compose * new envelope command: "save" to save as draft (bound to 'P') * --no-refocus and --spawn parameter for edit in envelope mode * header key completion for set/unset in envelope buffer * "Me" substitution for ones own name/address in authors string * new search mode command and search argument: "sort" * renamed search mode command 'toggletag' to "toggletags" * new search mode commands: "tag" and "untag" * custom tagstring representation: hiding, substitution, colours, multi-matching Thanks goes to those who contributed: $git shortlog -sen 0.21..| tail -n +2 52 dtk 34 Daniel 15 Justus Winter <4winter at informatik.uni-hamburg.de> 4 bjoernb 3 Stanislav Ochotnicky 2 Tom Prince , ..everyone who send feedback and of course to all notmuch contributors. After this release I will switch the git branching model [3], so expect the "testing" branch to retire soon. For the curious: The README.md lists some future goals together with their envisioned milestone and pointers proof-of-concept implementations. I could use some help from packagers. It should be relatively straight forward to package alot but I haven't bothered to read up on the python packaging docs for $YOUR_DISTRI. A minor complication could be that the docs should be generated at build time, which would introduce some build-dependencies (mostly sphinx) that aren't runtime deps. The installation section in the manual lists all dependencies, licence is GPL3+, let me know if you need any more info. As always, don't hesitate to send feedback, bug reports, feature or pull requests via the projects github page [2]. Cheers, /p [0]: https://github.com/pazz/alot/tarball/0.3 [1]: http://alot.rtfd.org [2]: https://github.com/pazz/alot [3]: http://blogpro.toutantic.net/2012/01/02/another-git-branching-model/
[PATCH 1/2] Add GNU as a valid platform
On Mon, 5 Mar 2012 11:23:43 +0100, Justus Winter <4winter at informatik.uni-hamburg.de> wrote: > Signed-off-by: Justus Winter <4winter at informatik.uni-hamburg.de> > --- > configure |6 +++--- > 1 files changed, 3 insertions(+), 3 deletions(-) pushed both. d
[PATCH 1/2] configure: store $IFS to $DEFAULT_IFS readonly variable
On Wed, 14 Mar 2012 16:59:59 +0200, Tomi Ollila wrote: > In the future, IFS value needs to be changed in a few places > in configure -- and then restored. Store the original value > to $DEFAULT_IFS for easy restoration. pushed both, d
notmuch release 0.12 now available
2.5+ and 3.2. Added missing unicode conversions Python strings have to be encoded to and decoded from utf-8 when calling libnotmuch functions. Porting the bindings to python 3.2 revealed a few function calls that were missing these conversions. Build fixes --- Compatibility with GMime 2.6 It is now possible to build notmuch against both GMime 2.4 and 2.6. However, a bug in GMime 2.6 before 2.6.5 causes notmuch not to report signatures where the signer key is unavailable (GNOME bug 668085). For compatibility with GMime 2.4's tolerance of "From " headers we require GMime 2.6 >= 2.6.7. What is notmuch === Notmuch is a system for indexing, searching, reading, and tagging large collections of email messages in maildir or mh format. It uses the Xapian library to provide fast, full-text search with a convenient search syntax. For more about notmuch, see http://notmuchmail.org -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 315 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120320/0596e09e/attachment.pgp>
notmuch release 0.12 now available
Where to obtain notmuch 0.12 === http://notmuchmail.org/releases/notmuch-0.12.tar.gz Which can be verified with: http://notmuchmail.org/releases/notmuch-0.12.tar.gz.sha1 93effc7f8993c7b29b854adf8a2662b50a187819 notmuch-0.12.tar.gz http://notmuchmail.org/releases/notmuch-0.12.tar.gz.sha1.asc (signed by David Bremner) What's new in notmuch 0.12 = Command-Line Interface -- Reply to sender notmuch reply has gained the ability to create a reply template for replying just to the sender of the message, in addition to reply to all. The feature is available through the new command line option --reply-to=(all|sender). Mail store folder/file ignore A new configuration option, `new.ignore`, lets users specify a ;-separated list of file and directory names that will not be searched for messages by notmuch new. NOTE: *Every* file/directory that goes by one of those names will be ignored, independent of its depth/location in the mail store. Unified help and manual pages The notmuch help command now runs man for the appropriate page. If you install notmuch somewhere unusual, you may need to update MANPATH. Manual page for notmuch configuration options The notmuch CLI configuration file options are now documented in the notmuch-config(1) manual page in addition to the configuration file itself. Emacs Interface --- Reply to sender The Emacs interface has, with the new CLI support, gained the ability to reply to sender in addition to reply to all. In both show and search modes, 'r' has been bound to reply to sender, replacing reply to all, which now has key binding 'R'. More flexible and consistent tagging operations All tagging operations (+, -, *) now accept multiple tags with + or - prefix, like * operation in notmuch-search view before. * operation (`notmuch-show-tag-all') is now available in notmuch-show view. `Notmuch-show-{add,remove}-tag' functions no longer accept tag argument, `notmuch-show-tag-message' should be used instead. Custom bindings using these functions should be updated, e.g.: (notmuch-show-remove-tag unread) should be changed to: (notmuch-show-tag-message -unread) Refreshing the show view ('=' by default) no longer opens or closes messages To get the old behavior of putting messages back in their initial opened/closed state, use a prefix argument, e.g., C-u =. Attachment buttons can be used to view or save attachments. When the cursor is on an attachment button the key 's' can be used to save the attachment, the key 'v' to view the attachment in the default mailcap application, and the key 'o' prompts the user for an application to use to open the attachment. By default Enter or mouse button 1 saves the attachment but this is customisable (option Notmuch Show Part Button Default Action). New functions `notmuch-show-stash-mlarchive-link{,-and-go}' allow stashing and optionally visiting a URI to the current message at one of a number of Mailing List Archives. Fix MML tag quoting in replies The MML tag quoting fix of 0.11.1 unintentionally quoted tags inserted in `message-setup-hook'. Quoting is now limited to the cited message. Show view archiving key binding changes The show view archiving key bindings 'a' and 'x' now remove the inbox tag from the current message only (instead of thread), and move to the next message. At the last message, 'a' proceeds to the next thread in search results, and 'x' returns to search results. The thread archiving functions are now available in 'A' and 'X'. Support text/calendar MIME type The text/calendar MIME type is now supported in addition to text/x-vcalendar. Generate inline patch fake attachment file names from message subject Use the message subject to generate file names for the inline patch fake attachments. The names are now similar to the ones generated by 'git format-patch' instead of just inline patch. See Notmuch Show Insert Text/Plain Hook in the notmuch customize interface. Enable `notmuch-search-line-faces' by default Make the `notmuch-search-line-faces' functionality more discoverable for new users by showing unread messages bold and flagged messages blue by default in the search view. Printing Support notmuch-show mode now has simple printing support, bound to '#' by default. You can customize the variable notmuch-print-mechanism. Library changes --- New functions notmuch_query_add_tag_exclude supports the new tag exclusion feature. Python bindings changes --- Python 3.2 compatibility The python bindings are now compatible with both python 2.5+ and 3.2. Added missing unicode conversions Python strings have to be encoded to and decoded from utf-8 when calling libnotmuch functions. Porting the bindings to python 3.2 revealed a few function
Re: [PATCH 1/2] configure: store $IFS to $DEFAULT_IFS readonly variable
On Wed, 14 Mar 2012 16:59:59 +0200, Tomi Ollila tomi.oll...@iki.fi wrote: In the future, IFS value needs to be changed in a few places in configure -- and then restored. Store the original value to $DEFAULT_IFS for easy restoration. pushed both, d ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 1/2] Add GNU as a valid platform
On Mon, 5 Mar 2012 11:23:43 +0100, Justus Winter 4win...@informatik.uni-hamburg.de wrote: Signed-off-by: Justus Winter 4win...@informatik.uni-hamburg.de --- configure |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) pushed both. d ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[alot] announcing v0.3
Hi everyone! I have just released version 0.3 of my terminal GUI `alot`; You can get a tarball here [0]. This release features many bugfixes, a revised config syntax and a fairly complete user and API manual [1]. Detailed usage updates since v0.21: * revised config syntax! * config file validation, better feedback on malformed configs * themes read from separate files in their own (validated) syntax * complete mailcap compatibility * user manual * direct addressbook type that parses `abook`s contacts * completion for multiple recipients via AbooksCompleter * completion for optional command parameter * generate and set a Message-ID header when constructing mails * add User-Agent header by default * add sent and saved draft mails to the notmuch index and add custom tags * guess file encodings with libmagic * new thread mode command: remove to delete messages from the index * new thread mode command: editnew e.g. to continue drafts (bound to 'n') * new thread mode command: togglesource to display raw messages (bound to 'h') * virtual Tags header for print and pipeto commands via --add_tags parameter * much improved pipeto command in thread mode * --spawn parameter for reply,forward,compose,editnew in thread mode * --no-flush parameter for delayed flushing in tag,untag,toggletags commands * make signature as attachment configurable; --omit_signature parameter for compose * new envelope command: save to save as draft (bound to 'P') * --no-refocus and --spawn parameter for edit in envelope mode * header key completion for set/unset in envelope buffer * Me substitution for ones own name/address in authors string * new search mode command and search argument: sort * renamed search mode command 'toggletag' to toggletags * new search mode commands: tag and untag * custom tagstring representation: hiding, substitution, colours, multi-matching Thanks goes to those who contributed: $git shortlog -sen 0.21..| tail -n +2 52 dtk d...@gmx.de 34 Daniel qu...@hack.org 15 Justus Winter 4win...@informatik.uni-hamburg.de 4 bjoernb p...@bjoern.homelinux.org 3 Stanislav Ochotnicky sochotni...@redhat.com 2 Tom Prince tom.pri...@ualberta.net, ..everyone who send feedback and of course to all notmuch contributors. After this release I will switch the git branching model [3], so expect the testing branch to retire soon. For the curious: The README.md lists some future goals together with their envisioned milestone and pointers proof-of-concept implementations. I could use some help from packagers. It should be relatively straight forward to package alot but I haven't bothered to read up on the python packaging docs for $YOUR_DISTRI. A minor complication could be that the docs should be generated at build time, which would introduce some build-dependencies (mostly sphinx) that aren't runtime deps. The installation section in the manual lists all dependencies, licence is GPL3+, let me know if you need any more info. As always, don't hesitate to send feedback, bug reports, feature or pull requests via the projects github page [2]. Cheers, /p [0]: https://github.com/pazz/alot/tarball/0.3 [1]: http://alot.rtfd.org [2]: https://github.com/pazz/alot [3]: http://blogpro.toutantic.net/2012/01/02/another-git-branching-model/ ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[WIP 0/2] Thread based searching
This is very definitely only a work in progress but there have been several requests for this or something similar on irc. It implements a very crude form of thread based search: the user can ask for all the threads that have a message matching the primary query and have a (possibly different) message matching a secondary query. For example notmuch search --secondary-search from:A :AND: from:B returns all threads that have a message from A and a message from B. Similarly it allows the user to say and not on a thread based way. For example notmuch search --secondary-search from:A :AND_NOT: tag:mute returns all threads that have a message from A and no message with tag:mute. Anything allowing queries of this form is going to have to do some parsing of the query (rather than leaving this to xapian). To keep things as simple as possible this version only tries parsing of this form if passed --secondary-search and it assumes the last command line argument is the entire secondary search (so any complex secondary search should be independently quoted) and that the penultimate command line argument is either :AND: or :AND_NOT: for thread based and or thread based and not respectively. Finally, the two queries do play a different role even in the :AND: case. The threads returned are exactly those that match the primary query in (the order that would normally give) just filtered by containing a message matching the secondary query. Thus a search for query_a :AND query_b and a search for query_b :AND: query_a return threads in different orders, and one may be much faster than the other. At the moment this is purely lib and cli (ie no emacs interface). It is also not heavily tested and interactions with excludes or anything unusual could easily give strange results. Anyway I am just posting this in case anyone is interested. Best wishes Mark Mark Walters (2): lib: multithread cli: search: multithread lib/notmuch.h| 12 lib/query.cc | 46 +- notmuch-search.c | 19 +++ 3 files changed, 76 insertions(+), 1 deletions(-) -- 1.7.9.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[WIP 1/2] lib: multithread
--- lib/notmuch.h | 12 lib/query.cc | 46 +- 2 files changed, 57 insertions(+), 1 deletions(-) diff --git a/lib/notmuch.h b/lib/notmuch.h index babd208..22dd69e 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -445,6 +445,18 @@ typedef enum { NOTMUCH_SORT_UNSORTED } notmuch_sort_t; +/* Values for notmuch_query_secondary_search_conjunction */ +typedef enum { +NOTMUCH_SECONDARY_SEARCH_NONE, +NOTMUCH_SECONDARY_SEARCH_AND, +NOTMUCH_SECONDARY_SEARCH_AND_NOT +} notmuch_ss_conjunction_t; + +void +notmuch_query_set_secondary_search (notmuch_query_t *query, + const char *secondary_search_terms, + notmuch_ss_conjunction_t conjunction); + /* Return the query_string of this query. See notmuch_query_create. */ const char * notmuch_query_get_query_string (notmuch_query_t *query); diff --git a/lib/query.cc b/lib/query.cc index 68ac1e4..0faef51 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -26,6 +26,8 @@ struct _notmuch_query { notmuch_database_t *notmuch; const char *query_string; +const char *secondary_search_terms; +notmuch_ss_conjunction_t ss_conjunction; notmuch_sort_t sort; notmuch_string_list_t *exclude_terms; notmuch_bool_t omit_excluded_messages; @@ -92,6 +94,8 @@ notmuch_query_create (notmuch_database_t *notmuch, query-exclude_terms = _notmuch_string_list_create (query); +query-secondary_search_terms = NULL; + query-omit_excluded_messages = FALSE; return query; @@ -122,6 +126,15 @@ notmuch_query_get_sort (notmuch_query_t *query) } void +notmuch_query_set_secondary_search (notmuch_query_t *query, + const char *secondary_search_terms, + notmuch_ss_conjunction_t conjunction) +{ +query-secondary_search_terms = talloc_strdup (query, secondary_search_terms); +query-ss_conjunction = conjunction; +} + +void notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag) { char *term = talloc_asprintf (query, %s%s, _find_prefix (tag), tag); @@ -454,6 +467,36 @@ notmuch_query_destroy (notmuch_query_t *query) talloc_free (query); } +/* This function tests whether the thread containing document with id + * seed_doc_id satisfies the secondary search terms of query.*/ +notmuch_bool_t +notmuch_thread_test_secondary_search (notmuch_query_t *query, unsigned int seed_doc_id) +{ +int count; +notmuch_message_t *seed_message; +const char *thread_id; +char *thread_id_query_string; +notmuch_query_t *thread_id_query; + +if (!query-secondary_search_terms) return TRUE; +seed_message = _notmuch_message_create (query, query-notmuch, seed_doc_id, NULL); + +thread_id = notmuch_message_get_thread_id (seed_message); +thread_id_query_string = talloc_asprintf (query, thread:%s and %s, + thread_id, + query-secondary_search_terms); +thread_id_query = notmuch_query_create (query-notmuch, thread_id_query_string); +count = notmuch_query_count_messages (thread_id_query); +switch (query-ss_conjunction) { +case NOTMUCH_SECONDARY_SEARCH_AND: + return (count 0); +case NOTMUCH_SECONDARY_SEARCH_AND_NOT: + return (count == 0); +default: + return TRUE; +} +} + notmuch_bool_t notmuch_threads_valid (notmuch_threads_t *threads) { @@ -462,7 +505,8 @@ notmuch_threads_valid (notmuch_threads_t *threads) while (threads-doc_id_pos threads-doc_ids-len) { doc_id = g_array_index (threads-doc_ids, unsigned int, threads-doc_id_pos); - if (_notmuch_doc_id_set_contains (threads-match_set, doc_id)) + if (_notmuch_doc_id_set_contains (threads-match_set, doc_id) + notmuch_thread_test_secondary_search (threads-query, doc_id)) break; threads-doc_id_pos++; -- 1.7.9.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[WIP 2/2] cli: search: multithread
--- notmuch-search.c | 19 +++ 1 files changed, 19 insertions(+), 0 deletions(-) diff --git a/notmuch-search.c b/notmuch-search.c index f6061e4..2fa4231 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -436,6 +436,9 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) int offset = 0; int limit = -1; /* unlimited */ notmuch_bool_t no_exclude = FALSE; +notmuch_bool_t secondary_search = FALSE; +char *secondary_search_terms = NULL; +notmuch_ss_conjunction_t ss_conjunction = NOTMUCH_SECONDARY_SEARCH_NONE; unsigned int i; enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT } @@ -458,6 +461,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) { tags, OUTPUT_TAGS }, { 0, 0 } } }, { NOTMUCH_OPT_BOOLEAN, no_exclude, no-exclude, 'd', 0 }, + { NOTMUCH_OPT_BOOLEAN, secondary_search, secondary-search, 'd', 0 }, { NOTMUCH_OPT_INT, offset, offset, 'O', 0 }, { NOTMUCH_OPT_INT, limit, limit, 'L', 0 }, { 0, 0, 0, 0, 0 } @@ -478,6 +482,18 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) break; } +if (secondary_search argc-opt_index = 2 ) { + if (strcmp (argv[argc - 2], :AND:) == 0) + ss_conjunction = NOTMUCH_SECONDARY_SEARCH_AND; + if (strcmp (argv[argc - 2], :AND_NOT:) == 0) + ss_conjunction = NOTMUCH_SECONDARY_SEARCH_AND_NOT; + + if (ss_conjunction != NOTMUCH_SECONDARY_SEARCH_NONE) { + secondary_search_terms = argv[argc - 1]; + argc -= 2; + } +} + config = notmuch_config_open (ctx, NULL, NULL); if (config == NULL) return 1; @@ -505,6 +521,9 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) notmuch_query_set_sort (query, sort); +if (secondary_search_terms) + notmuch_query_set_secondary_search (query, secondary_search_terms, ss_conjunction); + if (!no_exclude) { const char **search_exclude_tags; size_t search_exclude_tags_length; -- 1.7.9.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 2/2] configure: print info about required gmime 2.4 or 2.6 versions
In case required gmime (2.4 or 2.6) version if not found print information about both alternatives (and currently minimal 2.6 version that is needed). --- I'm not entirely happy about the implementation but I would be less happy to write static message that has the same spesific version information in second place (third if comments are counted). configure |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/configure b/configure index 393f859..43c2436 100755 --- a/configure +++ b/configure @@ -402,7 +402,9 @@ EOF echo http://xapian.org/; fi if [ $have_gmime -eq 0 ]; then - echo GMime 2.4 library (including development files such as headers) + _24v=${GMIME_24_VERSION#*2.4} _26v=${GMIME_26_VERSION#*2.6} + echo Either GMime 2.4 library $_24v or GMime 2.6 library $_26v + echo (including development files such as headers) echo http://spruce.sourceforge.net/gmime/; echo fi -- 1.7.8.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 1/2] configure: add empty line after each missing component message
Currently whenever message about missing GMime, Glib or talloc is printed the message is 2 lines, component info and its http location in next line. In the future the amount of lines will vary. To ease reading in these cases newline is added after each message. --- configure |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/configure b/configure index 8cf6f2d..393f859 100755 --- a/configure +++ b/configure @@ -404,17 +404,19 @@ EOF if [ $have_gmime -eq 0 ]; then echo GMime 2.4 library (including development files such as headers) echo http://spruce.sourceforge.net/gmime/; + echo fi if [ $have_glib -eq 0 ]; then echo Glib library = 2.22 (including development files such as headers) echo http://ftp.gnome.org/pub/gnome/sources/glib/; + echo fi if [ $have_talloc -eq 0 ]; then echo The talloc library (including development files such as headers) echo http://talloc.samba.org/; + echo fi cat EOF - With any luck, you're using a modern, package-based operating system that has all of these packages available in the distribution. In that case a simple command will install everything you need. For example: -- 1.7.8.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 1/2] config: Add 'config list' command
Add a command to list all keys in a given configuration section. One use is as follows: a MUA may prefer to store data in a central notmuch configuration file so that the data is accessible across different machines, e.g. an addressbook. The list command helps to implement features such as tab completion on the keys. --- notmuch-config.c | 27 +++ 1 files changed, 27 insertions(+), 0 deletions(-) diff --git a/notmuch-config.c b/notmuch-config.c index e9b2750..595cf54 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -799,6 +799,31 @@ notmuch_config_command_set (void *ctx, char *item, int argc, char *argv[]) return ret; } +static int +notmuch_config_command_list (void *ctx, char *group) +{ +notmuch_config_t *config; +char **keys; +size_t i, length; + +config = notmuch_config_open (ctx, NULL, NULL); +if (config == NULL) + return 1; + +keys = g_key_file_get_keys (config-key_file, + group, length, NULL); +if (keys != NULL) { + for (i = 0; i length; i++) + printf (%s\n, keys[i]); + + free (keys); +} + +notmuch_config_close (config); + +return 0; +} + int notmuch_config_command (void *ctx, int argc, char *argv[]) { @@ -813,6 +838,8 @@ notmuch_config_command (void *ctx, int argc, char *argv[]) return notmuch_config_command_get (ctx, argv[1]); else if (strcmp (argv[0], set) == 0) return notmuch_config_command_set (ctx, argv[1], argc - 2, argv + 2); +else if (strcmp (argv[0], list) == 0) + return notmuch_config_command_list (ctx, argv[1]); fprintf (stderr, Unrecognized argument for notmuch config: %s\n, argv[0]); -- 1.7.4.4 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 2/2] man: Document 'config list' command
Document the 'config list' command and its output. --- man/man1/notmuch-config.1 | 12 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/man/man1/notmuch-config.1 b/man/man1/notmuch-config.1 index 395cb9c..b9f81a5 100644 --- a/man/man1/notmuch-config.1 +++ b/man/man1/notmuch-config.1 @@ -9,6 +9,9 @@ notmuch-config \- Access notmuch configuration file. .B notmuch config set .RI section . item [ value ...] +.B notmuch config list +.RI section + .SH DESCRIPTION The @@ -35,6 +38,15 @@ If no values are provided, the specified configuration item will be removed from the configuration file. .RE +.RS 4 +.TP 4 +.B list +The name of each configuration item in the specified section is +printed to stdout, without the section name prefix. Each is terminated +by a newline character. The output is empty if the section does not +exist. +.RE + The available configuration items are described below. .RS 4 -- 1.7.4.4 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[RFC] Split notmuch_database_close into two functions
I propose to split the function notmuch_database_close into notmuch_database_close and notmuch_database_destroy so that long running processes like alot can close the database while still using data obtained from queries to that database. I've updated the tools, the go, ruby and python bindings to use notmuch_database_destroy instead of notmuch_database_close to destroy database objects. Cheers, Justus ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 2/7] NEWS: Document the notmuch_database_close split
Signed-off-by: Justus Winter 4win...@informatik.uni-hamburg.de --- NEWS | 12 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/NEWS b/NEWS index ed5e3c5..26fce67 100644 --- a/NEWS +++ b/NEWS @@ -52,6 +52,18 @@ Reply improvement using the JSON format reply body, and it will quote HTML parts if no text/plain parts are available. +Library changes +--- + +API changes + + The function notmuch_database_close has been split into + notmuch_database_close and notmuch_database_destroy. + + This makes it possible for long running programs to close the xapian + database and thus release the lock associated with it without + destroying the data structures obtained from it. + Notmuch 0.12 (2012-03-20) = -- 1.7.9.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 3/7] Use notmuch_database_destroy instead of notmuch_database_close
Adapt the notmuch binaries source to the notmuch_database_close split. Signed-off-by: Justus Winter 4win...@informatik.uni-hamburg.de --- notmuch-count.c |2 +- notmuch-dump.c|2 +- notmuch-new.c |2 +- notmuch-reply.c |2 +- notmuch-restore.c |2 +- notmuch-search.c |2 +- notmuch-show.c|2 +- notmuch-tag.c |2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/notmuch-count.c b/notmuch-count.c index 46b76ae..ade9138 100644 --- a/notmuch-count.c +++ b/notmuch-count.c @@ -100,7 +100,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) } notmuch_query_destroy (query); -notmuch_database_close (notmuch); +notmuch_database_destroy (notmuch); return 0; } diff --git a/notmuch-dump.c b/notmuch-dump.c index a735875..71ab0ea 100644 --- a/notmuch-dump.c +++ b/notmuch-dump.c @@ -116,7 +116,7 @@ notmuch_dump_command (unused (void *ctx), int argc, char *argv[]) fclose (output); notmuch_query_destroy (query); -notmuch_database_close (notmuch); +notmuch_database_destroy (notmuch); return 0; } diff --git a/notmuch-new.c b/notmuch-new.c index 4f13535..f078753 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -1017,7 +1017,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[]) notmuch_status_to_string (ret)); } -notmuch_database_close (notmuch); +notmuch_database_destroy (notmuch); if (run_hooks !ret !interrupted) ret = notmuch_run_hook (db_path, post-new); diff --git a/notmuch-reply.c b/notmuch-reply.c index e2b6c25..1684b20 100644 --- a/notmuch-reply.c +++ b/notmuch-reply.c @@ -804,7 +804,7 @@ notmuch_reply_command (void *ctx, int argc, char *argv[]) return 1; notmuch_query_destroy (query); -notmuch_database_close (notmuch); +notmuch_database_destroy (notmuch); if (params.cryptoctx) g_object_unref(params.cryptoctx); diff --git a/notmuch-restore.c b/notmuch-restore.c index 87d9772..60efc52 100644 --- a/notmuch-restore.c +++ b/notmuch-restore.c @@ -184,7 +184,7 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[]) if (line) free (line); -notmuch_database_close (notmuch); +notmuch_database_destroy (notmuch); if (input != stdin) fclose (input); diff --git a/notmuch-search.c b/notmuch-search.c index f6061e4..0b41573 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -531,7 +531,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) } notmuch_query_destroy (query); -notmuch_database_close (notmuch); +notmuch_database_destroy (notmuch); return ret; } diff --git a/notmuch-show.c b/notmuch-show.c index ff9d427..c2eaa44 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -1119,7 +1119,7 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) notmuch_query_destroy (query); -notmuch_database_close (notmuch); +notmuch_database_destroy (notmuch); if (params.cryptoctx) g_object_unref(params.cryptoctx); diff --git a/notmuch-tag.c b/notmuch-tag.c index 36b9b09..142005c 100644 --- a/notmuch-tag.c +++ b/notmuch-tag.c @@ -227,7 +227,7 @@ notmuch_tag_command (void *ctx, int argc, char *argv[]) } notmuch_query_destroy (query); -notmuch_database_close (notmuch); +notmuch_database_destroy (notmuch); return interrupted; } -- 1.7.9.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 1/7] Split notmuch_database_close into two functions
Formerly notmuch_database_close closed the xapian database and destroyed the talloc structure associated with the notmuch database object. Split notmuch_database_close into notmuch_database_close and notmuch_database_destroy. This makes it possible for long running programs to close the xapian database and thus release the lock associated with it without destroying the data structures obtained from it. This also makes the api more consistent since every other data structure has a destructor function. Signed-off-by: Justus Winter 4win...@informatik.uni-hamburg.de --- lib/database.cc | 14 -- lib/notmuch.h | 15 +++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/lib/database.cc b/lib/database.cc index 16c4354..2fefcad 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -642,7 +642,7 @@ notmuch_database_open (const char *path, read-write mode.\n, notmuch_path, version, NOTMUCH_DATABASE_VERSION); notmuch-mode = NOTMUCH_DATABASE_MODE_READ_ONLY; - notmuch_database_close (notmuch); + notmuch_database_destroy (notmuch); notmuch = NULL; goto DONE; } @@ -702,7 +702,7 @@ notmuch_database_open (const char *path, } catch (const Xapian::Error error) { fprintf (stderr, A Xapian exception occurred opening database: %s\n, error.get_msg().c_str()); - notmuch_database_close (notmuch); + notmuch_database_destroy (notmuch); notmuch = NULL; } @@ -738,9 +738,19 @@ notmuch_database_close (notmuch_database_t *notmuch) } delete notmuch-term_gen; +notmuch-term_gen = NULL; delete notmuch-query_parser; +notmuch-query_parser = NULL; delete notmuch-xapian_db; +notmuch-xapian_db = NULL; delete notmuch-value_range_processor; +notmuch-value_range_processor = NULL; +} + +void +notmuch_database_destroy (notmuch_database_t *notmuch) +{ +notmuch_database_close (notmuch); talloc_free (notmuch); } diff --git a/lib/notmuch.h b/lib/notmuch.h index babd208..6114f36 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -133,7 +133,7 @@ typedef struct _notmuch_filenames notmuch_filenames_t; * * After a successful call to notmuch_database_create, the returned * database will be open so the caller should call - * notmuch_database_close when finished with it. + * notmuch_database_destroy when finished with it. * * The database will not yet have any data in it * (notmuch_database_create itself is a very cheap function). Messages @@ -165,7 +165,7 @@ typedef enum { * An existing notmuch database can be identified by the presence of a * directory named .notmuch below 'path'. * - * The caller should call notmuch_database_close when finished with + * The caller should call notmuch_database_destroy when finished with * this database. * * In case of any failure, this function returns NULL, (after printing @@ -175,11 +175,18 @@ notmuch_database_t * notmuch_database_open (const char *path, notmuch_database_mode_t mode); -/* Close the given notmuch database, freeing all associated - * resources. See notmuch_database_open. */ +/* Close the given notmuch database. + * + * This function is called by notmuch_database_destroyed and can be + * called multiple times. */ void notmuch_database_close (notmuch_database_t *database); +/* Destroy the notmuch database freeing all associated + * resources */ +void +notmuch_database_destroy (notmuch_database_t *database); + /* Return the database path of the given database. * * The return value is a string owned by notmuch so should not be -- 1.7.9.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 4/7] Use notmuch_database_destroy instead of notmuch_database_close
Adapt notmuch-deliver to the notmuch_database_close split. Signed-off-by: Justus Winter 4win...@informatik.uni-hamburg.de --- contrib/notmuch-deliver/src/main.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/contrib/notmuch-deliver/src/main.c b/contrib/notmuch-deliver/src/main.c index 6f32f73..37d2919 100644 --- a/contrib/notmuch-deliver/src/main.c +++ b/contrib/notmuch-deliver/src/main.c @@ -455,7 +455,7 @@ main(int argc, char **argv) g_strfreev(opt_rtags); g_free(mail); - notmuch_database_close(db); + notmuch_database_destroy(db); return 0; } -- 1.7.9.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 5/7] go: Use notmuch_database_destroy instead of notmuch_database_close
Adapt the go bindings to the notmuch_database_close split. Signed-off-by: Justus Winter 4win...@informatik.uni-hamburg.de --- bindings/go/pkg/notmuch.go |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/go/pkg/notmuch.go b/bindings/go/pkg/notmuch.go index c6844ef..d32901d 100644 --- a/bindings/go/pkg/notmuch.go +++ b/bindings/go/pkg/notmuch.go @@ -114,7 +114,7 @@ func NewDatabase(path string) *Database { * An existing notmuch database can be identified by the presence of a * directory named .notmuch below 'path'. * - * The caller should call notmuch_database_close when finished with + * The caller should call notmuch_database_destroy when finished with * this database. * * In case of any failure, this function returns NULL, (after printing @@ -140,7 +140,7 @@ func OpenDatabase(path string, mode DatabaseMode) *Database { /* Close the given notmuch database, freeing all associated * resources. See notmuch_database_open. */ func (self *Database) Close() { - C.notmuch_database_close(self.db) + C.notmuch_database_destroy(self.db) } /* Return the database path of the given database. -- 1.7.9.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 6/7] ruby: Use notmuch_database_destroy instead of notmuch_database_close
Adapt the ruby bindings to the notmuch_database_close split. Signed-off-by: Justus Winter 4win...@informatik.uni-hamburg.de --- bindings/ruby/database.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/bindings/ruby/database.c b/bindings/ruby/database.c index 982fd59..ba9a139 100644 --- a/bindings/ruby/database.c +++ b/bindings/ruby/database.c @@ -110,7 +110,7 @@ notmuch_rb_database_close (VALUE self) notmuch_database_t *db; Data_Get_Notmuch_Database (self, db); -notmuch_database_close (db); +notmuch_database_destroy (db); DATA_PTR (self) = NULL; return Qnil; -- 1.7.9.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 7/7] python: wrap and use notmuch_database_destroy as destructor
Adapt the go bindings to the notmuch_database_close split. Signed-off-by: Justus Winter 4win...@informatik.uni-hamburg.de --- bindings/python/notmuch/database.py | 17 +++-- 1 files changed, 15 insertions(+), 2 deletions(-) diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py index 44d40fd..9a1896b 100644 --- a/bindings/python/notmuch/database.py +++ b/bindings/python/notmuch/database.py @@ -218,9 +218,22 @@ class Database(object): _close.restype = None def close(self): -Close and free the notmuch database if needed -if self._db is not None: +''' +Closes the notmuch database. +''' +if self._db: self._close(self._db) + +_destroy = nmlib.notmuch_database_destroy +_destroy.argtypes = [NotmuchDatabaseP] +_destroy.restype = None + +def destroy(self): +''' +Destroys the notmuch database. +''' +if self._db: +self._destroy(self._db) self._db = None def __enter__(self): -- 1.7.9.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v2 1/6] test: emacs: new tests notmuch-show: {add, remove} multiple tags {to, from} single message
Hi * test/emacs: - Rename subtests {Add,Remove} tag from notmuch-show view to notmuch-show: {add,remove} single tag {to,from} single message to be consistent with the following tests. - New subtest notmuch-show: add multiple tags to single message: `notmuch-show-add-tag' (+) can add multiple tags to a message. - New subtest notmuch-show: remove multiple tags from single message: `notmuch-show-remove-tag' (-) can remove multiple tags from a message. --- test/emacs | 16 ++-- 1 files changed, 14 insertions(+), 2 deletions(-) diff --git a/test/emacs b/test/emacs index b74cfa9..ec1dbb0 100755 --- a/test/emacs +++ b/test/emacs @@ -112,18 +112,30 @@ test_emacs (notmuch-search \$os_x_darwin_thread\) output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize) test_expect_equal $output thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread) -test_begin_subtest Add tag from notmuch-show view +test_begin_subtest notmuch-show: add single tag to single message test_emacs (notmuch-show \$os_x_darwin_thread\) (execute-kbd-macro \+tag-from-show-view\) output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize) test_expect_equal $output thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox tag-from-show-view unread) -test_begin_subtest Remove tag from notmuch-show view +test_begin_subtest notmuch-show: remove single tag from single message test_emacs (notmuch-show \$os_x_darwin_thread\) (execute-kbd-macro \-tag-from-show-view\) output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize) test_expect_equal $output thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread) +test_begin_subtest notmuch-show: add multiple tags to single message +test_emacs (notmuch-show \$os_x_darwin_thread\) + (execute-kbd-macro \+tag1-from-show-view +tag2-from-show-view\) +output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize) +test_expect_equal $output thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox tag1-from-show-view tag2-from-show-view unread) + +test_begin_subtest notmuch-show: remove multiple tags from single message +test_emacs (notmuch-show \$os_x_darwin_thread\) + (execute-kbd-macro \-tag1-from-show-view -tag2-from-show-view\) +output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize) +test_expect_equal $output thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread) + test_begin_subtest Message with .. in Message-Id: add_message [id]=123..456@example '[subject]=Message with .. in Message-Id' test_emacs '(notmuch-search id:\123..456@example\) This looks good to me but I think it would be nice to have an extra test for adding a tag and removing a tag simultaneously. Best wishes Mark ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v2 4/6] emacs: add optional predicate arg to `notmuch-show-mapc'
On Fri, 24 Feb 2012 23:30:38 +0100, Pieter Praet pie...@praet.org wrote: * emacs/notmuch-show.el (notmuch-show-mapc): If provided with optional argument PREDICATE, only call FUNCTION if calling PREDICATE returns non-nil. Also correct original docstring: 's/thread/buffer/'. --- emacs/notmuch-show.el | 14 ++ 1 files changed, 10 insertions(+), 4 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index aa9ccee..6adbdc0 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1272,13 +1272,19 @@ (defun notmuch-show-goto-message-previous () (notmuch-show-move-to-message-top) t)) -(defun notmuch-show-mapc (function) - Iterate through all messages in the current thread with +(defun notmuch-show-mapc (function optional predicate) + Iterate through all messages in the current buffer with `notmuch-show-goto-message-next' and call FUNCTION for side -effects. +effects. + +If provided with optional argument PREDICATE, only call +FUNCTION if calling PREDICATE returns non-nil. (save-excursion (goto-char (point-min)) -(loop do (funcall function) +(loop do (if predicate + (if (funcall predicate) + (funcall function)) +(funcall function)) while (notmuch-show-goto-message-next ;; Functions relating to the visibility of messages and their The change looks fine. The original function feels a little fragile to me as to what happens if predicate or function move point. Eg what happens if function collapses the message: where does point go, and so where does notmuch-show-goto-message-next go. Is this just my naivete as a lisp beginner? Is there someway of writing it so the user doesn't need to worry about such things? Best wishes Mark (sorry for the duplicate mail: I sent the first message from the wrong address) ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v2 5/6] emacs: simplify `notmuch-show-get-messages-ids{, -search}'
On Fri, 24 Feb 2012 23:30:39 +0100, Pieter Praet pie...@praet.org wrote: * emacs/notmuch-show.el (notmuch-show-get-messages-ids): If provided with optional arg SEPARATOR, return a string consisting of all Message-Id's, separated by SEPARATOR. Also improve original docstring wrt default return value. (notmuch-show-get-messages-ids-search): Removed, as its functionality is now in `notmuch-show-get-messages-ids'. (notmuch-show-tag-all): Call `notmuch-show-get-messages-ids' with SEPARATOR arg instead of `notmuch-show-get-messages-ids-search'. --- emacs/notmuch-show.el | 18 +- 1 files changed, 9 insertions(+), 9 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 6adbdc0..05606fc 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1339,17 +1339,17 @@ (defun notmuch-show-get-message-id () Return the message id of the current message. (concat id:\ (notmuch-show-get-prop :id) \)) -(defun notmuch-show-get-messages-ids () - Return all message ids of messages in the current thread. +(defun notmuch-show-get-messages-ids (optional separator) + Return a list of Message-Id's of all messages in the current buffer. + +If provided with optional argument SEPARATOR, return a string +instead, consisting of all Message-Id's separated by SEPARATOR. (let ((message-ids)) (notmuch-show-mapc (lambda () (push (notmuch-show-get-message-id) message-ids))) -message-ids)) - -(defun notmuch-show-get-messages-ids-search () - Return a search string for all message ids of messages in the -current thread. - (mapconcat 'identity (notmuch-show-get-messages-ids) or )) +(if separator + (mapconcat 'identity message-ids separator) + message-ids))) ;; dme: Would it make sense to use a macro for many of these? @@ -1638,7 +1638,7 @@ (defun notmuch-show-tag-all (rest tag-changes) TAG-CHANGES is a list of tag operations for `notmuch-tag'. (interactive (notmuch-read-tag-changes nil notmuch-show-thread-id)) - (apply 'notmuch-tag (notmuch-show-get-messages-ids-search) tag-changes) + (apply 'notmuch-tag (notmuch-show-get-messages-ids or ) tag-changes) (notmuch-show-mapc (lambda () (let* ((current-tags (notmuch-show-get-tags)) I like the use of separator rather than hard-wiring or . My personal preference would be to make that change but keep the two functions separate (my Cness makes me like functions that have clear return types!) But I am happy with the change too. Best wishes Mark ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v2 5/6] emacs: simplify `notmuch-show-get-messages-ids{, -search}'
On Fri, 24 Feb 2012 23:30:39 +0100, Pieter Praet pie...@praet.org wrote: * emacs/notmuch-show.el (notmuch-show-get-messages-ids): If provided with optional arg SEPARATOR, return a string consisting of all Message-Id's, separated by SEPARATOR. Also improve original docstring wrt default return value. (notmuch-show-get-messages-ids-search): Removed, as its functionality is now in `notmuch-show-get-messages-ids'. (notmuch-show-tag-all): Call `notmuch-show-get-messages-ids' with SEPARATOR arg instead of `notmuch-show-get-messages-ids-search'. --- emacs/notmuch-show.el | 18 +- 1 files changed, 9 insertions(+), 9 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 6adbdc0..05606fc 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1339,17 +1339,17 @@ (defun notmuch-show-get-message-id () Return the message id of the current message. (concat id:\ (notmuch-show-get-prop :id) \)) -(defun notmuch-show-get-messages-ids () - Return all message ids of messages in the current thread. +(defun notmuch-show-get-messages-ids (optional separator) + Return a list of Message-Id's of all messages in the current buffer. + +If provided with optional argument SEPARATOR, return a string +instead, consisting of all Message-Id's separated by SEPARATOR. (let ((message-ids)) (notmuch-show-mapc (lambda () (push (notmuch-show-get-message-id) message-ids))) -message-ids)) - -(defun notmuch-show-get-messages-ids-search () - Return a search string for all message ids of messages in the -current thread. - (mapconcat 'identity (notmuch-show-get-messages-ids) or )) +(if separator + (mapconcat 'identity message-ids separator) + message-ids))) ;; dme: Would it make sense to use a macro for many of these? @@ -1638,7 +1638,7 @@ (defun notmuch-show-tag-all (rest tag-changes) TAG-CHANGES is a list of tag operations for `notmuch-tag'. (interactive (notmuch-read-tag-changes nil notmuch-show-thread-id)) - (apply 'notmuch-tag (notmuch-show-get-messages-ids-search) tag-changes) + (apply 'notmuch-tag (notmuch-show-get-messages-ids or ) tag-changes) (notmuch-show-mapc (lambda () (let* ((current-tags (notmuch-show-get-tags)) Oh and I forgot to add that this patch doesn't seem to apply anymore. MW ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch