unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag
@ 2012-03-01 22:30 Mark Walters
  2012-03-01 22:30 ` [Patch v7 01/13] cli: add --no-exclude option to count and search Mark Walters
                   ` (15 more replies)
  0 siblings, 16 replies; 18+ messages in thread
From: Mark Walters @ 2012-03-01 22:30 UTC (permalink / raw)
  To: notmuch

This is essentially the same as
id:"1330157204-26094-1-git-send-email-markwalters1009@gmail.com" but
has been rebased against master. The changes are to patch 12/13 for
notmuch-show.el (which was posted as a followup to the previous series)
and to the tests (patch 9/13) which changed in Austin's JSON show
rewrite.

Best wishes

Mark

Mark Walters (13):
  cli: add --no-exclude option to count and search.
  cli: Add --no-exclude to the man pages for search and count
  test: add tests for new cli --no-exclude option
  lib: Rearrange the exclude code in query.cc
  lib: Make notmuch_query_search_messages set the exclude flag
  lib: Add the exclude flag to notmuch_query_search_threads
  test: update search test to reflect exclude flag
  cli: Make notmuch-show respect excludes.
  test: update tests to reflect the exclude flag
  man: update manpage for notmuch-show --no-exclude option
  cli: omit excluded messages in results where appropriate.
  emacs: show: recognize the exclude flag.
  emacs: notmuch.el ignore excluded matches

 emacs/notmuch-show.el     |   36 ++++++++++++++++-----
 emacs/notmuch.el          |   22 +++++++------
 lib/notmuch-private.h     |    8 +++-
 lib/notmuch.h             |   16 +++++++--
 lib/query.cc              |   77 +++++++++++++++++++++++++++++++++++++++------
 lib/thread.cc             |   18 +++++++++--
 man/man1/notmuch-count.1  |    7 ++++
 man/man1/notmuch-search.1 |    7 ++++
 man/man1/notmuch-show.1   |    7 ++++
 notmuch-count.c           |   19 +++++++---
 notmuch-search.c          |   26 ++++++++++++---
 notmuch-show.c            |   31 ++++++++++++++++--
 test/count                |   21 ++++++++++++
 test/crypto               |    9 +++++-
 test/encoding             |    2 +-
 test/json                 |    6 ++--
 test/maildir-sync         |    1 +
 test/multipart            |    6 ++--
 test/search               |    8 ++++-
 test/thread-naming        |   16 +++++-----
 20 files changed, 273 insertions(+), 70 deletions(-)

-- 
1.7.2.3

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Patch v7 01/13] cli: add --no-exclude option to count and search.
  2012-03-01 22:30 [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters
@ 2012-03-01 22:30 ` Mark Walters
  2012-03-01 22:30 ` [Patch v7 02/13] cli: Add --no-exclude to the man pages for search and count Mark Walters
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Mark Walters @ 2012-03-01 22:30 UTC (permalink / raw)
  To: notmuch

This option turns off the exclusion so all matching messages are
returned. We do not need to add this to notmuch-show as that does not
(yet) exclude.
---
 notmuch-count.c  |   17 +++++++++++------
 notmuch-search.c |   17 +++++++++++------
 2 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/notmuch-count.c b/notmuch-count.c
index 63459fb..5364507 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -35,8 +35,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
     char *query_str;
     int opt_index;
     int output = OUTPUT_MESSAGES;
-    const char **search_exclude_tags;
-    size_t search_exclude_tags_length;
+    notmuch_bool_t no_exclude = FALSE;
     unsigned int i;
 
     notmuch_opt_desc_t options[] = {
@@ -44,6 +43,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 	  (notmuch_keyword_t []){ { "threads", OUTPUT_THREADS },
 				  { "messages", OUTPUT_MESSAGES },
 				  { 0, 0 } } },
+	{ NOTMUCH_OPT_BOOLEAN, &no_exclude, "no-exclude", 'd', 0 },
 	{ 0, 0, 0, 0, 0 }
     };
 
@@ -78,10 +78,15 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 	return 1;
     }
 
-    search_exclude_tags = notmuch_config_get_search_exclude_tags
-	(config, &search_exclude_tags_length);
-    for (i = 0; i < search_exclude_tags_length; i++)
-	notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
+    if (!no_exclude) {
+	const char **search_exclude_tags;
+	size_t search_exclude_tags_length;
+
+	search_exclude_tags = notmuch_config_get_search_exclude_tags
+	    (config, &search_exclude_tags_length);
+	for (i = 0; i < search_exclude_tags_length; i++)
+	    notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
+    }
 
     switch (output) {
     case OUTPUT_MESSAGES:
diff --git a/notmuch-search.c b/notmuch-search.c
index 92ce38a..6d6c0e6 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -426,8 +426,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
     output_t output = OUTPUT_SUMMARY;
     int offset = 0;
     int limit = -1; /* unlimited */
-    const char **search_exclude_tags;
-    size_t search_exclude_tags_length;
+    notmuch_bool_t no_exclude = FALSE;
     unsigned int i;
 
     enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT }
@@ -449,6 +448,7 @@ 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_INT, &offset, "offset", 'O', 0 },
 	{ NOTMUCH_OPT_INT, &limit, "limit", 'L', 0  },
 	{ 0, 0, 0, 0, 0 }
@@ -496,10 +496,15 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
 
     notmuch_query_set_sort (query, sort);
 
-    search_exclude_tags = notmuch_config_get_search_exclude_tags
-	(config, &search_exclude_tags_length);
-    for (i = 0; i < search_exclude_tags_length; i++)
-	notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
+    if (!no_exclude) {
+	const char **search_exclude_tags;
+	size_t search_exclude_tags_length;
+
+	search_exclude_tags = notmuch_config_get_search_exclude_tags
+	    (config, &search_exclude_tags_length);
+	for (i = 0; i < search_exclude_tags_length; i++)
+	    notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
+    }
 
     switch (output) {
     default:
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Patch v7 02/13] cli: Add --no-exclude to the man pages for search and count
  2012-03-01 22:30 [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters
  2012-03-01 22:30 ` [Patch v7 01/13] cli: add --no-exclude option to count and search Mark Walters
@ 2012-03-01 22:30 ` Mark Walters
  2012-03-01 22:30 ` [Patch v7 03/13] test: add tests for new cli --no-exclude option Mark Walters
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Mark Walters @ 2012-03-01 22:30 UTC (permalink / raw)
  To: notmuch

---
 man/man1/notmuch-count.1  |    7 +++++++
 man/man1/notmuch-search.1 |    7 +++++++
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/man/man1/notmuch-count.1 b/man/man1/notmuch-count.1
index 0d0ab5d..805a8ae 100644
--- a/man/man1/notmuch-count.1
+++ b/man/man1/notmuch-count.1
@@ -38,6 +38,13 @@ Output the number of matching messages. This is the default.
 Output the number of matching threads.
 .RE
 .RE
+
+.RS 4
+.TP 4
+.BR \-\-no\-exclude
+
+Do not exclude the messages matching search.exclude_tags in the config file.
+.RE
 .RE
 .RE
 
diff --git a/man/man1/notmuch-search.1 b/man/man1/notmuch-search.1
index 19d85df..8426aa3 100644
--- a/man/man1/notmuch-search.1
+++ b/man/man1/notmuch-search.1
@@ -112,6 +112,13 @@ result from the end.
 Limit the number of displayed results to N.
 .RE
 
+.RS 4
+.TP 4
+.BR \-\-no\-exclude
+
+Do not exclude the messages matching search.exclude_tags in the config file.
+.RE
+
 .SH SEE ALSO
 
 \fBnotmuch\fR(1), \fBnotmuch-config\fR(1), \fBnotmuch-count\fR(1),
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Patch v7 03/13] test: add tests for new cli --no-exclude option
  2012-03-01 22:30 [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters
  2012-03-01 22:30 ` [Patch v7 01/13] cli: add --no-exclude option to count and search Mark Walters
  2012-03-01 22:30 ` [Patch v7 02/13] cli: Add --no-exclude to the man pages for search and count Mark Walters
@ 2012-03-01 22:30 ` Mark Walters
  2012-03-01 22:30 ` [Patch v7 04/13] lib: Rearrange the exclude code in query.cc Mark Walters
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Mark Walters @ 2012-03-01 22:30 UTC (permalink / raw)
  To: notmuch

The tests test the new --no-exclude option to search and count.
There were no existing tests for the exclude behaviour for count so
added these too.
---
 test/count  |   21 +++++++++++++++++++++
 test/search |    5 +++++
 2 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/test/count b/test/count
index 300b171..976fff1 100755
--- a/test/count
+++ b/test/count
@@ -37,4 +37,25 @@ test_expect_equal \
     "0" \
     "`notmuch count --output=threads ${SEARCH}`"
 
+test_begin_subtest "count excluding \"deleted\" messages"
+notmuch config set search.exclude_tags = deleted
+generate_message '[subject]="Not deleted"'
+generate_message '[subject]="Another not deleted"'
+generate_message '[subject]="Deleted"'
+notmuch new > /dev/null
+notmuch tag +deleted id:$gen_msg_id
+test_expect_equal \
+    "2" \
+    "`notmuch count subject:deleted`"
+
+test_begin_subtest "count \"deleted\" messages, exclude overridden"
+test_expect_equal \
+    "1" \
+    "`notmuch count subject:deleted and tag:deleted`"
+
+test_begin_subtest "count \"deleted\" messages, with --no-exclude"
+test_expect_equal \
+    "3" \
+    "`notmuch count --no-exclude subject:deleted`"
+
 test_done
diff --git a/test/search b/test/search
index 414be35..3da5d17 100755
--- a/test/search
+++ b/test/search
@@ -148,6 +148,11 @@ 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)
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Patch v7 04/13] lib: Rearrange the exclude code in query.cc
  2012-03-01 22:30 [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters
                   ` (2 preceding siblings ...)
  2012-03-01 22:30 ` [Patch v7 03/13] test: add tests for new cli --no-exclude option Mark Walters
@ 2012-03-01 22:30 ` Mark Walters
  2012-03-01 22:30 ` [Patch v7 05/13] lib: Make notmuch_query_search_messages set the exclude flag Mark Walters
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Mark Walters @ 2012-03-01 22:30 UTC (permalink / raw)
  To: notmuch

Slightly refactor the exclude code to give the callers access to the
exclude query itself. There should be no functional change.
---
 lib/query.cc |   29 +++++++++++++++++++----------
 1 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/lib/query.cc b/lib/query.cc
index 0b36602..c25b301 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -122,12 +122,15 @@ _notmuch_messages_destructor (notmuch_mset_messages_t *messages)
     return 0;
 }
 
-/* Return a query that does not match messages with the excluded tags
- * registered with the query.  Any tags that explicitly appear in
- * xquery will not be excluded. */
+/* Return a query that matches messages with the excluded tags
+ * registered with query.  Any tags that explicitly appear in xquery
+ * will not be excluded. The caller of this function has to combine
+ * the returned query appropriately.*/
 static Xapian::Query
 _notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery)
 {
+    Xapian::Query exclude_query = Xapian::Query::MatchNothing;
+
     for (notmuch_string_node_t *term = query->exclude_terms->head; term;
 	 term = term->next) {
 	Xapian::TermIterator it = xquery.get_terms_begin ();
@@ -137,10 +140,10 @@ _notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery)
 		break;
 	}
 	if (it == end)
-	    xquery = Xapian::Query (Xapian::Query::OP_AND_NOT,
-				    xquery, Xapian::Query (term->string));
+	    exclude_query = Xapian::Query (Xapian::Query::OP_OR,
+				    exclude_query, Xapian::Query (term->string));
     }
-    return xquery;
+    return exclude_query;
 }
 
 notmuch_messages_t *
@@ -168,7 +171,7 @@ notmuch_query_search_messages (notmuch_query_t *query)
 	Xapian::Query mail_query (talloc_asprintf (query, "%s%s",
 						   _find_prefix ("type"),
 						   "mail"));
-	Xapian::Query string_query, final_query;
+	Xapian::Query string_query, final_query, exclude_query;
 	Xapian::MSet mset;
 	unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN |
 			      Xapian::QueryParser::FLAG_PHRASE |
@@ -188,7 +191,10 @@ notmuch_query_search_messages (notmuch_query_t *query)
 					 mail_query, string_query);
 	}
 
-	final_query = _notmuch_exclude_tags (query, final_query);
+	exclude_query = _notmuch_exclude_tags (query, final_query);
+
+	final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
+					 final_query, exclude_query);
 
 	enquire.set_weighting_scheme (Xapian::BoolWeight());
 
@@ -449,7 +455,7 @@ notmuch_query_count_messages (notmuch_query_t *query)
 	Xapian::Query mail_query (talloc_asprintf (query, "%s%s",
 						   _find_prefix ("type"),
 						   "mail"));
-	Xapian::Query string_query, final_query;
+	Xapian::Query string_query, final_query, exclude_query;
 	Xapian::MSet mset;
 	unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN |
 			      Xapian::QueryParser::FLAG_PHRASE |
@@ -469,7 +475,10 @@ notmuch_query_count_messages (notmuch_query_t *query)
 					 mail_query, string_query);
 	}
 
-	final_query = _notmuch_exclude_tags (query, final_query);
+	exclude_query = _notmuch_exclude_tags (query, final_query);
+
+	final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
+					 final_query, exclude_query);
 
 	enquire.set_weighting_scheme(Xapian::BoolWeight());
 	enquire.set_docid_order(Xapian::Enquire::ASCENDING);
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Patch v7 05/13] lib: Make notmuch_query_search_messages set the exclude flag
  2012-03-01 22:30 [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters
                   ` (3 preceding siblings ...)
  2012-03-01 22:30 ` [Patch v7 04/13] lib: Rearrange the exclude code in query.cc Mark Walters
@ 2012-03-01 22:30 ` Mark Walters
  2012-03-01 22:30 ` [Patch v7 06/13] lib: Add the exclude flag to notmuch_query_search_threads Mark Walters
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Mark Walters @ 2012-03-01 22:30 UTC (permalink / raw)
  To: notmuch

Add a flag NOTMUCH_MESSAGE_FLAG_EXCLUDED which is set by
notmuch_query_search_messages for excluded messages. Also add an
option omit_excluded_messages to the search that we do not want the
excludes at all.

This exclude flag will be added to notmuch_query_search threads in the
next patch.
---
 lib/notmuch-private.h |    1 +
 lib/notmuch.h         |   10 +++++++-
 lib/query.cc          |   59 ++++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 7bf153e..e791bb0 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -401,6 +401,7 @@ typedef struct _notmuch_message_list {
  */
 struct visible _notmuch_messages {
     notmuch_bool_t is_of_list_type;
+    notmuch_doc_id_set_t *excluded_doc_ids;
     notmuch_message_node_t *iterator;
 };
 
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 7929fe7..f75afae 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -449,6 +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. */
+void
+notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit);
+
 /* Specify the sorting desired for this query. */
 void
 notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort);
@@ -895,7 +902,8 @@ notmuch_message_get_filenames (notmuch_message_t *message);
 
 /* Message flags */
 typedef enum _notmuch_message_flag {
-    NOTMUCH_MESSAGE_FLAG_MATCH
+    NOTMUCH_MESSAGE_FLAG_MATCH,
+    NOTMUCH_MESSAGE_FLAG_EXCLUDED
 } notmuch_message_flag_t;
 
 /* Get a value of a flag for the email corresponding to 'message'. */
diff --git a/lib/query.cc b/lib/query.cc
index c25b301..ef2a11f 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -28,6 +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;
 };
 
 typedef struct _notmuch_mset_messages {
@@ -57,6 +58,12 @@ struct visible _notmuch_threads {
     notmuch_doc_id_set_t match_set;
 };
 
+/* We need this in the message functions so forward declare. */
+static notmuch_bool_t
+_notmuch_doc_id_set_init (void *ctx,
+			  notmuch_doc_id_set_t *doc_ids,
+			  GArray *arr);
+
 notmuch_query_t *
 notmuch_query_create (notmuch_database_t *notmuch,
 		      const char *query_string)
@@ -79,6 +86,8 @@ notmuch_query_create (notmuch_database_t *notmuch,
 
     query->exclude_terms = _notmuch_string_list_create (query);
 
+    query->omit_excluded_messages = FALSE;
+
     return query;
 }
 
@@ -89,6 +98,12 @@ notmuch_query_get_query_string (notmuch_query_t *query)
 }
 
 void
+notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit)
+{
+    query->omit_excluded_messages = omit;
+}
+
+void
 notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort)
 {
     query->sort = sort;
@@ -124,8 +139,9 @@ _notmuch_messages_destructor (notmuch_mset_messages_t *messages)
 
 /* Return a query that matches messages with the excluded tags
  * registered with query.  Any tags that explicitly appear in xquery
- * will not be excluded. The caller of this function has to combine
- * the returned query appropriately.*/
+ * will not be excluded, and will be removed from the list of exclude
+ * tags.  The caller of this function has to combine the returned
+ * query appropriately.*/
 static Xapian::Query
 _notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery)
 {
@@ -142,6 +158,8 @@ _notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery)
 	if (it == end)
 	    exclude_query = Xapian::Query (Xapian::Query::OP_OR,
 				    exclude_query, Xapian::Query (term->string));
+	else
+	    term->string = talloc_strdup (query, "");
     }
     return exclude_query;
 }
@@ -173,6 +191,7 @@ notmuch_query_search_messages (notmuch_query_t *query)
 						   "mail"));
 	Xapian::Query string_query, final_query, exclude_query;
 	Xapian::MSet mset;
+	Xapian::MSetIterator iterator;
 	unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN |
 			      Xapian::QueryParser::FLAG_PHRASE |
 			      Xapian::QueryParser::FLAG_LOVEHATE |
@@ -190,11 +209,35 @@ notmuch_query_search_messages (notmuch_query_t *query)
 	    final_query = Xapian::Query (Xapian::Query::OP_AND,
 					 mail_query, string_query);
 	}
+	messages->base.excluded_doc_ids = NULL;
+
+	if (query->exclude_terms) {
+	    exclude_query = _notmuch_exclude_tags (query, final_query);
+	    exclude_query = Xapian::Query (Xapian::Query::OP_AND,
+					   exclude_query, final_query);
+
+	    if (query->omit_excluded_messages)
+		final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
+					     final_query, exclude_query);
+	    else {
+		enquire.set_weighting_scheme (Xapian::BoolWeight());
+		enquire.set_query (exclude_query);
+
+		mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ());
+
+		GArray *excluded_doc_ids = g_array_new (FALSE, FALSE, sizeof (unsigned int));
+
+		for (iterator = mset.begin (); iterator != mset.end (); iterator++) {
+		    unsigned int doc_id = *iterator;
+		    g_array_append_val (excluded_doc_ids, doc_id);
+		}
+		messages->base.excluded_doc_ids = talloc (messages, _notmuch_doc_id_set);
+		_notmuch_doc_id_set_init (query, messages->base.excluded_doc_ids,
+					  excluded_doc_ids);
+		g_array_unref (excluded_doc_ids);
+	    }
+	}
 
-	exclude_query = _notmuch_exclude_tags (query, final_query);
-
-	final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
-					 final_query, exclude_query);
 
 	enquire.set_weighting_scheme (Xapian::BoolWeight());
 
@@ -283,6 +326,10 @@ _notmuch_mset_messages_get (notmuch_messages_t *messages)
 	INTERNAL_ERROR ("a messages iterator contains a non-existent document ID.\n");
     }
 
+    if (messages->excluded_doc_ids &&
+	_notmuch_doc_id_set_contains (messages->excluded_doc_ids, doc_id))
+	notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE);
+
     return message;
 }
 
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Patch v7 06/13] lib: Add the exclude flag to notmuch_query_search_threads
  2012-03-01 22:30 [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters
                   ` (4 preceding siblings ...)
  2012-03-01 22:30 ` [Patch v7 05/13] lib: Make notmuch_query_search_messages set the exclude flag Mark Walters
@ 2012-03-01 22:30 ` Mark Walters
  2012-03-01 22:30 ` [Patch v7 07/13] test: update search test to reflect exclude flag Mark Walters
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Mark Walters @ 2012-03-01 22:30 UTC (permalink / raw)
  To: notmuch

Add the NOTMUCH_MESSAGE_FLAG_EXCLUDED flag to
notmuch_query_search_threads. Implemented by inspecting the tags
directly in _notmuch_thread_create/_thread_add_message rather than as
a Xapian query for speed reasons.

Note notmuch_thread_get_matched_messages now returns the number of
non-excluded matching messages. This API is not totally desirable but
fixing it means breaking binary compatibility so we delay that.
---
 lib/notmuch-private.h |    7 +++++--
 lib/notmuch.h         |    6 ++++--
 lib/query.cc          |    1 +
 lib/thread.cc         |   18 +++++++++++++++---
 4 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index e791bb0..ea836f7 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -148,6 +148,8 @@ typedef enum _notmuch_private_status {
 
 typedef struct _notmuch_doc_id_set notmuch_doc_id_set_t;
 
+typedef struct _notmuch_string_list notmuch_string_list_t;
+
 /* database.cc */
 
 /* Lookup a prefix value by name.
@@ -216,6 +218,7 @@ _notmuch_thread_create (void *ctx,
 			notmuch_database_t *notmuch,
 			unsigned int seed_doc_id,
 			notmuch_doc_id_set_t *match_set,
+			notmuch_string_list_t *excluded_terms,
 			notmuch_sort_t sort);
 
 /* message.cc */
@@ -459,11 +462,11 @@ typedef struct _notmuch_string_node {
     struct _notmuch_string_node *next;
 } notmuch_string_node_t;
 
-typedef struct visible _notmuch_string_list {
+struct visible _notmuch_string_list {
     int length;
     notmuch_string_node_t *head;
     notmuch_string_node_t **tail;
-} notmuch_string_list_t;
+};
 
 notmuch_string_list_t *
 _notmuch_string_list_create (const void *ctx);
diff --git a/lib/notmuch.h b/lib/notmuch.h
index f75afae..babd208 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -672,8 +672,10 @@ notmuch_thread_get_toplevel_messages (notmuch_thread_t *thread);
 /* Get the number of messages in 'thread' that matched the search.
  *
  * This count includes only the messages in this thread that were
- * matched by the search from which the thread was created. Contrast
- * with notmuch_thread_get_total_messages() .
+ * matched by the search from which the thread was created and were
+ * not excluded by any exclude tags passed in with the query (see
+ * notmuch_query_add_tag_exclude). Contrast with
+ * notmuch_thread_get_total_messages() .
  */
 int
 notmuch_thread_get_matched_messages (notmuch_thread_t *thread);
diff --git a/lib/query.cc b/lib/query.cc
index ef2a11f..ab18fbc 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -475,6 +475,7 @@ notmuch_threads_get (notmuch_threads_t *threads)
 				   threads->query->notmuch,
 				   doc_id,
 				   &threads->match_set,
+				   threads->query->exclude_terms,
 				   threads->query->sort);
 }
 
diff --git a/lib/thread.cc b/lib/thread.cc
index 0435ee6..e976d64 100644
--- a/lib/thread.cc
+++ b/lib/thread.cc
@@ -214,7 +214,8 @@ _thread_cleanup_author (notmuch_thread_t *thread,
  */
 static void
 _thread_add_message (notmuch_thread_t *thread,
-		     notmuch_message_t *message)
+		     notmuch_message_t *message,
+		     notmuch_string_list_t *exclude_terms)
 {
     notmuch_tags_t *tags;
     const char *tag;
@@ -262,6 +263,15 @@ _thread_add_message (notmuch_thread_t *thread,
 	 notmuch_tags_move_to_next (tags))
     {
 	tag = notmuch_tags_get (tags);
+	/* Mark excluded messages. */
+	for (notmuch_string_node_t *term = exclude_terms->head; term;
+	     term = term->next) {
+	    /* We ignore initial 'K'. */
+	    if (strcmp(tag, (term->string + 1)) == 0) {
+		notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE);
+		break;
+	    }
+	}
 	g_hash_table_insert (thread->tags, xstrdup (tag), NULL);
     }
 }
@@ -321,7 +331,8 @@ _thread_add_matched_message (notmuch_thread_t *thread,
 	    _thread_set_subject_from_message (thread, message);
     }
 
-    thread->matched_messages++;
+    if (!notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED))
+	thread->matched_messages++;
 
     if (g_hash_table_lookup_extended (thread->message_hash,
 			    notmuch_message_get_message_id (message), NULL,
@@ -392,6 +403,7 @@ _notmuch_thread_create (void *ctx,
 			notmuch_database_t *notmuch,
 			unsigned int seed_doc_id,
 			notmuch_doc_id_set_t *match_set,
+			notmuch_string_list_t *exclude_terms,
 			notmuch_sort_t sort)
 {
     notmuch_thread_t *thread;
@@ -467,7 +479,7 @@ _notmuch_thread_create (void *ctx,
 	if (doc_id == seed_doc_id)
 	    message = seed_message;
 
-	_thread_add_message (thread, message);
+	_thread_add_message (thread, message, exclude_terms);
 
 	if ( _notmuch_doc_id_set_contains (match_set, doc_id)) {
 	    _notmuch_doc_id_set_remove (match_set, doc_id);
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Patch v7 07/13] test: update search test to reflect exclude flag
  2012-03-01 22:30 [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters
                   ` (5 preceding siblings ...)
  2012-03-01 22:30 ` [Patch v7 06/13] lib: Add the exclude flag to notmuch_query_search_threads Mark Walters
@ 2012-03-01 22:30 ` Mark Walters
  2012-03-01 22:30 ` [Patch v7 08/13] cli: Make notmuch-show respect excludes Mark Walters
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Mark Walters @ 2012-03-01 22:30 UTC (permalink / raw)
  To: notmuch

notmuch-search.c now returns all matching threads even if it the
match is a search.tag_excluded message (but with a mark indicating
this). Update the test to reflect this.
---
 test/search |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/test/search b/test/search
index 3da5d17..081f60c 100755
--- a/test/search
+++ b/test/search
@@ -136,7 +136,8 @@ generate_message '[subject]="Deleted"'
 notmuch new > /dev/null
 notmuch tag +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)"
+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 search, overridden"
 output=$(notmuch search subject:deleted and tag:deleted | notmuch_search_sanitize)
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Patch v7 08/13] cli: Make notmuch-show respect excludes.
  2012-03-01 22:30 [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters
                   ` (6 preceding siblings ...)
  2012-03-01 22:30 ` [Patch v7 07/13] test: update search test to reflect exclude flag Mark Walters
@ 2012-03-01 22:30 ` Mark Walters
  2012-03-01 22:30 ` [Patch v7 09/13] test: update tests to reflect the exclude flag Mark Walters
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Mark Walters @ 2012-03-01 22:30 UTC (permalink / raw)
  To: notmuch

This adds the excludes to notmuch-show.c. We do not exclude when only
a single message (or part) is requested. notmuch-show will output the
exclude information when either text or json format is requested. As
this changes the output from notmuch-show it breaks many tests (in a
trivial and expected fashion).
---
 notmuch-show.c |   25 +++++++++++++++++++++----
 1 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index 6a171a4..8c0b925 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -143,9 +143,10 @@ format_message_json (const void *ctx, notmuch_message_t *message)
     date = notmuch_message_get_date (message);
     relative_date = notmuch_time_relative_date (ctx, date);
 
-    printf ("\"id\": %s, \"match\": %s, \"filename\": %s, \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [",
+    printf ("\"id\": %s, \"match\": %s, \"excluded\": %s, \"filename\": %s, \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [",
 	    json_quote_str (ctx_quote, notmuch_message_get_message_id (message)),
 	    notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? "true" : "false",
+	    notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? "true" : "false",
 	    json_quote_str (ctx_quote, notmuch_message_get_filename (message)),
 	    date, relative_date);
 
@@ -579,11 +580,12 @@ format_part_text (const void *ctx, mime_node_t *node,
 	notmuch_message_t *message = node->envelope_file;
 
 	part_type = "message";
-	printf ("\f%s{ id:%s depth:%d match:%d filename:%s\n",
+	printf ("\f%s{ id:%s depth:%d match:%d excluded:%d filename:%s\n",
 		part_type,
 		notmuch_message_get_message_id (message),
 		indent,
-		notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH),
+		notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 1 : 0,
+		notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 1 : 0,
 		notmuch_message_get_filename (message));
     } else {
 	GMimeContentDisposition *disposition = g_mime_object_get_content_disposition (meta);
@@ -984,6 +986,7 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
     notmuch_show_params_t params = { .part = -1 };
     int format_sel = NOTMUCH_FORMAT_NOT_SPECIFIED;
     notmuch_bool_t verify = FALSE;
+    notmuch_bool_t no_exclude = FALSE;
 
     notmuch_opt_desc_t options[] = {
 	{ NOTMUCH_OPT_KEYWORD, &format_sel, "format", 'f',
@@ -996,6 +999,7 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
 	{ NOTMUCH_OPT_BOOLEAN, &params.entire_thread, "entire-thread", 't', 0 },
 	{ NOTMUCH_OPT_BOOLEAN, &params.decrypt, "decrypt", 'd', 0 },
 	{ NOTMUCH_OPT_BOOLEAN, &verify, "verify", 'v', 0 },
+	{ NOTMUCH_OPT_BOOLEAN, &no_exclude, "no-exclude", 'n', 0 },
 	{ 0, 0, 0, 0, 0 }
     };
 
@@ -1083,10 +1087,23 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
 	return 1;
     }
 
+    /* If a single message is requested we do not use search_excludes. */
     if (params.part >= 0)
 	ret = do_show_single (ctx, query, format, &params);
-    else
+    else {
+	if (!no_exclude) {
+	    const char **search_exclude_tags;
+	    size_t search_exclude_tags_length;
+	    unsigned int i;
+
+	    search_exclude_tags = notmuch_config_get_search_exclude_tags
+		(config, &search_exclude_tags_length);
+	    for (i = 0; i < search_exclude_tags_length; i++)
+		notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
+	}
 	ret = do_show (ctx, query, format, &params);
+    }
+
 
     notmuch_query_destroy (query);
     notmuch_database_close (notmuch);
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Patch v7 09/13] test: update tests to reflect the exclude flag
  2012-03-01 22:30 [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters
                   ` (7 preceding siblings ...)
  2012-03-01 22:30 ` [Patch v7 08/13] cli: Make notmuch-show respect excludes Mark Walters
@ 2012-03-01 22:30 ` Mark Walters
  2012-03-01 22:30 ` [Patch v7 10/13] man: update manpage for notmuch-show --no-exclude option Mark Walters
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Mark Walters @ 2012-03-01 22:30 UTC (permalink / raw)
  To: notmuch

notmuch show outputs the exclude flag so many tests using notmuch
show failed. This commit adds "excluded:0" or "excluded: false" to
the expected outputs. After this commit there should be no failing
tests.
---
 test/crypto        |    9 ++++++++-
 test/encoding      |    2 +-
 test/json          |    6 +++---
 test/maildir-sync  |    1 +
 test/multipart     |    6 +++---
 test/thread-naming |   16 ++++++++--------
 6 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/test/crypto b/test/crypto
index 7e774c8..4de4d2b 100755
--- a/test/crypto
+++ b/test/crypto
@@ -43,6 +43,7 @@ output=$(notmuch show --format=json --verify subject:"test signed message 001" \
     | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "XXXXX",
  "match": true,
+ "excluded": false,
  "filename": "YYYYY",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -76,6 +77,7 @@ output=$(notmuch show --format=json --verify subject:"test signed message 001" \
     | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "XXXXX",
  "match": true,
+ "excluded": false,
  "filename": "YYYYY",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -111,6 +113,7 @@ output=$(notmuch show --format=json --verify subject:"test signed message 001" \
     | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "XXXXX",
  "match": true,
+ "excluded": false,
  "filename": "YYYYY",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -150,7 +153,7 @@ test_begin_subtest "decryption, --format=text"
 output=$(notmuch show --format=text --decrypt subject:"test encrypted message 001" \
     | notmuch_show_sanitize_all \
     | sed -e 's|"created": [1234567890]*|"created": 946728000|')
-expected='\fmessage{ id:XXXXX depth:0 match:1 filename:XXXXX
+expected='\fmessage{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX
 \fheader{
 Notmuch Test Suite <test_suite@notmuchmail.org> (2000-01-01) (encrypted inbox)
 Subject: test encrypted message 001
@@ -184,6 +187,7 @@ output=$(notmuch show --format=json --decrypt subject:"test encrypted message 00
     | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "XXXXX",
  "match": true,
+ "excluded": false,
  "filename": "YYYYY",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -238,6 +242,7 @@ output=$(notmuch show --format=json --decrypt subject:"test encrypted message 00
     | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "XXXXX",
  "match": true,
+ "excluded": false,
  "filename": "YYYYY",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -272,6 +277,7 @@ output=$(notmuch show --format=json --decrypt subject:"test encrypted message 00
     | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "XXXXX",
  "match": true,
+ "excluded": false,
  "filename": "YYYYY",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -326,6 +332,7 @@ output=$(notmuch show --format=json --verify subject:"test signed message 001" \
     | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "XXXXX",
  "match": true,
+ "excluded": false,
  "filename": "YYYYY",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
diff --git a/test/encoding b/test/encoding
index f0d073c..98abf77 100755
--- a/test/encoding
+++ b/test/encoding
@@ -6,7 +6,7 @@ test_begin_subtest "Message with text of unknown charset"
 add_message '[content-type]="text/plain; charset=unknown-8bit"' \
 	    "[body]=irrelevant"
 output=$(notmuch show id:${gen_msg_id} 2>&1 | notmuch_show_sanitize)
-test_expect_equal "$output" "\fmessage{ id:msg-001@notmuch-test-suite depth:0 match:1 filename:/XXX/mail/msg-001
+test_expect_equal "$output" "\fmessage{ id:msg-001@notmuch-test-suite depth:0 match:1 excluded:0 filename:/XXX/mail/msg-001
 \fheader{
 Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-05) (inbox unread)
 Subject: Test message #1
diff --git a/test/json b/test/json
index 1bdffd2..6439788 100755
--- a/test/json
+++ b/test/json
@@ -5,7 +5,7 @@ test_description="--format=json output"
 test_begin_subtest "Show message: json"
 add_message "[subject]=\"json-show-subject\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"json-show-message\""
 output=$(notmuch show --format=json "json-show-message")
-test_expect_equal "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-subject\", \"From\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"To\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"text/plain\", \"content\": \"json-show-message\n\"}]}, []]]]"
+test_expect_equal "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-subject\", \"From\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"To\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"text/plain\", \"content\": \"json-show-message\n\"}]}, []]]]"
 
 test_begin_subtest "Search message: json"
 add_message "[subject]=\"json-search-subject\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"json-search-message\""
@@ -22,7 +22,7 @@ test_expect_equal "$output" "[{\"thread\": \"XXX\",
 test_begin_subtest "Show message: json, utf-8"
 add_message "[subject]=\"json-show-utf8-body-sübjéct\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"jsön-show-méssage\""
 output=$(notmuch show --format=json "jsön-show-méssage")
-test_expect_equal "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-utf8-body-sübjéct\", \"From\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"To\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"text/plain\", \"content\": \"jsön-show-méssage\n\"}]}, []]]]"
+test_expect_equal "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-utf8-body-sübjéct\", \"From\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"To\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"text/plain\", \"content\": \"jsön-show-méssage\n\"}]}, []]]]"
 
 test_begin_subtest "Show message: json, inline attachment filename"
 subject='json-show-inline-attachment-filename'
@@ -35,7 +35,7 @@ emacs_deliver_message \
      (insert \"Message-ID: <$id>\n\")"
 output=$(notmuch show --format=json "id:$id")
 filename=$(notmuch search --output=files "id:$id")
-test_expect_equal "$output" "[[[{\"id\": \"$id\", \"match\": true, \"filename\": \"$filename\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\"], \"headers\": {\"Subject\": \"$subject\", \"From\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"To\": \"test_suite@notmuchmail.org\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"multipart/mixed\", \"content\": [{\"id\": 2, \"content-type\": \"text/plain\", \"content\": \"This is a test message with inline attachment with a filename\"}, {\"id\": 3, \"content-type\": \"application/octet-stream\", \"filename\": \"README\"}]}]}, []]]]"
+test_expect_equal "$output" "[[[{\"id\": \"$id\", \"match\": true, \"excluded\": false, \"filename\": \"$filename\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\"], \"headers\": {\"Subject\": \"$subject\", \"From\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"To\": \"test_suite@notmuchmail.org\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"multipart/mixed\", \"content\": [{\"id\": 2, \"content-type\": \"text/plain\", \"content\": \"This is a test message with inline attachment with a filename\"}, {\"id\": 3, \"content-type\": \"application/octet-stream\", \"filename\": \"README\"}]}]}, []]]]"
 
 test_begin_subtest "Search message: json, utf-8"
 add_message "[subject]=\"json-search-utf8-body-sübjéct\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"jsön-search-méssage\""
diff --git a/test/maildir-sync b/test/maildir-sync
index 1ee2db0..d72ec07 100755
--- a/test/maildir-sync
+++ b/test/maildir-sync
@@ -46,6 +46,7 @@ test_begin_subtest "notmuch show works with renamed file (without notmuch new)"
 output=$(notmuch show --format=json id:${gen_msg_id} | filter_show_json)
 test_expect_equal "$output" '[[[{"id": "adding-replied-tag@notmuch-test-suite",
 "match": true,
+"excluded": false,
 "filename": "MAIL_DIR/cur/adding-replied-tag:2,RS",
 "timestamp": 978709437,
 "date_relative": "2001-01-05",
diff --git a/test/multipart b/test/multipart
index a3036b4..53782c6 100755
--- a/test/multipart
+++ b/test/multipart
@@ -108,7 +108,7 @@ notmuch new > /dev/null
 test_begin_subtest "--format=text --part=0, full message"
 notmuch show --format=text --part=0 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT
 cat <<EOF >EXPECTED
-\fmessage{ id:87liy5ap00.fsf@yoom.home.cworth.org depth:0 match:1 filename:${MAIL_DIR}/multipart
+\fmessage{ id:87liy5ap00.fsf@yoom.home.cworth.org depth:0 match:1 excluded:0 filename:${MAIL_DIR}/multipart
 \fheader{
 Carl Worth <cworth@cworth.org> (2001-01-05) (attachment inbox signed unread)
 Subject: Multipart message
@@ -322,7 +322,7 @@ notmuch show --format=json --part=0 'id:87liy5ap00.fsf@yoom.home.cworth.org' | s
 echo >>OUTPUT # expect *no* newline at end of output
 cat <<EOF >EXPECTED
 
-{"id": "87liy5ap00.fsf@yoom.home.cworth.org", "match": true, "filename": "${MAIL_DIR}/multipart", "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["attachment","inbox","signed","unread"], "headers": {"Subject": "Multipart message", "From": "Carl Worth <cworth@cworth.org>", "To": "cworth@cworth.org", "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, "body": [
+{"id": "87liy5ap00.fsf@yoom.home.cworth.org", "match": true, "excluded": false, "filename": "${MAIL_DIR}/multipart", "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["attachment","inbox","signed","unread"], "headers": {"Subject": "Multipart message", "From": "Carl Worth <cworth@cworth.org>", "To": "cworth@cworth.org", "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, "body": [
 {"id": 1, "content-type": "multipart/signed", "content": [
 {"id": 2, "content-type": "multipart/mixed", "content": [
 {"id": 3, "content-type": "message/rfc822", "content": [{"headers": {"Subject": "html message", "From": "Carl Worth <cworth@cworth.org>", "To": "cworth@cworth.org", "Date": "Fri, 05 Jan 2001 15:42:57 +0000"}, "body": [
@@ -594,4 +594,4 @@ notmuch show --format=raw --part=3 id:base64-part-with-crlf > crlf.out
 echo -n -e "\xEF\x0D\x0A" > crlf.expected
 test_expect_equal_file crlf.out crlf.expected
 
-test_done
+test_done
\ No newline at end of file
diff --git a/test/thread-naming b/test/thread-naming
index 942e593..1a1a48f 100755
--- a/test/thread-naming
+++ b/test/thread-naming
@@ -65,7 +65,7 @@ test_expect_equal "$output" "thread:XXX   2001-01-12 [6/8] Notmuch Test Suite; t
 
 test_begin_subtest 'Test order of messages in "notmuch show"'
 output=$(notmuch show thread-naming | notmuch_show_sanitize)
-test_expect_equal "$output" "\fmessage{ id:msg-$(printf "%03d" $first)@notmuch-test-suite depth:0 match:1 filename:/XXX/mail/msg-$(printf "%03d" $first)
+test_expect_equal "$output" "\fmessage{ id:msg-$(printf "%03d" $first)@notmuch-test-suite depth:0 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $first)
 \fheader{
 Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-05) (unread)
 Subject: thread-naming: Initial thread subject
@@ -79,7 +79,7 @@ This is just a test message (#$first)
 \fpart}
 \fbody}
 \fmessage}
-\fmessage{ id:msg-$(printf "%03d" $((first + 1)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 1)))
+\fmessage{ id:msg-$(printf "%03d" $((first + 1)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 1)))
 \fheader{
 Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-06) (inbox unread)
 Subject: thread-naming: Older changed subject
@@ -93,7 +93,7 @@ This is just a test message (#$((first + 1)))
 \fpart}
 \fbody}
 \fmessage}
-\fmessage{ id:msg-$(printf "%03d" $((first + 2)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 2)))
+\fmessage{ id:msg-$(printf "%03d" $((first + 2)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 2)))
 \fheader{
 Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-07) (inbox unread)
 Subject: thread-naming: Newer changed subject
@@ -107,7 +107,7 @@ This is just a test message (#$((first + 2)))
 \fpart}
 \fbody}
 \fmessage}
-\fmessage{ id:msg-$(printf "%03d" $((first + 3)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 3)))
+\fmessage{ id:msg-$(printf "%03d" $((first + 3)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 3)))
 \fheader{
 Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-08) (unread)
 Subject: thread-naming: Final thread subject
@@ -121,7 +121,7 @@ This is just a test message (#$((first + 3)))
 \fpart}
 \fbody}
 \fmessage}
-\fmessage{ id:msg-$(printf "%03d" $((first + 4)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 4)))
+\fmessage{ id:msg-$(printf "%03d" $((first + 4)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 4)))
 \fheader{
 Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-09) (inbox unread)
 Subject: Re: thread-naming: Initial thread subject
@@ -135,7 +135,7 @@ This is just a test message (#$((first + 4)))
 \fpart}
 \fbody}
 \fmessage}
-\fmessage{ id:msg-$(printf "%03d" $((first + 5)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 5)))
+\fmessage{ id:msg-$(printf "%03d" $((first + 5)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 5)))
 \fheader{
 Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-10) (inbox unread)
 Subject: Aw: thread-naming: Initial thread subject
@@ -149,7 +149,7 @@ This is just a test message (#$((first + 5)))
 \fpart}
 \fbody}
 \fmessage}
-\fmessage{ id:msg-$(printf "%03d" $((first + 6)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 6)))
+\fmessage{ id:msg-$(printf "%03d" $((first + 6)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 6)))
 \fheader{
 Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-11) (inbox unread)
 Subject: Vs: thread-naming: Initial thread subject
@@ -163,7 +163,7 @@ This is just a test message (#$((first + 6)))
 \fpart}
 \fbody}
 \fmessage}
-\fmessage{ id:msg-$(printf "%03d" $((first + 7)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 7)))
+\fmessage{ id:msg-$(printf "%03d" $((first + 7)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 7)))
 \fheader{
 Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-12) (inbox unread)
 Subject: Sv: thread-naming: Initial thread subject
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Patch v7 10/13] man: update manpage for notmuch-show --no-exclude option
  2012-03-01 22:30 [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters
                   ` (8 preceding siblings ...)
  2012-03-01 22:30 ` [Patch v7 09/13] test: update tests to reflect the exclude flag Mark Walters
@ 2012-03-01 22:30 ` Mark Walters
  2012-03-01 22:30 ` [Patch v7 11/13] cli: omit excluded messages in results where appropriate Mark Walters
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Mark Walters @ 2012-03-01 22:30 UTC (permalink / raw)
  To: notmuch

---
 man/man1/notmuch-show.1 |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/man/man1/notmuch-show.1 b/man/man1/notmuch-show.1
index 4c5db94..d75d971 100644
--- a/man/man1/notmuch-show.1
+++ b/man/man1/notmuch-show.1
@@ -128,6 +128,13 @@ multipart/encrypted part will be replaced by the decrypted
 content.
 .RE
 
+.RS 4
+.TP 4
+.B \-\-no-exclude
+
+Do not exclude the messages matching search.exclude_tags in the config file.
+.RE
+
 A common use of
 .B notmuch show
 is to display a single thread of email messages. For this, use a
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Patch v7 11/13] cli: omit excluded messages in results where appropriate.
  2012-03-01 22:30 [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters
                   ` (9 preceding siblings ...)
  2012-03-01 22:30 ` [Patch v7 10/13] man: update manpage for notmuch-show --no-exclude option Mark Walters
@ 2012-03-01 22:30 ` Mark Walters
  2012-03-01 22:30 ` [Patch v7 12/13] emacs: show: recognize the exclude flag Mark Walters
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Mark Walters @ 2012-03-01 22:30 UTC (permalink / raw)
  To: notmuch

In all cases of notmuch count/search/show where the results returned
cannot reflect the exclude flag return just the matched not-excluded
results. If the caller wishes to have all the matched results (i.e.,
including the excluded ones) they should call with the
--no-exclude option.

The relevant cases are
    count: both threads and messages
    search: all cases except the summary view
    show: mbox format
---
 notmuch-count.c  |    2 ++
 notmuch-search.c |    9 +++++++++
 notmuch-show.c   |    6 ++++++
 3 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/notmuch-count.c b/notmuch-count.c
index 5364507..46b76ae 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -88,6 +88,8 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 	    notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
     }
 
+    notmuch_query_set_omit_excluded_messages (query, TRUE);
+
     switch (output) {
     case OUTPUT_MESSAGES:
 	printf ("%u\n", notmuch_query_count_messages (query));
diff --git a/notmuch-search.c b/notmuch-search.c
index 6d6c0e6..f6061e4 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -210,6 +210,9 @@ 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)
@@ -300,6 +303,8 @@ 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)
@@ -371,6 +376,10 @@ 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? */
+
     /* Special-case query of "*" for better performance. */
     if (strcmp (notmuch_query_get_query_string (query), "*") == 0) {
 	tags = notmuch_database_get_all_tags (notmuch);
diff --git a/notmuch-show.c b/notmuch-show.c
index 8c0b925..05d51b2 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -1030,6 +1030,7 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
 	    fprintf (stderr, "Error: specifying parts is incompatible with mbox output format.\n");
 	    return 1;
 	}
+
 	format = &format_mbox;
 	break;
     case NOTMUCH_FORMAT_RAW:
@@ -1087,6 +1088,11 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
 	return 1;
     }
 
+    /* if format=mbox then we can not output excluded messages as
+     * there is no way to make the exclude flag available */
+    if (format_sel == NOTMUCH_FORMAT_MBOX)
+	notmuch_query_set_omit_excluded_messages (query, TRUE);
+
     /* If a single message is requested we do not use search_excludes. */
     if (params.part >= 0)
 	ret = do_show_single (ctx, query, format, &params);
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Patch v7 12/13] emacs: show: recognize the exclude flag.
  2012-03-01 22:30 [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters
                   ` (10 preceding siblings ...)
  2012-03-01 22:30 ` [Patch v7 11/13] cli: omit excluded messages in results where appropriate Mark Walters
@ 2012-03-01 22:30 ` Mark Walters
  2012-03-01 22:30 ` [Patch v7 13/13] emacs: notmuch.el ignore excluded matches Mark Walters
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Mark Walters @ 2012-03-01 22:30 UTC (permalink / raw)
  To: notmuch

Show mode will recognize the exclude flag by not opening excluding
messages by default, and will start at the first matching non-excluded
message. If there are no matching non-excluded messages it will go to
the first matching (necessarily excluded) message.
---
 emacs/notmuch-show.el |   36 +++++++++++++++++++++++++++---------
 1 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 7c4c0be..4a60631 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -981,7 +981,8 @@ current buffer, if possible."
 
     ;; Message visibility depends on whether it matched the search
     ;; criteria.
-    (notmuch-show-message-visible msg (plist-get msg :match))))
+    (notmuch-show-message-visible msg (and (plist-get msg :match)
+					   (not (plist-get msg :excluded))))))
 
 (defun notmuch-show-toggle-process-crypto ()
   "Toggle the processing of cryptographic MIME parts."
@@ -1081,11 +1082,7 @@ function is used."
 	  notmuch-show-parent-buffer parent-buffer
 	  notmuch-show-query-context query-context)
     (notmuch-show-build-buffer)
-
-    ;; Move to the first open message and mark it read
-    (if (notmuch-show-message-visible-p)
-	(notmuch-show-mark-read)
-      (notmuch-show-next-open-message))))
+    (notmuch-show-goto-first-wanted-message)))
 
 (defun notmuch-show-build-buffer ()
   (let ((inhibit-read-only t))
@@ -1167,9 +1164,7 @@ reset based on the original query."
 	(notmuch-show-apply-state state)
       ;; We're resetting state, so navigate to the first open message
       ;; and mark it read, just like opening a new show buffer.
-      (if (notmuch-show-message-visible-p)
-	  (notmuch-show-mark-read)
-	(notmuch-show-next-open-message)))))
+      (notmuch-show-goto-first-wanted-message))))
 
 (defvar notmuch-show-stash-map
   (let ((map (make-sparse-keymap)))
@@ -1601,6 +1596,29 @@ to show, nil otherwise."
 	(goto-char (point-max))))
     r))
 
+(defun notmuch-show-next-matching-message ()
+  "Show the next matching message."
+  (interactive)
+  (let (r)
+    (while (and (setq r (notmuch-show-goto-message-next))
+		(not (notmuch-show-get-prop :match))))
+    (if r
+	(progn
+	  (notmuch-show-mark-read)
+	  (notmuch-show-message-adjust))
+      (goto-char (point-max)))))
+
+(defun notmuch-show-goto-first-wanted-message ()
+  "Move to the first open message and mark it read"
+  (goto-char (point-min))
+  (if (notmuch-show-message-visible-p)
+      (notmuch-show-mark-read)
+    (notmuch-show-next-open-message))
+  (when (eobp)
+    (goto-char (point-min))
+    (unless (notmuch-show-get-prop :match)
+      (notmuch-show-next-matching-message))))
+
 (defun notmuch-show-previous-open-message ()
   "Show the previous open message."
   (interactive)
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Patch v7 13/13] emacs: notmuch.el ignore excluded matches
  2012-03-01 22:30 [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters
                   ` (11 preceding siblings ...)
  2012-03-01 22:30 ` [Patch v7 12/13] emacs: show: recognize the exclude flag Mark Walters
@ 2012-03-01 22:30 ` Mark Walters
  2012-03-02 13:03 ` [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag David Bremner
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Mark Walters @ 2012-03-01 22:30 UTC (permalink / raw)
  To: notmuch

This is a small change to make notmuch.el ignore excluded matches.  In
the future it could do something better like add a button for
rerunning the search with the excludes (particularly if nothing
matches with the excludes) or having them invisible and allowing the
visibility to be toggled.
---
 emacs/notmuch.el |   22 ++++++++++++----------
 1 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index f851c6f..99e0c93 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -872,16 +872,18 @@ non-authors is found, assume that all of the authors match."
 		      (goto-char (point-max))
 		      (if (/= (match-beginning 1) line)
 			  (insert (concat "Error: Unexpected output from notmuch search:\n" (substring string line (match-beginning 1)) "\n")))
-		      (let ((beg (point)))
-			(notmuch-search-show-result date count authors
-						    (notmuch-prettify-subject subject) tags)
-			(notmuch-search-color-line beg (point) tag-list)
-			(put-text-property beg (point) 'notmuch-search-thread-id thread-id)
-			(put-text-property beg (point) 'notmuch-search-authors authors)
-			(put-text-property beg (point) 'notmuch-search-subject subject)
-			(when (string= thread-id notmuch-search-target-thread)
-			  (set 'found-target beg)
-			  (set 'notmuch-search-target-thread "found")))
+		      ;; We currently just throw away excluded matches.
+		      (unless (eq (aref count 1) ?0)
+			(let ((beg (point)))
+			  (notmuch-search-show-result date count authors
+						      (notmuch-prettify-subject subject) tags)
+			  (notmuch-search-color-line beg (point) tag-list)
+			  (put-text-property beg (point) 'notmuch-search-thread-id thread-id)
+			  (put-text-property beg (point) 'notmuch-search-authors authors)
+			  (put-text-property beg (point) 'notmuch-search-subject subject)
+			  (when (string= thread-id notmuch-search-target-thread)
+			    (set 'found-target beg)
+			    (set 'notmuch-search-target-thread "found"))))
 		      (set 'line (match-end 0)))
 		  (set 'more nil)
 		  (while (and (< line (length string)) (= (elt string line) ?\n))
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag
  2012-03-01 22:30 [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters
                   ` (12 preceding siblings ...)
  2012-03-01 22:30 ` [Patch v7 13/13] emacs: notmuch.el ignore excluded matches Mark Walters
@ 2012-03-02 13:03 ` David Bremner
  2012-03-02 20:31 ` Mark Walters
  2012-03-03  3:42 ` Mark Walters
  15 siblings, 0 replies; 18+ messages in thread
From: David Bremner @ 2012-03-02 13:03 UTC (permalink / raw)
  To: Mark Walters, notmuch

On Thu,  1 Mar 2012 22:30:32 +0000, Mark Walters <markwalters1009@gmail.com> wrote:
> This is essentially the same as
> id:"1330157204-26094-1-git-send-email-markwalters1009@gmail.com" but
> has been rebased against master. The changes are to patch 12/13 for
> notmuch-show.el (which was posted as a followup to the previous series)
> and to the tests (patch 9/13) which changed in Austin's JSON show
> rewrite.

Pushed, 

d

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag
  2012-03-01 22:30 [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters
                   ` (13 preceding siblings ...)
  2012-03-02 13:03 ` [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag David Bremner
@ 2012-03-02 20:31 ` Mark Walters
  2012-03-03  3:42 ` Mark Walters
  15 siblings, 0 replies; 18+ messages in thread
From: Mark Walters @ 2012-03-02 20:31 UTC (permalink / raw)
  To: notmuch, Jameson Graef Rollins

On Thu,  1 Mar 2012 22:30:32 +0000, Mark Walters <markwalters1009@gmail.com> wrote:
> This is essentially the same as
> id:"1330157204-26094-1-git-send-email-markwalters1009@gmail.com" but
> has been rebased against master. The changes are to patch 12/13 for
> notmuch-show.el (which was posted as a followup to the previous series)
> and to the tests (patch 9/13) which changed in Austin's JSON show
> rewrite.

This series has some significant speed issues in some use cases. It also
defaults to returning excluded messages on the command line which is
wrong.

This adds an option --include-excluded to tell search to return all
threads (excluded threads will show up as [0/n] in the match column) but
otherwise (default) omits them.

It is not clear whether there is sufficient utility to make it
worthwhile keeping this option but it should make the series usable
while that is worked out.

I will try to check old emails and work out what the uses were/corner
cases fixed by the series and post that later. It may be the case that 
the show part of this series is worth keeping but not the search part.

Best wishes 

Mark


--->8--- 

From 64416494f4eceb9f0afbdcb973fd7a82e1e2fcf5 Mon Sep 17 00:00:00 2001
From: Mark Walters <markwalters1009@gmail.com>
Date: Fri, 2 Mar 2012 20:19:01 +0000
Subject: [PATCH] cli: make notmuch-search.c default to omitting excluded messages

This is a temporary measure to make notmuch-search.c default to
omitting threads only matching in excluded messages entirely. This is
intended as a temporary measure while we decide whether to revert this
part of the exclude_flag series entirely.
---
 notmuch-search.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/notmuch-search.c b/notmuch-search.c
index f6061e4..3d73bd5 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -436,6 +436,7 @@ 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 include_excluded = FALSE;
     unsigned int i;
 
     enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT }
@@ -458,6 +459,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, &include_excluded, "include-excluded", 'd', 0 },
 	{ NOTMUCH_OPT_INT, &offset, "offset", 'O', 0 },
 	{ NOTMUCH_OPT_INT, &limit, "limit", 'L', 0  },
 	{ 0, 0, 0, 0, 0 }
@@ -514,6 +516,8 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
 	for (i = 0; i < search_exclude_tags_length; i++)
 	    notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
     }
+    if (!include_excluded)
+	notmuch_query_set_omit_excluded_messages (query, TRUE);
 
     switch (output) {
     default:
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag
  2012-03-01 22:30 [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters
                   ` (14 preceding siblings ...)
  2012-03-02 20:31 ` Mark Walters
@ 2012-03-03  3:42 ` Mark Walters
  2012-03-03 12:41   ` Mark Walters
  15 siblings, 1 reply; 18+ messages in thread
From: Mark Walters @ 2012-03-03  3:42 UTC (permalink / raw)
  To: notmuch

On Thu,  1 Mar 2012 22:30:32 +0000, Mark Walters <markwalters1009@gmail.com> wrote:
> This is essentially the same as
> id:"1330157204-26094-1-git-send-email-markwalters1009@gmail.com" but
> has been rebased against master. The changes are to patch 12/13 for
> notmuch-show.el (which was posted as a followup to the previous series)
> and to the tests (patch 9/13) which changed in Austin's JSON show
> rewrite.

There are some problems with this series which were discussed on irc
today. In particular the cli notmuch search output is too cluttered for
human readability (with lots of excluded threads showing [0/n]) and in
some cases it is too slow (it is the same speed as if there were no
excludes but looks slower as it outputs less). The following is a
proposal to address this.

PROPOSAL

lib: Change the notmuch_query_set_omit_excluded_messages to a
notmuch_query_set_with_excluded_messages option (essentially the
negation) This just affects the `seeding' of the thread search: whole
threads are returned regardless but unless this is set only threads that
match in a non-excluded message are returned. In either case excluded
messages have the exclude flag set.

cli: replace the --no-excludes option with a --with-excluded option
which is roughly the *same*: it outputs the excluded messages (but marks
them excluded in so far as the output allows it). I deal with each of
count/search and show in turn.

count: apply excludes unless --with-excluded. This includes the excluded
messages/threads in the count. This could be done with the lib call
above but it is easier not to set the excludes in the first place.

search: for output=threads|messages|tags we either set or not the
exclude terms depending on the --with-excluded option. 

For output=summary (default) we normally return just those threads which
match in a non-excluded message. With the --with-excluded option return
all threads that match (using the with_excluded lib call). In both cases
the count is [x/y] where x is the number of matching non-excluded
messages and y is the total number of messages.  It will not be possible
to get the pre-exclude output; with the --with-excluded option you get
the same threads but the count (x in the above) will show matched and
non-excluded instead of matched.

show: raw/part are irrelevant as they do not (and should not) apply
excludes. 

When given --with-excluded it returns all messages (in all threads if
given --entire-thread) and marks excluded if possible (i.e., unless
format=mbox).

The remaining cases are all when --with-excluded is not passed. We can
have format=json/text/mbox and entire-thread or not. We do not pass
with_excluded to the lib so we only get threads matching in a
non-excluded message. The question is which of the messages in these
threads to output. Note emacs will not care as it will pass in the
--with-excluded option.

Perhaps --entire-thread should return the whole thread including
excluded messages but without --entire-thread just return the
matching-non-excluded messages. We have flexibility here as show did not
do anything with exclude_tags until this series so not even git users
will have got used to any particular behaviour.

Does this seem reasonable? The only potential problem I can see is
someone wanting exactly the pre-exclude search output. Oh and someone
might suggest a better name than --with-excluded: --include-excluded
seemed worse!

Best wishes

Mark

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag
  2012-03-03  3:42 ` Mark Walters
@ 2012-03-03 12:41   ` Mark Walters
  0 siblings, 0 replies; 18+ messages in thread
From: Mark Walters @ 2012-03-03 12:41 UTC (permalink / raw)
  To: notmuch

On Sat, 03 Mar 2012 03:42:44 +0000, Mark Walters <markwalters1009@gmail.com> wrote:
> On Thu,  1 Mar 2012 22:30:32 +0000, Mark Walters <markwalters1009@gmail.com> wrote:
> > This is essentially the same as
> > id:"1330157204-26094-1-git-send-email-markwalters1009@gmail.com" but
> > has been rebased against master. The changes are to patch 12/13 for
> > notmuch-show.el (which was posted as a followup to the previous series)
> > and to the tests (patch 9/13) which changed in Austin's JSON show
> > rewrite.
> 
> There are some problems with this series which were discussed on irc
> today. In particular the cli notmuch search output is too cluttered for
> human readability (with lots of excluded threads showing [0/n]) and in
> some cases it is too slow (it is the same speed as if there were no
> excludes but looks slower as it outputs less). The following is a
> proposal to address this.

I have thought some more about this and this does seem the correct way
to go. I have implemented this and will post it as a patch series
shortly.

The original series essentially distinguished between show
everything and mark excluded (default) and show everything not marking
excluded (with the --no-exclude option). These two options are very
similar and do not include the option of just throwing away the excluded
messages. 

This proposal makes the two options roughly "return only non-excluded
messages" (the default) and return all messages marking the excluded
ones (with a new option --with-excluded which replace the --no-exclude
option).

The exact behaviour is a little more subtle but that is essentially it
(as detailed in the parent message).

> PROPOSAL
> 
> lib: Change the notmuch_query_set_omit_excluded_messages to a
> notmuch_query_set_with_excluded_messages option (essentially the
> negation) This just affects the `seeding' of the thread search: whole
> threads are returned regardless but unless this is set only threads that
> match in a non-excluded message are returned. In either case excluded
> messages have the exclude flag set.
> 
> cli: replace the --no-excludes option with a --with-excluded option
> which is roughly the *same*: it outputs the excluded messages (but marks
> them excluded in so far as the output allows it). I deal with each of
> count/search and show in turn.
> 
> count: apply excludes unless --with-excluded. This includes the excluded
> messages/threads in the count. This could be done with the lib call
> above but it is easier not to set the excludes in the first place.
> 
> search: for output=threads|messages|tags we either set or not the
> exclude terms depending on the --with-excluded option. 
> 
> For output=summary (default) we normally return just those threads which
> match in a non-excluded message. With the --with-excluded option return
> all threads that match (using the with_excluded lib call). In both cases
> the count is [x/y] where x is the number of matching non-excluded
> messages and y is the total number of messages.  It will not be possible
> to get the pre-exclude output; with the --with-excluded option you get
> the same threads but the count (x in the above) will show matched and
> non-excluded instead of matched.
> 
> show: raw/part are irrelevant as they do not (and should not) apply
> excludes. 
> 
> When given --with-excluded it returns all messages (in all threads if
> given --entire-thread) and marks excluded if possible (i.e., unless
> format=mbox).
> 
> The remaining cases are all when --with-excluded is not passed. We can
> have format=json/text/mbox and entire-thread or not. We do not pass
> with_excluded to the lib so we only get threads matching in a
> non-excluded message. The question is which of the messages in these
> threads to output. Note emacs will not care as it will pass in the
> --with-excluded option.
> 
> Perhaps --entire-thread should return the whole thread including
> excluded messages but without --entire-thread just return the
> matching-non-excluded messages. We have flexibility here as show did not
> do anything with exclude_tags until this series so not even git users
> will have got used to any particular behaviour.

I have followed this behaviour as it does seem the logical one. If the
user asks for entire-thread it would seem odd to omit some messages from
it (and if passing it to some other program the missing messages could
inhibit reconstruction of the thread). When it is not entire-thread it
would be weird to return all matched messages (including the excluded
ones) in threads with a matched non-excluded message but not
matched-excluded messages in threads which only contain matched-excluded
messages.

As an example of a use for the former is an emacs frontend showing
threaded messages (eg notmuch-pick): it would want all the messages in
the threads it gets (or it will mess up the threading) but probably does
not want threads that only match in excluded messages.

Best wishes

Mark

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2012-03-03 12:39 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-01 22:30 [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters
2012-03-01 22:30 ` [Patch v7 01/13] cli: add --no-exclude option to count and search Mark Walters
2012-03-01 22:30 ` [Patch v7 02/13] cli: Add --no-exclude to the man pages for search and count Mark Walters
2012-03-01 22:30 ` [Patch v7 03/13] test: add tests for new cli --no-exclude option Mark Walters
2012-03-01 22:30 ` [Patch v7 04/13] lib: Rearrange the exclude code in query.cc Mark Walters
2012-03-01 22:30 ` [Patch v7 05/13] lib: Make notmuch_query_search_messages set the exclude flag Mark Walters
2012-03-01 22:30 ` [Patch v7 06/13] lib: Add the exclude flag to notmuch_query_search_threads Mark Walters
2012-03-01 22:30 ` [Patch v7 07/13] test: update search test to reflect exclude flag Mark Walters
2012-03-01 22:30 ` [Patch v7 08/13] cli: Make notmuch-show respect excludes Mark Walters
2012-03-01 22:30 ` [Patch v7 09/13] test: update tests to reflect the exclude flag Mark Walters
2012-03-01 22:30 ` [Patch v7 10/13] man: update manpage for notmuch-show --no-exclude option Mark Walters
2012-03-01 22:30 ` [Patch v7 11/13] cli: omit excluded messages in results where appropriate Mark Walters
2012-03-01 22:30 ` [Patch v7 12/13] emacs: show: recognize the exclude flag Mark Walters
2012-03-01 22:30 ` [Patch v7 13/13] emacs: notmuch.el ignore excluded matches Mark Walters
2012-03-02 13:03 ` [Patch v7 00/13] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag David Bremner
2012-03-02 20:31 ` Mark Walters
2012-03-03  3:42 ` Mark Walters
2012-03-03 12:41   ` Mark Walters

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).