Re: [PATCH] emacs: search: edit current query

Subject: Re: [PATCH] emacs: search: edit current query

Date: Thu, 17 Apr 2014 14:47:19 -0400

To: Mark Walters

Cc: notmuch@notmuchmail.org

From: Austin Clements


You can *almost* do this already with the search minibuffer history.
As far as I can tell, the only thing missing is modifying a search
that started as a saved search.  We could fix that by simply adding
saved searches to this history (and possibly filtering saved searches
out for the hello "recent searches" widget).

Quoth Mark Walters on Apr 17 at  6:43 am:
> This adds an option to edit the current query. It is bound to
> prefix-key f as it is a sort of inverse operation to filtering.
> ---
> rlb asked for the option to modify the existing search query on
> irc. This implements that for the search view.
> 
> Best wishes
> 
> Mark 
> 
> 
> 
> 
> 
>  emacs/notmuch.el |   37 ++++++++++++++++++++++++++-----------
>  1 file changed, 26 insertions(+), 11 deletions(-)
> 
> diff --git a/emacs/notmuch.el b/emacs/notmuch.el
> index 6c0bc1b..b4408f1 100644
> --- a/emacs/notmuch.el
> +++ b/emacs/notmuch.el
> @@ -848,7 +848,7 @@ See `notmuch-tag' for information on the format of TAG-CHANGES."
>  	   (concat "*notmuch-search-" query "*"))
>  	  )))
>  
> -(defun notmuch-read-query (prompt)
> +(defun notmuch-read-query (prompt &optional initial-contents)
>    "Read a notmuch-query from the minibuffer with completion.
>  
>  PROMPT is the string to prompt with."
> @@ -876,7 +876,7 @@ PROMPT is the string to prompt with."
>        ;; this was simpler than convincing completing-read to accept spaces:
>        (define-key keymap (kbd "TAB") 'minibuffer-complete)
>        (let ((history-delete-duplicates t))
> -	(read-from-minibuffer prompt nil keymap nil
> +	(read-from-minibuffer prompt initial-contents keymap nil
>  			      'notmuch-search-history nil nil)))))
>  
>  ;;;###autoload
> @@ -963,18 +963,33 @@ default sort order is defined by `notmuch-search-oldest-first'."
>    (set 'notmuch-search-oldest-first (not notmuch-search-oldest-first))
>    (notmuch-search-refresh-view))
>  
> -(defun notmuch-search-filter (query)
> +(put 'notmuch-search-filter 'notmuch-doc
> +     "Filter the current search results based on an additional query string.")

Since this is purely user-facing, you could drop the word "string".

> +(put 'notmuch-search-filter 'notmuch-prefix-doc
> +     "Edit the current search query.")
> +(defun notmuch-search-filter (modify query)

This could easily be kept backwards compatible by changing this to
something like (query &optional replace).

>    "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)
> -			   (concat "( " query " )")
> -			 query)))
> -    (notmuch-search (if (string= notmuch-search-query-string "*")
> -			grouped-query
> -		      (concat notmuch-search-query-string " and " grouped-query)) notmuch-search-oldest-first)))
> +current search results AND the additional query string provided.
> +
> +If called with a prefix-arg then present the user with the
> +existing query string to allow the user to edit it."

The documentation doesn't say how the Lisp-oriented interface to this
works.  How about

  "Runs a new search based on the current search query.

If REPLACE is non-nil, starts a search for QUERY.  If REPLACE is nil
or omitted, starts a search for the current buffer's query \"and\"
QUERY.  In both cases, this uses the same options as the current
search buffer.

If called interactively with a prefix argument, prompts the user to
edit the current query.  Otherwise, prompts for a filter query."

> +  (interactive (let ((query-string (if current-prefix-arg
> +				       "Modify Search: "
> +				     "Filter Search: "))
> +		     (initial-contents (if current-prefix-arg
> +				 notmuch-search-query-string
> +				 nil)))
> +		 (list current-prefix-arg (notmuch-read-query query-string initial-contents))))
> +  (if modify
> +      (notmuch-search query notmuch-search-oldest-first)
> +    (let ((grouped-query (if (string-match-p notmuch-search-disjunctive-regexp query)

I can think of so many ways to break this heuristic...  But that's not
really this patch's concern.

> +			     (concat "( " query " )")
> +			   query)))
> +      (notmuch-search (if (string= notmuch-search-query-string "*")
> +			  grouped-query
> +			(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.

Thread: