unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [RFC PATCH] emacs: search: allow command line args as part of query
@ 2013-06-03  9:42 Mark Walters
  2013-06-03 20:52 ` [PATCH v2] " Mark Walters
  0 siblings, 1 reply; 5+ messages in thread
From: Mark Walters @ 2013-06-03  9:42 UTC (permalink / raw)
  To: notmuch, jani

This allows command line arguments for notmuch-search to be part of
the query-string. The string must be of the form
[:blank:]*--cli-arguments -- query. I hope this doesn't clash with
xapian: I believe that queries shouldn't start with a "-".

Correctly parsed example queries are
--sort=oldest-first -- tag:inbox
--exclude=false -- from:fred

Some options (currently only sort-order) we parse in emacs, the rest
we just pass to the cli. In light testing it seems to work.

A full custom parser would be nicer but at least here we are only parsing
the non-query part of a string which is relatively simple: indeed we
already do that in the c code.

We could just implement the option for sort-order, but I thought for
interface consistency making all the options (sort-order exclude limit
and offset) work was worth the small extra hassle.
---

This is an attempt to achieve the same as
id:1349209083-7170-1-git-send-email-jani@nikula.org : that is allow a
saved search to specify the query sort order. However, this is a
rather more complete solution (note as this might be viewed a hack
minimal may be *better* than complete): it works for any search (saved
or from "s") and lets other options (exclude etc) work. What do people
think?

Best wishes

Mark

 emacs/notmuch.el |   31 ++++++++++++++++++++++++++-----
 1 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 7994d74..26ba7e7 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -255,6 +255,7 @@ For a mouse binding, return nil."
   (notmuch-common-do-stash (notmuch-search-find-thread-id)))
 
 (defvar notmuch-search-query-string)
+(defvar notmuch-search-full-query)
 (defvar notmuch-search-target-thread)
 (defvar notmuch-search-target-line)
 (defvar notmuch-search-continuation)
@@ -409,6 +410,7 @@ Complete list of currently available key bindings:
   (interactive)
   (kill-all-local-variables)
   (make-local-variable 'notmuch-search-query-string)
+  (make-local-variable 'notmuch-search-full-query)
   (make-local-variable 'notmuch-search-oldest-first)
   (make-local-variable 'notmuch-search-target-thread)
   (make-local-variable 'notmuch-search-target-line)
@@ -896,6 +898,26 @@ PROMPT is the string to prompt with."
 	(read-from-minibuffer prompt nil keymap nil
 			      'notmuch-search-history nil nil)))))
 
+(defun notmuch-search-parse-query (query oldest-first)
+  (setq notmuch-search-oldest-first oldest-first)
+  (if (string-match "^[:blank:]*--.*? -- " query)
+      (let ((actual-query (substring query (match-end 0)))
+	    (args (split-string (match-string 0 query) " " t)))
+	(setq notmuch-search-query-string actual-query)
+	(dolist (arg args nil)
+	  (when (equal arg "--sort=oldest-first")
+	    (setq notmuch-search-oldest-first t)
+	    (message "oldest first found"))
+	  (when (equal arg "--sort=newest-first")
+	    (setq notmuch-search-oldest-first nil)
+	    (message "newest first found")))
+	(setq args (delete "--sort=oldest-first" args))
+	(setq args (delete "--sort=newest-first" args))
+	(setq notmuch-search-full-query (append args (list actual-query))))
+    ;; no special arguments
+    (setq notmuch-search-full-query (list query))
+    (setq notmuch-search-query-string query)))
+
 ;;;###autoload
 (defun notmuch-search (&optional query oldest-first target-thread target-line continuation)
   "Run \"notmuch search\" with the given `query' and display results.
@@ -915,8 +937,7 @@ Other optional parameters are used as follows:
     (notmuch-search-mode)
     ;; Don't track undo information for this buffer
     (set 'buffer-undo-list t)
-    (set 'notmuch-search-query-string query)
-    (set 'notmuch-search-oldest-first oldest-first)
+    (notmuch-search-parse-query query oldest-first)
     (set 'notmuch-search-target-thread target-thread)
     (set 'notmuch-search-target-line target-line)
     (set 'notmuch-search-continuation continuation)
@@ -928,13 +949,13 @@ Other optional parameters are used as follows:
       (erase-buffer)
       (goto-char (point-min))
       (save-excursion
-	(let ((proc (notmuch-start-notmuch
+	(let ((proc (apply #'notmuch-start-notmuch
 		     "notmuch-search" buffer #'notmuch-search-process-sentinel
 		     "search" "--format=sexp" "--format-version=1"
-		     (if oldest-first
+		     (if notmuch-search-oldest-first
 			 "--sort=oldest-first"
 		       "--sort=newest-first")
-		     query))
+		     notmuch-search-full-query))
 	      ;; Use a scratch buffer to accumulate partial output.
 	      ;; This buffer will be killed by the sentinel, which
 	      ;; should be called no matter how the process dies.
-- 
1.7.9.1

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

* [PATCH v2] emacs: search: allow command line args as part of query
  2013-06-03  9:42 [RFC PATCH] emacs: search: allow command line args as part of query Mark Walters
@ 2013-06-03 20:52 ` Mark Walters
  2013-06-04 15:21   ` [PATCH] " Mark Walters
  0 siblings, 1 reply; 5+ messages in thread
From: Mark Walters @ 2013-06-03 20:52 UTC (permalink / raw)
  To: notmuch, jani

This allows command line arguments for notmuch-search to be part of
the query-string. The string must be of the form
[:blank:]*--cli-arguments -- query. I hope this doesn't clash with
xapian: I believe that queries shouldn't start with a "-".

Correctly parsed example queries are
--sort=oldest-first -- tag:inbox
--exclude=false -- from:fred

Some options (currently only sort-order) we parse in emacs, the rest
we just pass to the cli. In light testing it seems to work.

A full custom parser would be nicer but at least here we are only parsing
the non-query part of a string which is relatively simple: indeed we
already do that in the c code.

We could just implement the option for sort-order, but I thought for
interface consistency making all the options (sort-order exclude limit
and offset) work was worth the small extra hassle.
---
This is a rather more complete version of the parent patch with a key
bugfix (thanks to Jani): saved searches with cli arguments work,
refreshing a query works correctly, filtering a query works correctly
(and can take extra cli arguments). 

It may all be too complex, and it may be too hackish but it does seem to work.

Best wishes

Mark



 emacs/notmuch-hello.el |    5 +++--
 emacs/notmuch-lib.el   |   23 +++++++++++++++++++++++
 emacs/notmuch.el       |   36 +++++++++++++++++++++++++-----------
 3 files changed, 51 insertions(+), 13 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index c1c6f4b..bcc1843 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -383,10 +383,11 @@ options will be handled as specified for
 `notmuch-hello-insert-searches'."
   (with-temp-buffer
     (dolist (elem query-alist nil)
-      (let ((count-query (if (consp (cdr elem))
+      (let* ((full-count-query (if (consp (cdr elem))
 			     ;; do we have a different query for the message count?
 			     (third elem)
-			   (cdr elem))))
+			   (cdr elem)))
+	     (count-query (car (notmuch-parse-query full-count-query))))
 	(insert
 	 (notmuch-hello-filtered-query count-query
 				       (or (plist-get options :filter-count)
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 28f78e0..705d4f3 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -189,6 +189,29 @@ user-friendly queries."
   "Return a query that matches the message with id ID."
   (concat "id:" (notmuch-escape-boolean-term id)))
 
+(defun notmuch-search-parse-sort-order (args oldest-first)
+  (dolist (arg args nil)
+    (when (equal arg "--sort=oldest-first")
+      (setq oldest-first t))
+    (when (equal arg "--sort=newest-first")
+      (setq oldest-first nil)))
+  (setq args (delete "--sort=oldest-first" args))
+  (setq args (delete "--sort=newest-first" args))
+  (cons oldest-first args))
+
+(defun notmuch-parse-query (query)
+  "Parse a query into a search and cli arguments
+
+Returns a list consisting of query followed by the cli-args (as a
+list). If the string does not have cli-args then this will be nil."
+
+  (if (string-match "^[[:blank:]]*--.*? -- " query)
+      (let ((actual-query (substring query (match-end 0)))
+	    (args (split-string (match-string 0 query) " " t)))
+	(message "Parsing query")
+	(cons actual-query args))
+    ;; no cli arguments
+    (list query)))
 ;;
 
 (defun notmuch-common-do-stash (text)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 7994d74..6a4052e 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -255,6 +255,7 @@ For a mouse binding, return nil."
   (notmuch-common-do-stash (notmuch-search-find-thread-id)))
 
 (defvar notmuch-search-query-string)
+(defvar notmuch-search-query-args)
 (defvar notmuch-search-target-thread)
 (defvar notmuch-search-target-line)
 (defvar notmuch-search-continuation)
@@ -409,6 +410,7 @@ Complete list of currently available key bindings:
   (interactive)
   (kill-all-local-variables)
   (make-local-variable 'notmuch-search-query-string)
+  (make-local-variable 'notmuch-search-query-args)
   (make-local-variable 'notmuch-search-oldest-first)
   (make-local-variable 'notmuch-search-target-thread)
   (make-local-variable 'notmuch-search-target-line)
@@ -897,7 +899,7 @@ PROMPT is the string to prompt with."
 			      'notmuch-search-history nil nil)))))
 
 ;;;###autoload
-(defun notmuch-search (&optional query oldest-first target-thread target-line continuation)
+(defun notmuch-search (&optional query oldest-first target-thread target-line continuation cli-args)
   "Run \"notmuch search\" with the given `query' and display results.
 
 If `query' is nil, it is read interactively from the minibuffer.
@@ -909,13 +911,20 @@ Other optional parameters are used as follows:
   target-line: The line number to move to if the target thread does not
                appear in the search results."
   (interactive)
-  (let* ((query (or query (notmuch-read-query "Notmuch search: ")))
+  (let* ((full-query (or query (notmuch-read-query "Notmuch search: ")))
+	 (parsed-query (notmuch-parse-query full-query))
+	 (query (car parsed-query))
+	 (cli-args (or cli-args (cdr parsed-query)))
+	 (combined-order-query (notmuch-search-parse-sort-order cli-args oldest-first))
+	 (oldest-first (car combined-order-query))
+	 (cli-args (cdr combined-order-query))
 	 (buffer (get-buffer-create (notmuch-search-buffer-title query))))
     (switch-to-buffer buffer)
     (notmuch-search-mode)
     ;; Don't track undo information for this buffer
     (set 'buffer-undo-list t)
     (set 'notmuch-search-query-string query)
+    (set 'notmuch-search-query-args cli-args)
     (set 'notmuch-search-oldest-first oldest-first)
     (set 'notmuch-search-target-thread target-thread)
     (set 'notmuch-search-target-line target-line)
@@ -928,13 +937,13 @@ Other optional parameters are used as follows:
       (erase-buffer)
       (goto-char (point-min))
       (save-excursion
-	(let ((proc (notmuch-start-notmuch
+	(let ((proc (apply #'notmuch-start-notmuch
 		     "notmuch-search" buffer #'notmuch-search-process-sentinel
 		     "search" "--format=sexp" "--format-version=1"
-		     (if oldest-first
+		     (if notmuch-search-oldest-first
 			 "--sort=oldest-first"
 		       "--sort=newest-first")
-		     query))
+		     (append cli-args (list query))))
 	      ;; Use a scratch buffer to accumulate partial output.
 	      ;; This buffer will be killed by the sentinel, which
 	      ;; should be called no matter how the process dies.
@@ -957,9 +966,10 @@ same relative position within the new buffer."
 	(oldest-first notmuch-search-oldest-first)
 	(target-thread (notmuch-search-find-thread-id 'bare))
 	(query notmuch-search-query-string)
-	(continuation notmuch-search-continuation))
+	(continuation notmuch-search-continuation)
+	(cli-args notmuch-search-query-args))
     (notmuch-kill-this-buffer)
-    (notmuch-search query oldest-first target-thread target-line continuation)
+    (notmuch-search query oldest-first target-thread target-line continuation cli-args)
     (goto-char (point-min))))
 
 (defcustom notmuch-poll-script nil
@@ -1024,18 +1034,22 @@ search."
   (set 'notmuch-search-oldest-first (not notmuch-search-oldest-first))
   (notmuch-search-refresh-view))
 
-(defun notmuch-search-filter (query)
+(defun notmuch-search-filter (full-query)
   "Filter the current search results based on an additional query string.
 
 Runs a new search matching only messages that match both the
 current search results AND the additional query string provided."
   (interactive (list (notmuch-read-query "Filter search: ")))
-  (let ((grouped-query (if (string-match-p notmuch-search-disjunctive-regexp query)
+  (let* ((parsed-query (notmuch-parse-query full-query))
+	 (query (car parsed-query))
+	 (grouped-query (if (string-match-p notmuch-search-disjunctive-regexp query)
 			   (concat "( " query " )")
-			 query)))
+			 query))
+	 (extra-cli-args (cdr parsed-query))
+	 (cli-args (append notmuch-search-query-args extra-cli-args)))
     (notmuch-search (if (string= notmuch-search-query-string "*")
 			grouped-query
-		      (concat notmuch-search-query-string " and " grouped-query)) notmuch-search-oldest-first)))
+		      (concat notmuch-search-query-string " and " grouped-query)) notmuch-search-oldest-first nil nil nil cli-args)))
 
 (defun notmuch-search-filter-by-tag (tag)
   "Filter the current search results based on a single tag.
-- 
1.7.9.1

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

* [PATCH] emacs: search: allow command line args as part of query
  2013-06-03 20:52 ` [PATCH v2] " Mark Walters
@ 2013-06-04 15:21   ` Mark Walters
  2013-06-04 19:40     ` Tomi Ollila
  0 siblings, 1 reply; 5+ messages in thread
From: Mark Walters @ 2013-06-04 15:21 UTC (permalink / raw)
  To: notmuch

This allows command line arguments for notmuch-search to be part of
the query-string. The string must be of the form
[:blank:]*--cli-arguments -- query. I hope this doesn't clash with
xapian: I believe that queries shouldn't start with a "-".

The cli-arguments must be arguments in a whitelist of arguments: this
adds a slight maintenance burden but means we don't have to deal with
users who passed "--format=text" or other incompatible options.

Correctly parsed example queries are
--sort=oldest-first -- tag:inbox
--exclude=false -- from:fred

Some options (currently only sort-order) we parse in emacs, the rest
we just pass to the cli. In light testing it seems to work.

A full custom parser would be nicer but at least here we are only parsing
the non-query part of a string which is relatively simple: indeed we
already do that in the c code.

We could just implement the option for sort-order, but I thought for
interface consistency making all the sensible options (sort-order
exclude limit and offset) work was worth the extra hassle.
---

This is a slight change to
1370292776-24535-1-git-send-email-markwalters1009@gmail.com The change
is that we add a whitelist of allowed cli options; other options are
removed and the user is warned (but the query is not aborted).

One other tiny change is that a query starting with "[[:blank:]]*-- "
is allowed: everything after the -- is part of the real qeury so if
any strange query is accidentally being misparsed the user can prefix
with "-- " and it will give the current behaviour.

Best wishes

Mark


 emacs/notmuch-hello.el |    5 +++--
 emacs/notmuch-lib.el   |   44 ++++++++++++++++++++++++++++++++++++++++++++
 emacs/notmuch.el       |   36 +++++++++++++++++++++++++-----------
 3 files changed, 72 insertions(+), 13 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index c1c6f4b..bcc1843 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -383,10 +383,11 @@ options will be handled as specified for
 `notmuch-hello-insert-searches'."
   (with-temp-buffer
     (dolist (elem query-alist nil)
-      (let ((count-query (if (consp (cdr elem))
+      (let* ((full-count-query (if (consp (cdr elem))
 			     ;; do we have a different query for the message count?
 			     (third elem)
-			   (cdr elem))))
+			   (cdr elem)))
+	     (count-query (car (notmuch-parse-query full-count-query))))
 	(insert
 	 (notmuch-hello-filtered-query count-query
 				       (or (plist-get options :filter-count)
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 28f78e0..65c489e 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -189,6 +189,50 @@ user-friendly queries."
   "Return a query that matches the message with id ID."
   (concat "id:" (notmuch-escape-boolean-term id)))
 
+(defun notmuch-search-parse-sort-order (args oldest-first)
+  (dolist (arg args nil)
+    (when (equal arg "--sort=oldest-first")
+      (setq oldest-first t))
+    (when (equal arg "--sort=newest-first")
+      (setq oldest-first nil)))
+  (setq args (delete "--sort=oldest-first" args))
+  (setq args (delete "--sort=newest-first" args))
+  (cons oldest-first args))
+
+(defvar notmuch-parse-option-whitelist
+  '("^--sort=oldest-first$"
+    "^--sort=newest-first$"
+    "^--exclude=true$"
+    "^--exclude=false$"
+    "^--exclude=flag$"
+    "^--limit=[0-9]*$"
+    "^--offset=[0-9]*$"
+    "^--$"))
+
+(defun notmuch-parse-in-whitelist-p (arg)
+  (let ((allowed nil))
+    (dolist (opt notmuch-parse-option-whitelist nil)
+      (setq allowed (or allowed (string-match-p opt arg))))
+    allowed))
+
+(defun notmuch-parse-query (query)
+  "Parse a query into a search and cli arguments
+
+Returns a list consisting of query followed by the cli-args (as a
+list). If the string does not have cli-args then this will be nil."
+
+  (if (or (string-match "^[[:blank:]]*--.*? -- " query)
+	  (string-match "^[[:blank:]]*-- " query))
+      (let ((actual-query (substring query (match-end 0)))
+	    (args (split-string (match-string 0 query) " " t)))
+	(message "Parsing query")
+	(dolist (arg args nil)
+	  (unless (notmuch-parse-in-whitelist-p arg)
+	    (setq args (delete arg args))
+	    (message "Removing unknown option %s" arg)))
+	(cons actual-query args))
+    ;; no cli arguments
+    (list query)))
 ;;
 
 (defun notmuch-common-do-stash (text)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 7994d74..6a4052e 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -255,6 +255,7 @@ For a mouse binding, return nil."
   (notmuch-common-do-stash (notmuch-search-find-thread-id)))
 
 (defvar notmuch-search-query-string)
+(defvar notmuch-search-query-args)
 (defvar notmuch-search-target-thread)
 (defvar notmuch-search-target-line)
 (defvar notmuch-search-continuation)
@@ -409,6 +410,7 @@ Complete list of currently available key bindings:
   (interactive)
   (kill-all-local-variables)
   (make-local-variable 'notmuch-search-query-string)
+  (make-local-variable 'notmuch-search-query-args)
   (make-local-variable 'notmuch-search-oldest-first)
   (make-local-variable 'notmuch-search-target-thread)
   (make-local-variable 'notmuch-search-target-line)
@@ -897,7 +899,7 @@ PROMPT is the string to prompt with."
 			      'notmuch-search-history nil nil)))))
 
 ;;;###autoload
-(defun notmuch-search (&optional query oldest-first target-thread target-line continuation)
+(defun notmuch-search (&optional query oldest-first target-thread target-line continuation cli-args)
   "Run \"notmuch search\" with the given `query' and display results.
 
 If `query' is nil, it is read interactively from the minibuffer.
@@ -909,13 +911,20 @@ Other optional parameters are used as follows:
   target-line: The line number to move to if the target thread does not
                appear in the search results."
   (interactive)
-  (let* ((query (or query (notmuch-read-query "Notmuch search: ")))
+  (let* ((full-query (or query (notmuch-read-query "Notmuch search: ")))
+	 (parsed-query (notmuch-parse-query full-query))
+	 (query (car parsed-query))
+	 (cli-args (or cli-args (cdr parsed-query)))
+	 (combined-order-query (notmuch-search-parse-sort-order cli-args oldest-first))
+	 (oldest-first (car combined-order-query))
+	 (cli-args (cdr combined-order-query))
 	 (buffer (get-buffer-create (notmuch-search-buffer-title query))))
     (switch-to-buffer buffer)
     (notmuch-search-mode)
     ;; Don't track undo information for this buffer
     (set 'buffer-undo-list t)
     (set 'notmuch-search-query-string query)
+    (set 'notmuch-search-query-args cli-args)
     (set 'notmuch-search-oldest-first oldest-first)
     (set 'notmuch-search-target-thread target-thread)
     (set 'notmuch-search-target-line target-line)
@@ -928,13 +937,13 @@ Other optional parameters are used as follows:
       (erase-buffer)
       (goto-char (point-min))
       (save-excursion
-	(let ((proc (notmuch-start-notmuch
+	(let ((proc (apply #'notmuch-start-notmuch
 		     "notmuch-search" buffer #'notmuch-search-process-sentinel
 		     "search" "--format=sexp" "--format-version=1"
-		     (if oldest-first
+		     (if notmuch-search-oldest-first
 			 "--sort=oldest-first"
 		       "--sort=newest-first")
-		     query))
+		     (append cli-args (list query))))
 	      ;; Use a scratch buffer to accumulate partial output.
 	      ;; This buffer will be killed by the sentinel, which
 	      ;; should be called no matter how the process dies.
@@ -957,9 +966,10 @@ same relative position within the new buffer."
 	(oldest-first notmuch-search-oldest-first)
 	(target-thread (notmuch-search-find-thread-id 'bare))
 	(query notmuch-search-query-string)
-	(continuation notmuch-search-continuation))
+	(continuation notmuch-search-continuation)
+	(cli-args notmuch-search-query-args))
     (notmuch-kill-this-buffer)
-    (notmuch-search query oldest-first target-thread target-line continuation)
+    (notmuch-search query oldest-first target-thread target-line continuation cli-args)
     (goto-char (point-min))))
 
 (defcustom notmuch-poll-script nil
@@ -1024,18 +1034,22 @@ search."
   (set 'notmuch-search-oldest-first (not notmuch-search-oldest-first))
   (notmuch-search-refresh-view))
 
-(defun notmuch-search-filter (query)
+(defun notmuch-search-filter (full-query)
   "Filter the current search results based on an additional query string.
 
 Runs a new search matching only messages that match both the
 current search results AND the additional query string provided."
   (interactive (list (notmuch-read-query "Filter search: ")))
-  (let ((grouped-query (if (string-match-p notmuch-search-disjunctive-regexp query)
+  (let* ((parsed-query (notmuch-parse-query full-query))
+	 (query (car parsed-query))
+	 (grouped-query (if (string-match-p notmuch-search-disjunctive-regexp query)
 			   (concat "( " query " )")
-			 query)))
+			 query))
+	 (extra-cli-args (cdr parsed-query))
+	 (cli-args (append notmuch-search-query-args extra-cli-args)))
     (notmuch-search (if (string= notmuch-search-query-string "*")
 			grouped-query
-		      (concat notmuch-search-query-string " and " grouped-query)) notmuch-search-oldest-first)))
+		      (concat notmuch-search-query-string " and " grouped-query)) notmuch-search-oldest-first nil nil nil cli-args)))
 
 (defun notmuch-search-filter-by-tag (tag)
   "Filter the current search results based on a single tag.
-- 
1.7.9.1

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

* Re: [PATCH] emacs: search: allow command line args as part of query
  2013-06-04 15:21   ` [PATCH] " Mark Walters
@ 2013-06-04 19:40     ` Tomi Ollila
  2013-06-04 21:12       ` Mark Walters
  0 siblings, 1 reply; 5+ messages in thread
From: Tomi Ollila @ 2013-06-04 19:40 UTC (permalink / raw)
  To: Mark Walters, notmuch

On Tue, Jun 04 2013, Mark Walters <markwalters1009@gmail.com> wrote:

> This allows command line arguments for notmuch-search to be part of
> the query-string. 

Nice feature -- some comments below:

> The string must be of the form
> [:blank:]*--cli-arguments -- query. I hope this doesn't clash with

One problem requiring trailing '--' noticed after reviewed -- if one
forgets that the whole string is going to be query string.

> xapian: I believe that queries shouldn't start with a "-".
> The cli-arguments must be arguments in a whitelist of arguments: this
> adds a slight maintenance burden but means we don't have to deal with
> users who passed "--format=text" or other incompatible options.
>
> Correctly parsed example queries are
> --sort=oldest-first -- tag:inbox
> --exclude=false -- from:fred
>
> Some options (currently only sort-order) we parse in emacs, the rest
> we just pass to the cli. In light testing it seems to work.
>
> A full custom parser would be nicer but at least here we are only parsing
> the non-query part of a string which is relatively simple: indeed we
> already do that in the c code.
>
> We could just implement the option for sort-order, but I thought for
> interface consistency making all the sensible options (sort-order
> exclude limit and offset) work was worth the extra hassle.
> ---
>
> This is a slight change to
> 1370292776-24535-1-git-send-email-markwalters1009@gmail.com The change
> is that we add a whitelist of allowed cli options; other options are
> removed and the user is warned (but the query is not aborted).
>
> One other tiny change is that a query starting with "[[:blank:]]*-- "
> is allowed: everything after the -- is part of the real qeury so if
> any strange query is accidentally being misparsed the user can prefix
> with "-- " and it will give the current behaviour.
>
> Best wishes
>
> Mark
>
>
>  emacs/notmuch-hello.el |    5 +++--
>  emacs/notmuch-lib.el   |   44 ++++++++++++++++++++++++++++++++++++++++++++
>  emacs/notmuch.el       |   36 +++++++++++++++++++++++++-----------
>  3 files changed, 72 insertions(+), 13 deletions(-)
>
> diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
> index c1c6f4b..bcc1843 100644
> --- a/emacs/notmuch-hello.el
> +++ b/emacs/notmuch-hello.el
> @@ -383,10 +383,11 @@ options will be handled as specified for
>  `notmuch-hello-insert-searches'."
>    (with-temp-buffer
>      (dolist (elem query-alist nil)
> -      (let ((count-query (if (consp (cdr elem))
> +      (let* ((full-count-query (if (consp (cdr elem))
>  			     ;; do we have a different query for the message count?
>  			     (third elem)
> -			   (cdr elem))))
> +			   (cdr elem)))
> +	     (count-query (car (notmuch-parse-query full-count-query))))
>  	(insert
>  	 (notmuch-hello-filtered-query count-query
>  				       (or (plist-get options :filter-count)
> diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
> index 28f78e0..65c489e 100644
> --- a/emacs/notmuch-lib.el
> +++ b/emacs/notmuch-lib.el
> @@ -189,6 +189,50 @@ user-friendly queries."
>    "Return a query that matches the message with id ID."
>    (concat "id:" (notmuch-escape-boolean-term id)))
>  
> +(defun notmuch-search-parse-sort-order (args oldest-first)
> +  (dolist (arg args nil)
> +    (when (equal arg "--sort=oldest-first")
> +      (setq oldest-first t))
> +    (when (equal arg "--sort=newest-first")
> +      (setq oldest-first nil)))
> +  (setq args (delete "--sort=oldest-first" args))
> +  (setq args (delete "--sort=newest-first" args))
> +  (cons oldest-first args))

If one gave --sort=oldest-first --sort=newest-first  oldest-first is
chosen instead of newest-first as both are removed from args -- that
should be pretty easy to fix by putting deletes inside whens.

> +(defvar notmuch-parse-option-whitelist
> +  '("^--sort=oldest-first$"
> +    "^--sort=newest-first$"
> +    "^--exclude=true$"
> +    "^--exclude=false$"
> +    "^--exclude=flag$"
> +    "^--limit=[0-9]*$"
> +    "^--offset=[0-9]*$"
> +    "^--$"))

is zero numbers of numbers for --limit & --offset good ([0-9]*) ?

> +(defun notmuch-parse-in-whitelist-p (arg)
> +  (let ((allowed nil))
> +    (dolist (opt notmuch-parse-option-whitelist nil)
> +      (setq allowed (or allowed (string-match-p opt arg))))
> +    allowed))
> +
> +(defun notmuch-parse-query (query)
> +  "Parse a query into a search and cli arguments
> +
> +Returns a list consisting of query followed by the cli-args (as a
> +list). If the string does not have cli-args then this will be nil."
> +
> +  (if (or (string-match "^[[:blank:]]*--.*? -- " query)
> +	  (string-match "^[[:blank:]]*-- " query))
> +      (let ((actual-query (substring query (match-end 0)))
> +	    (args (split-string (match-string 0 query) " " t)))

Should the whitespace matching in locations above be consistent:
like "^[[:blank:]]*--.*?[[:blank:]]--[[:blank:]]". Blank matches
space & tab (according to http://www.gnu.org/software/emacs/manual/html_node/elisp/Char-Classes.html#Char-Classes )

Hmm, learned a bit:

(split-string "  foo   bar  ") -> ("foo" "bar")
(split-string "  foo   bar  " " ") -> ("" "" "foo" "" "" "bar" "" "")
(split-string "  foo   bar  " " " t) -> ("foo" "bar")
(split-string "  foo   bar  " " +") -> ("" "foo" "bar" "")
(split-string "  foo   bar  " " +" t) -> ("foo" "bar")

-> ... (args (split-string (match-string 0 query) "[[:blank:]]" t)))

> +	(message "Parsing query")
> +	(dolist (arg args nil)
> +	  (unless (notmuch-parse-in-whitelist-p arg)
> +	    (setq args (delete arg args))
> +	    (message "Removing unknown option %s" arg)))

And finally, I'd suggest it is an error to encounter unknown
option and in that case operation is aborted.


Tomi


> +	(cons actual-query args))
> +    ;; no cli arguments
> +    (list query)))
>  ;;
>  
>  (defun notmuch-common-do-stash (text)
> diff --git a/emacs/notmuch.el b/emacs/notmuch.el
> index 7994d74..6a4052e 100644
> --- a/emacs/notmuch.el
> +++ b/emacs/notmuch.el
> @@ -255,6 +255,7 @@ For a mouse binding, return nil."
>    (notmuch-common-do-stash (notmuch-search-find-thread-id)))
>  
>  (defvar notmuch-search-query-string)
> +(defvar notmuch-search-query-args)
>  (defvar notmuch-search-target-thread)
>  (defvar notmuch-search-target-line)
>  (defvar notmuch-search-continuation)
> @@ -409,6 +410,7 @@ Complete list of currently available key bindings:
>    (interactive)
>    (kill-all-local-variables)
>    (make-local-variable 'notmuch-search-query-string)
> +  (make-local-variable 'notmuch-search-query-args)
>    (make-local-variable 'notmuch-search-oldest-first)
>    (make-local-variable 'notmuch-search-target-thread)
>    (make-local-variable 'notmuch-search-target-line)
> @@ -897,7 +899,7 @@ PROMPT is the string to prompt with."
>  			      'notmuch-search-history nil nil)))))
>  
>  ;;;###autoload
> -(defun notmuch-search (&optional query oldest-first target-thread target-line continuation)
> +(defun notmuch-search (&optional query oldest-first target-thread target-line continuation cli-args)
>    "Run \"notmuch search\" with the given `query' and display results.
>  
>  If `query' is nil, it is read interactively from the minibuffer.
> @@ -909,13 +911,20 @@ Other optional parameters are used as follows:
>    target-line: The line number to move to if the target thread does not
>                 appear in the search results."
>    (interactive)
> -  (let* ((query (or query (notmuch-read-query "Notmuch search: ")))
> +  (let* ((full-query (or query (notmuch-read-query "Notmuch search: ")))
> +	 (parsed-query (notmuch-parse-query full-query))
> +	 (query (car parsed-query))
> +	 (cli-args (or cli-args (cdr parsed-query)))
> +	 (combined-order-query (notmuch-search-parse-sort-order cli-args oldest-first))
> +	 (oldest-first (car combined-order-query))
> +	 (cli-args (cdr combined-order-query))
>  	 (buffer (get-buffer-create (notmuch-search-buffer-title query))))
>      (switch-to-buffer buffer)
>      (notmuch-search-mode)
>      ;; Don't track undo information for this buffer
>      (set 'buffer-undo-list t)
>      (set 'notmuch-search-query-string query)
> +    (set 'notmuch-search-query-args cli-args)
>      (set 'notmuch-search-oldest-first oldest-first)
>      (set 'notmuch-search-target-thread target-thread)
>      (set 'notmuch-search-target-line target-line)
> @@ -928,13 +937,13 @@ Other optional parameters are used as follows:
>        (erase-buffer)
>        (goto-char (point-min))
>        (save-excursion
> -	(let ((proc (notmuch-start-notmuch
> +	(let ((proc (apply #'notmuch-start-notmuch
>  		     "notmuch-search" buffer #'notmuch-search-process-sentinel
>  		     "search" "--format=sexp" "--format-version=1"
> -		     (if oldest-first
> +		     (if notmuch-search-oldest-first
>  			 "--sort=oldest-first"
>  		       "--sort=newest-first")
> -		     query))
> +		     (append cli-args (list query))))
>  	      ;; Use a scratch buffer to accumulate partial output.
>  	      ;; This buffer will be killed by the sentinel, which
>  	      ;; should be called no matter how the process dies.
> @@ -957,9 +966,10 @@ same relative position within the new buffer."
>  	(oldest-first notmuch-search-oldest-first)
>  	(target-thread (notmuch-search-find-thread-id 'bare))
>  	(query notmuch-search-query-string)
> -	(continuation notmuch-search-continuation))
> +	(continuation notmuch-search-continuation)
> +	(cli-args notmuch-search-query-args))
>      (notmuch-kill-this-buffer)
> -    (notmuch-search query oldest-first target-thread target-line continuation)
> +    (notmuch-search query oldest-first target-thread target-line continuation cli-args)
>      (goto-char (point-min))))
>  
>  (defcustom notmuch-poll-script nil
> @@ -1024,18 +1034,22 @@ search."
>    (set 'notmuch-search-oldest-first (not notmuch-search-oldest-first))
>    (notmuch-search-refresh-view))
>  
> -(defun notmuch-search-filter (query)
> +(defun notmuch-search-filter (full-query)
>    "Filter the current search results based on an additional query string.
>  
>  Runs a new search matching only messages that match both the
>  current search results AND the additional query string provided."
>    (interactive (list (notmuch-read-query "Filter search: ")))
> -  (let ((grouped-query (if (string-match-p notmuch-search-disjunctive-regexp query)
> +  (let* ((parsed-query (notmuch-parse-query full-query))
> +	 (query (car parsed-query))
> +	 (grouped-query (if (string-match-p notmuch-search-disjunctive-regexp query)
>  			   (concat "( " query " )")
> -			 query)))
> +			 query))
> +	 (extra-cli-args (cdr parsed-query))
> +	 (cli-args (append notmuch-search-query-args extra-cli-args)))
>      (notmuch-search (if (string= notmuch-search-query-string "*")
>  			grouped-query
> -		      (concat notmuch-search-query-string " and " grouped-query)) notmuch-search-oldest-first)))
> +		      (concat notmuch-search-query-string " and " grouped-query)) notmuch-search-oldest-first nil nil nil cli-args)))
>  
>  (defun notmuch-search-filter-by-tag (tag)
>    "Filter the current search results based on a single tag.
> -- 
> 1.7.9.1
>
> _______________________________________________
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch

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

* Re: [PATCH] emacs: search: allow command line args as part of query
  2013-06-04 19:40     ` Tomi Ollila
@ 2013-06-04 21:12       ` Mark Walters
  0 siblings, 0 replies; 5+ messages in thread
From: Mark Walters @ 2013-06-04 21:12 UTC (permalink / raw)
  To: Tomi Ollila, notmuch



> On Tue, Jun 04 2013, Mark Walters <markwalters1009@gmail.com> wrote:
>
>> This allows command line arguments for notmuch-search to be part of
>> the query-string. 
>
> Nice feature -- some comments below:
>

Thanks for the review! replies below

>> The string must be of the form
>> [:blank:]*--cli-arguments -- query. I hope this doesn't clash with
>
> One problem requiring trailing '--' noticed after reviewed -- if one
> forgets that the whole string is going to be query string.

One easy fix would be to require any query starting with --something to
be prefixed by "-- ". We could also just assume the query starts if we
see a term not prefixed with -- or having a "--" term. What do you think?

>> xapian: I believe that queries shouldn't start with a "-".
>> The cli-arguments must be arguments in a whitelist of arguments: this
>> adds a slight maintenance burden but means we don't have to deal with
>> users who passed "--format=text" or other incompatible options.
>>
>> Correctly parsed example queries are
>> --sort=oldest-first -- tag:inbox
>> --exclude=false -- from:fred
>>
>> Some options (currently only sort-order) we parse in emacs, the rest
>> we just pass to the cli. In light testing it seems to work.
>>
>> A full custom parser would be nicer but at least here we are only parsing
>> the non-query part of a string which is relatively simple: indeed we
>> already do that in the c code.
>>
>> We could just implement the option for sort-order, but I thought for
>> interface consistency making all the sensible options (sort-order
>> exclude limit and offset) work was worth the extra hassle.
>> ---
>>
>> This is a slight change to
>> 1370292776-24535-1-git-send-email-markwalters1009@gmail.com The change
>> is that we add a whitelist of allowed cli options; other options are
>> removed and the user is warned (but the query is not aborted).
>>
>> One other tiny change is that a query starting with "[[:blank:]]*-- "
>> is allowed: everything after the -- is part of the real qeury so if
>> any strange query is accidentally being misparsed the user can prefix
>> with "-- " and it will give the current behaviour.
>>
>> Best wishes
>>
>> Mark
>>
>>
>>  emacs/notmuch-hello.el |    5 +++--
>>  emacs/notmuch-lib.el   |   44 ++++++++++++++++++++++++++++++++++++++++++++
>>  emacs/notmuch.el       |   36 +++++++++++++++++++++++++-----------
>>  3 files changed, 72 insertions(+), 13 deletions(-)
>>
>> diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
>> index c1c6f4b..bcc1843 100644
>> --- a/emacs/notmuch-hello.el
>> +++ b/emacs/notmuch-hello.el
>> @@ -383,10 +383,11 @@ options will be handled as specified for
>>  `notmuch-hello-insert-searches'."
>>    (with-temp-buffer
>>      (dolist (elem query-alist nil)
>> -      (let ((count-query (if (consp (cdr elem))
>> +      (let* ((full-count-query (if (consp (cdr elem))
>>  			     ;; do we have a different query for the message count?
>>  			     (third elem)
>> -			   (cdr elem))))
>> +			   (cdr elem)))
>> +	     (count-query (car (notmuch-parse-query full-count-query))))
>>  	(insert
>>  	 (notmuch-hello-filtered-query count-query
>>  				       (or (plist-get options :filter-count)
>> diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
>> index 28f78e0..65c489e 100644
>> --- a/emacs/notmuch-lib.el
>> +++ b/emacs/notmuch-lib.el
>> @@ -189,6 +189,50 @@ user-friendly queries."
>>    "Return a query that matches the message with id ID."
>>    (concat "id:" (notmuch-escape-boolean-term id)))
>>  
>> +(defun notmuch-search-parse-sort-order (args oldest-first)
>> +  (dolist (arg args nil)
>> +    (when (equal arg "--sort=oldest-first")
>> +      (setq oldest-first t))
>> +    (when (equal arg "--sort=newest-first")
>> +      (setq oldest-first nil)))
>> +  (setq args (delete "--sort=oldest-first" args))
>> +  (setq args (delete "--sort=newest-first" args))
>> +  (cons oldest-first args))
>
> If one gave --sort=oldest-first --sort=newest-first  oldest-first is
> chosen instead of newest-first as both are removed from args -- that
> should be pretty easy to fix by putting deletes inside whens.

I think this one is ok as the delete is outside the dolist.

>> +(defvar notmuch-parse-option-whitelist
>> +  '("^--sort=oldest-first$"
>> +    "^--sort=newest-first$"
>> +    "^--exclude=true$"
>> +    "^--exclude=false$"
>> +    "^--exclude=flag$"
>> +    "^--limit=[0-9]*$"
>> +    "^--offset=[0-9]*$"
>> +    "^--$"))
>
> is zero numbers of numbers for --limit & --offset good ([0-9]*) ?

You are quite right (ie + would be better).

>
>> +(defun notmuch-parse-in-whitelist-p (arg)
>> +  (let ((allowed nil))
>> +    (dolist (opt notmuch-parse-option-whitelist nil)
>> +      (setq allowed (or allowed (string-match-p opt arg))))
>> +    allowed))
>> +
>> +(defun notmuch-parse-query (query)
>> +  "Parse a query into a search and cli arguments
>> +
>> +Returns a list consisting of query followed by the cli-args (as a
>> +list). If the string does not have cli-args then this will be nil."
>> +
>> +  (if (or (string-match "^[[:blank:]]*--.*? -- " query)
>> +	  (string-match "^[[:blank:]]*-- " query))
>> +      (let ((actual-query (substring query (match-end 0)))
>> +	    (args (split-string (match-string 0 query) " " t)))
>
> Should the whitespace matching in locations above be consistent:
> like "^[[:blank:]]*--.*?[[:blank:]]--[[:blank:]]". Blank matches
> space & tab (according to http://www.gnu.org/software/emacs/manual/html_node/elisp/Char-Classes.html#Char-Classes )
>
> Hmm, learned a bit:
>
> (split-string "  foo   bar  ") -> ("foo" "bar")
> (split-string "  foo   bar  " " ") -> ("" "" "foo" "" "" "bar" "" "")
> (split-string "  foo   bar  " " " t) -> ("foo" "bar")
> (split-string "  foo   bar  " " +") -> ("" "foo" "bar" "")
> (split-string "  foo   bar  " " +" t) -> ("foo" "bar")
>
> -> ... (args (split-string (match-string 0 query) "[[:blank:]]" t)))

These are both clear improvements.

>> +	(message "Parsing query")
>> +	(dolist (arg args nil)
>> +	  (unless (notmuch-parse-in-whitelist-p arg)
>> +	    (setq args (delete arg args))
>> +	    (message "Removing unknown option %s" arg)))
>
> And finally, I'd suggest it is an error to encounter unknown
> option and in that case operation is aborted.

I think this would be better. I am not quite sure how to implement it,
and I wasn't sure what notmuch-hello should do when displaying counts of
an "illegal" saved search. What do you think?

Best wishes

Mark





>
> Tomi
>
>
>> +	(cons actual-query args))
>> +    ;; no cli arguments
>> +    (list query)))
>>  ;;
>>  
>>  (defun notmuch-common-do-stash (text)
>> diff --git a/emacs/notmuch.el b/emacs/notmuch.el
>> index 7994d74..6a4052e 100644
>> --- a/emacs/notmuch.el
>> +++ b/emacs/notmuch.el
>> @@ -255,6 +255,7 @@ For a mouse binding, return nil."
>>    (notmuch-common-do-stash (notmuch-search-find-thread-id)))
>>  
>>  (defvar notmuch-search-query-string)
>> +(defvar notmuch-search-query-args)
>>  (defvar notmuch-search-target-thread)
>>  (defvar notmuch-search-target-line)
>>  (defvar notmuch-search-continuation)
>> @@ -409,6 +410,7 @@ Complete list of currently available key bindings:
>>    (interactive)
>>    (kill-all-local-variables)
>>    (make-local-variable 'notmuch-search-query-string)
>> +  (make-local-variable 'notmuch-search-query-args)
>>    (make-local-variable 'notmuch-search-oldest-first)
>>    (make-local-variable 'notmuch-search-target-thread)
>>    (make-local-variable 'notmuch-search-target-line)
>> @@ -897,7 +899,7 @@ PROMPT is the string to prompt with."
>>  			      'notmuch-search-history nil nil)))))
>>  
>>  ;;;###autoload
>> -(defun notmuch-search (&optional query oldest-first target-thread target-line continuation)
>> +(defun notmuch-search (&optional query oldest-first target-thread target-line continuation cli-args)
>>    "Run \"notmuch search\" with the given `query' and display results.
>>  
>>  If `query' is nil, it is read interactively from the minibuffer.
>> @@ -909,13 +911,20 @@ Other optional parameters are used as follows:
>>    target-line: The line number to move to if the target thread does not
>>                 appear in the search results."
>>    (interactive)
>> -  (let* ((query (or query (notmuch-read-query "Notmuch search: ")))
>> +  (let* ((full-query (or query (notmuch-read-query "Notmuch search: ")))
>> +	 (parsed-query (notmuch-parse-query full-query))
>> +	 (query (car parsed-query))
>> +	 (cli-args (or cli-args (cdr parsed-query)))
>> +	 (combined-order-query (notmuch-search-parse-sort-order cli-args oldest-first))
>> +	 (oldest-first (car combined-order-query))
>> +	 (cli-args (cdr combined-order-query))
>>  	 (buffer (get-buffer-create (notmuch-search-buffer-title query))))
>>      (switch-to-buffer buffer)
>>      (notmuch-search-mode)
>>      ;; Don't track undo information for this buffer
>>      (set 'buffer-undo-list t)
>>      (set 'notmuch-search-query-string query)
>> +    (set 'notmuch-search-query-args cli-args)
>>      (set 'notmuch-search-oldest-first oldest-first)
>>      (set 'notmuch-search-target-thread target-thread)
>>      (set 'notmuch-search-target-line target-line)
>> @@ -928,13 +937,13 @@ Other optional parameters are used as follows:
>>        (erase-buffer)
>>        (goto-char (point-min))
>>        (save-excursion
>> -	(let ((proc (notmuch-start-notmuch
>> +	(let ((proc (apply #'notmuch-start-notmuch
>>  		     "notmuch-search" buffer #'notmuch-search-process-sentinel
>>  		     "search" "--format=sexp" "--format-version=1"
>> -		     (if oldest-first
>> +		     (if notmuch-search-oldest-first
>>  			 "--sort=oldest-first"
>>  		       "--sort=newest-first")
>> -		     query))
>> +		     (append cli-args (list query))))
>>  	      ;; Use a scratch buffer to accumulate partial output.
>>  	      ;; This buffer will be killed by the sentinel, which
>>  	      ;; should be called no matter how the process dies.
>> @@ -957,9 +966,10 @@ same relative position within the new buffer."
>>  	(oldest-first notmuch-search-oldest-first)
>>  	(target-thread (notmuch-search-find-thread-id 'bare))
>>  	(query notmuch-search-query-string)
>> -	(continuation notmuch-search-continuation))
>> +	(continuation notmuch-search-continuation)
>> +	(cli-args notmuch-search-query-args))
>>      (notmuch-kill-this-buffer)
>> -    (notmuch-search query oldest-first target-thread target-line continuation)
>> +    (notmuch-search query oldest-first target-thread target-line continuation cli-args)
>>      (goto-char (point-min))))
>>  
>>  (defcustom notmuch-poll-script nil
>> @@ -1024,18 +1034,22 @@ search."
>>    (set 'notmuch-search-oldest-first (not notmuch-search-oldest-first))
>>    (notmuch-search-refresh-view))
>>  
>> -(defun notmuch-search-filter (query)
>> +(defun notmuch-search-filter (full-query)
>>    "Filter the current search results based on an additional query string.
>>  
>>  Runs a new search matching only messages that match both the
>>  current search results AND the additional query string provided."
>>    (interactive (list (notmuch-read-query "Filter search: ")))
>> -  (let ((grouped-query (if (string-match-p notmuch-search-disjunctive-regexp query)
>> +  (let* ((parsed-query (notmuch-parse-query full-query))
>> +	 (query (car parsed-query))
>> +	 (grouped-query (if (string-match-p notmuch-search-disjunctive-regexp query)
>>  			   (concat "( " query " )")
>> -			 query)))
>> +			 query))
>> +	 (extra-cli-args (cdr parsed-query))
>> +	 (cli-args (append notmuch-search-query-args extra-cli-args)))
>>      (notmuch-search (if (string= notmuch-search-query-string "*")
>>  			grouped-query
>> -		      (concat notmuch-search-query-string " and " grouped-query)) notmuch-search-oldest-first)))
>> +		      (concat notmuch-search-query-string " and " grouped-query)) notmuch-search-oldest-first nil nil nil cli-args)))
>>  
>>  (defun notmuch-search-filter-by-tag (tag)
>>    "Filter the current search results based on a single tag.
>> -- 
>> 1.7.9.1
>>
>> _______________________________________________
>> notmuch mailing list
>> notmuch@notmuchmail.org
>> http://notmuchmail.org/mailman/listinfo/notmuch

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

end of thread, other threads:[~2013-06-04 21:12 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-03  9:42 [RFC PATCH] emacs: search: allow command line args as part of query Mark Walters
2013-06-03 20:52 ` [PATCH v2] " Mark Walters
2013-06-04 15:21   ` [PATCH] " Mark Walters
2013-06-04 19:40     ` Tomi Ollila
2013-06-04 21:12       ` Mark Walters

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

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

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