[PATCH v2 0/6] Move --no-exclude to --exclude=(true|false|flag)
On Sat, 31 Mar 2012, Mark Walters wrote: > This is version 2 of the exclude= series (version 1 is [1]). > > The main changes are the addition of some systematic notmuch-search > tests for all the exclude options, and I no longer add the > exclude=flag option to notmuch-show.c (the output was too similar to > exclude=false to be worth keeping). > > Best wishes > > Mark > > > id:"1331836925-31437-1-git-send-email-markwalters1009 at gmail.com". Sorry for the slow review. Besides my fairly superficial comments, everything else LGTM. It's great to see exclude really turning into a robust feature! I had no idea the path would be this long when I wrote that original little hack. I'm thankful you're sticking with it.
[PATCH v2 4/6] test: add some exclude tests
On Sat, 31 Mar 2012, Mark Walters wrote: > Systematically test the exclude options for search. Also move the > search existing exclude tests into the new test. There is some overlap > between the two sets of tests but many of the existing ones are there > because they triggered bugs in the past so I have kept them to ensure > coverage. > --- > test/notmuch-test|1 + > test/search | 48 --- > test/search-excludes | 214 > ++ > 3 files changed, 215 insertions(+), 48 deletions(-) > create mode 100755 test/search-excludes > > diff --git a/test/notmuch-test b/test/notmuch-test > index f03b594..4dcd8c6 100755 > --- a/test/notmuch-test > +++ b/test/notmuch-test > @@ -27,6 +27,7 @@ TESTS=" >search-position-overlap-bug >search-insufficient-from-quoting >search-limiting > + search-excludes >tagging >json >multipart > diff --git a/test/search b/test/search > index 17af6a2..a7a0b18 100755 > --- a/test/search > +++ b/test/search > @@ -129,52 +129,4 @@ add_message '[subject]="utf8-message-body-subject"' > '[date]="Sat, 01 Jan 2000 12 > output=$(notmuch search "b?d?" | notmuch_search_sanitize) > test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test > Suite; utf8-message-body-subject (inbox unread)" > > -test_begin_subtest "Exclude \"deleted\" messages from search" > -notmuch config set search.exclude_tags deleted > -generate_message '[subject]="Not deleted"' > -not_deleted_id=$gen_msg_id > -generate_message '[subject]="Deleted"' > -notmuch new > /dev/null > -notmuch tag +deleted id:$gen_msg_id > -deleted_id=$gen_msg_id > -output=$(notmuch search subject:deleted | notmuch_search_sanitize) > -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test > Suite; Not deleted (inbox unread) > -thread:XXX 2001-01-05 [0/1] Notmuch Test Suite; Deleted (deleted inbox > unread)" > - > -test_begin_subtest "Exclude \"deleted\" messages from message search" > -output=$(notmuch search --output=messages subject:deleted | > notmuch_search_sanitize) > -test_expect_equal "$output" "id:$not_deleted_id" > - > -test_begin_subtest "Exclude \"deleted\" messages from message search > (no-exclude)" > -output=$(notmuch search --no-exclude --output=messages subject:deleted | > notmuch_search_sanitize) > -test_expect_equal "$output" "id:$not_deleted_id > -id:$deleted_id" > - > -test_begin_subtest "Exclude \"deleted\" messages from message search > (non-existent exclude-tag)" > -notmuch config set search.exclude_tags deleted non_existent_tag > -output=$(notmuch search --output=messages subject:deleted | > notmuch_search_sanitize) > -test_expect_equal "$output" "id:$not_deleted_id" > -notmuch config set search.exclude_tags deleted > - > -test_begin_subtest "Exclude \"deleted\" messages from search, overridden" > -output=$(notmuch search subject:deleted and tag:deleted | > notmuch_search_sanitize) > -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test > Suite; Deleted (deleted inbox unread)" > - > -test_begin_subtest "Exclude \"deleted\" messages from threads" > -add_message '[subject]="Not deleted reply"' '[in-reply-to]="<$gen_msg_id>"' > -output=$(notmuch search subject:deleted | notmuch_search_sanitize) > -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test > Suite; Not deleted (inbox unread) > -thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Not deleted reply (deleted > inbox unread)" > - > -test_begin_subtest "Don't exclude \"deleted\" messages when --no-exclude > specified" > -output=$(notmuch search --no-exclude subject:deleted | > notmuch_search_sanitize) > -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test > Suite; Not deleted (inbox unread) > -thread:XXX 2001-01-05 [2/2] Notmuch Test Suite; Deleted (deleted inbox > unread)" > - > -test_begin_subtest "Don't exclude \"deleted\" messages from search if not > configured" > -notmuch config set search.exclude_tags > -output=$(notmuch search subject:deleted | notmuch_search_sanitize) > -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test > Suite; Not deleted (inbox unread) > -thread:XXX 2001-01-05 [2/2] Notmuch Test Suite; Deleted (deleted inbox > unread)" > - > test_done > diff --git a/test/search-excludes b/test/search-excludes > new file mode 100755 > index 000..63acb7b > --- /dev/null > +++ b/test/search-excludes > @@ -0,0 +1,214 @@ > +#!/usr/bin/env bash > +test_description='"notmuch search" with excludes in several variations' > +. ./test-lib.sh > + > +# Generates a thread of 'length' messages. The subject of the nth > +# message in the thread is 'subject: message n' > +generate_thread () > +{ > +local subject="$1" > +local length="$2" > +generate_message '[subject]="'"${subject}: message 1"'"' > +parent_id=$gen_msg_id > +for i in `seq 2 $length` > +do > + generate_message '[subject]="'"${subject}: message $i"'"' \
[PATCH v2 3/6] cli: move search to the new --exclude= naming scheme.
On Sat, 31 Mar 2012, Mark Walters wrote: > This commit replaces the --no-exclude option with a > --exclude=(true|false|flag) option. The default is to omit the > excluded messages. > > The flag option only makes sense if output=summary (as otherwise there > is nowhere to print the flag). In summary output exclude=false and > exclude=flag give almost identical output: > they differ in that with the exclude=flag option the match count > (i.e., the x in [x/n] in the output) is the number of matching > non-excluded messages rather than the number of matching messages. > > Note this changes the default for output=summary when no --exclude= > option is given: it used to default to flag and now defaults to true > (i.e. omit excluded messages). This is neccesary to keep the cli > output uncluttered and for speed reasons. > --- > man/man1/notmuch-search.1 | 12 +--- > notmuch-search.c | 32 +++- > 2 files changed, 32 insertions(+), 12 deletions(-) > > diff --git a/man/man1/notmuch-search.1 b/man/man1/notmuch-search.1 > index 06d81a6..ebb61fc 100644 > --- a/man/man1/notmuch-search.1 > +++ b/man/man1/notmuch-search.1 > @@ -114,9 +114,15 @@ Limit the number of displayed results to N. > > .RS 4 > .TP 4 > -.BR \-\-no\-exclude > - > -Do not exclude the messages matching search.exclude_tags in the config file. > +.BR \-\-exclude=(true|false|flag) > + > +Specify whether to omit messages matching search.tag_exclude from the > +search results (the default) or not. The extra option > +.B flag > +only has an effect when > +.B --output=summary > +In this case all matching threads are returned but the "match count" > +is the number of matching non-excluded messages in the thread. > .RE > > .SH SEE ALSO > diff --git a/notmuch-search.c b/notmuch-search.c > index f6061e4..fe18a93 100644 > --- a/notmuch-search.c > +++ b/notmuch-search.c > @@ -210,9 +210,6 @@ do_search_threads (const search_format_t *format, > int first_thread = 1; > int i; > > -if (output == OUTPUT_THREADS) > - notmuch_query_set_omit_excluded_messages (query, TRUE); > - > if (offset < 0) { > offset += notmuch_query_count_threads (query); > if (offset < 0) > @@ -303,8 +300,6 @@ do_search_messages (const search_format_t *format, > int first_message = 1; > int i; > > -notmuch_query_set_omit_excluded_messages (query, TRUE); > - > if (offset < 0) { > offset += notmuch_query_count_messages (query); > if (offset < 0) > @@ -376,7 +371,6 @@ do_search_tags (notmuch_database_t *notmuch, > const char *tag; > int first_tag = 1; > > -notmuch_query_set_omit_excluded_messages (query, TRUE); > /* should the following only special case if no excluded terms > * specified? */ > > @@ -422,6 +416,12 @@ do_search_tags (notmuch_database_t *notmuch, > return 0; > } > > +enum { > +EXCLUDE_TRUE, > +EXCLUDE_FALSE, > +EXCLUDE_FLAG, > +}; > + > int > notmuch_search_command (void *ctx, int argc, char *argv[]) > { > @@ -435,7 +435,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) > output_t output = OUTPUT_SUMMARY; > int offset = 0; > int limit = -1; /* unlimited */ > -notmuch_bool_t no_exclude = FALSE; > +int exclude = EXCLUDE_TRUE; > unsigned int i; > > enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT } > @@ -457,7 +457,11 @@ notmuch_search_command (void *ctx, int argc, char > *argv[]) > { "files", OUTPUT_FILES }, > { "tags", OUTPUT_TAGS }, > { 0, 0 } } }, > - { NOTMUCH_OPT_BOOLEAN, _exclude, "no-exclude", 'd', 0 }, > +{ NOTMUCH_OPT_KEYWORD, , "exclude", 'x', > + (notmuch_keyword_t []){ { "true", EXCLUDE_TRUE }, > + { "false", EXCLUDE_FALSE }, > + { "flag", EXCLUDE_FLAG }, > + { 0, 0 } } }, > { NOTMUCH_OPT_INT, , "offset", 'O', 0 }, > { NOTMUCH_OPT_INT, , "limit", 'L', 0 }, > { 0, 0, 0, 0, 0 } > @@ -505,7 +509,15 @@ notmuch_search_command (void *ctx, int argc, char > *argv[]) > > notmuch_query_set_sort (query, sort); > > -if (!no_exclude) { > +if (exclude == EXCLUDE_FLAG && output != OUTPUT_SUMMARY) { > + /* if we are not doing summary output there is no where to s/no where/nowhere/. Also, s/if/If/ for style consistency. > + * print the excluded flag so fall back on including the > + * excluded messages */ > + fprintf (stderr, "Cannot flag excluded messages with this output: fall > back on just including them\n"); I commented on the equivalent of this message in the last version of the show patch (and now that code is gone anyway), but must have missed it here. How about just "Warning: this output format cannot flag excluded messages"? Flag already implies including them, so all you're not doing
[PATCH v2 1/6] lib: change default for notmuch_query_set_omit_excluded
On Sat, 31 Mar 2012, Mark Walters wrote: > --- > lib/notmuch.h | 11 ++- > lib/query.cc | 10 +- > 2 files changed, 11 insertions(+), 10 deletions(-) > > diff --git a/lib/notmuch.h b/lib/notmuch.h > index babd208..029a2c3 100644 > --- a/lib/notmuch.h > +++ b/lib/notmuch.h > @@ -449,12 +449,13 @@ typedef enum { > const char * > notmuch_query_get_query_string (notmuch_query_t *query); > > -/* Specify whether to results should omit the excluded results rather > - * than just marking them excluded. This is useful for passing a > - * notmuch_messages_t not containing the excluded messages to other > - * functions. */ > +/* Specify whether to omit the excluded results or just flag > + * them. Note when calling notmuch_query_search_threads, the returned > + * thread will contain all messages regardless of this setting but, > + * unless this is unset, only threads matching in a non-excluded > + * message will be returned. */ The docs seem a bit awkward (I suppose the interface is slightly awkward, but the comment makes it sound much more so) and I don't see a mention of the default behavior anywhere. How about something like Specify whether to omit excluded results or simply flag them. By default, this is set to TRUE. If this is TRUE, notmuch_query_search_messages will omit excluded messages from the results. notmuch_query_search_threads will omit threads that match only in excluded messages, but will include all messages in threads that are only partially excluded. It might be nice to mention the performance implications of the various options, too. > void > -notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, > notmuch_bool_t omit); > +notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, > notmuch_bool_t omit_excluded); Should this be notmuch_query_set_omit_excluded? > > /* Specify the sorting desired for this query. */ > void > diff --git a/lib/query.cc b/lib/query.cc > index 68ac1e4..f7c7099 100644 > --- a/lib/query.cc > +++ b/lib/query.cc > @@ -28,7 +28,7 @@ struct _notmuch_query { > const char *query_string; > notmuch_sort_t sort; > notmuch_string_list_t *exclude_terms; > -notmuch_bool_t omit_excluded_messages; > +notmuch_bool_t omit_excluded; > }; > > typedef struct _notmuch_mset_messages { > @@ -92,7 +92,7 @@ notmuch_query_create (notmuch_database_t *notmuch, > > query->exclude_terms = _notmuch_string_list_create (query); > > -query->omit_excluded_messages = FALSE; > +query->omit_excluded = TRUE; > > return query; > } > @@ -104,9 +104,9 @@ notmuch_query_get_query_string (notmuch_query_t *query) > } > > void > -notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, > notmuch_bool_t omit) > +notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, > notmuch_bool_t omit_excluded) > { > -query->omit_excluded_messages = omit; > +query->omit_excluded = omit_excluded; > } > > void > @@ -220,7 +220,7 @@ notmuch_query_search_messages (notmuch_query_t *query) > if (query->exclude_terms) { > exclude_query = _notmuch_exclude_tags (query, final_query); > > - if (query->omit_excluded_messages) > + if (query->omit_excluded) > final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, >final_query, exclude_query); > else { > -- > 1.7.9.1 > > ___ > notmuch mailing list > notmuch at notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch
Message deletion wisdom
On Wed, 04 Apr 2012 07:38:37 +, Jani Nikula wrote: > To amend that (with mostly historical and not so helpful info), notmuch > used to have the ability to sync the "deleted" tag with the T > ("trashed") maildir flag (with maildir.synchronize_flags option > set). Other mail clients or offlineimap were then able to delete the > mails locally and/or on a server. However, this too had some issues > (concerning multiple files with the same message-id) making it > potentially dangerous, and was removed [1]. Whether this feature ever > makes a comeback depends on someone tackling the problems. And taking > into account the fact that current users of the deleted tag probably do > not expect the files to be actually deleted. I rolled patches for this in the past, see the following message: id:"1310874973-28437-1-git-send-email-anarcat at koumbit.org" id:"1310874973-28437-2-git-send-email-anarcat at koumbit.org" They were indeed refused by the community, but I felt they were still useful. I do not use those patches nowadays, however, but to me they would fit in a broader architectural view of notmuch, where tags are not only metadata sitting outside of your email, but is also written to the messages themselves. The idea is that you can then run notmuch from multiple places without having to worry about synchronising your tags manually: the tags would sit in the messages themselves. A. -- Ce que les si?cles des grands abatoirs nous aura appris Devrait ?tre inscrit au fond de toutes les ?coles; Voici l'homme: le destructeur des mondes est arriv?. - [no one is innocent] -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 835 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120405/a5463d84/attachment.pgp>
Message deletion wisdom
On Tue, 03 Apr 2012 16:32:04 -0700, Jameson Graef Rollins wrote: > So in summary, if you would like to "delete" messages, you can: > > * add a key binding to emacs (or your favorite ui) to add a "deleted" >tag to messages that you want to delete: > > (define-key notmuch-show-mode-map "d" > (lambda () > (interactive) > (notmuch-show-tag-message "+deleted"))) Thank you for this. I had tried to reroll your patches (id:"1326826969-23545-1-git-send-email-jrollins at finestructure.net") on top of 0.12 and that was a miserable failure, so the above works well. In fact, I have made it like this instead: (define-key notmuch-show-mode-map "d" (lambda () (interactive) (notmuch-show-tag-message "+deleted") (notmuch-show-next-open-message))) ... but it doesn't seem to actually go to the next message... oh well, at least I can delete mail. Also note that you can delete whole threads with this: (define-key notmuch-search-mode-map "d" (lambda () (interactive) (notmuch-search-tag-thread "+deleted") (notmuch-search-next-thread))) ... and I have added an undelete function: (define-key notmuch-search-mode-map "u" (lambda () (interactive) (notmuch-search-tag-thread "-deleted") (notmuch-search-next-thread))) > * and if you really want them purged from disk, delete them manually >with: > > notmuch search --output=files tag:deleted | xargs -l rm I use this script: -- next part -- A non-text attachment was scrubbed... Name: notmuch-purge Type: application/x-sh Size: 219 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120405/494f8225/attachment-0001.sh> -- next part -- Finally, I want to voice that I feel a "delete" key, even if it doesn't delete mails, seems like an important part of a mail user agent. Archiving mail is one thing, but for the love and respect of sysadmins and the infrastructure they maintain, please consider adding at least a way to *tag* those deleted emails. Having the above keys being defined as standard in notmuch don't seem like much to ask. This may be a dissenting view here, but your mail is not that important. :P Cheers, A. -- L'art n'est pas un bureau d'anthropom?trie. - L?o Ferr?, "Pr?face" -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 835 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120405/494f8225/attachment-0001.pgp>
[PATCH 3/8] hex-escape: add function to decode escaped string in-place
Thanks for the review, David. Agreed on all points. J. On Thu, 05 Apr 2012 08:56:24 -0300, David Bremner wrote: > Jani Nikula writes: > > > Add function hex_decode_inplace() to decode the input string onto > > itself. > > > > Signed-off-by: Jani Nikula > > > > --- > > > > This could be folded to "hex-escape: (en|de)code strings to/from > > restricted character set". > > Probably. It's a bit hard to follow as is; somehow the code movement is > a bit noisy. > > > while (*p) { > > - > > if (*p == escape_char) { > > - > unrelated whitespace changes, naughty naughty. > > > +hex_status_t > > +hex_decode_inplace (char *p) > > +{ > > +return hex_decode_internal (p, (unsigned char *) p); > this could probably use a comment to the effect that there _will_ be > enough space. > > > + > > +p = in; > > +q = (unsigned char *) *out; > > I understand trying to minimize changes, but do p and q serve any > purpose here? > > > + > > +return hex_decode_internal (p, q); > > +} > > > > +/* > > + * Decode 'in' onto itself. > > + */ > > This is just a bit terse for my taste. > > d
[PATCH 2/8] hex-escape: be more strict about the format while decoding
On Thu, 05 Apr 2012 08:33:23 -0300, David Bremner wrote: > Jani Nikula writes: > > > Signed-off-by: Jani Nikula > > > > --- > > > > This could be folded to "hex-escape: (en|de)code strings to/from > > restricted character set". > > That's probably a good plan. > > > - if (len < 3) > > + if (!isxdigit ((unsigned char) p[1]) || > > + !isxdigit ((unsigned char) p[2])) > > What happens if there are not two characters after the escape? Is this > relying on calling isxdigit on the null terminator? It is, and technically there's nothing wrong with that. Would you prefer explicit checks for '\0' in the if condition, for clarity? Or a comment about it? Jani.
[PATCH 2/8] hex-escape: be more strict about the format while decoding
Jani Nikula writes: > On Thu, 05 Apr 2012 08:33:23 -0300, David Bremner > wrote: >> >> > - if (len < 3) >> > + if (!isxdigit ((unsigned char) p[1]) || >> > + !isxdigit ((unsigned char) p[2])) >> >> What happens if there are not two characters after the escape? Is this >> relying on calling isxdigit on the null terminator? > > It is, and technically there's nothing wrong with that. Would you prefer > explicit checks for '\0' in the if condition, for clarity? Or a comment > about it? I think a comment would do. Or the checks if you prefer.
[PATCH 3/8] hex-escape: add function to decode escaped string in-place
Jani Nikula writes: > Add function hex_decode_inplace() to decode the input string onto > itself. > > Signed-off-by: Jani Nikula > > --- > > This could be folded to "hex-escape: (en|de)code strings to/from > restricted character set". Probably. It's a bit hard to follow as is; somehow the code movement is a bit noisy. > while (*p) { > - > if (*p == escape_char) { > - unrelated whitespace changes, naughty naughty. > +hex_status_t > +hex_decode_inplace (char *p) > +{ > +return hex_decode_internal (p, (unsigned char *) p); this could probably use a comment to the effect that there _will_ be enough space. > + > +p = in; > +q = (unsigned char *) *out; I understand trying to minimize changes, but do p and q serve any purpose here? > + > +return hex_decode_internal (p, q); > +} > +/* > + * Decode 'in' onto itself. > + */ This is just a bit terse for my taste. d
[PATCH 2/8] hex-escape: be more strict about the format while decoding
Jani Nikula writes: > Signed-off-by: Jani Nikula > > --- > > This could be folded to "hex-escape: (en|de)code strings to/from > restricted character set". That's probably a good plan. > - if (len < 3) > + if (!isxdigit ((unsigned char) p[1]) || > + !isxdigit ((unsigned char) p[2])) What happens if there are not two characters after the escape? Is this relying on calling isxdigit on the null terminator? d
[PATCH] configure: change gmime version in help message to 2.6
From: David BremnerSince GMime 2.6 is now the stable version upstream, and probably the most tested by notmuch developers, it makes sense to suggest that to users to install. --- Tomi's second patch looks fine to me, and I promoted it to pushable. I also noticed this minor issue with the help message. configure |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/configure b/configure index ace465b..71981b7 100755 --- a/configure +++ b/configure @@ -427,7 +427,7 @@ case a simple command will install everything you need. For example: On Debian and similar systems: - sudo apt-get install libxapian-dev libgmime-2.4-dev libtalloc-dev + sudo apt-get install libxapian-dev libgmime-2.6-dev libtalloc-dev Or on Fedora and similar systems: -- 1.7.9.1
[PATCH 1/2] test: add broken test for long names in Emacs notmuch-hello view
Dmitry Kurochkin writes: > It has been a while since these patches were posted. They are pretty > simple, just a single line (and a single char) is changed in actual > code. So I am going to remove the needs-review tag. Probably it would be better in general to tag such patches trivial from the start (at least 2/2). Pushed both. d
Re: [PATCH 1/2] test: add broken test for long names in Emacs notmuch-hello view
Dmitry Kurochkin dmitry.kuroch...@gmail.com writes: It has been a while since these patches were posted. They are pretty simple, just a single line (and a single char) is changed in actual code. So I am going to remove the needs-review tag. Probably it would be better in general to tag such patches trivial from the start (at least 2/2). Pushed both. d ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] configure: change gmime version in help message to 2.6
From: David Bremner brem...@debian.org Since GMime 2.6 is now the stable version upstream, and probably the most tested by notmuch developers, it makes sense to suggest that to users to install. --- Tomi's second patch looks fine to me, and I promoted it to pushable. I also noticed this minor issue with the help message. configure |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/configure b/configure index ace465b..71981b7 100755 --- a/configure +++ b/configure @@ -427,7 +427,7 @@ case a simple command will install everything you need. For example: On Debian and similar systems: - sudo apt-get install libxapian-dev libgmime-2.4-dev libtalloc-dev + sudo apt-get install libxapian-dev libgmime-2.6-dev libtalloc-dev Or on Fedora and similar systems: -- 1.7.9.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 2/8] hex-escape: be more strict about the format while decoding
Jani Nikula j...@nikula.org writes: Signed-off-by: Jani Nikula j...@nikula.org --- This could be folded to hex-escape: (en|de)code strings to/from restricted character set. That's probably a good plan. - if (len 3) + if (!isxdigit ((unsigned char) p[1]) || + !isxdigit ((unsigned char) p[2])) What happens if there are not two characters after the escape? Is this relying on calling isxdigit on the null terminator? d ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 2/8] hex-escape: be more strict about the format while decoding
On Thu, 05 Apr 2012 08:33:23 -0300, David Bremner da...@tethera.net wrote: Jani Nikula j...@nikula.org writes: Signed-off-by: Jani Nikula j...@nikula.org --- This could be folded to hex-escape: (en|de)code strings to/from restricted character set. That's probably a good plan. - if (len 3) + if (!isxdigit ((unsigned char) p[1]) || + !isxdigit ((unsigned char) p[2])) What happens if there are not two characters after the escape? Is this relying on calling isxdigit on the null terminator? It is, and technically there's nothing wrong with that. Would you prefer explicit checks for '\0' in the if condition, for clarity? Or a comment about it? Jani. ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 2/8] hex-escape: be more strict about the format while decoding
Jani Nikula j...@nikula.org writes: On Thu, 05 Apr 2012 08:33:23 -0300, David Bremner da...@tethera.net wrote: - if (len 3) + if (!isxdigit ((unsigned char) p[1]) || + !isxdigit ((unsigned char) p[2])) What happens if there are not two characters after the escape? Is this relying on calling isxdigit on the null terminator? It is, and technically there's nothing wrong with that. Would you prefer explicit checks for '\0' in the if condition, for clarity? Or a comment about it? I think a comment would do. Or the checks if you prefer. ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 3/8] hex-escape: add function to decode escaped string in-place
Thanks for the review, David. Agreed on all points. J. On Thu, 05 Apr 2012 08:56:24 -0300, David Bremner brem...@unb.ca wrote: Jani Nikula j...@nikula.org writes: Add function hex_decode_inplace() to decode the input string onto itself. Signed-off-by: Jani Nikula j...@nikula.org --- This could be folded to hex-escape: (en|de)code strings to/from restricted character set. Probably. It's a bit hard to follow as is; somehow the code movement is a bit noisy. while (*p) { - if (*p == escape_char) { - unrelated whitespace changes, naughty naughty. +hex_status_t +hex_decode_inplace (char *p) +{ +return hex_decode_internal (p, (unsigned char *) p); this could probably use a comment to the effect that there _will_ be enough space. + +p = in; +q = (unsigned char *) *out; I understand trying to minimize changes, but do p and q serve any purpose here? + +return hex_decode_internal (p, q); +} +/* + * Decode 'in' onto itself. + */ This is just a bit terse for my taste. d ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: Message deletion wisdom
On Wed, 04 Apr 2012 07:38:37 +, Jani Nikula j...@nikula.org wrote: To amend that (with mostly historical and not so helpful info), notmuch used to have the ability to sync the deleted tag with the T (trashed) maildir flag (with maildir.synchronize_flags option set). Other mail clients or offlineimap were then able to delete the mails locally and/or on a server. However, this too had some issues (concerning multiple files with the same message-id) making it potentially dangerous, and was removed [1]. Whether this feature ever makes a comeback depends on someone tackling the problems. And taking into account the fact that current users of the deleted tag probably do not expect the files to be actually deleted. I rolled patches for this in the past, see the following message: id:1310874973-28437-1-git-send-email-anar...@koumbit.org id:1310874973-28437-2-git-send-email-anar...@koumbit.org They were indeed refused by the community, but I felt they were still useful. I do not use those patches nowadays, however, but to me they would fit in a broader architectural view of notmuch, where tags are not only metadata sitting outside of your email, but is also written to the messages themselves. The idea is that you can then run notmuch from multiple places without having to worry about synchronising your tags manually: the tags would sit in the messages themselves. A. -- Ce que les siècles des grands abatoirs nous aura appris Devrait être inscrit au fond de toutes les écoles; Voici l'homme: le destructeur des mondes est arrivé. - [no one is innocent] pgp3Hmn5AFgRT.pgp Description: PGP signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v2 1/6] lib: change default for notmuch_query_set_omit_excluded
On Sat, 31 Mar 2012, Mark Walters markwalters1...@gmail.com wrote: --- lib/notmuch.h | 11 ++- lib/query.cc | 10 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/notmuch.h b/lib/notmuch.h index babd208..029a2c3 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -449,12 +449,13 @@ typedef enum { const char * notmuch_query_get_query_string (notmuch_query_t *query); -/* Specify whether to results should omit the excluded results rather - * than just marking them excluded. This is useful for passing a - * notmuch_messages_t not containing the excluded messages to other - * functions. */ +/* Specify whether to omit the excluded results or just flag + * them. Note when calling notmuch_query_search_threads, the returned + * thread will contain all messages regardless of this setting but, + * unless this is unset, only threads matching in a non-excluded + * message will be returned. */ The docs seem a bit awkward (I suppose the interface is slightly awkward, but the comment makes it sound much more so) and I don't see a mention of the default behavior anywhere. How about something like Specify whether to omit excluded results or simply flag them. By default, this is set to TRUE. If this is TRUE, notmuch_query_search_messages will omit excluded messages from the results. notmuch_query_search_threads will omit threads that match only in excluded messages, but will include all messages in threads that are only partially excluded. It might be nice to mention the performance implications of the various options, too. void -notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit); +notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit_excluded); Should this be notmuch_query_set_omit_excluded? /* Specify the sorting desired for this query. */ void diff --git a/lib/query.cc b/lib/query.cc index 68ac1e4..f7c7099 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -28,7 +28,7 @@ struct _notmuch_query { const char *query_string; notmuch_sort_t sort; notmuch_string_list_t *exclude_terms; -notmuch_bool_t omit_excluded_messages; +notmuch_bool_t omit_excluded; }; typedef struct _notmuch_mset_messages { @@ -92,7 +92,7 @@ notmuch_query_create (notmuch_database_t *notmuch, query-exclude_terms = _notmuch_string_list_create (query); -query-omit_excluded_messages = FALSE; +query-omit_excluded = TRUE; return query; } @@ -104,9 +104,9 @@ notmuch_query_get_query_string (notmuch_query_t *query) } void -notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit) +notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit_excluded) { -query-omit_excluded_messages = omit; +query-omit_excluded = omit_excluded; } void @@ -220,7 +220,7 @@ notmuch_query_search_messages (notmuch_query_t *query) if (query-exclude_terms) { exclude_query = _notmuch_exclude_tags (query, final_query); - if (query-omit_excluded_messages) + if (query-omit_excluded) final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, final_query, exclude_query); else { -- 1.7.9.1 ___ 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: [PATCH v2 3/6] cli: move search to the new --exclude= naming scheme.
On Sat, 31 Mar 2012, Mark Walters markwalters1...@gmail.com wrote: This commit replaces the --no-exclude option with a --exclude=(true|false|flag) option. The default is to omit the excluded messages. The flag option only makes sense if output=summary (as otherwise there is nowhere to print the flag). In summary output exclude=false and exclude=flag give almost identical output: they differ in that with the exclude=flag option the match count (i.e., the x in [x/n] in the output) is the number of matching non-excluded messages rather than the number of matching messages. Note this changes the default for output=summary when no --exclude= option is given: it used to default to flag and now defaults to true (i.e. omit excluded messages). This is neccesary to keep the cli output uncluttered and for speed reasons. --- man/man1/notmuch-search.1 | 12 +--- notmuch-search.c | 32 +++- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/man/man1/notmuch-search.1 b/man/man1/notmuch-search.1 index 06d81a6..ebb61fc 100644 --- a/man/man1/notmuch-search.1 +++ b/man/man1/notmuch-search.1 @@ -114,9 +114,15 @@ Limit the number of displayed results to N. .RS 4 .TP 4 -.BR \-\-no\-exclude - -Do not exclude the messages matching search.exclude_tags in the config file. +.BR \-\-exclude=(true|false|flag) + +Specify whether to omit messages matching search.tag_exclude from the +search results (the default) or not. The extra option +.B flag +only has an effect when +.B --output=summary +In this case all matching threads are returned but the match count +is the number of matching non-excluded messages in the thread. .RE .SH SEE ALSO diff --git a/notmuch-search.c b/notmuch-search.c index f6061e4..fe18a93 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -210,9 +210,6 @@ do_search_threads (const search_format_t *format, int first_thread = 1; int i; -if (output == OUTPUT_THREADS) - notmuch_query_set_omit_excluded_messages (query, TRUE); - if (offset 0) { offset += notmuch_query_count_threads (query); if (offset 0) @@ -303,8 +300,6 @@ do_search_messages (const search_format_t *format, int first_message = 1; int i; -notmuch_query_set_omit_excluded_messages (query, TRUE); - if (offset 0) { offset += notmuch_query_count_messages (query); if (offset 0) @@ -376,7 +371,6 @@ do_search_tags (notmuch_database_t *notmuch, const char *tag; int first_tag = 1; -notmuch_query_set_omit_excluded_messages (query, TRUE); /* should the following only special case if no excluded terms * specified? */ @@ -422,6 +416,12 @@ do_search_tags (notmuch_database_t *notmuch, return 0; } +enum { +EXCLUDE_TRUE, +EXCLUDE_FALSE, +EXCLUDE_FLAG, +}; + int notmuch_search_command (void *ctx, int argc, char *argv[]) { @@ -435,7 +435,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) output_t output = OUTPUT_SUMMARY; int offset = 0; int limit = -1; /* unlimited */ -notmuch_bool_t no_exclude = FALSE; +int exclude = EXCLUDE_TRUE; unsigned int i; enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT } @@ -457,7 +457,11 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) { files, OUTPUT_FILES }, { tags, OUTPUT_TAGS }, { 0, 0 } } }, - { NOTMUCH_OPT_BOOLEAN, no_exclude, no-exclude, 'd', 0 }, +{ NOTMUCH_OPT_KEYWORD, exclude, exclude, 'x', + (notmuch_keyword_t []){ { true, EXCLUDE_TRUE }, + { false, EXCLUDE_FALSE }, + { flag, EXCLUDE_FLAG }, + { 0, 0 } } }, { NOTMUCH_OPT_INT, offset, offset, 'O', 0 }, { NOTMUCH_OPT_INT, limit, limit, 'L', 0 }, { 0, 0, 0, 0, 0 } @@ -505,7 +509,15 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) notmuch_query_set_sort (query, sort); -if (!no_exclude) { +if (exclude == EXCLUDE_FLAG output != OUTPUT_SUMMARY) { + /* if we are not doing summary output there is no where to s/no where/nowhere/. Also, s/if/If/ for style consistency. + * print the excluded flag so fall back on including the + * excluded messages */ + fprintf (stderr, Cannot flag excluded messages with this output: fall back on just including them\n); I commented on the equivalent of this message in the last version of the show patch (and now that code is gone anyway), but must have missed it here. How about just Warning: this output format cannot flag excluded messages? Flag already implies including them, so all you're not doing in this case is flagging them. + exclude = EXCLUDE_FALSE; +} + +if (exclude ==
Re: [PATCH v2 4/6] test: add some exclude tests
On Sat, 31 Mar 2012, Mark Walters markwalters1...@gmail.com wrote: Systematically test the exclude options for search. Also move the search existing exclude tests into the new test. There is some overlap between the two sets of tests but many of the existing ones are there because they triggered bugs in the past so I have kept them to ensure coverage. --- test/notmuch-test|1 + test/search | 48 --- test/search-excludes | 214 ++ 3 files changed, 215 insertions(+), 48 deletions(-) create mode 100755 test/search-excludes diff --git a/test/notmuch-test b/test/notmuch-test index f03b594..4dcd8c6 100755 --- a/test/notmuch-test +++ b/test/notmuch-test @@ -27,6 +27,7 @@ TESTS= search-position-overlap-bug search-insufficient-from-quoting search-limiting + search-excludes tagging json multipart diff --git a/test/search b/test/search index 17af6a2..a7a0b18 100755 --- a/test/search +++ b/test/search @@ -129,52 +129,4 @@ add_message '[subject]=utf8-message-body-subject' '[date]=Sat, 01 Jan 2000 12 output=$(notmuch search bödý | notmuch_search_sanitize) test_expect_equal $output thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-message-body-subject (inbox unread) -test_begin_subtest Exclude \deleted\ messages from search -notmuch config set search.exclude_tags deleted -generate_message '[subject]=Not deleted' -not_deleted_id=$gen_msg_id -generate_message '[subject]=Deleted' -notmuch new /dev/null -notmuch tag +deleted id:$gen_msg_id -deleted_id=$gen_msg_id -output=$(notmuch search subject:deleted | notmuch_search_sanitize) -test_expect_equal $output thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) -thread:XXX 2001-01-05 [0/1] Notmuch Test Suite; Deleted (deleted inbox unread) - -test_begin_subtest Exclude \deleted\ messages from message search -output=$(notmuch search --output=messages subject:deleted | notmuch_search_sanitize) -test_expect_equal $output id:$not_deleted_id - -test_begin_subtest Exclude \deleted\ messages from message search (no-exclude) -output=$(notmuch search --no-exclude --output=messages subject:deleted | notmuch_search_sanitize) -test_expect_equal $output id:$not_deleted_id -id:$deleted_id - -test_begin_subtest Exclude \deleted\ messages from message search (non-existent exclude-tag) -notmuch config set search.exclude_tags deleted non_existent_tag -output=$(notmuch search --output=messages subject:deleted | notmuch_search_sanitize) -test_expect_equal $output id:$not_deleted_id -notmuch config set search.exclude_tags deleted - -test_begin_subtest Exclude \deleted\ messages from search, overridden -output=$(notmuch search subject:deleted and tag:deleted | notmuch_search_sanitize) -test_expect_equal $output thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Deleted (deleted inbox unread) - -test_begin_subtest Exclude \deleted\ messages from threads -add_message '[subject]=Not deleted reply' '[in-reply-to]=$gen_msg_id' -output=$(notmuch search subject:deleted | notmuch_search_sanitize) -test_expect_equal $output thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) -thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Not deleted reply (deleted inbox unread) - -test_begin_subtest Don't exclude \deleted\ messages when --no-exclude specified -output=$(notmuch search --no-exclude subject:deleted | notmuch_search_sanitize) -test_expect_equal $output thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) -thread:XXX 2001-01-05 [2/2] Notmuch Test Suite; Deleted (deleted inbox unread) - -test_begin_subtest Don't exclude \deleted\ messages from search if not configured -notmuch config set search.exclude_tags -output=$(notmuch search subject:deleted | notmuch_search_sanitize) -test_expect_equal $output thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) -thread:XXX 2001-01-05 [2/2] Notmuch Test Suite; Deleted (deleted inbox unread) - test_done diff --git a/test/search-excludes b/test/search-excludes new file mode 100755 index 000..63acb7b --- /dev/null +++ b/test/search-excludes @@ -0,0 +1,214 @@ +#!/usr/bin/env bash +test_description='notmuch search with excludes in several variations' +. ./test-lib.sh + +# Generates a thread of 'length' messages. The subject of the nth +# message in the thread is 'subject: message n' +generate_thread () +{ +local subject=$1 +local length=$2 +generate_message '[subject]='${subject}: message 1'' +parent_id=$gen_msg_id +for i in `seq 2 $length` +do + generate_message '[subject]='${subject}: message $i'' \ + [in-reply-to]=\$parent_id\ + parent_id=$gen_msg_id +done +notmuch new /dev/null +} + +# These are the original search exclude tests. +
[PATCH v3 0/5] Add 'config list' command
This version tests 'config set' by reading back the set value, as suggested. Peter Wang (5): config: Fix free in 'config get' implementation. test: Add tests for 'config' command test: Add broken test for 'config list' config: Add 'config list' command man: Document 'config list' command man/man1/notmuch-config.1 | 14 + notmuch-config.c | 68 +--- test/config | 40 ++ test/notmuch-test |1 + 4 files changed, 118 insertions(+), 5 deletions(-) create mode 100755 test/config -- 1.7.4.4 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v3 1/5] config: Fix free in 'config get' implementation.
The array returned by g_key_file_get_string_list() should be freed with g_strfreev(), not free(). --- notmuch-config.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/notmuch-config.c b/notmuch-config.c index e9b2750..85fc774 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -751,7 +751,7 @@ notmuch_config_command_get (void *ctx, char *item) for (i = 0; i length; i++) printf (%s\n, value[i]); - free (value); + g_strfreev (value); } notmuch_config_close (config); -- 1.7.4.4 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v3 2/5] test: Add tests for 'config' command
Start a new test script. --- test/config | 25 + test/notmuch-test |1 + 2 files changed, 26 insertions(+), 0 deletions(-) create mode 100755 test/config diff --git a/test/config b/test/config new file mode 100755 index 000..75f662d --- /dev/null +++ b/test/config @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +test_description='notmuch config' +. test-lib.sh + +test_begin_subtest Get string value +test_expect_equal $(notmuch config get user.name) Notmuch Test Suite + +test_begin_subtest Get list value +test_expect_equal $(notmuch config get new.tags) \ +unread +inbox + +test_begin_subtest Set string value +notmuch config set foo.bar baz +test_expect_equal $(notmuch config get foo.bar) baz + +test_begin_subtest Set list value +notmuch config set foo.list xxx yyy yyy zzz zzz +test_expect_equal $(notmuch config get foo.list) \ +xxx +yyy yyy +zzz zzz + +test_done diff --git a/test/notmuch-test b/test/notmuch-test index f03b594..e08ec72 100755 --- a/test/notmuch-test +++ b/test/notmuch-test @@ -19,6 +19,7 @@ cd $(dirname $0) TESTS= basic help-test + config new count search -- 1.7.4.4 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v3 5/5] man: Document 'config list' command
Document the 'config list' command and its output. --- man/man1/notmuch-config.1 | 14 ++ 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/man/man1/notmuch-config.1 b/man/man1/notmuch-config.1 index 395cb9c..a55dbef 100644 --- a/man/man1/notmuch-config.1 +++ b/man/man1/notmuch-config.1 @@ -9,6 +9,8 @@ notmuch-config \- Access notmuch configuration file. .B notmuch config set .RI section . item [ value ...] +.B notmuch config list + .SH DESCRIPTION The @@ -35,6 +37,18 @@ If no values are provided, the specified configuration item will be removed from the configuration file. .RE +.RS 4 +.TP 4 +.B list +Every configuration item is printed to stdout, each on a separate line +of the form: + +.RI section . item = value + +No additional whitespace surrounds the dot or equals sign characters. In a +multiple-value item (a list), the values are separated by semicolon characters. +.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
Re: [PATCH v2 0/6] Move --no-exclude to --exclude=(true|false|flag)
On Sat, 31 Mar 2012, Mark Walters markwalters1...@gmail.com wrote: This is version 2 of the exclude= series (version 1 is [1]). The main changes are the addition of some systematic notmuch-search tests for all the exclude options, and I no longer add the exclude=flag option to notmuch-show.c (the output was too similar to exclude=false to be worth keeping). Best wishes Mark id:1331836925-31437-1-git-send-email-markwalters1...@gmail.com. Sorry for the slow review. Besides my fairly superficial comments, everything else LGTM. It's great to see exclude really turning into a robust feature! I had no idea the path would be this long when I wrote that original little hack. I'm thankful you're sticking with it. ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch