]> granicus.if.org Git - neomutt/commitdiff
allow to read whole-threads
authorKarel Zak <kzak@redhat.com>
Fri, 15 Jun 2012 13:11:45 +0000 (15:11 +0200)
committerRichard Russon <rich@flatcap.org>
Mon, 4 Apr 2016 15:30:05 +0000 (16:30 +0100)
This patch allows to specify type of query for notmuch DB, supported
are "threads" and "messages", the default is "messages". For example:

   notmuch://?type=threads&query=tag:inbox"

will read all matching threads.

Based on prototype from Chris Mason <chris.mason@fusionio.com>.

Signed-off-by: Karel Zak <kzak@redhat.com>
README.notmuch
mutt_notmuch.c

index 3d6e09a3ec53d29fe9d2e5a81dae52ab70efcf15..eb6fd2b4293a2a2e5df130228cc10886f5084172 100644 (file)
@@ -57,8 +57,17 @@ notmuch support for mutt
 
       in your config files to keep things readable.
 
-   See http://xapian.org/docs/queryparser.html for more details about Xapian
-   queries.
+      See http://xapian.org/docs/queryparser.html for more details about Xapian
+      queries.
+
+
+      limit=<number>
+
+         Restricts number of messages/threads in the result.
+
+      type=<threads|messages>
+
+         Reads all matching messages or whole-threads. The defauls is 'messages'.
 
 
  * commands:
index 3a05a6287d8bb278c0de1029afe070f083f7a0b2..bfd6247d3458417dde7eee2290066a8682f6934e 100644 (file)
 #include "mutt_notmuch.h"
 #include "mutt_curses.h"
 
+/* read whole-thread or maching messages only? */
+enum {
+       NM_QUERY_TYPE_MESGS = 0,        /* default */
+       NM_QUERY_TYPE_THREADS
+};
+
 /*
  * Parsed URI arguments
  */
@@ -73,6 +79,7 @@ struct nm_ctxdata {
        char *db_filename;
        char *db_query;
        int db_limit;
+       int query_type;
        int longrun;
 
        struct uri_tag *query_items;
@@ -203,6 +210,7 @@ static struct nm_ctxdata *new_ctxdata(char *uri)
                mutt_error(_("failed to parse notmuch uri: %s"), uri);
                data->db_filename = NULL;
                data->query_items = NULL;
+               data->query_type = 0;
                return NULL;
        }
 
@@ -311,6 +319,14 @@ static char *get_query_string(struct nm_ctxdata *data)
                        if (mutt_atoi(item->value, &data->db_limit))
                                mutt_error (_("failed to parse notmuch limit: %s"), item->value);
 
+               } else if (strcmp(item->name, "type") == 0) {
+                       if (strcmp(item->value, "threads") == 0)
+                               data->query_type = NM_QUERY_TYPE_THREADS;
+                       else if (strcmp(item->value, "messages") == 0)
+                               data->query_type = NM_QUERY_TYPE_MESGS;
+                       else
+                               mutt_error (_("failed to parse notmuch query type: %s"), item->value);
+
                } else if (strcmp(item->name, "query") == 0)
                        data->db_query = safe_strdup(item->value);
        }
@@ -325,6 +341,11 @@ static int get_limit(struct nm_ctxdata *data)
        return data ? data->db_limit : 0;
 }
 
+static int get_query_type(struct nm_ctxdata *data)
+{
+       return data ? data->query_type : 0;
+}
+
 static const char *get_db_filename(struct nm_ctxdata *data)
 {
        char *db_filename;
@@ -699,12 +720,95 @@ done:
        FREE(&newpath);
 }
 
+/*
+ * add all the replies to a given messages into the display.
+ * Careful, this calls itself recursively to make sure we get
+ * everything.
+ */
+static void append_replies(CONTEXT *ctx, notmuch_message_t *top)
+{
+       notmuch_messages_t *msgs;
+
+       for (msgs = notmuch_message_get_replies(top);
+            notmuch_messages_valid(msgs);
+            notmuch_messages_move_to_next(msgs)) {
+
+               notmuch_message_t *m = notmuch_messages_get(msgs);
+               append_message(ctx, m);
+               /* recurse through all the replies to this message too */
+               append_replies(ctx, m);
+               notmuch_message_destroy(m);
+       }
+}
+
+/*
+ * add each top level reply in the thread, and then add each
+ * reply to the top level replies
+ */
+static void append_thread(CONTEXT *ctx, notmuch_thread_t *thread)
+{
+       notmuch_messages_t *msgs;
+
+       for (msgs = notmuch_thread_get_toplevel_messages(thread);
+            notmuch_messages_valid(msgs);
+            notmuch_messages_move_to_next(msgs)) {
+
+               notmuch_message_t *m = notmuch_messages_get(msgs);
+               append_message(ctx, m);
+               append_replies(ctx, m);
+               notmuch_message_destroy(m);
+       }
+}
+
+static void read_mesgs_query(CONTEXT *ctx, notmuch_query_t *q)
+{
+       struct nm_ctxdata *data = get_ctxdata(ctx);
+       int limit;
+       notmuch_messages_t *msgs;
+
+       if (!data)
+               return;
+
+       limit = get_limit(data);
+
+       for (msgs = notmuch_query_search_messages(q);
+            notmuch_messages_valid(msgs) &&
+               (limit == 0 || ctx->msgcount < limit);
+            notmuch_messages_move_to_next(msgs)) {
+
+               notmuch_message_t *m = notmuch_messages_get(msgs);
+               append_message(ctx, m);
+               notmuch_message_destroy(m);
+       }
+}
+
+static void read_threads_query(CONTEXT *ctx, notmuch_query_t *q)
+{
+       struct nm_ctxdata *data = get_ctxdata(ctx);
+       int limit;
+       notmuch_threads_t *threads;
+
+       if (!data)
+               return;
+
+       limit = get_limit(data);
+
+       for (threads = notmuch_query_search_threads(q);
+            notmuch_threads_valid(threads) &&
+               (limit == 0 || ctx->msgcount < limit);
+            notmuch_threads_move_to_next(threads)) {
+
+               notmuch_thread_t *thread = notmuch_threads_get(threads);
+               append_thread(ctx, thread);
+               notmuch_thread_destroy(thread);
+       }
+}
+
 int nm_read_query(CONTEXT *ctx)
 {
        notmuch_query_t *q;
-       notmuch_messages_t *msgs;
        struct nm_ctxdata *data;
-       int limit, rc = -1;
+       int rc = -1;
 
        if (init_context(ctx) != 0)
                return -1;
@@ -717,20 +821,19 @@ int nm_read_query(CONTEXT *ctx)
 
        q = get_query(data, FALSE);
        if (q) {
-               limit = get_limit(data);
-
-               for (msgs = notmuch_query_search_messages(q);
-                    notmuch_messages_valid(msgs) &&
-                       (limit == 0 || ctx->msgcount < limit);
-                    notmuch_messages_move_to_next(msgs)) {
+               int type = get_query_type(data);
 
-                       notmuch_message_t *m = notmuch_messages_get(msgs);
-                       append_message(ctx, m);
-                       notmuch_message_destroy(m);
+               switch(type) {
+               case NM_QUERY_TYPE_MESGS:
+                       read_mesgs_query(ctx, q);
+                       break;
+               case NM_QUERY_TYPE_THREADS:
+                       read_threads_query(ctx, q);
+                       break;
                }
-
                notmuch_query_destroy(q);
                rc = 0;
+
        }
 
        if (!is_longrun(data))