[PATCH v6 6/6] test: add tests for notmuch search --first and --maxitems

2011-11-13 Thread Jani Nikula
Signed-off-by: Jani Nikula 
---
 test/notmuch-test|1 +
 test/search-limiting |   71 ++
 2 files changed, 72 insertions(+), 0 deletions(-)
 create mode 100755 test/search-limiting

diff --git a/test/notmuch-test b/test/notmuch-test
index 587adb5..435b469 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -25,6 +25,7 @@ TESTS="
   search-by-folder
   search-position-overlap-bug
   search-insufficient-from-quoting
+  search-limiting
   json
   multipart
   thread-naming
diff --git a/test/search-limiting b/test/search-limiting
new file mode 100755
index 000..45cc0a9
--- /dev/null
+++ b/test/search-limiting
@@ -0,0 +1,71 @@
+#!/usr/bin/env bash
+test_description='"notmuch search" --first and --maxitems parameters'
+. ./test-lib.sh
+
+add_email_corpus
+
+for outp in messages threads; do
+test_begin_subtest "${outp}: maxitems does the right thing"
+notmuch search --output=${outp} "*" | head -n 20 >expected
+notmuch search --output=${outp} --maxitems=20 "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: concatenation of limited searches"
+notmuch search --output=${outp} "*" | head -n 20 >expected
+notmuch search --output=${outp} --maxitems=10 "*" >output
+notmuch search --output=${outp} --maxitems=10 --first=10 "*" >>output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: maxitems larger than result set"
+N=`notmuch count --output=${outp} "*"`
+notmuch search --output=${outp} "*" >expected
+notmuch search --output=${outp} --maxitems=$((1 + ${N})) "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: maxitems = 0"
+test_expect_equal "`notmuch search --output=${outp} --maxitems=0 "*"`" ""
+
+test_begin_subtest "${outp}: first does the right thing"
+# note: tail -n +N is 1-based
+notmuch search --output=${outp} "*" | tail -n +21 >expected
+notmuch search --output=${outp} --first=20 "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: first = 0"
+notmuch search --output=${outp} "*" >expected
+notmuch search --output=${outp} --first=0 "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: negative first"
+notmuch search --output=${outp} "*" | tail -n 20 >expected
+notmuch search --output=${outp} --first=-20 "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: negative first"
+notmuch search --output=${outp} "*" | tail -n 1 >expected
+notmuch search --output=${outp} --first=-1 "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: negative first combined with maxitems"
+notmuch search --output=${outp} "*" | tail -n 20 | head -n 10 >expected
+notmuch search --output=${outp} --first=-20 --maxitems=10 "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: negative first combined with equal maxitems"
+notmuch search --output=${outp} "*" | tail -n 20 >expected
+notmuch search --output=${outp} --first=-20 --maxitems=20 "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: negative first combined with large maxitems"
+notmuch search --output=${outp} "*" | tail -n 20 >expected
+notmuch search --output=${outp} --first=-20 --maxitems=50 "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: negative first larger then results"
+N=`notmuch count --output=${outp} "*"`
+notmuch search --output=${outp} "*" >expected
+notmuch search --output=${outp} --first=-$((1 + ${N})) "*" >output
+test_expect_equal_file expected output
+done
+
+test_done
-- 
1.7.5.4



[PATCH v6 5/6] test: add tests for notmuch count

2011-11-13 Thread Jani Nikula
Signed-off-by: Jani Nikula 
---
 test/count|   40 
 test/notmuch-test |1 +
 2 files changed, 41 insertions(+), 0 deletions(-)
 create mode 100755 test/count

diff --git a/test/count b/test/count
new file mode 100755
index 000..300b171
--- /dev/null
+++ b/test/count
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+test_description='"notmuch count" for messages and threads'
+. ./test-lib.sh
+
+add_email_corpus
+
+SEARCH="\"*\""
+
+test_begin_subtest "message count is the default for notmuch count"
+test_expect_equal \
+"`notmuch search --output=messages ${SEARCH} | wc -l`" \
+"`notmuch count ${SEARCH}`"
+
+test_begin_subtest "message count with --output=messages"
+test_expect_equal \
+"`notmuch search --output=messages ${SEARCH} | wc -l`" \
+"`notmuch count --output=messages ${SEARCH}`"
+
+test_begin_subtest "thread count with --output=threads"
+test_expect_equal \
+"`notmuch search --output=threads ${SEARCH} | wc -l`" \
+"`notmuch count --output=threads ${SEARCH}`"
+
+test_begin_subtest "thread count is the default for notmuch search"
+test_expect_equal \
+"`notmuch search ${SEARCH} | wc -l`" \
+"`notmuch count --output=threads ${SEARCH}`"
+
+SEARCH="from:cworth and not from:cworth"
+test_begin_subtest "count with no matching messages"
+test_expect_equal \
+"0" \
+"`notmuch count --output=messages ${SEARCH}`"
+
+test_begin_subtest "count with no matching threads"
+test_expect_equal \
+"0" \
+"`notmuch count --output=threads ${SEARCH}`"
+
+test_done
diff --git a/test/notmuch-test b/test/notmuch-test
index 738f8f6..587adb5 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -19,6 +19,7 @@ cd $(dirname "$0")
 TESTS="
   basic
   new
+  count
   search
   search-output
   search-by-folder
-- 
1.7.5.4



[PATCH v6 4/6] cli: add support for --output parameter in notmuch count

2011-11-13 Thread Jani Nikula
Add support for --output=messages (which remains the default) and
--output=threads to notmuch count.

Signed-off-by: Jani Nikula 
---
 NEWS|5 +
 notmuch-count.c |   18 --
 notmuch.1   |   29 +
 notmuch.c   |   20 
 4 files changed, 62 insertions(+), 10 deletions(-)

diff --git a/NEWS b/NEWS
index abc749a..78434d9 100644
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,11 @@ Add "notmuch search" --first and --maxitems options
   The search command now takes options --first=[-]N and --maxitems=N to limit
   the number of results shown.

+Add "notmuch count --output" option
+
+  The count command is now capable of counting threads in addition to
+  messages. This is selected using the new --output=(threads|messages) option.
+
 Notmuch 0.9 (2011-10-01)
 

diff --git a/notmuch-count.c b/notmuch-count.c
index a35be40..20ce334 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -29,6 +29,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 notmuch_query_t *query;
 char *query_str;
 int i;
+notmuch_bool_t output_messages = TRUE;

 argc--; argv++; /* skip subcommand argument */

@@ -37,7 +38,17 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
i++;
break;
}
-   {
+   if (STRNCMP_LITERAL (argv[i], "--output=") == 0) {
+   const char *opt = argv[i] + sizeof ("--output=") - 1;
+   if (strcmp (opt, "threads") == 0) {
+   output_messages = FALSE;
+   } else if (strcmp (opt, "messages") == 0) {
+   output_messages = TRUE;
+   } else {
+   fprintf (stderr, "Invalid value for --output: %s\n", opt);
+   return 1;
+   }
+   } else {
fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
return 1;
}
@@ -71,7 +82,10 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
return 1;
 }

-printf ("%u\n", notmuch_query_count_messages(query));
+if (output_messages)
+   printf ("%u\n", notmuch_query_count_messages (query));
+else
+   printf ("%u\n", notmuch_query_count_threads (query));

 notmuch_query_destroy (query);
 notmuch_database_close (notmuch);
diff --git a/notmuch.1 b/notmuch.1
index 15c3147..64114db 100644
--- a/notmuch.1
+++ b/notmuch.1
@@ -372,14 +372,35 @@ section below for details of the supported syntax for 
.
 .RE
 .RS 4
 .TP 4
-.BR count " ..."
+.BR count " [options...] ..."

 Count messages matching the search terms.

-The number of matching messages is output to stdout.
+The number of matching messages (or threads) is output to stdout.

-With no search terms, a count of all messages in the database will be
-displayed.
+With no search terms, a count of all messages (or threads) in the database will
+be displayed.
+
+Supported options for
+.B count
+include
+.RS 4
+.TP 4
+.B \-\-output=(messages|threads)
+
+.RS 4
+.TP 4
+.B messages
+
+Output the number of matching messages. This is the default.
+.RE
+.RS 4
+.TP 4
+.B threads
+
+Output the number of matching threads.
+.RE
+.RE
 .RE
 .RE

diff --git a/notmuch.c b/notmuch.c
index 601ffad..0a4ffe9 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -328,12 +328,24 @@ static command_t commands[] = {
   "\tSee \"notmuch help search-terms\" for details of the search\n"
   "\tterms syntax." },
 { "count", notmuch_count_command,
-  " [...]",
+  "[options...]  [...]",
   "Count messages matching the search terms.",
-  "\tThe number of matching messages is output to stdout.\n"
+  "\tThe number of matching messages (or threads) is output to stdout.\n"
+  "\n"
+  "\tWith no search terms, a count of all messages (or threads) in\n"
+  "\tthe database will be displayed.\n"
+  "\n"
+  "\tSupported options for count include:\n"
+  "\n"
+  "\t--output=(messages|threads)\n"
+  "\n"
+  "\t\tmessages (default)\n"
+  "\n"
+  "\t\tOutput the number of matching messages.\n"
+  "\n"
+  "\t\tthreads\n"
   "\n"
-  "\tWith no search terms, a count of all messages in the database\n"
-  "\twill be displayed.\n"
+  "\t\tOutput the number of matching threads.\n"
   "\n"
   "\tSee \"notmuch help search-terms\" for details of the search\n"
   "\tterms syntax." },
-- 
1.7.5.4



[PATCH v6 3/6] cli: drop unused code from notmuch count

2011-11-13 Thread Jani Nikula
Remove unused code within #if 0 blocks from notmuch count.

Signed-off-by: Jani Nikula 
---
 notmuch-count.c |   32 
 1 files changed, 0 insertions(+), 32 deletions(-)

diff --git a/notmuch-count.c b/notmuch-count.c
index 0d700a9..a35be40 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -29,11 +29,6 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 notmuch_query_t *query;
 char *query_str;
 int i;
-#if 0
-char *opt, *end;
-int i, first = 0, max_threads = -1;
-notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST;
-#endif

 argc--; argv++; /* skip subcommand argument */

@@ -42,33 +37,6 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
i++;
break;
}
-#if 0
-   if (STRNCMP_LITERAL (argv[i], "--first=") == 0) {
-   opt = argv[i] + sizeof ("--first=") - 1;
-   first = strtoul (opt, , 10);
-   if (*opt == '\0' || *end != '\0') {
-   fprintf (stderr, "Invalid value for --first: %s\n", opt);
-   return 1;
-   }
-   } else if (STRNCMP_LITERAL (argv[i], "--max-threads=") == 0) {
-   opt = argv[i] + sizeof ("--max-threads=") - 1;
-   max_threads = strtoul (opt, , 10);
-   if (*opt == '\0' || *end != '\0') {
-   fprintf (stderr, "Invalid value for --max-threads: %s\n", opt);
-   return 1;
-   }
-   } else if (STRNCMP_LITERAL (argv[i], "--sort=") == 0) {
-   opt = argv[i] + sizeof ("--sort=") - 1;
-   if (strcmp (opt, "oldest-first") == 0) {
-   sort = NOTMUCH_SORT_OLDEST_FIRST;
-   } else if (strcmp (opt, "newest-first") == 0) {
-   sort = NOTMUCH_SORT_NEWEST_FIRST;
-   } else {
-   fprintf (stderr, "Invalid value for --sort: %s\n", opt);
-   return 1;
-   }
-   } else
-#endif
{
fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
return 1;
-- 
1.7.5.4



[PATCH v6 2/6] cli: add options --first and --maxitems to notmuch search

2011-11-13 Thread Jani Nikula
Add options --first=[-]N and --maxitems=M to notmuch search to determine
the first result and maximum number of results to display.

Option --maxitems=M limits the maximum number of results to display to M.

Option --first=[-]N skips the first N results; with the leading '-' skip
until the Nth result from the end (showing a total of N results if within
bounds of the total number of results and not limited with --maxitems).

Note that --first with a negative N for thread or summary output requires
counting the number of matching threads in advance.

Signed-off-by: Jani Nikula 
---
 NEWS |5 
 notmuch-search.c |   70 -
 notmuch.1|   19 +-
 notmuch.c|9 +++
 4 files changed, 89 insertions(+), 14 deletions(-)

diff --git a/NEWS b/NEWS
index 71c7c9a..abc749a 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,11 @@ Add search terms to  "notmuch dump"
   search/show/tag. The output file argument of dump is deprecated in
   favour of using stdout.

+Add "notmuch search" --first and --maxitems options
+
+  The search command now takes options --first=[-]N and --maxitems=N to limit
+  the number of results shown.
+
 Notmuch 0.9 (2011-10-01)
 

diff --git a/notmuch-search.c b/notmuch-search.c
index 6f04d9a..c62a594 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -194,13 +194,22 @@ static int
 do_search_threads (const search_format_t *format,
   notmuch_query_t *query,
   notmuch_sort_t sort,
-  output_t output)
+  output_t output,
+  int first,
+  int maxitems)
 {
 notmuch_thread_t *thread;
 notmuch_threads_t *threads;
 notmuch_tags_t *tags;
 time_t date;
 int first_thread = 1;
+int i;
+
+if (first < 0) {
+   first += notmuch_query_count_threads (query);
+   if (first < 0)
+   first = 0;
+}

 threads = notmuch_query_search_threads (query);
 if (threads == NULL)
@@ -208,17 +217,23 @@ do_search_threads (const search_format_t *format,

 fputs (format->results_start, stdout);

-for (;
-notmuch_threads_valid (threads);
-notmuch_threads_move_to_next (threads))
+for (i = 0;
+notmuch_threads_valid (threads) &&
+(maxitems < 0 || i < first + maxitems);
+notmuch_threads_move_to_next (threads), i++)
 {
int first_tag = 1;

+   thread = notmuch_threads_get (threads);
+
+   if (i < first) {
+   notmuch_thread_destroy (thread);
+   continue;
+   }
+
if (! first_thread)
fputs (format->item_sep, stdout);

-   thread = notmuch_threads_get (threads);
-
if (output == OUTPUT_THREADS) {
format->item_id (thread, "thread:",
 notmuch_thread_get_thread_id (thread));
@@ -271,12 +286,21 @@ do_search_threads (const search_format_t *format,
 static int
 do_search_messages (const search_format_t *format,
notmuch_query_t *query,
-   output_t output)
+   output_t output,
+   int first,
+   int maxitems)
 {
 notmuch_message_t *message;
 notmuch_messages_t *messages;
 notmuch_filenames_t *filenames;
 int first_message = 1;
+int i;
+
+if (first < 0) {
+   first += notmuch_query_count_messages (query);
+   if (first < 0)
+   first = 0;
+}

 messages = notmuch_query_search_messages (query);
 if (messages == NULL)
@@ -284,10 +308,14 @@ do_search_messages (const search_format_t *format,

 fputs (format->results_start, stdout);

-for (;
-notmuch_messages_valid (messages);
-notmuch_messages_move_to_next (messages))
+for (i = 0;
+notmuch_messages_valid (messages) &&
+(maxitems < 0 || i < first + maxitems);
+notmuch_messages_move_to_next (messages), i++)
 {
+   if (i < first)
+   continue;
+
message = notmuch_messages_get (messages);

if (output == OUTPUT_FILES) {
@@ -394,6 +422,8 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
 const search_format_t *format = _text;
 int i, ret;
 output_t output = OUTPUT_SUMMARY;
+int maxitems = -1; /* unlimited */
+int first = 0;

 argc--; argv++; /* skip subcommand argument */

@@ -412,6 +442,22 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
fprintf (stderr, "Invalid value for --sort: %s\n", opt);
return 1;
}
+   } else if (STRNCMP_LITERAL (argv[i], "--first=") == 0) {
+   char *p;
+   opt = argv[i] + sizeof ("--first=") - 1;
+   first = strtol (opt, , 10);
+   if (*opt == '\0' || p == opt || *p != '\0') {
+   fprintf (stderr, "Invalid value for --first: %s\n", opt);
+   return 1;
+   }
+   } else 

[PATCH v6 1/6] lib: add function to get the number of threads matching a search

2011-11-13 Thread Jani Nikula
Add function notmuch_query_count_threads() to get the number of threads
matching a search. This is done by performing a search and figuring out the
number of unique thread IDs in the matching messages, a significantly
heavier operation than notmuch_query_count_messages().

Signed-off-by: Jani Nikula 
---
 lib/notmuch.h |   14 ++
 lib/query.cc  |   44 
 2 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/lib/notmuch.h b/lib/notmuch.h
index c4330e4..9f23a10 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -609,6 +609,20 @@ notmuch_threads_destroy (notmuch_threads_t *threads);
 unsigned
 notmuch_query_count_messages (notmuch_query_t *query);

+/* Return the number of threads matching a search.
+ *
+ * This function performs a search and returns the number of unique thread IDs
+ * in the matching messages. This is the same as number of threads matching a
+ * search.
+ *
+ * Note that this is a significantly heavier operation than
+ * notmuch_query_count_messages().
+ *
+ * If an error occurs, this function may return 0.
+ */
+unsigned
+notmuch_query_count_threads (notmuch_query_t *query);
+
 /* Get the thread ID of 'thread'.
  *
  * The returned string belongs to 'thread' and as such, should not be
diff --git a/lib/query.cc b/lib/query.cc
index 6f02b04..b6c0f12 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -457,3 +457,47 @@ notmuch_query_count_messages (notmuch_query_t *query)

 return count;
 }
+
+unsigned
+notmuch_query_count_threads (notmuch_query_t *query)
+{
+notmuch_messages_t *messages;
+GHashTable *hash;
+unsigned int count;
+notmuch_sort_t sort;
+
+sort = query->sort;
+query->sort = NOTMUCH_SORT_UNSORTED;
+messages = notmuch_query_search_messages (query);
+query->sort = sort;
+if (messages == NULL)
+   return 0;
+
+hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
+if (hash == NULL) {
+   talloc_free (messages);
+   return 0;
+}
+
+while (notmuch_messages_valid (messages)) {
+   notmuch_message_t *message = notmuch_messages_get (messages);
+   const char *thread_id = notmuch_message_get_thread_id (message);
+   char *thread_id_copy = talloc_strdup (messages, thread_id);
+   if (unlikely (thread_id_copy == NULL)) {
+   notmuch_message_destroy (message);
+   count = 0;
+   goto DONE;
+   }
+   g_hash_table_insert (hash, thread_id_copy, NULL);
+   notmuch_message_destroy (message);
+   notmuch_messages_move_to_next (messages);
+}
+
+count = g_hash_table_size (hash);
+
+  DONE:
+g_hash_table_unref (hash);
+talloc_free (messages);
+
+return count;
+}
-- 
1.7.5.4



[PATCH v6 0/6] lib/cli: limit number of messages in search results

2011-11-13 Thread Jani Nikula
v6, now with the missing 'notmuch help' documentation spotted by
jrollins. Previous version at id:"cover.1321212673.git.jani at nikula.org".

BR,
Jani.


Jani Nikula (6):
  lib: add function to get the number of threads matching a search
  cli: add options --first and --maxitems to notmuch search
  cli: drop unused code from notmuch count
  cli: add support for --output parameter in notmuch count
  test: add tests for notmuch count
  test: add tests for notmuch search --first and --maxitems

 NEWS |   10 +++
 lib/notmuch.h|   14 ++
 lib/query.cc |   44 +++
 notmuch-count.c  |   44 +--
 notmuch-search.c |   70 
 notmuch.1|   48 +
 notmuch.c|   29 +---
 test/count   |   40 
 test/notmuch-test|2 +
 test/search-limiting |   71 ++
 10 files changed, 319 insertions(+), 53 deletions(-)
 create mode 100755 test/count
 create mode 100755 test/search-limiting

-- 
1.7.5.4



[PATCH] Store "from" and "subject" headers in the database.

2011-11-13 Thread Jameson Graef Rollins
On Sun,  6 Nov 2011 12:17:36 -0500, Austin Clements  wrote:
> This is a rebase and cleanup of Istvan Marko's patch from
> id:m3pqnj2j7a.fsf at zsu.kismala.com
> 
> Search retrieves these headers for every message in the search
> results.  Previously, this required opening and parsing every message
> file.  Storing them directly in the database significantly reduces IO
> and computation, speeding up search by between 50% and 10X.

Hey, Austin.  This is a very nice patch.  Short and sweet, a really nice
performance improvement, and a nice gentle fallback.

I just rebuilt my database and I can definitely see the improvements.
Search results are incredibly snappy, and the resultant database is only
about 8% bigger.

I fully endorse this being pushed.

jamie.
-- 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/2013/fe58b8d2/attachment-0001.pgp>


[PATCH v5 6/6] test: add tests for notmuch search --first and --maxitems

2011-11-13 Thread Jani Nikula
Signed-off-by: Jani Nikula 
---
 test/notmuch-test|1 +
 test/search-limiting |   71 ++
 2 files changed, 72 insertions(+), 0 deletions(-)
 create mode 100755 test/search-limiting

diff --git a/test/notmuch-test b/test/notmuch-test
index 587adb5..435b469 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -25,6 +25,7 @@ TESTS="
   search-by-folder
   search-position-overlap-bug
   search-insufficient-from-quoting
+  search-limiting
   json
   multipart
   thread-naming
diff --git a/test/search-limiting b/test/search-limiting
new file mode 100755
index 000..45cc0a9
--- /dev/null
+++ b/test/search-limiting
@@ -0,0 +1,71 @@
+#!/usr/bin/env bash
+test_description='"notmuch search" --first and --maxitems parameters'
+. ./test-lib.sh
+
+add_email_corpus
+
+for outp in messages threads; do
+test_begin_subtest "${outp}: maxitems does the right thing"
+notmuch search --output=${outp} "*" | head -n 20 >expected
+notmuch search --output=${outp} --maxitems=20 "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: concatenation of limited searches"
+notmuch search --output=${outp} "*" | head -n 20 >expected
+notmuch search --output=${outp} --maxitems=10 "*" >output
+notmuch search --output=${outp} --maxitems=10 --first=10 "*" >>output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: maxitems larger than result set"
+N=`notmuch count --output=${outp} "*"`
+notmuch search --output=${outp} "*" >expected
+notmuch search --output=${outp} --maxitems=$((1 + ${N})) "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: maxitems = 0"
+test_expect_equal "`notmuch search --output=${outp} --maxitems=0 "*"`" ""
+
+test_begin_subtest "${outp}: first does the right thing"
+# note: tail -n +N is 1-based
+notmuch search --output=${outp} "*" | tail -n +21 >expected
+notmuch search --output=${outp} --first=20 "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: first = 0"
+notmuch search --output=${outp} "*" >expected
+notmuch search --output=${outp} --first=0 "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: negative first"
+notmuch search --output=${outp} "*" | tail -n 20 >expected
+notmuch search --output=${outp} --first=-20 "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: negative first"
+notmuch search --output=${outp} "*" | tail -n 1 >expected
+notmuch search --output=${outp} --first=-1 "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: negative first combined with maxitems"
+notmuch search --output=${outp} "*" | tail -n 20 | head -n 10 >expected
+notmuch search --output=${outp} --first=-20 --maxitems=10 "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: negative first combined with equal maxitems"
+notmuch search --output=${outp} "*" | tail -n 20 >expected
+notmuch search --output=${outp} --first=-20 --maxitems=20 "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: negative first combined with large maxitems"
+notmuch search --output=${outp} "*" | tail -n 20 >expected
+notmuch search --output=${outp} --first=-20 --maxitems=50 "*" >output
+test_expect_equal_file expected output
+
+test_begin_subtest "${outp}: negative first larger then results"
+N=`notmuch count --output=${outp} "*"`
+notmuch search --output=${outp} "*" >expected
+notmuch search --output=${outp} --first=-$((1 + ${N})) "*" >output
+test_expect_equal_file expected output
+done
+
+test_done
-- 
1.7.5.4



[PATCH v5 5/6] test: add tests for notmuch count

2011-11-13 Thread Jani Nikula
Signed-off-by: Jani Nikula 
---
 test/count|   40 
 test/notmuch-test |1 +
 2 files changed, 41 insertions(+), 0 deletions(-)
 create mode 100755 test/count

diff --git a/test/count b/test/count
new file mode 100755
index 000..300b171
--- /dev/null
+++ b/test/count
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+test_description='"notmuch count" for messages and threads'
+. ./test-lib.sh
+
+add_email_corpus
+
+SEARCH="\"*\""
+
+test_begin_subtest "message count is the default for notmuch count"
+test_expect_equal \
+"`notmuch search --output=messages ${SEARCH} | wc -l`" \
+"`notmuch count ${SEARCH}`"
+
+test_begin_subtest "message count with --output=messages"
+test_expect_equal \
+"`notmuch search --output=messages ${SEARCH} | wc -l`" \
+"`notmuch count --output=messages ${SEARCH}`"
+
+test_begin_subtest "thread count with --output=threads"
+test_expect_equal \
+"`notmuch search --output=threads ${SEARCH} | wc -l`" \
+"`notmuch count --output=threads ${SEARCH}`"
+
+test_begin_subtest "thread count is the default for notmuch search"
+test_expect_equal \
+"`notmuch search ${SEARCH} | wc -l`" \
+"`notmuch count --output=threads ${SEARCH}`"
+
+SEARCH="from:cworth and not from:cworth"
+test_begin_subtest "count with no matching messages"
+test_expect_equal \
+"0" \
+"`notmuch count --output=messages ${SEARCH}`"
+
+test_begin_subtest "count with no matching threads"
+test_expect_equal \
+"0" \
+"`notmuch count --output=threads ${SEARCH}`"
+
+test_done
diff --git a/test/notmuch-test b/test/notmuch-test
index 738f8f6..587adb5 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -19,6 +19,7 @@ cd $(dirname "$0")
 TESTS="
   basic
   new
+  count
   search
   search-output
   search-by-folder
-- 
1.7.5.4



[PATCH v5 4/6] cli: add support for --output parameter in notmuch count

2011-11-13 Thread Jani Nikula
Add support for --output=messages (which remains the default) and
--output=threads to notmuch count.

Signed-off-by: Jani Nikula 
---
 NEWS|5 +
 notmuch-count.c |   18 --
 notmuch.1   |   29 +
 3 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/NEWS b/NEWS
index abc749a..78434d9 100644
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,11 @@ Add "notmuch search" --first and --maxitems options
   The search command now takes options --first=[-]N and --maxitems=N to limit
   the number of results shown.

+Add "notmuch count --output" option
+
+  The count command is now capable of counting threads in addition to
+  messages. This is selected using the new --output=(threads|messages) option.
+
 Notmuch 0.9 (2011-10-01)
 

diff --git a/notmuch-count.c b/notmuch-count.c
index a35be40..20ce334 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -29,6 +29,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 notmuch_query_t *query;
 char *query_str;
 int i;
+notmuch_bool_t output_messages = TRUE;

 argc--; argv++; /* skip subcommand argument */

@@ -37,7 +38,17 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
i++;
break;
}
-   {
+   if (STRNCMP_LITERAL (argv[i], "--output=") == 0) {
+   const char *opt = argv[i] + sizeof ("--output=") - 1;
+   if (strcmp (opt, "threads") == 0) {
+   output_messages = FALSE;
+   } else if (strcmp (opt, "messages") == 0) {
+   output_messages = TRUE;
+   } else {
+   fprintf (stderr, "Invalid value for --output: %s\n", opt);
+   return 1;
+   }
+   } else {
fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
return 1;
}
@@ -71,7 +82,10 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
return 1;
 }

-printf ("%u\n", notmuch_query_count_messages(query));
+if (output_messages)
+   printf ("%u\n", notmuch_query_count_messages (query));
+else
+   printf ("%u\n", notmuch_query_count_threads (query));

 notmuch_query_destroy (query);
 notmuch_database_close (notmuch);
diff --git a/notmuch.1 b/notmuch.1
index 15c3147..64114db 100644
--- a/notmuch.1
+++ b/notmuch.1
@@ -372,14 +372,35 @@ section below for details of the supported syntax for 
.
 .RE
 .RS 4
 .TP 4
-.BR count " ..."
+.BR count " [options...] ..."

 Count messages matching the search terms.

-The number of matching messages is output to stdout.
+The number of matching messages (or threads) is output to stdout.

-With no search terms, a count of all messages in the database will be
-displayed.
+With no search terms, a count of all messages (or threads) in the database will
+be displayed.
+
+Supported options for
+.B count
+include
+.RS 4
+.TP 4
+.B \-\-output=(messages|threads)
+
+.RS 4
+.TP 4
+.B messages
+
+Output the number of matching messages. This is the default.
+.RE
+.RS 4
+.TP 4
+.B threads
+
+Output the number of matching threads.
+.RE
+.RE
 .RE
 .RE

-- 
1.7.5.4



[PATCH v5 3/6] cli: drop unused code from notmuch count

2011-11-13 Thread Jani Nikula
Remove unused code within #if 0 blocks from notmuch count.

Signed-off-by: Jani Nikula 
---
 notmuch-count.c |   32 
 1 files changed, 0 insertions(+), 32 deletions(-)

diff --git a/notmuch-count.c b/notmuch-count.c
index 0d700a9..a35be40 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -29,11 +29,6 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 notmuch_query_t *query;
 char *query_str;
 int i;
-#if 0
-char *opt, *end;
-int i, first = 0, max_threads = -1;
-notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST;
-#endif

 argc--; argv++; /* skip subcommand argument */

@@ -42,33 +37,6 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
i++;
break;
}
-#if 0
-   if (STRNCMP_LITERAL (argv[i], "--first=") == 0) {
-   opt = argv[i] + sizeof ("--first=") - 1;
-   first = strtoul (opt, , 10);
-   if (*opt == '\0' || *end != '\0') {
-   fprintf (stderr, "Invalid value for --first: %s\n", opt);
-   return 1;
-   }
-   } else if (STRNCMP_LITERAL (argv[i], "--max-threads=") == 0) {
-   opt = argv[i] + sizeof ("--max-threads=") - 1;
-   max_threads = strtoul (opt, , 10);
-   if (*opt == '\0' || *end != '\0') {
-   fprintf (stderr, "Invalid value for --max-threads: %s\n", opt);
-   return 1;
-   }
-   } else if (STRNCMP_LITERAL (argv[i], "--sort=") == 0) {
-   opt = argv[i] + sizeof ("--sort=") - 1;
-   if (strcmp (opt, "oldest-first") == 0) {
-   sort = NOTMUCH_SORT_OLDEST_FIRST;
-   } else if (strcmp (opt, "newest-first") == 0) {
-   sort = NOTMUCH_SORT_NEWEST_FIRST;
-   } else {
-   fprintf (stderr, "Invalid value for --sort: %s\n", opt);
-   return 1;
-   }
-   } else
-#endif
{
fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
return 1;
-- 
1.7.5.4



[PATCH v5 1/6] lib: add function to get the number of threads matching a search

2011-11-13 Thread Jani Nikula
Add function notmuch_query_count_threads() to get the number of threads
matching a search. This is done by performing a search and figuring out the
number of unique thread IDs in the matching messages, a significantly
heavier operation than notmuch_query_count_messages().

Signed-off-by: Jani Nikula 
---
 lib/notmuch.h |   14 ++
 lib/query.cc  |   44 
 2 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/lib/notmuch.h b/lib/notmuch.h
index c4330e4..9f23a10 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -609,6 +609,20 @@ notmuch_threads_destroy (notmuch_threads_t *threads);
 unsigned
 notmuch_query_count_messages (notmuch_query_t *query);

+/* Return the number of threads matching a search.
+ *
+ * This function performs a search and returns the number of unique thread IDs
+ * in the matching messages. This is the same as number of threads matching a
+ * search.
+ *
+ * Note that this is a significantly heavier operation than
+ * notmuch_query_count_messages().
+ *
+ * If an error occurs, this function may return 0.
+ */
+unsigned
+notmuch_query_count_threads (notmuch_query_t *query);
+
 /* Get the thread ID of 'thread'.
  *
  * The returned string belongs to 'thread' and as such, should not be
diff --git a/lib/query.cc b/lib/query.cc
index 6f02b04..b6c0f12 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -457,3 +457,47 @@ notmuch_query_count_messages (notmuch_query_t *query)

 return count;
 }
+
+unsigned
+notmuch_query_count_threads (notmuch_query_t *query)
+{
+notmuch_messages_t *messages;
+GHashTable *hash;
+unsigned int count;
+notmuch_sort_t sort;
+
+sort = query->sort;
+query->sort = NOTMUCH_SORT_UNSORTED;
+messages = notmuch_query_search_messages (query);
+query->sort = sort;
+if (messages == NULL)
+   return 0;
+
+hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
+if (hash == NULL) {
+   talloc_free (messages);
+   return 0;
+}
+
+while (notmuch_messages_valid (messages)) {
+   notmuch_message_t *message = notmuch_messages_get (messages);
+   const char *thread_id = notmuch_message_get_thread_id (message);
+   char *thread_id_copy = talloc_strdup (messages, thread_id);
+   if (unlikely (thread_id_copy == NULL)) {
+   notmuch_message_destroy (message);
+   count = 0;
+   goto DONE;
+   }
+   g_hash_table_insert (hash, thread_id_copy, NULL);
+   notmuch_message_destroy (message);
+   notmuch_messages_move_to_next (messages);
+}
+
+count = g_hash_table_size (hash);
+
+  DONE:
+g_hash_table_unref (hash);
+talloc_free (messages);
+
+return count;
+}
-- 
1.7.5.4



[PATCH v5 0/6] lib/cli: limit number of messages in search results

2011-11-13 Thread Jani Nikula
Hi, output limiting patches v5, with only documentation changes since the
previous version id:"cover.1320615322.git.jani at nikula.org".

The changes are as suggested by Austin Clements:
id:"87ehxcufr0.fsf at awakening.csail.mit.edu"
id:"87bosgufcf.fsf at awakening.csail.mit.edu"


BR,
Jani.


Jani Nikula (6):
  lib: add function to get the number of threads matching a search
  cli: add options --first and --maxitems to notmuch search
  cli: drop unused code from notmuch count
  cli: add support for --output parameter in notmuch count
  test: add tests for notmuch count
  test: add tests for notmuch search --first and --maxitems

 NEWS |   10 +++
 lib/notmuch.h|   14 ++
 lib/query.cc |   44 +++
 notmuch-count.c  |   44 +--
 notmuch-search.c |   70 
 notmuch.1|   48 +
 test/count   |   40 
 test/notmuch-test|2 +
 test/search-limiting |   71 ++
 9 files changed, 294 insertions(+), 49 deletions(-)
 create mode 100755 test/count
 create mode 100755 test/search-limiting

-- 
1.7.5.4



[PATCH] add `tag:' prefix to `--output=tags' results

2011-11-13 Thread Jani Nikula
On Sat, 12 Nov 2011 10:17:30 -0500, David Bremner  wrote:
> On Thu, 30 Jun 2011 10:20:29 +0200, Pieter Praet  wrote:
> > Alter `do_search_tags()' to prepend each result with `tag:',
> > and update affected test.
> > 
> > This makes its output consistent with `do_search_threads()' and
> > `do_search_messages()'.
> 
> What do people think about this change? Personally I will have change
> some scripts to not add "tag:", but it isn't that big of a deal.

I'm curious why this change is needed in the first place. What is gained
from this in addition to consistency? It seems I don't have enough list
history to find the referenced discussion.

The command line interface is an API, and this change causes regressions
in all scripts and programs using it, including the emacs ui. (And that
should probably be fixed with something other than "...a quick'n'dirty
patch, thus probably not fit for consumption.")

BR,
Jani.


[PATCH v6 2/6] cli: add options --first and --maxitems to notmuch search

2011-11-13 Thread Jameson Graef Rollins
On Sun, 13 Nov 2011 23:15:31 +0200, Jani Nikula  wrote:
> Option --maxitems=M limits the maximum number of results to display to M.

This is bike shedding, but can this option be called "--limit" instead
of maxitems?  Somehow that's more intuitive to me.

jamie.
-- 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/2013/621b66d0/attachment.pgp>


[PATCH] Link libutil using filenmae, rather than using -l.

2011-11-13 Thread David Bremner
On Sun, 13 Nov 2011 12:05:03 -0500, Tom Prince  
wrote:
> glibc includes a libutil, so if the wrong -L options get passed, we
> will pick up glibc's version, rather than our own.

pushed,

d


[PATCH 13/13] test: make smtp-dummy work with Emacs 24

2011-11-13 Thread David Bremner
On Mon,  3 Oct 2011 18:47:27 +0200, Thomas Jost  
wrote:
> In Emacs 24, a space is expected after a SMTP response code. If we don't 
> respect
> that, smtpmail-send-it will wait forever.

pushed.

d


[PATCH] add `tag:' prefix to `--output=tags' results

2011-11-13 Thread Jameson Graef Rollins
On Sat, 12 Nov 2011 10:17:30 -0500, David Bremner  wrote:
> What do people think about this change? Personally I will have change
> some scripts to not add "tag:", but it isn't that big of a deal.

I would actually prefer to see the prefixes removed from the messages
and threads output rather than see it added to the tags output.  I think
that's the way to make the output most consistent.  When I ask for
--output=messages I'm asking for the message ids of the messages, not
for search terms for the messages.  I think it should be up to the
consumer to add the prefix if they would like to construct search terms
based on the output.

My 2 cents.  I would be happy to provide a patch to make that change if
people agree to that behavior.

jamie.
-- 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/2013/b65d33e4/attachment.pgp>


[PATCH 00/13] Test prereqs and screen-based Emacs tests

2011-11-13 Thread David Bremner
On Tue, 01 Nov 2011 20:54:49 +0100, Pieter Praet  wrote:
> 
> I'll be commenting on these modified commits where needed, and have
> re-submitted my original series (rebased to current master) in a new
> thread [1].
> 

I'm having trouble sorting out which of these series should be
considered for notmuch master. Is there something in the rebased version
of Pieter's patches that is not present in Thomas's rebased version?

d


[PATCH] emacs: breakout notmuch-show-advance functionality from notmuch-show-advance-and-archive

2011-11-13 Thread Jameson Graef Rollins
This patch breaks out much of the functionality of
notmuch-show-advance-and-archive into a new function:
notmuch-show-advance.  This new function does all the advancing
through a show buffer that notmuch-show-advance-and-archive did,
without all the invasive thread archiving.  The return value of
notmuch-show-advance is nil if the bottom of the thread is not
reached, and t if it is.

notmuch-show-advance-and-archive is modified to just call
notmuch-show-advance, and then call notmuch-show-archive-thread if the
return value is true.  In this way the previous functionality of
notmuch-show-advance-and-archive is preserved.

This provides a way for people to rebind the space bar to a more sane
function if they don't like the default behavior.
---
 emacs/notmuch-show.el |   38 +++---
 1 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index d5c95d8..a7f3263 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1135,26 +1135,18 @@ All currently available key bindings:

 ;; Commands typically bound to keys.

-(defun notmuch-show-advance-and-archive ()
-  "Advance through thread and archive.
-
-This command is intended to be one of the simplest ways to
-process a thread of email. It does the following:
+(defun notmuch-show-advance ()
+  "Advance through thread.

 If the current message in the thread is not yet fully visible,
 scroll by a near screenful to read more of the message.

 Otherwise, (the end of the current message is already within the
-current window), advance to the next open message.
-
-Finally, if there is no further message to advance to, and this
-last message is already read, then archive the entire current
-thread, (remove the \"inbox\" tag from each message). Also kill
-this buffer, and display the next thread from the search from
-which this thread was originally shown."
+current window), advance to the next open message."
   (interactive)
   (let* ((end-of-this-message (notmuch-show-message-bottom))
-(visible-end-of-this-message (1- end-of-this-message)))
+(visible-end-of-this-message (1- end-of-this-message))
+(ret nil))
 (while (invisible-p visible-end-of-this-message)
   (setq visible-end-of-this-message
(previous-single-char-property-change visible-end-of-this-message
@@ -1173,8 +1165,24 @@ which this thread was originally shown."
   (notmuch-show-next-open-message))

  (t
-  ;; This is the last message - archive the thread.
-  (notmuch-show-archive-thread)
+  ;; This is the last message - change the return value
+  (setq ret t)))
+ret))
+
+(defun notmuch-show-advance-and-archive ()
+  "Advance through thread and archive.
+
+This command is intended to be one of the simplest ways to
+process a thread of email. It works exactly like
+notmuch-show-advance, in that it scrolls through messages in a
+show buffer, except that when it gets to the end of the buffer it
+archives the entire current thread, (remove the \"inbox\" tag
+from each message), kills the buffer, and displays the next
+thread from the search from which this thread was originally
+shown."
+  (interactive)
+  (if (notmuch-show-advance)
+  (notmuch-show-archive-thread)))

 (defun notmuch-show-rewind ()
   "Backup through the thread, (reverse scrolling compared to 
\\[notmuch-show-advance-and-archive]).
-- 
1.7.7.1



No subject

2011-11-13 Thread Jameson Graef Rollins
I really hate the default behavior of the space bar in notmuch-show; I
don't want it to pop out of the thread that i'm currently view, and I
especially don't want it to archive threads.  The space bar should
just be for viewing, not altering.

The following patch breaks out the food functionality from
notmuch-show-advance-and-archive so that people can easily rebind it
to the space bar.  Although I do personally think we should change the
default behavior, I leave the current behavior untouched, since I
suppose there maybe are some people out there that like the current
behavior and don't expect it to change.

jamie.


Winter is coming [upcoming release 0.10]

2011-11-13 Thread Austin Clements
Quoth David Bremner on Nov 13 at 10:19 am:
> - id:"1320599856-24078-1-git-send-email-amdragon at mit.edu" is probably
>   not a candidate. I'm not ready to push database format changing
>   patches without some feedback from cworth.  It also needs some more
>   review in general.

This was originally Istvan Marko's patch back in
id:"m3sjsv2kw2.fsf at zsu.kismala.com", where it received a decent amount
of discussion (and then some more starting at
id:"m3pqlfhrkk.fsf at zsu.kismala.com" ).

I've poked cworth about the schema change on IRC (and CC'd him here).


[PATCH] Link libutil using filenmae, rather than using -l.

2011-11-13 Thread Tom Prince
glibc includes a libutil, so if the wrong -L options get passed, we
will pick up glibc's version, rather than our own.
---
 lib/Makefile.local |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/lib/Makefile.local b/lib/Makefile.local
index cb53781..54c4dea 100644
--- a/lib/Makefile.local
+++ b/lib/Makefile.local
@@ -70,7 +70,7 @@ $(dir)/libnotmuch.a: $(libnotmuch_modules)
$(call quiet,AR) rcs $@ $^

 $(dir)/$(LIBNAME): $(libnotmuch_modules) notmuch.sym
-   $(call quiet,CXX $(CXXFLAGS)) $(libnotmuch_modules) 
$(FINAL_LIBNOTMUCH_LDFLAGS) $(LIBRARY_LINK_FLAG) -o $@ -L$(srcdir)/util -lutil
+   $(call quiet,CXX $(CXXFLAGS)) $(libnotmuch_modules) 
$(FINAL_LIBNOTMUCH_LDFLAGS) $(LIBRARY_LINK_FLAG) -o $@ util/libutil.a

 notmuch.sym: $(srcdir)/$(dir)/notmuch.h $(libnotmuch_modules)
sh $(srcdir)/$(lib)/gen-version-script.sh $< $(libnotmuch_modules) > $@
-- 
1.7.6.1



[PATCH v4 4/6] cli: add support for --output parameter in notmuch count

2011-11-13 Thread Austin Clements
Code looks good.  Maybe put messages before threads in the documentation
(both in the | list and in the descriptions), since that's the default?
The output documentation for search does that.

"--output" is an unfortunate name for this option since the *output* of
count is always a count, but this seems necessary for consistency.

On Sun,  6 Nov 2011 23:47:13 +0200, Jani Nikula  wrote:
> Add support for --output=messages (which remains the default) and
> --output=threads to notmuch count.
> 
> Signed-off-by: Jani Nikula 
> ---
>  NEWS|5 +
>  notmuch-count.c |   18 --
>  notmuch.1   |   29 +
>  3 files changed, 46 insertions(+), 6 deletions(-)
> 
> diff --git a/NEWS b/NEWS
> index bfdba7b..009811f 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -28,6 +28,11 @@ Add "notmuch search" --first and --maxitems options
>The search command now takes options --first=[-]N and --maxitems=N to limit
>the number of results shown.
>  
> +Add "notmuch count --output" option
> +
> +  The count command is now capable of counting threads in addition to
> +  messages. This is selected using the new --output=(threads|messages) 
> option.
> +
>  Notmuch 0.9 (2011-10-01)
>  
>  
> diff --git a/notmuch-count.c b/notmuch-count.c
> index a35be40..20ce334 100644
> --- a/notmuch-count.c
> +++ b/notmuch-count.c
> @@ -29,6 +29,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
>  notmuch_query_t *query;
>  char *query_str;
>  int i;
> +notmuch_bool_t output_messages = TRUE;
>  
>  argc--; argv++; /* skip subcommand argument */
>  
> @@ -37,7 +38,17 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
>   i++;
>   break;
>   }
> - {
> + if (STRNCMP_LITERAL (argv[i], "--output=") == 0) {
> + const char *opt = argv[i] + sizeof ("--output=") - 1;
> + if (strcmp (opt, "threads") == 0) {
> + output_messages = FALSE;
> + } else if (strcmp (opt, "messages") == 0) {
> + output_messages = TRUE;
> + } else {
> + fprintf (stderr, "Invalid value for --output: %s\n", opt);
> + return 1;
> + }
> + } else {
>   fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
>   return 1;
>   }
> @@ -71,7 +82,10 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
>   return 1;
>  }
>  
> -printf ("%u\n", notmuch_query_count_messages(query));
> +if (output_messages)
> + printf ("%u\n", notmuch_query_count_messages (query));
> +else
> + printf ("%u\n", notmuch_query_count_threads (query));
>  
>  notmuch_query_destroy (query);
>  notmuch_database_close (notmuch);
> diff --git a/notmuch.1 b/notmuch.1
> index c97334c..f53c183 100644
> --- a/notmuch.1
> +++ b/notmuch.1
> @@ -374,14 +374,35 @@ section below for details of the supported syntax for 
> .
>  .RE
>  .RS 4
>  .TP 4
> -.BR count " ..."
> +.BR count " [options...] ..."
>  
>  Count messages matching the search terms.
>  
> -The number of matching messages is output to stdout.
> +The number of matching messages (or threads) is output to stdout.
>  
> -With no search terms, a count of all messages in the database will be
> -displayed.
> +With no search terms, a count of all messages (or threads) in the database 
> will
> +be displayed.
> +
> +Supported options for
> +.B count
> +include
> +.RS 4
> +.TP 4
> +.B \-\-output=(threads|messages)
> +
> +.RS 4
> +.TP 4
> +.B threads
> +
> +Output the number of matching threads.
> +.RE
> +.RS 4
> +.TP 4
> +.B messages
> +
> +Output the number of matching messages. This is the default.
> +.RE
> +.RE
>  .RE
>  .RE
>  
> -- 
> 1.7.5.4
> 


[PATCH v4 2/6] cli: add options --first and --maxitems to notmuch search

2011-11-13 Thread Austin Clements
Code LGTM.  Some documentation nits below.

On Sun,  6 Nov 2011 23:47:11 +0200, Jani Nikula  wrote:
> Add options --first=[-]N and --maxitems=M to notmuch search to determine
> the first result and maximum number of results to display.
> 
> Option --maxitems=M limits the maximum number of results to display to M.
> 
> Option --first=[-]N skips the first N results; with the leading '-' skip
> until the Nth result from the end (showing a total of N results if within
> bounds of the total number of results and not limited with --maxitems).
> 
> Note that --first with a negative N for thread or summary output requires
> counting the number of matching threads in advance.
> 
> Signed-off-by: Jani Nikula 
> ---
>  NEWS |5 
>  notmuch-search.c |   70 -
>  notmuch.1|   21 ++-
>  3 files changed, 82 insertions(+), 14 deletions(-)
> 
> diff --git a/NEWS b/NEWS
> index b44b11e..bfdba7b 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -23,6 +23,11 @@ Add search terms to  "notmuch dump"
>search/show/tag. The output file argument of dump is deprecated in
>favour of using stdout.
>  
> +Add "notmuch search" --first and --maxitems options
> +
> +  The search command now takes options --first=[-]N and --maxitems=N to limit
> +  the number of results shown.
> +
>  Notmuch 0.9 (2011-10-01)
>  
>  
> diff --git a/notmuch-search.c b/notmuch-search.c
> index 6f04d9a..c62a594 100644
> --- a/notmuch-search.c
> +++ b/notmuch-search.c
> @@ -194,13 +194,22 @@ static int
>  do_search_threads (const search_format_t *format,
>  notmuch_query_t *query,
>  notmuch_sort_t sort,
> -output_t output)
> +output_t output,
> +int first,
> +int maxitems)
>  {
>  notmuch_thread_t *thread;
>  notmuch_threads_t *threads;
>  notmuch_tags_t *tags;
>  time_t date;
>  int first_thread = 1;
> +int i;
> +
> +if (first < 0) {
> + first += notmuch_query_count_threads (query);
> + if (first < 0)
> + first = 0;
> +}
>  
>  threads = notmuch_query_search_threads (query);
>  if (threads == NULL)
> @@ -208,17 +217,23 @@ do_search_threads (const search_format_t *format,
>  
>  fputs (format->results_start, stdout);
>  
> -for (;
> -  notmuch_threads_valid (threads);
> -  notmuch_threads_move_to_next (threads))
> +for (i = 0;
> +  notmuch_threads_valid (threads) &&
> +  (maxitems < 0 || i < first + maxitems);
> +  notmuch_threads_move_to_next (threads), i++)
>  {
>   int first_tag = 1;
>  
> + thread = notmuch_threads_get (threads);
> +
> + if (i < first) {
> + notmuch_thread_destroy (thread);
> + continue;
> + }
> +
>   if (! first_thread)
>   fputs (format->item_sep, stdout);
>  
> - thread = notmuch_threads_get (threads);
> -
>   if (output == OUTPUT_THREADS) {
>   format->item_id (thread, "thread:",
>notmuch_thread_get_thread_id (thread));
> @@ -271,12 +286,21 @@ do_search_threads (const search_format_t *format,
>  static int
>  do_search_messages (const search_format_t *format,
>   notmuch_query_t *query,
> - output_t output)
> + output_t output,
> + int first,
> + int maxitems)
>  {
>  notmuch_message_t *message;
>  notmuch_messages_t *messages;
>  notmuch_filenames_t *filenames;
>  int first_message = 1;
> +int i;
> +
> +if (first < 0) {
> + first += notmuch_query_count_messages (query);
> + if (first < 0)
> + first = 0;
> +}
>  
>  messages = notmuch_query_search_messages (query);
>  if (messages == NULL)
> @@ -284,10 +308,14 @@ do_search_messages (const search_format_t *format,
>  
>  fputs (format->results_start, stdout);
>  
> -for (;
> -  notmuch_messages_valid (messages);
> -  notmuch_messages_move_to_next (messages))
> +for (i = 0;
> +  notmuch_messages_valid (messages) &&
> +  (maxitems < 0 || i < first + maxitems);
> +  notmuch_messages_move_to_next (messages), i++)
>  {
> + if (i < first)
> + continue;
> +
>   message = notmuch_messages_get (messages);
>  
>   if (output == OUTPUT_FILES) {
> @@ -394,6 +422,8 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
>  const search_format_t *format = _text;
>  int i, ret;
>  output_t output = OUTPUT_SUMMARY;
> +int maxitems = -1; /* unlimited */
> +int first = 0;
>  
>  argc--; argv++; /* skip subcommand argument */
>  
> @@ -412,6 +442,22 @@ notmuch_search_command (void *ctx, int argc, char 
> *argv[])
>   fprintf (stderr, "Invalid value for --sort: %s\n", opt);
>   return 1;
>   }
> + } else if (STRNCMP_LITERAL (argv[i], "--first=") == 0) {
> + char 

[PATCH] Don't link libnotmuch if libutil isn't linked in properly.

2011-11-13 Thread Tom Prince
For some reason, on my machine, the link is picking up
/usr/lib/libutil.so instead of util/libutil.a. This causes there to be
undefined symbols in libnotmuch, making it unuseable. This patch causes
the link to fail instead.
---
 lib/Makefile.local |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

On Sun, 13 Nov 2011 10:19:14 -0400, David Bremner  wrote:
> According to our sortof-schedule, we should release 0.10 soonish.  I'd
> like to freeze for a few days first, so that means we have time for
> maybe one or two more non-trivial patches before the freeze.

libnotmuch isn't linking properly to libutil for me. This seems to be
due to $(xapian-config --libs) including -L/usr/lib64, which then causes
-lutil to pick up /usr/lib64/libutil.so (from glibc) instead.
I noticed this failing because symbol-test fails to compile, causing
both symbol-hinding test to fail.

The following patch doesn't fix this, but does cuase the build to fail
earlier.

diff --git a/lib/Makefile.local b/lib/Makefile.local
index d58552c..cb53781 100644
--- a/lib/Makefile.local
+++ b/lib/Makefile.local
@@ -30,7 +30,7 @@ LIBRARY_SUFFIX = so
 LINKER_NAME = libnotmuch.$(LIBRARY_SUFFIX)
 SONAME = $(LINKER_NAME).$(LIBNOTMUCH_VERSION_MAJOR)
 LIBNAME = $(SONAME).$(LIBNOTMUCH_VERSION_MINOR).$(LIBNOTMUCH_VERSION_RELEASE)
-LIBRARY_LINK_FLAG = -shared -Wl,--version-script=notmuch.sym,-soname=$(SONAME)
+LIBRARY_LINK_FLAG = -shared -Wl,--version-script=notmuch.sym,-soname=$(SONAME) 
-Wl,--no-undefined
 ifeq ($(LIBDIR_IN_LDCONFIG),1)
 ifeq ($(DESTDIR),)
 LIBRARY_INSTALL_POST_COMMAND=ldconfig
--
1.7.6.1


[PATCH 2/2] emacs: add notmuch-show-worker function for specifying crypto processing directly

2011-11-13 Thread Jameson Graef Rollins
The main reason to introduce this new unexposed function is to allow
the buffer redisplay crypto switch to behaving in a more expected way.
The prefix to notmuch-show-redisplay buffer now switches the crypto
processing of the current show buffer, as opposed to switching the
logic of the notmuch-crypto-process-mime customization variable.  This
behavior is more intuitive.
---
 emacs/notmuch-show.el |   20 
 1 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 95af32a..d5c95d8 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -830,13 +830,16 @@ The optional CRYPTO-SWITCH toggles the value of the
 notmuch-crypto-process-mime customization variable for this show
 buffer."
   (interactive "sNotmuch show: ")
+  (let* ((process-crypto (if crypto-switch
+(not notmuch-crypto-process-mime)
+  notmuch-crypto-process-mime)))
+(notmuch-show-worker thread-id parent-buffer query-context buffer-name 
process-crypto)))
+
+(defun notmuch-show-worker (thread-id parent-buffer query-context buffer-name 
process-crypto)
   (let* ((buffer-name (generate-new-buffer-name
   (or buffer-name
   (concat "*notmuch-" thread-id "*"
 (buffer (get-buffer-create buffer-name))
-(process-crypto (if crypto-switch
-(not notmuch-crypto-process-mime)
-  notmuch-crypto-process-mime))
 (inhibit-read-only t))
 (switch-to-buffer buffer)
 (notmuch-show-mode)
@@ -882,16 +885,17 @@ buffer."
   "Refresh the current view (with crypto switch if prefix given).

 Kills the current buffer and reruns notmuch show with the same
-thread id.  If a prefix is given, the current thread is
-redisplayed with the crypto switch activated, which switch the
-logic of the notmuch-crypto-process-mime customization variable."
+thread id.  If a prefix is given, crypto processing is toggled."
   (interactive "P")
   (let ((thread-id notmuch-show-thread-id)
(parent-buffer notmuch-show-parent-buffer)
(query-context notmuch-show-query-context)
-   (buffer-name notmuch-show-buffer-name))
+   (buffer-name notmuch-show-buffer-name)
+   (process-crypto (if crypto-switch
+   (not notmuch-show-process-crypto)
+ notmuch-show-process-crypto)))
 (notmuch-kill-this-buffer)
-(notmuch-show thread-id parent-buffer query-context buffer-name 
crypto-switch)))
+(notmuch-show-worker thread-id parent-buffer query-context buffer-name 
process-crypto)))

 (defvar notmuch-show-stash-map
   (let ((map (make-sparse-keymap)))
-- 
1.7.7.1



[PATCH 1/2] emacs: add documentation for notmuch-show crypto-switch option

2011-11-13 Thread Jameson Graef Rollins
---
 emacs/notmuch-show.el |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index d395d87..95af32a 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -824,7 +824,11 @@ non-nil.
 The optional BUFFER-NAME provides the name of the buffer in
 which the message thread is shown. If it is nil (which occurs
 when the command is called interactively) the argument to the
-function is used. "
+function is used.
+
+The optional CRYPTO-SWITCH toggles the value of the
+notmuch-crypto-process-mime customization variable for this show
+buffer."
   (interactive "sNotmuch show: ")
   (let* ((buffer-name (generate-new-buffer-name
   (or buffer-name
-- 
1.7.7.1



No subject

2011-11-13 Thread Jameson Graef Rollins
So this is incredibly confusing to me, but git is supposedly doing
something clever that allows these patches to apply in my repo but not
in a clean one.

In any event, I'm resending the patches after being applied to my
master, which should resolve any conflict and allow them to apply.

jamie.


[PATCH] test: do not hide test_emacs errors

2011-11-13 Thread Dmitry Kurochkin
On Sat, 12 Nov 2011 09:57:53 -0500, David Bremner  wrote:
> On Fri,  1 Jul 2011 06:23:48 +0400, Dmitry Kurochkin  gmail.com> wrote:
> > Do not redirect test_emacs stderr to /dev/null.  Test_emacs uses
> > emacsclient(1) now and it does not print unwanted messages (like
> > those from `message') to stderr.  But it does print useful
> > errors, e.g. when emacs server connection fails, given expression
> > is not valid or undefined function is called.
> 
> Is this patch still relevant now that we use dtach to run the tests?
> 

It is still relevant.  If test_emacs prints any errors, we should see
them.  If it does not, we should remove the redirection.

But we need to check for other similar cases.  New test cases may have
been added with test_emacs stderr redirect.

> I didn't notice any difference, but maybe I was not supposed to.
> 

I think that is expected.

Regards,
  Dmitry

> d


[PATCH] test: attempt to send QUIT to smtp-dummy in case mail send failed

2011-11-13 Thread Dmitry Kurochkin
On Sat, 12 Nov 2011 23:07:38 +0200, Tomi Ollila  wrote:
> On Sat, 12 Nov 2011 10:41:28 -0500, Austin Clements  
> wrote:
> > 
> > Actually, since sending mail is synchronous, there shouldn't be any
> > issues with buffering or timing.  If Emacs successfully sends the
> > message, it will wait for the OK response (`smtpmail-via-smtp'), which
> > should indicate that the message is in stable storage on the SMTP
> > server (this is rather fundamental to SMTP's reliability as a
> > protocol, after all).  Thus, the smtp-dummy *should* be done by the
> > time Emacs exits.  If Emacs fails to send the message, then it doesn't
> > really matter and you just want the smtp-dummy to go away.
> > 
> > I say "should" because smtp-dummy needs a one line patch to add an
> > fflush at the end of receive_data_to_file.  Any real SMTP server would
> > do this (not to mention a full fsync) before acknowledging the
> > message.
> 
> SO, in our cases there are 2 options:
> 
> 
> 1) add line 
>   { echo QUIT > /dev/tcp/127.0.0.1/25025; } 2>/dev/null
>   before 
>   wait ${smtp_dummy_pid}
> 
> in test-lib.sh
> 
> 
> 2) add line
>   kill ${smtp_dummy_pid}
>   before 
>   wait ${smtp_dummy_pid}
> 
> in test-lib.sh *and* add that fflush (output) before free (line) in 
> smtp-dummy.c function receive_data_to_file.
> 
> folks! opinions!
> 

I think we should add fflush(3) call to smtp-dummy in any case.

As for sending QUIT over TCP vs kill, I prefer the former.  On one hand,
kill is more reliable.  But smtp-dummy must handle QUIT and it is a bug
if it does not.

An unrelated issue: currently we discard test_emacs output in
emacs_deliver_message and other cases.  Ideally we should not do that
because it may contain useful information.  We should capture the output
and print it in case of error, at least.

Regards,
  Dmitry

> Tomi
> ___
> notmuch mailing list
> notmuch at notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch


the present and future of patch tracking for notmuch.

2011-11-13 Thread David Bremner

As some of you probably know, I have been using "nmbug" [1], now in git
master, to help track the state of notmuch patches.  At this point I
think I am about ready to declare the experimental deployment of nmbug a
success and make it more official.

## present?

- Currently this is running off a git repo on my server. I don't really
  mind doing this, but it would probably reduce confusion to have the 
  "the" repo on git.notmuchmail.org

- Currently I am controlling push access to the nmbug repo by ssh-key.
  This is not really a burden, but I wonder if it would be better to
  allow anonymous pushes, perhaps to some staging repo that trusted
  people (i.e. those with ssh keys) could pull from.

## future?

- It would be nice if people without notmuch installed had access to the
  information.  Some way to make html dumps of threads with tags would
  do the trick, I believe. So far I am resisting the temptation to write
  such a thing.

- I'm not sure about the future of the notmuch patchwork instance. It
  doesn't hurt anything, but it does consume resources, and maybe
  generate confusion.

- So far, I'm continuing to post messages about pushed patches to the
  list. If at some point the consensus is that this is more annoying
  than useful, I'm perfectly willing to stop.

d


[1]: http://notmuchmail.org/nmbug
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 315 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/2013/1d9a8c50/attachment.pgp>


[PATCH] test/atomicity: change shebang to '#!/usr/bin/env bash'

2011-11-13 Thread Tomi Ollila
---
 test/atomicity |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/test/atomicity b/test/atomicity
index 3464238..ad7d4a3 100755
--- a/test/atomicity
+++ b/test/atomicity
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 test_description='atomicity'
 . ./test-lib.sh

-- 
1.5.6.5



[PATCH] test: attempt to send QUIT to smtp-dummy in case mail send failed

2011-11-13 Thread Tomi Ollila
On Sun, 13 Nov 2011 11:01:24 +0400, Dmitry Kurochkin  wrote:
> On Sat, 12 Nov 2011 23:07:38 +0200, Tomi Ollila  wrote:
> > SO, in our cases there are 2 options:
> > 
> > 
> > 1) add line 
> > { echo QUIT > /dev/tcp/127.0.0.1/25025; } 2>/dev/null
> >   before 
> > wait ${smtp_dummy_pid}
> > 
> > in test-lib.sh
> > 
> > 
> > 2) add line
> > kill ${smtp_dummy_pid}
> >   before 
> > wait ${smtp_dummy_pid}
> > 
> > in test-lib.sh *and* add that fflush (output) before free (line) in 
> > smtp-dummy.c function receive_data_to_file.
> > 
> > folks! opinions!
> > 
> 
> I think we should add fflush(3) call to smtp-dummy in any case.

True. In a separate patch. 

> As for sending QUIT over TCP vs kill, I prefer the former.  On one hand,
> kill is more reliable.  But smtp-dummy must handle QUIT and it is a bug
> if it does not.

Me too, basically for the same reasons. It is also aesthetically nicer
not to kill anything ;)

> An unrelated issue: currently we discard test_emacs output in
> emacs_deliver_message and other cases.  Ideally we should not do that
> because it may contain useful information.  We should capture the output
> and print it in case of error, at least.

I agree. And if id:"<1309487028-18786-1-git-send-email-dmitry.kurochkin at 
gmail.com>"
is applied before creating new patch based on this then these 2 apply cleanly.

> 
> Regards,
>   Dmitry
> 
> > Tomi

Tomi


Winter is coming [upcoming release 0.10]

2011-11-13 Thread David Bremner

Hi All.

According to our sortof-schedule, we should release 0.10 soonish.  I'd
like to freeze for a few days first, so that means we have time for
maybe one or two more non-trivial patches before the freeze.

- id:"1320846275-28520-1-git-send-email-amdragon at mit.edu" is a
  candidate, but needs review

- id:"8771bb7ee67586515ff5114747fd680005ccfc5a.1320615322.git.jani at 
nikula.org" 
  Needs a review of the cli part

- id:"1320599856-24078-1-git-send-email-amdragon at mit.edu" is probably
  not a candidate. I'm not ready to push database format changing
  patches without some feedback from cworth.  It also needs some more
  review in general.

Other suggestions/comments?

David






-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 315 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/2013/12149687/attachment.pgp>


[PATCH] test: do not hide test_emacs errors

2011-11-13 Thread David Bremner
On Sun, 13 Nov 2011 11:06:43 +0400, Dmitry Kurochkin  wrote:
> > Is this patch still relevant now that we use dtach to run the tests?
> > 
> 
> It is still relevant.  If test_emacs prints any errors, we should see
> them.  If it does not, we should remove the redirection.

pushed, 

d


[PATCH] exec emacs at the end of run_emacs script

2011-11-13 Thread David Bremner
On Fri, 11 Nov 2011 01:43:03 +0200, Tomi Ollila  wrote:
> In the last line of run_emacs, exec the emacs process.
> With one fork less the process list is (also) neater.

pushed.


Re: [PATCH] test: attempt to send QUIT to smtp-dummy in case mail send failed

2011-11-13 Thread Tomi Ollila
On Sun, 13 Nov 2011 11:01:24 +0400, Dmitry Kurochkin 
dmitry.kuroch...@gmail.com wrote:
 On Sat, 12 Nov 2011 23:07:38 +0200, Tomi Ollila tomi.oll...@iki.fi wrote:
  SO, in our cases there are 2 options:
  
  
  1) add line 
  { echo QUIT  /dev/tcp/127.0.0.1/25025; } 2/dev/null
before 
  wait ${smtp_dummy_pid}
  
  in test-lib.sh
  
  
  2) add line
  kill ${smtp_dummy_pid}
before 
  wait ${smtp_dummy_pid}
  
  in test-lib.sh *and* add that fflush (output) before free (line) in 
  smtp-dummy.c function receive_data_to_file.
  
  folks! opinions!
  
 
 I think we should add fflush(3) call to smtp-dummy in any case.

True. In a separate patch. 

 As for sending QUIT over TCP vs kill, I prefer the former.  On one hand,
 kill is more reliable.  But smtp-dummy must handle QUIT and it is a bug
 if it does not.

Me too, basically for the same reasons. It is also aesthetically nicer
not to kill anything ;)

 An unrelated issue: currently we discard test_emacs output in
 emacs_deliver_message and other cases.  Ideally we should not do that
 because it may contain useful information.  We should capture the output
 and print it in case of error, at least.

I agree. And if 
id:1309487028-18786-1-git-send-email-dmitry.kuroch...@gmail.com
is applied before creating new patch based on this then these 2 apply cleanly.

 
 Regards,
   Dmitry
 
  Tomi

Tomi
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] test: do not hide test_emacs errors

2011-11-13 Thread David Bremner
On Sun, 13 Nov 2011 11:06:43 +0400, Dmitry Kurochkin 
dmitry.kuroch...@gmail.com wrote:
  Is this patch still relevant now that we use dtach to run the tests?
  
 
 It is still relevant.  If test_emacs prints any errors, we should see
 them.  If it does not, we should remove the redirection.

pushed, 

d
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] add `tag:' prefix to `--output=tags' results

2011-11-13 Thread Jani Nikula
On Sat, 12 Nov 2011 10:17:30 -0500, David Bremner da...@tethera.net wrote:
 On Thu, 30 Jun 2011 10:20:29 +0200, Pieter Praet pie...@praet.org wrote:
  Alter `do_search_tags()' to prepend each result with `tag:',
  and update affected test.
  
  This makes its output consistent with `do_search_threads()' and
  `do_search_messages()'.
 
 What do people think about this change? Personally I will have change
 some scripts to not add tag:, but it isn't that big of a deal.

I'm curious why this change is needed in the first place. What is gained
from this in addition to consistency? It seems I don't have enough list
history to find the referenced discussion.

The command line interface is an API, and this change causes regressions
in all scripts and programs using it, including the emacs ui. (And that
should probably be fixed with something other than ...a quick'n'dirty
patch, thus probably not fit for consumption.)

BR,
Jani.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Winter is coming [upcoming release 0.10]

2011-11-13 Thread David Bremner

Hi All.

According to our sortof-schedule, we should release 0.10 soonish.  I'd
like to freeze for a few days first, so that means we have time for
maybe one or two more non-trivial patches before the freeze.

- id:1320846275-28520-1-git-send-email-amdra...@mit.edu is a
  candidate, but needs review

- id:8771bb7ee67586515ff5114747fd680005ccfc5a.1320615322.git.j...@nikula.org 
  Needs a review of the cli part

- id:1320599856-24078-1-git-send-email-amdra...@mit.edu is probably
  not a candidate. I'm not ready to push database format changing
  patches without some feedback from cworth.  It also needs some more
  review in general.

Other suggestions/comments?

David





  


pgpzln1tyLGvG.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


the present and future of patch tracking for notmuch.

2011-11-13 Thread David Bremner

As some of you probably know, I have been using nmbug [1], now in git
master, to help track the state of notmuch patches.  At this point I
think I am about ready to declare the experimental deployment of nmbug a
success and make it more official.

## present?

- Currently this is running off a git repo on my server. I don't really
  mind doing this, but it would probably reduce confusion to have the 
  the repo on git.notmuchmail.org

- Currently I am controlling push access to the nmbug repo by ssh-key.
  This is not really a burden, but I wonder if it would be better to
  allow anonymous pushes, perhaps to some staging repo that trusted
  people (i.e. those with ssh keys) could pull from.

## future?

- It would be nice if people without notmuch installed had access to the
  information.  Some way to make html dumps of threads with tags would
  do the trick, I believe. So far I am resisting the temptation to write
  such a thing.

- I'm not sure about the future of the notmuch patchwork instance. It
  doesn't hurt anything, but it does consume resources, and maybe
  generate confusion.

- So far, I'm continuing to post messages about pushed patches to the
  list. If at some point the consensus is that this is more annoying
  than useful, I'm perfectly willing to stop.

d


[1]: http://notmuchmail.org/nmbug


pgpC9GKgCSD7n.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] Don't link libnotmuch if libutil isn't linked in properly.

2011-11-13 Thread Tom Prince
For some reason, on my machine, the link is picking up
/usr/lib/libutil.so instead of util/libutil.a. This causes there to be
undefined symbols in libnotmuch, making it unuseable. This patch causes
the link to fail instead.
---
 lib/Makefile.local |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
 
On Sun, 13 Nov 2011 10:19:14 -0400, David Bremner da...@tethera.net wrote:
 According to our sortof-schedule, we should release 0.10 soonish.  I'd
 like to freeze for a few days first, so that means we have time for
 maybe one or two more non-trivial patches before the freeze.

libnotmuch isn't linking properly to libutil for me. This seems to be
due to $(xapian-config --libs) including -L/usr/lib64, which then causes
-lutil to pick up /usr/lib64/libutil.so (from glibc) instead.
I noticed this failing because symbol-test fails to compile, causing
both symbol-hinding test to fail.

The following patch doesn't fix this, but does cuase the build to fail
earlier.

diff --git a/lib/Makefile.local b/lib/Makefile.local
index d58552c..cb53781 100644
--- a/lib/Makefile.local
+++ b/lib/Makefile.local
@@ -30,7 +30,7 @@ LIBRARY_SUFFIX = so
 LINKER_NAME = libnotmuch.$(LIBRARY_SUFFIX)
 SONAME = $(LINKER_NAME).$(LIBNOTMUCH_VERSION_MAJOR)
 LIBNAME = $(SONAME).$(LIBNOTMUCH_VERSION_MINOR).$(LIBNOTMUCH_VERSION_RELEASE)
-LIBRARY_LINK_FLAG = -shared -Wl,--version-script=notmuch.sym,-soname=$(SONAME)
+LIBRARY_LINK_FLAG = -shared -Wl,--version-script=notmuch.sym,-soname=$(SONAME) 
-Wl,--no-undefined
 ifeq ($(LIBDIR_IN_LDCONFIG),1)
 ifeq ($(DESTDIR),)
 LIBRARY_INSTALL_POST_COMMAND=ldconfig
--
1.7.6.1
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v4 2/6] cli: add options --first and --maxitems to notmuch search

2011-11-13 Thread Austin Clements
Code LGTM.  Some documentation nits below.

On Sun,  6 Nov 2011 23:47:11 +0200, Jani Nikula j...@nikula.org wrote:
 Add options --first=[-]N and --maxitems=M to notmuch search to determine
 the first result and maximum number of results to display.
 
 Option --maxitems=M limits the maximum number of results to display to M.
 
 Option --first=[-]N skips the first N results; with the leading '-' skip
 until the Nth result from the end (showing a total of N results if within
 bounds of the total number of results and not limited with --maxitems).
 
 Note that --first with a negative N for thread or summary output requires
 counting the number of matching threads in advance.
 
 Signed-off-by: Jani Nikula j...@nikula.org
 ---
  NEWS |5 
  notmuch-search.c |   70 -
  notmuch.1|   21 ++-
  3 files changed, 82 insertions(+), 14 deletions(-)
 
 diff --git a/NEWS b/NEWS
 index b44b11e..bfdba7b 100644
 --- a/NEWS
 +++ b/NEWS
 @@ -23,6 +23,11 @@ Add search terms to  notmuch dump
search/show/tag. The output file argument of dump is deprecated in
favour of using stdout.
  
 +Add notmuch search --first and --maxitems options
 +
 +  The search command now takes options --first=[-]N and --maxitems=N to limit
 +  the number of results shown.
 +
  Notmuch 0.9 (2011-10-01)
  
  
 diff --git a/notmuch-search.c b/notmuch-search.c
 index 6f04d9a..c62a594 100644
 --- a/notmuch-search.c
 +++ b/notmuch-search.c
 @@ -194,13 +194,22 @@ static int
  do_search_threads (const search_format_t *format,
  notmuch_query_t *query,
  notmuch_sort_t sort,
 -output_t output)
 +output_t output,
 +int first,
 +int maxitems)
  {
  notmuch_thread_t *thread;
  notmuch_threads_t *threads;
  notmuch_tags_t *tags;
  time_t date;
  int first_thread = 1;
 +int i;
 +
 +if (first  0) {
 + first += notmuch_query_count_threads (query);
 + if (first  0)
 + first = 0;
 +}
  
  threads = notmuch_query_search_threads (query);
  if (threads == NULL)
 @@ -208,17 +217,23 @@ do_search_threads (const search_format_t *format,
  
  fputs (format-results_start, stdout);
  
 -for (;
 -  notmuch_threads_valid (threads);
 -  notmuch_threads_move_to_next (threads))
 +for (i = 0;
 +  notmuch_threads_valid (threads) 
 +  (maxitems  0 || i  first + maxitems);
 +  notmuch_threads_move_to_next (threads), i++)
  {
   int first_tag = 1;
  
 + thread = notmuch_threads_get (threads);
 +
 + if (i  first) {
 + notmuch_thread_destroy (thread);
 + continue;
 + }
 +
   if (! first_thread)
   fputs (format-item_sep, stdout);
  
 - thread = notmuch_threads_get (threads);
 -
   if (output == OUTPUT_THREADS) {
   format-item_id (thread, thread:,
notmuch_thread_get_thread_id (thread));
 @@ -271,12 +286,21 @@ do_search_threads (const search_format_t *format,
  static int
  do_search_messages (const search_format_t *format,
   notmuch_query_t *query,
 - output_t output)
 + output_t output,
 + int first,
 + int maxitems)
  {
  notmuch_message_t *message;
  notmuch_messages_t *messages;
  notmuch_filenames_t *filenames;
  int first_message = 1;
 +int i;
 +
 +if (first  0) {
 + first += notmuch_query_count_messages (query);
 + if (first  0)
 + first = 0;
 +}
  
  messages = notmuch_query_search_messages (query);
  if (messages == NULL)
 @@ -284,10 +308,14 @@ do_search_messages (const search_format_t *format,
  
  fputs (format-results_start, stdout);
  
 -for (;
 -  notmuch_messages_valid (messages);
 -  notmuch_messages_move_to_next (messages))
 +for (i = 0;
 +  notmuch_messages_valid (messages) 
 +  (maxitems  0 || i  first + maxitems);
 +  notmuch_messages_move_to_next (messages), i++)
  {
 + if (i  first)
 + continue;
 +
   message = notmuch_messages_get (messages);
  
   if (output == OUTPUT_FILES) {
 @@ -394,6 +422,8 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
  const search_format_t *format = format_text;
  int i, ret;
  output_t output = OUTPUT_SUMMARY;
 +int maxitems = -1; /* unlimited */
 +int first = 0;
  
  argc--; argv++; /* skip subcommand argument */
  
 @@ -412,6 +442,22 @@ notmuch_search_command (void *ctx, int argc, char 
 *argv[])
   fprintf (stderr, Invalid value for --sort: %s\n, opt);
   return 1;
   }
 + } else if (STRNCMP_LITERAL (argv[i], --first=) == 0) {
 + char *p;
 + opt = argv[i] + sizeof (--first=) - 1;
 + first = strtol (opt, p, 10);
 + if (*opt == '\0' || p == opt || *p 

Re: [PATCH v4 4/6] cli: add support for --output parameter in notmuch count

2011-11-13 Thread Austin Clements
Code looks good.  Maybe put messages before threads in the documentation
(both in the | list and in the descriptions), since that's the default?
The output documentation for search does that.

--output is an unfortunate name for this option since the *output* of
count is always a count, but this seems necessary for consistency.

On Sun,  6 Nov 2011 23:47:13 +0200, Jani Nikula j...@nikula.org wrote:
 Add support for --output=messages (which remains the default) and
 --output=threads to notmuch count.
 
 Signed-off-by: Jani Nikula j...@nikula.org
 ---
  NEWS|5 +
  notmuch-count.c |   18 --
  notmuch.1   |   29 +
  3 files changed, 46 insertions(+), 6 deletions(-)
 
 diff --git a/NEWS b/NEWS
 index bfdba7b..009811f 100644
 --- a/NEWS
 +++ b/NEWS
 @@ -28,6 +28,11 @@ Add notmuch search --first and --maxitems options
The search command now takes options --first=[-]N and --maxitems=N to limit
the number of results shown.
  
 +Add notmuch count --output option
 +
 +  The count command is now capable of counting threads in addition to
 +  messages. This is selected using the new --output=(threads|messages) 
 option.
 +
  Notmuch 0.9 (2011-10-01)
  
  
 diff --git a/notmuch-count.c b/notmuch-count.c
 index a35be40..20ce334 100644
 --- a/notmuch-count.c
 +++ b/notmuch-count.c
 @@ -29,6 +29,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
  notmuch_query_t *query;
  char *query_str;
  int i;
 +notmuch_bool_t output_messages = TRUE;
  
  argc--; argv++; /* skip subcommand argument */
  
 @@ -37,7 +38,17 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
   i++;
   break;
   }
 - {
 + if (STRNCMP_LITERAL (argv[i], --output=) == 0) {
 + const char *opt = argv[i] + sizeof (--output=) - 1;
 + if (strcmp (opt, threads) == 0) {
 + output_messages = FALSE;
 + } else if (strcmp (opt, messages) == 0) {
 + output_messages = TRUE;
 + } else {
 + fprintf (stderr, Invalid value for --output: %s\n, opt);
 + return 1;
 + }
 + } else {
   fprintf (stderr, Unrecognized option: %s\n, argv[i]);
   return 1;
   }
 @@ -71,7 +82,10 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
   return 1;
  }
  
 -printf (%u\n, notmuch_query_count_messages(query));
 +if (output_messages)
 + printf (%u\n, notmuch_query_count_messages (query));
 +else
 + printf (%u\n, notmuch_query_count_threads (query));
  
  notmuch_query_destroy (query);
  notmuch_database_close (notmuch);
 diff --git a/notmuch.1 b/notmuch.1
 index c97334c..f53c183 100644
 --- a/notmuch.1
 +++ b/notmuch.1
 @@ -374,14 +374,35 @@ section below for details of the supported syntax for 
 search-terms.
  .RE
  .RS 4
  .TP 4
 -.BR count  search-term...
 +.BR count  [options...] search-term...
  
  Count messages matching the search terms.
  
 -The number of matching messages is output to stdout.
 +The number of matching messages (or threads) is output to stdout.
  
 -With no search terms, a count of all messages in the database will be
 -displayed.
 +With no search terms, a count of all messages (or threads) in the database 
 will
 +be displayed.
 +
 +Supported options for
 +.B count
 +include
 +.RS 4
 +.TP 4
 +.B \-\-output=(threads|messages)
 +
 +.RS 4
 +.TP 4
 +.B threads
 +
 +Output the number of matching threads.
 +.RE
 +.RS 4
 +.TP 4
 +.B messages
 +
 +Output the number of matching messages. This is the default.
 +.RE
 +.RE
  .RE
  .RE
  
 -- 
 1.7.5.4
 
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] Link libutil using filenmae, rather than using -l.

2011-11-13 Thread Tom Prince
glibc includes a libutil, so if the wrong -L options get passed, we
will pick up glibc's version, rather than our own.
---
 lib/Makefile.local |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/lib/Makefile.local b/lib/Makefile.local
index cb53781..54c4dea 100644
--- a/lib/Makefile.local
+++ b/lib/Makefile.local
@@ -70,7 +70,7 @@ $(dir)/libnotmuch.a: $(libnotmuch_modules)
$(call quiet,AR) rcs $@ $^
 
 $(dir)/$(LIBNAME): $(libnotmuch_modules) notmuch.sym
-   $(call quiet,CXX $(CXXFLAGS)) $(libnotmuch_modules) 
$(FINAL_LIBNOTMUCH_LDFLAGS) $(LIBRARY_LINK_FLAG) -o $@ -L$(srcdir)/util -lutil
+   $(call quiet,CXX $(CXXFLAGS)) $(libnotmuch_modules) 
$(FINAL_LIBNOTMUCH_LDFLAGS) $(LIBRARY_LINK_FLAG) -o $@ util/libutil.a
 
 notmuch.sym: $(srcdir)/$(dir)/notmuch.h $(libnotmuch_modules)
sh $(srcdir)/$(lib)/gen-version-script.sh $ $(libnotmuch_modules)  $@
-- 
1.7.6.1

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] Don't link libnotmuch if libutil isn't linked in properly.

2011-11-13 Thread Tom Prince
Perhaps the g++ step in symbol-hiding should in fact be a test. Right
now, that step failing isn't captured by the test-suite.

  Tom
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: Winter is coming [upcoming release 0.10]

2011-11-13 Thread Austin Clements
Quoth David Bremner on Nov 13 at 10:19 am:
 - id:1320599856-24078-1-git-send-email-amdra...@mit.edu is probably
   not a candidate. I'm not ready to push database format changing
   patches without some feedback from cworth.  It also needs some more
   review in general.

This was originally Istvan Marko's patch back in
id:m3sjsv2kw2@zsu.kismala.com, where it received a decent amount
of discussion (and then some more starting at
id:m3pqlfhrkk@zsu.kismala.com ).

I've poked cworth about the schema change on IRC (and CC'd him here).
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: Configure mail responses headers to use Gcc anddddd not Fcc header in Emacs

2011-11-13 Thread Olivier Berger
Olivier Berger olivier.ber...@it-sudparis.eu writes:

 Hi.

 I'm using notmuch together with a local dovecot imap server, and with
 Gnus in Emacs.

 When sending mails from notmuch, I'd like to be able to have a
 nnimap+localdovecot:Sentmail added for instance, instead of a Fcc
 header.

 Is this possible ?


Responding to myself.

The problem was that I had removed the Fcc addition made by notmuch hook
as it was redundant when sending mails with Gnus, which uses a Gcc.

But I cannot seem to use Gnu's Gcc in mail sent from withing notmuch,
actually.

So I've made it so that Gnus won't add a Gcc, and so that Fcc is set
correctly for my local dovecot.

So, in the end, I have customized these variables :

 '(gnus-outgoing-message-group 
   (lambda nil 
   (goto-char (point-max)) 
   (cond 
  ((message-field-value Fcc) 
   nnimap+localdovecot:Sentmail) 
   (t nil
 '(message-directory ~/Maildir/)
 '(notmuch-fcc-dirs .Sentmail)

So in notmuch, Fcc makes it saving the file in my ~/Maildir/.Sentmail/cur
which suits dovecot, and if I'm sending from Gnus, the Gcc is set
according to my nnimap folder definitions.

Hope this helps.

Best regards,

-- 
Olivier BERGER 
http://www-public.it-sudparis.eu/~berger_o/ - OpenPGP-Id: 2048R/5819D7E8
Ingenieur Recherche - Dept INF
Institut TELECOM, SudParis (http://www.it-sudparis.eu/), Evry (France)
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 00/13] Test prereqs and screen-based Emacs tests

2011-11-13 Thread David Bremner
On Tue, 01 Nov 2011 20:54:49 +0100, Pieter Praet pie...@praet.org wrote:
 
 I'll be commenting on these modified commits where needed, and have
 re-submitted my original series (rebased to current master) in a new
 thread [1].
 

I'm having trouble sorting out which of these series should be
considered for notmuch master. Is there something in the rebased version
of Pieter's patches that is not present in Thomas's rebased version?

d
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 13/13] test: make smtp-dummy work with Emacs 24

2011-11-13 Thread David Bremner
On Mon,  3 Oct 2011 18:47:27 +0200, Thomas Jost schno...@schnouki.net wrote:
 In Emacs 24, a space is expected after a SMTP response code. If we don't 
 respect
 that, smtpmail-send-it will wait forever.

pushed.

d
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] Link libutil using filenmae, rather than using -l.

2011-11-13 Thread David Bremner
On Sun, 13 Nov 2011 12:05:03 -0500, Tom Prince tom.pri...@ualberta.net wrote:
 glibc includes a libutil, so if the wrong -L options get passed, we
 will pick up glibc's version, rather than our own.

pushed,

d
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[no subject]

2011-11-13 Thread Jameson Graef Rollins
So this is incredibly confusing to me, but git is supposedly doing
something clever that allows these patches to apply in my repo but not
in a clean one.

In any event, I'm resending the patches after being applied to my
master, which should resolve any conflict and allow them to apply.

jamie.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 1/2] emacs: add documentation for notmuch-show crypto-switch option

2011-11-13 Thread Jameson Graef Rollins
---
 emacs/notmuch-show.el |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index d395d87..95af32a 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -824,7 +824,11 @@ non-nil.
 The optional BUFFER-NAME provides the name of the buffer in
 which the message thread is shown. If it is nil (which occurs
 when the command is called interactively) the argument to the
-function is used. 
+function is used.
+
+The optional CRYPTO-SWITCH toggles the value of the
+notmuch-crypto-process-mime customization variable for this show
+buffer.
   (interactive sNotmuch show: )
   (let* ((buffer-name (generate-new-buffer-name
   (or buffer-name
-- 
1.7.7.1

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v5 1/6] lib: add function to get the number of threads matching a search

2011-11-13 Thread Jani Nikula
Add function notmuch_query_count_threads() to get the number of threads
matching a search. This is done by performing a search and figuring out the
number of unique thread IDs in the matching messages, a significantly
heavier operation than notmuch_query_count_messages().

Signed-off-by: Jani Nikula j...@nikula.org
---
 lib/notmuch.h |   14 ++
 lib/query.cc  |   44 
 2 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/lib/notmuch.h b/lib/notmuch.h
index c4330e4..9f23a10 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -609,6 +609,20 @@ notmuch_threads_destroy (notmuch_threads_t *threads);
 unsigned
 notmuch_query_count_messages (notmuch_query_t *query);
  
+/* Return the number of threads matching a search.
+ *
+ * This function performs a search and returns the number of unique thread IDs
+ * in the matching messages. This is the same as number of threads matching a
+ * search.
+ *
+ * Note that this is a significantly heavier operation than
+ * notmuch_query_count_messages().
+ *
+ * If an error occurs, this function may return 0.
+ */
+unsigned
+notmuch_query_count_threads (notmuch_query_t *query);
+
 /* Get the thread ID of 'thread'.
  *
  * The returned string belongs to 'thread' and as such, should not be
diff --git a/lib/query.cc b/lib/query.cc
index 6f02b04..b6c0f12 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -457,3 +457,47 @@ notmuch_query_count_messages (notmuch_query_t *query)
 
 return count;
 }
+
+unsigned
+notmuch_query_count_threads (notmuch_query_t *query)
+{
+notmuch_messages_t *messages;
+GHashTable *hash;
+unsigned int count;
+notmuch_sort_t sort;
+
+sort = query-sort;
+query-sort = NOTMUCH_SORT_UNSORTED;
+messages = notmuch_query_search_messages (query);
+query-sort = sort;
+if (messages == NULL)
+   return 0;
+
+hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
+if (hash == NULL) {
+   talloc_free (messages);
+   return 0;
+}
+
+while (notmuch_messages_valid (messages)) {
+   notmuch_message_t *message = notmuch_messages_get (messages);
+   const char *thread_id = notmuch_message_get_thread_id (message);
+   char *thread_id_copy = talloc_strdup (messages, thread_id);
+   if (unlikely (thread_id_copy == NULL)) {
+   notmuch_message_destroy (message);
+   count = 0;
+   goto DONE;
+   }
+   g_hash_table_insert (hash, thread_id_copy, NULL);
+   notmuch_message_destroy (message);
+   notmuch_messages_move_to_next (messages);
+}
+
+count = g_hash_table_size (hash);
+
+  DONE:
+g_hash_table_unref (hash);
+talloc_free (messages);
+
+return count;
+}
-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v5 2/6] cli: add options --first and --maxitems to notmuch search

2011-11-13 Thread Jani Nikula
Add options --first=[-]N and --maxitems=M to notmuch search to determine
the first result and maximum number of results to display.

Option --maxitems=M limits the maximum number of results to display to M.

Option --first=[-]N skips the first N results; with the leading '-' skip
until the Nth result from the end (showing a total of N results if within
bounds of the total number of results and not limited with --maxitems).

Note that --first with a negative N for thread or summary output requires
counting the number of matching threads in advance.

Signed-off-by: Jani Nikula j...@nikula.org
---
 NEWS |5 
 notmuch-search.c |   70 -
 notmuch.1|   19 +-
 3 files changed, 80 insertions(+), 14 deletions(-)

diff --git a/NEWS b/NEWS
index 71c7c9a..abc749a 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,11 @@ Add search terms to  notmuch dump
   search/show/tag. The output file argument of dump is deprecated in
   favour of using stdout.
 
+Add notmuch search --first and --maxitems options
+
+  The search command now takes options --first=[-]N and --maxitems=N to limit
+  the number of results shown.
+
 Notmuch 0.9 (2011-10-01)
 
 
diff --git a/notmuch-search.c b/notmuch-search.c
index 6f04d9a..c62a594 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -194,13 +194,22 @@ static int
 do_search_threads (const search_format_t *format,
   notmuch_query_t *query,
   notmuch_sort_t sort,
-  output_t output)
+  output_t output,
+  int first,
+  int maxitems)
 {
 notmuch_thread_t *thread;
 notmuch_threads_t *threads;
 notmuch_tags_t *tags;
 time_t date;
 int first_thread = 1;
+int i;
+
+if (first  0) {
+   first += notmuch_query_count_threads (query);
+   if (first  0)
+   first = 0;
+}
 
 threads = notmuch_query_search_threads (query);
 if (threads == NULL)
@@ -208,17 +217,23 @@ do_search_threads (const search_format_t *format,
 
 fputs (format-results_start, stdout);
 
-for (;
-notmuch_threads_valid (threads);
-notmuch_threads_move_to_next (threads))
+for (i = 0;
+notmuch_threads_valid (threads) 
+(maxitems  0 || i  first + maxitems);
+notmuch_threads_move_to_next (threads), i++)
 {
int first_tag = 1;
 
+   thread = notmuch_threads_get (threads);
+
+   if (i  first) {
+   notmuch_thread_destroy (thread);
+   continue;
+   }
+
if (! first_thread)
fputs (format-item_sep, stdout);
 
-   thread = notmuch_threads_get (threads);
-
if (output == OUTPUT_THREADS) {
format-item_id (thread, thread:,
 notmuch_thread_get_thread_id (thread));
@@ -271,12 +286,21 @@ do_search_threads (const search_format_t *format,
 static int
 do_search_messages (const search_format_t *format,
notmuch_query_t *query,
-   output_t output)
+   output_t output,
+   int first,
+   int maxitems)
 {
 notmuch_message_t *message;
 notmuch_messages_t *messages;
 notmuch_filenames_t *filenames;
 int first_message = 1;
+int i;
+
+if (first  0) {
+   first += notmuch_query_count_messages (query);
+   if (first  0)
+   first = 0;
+}
 
 messages = notmuch_query_search_messages (query);
 if (messages == NULL)
@@ -284,10 +308,14 @@ do_search_messages (const search_format_t *format,
 
 fputs (format-results_start, stdout);
 
-for (;
-notmuch_messages_valid (messages);
-notmuch_messages_move_to_next (messages))
+for (i = 0;
+notmuch_messages_valid (messages) 
+(maxitems  0 || i  first + maxitems);
+notmuch_messages_move_to_next (messages), i++)
 {
+   if (i  first)
+   continue;
+
message = notmuch_messages_get (messages);
 
if (output == OUTPUT_FILES) {
@@ -394,6 +422,8 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
 const search_format_t *format = format_text;
 int i, ret;
 output_t output = OUTPUT_SUMMARY;
+int maxitems = -1; /* unlimited */
+int first = 0;
 
 argc--; argv++; /* skip subcommand argument */
 
@@ -412,6 +442,22 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
fprintf (stderr, Invalid value for --sort: %s\n, opt);
return 1;
}
+   } else if (STRNCMP_LITERAL (argv[i], --first=) == 0) {
+   char *p;
+   opt = argv[i] + sizeof (--first=) - 1;
+   first = strtol (opt, p, 10);
+   if (*opt == '\0' || p == opt || *p != '\0') {
+   fprintf (stderr, Invalid value for --first: %s\n, opt);
+   return 1;
+   }
+   } else if (STRNCMP_LITERAL (argv[i], 

[PATCH v5 3/6] cli: drop unused code from notmuch count

2011-11-13 Thread Jani Nikula
Remove unused code within #if 0 blocks from notmuch count.

Signed-off-by: Jani Nikula j...@nikula.org
---
 notmuch-count.c |   32 
 1 files changed, 0 insertions(+), 32 deletions(-)

diff --git a/notmuch-count.c b/notmuch-count.c
index 0d700a9..a35be40 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -29,11 +29,6 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 notmuch_query_t *query;
 char *query_str;
 int i;
-#if 0
-char *opt, *end;
-int i, first = 0, max_threads = -1;
-notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST;
-#endif
 
 argc--; argv++; /* skip subcommand argument */
 
@@ -42,33 +37,6 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
i++;
break;
}
-#if 0
-   if (STRNCMP_LITERAL (argv[i], --first=) == 0) {
-   opt = argv[i] + sizeof (--first=) - 1;
-   first = strtoul (opt, end, 10);
-   if (*opt == '\0' || *end != '\0') {
-   fprintf (stderr, Invalid value for --first: %s\n, opt);
-   return 1;
-   }
-   } else if (STRNCMP_LITERAL (argv[i], --max-threads=) == 0) {
-   opt = argv[i] + sizeof (--max-threads=) - 1;
-   max_threads = strtoul (opt, end, 10);
-   if (*opt == '\0' || *end != '\0') {
-   fprintf (stderr, Invalid value for --max-threads: %s\n, opt);
-   return 1;
-   }
-   } else if (STRNCMP_LITERAL (argv[i], --sort=) == 0) {
-   opt = argv[i] + sizeof (--sort=) - 1;
-   if (strcmp (opt, oldest-first) == 0) {
-   sort = NOTMUCH_SORT_OLDEST_FIRST;
-   } else if (strcmp (opt, newest-first) == 0) {
-   sort = NOTMUCH_SORT_NEWEST_FIRST;
-   } else {
-   fprintf (stderr, Invalid value for --sort: %s\n, opt);
-   return 1;
-   }
-   } else
-#endif
{
fprintf (stderr, Unrecognized option: %s\n, argv[i]);
return 1;
-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v5 6/6] test: add tests for notmuch search --first and --maxitems

2011-11-13 Thread Jani Nikula
Signed-off-by: Jani Nikula j...@nikula.org
---
 test/notmuch-test|1 +
 test/search-limiting |   71 ++
 2 files changed, 72 insertions(+), 0 deletions(-)
 create mode 100755 test/search-limiting

diff --git a/test/notmuch-test b/test/notmuch-test
index 587adb5..435b469 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -25,6 +25,7 @@ TESTS=
   search-by-folder
   search-position-overlap-bug
   search-insufficient-from-quoting
+  search-limiting
   json
   multipart
   thread-naming
diff --git a/test/search-limiting b/test/search-limiting
new file mode 100755
index 000..45cc0a9
--- /dev/null
+++ b/test/search-limiting
@@ -0,0 +1,71 @@
+#!/usr/bin/env bash
+test_description='notmuch search --first and --maxitems parameters'
+. ./test-lib.sh
+
+add_email_corpus
+
+for outp in messages threads; do
+test_begin_subtest ${outp}: maxitems does the right thing
+notmuch search --output=${outp} * | head -n 20 expected
+notmuch search --output=${outp} --maxitems=20 * output
+test_expect_equal_file expected output
+
+test_begin_subtest ${outp}: concatenation of limited searches
+notmuch search --output=${outp} * | head -n 20 expected
+notmuch search --output=${outp} --maxitems=10 * output
+notmuch search --output=${outp} --maxitems=10 --first=10 * output
+test_expect_equal_file expected output
+
+test_begin_subtest ${outp}: maxitems larger than result set
+N=`notmuch count --output=${outp} *`
+notmuch search --output=${outp} * expected
+notmuch search --output=${outp} --maxitems=$((1 + ${N})) * output
+test_expect_equal_file expected output
+
+test_begin_subtest ${outp}: maxitems = 0
+test_expect_equal `notmuch search --output=${outp} --maxitems=0 *` 
+
+test_begin_subtest ${outp}: first does the right thing
+# note: tail -n +N is 1-based
+notmuch search --output=${outp} * | tail -n +21 expected
+notmuch search --output=${outp} --first=20 * output
+test_expect_equal_file expected output
+
+test_begin_subtest ${outp}: first = 0
+notmuch search --output=${outp} * expected
+notmuch search --output=${outp} --first=0 * output
+test_expect_equal_file expected output
+
+test_begin_subtest ${outp}: negative first
+notmuch search --output=${outp} * | tail -n 20 expected
+notmuch search --output=${outp} --first=-20 * output
+test_expect_equal_file expected output
+
+test_begin_subtest ${outp}: negative first
+notmuch search --output=${outp} * | tail -n 1 expected
+notmuch search --output=${outp} --first=-1 * output
+test_expect_equal_file expected output
+
+test_begin_subtest ${outp}: negative first combined with maxitems
+notmuch search --output=${outp} * | tail -n 20 | head -n 10 expected
+notmuch search --output=${outp} --first=-20 --maxitems=10 * output
+test_expect_equal_file expected output
+
+test_begin_subtest ${outp}: negative first combined with equal maxitems
+notmuch search --output=${outp} * | tail -n 20 expected
+notmuch search --output=${outp} --first=-20 --maxitems=20 * output
+test_expect_equal_file expected output
+
+test_begin_subtest ${outp}: negative first combined with large maxitems
+notmuch search --output=${outp} * | tail -n 20 expected
+notmuch search --output=${outp} --first=-20 --maxitems=50 * output
+test_expect_equal_file expected output
+
+test_begin_subtest ${outp}: negative first larger then results
+N=`notmuch count --output=${outp} *`
+notmuch search --output=${outp} * expected
+notmuch search --output=${outp} --first=-$((1 + ${N})) * output
+test_expect_equal_file expected output
+done
+
+test_done
-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v6 1/6] lib: add function to get the number of threads matching a search

2011-11-13 Thread Jani Nikula
Add function notmuch_query_count_threads() to get the number of threads
matching a search. This is done by performing a search and figuring out the
number of unique thread IDs in the matching messages, a significantly
heavier operation than notmuch_query_count_messages().

Signed-off-by: Jani Nikula j...@nikula.org
---
 lib/notmuch.h |   14 ++
 lib/query.cc  |   44 
 2 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/lib/notmuch.h b/lib/notmuch.h
index c4330e4..9f23a10 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -609,6 +609,20 @@ notmuch_threads_destroy (notmuch_threads_t *threads);
 unsigned
 notmuch_query_count_messages (notmuch_query_t *query);
  
+/* Return the number of threads matching a search.
+ *
+ * This function performs a search and returns the number of unique thread IDs
+ * in the matching messages. This is the same as number of threads matching a
+ * search.
+ *
+ * Note that this is a significantly heavier operation than
+ * notmuch_query_count_messages().
+ *
+ * If an error occurs, this function may return 0.
+ */
+unsigned
+notmuch_query_count_threads (notmuch_query_t *query);
+
 /* Get the thread ID of 'thread'.
  *
  * The returned string belongs to 'thread' and as such, should not be
diff --git a/lib/query.cc b/lib/query.cc
index 6f02b04..b6c0f12 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -457,3 +457,47 @@ notmuch_query_count_messages (notmuch_query_t *query)
 
 return count;
 }
+
+unsigned
+notmuch_query_count_threads (notmuch_query_t *query)
+{
+notmuch_messages_t *messages;
+GHashTable *hash;
+unsigned int count;
+notmuch_sort_t sort;
+
+sort = query-sort;
+query-sort = NOTMUCH_SORT_UNSORTED;
+messages = notmuch_query_search_messages (query);
+query-sort = sort;
+if (messages == NULL)
+   return 0;
+
+hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
+if (hash == NULL) {
+   talloc_free (messages);
+   return 0;
+}
+
+while (notmuch_messages_valid (messages)) {
+   notmuch_message_t *message = notmuch_messages_get (messages);
+   const char *thread_id = notmuch_message_get_thread_id (message);
+   char *thread_id_copy = talloc_strdup (messages, thread_id);
+   if (unlikely (thread_id_copy == NULL)) {
+   notmuch_message_destroy (message);
+   count = 0;
+   goto DONE;
+   }
+   g_hash_table_insert (hash, thread_id_copy, NULL);
+   notmuch_message_destroy (message);
+   notmuch_messages_move_to_next (messages);
+}
+
+count = g_hash_table_size (hash);
+
+  DONE:
+g_hash_table_unref (hash);
+talloc_free (messages);
+
+return count;
+}
-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v6 3/6] cli: drop unused code from notmuch count

2011-11-13 Thread Jani Nikula
Remove unused code within #if 0 blocks from notmuch count.

Signed-off-by: Jani Nikula j...@nikula.org
---
 notmuch-count.c |   32 
 1 files changed, 0 insertions(+), 32 deletions(-)

diff --git a/notmuch-count.c b/notmuch-count.c
index 0d700a9..a35be40 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -29,11 +29,6 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 notmuch_query_t *query;
 char *query_str;
 int i;
-#if 0
-char *opt, *end;
-int i, first = 0, max_threads = -1;
-notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST;
-#endif
 
 argc--; argv++; /* skip subcommand argument */
 
@@ -42,33 +37,6 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
i++;
break;
}
-#if 0
-   if (STRNCMP_LITERAL (argv[i], --first=) == 0) {
-   opt = argv[i] + sizeof (--first=) - 1;
-   first = strtoul (opt, end, 10);
-   if (*opt == '\0' || *end != '\0') {
-   fprintf (stderr, Invalid value for --first: %s\n, opt);
-   return 1;
-   }
-   } else if (STRNCMP_LITERAL (argv[i], --max-threads=) == 0) {
-   opt = argv[i] + sizeof (--max-threads=) - 1;
-   max_threads = strtoul (opt, end, 10);
-   if (*opt == '\0' || *end != '\0') {
-   fprintf (stderr, Invalid value for --max-threads: %s\n, opt);
-   return 1;
-   }
-   } else if (STRNCMP_LITERAL (argv[i], --sort=) == 0) {
-   opt = argv[i] + sizeof (--sort=) - 1;
-   if (strcmp (opt, oldest-first) == 0) {
-   sort = NOTMUCH_SORT_OLDEST_FIRST;
-   } else if (strcmp (opt, newest-first) == 0) {
-   sort = NOTMUCH_SORT_NEWEST_FIRST;
-   } else {
-   fprintf (stderr, Invalid value for --sort: %s\n, opt);
-   return 1;
-   }
-   } else
-#endif
{
fprintf (stderr, Unrecognized option: %s\n, argv[i]);
return 1;
-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v6 4/6] cli: add support for --output parameter in notmuch count

2011-11-13 Thread Jani Nikula
Add support for --output=messages (which remains the default) and
--output=threads to notmuch count.

Signed-off-by: Jani Nikula j...@nikula.org
---
 NEWS|5 +
 notmuch-count.c |   18 --
 notmuch.1   |   29 +
 notmuch.c   |   20 
 4 files changed, 62 insertions(+), 10 deletions(-)

diff --git a/NEWS b/NEWS
index abc749a..78434d9 100644
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,11 @@ Add notmuch search --first and --maxitems options
   The search command now takes options --first=[-]N and --maxitems=N to limit
   the number of results shown.
 
+Add notmuch count --output option
+
+  The count command is now capable of counting threads in addition to
+  messages. This is selected using the new --output=(threads|messages) option.
+
 Notmuch 0.9 (2011-10-01)
 
 
diff --git a/notmuch-count.c b/notmuch-count.c
index a35be40..20ce334 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -29,6 +29,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 notmuch_query_t *query;
 char *query_str;
 int i;
+notmuch_bool_t output_messages = TRUE;
 
 argc--; argv++; /* skip subcommand argument */
 
@@ -37,7 +38,17 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
i++;
break;
}
-   {
+   if (STRNCMP_LITERAL (argv[i], --output=) == 0) {
+   const char *opt = argv[i] + sizeof (--output=) - 1;
+   if (strcmp (opt, threads) == 0) {
+   output_messages = FALSE;
+   } else if (strcmp (opt, messages) == 0) {
+   output_messages = TRUE;
+   } else {
+   fprintf (stderr, Invalid value for --output: %s\n, opt);
+   return 1;
+   }
+   } else {
fprintf (stderr, Unrecognized option: %s\n, argv[i]);
return 1;
}
@@ -71,7 +82,10 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
return 1;
 }
 
-printf (%u\n, notmuch_query_count_messages(query));
+if (output_messages)
+   printf (%u\n, notmuch_query_count_messages (query));
+else
+   printf (%u\n, notmuch_query_count_threads (query));
 
 notmuch_query_destroy (query);
 notmuch_database_close (notmuch);
diff --git a/notmuch.1 b/notmuch.1
index 15c3147..64114db 100644
--- a/notmuch.1
+++ b/notmuch.1
@@ -372,14 +372,35 @@ section below for details of the supported syntax for 
search-terms.
 .RE
 .RS 4
 .TP 4
-.BR count  search-term...
+.BR count  [options...] search-term...
 
 Count messages matching the search terms.
 
-The number of matching messages is output to stdout.
+The number of matching messages (or threads) is output to stdout.
 
-With no search terms, a count of all messages in the database will be
-displayed.
+With no search terms, a count of all messages (or threads) in the database will
+be displayed.
+
+Supported options for
+.B count
+include
+.RS 4
+.TP 4
+.B \-\-output=(messages|threads)
+
+.RS 4
+.TP 4
+.B messages
+
+Output the number of matching messages. This is the default.
+.RE
+.RS 4
+.TP 4
+.B threads
+
+Output the number of matching threads.
+.RE
+.RE
 .RE
 .RE
 
diff --git a/notmuch.c b/notmuch.c
index 601ffad..0a4ffe9 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -328,12 +328,24 @@ static command_t commands[] = {
   \tSee \notmuch help search-terms\ for details of the search\n
   \tterms syntax. },
 { count, notmuch_count_command,
-  search-terms [...],
+  [options...] search-terms [...],
   Count messages matching the search terms.,
-  \tThe number of matching messages is output to stdout.\n
+  \tThe number of matching messages (or threads) is output to stdout.\n
+  \n
+  \tWith no search terms, a count of all messages (or threads) in\n
+  \tthe database will be displayed.\n
+  \n
+  \tSupported options for count include:\n
+  \n
+  \t--output=(messages|threads)\n
+  \n
+  \t\tmessages (default)\n
+  \n
+  \t\tOutput the number of matching messages.\n
+  \n
+  \t\tthreads\n
   \n
-  \tWith no search terms, a count of all messages in the database\n
-  \twill be displayed.\n
+  \t\tOutput the number of matching threads.\n
   \n
   \tSee \notmuch help search-terms\ for details of the search\n
   \tterms syntax. },
-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v6 5/6] test: add tests for notmuch count

2011-11-13 Thread Jani Nikula
Signed-off-by: Jani Nikula j...@nikula.org
---
 test/count|   40 
 test/notmuch-test |1 +
 2 files changed, 41 insertions(+), 0 deletions(-)
 create mode 100755 test/count

diff --git a/test/count b/test/count
new file mode 100755
index 000..300b171
--- /dev/null
+++ b/test/count
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+test_description='notmuch count for messages and threads'
+. ./test-lib.sh
+
+add_email_corpus
+
+SEARCH=\*\
+
+test_begin_subtest message count is the default for notmuch count
+test_expect_equal \
+`notmuch search --output=messages ${SEARCH} | wc -l` \
+`notmuch count ${SEARCH}`
+
+test_begin_subtest message count with --output=messages
+test_expect_equal \
+`notmuch search --output=messages ${SEARCH} | wc -l` \
+`notmuch count --output=messages ${SEARCH}`
+
+test_begin_subtest thread count with --output=threads
+test_expect_equal \
+`notmuch search --output=threads ${SEARCH} | wc -l` \
+`notmuch count --output=threads ${SEARCH}`
+
+test_begin_subtest thread count is the default for notmuch search
+test_expect_equal \
+`notmuch search ${SEARCH} | wc -l` \
+`notmuch count --output=threads ${SEARCH}`
+
+SEARCH=from:cworth and not from:cworth
+test_begin_subtest count with no matching messages
+test_expect_equal \
+0 \
+`notmuch count --output=messages ${SEARCH}`
+
+test_begin_subtest count with no matching threads
+test_expect_equal \
+0 \
+`notmuch count --output=threads ${SEARCH}`
+
+test_done
diff --git a/test/notmuch-test b/test/notmuch-test
index 738f8f6..587adb5 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -19,6 +19,7 @@ cd $(dirname $0)
 TESTS=
   basic
   new
+  count
   search
   search-output
   search-by-folder
-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[no subject]

2011-11-13 Thread Jameson Graef Rollins
I really hate the default behavior of the space bar in notmuch-show; I
don't want it to pop out of the thread that i'm currently view, and I
especially don't want it to archive threads.  The space bar should
just be for viewing, not altering.

The following patch breaks out the food functionality from
notmuch-show-advance-and-archive so that people can easily rebind it
to the space bar.  Although I do personally think we should change the
default behavior, I leave the current behavior untouched, since I
suppose there maybe are some people out there that like the current
behavior and don't expect it to change.

jamie.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] emacs: breakout notmuch-show-advance functionality from notmuch-show-advance-and-archive

2011-11-13 Thread Jameson Graef Rollins
This patch breaks out much of the functionality of
notmuch-show-advance-and-archive into a new function:
notmuch-show-advance.  This new function does all the advancing
through a show buffer that notmuch-show-advance-and-archive did,
without all the invasive thread archiving.  The return value of
notmuch-show-advance is nil if the bottom of the thread is not
reached, and t if it is.

notmuch-show-advance-and-archive is modified to just call
notmuch-show-advance, and then call notmuch-show-archive-thread if the
return value is true.  In this way the previous functionality of
notmuch-show-advance-and-archive is preserved.

This provides a way for people to rebind the space bar to a more sane
function if they don't like the default behavior.
---
 emacs/notmuch-show.el |   38 +++---
 1 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index d5c95d8..a7f3263 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1135,26 +1135,18 @@ All currently available key bindings:
 
 ;; Commands typically bound to keys.
 
-(defun notmuch-show-advance-and-archive ()
-  Advance through thread and archive.
-
-This command is intended to be one of the simplest ways to
-process a thread of email. It does the following:
+(defun notmuch-show-advance ()
+  Advance through thread.
 
 If the current message in the thread is not yet fully visible,
 scroll by a near screenful to read more of the message.
 
 Otherwise, (the end of the current message is already within the
-current window), advance to the next open message.
-
-Finally, if there is no further message to advance to, and this
-last message is already read, then archive the entire current
-thread, (remove the \inbox\ tag from each message). Also kill
-this buffer, and display the next thread from the search from
-which this thread was originally shown.
+current window), advance to the next open message.
   (interactive)
   (let* ((end-of-this-message (notmuch-show-message-bottom))
-(visible-end-of-this-message (1- end-of-this-message)))
+(visible-end-of-this-message (1- end-of-this-message))
+(ret nil))
 (while (invisible-p visible-end-of-this-message)
   (setq visible-end-of-this-message
(previous-single-char-property-change visible-end-of-this-message
@@ -1173,8 +1165,24 @@ which this thread was originally shown.
   (notmuch-show-next-open-message))
 
  (t
-  ;; This is the last message - archive the thread.
-  (notmuch-show-archive-thread)
+  ;; This is the last message - change the return value
+  (setq ret t)))
+ret))
+
+(defun notmuch-show-advance-and-archive ()
+  Advance through thread and archive.
+
+This command is intended to be one of the simplest ways to
+process a thread of email. It works exactly like
+notmuch-show-advance, in that it scrolls through messages in a
+show buffer, except that when it gets to the end of the buffer it
+archives the entire current thread, (remove the \inbox\ tag
+from each message), kills the buffer, and displays the next
+thread from the search from which this thread was originally
+shown.
+  (interactive)
+  (if (notmuch-show-advance)
+  (notmuch-show-archive-thread)))
 
 (defun notmuch-show-rewind ()
   Backup through the thread, (reverse scrolling compared to 
\\[notmuch-show-advance-and-archive]).
-- 
1.7.7.1

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v2] emacs: Let the user choose where to compose new mails

2011-11-13 Thread Jameson Graef Rollins
Hey, Thomas et. al.  I've tested this patch and it works great!  The
customization interface is very clean now, and the newly created
windows/frames close automatically when the message is sent.  Very
nice.

Thanks so much, Thomas, for this nice ui feature.  The commit message is
a little sparse, but other than that I definitely support it's
inclusion.

jamie.


pgp4mRz1hCsui.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 0/6] cli getoptification

2011-11-13 Thread Jani Nikula
Hi, this set switches to getopt_long for parsing command line options where
applicable, and hopefully makes David happy. ;)

This is on top of id:cover.1321217854.git.j...@nikula.org.

This was a fairly quick exercise, so watch out for bugs. getopt_long does have
subtle differences from the original. All the tests pass after patch 6/6.

BR,
Jani.


Jani Nikula (6):
  cli: notmuch new: use getopt_long for parsing command line options
  cli: notmuch search: use getopt_long for parsing command line options
  cli: notmuch show: use getopt_long for parsing command line options
  cli: notmuch count: use getopt_long for parsing command line options
  cli: notmuch reply: use getopt_long for parsing command line options
  test: emacs-large-search-buffer: expected results according to
getopt_long

 notmuch-client.h   |1 +
 notmuch-count.c|   33 ---
 notmuch-new.c  |   20 +++--
 notmuch-reply.c|   40 ++
 notmuch-search.c   |   90 +--
 notmuch-show.c |   61 +++---
 test/emacs-large-search-buffer |2 +-
 7 files changed, 141 insertions(+), 106 deletions(-)

-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 1/6] cli: notmuch new: use getopt_long for parsing command line options

2011-11-13 Thread Jani Nikula
Signed-off-by: Jani Nikula j...@nikula.org
---
 notmuch-client.h |1 +
 notmuch-new.c|   20 +++-
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index b50cb38..eb16f0d 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -43,6 +43,7 @@
 #include sys/stat.h
 #include sys/time.h
 #include unistd.h
+#include getopt.h
 #include dirent.h
 #include errno.h
 #include signal.h
diff --git a/notmuch-new.c b/notmuch-new.c
index 81a9350..145aa64 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -815,16 +815,26 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
 add_files_state.verbose = 0;
 add_files_state.output_is_a_tty = isatty (fileno (stdout));
 
-argc--; argv++; /* skip subcommand argument */
+while (1) {
+   int opt;
+   static struct option options[] = {
+   { verbose, no_argument, NULL, 0 },
+   { NULL, 0, NULL, 0 },
+   };
+
+   opt = getopt_long (argc, argv, , options, NULL);
+   if (opt == -1)
+   break;
 
-for (i = 0; i  argc  argv[i][0] == '-'; i++) {
-   if (STRNCMP_LITERAL (argv[i], --verbose) == 0) {
+   switch (opt) {
+   case 0:
add_files_state.verbose = 1;
-   } else {
-   fprintf (stderr, Unrecognized option: %s\n, argv[i]);
+   break;
+   case '?':
return 1;
}
 }
+
 config = notmuch_config_open (ctx, NULL, NULL);
 if (config == NULL)
return 1;
-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 2/6] cli: notmuch search: use getopt_long for parsing command line options

2011-11-13 Thread Jani Nikula
Signed-off-by: Jani Nikula j...@nikula.org
---
 notmuch-search.c |   90 -
 1 files changed, 48 insertions(+), 42 deletions(-)

diff --git a/notmuch-search.c b/notmuch-search.c
index c62a594..4f7384a 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -417,81 +417,87 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
 notmuch_database_t *notmuch;
 notmuch_query_t *query;
 char *query_str;
-char *opt;
 notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST;
 const search_format_t *format = format_text;
-int i, ret;
+int ret;
 output_t output = OUTPUT_SUMMARY;
 int maxitems = -1; /* unlimited */
 int first = 0;
 
-argc--; argv++; /* skip subcommand argument */
-
-for (i = 0; i  argc  argv[i][0] == '-'; i++) {
-   if (strcmp (argv[i], --) == 0) {
-   i++;
+while (1) {
+   char *p;
+   int opt;
+   static struct option options[] = {
+   { sort, required_argument, NULL, 0 },
+   { first, required_argument, NULL, 1 },
+   { maxitems, required_argument, NULL, 2 },
+   { format, required_argument, NULL, 3 },
+   { output, required_argument, NULL, 4 },
+   { NULL, 0, NULL, 0 },
+   };
+
+   opt = getopt_long (argc, argv, , options, NULL);
+   if (opt == -1)
break;
-   }
-if (STRNCMP_LITERAL (argv[i], --sort=) == 0) {
-   opt = argv[i] + sizeof (--sort=) - 1;
-   if (strcmp (opt, oldest-first) == 0) {
+
+   switch (opt) {
+   case 0:
+   if (strcmp (optarg, oldest-first) == 0) {
sort = NOTMUCH_SORT_OLDEST_FIRST;
-   } else if (strcmp (opt, newest-first) == 0) {
+   } else if (strcmp (optarg, newest-first) == 0) {
sort = NOTMUCH_SORT_NEWEST_FIRST;
} else {
-   fprintf (stderr, Invalid value for --sort: %s\n, opt);
+   fprintf (stderr, Invalid value for --sort: %s\n, optarg);
return 1;
}
-   } else if (STRNCMP_LITERAL (argv[i], --first=) == 0) {
-   char *p;
-   opt = argv[i] + sizeof (--first=) - 1;
-   first = strtol (opt, p, 10);
-   if (*opt == '\0' || p == opt || *p != '\0') {
-   fprintf (stderr, Invalid value for --first: %s\n, opt);
+   break;
+   case 1:
+   first = strtol (optarg, p, 10);
+   if (*optarg == '\0' || p == optarg || *p != '\0') {
+   fprintf (stderr, Invalid value for --first: %s\n, optarg);
return 1;
}
-   } else if (STRNCMP_LITERAL (argv[i], --maxitems=) == 0) {
-   char *p;
-   opt = argv[i] + sizeof (--maxitems=) - 1;
-   maxitems = strtoul (opt, p, 10);
-   if (*opt == '\0' || p == opt || *p != '\0') {
-   fprintf (stderr, Invalid value for --maxitems: %s\n, opt);
+   break;
+   case 2:
+   maxitems = strtoul (optarg, p, 10);
+   if (*optarg == '\0' || p == optarg || *p != '\0') {
+   fprintf (stderr, Invalid value for --maxitems: %s\n, optarg);
return 1;
}
-   } else if (STRNCMP_LITERAL (argv[i], --format=) == 0) {
-   opt = argv[i] + sizeof (--format=) - 1;
-   if (strcmp (opt, text) == 0) {
+   break;
+   case 3:
+   if (strcmp (optarg, text) == 0) {
format = format_text;
-   } else if (strcmp (opt, json) == 0) {
+   } else if (strcmp (optarg, json) == 0) {
format = format_json;
} else {
-   fprintf (stderr, Invalid value for --format: %s\n, opt);
+   fprintf (stderr, Invalid value for --format: %s\n, optarg);
return 1;
}
-   } else if (STRNCMP_LITERAL (argv[i], --output=) == 0) {
-   opt = argv[i] + sizeof (--output=) - 1;
-   if (strcmp (opt, summary) == 0) {
+   break;
+   case 4:
+   if (strcmp (optarg, summary) == 0) {
output = OUTPUT_SUMMARY;
-   } else if (strcmp (opt, threads) == 0) {
+   } else if (strcmp (optarg, threads) == 0) {
output = OUTPUT_THREADS;
-   } else if (strcmp (opt, messages) == 0) {
+   } else if (strcmp (optarg, messages) == 0) {
output = OUTPUT_MESSAGES;
-   } else if (strcmp (opt, files) == 0) {
+   } else if (strcmp (optarg, files) == 0) {
output = OUTPUT_FILES;
-   } else if (strcmp (opt, tags) == 0) {
+   } else if (strcmp (optarg, tags) == 0) {
output = OUTPUT_TAGS;
} else {
-   fprintf (stderr, Invalid value for --output: %s\n, opt);
+   fprintf (stderr, Invalid value for --output: %s\n, optarg);
return 1;
}
-   } else {
-   fprintf (stderr, Unrecognized 

[PATCH 3/6] cli: notmuch show: use getopt_long for parsing command line options

2011-11-13 Thread Jani Nikula
Signed-off-by: Jani Nikula j...@nikula.org
---
 notmuch-show.c |   61 ---
 1 files changed, 35 insertions(+), 26 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index 603992a..73b4557 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -923,12 +923,10 @@ notmuch_show_command (void *ctx, unused (int argc), 
unused (char *argv[]))
 notmuch_database_t *notmuch;
 notmuch_query_t *query;
 char *query_string;
-char *opt;
 const notmuch_show_format_t *format = format_text;
 notmuch_show_params_t params;
 int mbox = 0;
 int format_specified = 0;
-int i;
 
 params.entire_thread = 0;
 params.raw = 0;
@@ -936,37 +934,50 @@ notmuch_show_command (void *ctx, unused (int argc), 
unused (char *argv[]))
 params.cryptoctx = NULL;
 params.decrypt = 0;
 
-argc--; argv++; /* skip subcommand argument */
-
-for (i = 0; i  argc  argv[i][0] == '-'; i++) {
-   if (strcmp (argv[i], --) == 0) {
-   i++;
+while (1) {
+   int opt;
+   static struct option options[] = {
+   { format, required_argument, NULL, 0 },
+   { part, required_argument, NULL, 1 },
+   { entire-thread, no_argument, NULL, 2 },
+   { decrypt, no_argument, NULL, 3 },
+   { verify, no_argument, NULL, 4 },
+   { NULL, 0, NULL, 0 },
+   };
+
+   opt = getopt_long (argc, argv, , options, NULL);
+   if (opt == -1)
break;
-   }
-   if (STRNCMP_LITERAL (argv[i], --format=) == 0) {
-   opt = argv[i] + sizeof (--format=) - 1;
-   if (strcmp (opt, text) == 0) {
+
+   switch (opt) {
+   case 0:
+   if (strcmp (optarg, text) == 0) {
format = format_text;
-   } else if (strcmp (opt, json) == 0) {
+   } else if (strcmp (optarg, json) == 0) {
format = format_json;
params.entire_thread = 1;
-   } else if (strcmp (opt, mbox) == 0) {
+   } else if (strcmp (optarg, mbox) == 0) {
format = format_mbox;
mbox = 1;
-   } else if (strcmp (opt, raw) == 0) {
+   } else if (strcmp (optarg, raw) == 0) {
format = format_raw;
params.raw = 1;
} else {
-   fprintf (stderr, Invalid value for --format: %s\n, opt);
+   fprintf (stderr, Invalid value for --format: %s\n, optarg);
return 1;
}
format_specified = 1;
-   } else if (STRNCMP_LITERAL (argv[i], --part=) == 0) {
-   params.part = atoi(argv[i] + sizeof (--part=) - 1);
-   } else if (STRNCMP_LITERAL (argv[i], --entire-thread) == 0) {
+   break;
+   case 1:
+   params.part = atoi(optarg);
+   break;
+   case 2:
params.entire_thread = 1;
-   } else if ((STRNCMP_LITERAL (argv[i], --verify) == 0) ||
-  (STRNCMP_LITERAL (argv[i], --decrypt) == 0)) {
+   break;
+   case 3:
+   params.decrypt = 1;
+   /* fallthrough */
+   case 4:
if (params.cryptoctx == NULL) {
GMimeSession* session = g_object_new(g_mime_session_get_type(), 
NULL);
if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, 
gpg)))
@@ -976,16 +987,14 @@ notmuch_show_command (void *ctx, unused (int argc), 
unused (char *argv[]))
g_object_unref (session);
session = NULL;
}
-   if (STRNCMP_LITERAL (argv[i], --decrypt) == 0)
-   params.decrypt = 1;
-   } else {
-   fprintf (stderr, Unrecognized option: %s\n, argv[i]);
+   break;
+   case '?':
return 1;
}
 }
 
-argc -= i;
-argv += i;
+argc -= optind;
+argv += optind;
 
 config = notmuch_config_open (ctx, NULL, NULL);
 if (config == NULL)
-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 4/6] cli: notmuch count: use getopt_long for parsing command line options

2011-11-13 Thread Jani Nikula
Signed-off-by: Jani Nikula j...@nikula.org
---
 notmuch-count.c |   33 ++---
 1 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/notmuch-count.c b/notmuch-count.c
index 20ce334..4987ca8 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -28,34 +28,37 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 notmuch_database_t *notmuch;
 notmuch_query_t *query;
 char *query_str;
-int i;
 notmuch_bool_t output_messages = TRUE;
 
-argc--; argv++; /* skip subcommand argument */
+while (1) {
+   int opt;
+   static struct option options[] = {
+   { output, required_argument, NULL, 0 },
+   { NULL, 0, NULL, 0 },
+   };
 
-for (i = 0; i  argc  argv[i][0] == '-'; i++) {
-   if (strcmp (argv[i], --) == 0) {
-   i++;
+   opt = getopt_long (argc, argv, , options, NULL);
+   if (opt == -1)
break;
-   }
-   if (STRNCMP_LITERAL (argv[i], --output=) == 0) {
-   const char *opt = argv[i] + sizeof (--output=) - 1;
-   if (strcmp (opt, threads) == 0) {
+
+   switch (opt) {
+   case 0:
+   if (strcmp (optarg, threads) == 0) {
output_messages = FALSE;
-   } else if (strcmp (opt, messages) == 0) {
+   } else if (strcmp (optarg, messages) == 0) {
output_messages = TRUE;
} else {
-   fprintf (stderr, Invalid value for --output: %s\n, opt);
+   fprintf (stderr, Invalid value for --output: %s\n, optarg);
return 1;
}
-   } else {
-   fprintf (stderr, Unrecognized option: %s\n, argv[i]);
+   break;
+   case '?':
return 1;
}
 }
 
-argc -= i;
-argv += i;
+argc -= optind;
+argv += optind;
 
 config = notmuch_config_open (ctx, NULL, NULL);
 if (config == NULL)
-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 6/6] test: emacs-large-search-buffer: expected results according to getopt_long

2011-11-13 Thread Jani Nikula
Signed-off-by: Jani Nikula j...@nikula.org
---
 test/emacs-large-search-buffer |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/test/emacs-large-search-buffer b/test/emacs-large-search-buffer
index 6095e9d..1bdffac 100755
--- a/test/emacs-large-search-buffer
+++ b/test/emacs-large-search-buffer
@@ -35,7 +35,7 @@ test_emacs '(notmuch-search --this-option-does-not-exist)
(test-output)'
 cat EOF EXPEXTED
 Error: Unexpected output from notmuch search:
-Unrecognized option: --this-option-does-not-exist
+search: unrecognized option '--this-option-does-not-exist'
 End of search results. (process returned 1)
 EOF
 test_expect_equal_file OUTPUT EXPEXTED
-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] add `tag:' prefix to `--output=tags' results

2011-11-13 Thread Jameson Graef Rollins
On Sat, 12 Nov 2011 10:17:30 -0500, David Bremner da...@tethera.net wrote:
 What do people think about this change? Personally I will have change
 some scripts to not add tag:, but it isn't that big of a deal.

I would actually prefer to see the prefixes removed from the messages
and threads output rather than see it added to the tags output.  I think
that's the way to make the output most consistent.  When I ask for
--output=messages I'm asking for the message ids of the messages, not
for search terms for the messages.  I think it should be up to the
consumer to add the prefix if they would like to construct search terms
based on the output.

My 2 cents.  I would be happy to provide a patch to make that change if
people agree to that behavior.

jamie.


pgpxNkJmIVogM.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v6 2/6] cli: add options --first and --maxitems to notmuch search

2011-11-13 Thread Jameson Graef Rollins
On Sun, 13 Nov 2011 23:15:31 +0200, Jani Nikula j...@nikula.org wrote:
 Option --maxitems=M limits the maximum number of results to display to M.

This is bike shedding, but can this option be called --limit instead
of maxitems?  Somehow that's more intuitive to me.

jamie.


pgpj1fvibw0LJ.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] Store from and subject headers in the database.

2011-11-13 Thread Jameson Graef Rollins
On Sun,  6 Nov 2011 12:17:36 -0500, Austin Clements amdra...@mit.edu wrote:
 This is a rebase and cleanup of Istvan Marko's patch from
 id:m3pqnj2j7a@zsu.kismala.com
 
 Search retrieves these headers for every message in the search
 results.  Previously, this required opening and parsing every message
 file.  Storing them directly in the database significantly reduces IO
 and computation, speeding up search by between 50% and 10X.

Hey, Austin.  This is a very nice patch.  Short and sweet, a really nice
performance improvement, and a nice gentle fallback.

I just rebuilt my database and I can definitely see the improvements.
Search results are incredibly snappy, and the resultant database is only
about 8% bigger.

I fully endorse this being pushed.

jamie.


pgpUikqhIU53e.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] add `tag:' prefix to `--output=tags' results

2011-11-13 Thread Dmitry Kurochkin
On Sun, 13 Nov 2011 15:00:56 -0800, Jameson Graef Rollins 
jroll...@finestructure.net wrote:
 On Sat, 12 Nov 2011 10:17:30 -0500, David Bremner da...@tethera.net wrote:
  What do people think about this change? Personally I will have change
  some scripts to not add tag:, but it isn't that big of a deal.
 
 I would actually prefer to see the prefixes removed from the messages
 and threads output rather than see it added to the tags output.  I think
 that's the way to make the output most consistent.  When I ask for
 --output=messages I'm asking for the message ids of the messages, not
 for search terms for the messages.  I think it should be up to the
 consumer to add the prefix if they would like to construct search terms
 based on the output.
 

Makes sense to me.

Regards,
  Dmitry

 My 2 cents.  I would be happy to provide a patch to make that change if
 people agree to that behavior.
 
 jamie.
 ___
 notmuch mailing list
 notmuch@notmuchmail.org
 http://notmuchmail.org/mailman/listinfo/notmuch
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch