[PATCH v4] emacs: add completion to "tag all" operation ("*" binding)

2012-01-26 Thread Dmitry Kurochkin
On Thu, 26 Jan 2012 02:04:39 -0500, Austin Clements  wrote:
> Quoth Dmitry Kurochkin on Jan 26 at  9:06 am:
> > The patch adds  completion to "tag all" operation bound to "*"
> > (`notmuch-search-operate-all' function).
> > ---
> > 
> > On a second thought, `notmuch-select-tag-with-completion' should never
> > need `prefixes' argument at all.  So I reverted the API and related
> > changes.
> > 
> > Changes:
> > 
> > v4:
> > 
> > * do not change `notmuch-select-tag-with-completion' API, revert
> >   related changes
> > 
> > v3:
> > 
> > * fixed comments from Austin's review [1]
> > 
> > v2:
> > 
> > * s/thistag/this_tag/ for consistency with "that_tag", since we touch
> >   the line anyway
> > 
> > Regards,
> >   Dmitry
> > 
> > [1] id:"20120126013727.GB1176 at mit.edu"
> > 
> >  emacs/notmuch.el |   53 
> > -
> >  1 files changed, 40 insertions(+), 13 deletions(-)
> > 
> > diff --git a/emacs/notmuch.el b/emacs/notmuch.el
> > index e02966f..d2af630 100644
> > --- a/emacs/notmuch.el
> > +++ b/emacs/notmuch.el
> > @@ -48,6 +48,7 @@
> >  ;; required, but is available from http://notmuchmail.org).
> >  
> >  (eval-when-compile (require 'cl))
> > +(require 'crm)
> >  (require 'mm-view)
> >  (require 'message)
> >  
> > @@ -75,12 +76,36 @@ For example:
> >  (defvar notmuch-query-history nil
> >"Variable to store minibuffer history for notmuch queries")
> >  
> > -(defun notmuch-select-tag-with-completion (prompt  search-terms)
> > +(defun notmuch-tag-completions ( prefixes search-terms)
> >(let ((tag-list
> >  (with-output-to-string
> >(with-current-buffer standard-output
> >  (apply 'call-process notmuch-command nil t nil "search-tags" 
> > search-terms)
> > -(completing-read prompt (split-string tag-list "\n+" t) nil nil nil)))
> > +(setq tag-list (split-string tag-list "\n+" t))
> 
> Since this setq is unconditional, you can do the split-string right in
> the let binding, around the with-output-to-string.
> 

I was thinking about it, but decided to use `setq', to make the diff
smaller and the let binding simpler.  Changed in v5.

> > +(if (null prefixes)
> > +   tag-list
> > +  (apply #'append
> > +(mapcar (lambda (tag)
> > +  (mapcar (lambda (prefix)
> > +(concat prefix tag)) prefixes))
> > +tag-list)
> > +
> > +(defun notmuch-select-tag-with-completion (prompt  search-terms)
> > +  (let ((tag-list (notmuch-tag-completions nil search-terms)))
> > +(completing-read prompt tag-list)))
> > +
> > +(defun notmuch-select-tags-with-completion (prompt  prefixes 
> >  search-terms)
> > +  (let ((tag-list (notmuch-tag-completions prefixes search-terms))
> > +   (crm-separator " ")
> > +   (crm-local-completion-map
> > +(let ((map (make-sparse-keymap)))
> > +  (set-keymap-parent map crm-local-completion-map)
> > +  map)))
> > +;; By default, space is bound to "complete word" function.
> > +;; Re-bind it to insert a space instead.  Note that  still
> > +;; does the completion.
> > +(define-key crm-local-completion-map " " 'self-insert-command)
> 
> You could do the define-key inside the (let ((map ..)) ..) so you get
> back the fully formed keymap.  Your call.
> 

Good point.  Changed in v5.

> > +(completing-read-multiple prompt tag-list)))
> >  
> >  (defun notmuch-foreach-mime-part (function mm-handle)
> >(cond ((stringp (car mm-handle))
> > @@ -849,7 +874,7 @@ non-authors is found, assume that all of the authors 
> > match."
> >   (goto-char found-target)))
> >(delete-process proc
> >  
> > -(defun notmuch-search-operate-all (action)
> > +(defun notmuch-search-operate-all ( actions)
> >"Add/remove tags from all matching messages.
> >  
> >  This command adds or removes tags from all messages matching the
> > @@ -860,16 +885,18 @@ will prompt for tags to be added or removed. Tags 
> > prefixed with
> >  Each character of the tag name may consist of alphanumeric
> >  characters as well as `_.+-'.
> >  "
> > -  (interactive "sOperation (+add -drop): notmuch tag ")
> > -  (let ((action-split (split-string action " +")))
> > -;; Perform some validation
> > -(let ((words action-split))
> > -  (when (null words) (error "No operation given"))
> > -  (while words
> > -   (unless (string-match-p "^[-+][-+_.[:word:]]+$" (car words))
> > - (error "Action must be of the form `+thistag -that_tag'"))
> > -   (setq words (cdr words
> > -(apply 'notmuch-tag notmuch-search-query-string action-split)))
> > +  (interactive (notmuch-select-tags-with-completion
> > +   "Operations (+add -drop): notmuch tag "
> > +   '("+" "-")))
> > +  (setq actions (delete "" actions))
> 
> Either this line isn't necessary or
> notmuch-select-tags-with-completion can do something funny that it
> should take care of internally.
> 

It is necessary and it belongs to 

[PATCH v4] emacs: add completion to "tag all" operation ("*" binding)

2012-01-26 Thread Dmitry Kurochkin
The patch adds  completion to "tag all" operation bound to "*"
(`notmuch-search-operate-all' function).
---

On a second thought, `notmuch-select-tag-with-completion' should never
need `prefixes' argument at all.  So I reverted the API and related
changes.

Changes:

v4:

* do not change `notmuch-select-tag-with-completion' API, revert
  related changes

v3:

* fixed comments from Austin's review [1]

v2:

* s/thistag/this_tag/ for consistency with "that_tag", since we touch
  the line anyway

Regards,
  Dmitry

[1] id:"20120126013727.GB1176 at mit.edu"

 emacs/notmuch.el |   53 -
 1 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index e02966f..d2af630 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -48,6 +48,7 @@
 ;; required, but is available from http://notmuchmail.org).

 (eval-when-compile (require 'cl))
+(require 'crm)
 (require 'mm-view)
 (require 'message)

@@ -75,12 +76,36 @@ For example:
 (defvar notmuch-query-history nil
   "Variable to store minibuffer history for notmuch queries")

-(defun notmuch-select-tag-with-completion (prompt  search-terms)
+(defun notmuch-tag-completions ( prefixes search-terms)
   (let ((tag-list
 (with-output-to-string
   (with-current-buffer standard-output
 (apply 'call-process notmuch-command nil t nil "search-tags" 
search-terms)
-(completing-read prompt (split-string tag-list "\n+" t) nil nil nil)))
+(setq tag-list (split-string tag-list "\n+" t))
+(if (null prefixes)
+   tag-list
+  (apply #'append
+(mapcar (lambda (tag)
+  (mapcar (lambda (prefix)
+(concat prefix tag)) prefixes))
+tag-list)
+
+(defun notmuch-select-tag-with-completion (prompt  search-terms)
+  (let ((tag-list (notmuch-tag-completions nil search-terms)))
+(completing-read prompt tag-list)))
+
+(defun notmuch-select-tags-with-completion (prompt  prefixes  
search-terms)
+  (let ((tag-list (notmuch-tag-completions prefixes search-terms))
+   (crm-separator " ")
+   (crm-local-completion-map
+(let ((map (make-sparse-keymap)))
+  (set-keymap-parent map crm-local-completion-map)
+  map)))
+;; By default, space is bound to "complete word" function.
+;; Re-bind it to insert a space instead.  Note that  still
+;; does the completion.
+(define-key crm-local-completion-map " " 'self-insert-command)
+(completing-read-multiple prompt tag-list)))

 (defun notmuch-foreach-mime-part (function mm-handle)
   (cond ((stringp (car mm-handle))
@@ -849,7 +874,7 @@ non-authors is found, assume that all of the authors match."
  (goto-char found-target)))
   (delete-process proc

-(defun notmuch-search-operate-all (action)
+(defun notmuch-search-operate-all ( actions)
   "Add/remove tags from all matching messages.

 This command adds or removes tags from all messages matching the
@@ -860,16 +885,18 @@ will prompt for tags to be added or removed. Tags 
prefixed with
 Each character of the tag name may consist of alphanumeric
 characters as well as `_.+-'.
 "
-  (interactive "sOperation (+add -drop): notmuch tag ")
-  (let ((action-split (split-string action " +")))
-;; Perform some validation
-(let ((words action-split))
-  (when (null words) (error "No operation given"))
-  (while words
-   (unless (string-match-p "^[-+][-+_.[:word:]]+$" (car words))
- (error "Action must be of the form `+thistag -that_tag'"))
-   (setq words (cdr words
-(apply 'notmuch-tag notmuch-search-query-string action-split)))
+  (interactive (notmuch-select-tags-with-completion
+   "Operations (+add -drop): notmuch tag "
+   '("+" "-")))
+  (setq actions (delete "" actions))
+  ;; Perform some validation
+  (let ((words actions))
+(when (null words) (error "No operations given"))
+(while words
+  (unless (string-match-p "^[-+][-+_.[:word:]]+$" (car words))
+   (error "Action must be of the form `+this_tag' or `-that_tag'"))
+  (setq words (cdr words
+  (apply 'notmuch-tag notmuch-search-query-string actions))

 (defun notmuch-search-buffer-title (query)
   "Returns the title for a buffer with notmuch search results."
-- 
1.7.8.3



[PATCH v4] emacs: add completion to "tag all" operation ("*" binding)

2012-01-26 Thread Austin Clements
Quoth Dmitry Kurochkin on Jan 26 at  9:06 am:
> The patch adds  completion to "tag all" operation bound to "*"
> (`notmuch-search-operate-all' function).
> ---
> 
> On a second thought, `notmuch-select-tag-with-completion' should never
> need `prefixes' argument at all.  So I reverted the API and related
> changes.
> 
> Changes:
> 
> v4:
> 
> * do not change `notmuch-select-tag-with-completion' API, revert
>   related changes
> 
> v3:
> 
> * fixed comments from Austin's review [1]
> 
> v2:
> 
> * s/thistag/this_tag/ for consistency with "that_tag", since we touch
>   the line anyway
> 
> Regards,
>   Dmitry
> 
> [1] id:"20120126013727.GB1176 at mit.edu"
> 
>  emacs/notmuch.el |   53 -
>  1 files changed, 40 insertions(+), 13 deletions(-)
> 
> diff --git a/emacs/notmuch.el b/emacs/notmuch.el
> index e02966f..d2af630 100644
> --- a/emacs/notmuch.el
> +++ b/emacs/notmuch.el
> @@ -48,6 +48,7 @@
>  ;; required, but is available from http://notmuchmail.org).
>  
>  (eval-when-compile (require 'cl))
> +(require 'crm)
>  (require 'mm-view)
>  (require 'message)
>  
> @@ -75,12 +76,36 @@ For example:
>  (defvar notmuch-query-history nil
>"Variable to store minibuffer history for notmuch queries")
>  
> -(defun notmuch-select-tag-with-completion (prompt  search-terms)
> +(defun notmuch-tag-completions ( prefixes search-terms)
>(let ((tag-list
>(with-output-to-string
>  (with-current-buffer standard-output
>(apply 'call-process notmuch-command nil t nil "search-tags" 
> search-terms)
> -(completing-read prompt (split-string tag-list "\n+" t) nil nil nil)))
> +(setq tag-list (split-string tag-list "\n+" t))

Since this setq is unconditional, you can do the split-string right in
the let binding, around the with-output-to-string.

> +(if (null prefixes)
> + tag-list
> +  (apply #'append
> +  (mapcar (lambda (tag)
> +(mapcar (lambda (prefix)
> +  (concat prefix tag)) prefixes))
> +  tag-list)
> +
> +(defun notmuch-select-tag-with-completion (prompt  search-terms)
> +  (let ((tag-list (notmuch-tag-completions nil search-terms)))
> +(completing-read prompt tag-list)))
> +
> +(defun notmuch-select-tags-with-completion (prompt  prefixes  
> search-terms)
> +  (let ((tag-list (notmuch-tag-completions prefixes search-terms))
> + (crm-separator " ")
> + (crm-local-completion-map
> +  (let ((map (make-sparse-keymap)))
> +(set-keymap-parent map crm-local-completion-map)
> +map)))
> +;; By default, space is bound to "complete word" function.
> +;; Re-bind it to insert a space instead.  Note that  still
> +;; does the completion.
> +(define-key crm-local-completion-map " " 'self-insert-command)

You could do the define-key inside the (let ((map ..)) ..) so you get
back the fully formed keymap.  Your call.

> +(completing-read-multiple prompt tag-list)))
>  
>  (defun notmuch-foreach-mime-part (function mm-handle)
>(cond ((stringp (car mm-handle))
> @@ -849,7 +874,7 @@ non-authors is found, assume that all of the authors 
> match."
> (goto-char found-target)))
>(delete-process proc
>  
> -(defun notmuch-search-operate-all (action)
> +(defun notmuch-search-operate-all ( actions)
>"Add/remove tags from all matching messages.
>  
>  This command adds or removes tags from all messages matching the
> @@ -860,16 +885,18 @@ will prompt for tags to be added or removed. Tags 
> prefixed with
>  Each character of the tag name may consist of alphanumeric
>  characters as well as `_.+-'.
>  "
> -  (interactive "sOperation (+add -drop): notmuch tag ")
> -  (let ((action-split (split-string action " +")))
> -;; Perform some validation
> -(let ((words action-split))
> -  (when (null words) (error "No operation given"))
> -  (while words
> - (unless (string-match-p "^[-+][-+_.[:word:]]+$" (car words))
> -   (error "Action must be of the form `+thistag -that_tag'"))
> - (setq words (cdr words
> -(apply 'notmuch-tag notmuch-search-query-string action-split)))
> +  (interactive (notmuch-select-tags-with-completion
> + "Operations (+add -drop): notmuch tag "
> + '("+" "-")))
> +  (setq actions (delete "" actions))

Either this line isn't necessary or
notmuch-select-tags-with-completion can do something funny that it
should take care of internally.

> +  ;; Perform some validation
> +  (let ((words actions))
> +(when (null words) (error "No operations given"))
> +(while words
> +  (unless (string-match-p "^[-+][-+_.[:word:]]+$" (car words))
> + (error "Action must be of the form `+this_tag' or `-that_tag'"))
> +  (setq words (cdr words
> +  (apply 'notmuch-tag notmuch-search-query-string actions))
>  
>  (defun notmuch-search-buffer-title (query)
>"Returns the title for a buffer with notmuch search 

[PATCH v4] emacs: add completion to tag all operation (* binding)

2012-01-25 Thread Dmitry Kurochkin
The patch adds tab completion to tag all operation bound to *
(`notmuch-search-operate-all' function).
---

On a second thought, `notmuch-select-tag-with-completion' should never
need `prefixes' argument at all.  So I reverted the API and related
changes.

Changes:

v4:

* do not change `notmuch-select-tag-with-completion' API, revert
  related changes

v3:

* fixed comments from Austin's review [1]

v2:

* s/thistag/this_tag/ for consistency with that_tag, since we touch
  the line anyway

Regards,
  Dmitry

[1] id:20120126013727.gb1...@mit.edu

 emacs/notmuch.el |   53 -
 1 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index e02966f..d2af630 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -48,6 +48,7 @@
 ;; required, but is available from http://notmuchmail.org).
 
 (eval-when-compile (require 'cl))
+(require 'crm)
 (require 'mm-view)
 (require 'message)
 
@@ -75,12 +76,36 @@ For example:
 (defvar notmuch-query-history nil
   Variable to store minibuffer history for notmuch queries)
 
-(defun notmuch-select-tag-with-completion (prompt rest search-terms)
+(defun notmuch-tag-completions (optional prefixes search-terms)
   (let ((tag-list
 (with-output-to-string
   (with-current-buffer standard-output
 (apply 'call-process notmuch-command nil t nil search-tags 
search-terms)
-(completing-read prompt (split-string tag-list \n+ t) nil nil nil)))
+(setq tag-list (split-string tag-list \n+ t))
+(if (null prefixes)
+   tag-list
+  (apply #'append
+(mapcar (lambda (tag)
+  (mapcar (lambda (prefix)
+(concat prefix tag)) prefixes))
+tag-list)
+
+(defun notmuch-select-tag-with-completion (prompt rest search-terms)
+  (let ((tag-list (notmuch-tag-completions nil search-terms)))
+(completing-read prompt tag-list)))
+
+(defun notmuch-select-tags-with-completion (prompt optional prefixes rest 
search-terms)
+  (let ((tag-list (notmuch-tag-completions prefixes search-terms))
+   (crm-separator  )
+   (crm-local-completion-map
+(let ((map (make-sparse-keymap)))
+  (set-keymap-parent map crm-local-completion-map)
+  map)))
+;; By default, space is bound to complete word function.
+;; Re-bind it to insert a space instead.  Note that tab still
+;; does the completion.
+(define-key crm-local-completion-map   'self-insert-command)
+(completing-read-multiple prompt tag-list)))
 
 (defun notmuch-foreach-mime-part (function mm-handle)
   (cond ((stringp (car mm-handle))
@@ -849,7 +874,7 @@ non-authors is found, assume that all of the authors match.
  (goto-char found-target)))
   (delete-process proc
 
-(defun notmuch-search-operate-all (action)
+(defun notmuch-search-operate-all (rest actions)
   Add/remove tags from all matching messages.
 
 This command adds or removes tags from all messages matching the
@@ -860,16 +885,18 @@ will prompt for tags to be added or removed. Tags 
prefixed with
 Each character of the tag name may consist of alphanumeric
 characters as well as `_.+-'.
 
-  (interactive sOperation (+add -drop): notmuch tag )
-  (let ((action-split (split-string action  +)))
-;; Perform some validation
-(let ((words action-split))
-  (when (null words) (error No operation given))
-  (while words
-   (unless (string-match-p ^[-+][-+_.[:word:]]+$ (car words))
- (error Action must be of the form `+thistag -that_tag'))
-   (setq words (cdr words
-(apply 'notmuch-tag notmuch-search-query-string action-split)))
+  (interactive (notmuch-select-tags-with-completion
+   Operations (+add -drop): notmuch tag 
+   '(+ -)))
+  (setq actions (delete  actions))
+  ;; Perform some validation
+  (let ((words actions))
+(when (null words) (error No operations given))
+(while words
+  (unless (string-match-p ^[-+][-+_.[:word:]]+$ (car words))
+   (error Action must be of the form `+this_tag' or `-that_tag'))
+  (setq words (cdr words
+  (apply 'notmuch-tag notmuch-search-query-string actions))
 
 (defun notmuch-search-buffer-title (query)
   Returns the title for a buffer with notmuch search results.
-- 
1.7.8.3

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v4] emacs: add completion to tag all operation (* binding)

2012-01-25 Thread Austin Clements
Quoth Dmitry Kurochkin on Jan 26 at  9:06 am:
 The patch adds tab completion to tag all operation bound to *
 (`notmuch-search-operate-all' function).
 ---
 
 On a second thought, `notmuch-select-tag-with-completion' should never
 need `prefixes' argument at all.  So I reverted the API and related
 changes.
 
 Changes:
 
 v4:
 
 * do not change `notmuch-select-tag-with-completion' API, revert
   related changes
 
 v3:
 
 * fixed comments from Austin's review [1]
 
 v2:
 
 * s/thistag/this_tag/ for consistency with that_tag, since we touch
   the line anyway
 
 Regards,
   Dmitry
 
 [1] id:20120126013727.gb1...@mit.edu
 
  emacs/notmuch.el |   53 -
  1 files changed, 40 insertions(+), 13 deletions(-)
 
 diff --git a/emacs/notmuch.el b/emacs/notmuch.el
 index e02966f..d2af630 100644
 --- a/emacs/notmuch.el
 +++ b/emacs/notmuch.el
 @@ -48,6 +48,7 @@
  ;; required, but is available from http://notmuchmail.org).
  
  (eval-when-compile (require 'cl))
 +(require 'crm)
  (require 'mm-view)
  (require 'message)
  
 @@ -75,12 +76,36 @@ For example:
  (defvar notmuch-query-history nil
Variable to store minibuffer history for notmuch queries)
  
 -(defun notmuch-select-tag-with-completion (prompt rest search-terms)
 +(defun notmuch-tag-completions (optional prefixes search-terms)
(let ((tag-list
(with-output-to-string
  (with-current-buffer standard-output
(apply 'call-process notmuch-command nil t nil search-tags 
 search-terms)
 -(completing-read prompt (split-string tag-list \n+ t) nil nil nil)))
 +(setq tag-list (split-string tag-list \n+ t))

Since this setq is unconditional, you can do the split-string right in
the let binding, around the with-output-to-string.

 +(if (null prefixes)
 + tag-list
 +  (apply #'append
 +  (mapcar (lambda (tag)
 +(mapcar (lambda (prefix)
 +  (concat prefix tag)) prefixes))
 +  tag-list)
 +
 +(defun notmuch-select-tag-with-completion (prompt rest search-terms)
 +  (let ((tag-list (notmuch-tag-completions nil search-terms)))
 +(completing-read prompt tag-list)))
 +
 +(defun notmuch-select-tags-with-completion (prompt optional prefixes rest 
 search-terms)
 +  (let ((tag-list (notmuch-tag-completions prefixes search-terms))
 + (crm-separator  )
 + (crm-local-completion-map
 +  (let ((map (make-sparse-keymap)))
 +(set-keymap-parent map crm-local-completion-map)
 +map)))
 +;; By default, space is bound to complete word function.
 +;; Re-bind it to insert a space instead.  Note that tab still
 +;; does the completion.
 +(define-key crm-local-completion-map   'self-insert-command)

You could do the define-key inside the (let ((map ..)) ..) so you get
back the fully formed keymap.  Your call.

 +(completing-read-multiple prompt tag-list)))
  
  (defun notmuch-foreach-mime-part (function mm-handle)
(cond ((stringp (car mm-handle))
 @@ -849,7 +874,7 @@ non-authors is found, assume that all of the authors 
 match.
 (goto-char found-target)))
(delete-process proc
  
 -(defun notmuch-search-operate-all (action)
 +(defun notmuch-search-operate-all (rest actions)
Add/remove tags from all matching messages.
  
  This command adds or removes tags from all messages matching the
 @@ -860,16 +885,18 @@ will prompt for tags to be added or removed. Tags 
 prefixed with
  Each character of the tag name may consist of alphanumeric
  characters as well as `_.+-'.
  
 -  (interactive sOperation (+add -drop): notmuch tag )
 -  (let ((action-split (split-string action  +)))
 -;; Perform some validation
 -(let ((words action-split))
 -  (when (null words) (error No operation given))
 -  (while words
 - (unless (string-match-p ^[-+][-+_.[:word:]]+$ (car words))
 -   (error Action must be of the form `+thistag -that_tag'))
 - (setq words (cdr words
 -(apply 'notmuch-tag notmuch-search-query-string action-split)))
 +  (interactive (notmuch-select-tags-with-completion
 + Operations (+add -drop): notmuch tag 
 + '(+ -)))
 +  (setq actions (delete  actions))

Either this line isn't necessary or
notmuch-select-tags-with-completion can do something funny that it
should take care of internally.

 +  ;; Perform some validation
 +  (let ((words actions))
 +(when (null words) (error No operations given))
 +(while words
 +  (unless (string-match-p ^[-+][-+_.[:word:]]+$ (car words))
 + (error Action must be of the form `+this_tag' or `-that_tag'))
 +  (setq words (cdr words
 +  (apply 'notmuch-tag notmuch-search-query-string actions))
  
  (defun notmuch-search-buffer-title (query)
Returns the title for a buffer with notmuch search results.
___
notmuch mailing list
notmuch@notmuchmail.org