[notmuch] [PATCH] Make search filters handle disjunctive queries.

Subject: [notmuch] [PATCH] Make search filters handle disjunctive queries.

Date: Mon, 23 Nov 2009 19:07:23 +0100

To: notmuch@notmuchmail.org, cworth@cworth.org

Cc:

From: Jed Brown


notmuch-search-filter accepts now accepts an arbitrary query and will
group if necessary so that we get

  tag:inbox AND (gravy OR biscuits)

notmuch-search-filter-tag now handles multiple terms.  All terms in the
query except AND and OR are interpreted as tags.

This version has nice regexes and handles NOT.

Signed-off-by: Jed Brown <jed@59A2.org>
---
 notmuch.el |   27 ++++++++++++++++++++++-----
 1 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index 0cabbe2..fdd30ae 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -828,6 +828,10 @@ thread from that buffer can be show when done with this one)."
 (defvar notmuch-search-query-string)
 (defvar notmuch-search-oldest-first)
 
+(defvar notmuch-search-boolean-operator-regexp "\\([aA][nN][dD]\\|[oO][rR]\\|[nN][oO][tT]\\)")
+(defvar notmuch-search-valid-term-regexp       "\\([-+_.[:word:]]+\\)")
+(defvar notmuch-search-disjunctive-regexp      "\\<[oO][rR]\\>")
+
 (defun notmuch-search-scroll-up ()
   "Scroll up, moving point to last message in thread if at end."
   (interactive)
@@ -1057,15 +1061,28 @@ search."
 Runs a new search matching only messages that match both the
 current search results AND the additional query string provided."
   (interactive "sFilter search: ")
-  (notmuch-search (concat notmuch-search-query-string " and " query) notmuch-search-oldest-first))
+  (let ((grouped-query (if (string-match-p notmuch-search-disjunctive-regexp query) (concat "( " query " )") query)))
+    (notmuch-search (concat notmuch-search-query-string " and " grouped-query) notmuch-search-oldest-first)))
 
-(defun notmuch-search-filter-by-tag (tag)
-  "Filter the current search results based on a single tag.
+(defun notmuch-search-filter-by-tag (query)
+  "Filter the current search results based on one or more tags.
 
 Runs a new search matching only messages that match both the
-current search results AND that are tagged with the given tag."
+current search results AND that are tagged with the given
+expression involving tags.  For example, the input
+
+  chicken and (gravy or biscuits)
+
+will filter the current search by
+
+  tag:chicken and ( tag:gravy or tag:biscuits )"
   (interactive "sFilter by tag: ")
-  (notmuch-search (concat notmuch-search-query-string " and tag:" tag) notmuch-search-oldest-first))
+  (let ((tagged-query (replace-regexp-in-string notmuch-search-valid-term-regexp
+						(lambda (match) ; Prepend `tag:' to all except boolean operators
+						  (if (string-match-p notmuch-search-boolean-operator-regexp match)
+						      match (concat "tag:" match)))
+						query)))
+    (notmuch-search-filter tagged-query)))
 
 (defun notmuch ()
   "Run notmuch to display all mail with tag of 'inbox'"
-- 
1.6.5.3


Thread: