[PATCH] notmuch: Add "maildir:" search option

Peter Zijlstra peterz at infradead.org
Tue Nov 12 07:56:37 PST 2013


Subject: notmuch: Add "maildir:" search option

The current "folder:" search terms are near useless when you have
recursive folders, introduce a boolean "maildir:" search term to
exactly match the maildir folder.

Given a Maildir++ layout like:

	~/Maildir/
	~/Maildir/cur
	~/Maildir/new
	~/Maildir/tmp
	~/Maildir/.Sent
	~/Maildir/.Sent/cur
	~/Maildir/.Sent/new
	~/Maildir/.Sent/tmp
	~/Maildir/.INBOX.LKML
	~/Maildir/.INBOX.LKML/cur
	~/Maildir/.INBOX.LKML/new
	~/Maildir/.INBOX.LKML/tmp
	~/Maildir/.INBOX.LKML.netdev
	~/Maildir/.INBOX.LKML.netdev/cur
	~/Maildir/.INBOX.LKML.netdev/new
	~/Maildir/.INBOX.LKML.netdev/tmp
	~/Maildir/.INBOX.LKML.arch
	~/Maildir/.INBOX.LKML.arch/cur
	~/Maildir/.INBOX.LKML.arch/new
	~/Maildir/.INBOX.LKML.arch/tmp

This patch generates the following search index:

	$ delve -a Maildir/.notmuch/xapian/ | ~/s XMAILDIR
	XMAILDIR:INBOX
	XMAILDIR:INBOX/LKML
	XMAILDIR:INBOX/LKML/arch
	XMAILDIR:INBOX/LKML/netdev
	XMAILDIR:Sent

Which allows one (me!!1) to pose queries like:

	maildir:INBOX and not tag:list

to more easily find offlist mail (from people like my family who don't
actually send their stuff over LKML :-).

Signed-off-by: Peter Zijlstra <peterz at infradead.org>
---

XXX: now I need to go figure out how to do searches like:

  subject:PATCH/0

which would mandate that PATCH is the first word occurring in the
subject. I think the position index holds enough information but I
need to look into that and obviously the query parser needs work for
this.


 lib/database.cc |  7 ++++---
 lib/message.cc  | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/lib/database.cc b/lib/database.cc
index a021bf17253c..53aeaa68954d 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -208,15 +208,16 @@ static prefix_t BOOLEAN_PREFIX_EXTERNAL[] = {
     { "thread",			"G" },
     { "tag",			"K" },
     { "is",			"K" },
-    { "id",			"Q" }
+    { "id",			"Q" },
+    { "maildir",		"XMAILDIR:" },
 };
 
 static prefix_t PROBABILISTIC_PREFIX[]= {
     { "from",			"XFROM" },
     { "to",			"XTO" },
     { "attachment",		"XATTACHMENT" },
-    { "subject",		"XSUBJECT"},
-    { "folder",			"XFOLDER"}
+    { "subject",		"XSUBJECT" },
+    { "folder",			"XFOLDER" },
 };
 
 const char *
diff --git a/lib/message.cc b/lib/message.cc
index 1b4637950f8e..45a727a6208f 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -22,6 +22,7 @@
 #include "database-private.h"
 
 #include <stdint.h>
+#include <string.h>
 
 #include <gmime/gmime.h>
 
@@ -485,6 +486,8 @@ _notmuch_message_add_filename (notmuch_message_t *message,
     notmuch_status_t status;
     void *local = talloc_new (message);
     char *direntry;
+    char *maildir;
+    int i;
 
     if (filename == NULL)
 	INTERNAL_ERROR ("Message filename cannot be NULL.");
@@ -507,6 +510,43 @@ _notmuch_message_add_filename (notmuch_message_t *message,
     /* New terms allow user to search with folder: specification. */
     _notmuch_message_gen_terms (message, "folder", directory);
 
+    /* Convert the directory into a maildir path */
+    maildir = talloc_strdup(local, directory);
+
+    /* Strip the maildir "cur", "new" directory entries. */
+    i = strlen(maildir);
+    if (strncmp(maildir + i - 3, "cur", 3) == 0 ||
+	strncmp(maildir + i - 3, "new", 3) == 0) {
+	    maildir[i - 3] = '\0';
+	    i -= 3;
+    }
+
+    /* Strip trailing '/' */
+    while (maildir[i-1] == '/') {
+	    maildir[i-1] = '\0';
+	    i--;
+    }
+
+    /* Strip leading '/' */
+    while (maildir[0] == '/')
+	    maildir++;
+
+    /* Strip leading '.' */
+    while (maildir[0] == '.')
+	    maildir++;
+
+    /* Replace all remaining '.' with '/' */
+    for (i = 0; maildir[i]; i++) {
+	    if (maildir[i] == '.')
+		    maildir[i] = '/';
+    }
+
+    /* If there's no string left, we're the "INBOX" */
+    if (maildir[0] == '\0')
+	    maildir = talloc_strdup(local, "INBOX");
+
+    _notmuch_message_add_term (message, "maildir", maildir);
+
     talloc_free (local);
 
     return NOTMUCH_STATUS_SUCCESS;


More information about the notmuch mailing list