unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [PATCH] Support for deletion (patch included)
@ 2009-12-13 11:54 Matthieu Lemerre
  2010-02-24 18:49 ` Carl Worth
  0 siblings, 1 reply; 7+ messages in thread
From: Matthieu Lemerre @ 2009-12-13 11:54 UTC (permalink / raw)
  To: notmuch

[-- Attachment #1: Type: text/plain, Size: 28 bytes --]


I forgot the attachment..


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: notmuch-deletion.patch --]
[-- Type: text/x-diff, Size: 4002 bytes --]

diff --git a/notmuch.el b/notmuch.el
index 97914f2..f770dd0 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -991,6 +991,7 @@ matching this search term are shown if non-nil. "
     (define-key map [mouse-1] 'notmuch-search-show-thread)
     (define-key map "*" 'notmuch-search-operate-all)
     (define-key map "a" 'notmuch-search-archive-thread)
+    (define-key map "d" 'notmuch-search-mark-as-deleted)
     (define-key map "-" 'notmuch-search-remove-tag)
     (define-key map "+" 'notmuch-search-add-tag)
     (define-key map (kbd "RET") 'notmuch-search-show-thread)
@@ -999,6 +1000,7 @@ matching this search term are shown if non-nil. "
 (fset 'notmuch-search-mode-map notmuch-search-mode-map)
 
 (defvar notmuch-search-query-string)
+(defvar notmuch-search-history nil)
 (defvar notmuch-search-oldest-first t
   "Show the oldest mail first in the search-mode")
 
@@ -1210,6 +1212,15 @@ This function advances the next thread when finished."
   (notmuch-search-remove-tag "inbox")
   (forward-line))
 
+
+(defun notmuch-search-mark-as-deleted ()
+  "Mark the currently selected thread as deleted (set its \"deleted\" tag).
+This function advances the next thread when finished."
+  (interactive)
+  (notmuch-search-add-tag "deleted")
+  (forward-line))
+
+
 (defun notmuch-search-process-sentinel (proc msg)
   "Add a message to let user know when \"notmuch search\" exits"
   (let ((buffer (process-buffer proc))
@@ -1284,10 +1295,22 @@ characters as well as `_.+-'.
 	   (append action-split (list notmuch-search-query-string) nil))))
 
 ;;;###autoload
-(defun notmuch-search (query &optional oldest-first)
-  "Run \"notmuch search\" with the given query string and display results."
-  (interactive "sNotmuch search: ")
-  (let ((buffer (get-buffer-create (concat "*notmuch-search-" query "*"))))
+(defun notmuch-search (query &optional oldest-first include-deleted)
+  "Run \"notmuch search\" with the given query string and display results.
+
+With prefix argument, include deleted items.
+"
+  (interactive (let* ((prefix current-prefix-arg)
+		      (query (if prefix
+				 (read-string "Notmuch search (including deleted): "
+					      notmuch-search-query-string
+					      'notmuch-search-history)
+			       (read-string "Notmuch search: " nil
+					    'notmuch-search-history))))
+		 (list query nil prefix)))
+  (let ((real-query (if include-deleted query 
+		      (concat "not tag:deleted and (" query ")")))
+	(buffer (get-buffer-create (concat "*notmuch-search-" query "*"))))
     (switch-to-buffer buffer)
     (notmuch-search-mode)
     (set 'notmuch-search-query-string query)
@@ -1303,7 +1326,7 @@ characters as well as `_.+-'.
 	(let ((proc (start-process-shell-command
 		     "notmuch-search" buffer notmuch-command "search"
 		     (if oldest-first "--sort=oldest-first" "--sort=newest-first")
-		     (shell-quote-argument query))))
+		     (shell-quote-argument real-query))))
 	  (set-process-sentinel proc 'notmuch-search-process-sentinel)
 	  (set-process-filter proc 'notmuch-search-process-filter))))
     (run-hooks 'notmuch-search-hook)))
@@ -1351,7 +1374,6 @@ search."
 
 Runs a new search matching only messages that match both the
 current search results AND the additional query string provided."
-  (interactive "sFilter search: ")
   (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)))
 
@@ -1391,7 +1413,9 @@ current search results AND that are tagged with the given tag."
 
 (fset 'notmuch-folder-mode-map notmuch-folder-mode-map)
 
-(defcustom notmuch-folders (quote (("inbox" . "tag:inbox") ("unread" . "tag:unread")))
+(defcustom notmuch-folders (quote (("inbox" . "tag:inbox") 
+				   ("unread" . "tag:unread")
+				   ("deleted" . "tag:deleted")))
   "List of searches for the notmuch folder view"
   :type '(alist :key-type (string) :value-type (string))
   :group 'notmuch)

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

* Re: [PATCH] Support for deletion (patch included)
  2009-12-13 11:54 Matthieu Lemerre
@ 2010-02-24 18:49 ` Carl Worth
  2010-02-25  0:00   ` racin
  0 siblings, 1 reply; 7+ messages in thread
From: Carl Worth @ 2010-02-24 18:49 UTC (permalink / raw)
  To: Matthieu Lemerre, notmuch

[-- Attachment #1: Type: text/plain, Size: 3883 bytes --]

On Sun, 13 Dec 2009 12:54:09 +0100, Matthieu Lemerre <racin@free.fr> wrote:
> I forgot the attachment..

Hi Matthieu,

This is a very interesting patch. Thanks for contributing it.

Could you also write a commit message describing what the patch does?
The easiest way for me to apply that would be if you would create a git
commit, then run "git format-patch origin/master" and mail the resulting
files, (the "git send-email" command can be used here, or you can insert
the files into a mail-composition buffer and modify them as needed).

A couple of minor comments on the patch:

>      (define-key map "a" 'notmuch-search-archive-thread)
> +    (define-key map "d" 'notmuch-search-mark-as-deleted)

For consistency, let's name this notmuch-search-delete-thread.

And we'll probably want a notmuch-show-delete-message function as well,
no?

> +(defvar notmuch-search-history nil)

Excellent! I've wanted custom search history for a while, and just
didn't know how to do it with (interactive "s"). It looks easy enough
with read-string as you're doing here. But this is independent
functionality, so would be preferred as an independent patch/commit.

>    (forward-line))
>  
> +
> +(defun notmuch-search-mark-as-deleted ()
> +  "Mark the currently selected thread as deleted (set its \"deleted\" tag).
> +This function advances the next thread when finished."
> +  (interactive)
> +  (notmuch-search-add-tag "deleted")
> +  (forward-line))
> +
> +
>  (defun notmuch-search-process-sentinel (proc msg)

Watch that extra whitespace. The convention is a single line of
whitespace between each function.

And should we also archive the thread before removing the deleted tag?

> +With prefix argument, include deleted items.

That's a pretty good interface I think.

Another approach would be to do something like what sup does---that
would be to scan the search terms and if it contains "tag:deleted" and
all then don't prepend the "not tag:deleted and" to the search
string. The assumption there is that if the user is explicitly
mentioning the deleted tag, then we should just rely on the user to
explicitly describe how the tag should be treated.

That's perhaps not an unreasonable heuristic, and might be done even in
addition to the prefix-argument approach. But that could be an
additional commit, and I won't require it.

> +  (interactive (let* ((prefix current-prefix-arg)
> +		      (query (if prefix
> +				 (read-string "Notmuch search (including deleted): "
> +					      notmuch-search-query-string
> +					      'notmuch-search-history)
> +			       (read-string "Notmuch search: " nil
> +					    'notmuch-search-history))))

Why is the second (initial-input) argument non-nil in one case, but nil
in the other? The documentation for `read-string' says the argument is
deprecated and should be nil in all new code.

> +		 (list query nil prefix)))
> +  (let ((real-query (if include-deleted query 
> +		      (concat "not tag:deleted and (" query ")")))
> +	(buffer (get-buffer-create (concat "*notmuch-search-" query
> "*"))))

Does the include-deleted case actually work? I don't see anything in the
code that sets this variable. (I'm just reviewing here--I haven't tested
it manually).

> @@ -1351,7 +1374,6 @@ search."
>  
>  Runs a new search matching only messages that match both the
>  current search results AND the additional query string provided."
> -  (interactive "sFilter search: ")
>    (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)))

Is this just an accidental chunk in the patch? I don't see why this
function should become non-interactive now.

Thanks again,

-Carl

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

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

* Re: [PATCH] Support for deletion (patch included)
  2010-02-24 18:49 ` Carl Worth
@ 2010-02-25  0:00   ` racin
  2010-02-25 10:49     ` Sebastian Spaeth
  2010-03-01  9:09     ` Michal Sojka
  0 siblings, 2 replies; 7+ messages in thread
From: racin @ 2010-02-25  0:00 UTC (permalink / raw)
  To: Carl Worth; +Cc: notmuch

Hi Carl,

> Could you also write a commit message describing what the patch does?
> The easiest way for me to apply that would be if you would create a git
> commit, then run "git format-patch origin/master" and mail the resulting
> files, (the "git send-email" command can be used here, or you can insert
> the files into a mail-composition buffer and modify them as needed).
> 

OK, here it is (comments below). I had trouble splitting the patches into a patch series; I
found git add -p, but isn't there a better interface for selecting patches?

From bdee9558d93bffb97c80632f522288e059deb7c2 Mon Sep 17 00:00:00 2001
From: Matthieu Lemerre <racin@racin.rez-gif.supelec.fr>
Date: Thu, 25 Feb 2010 00:24:24 +0100
Subject: [PATCH 1/2] Add and use notmuch-show-forall-in-thread macro

---
 notmuch.el |   17 +++++++++++------
 1 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index 6482170..5d7342a 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -321,17 +321,22 @@ pseudoheader summary"
 			 (cons (notmuch-show-get-message-id) nil)))
 	  (notmuch-show-set-tags (sort (set-difference tags toremove :test 'string=) 'string<))))))
 
-(defun notmuch-show-archive-thread-maybe-mark-read (markread)
-  (save-excursion
+(defmacro notmuch-show-forall-in-thread (&rest body)
+  "Executes BODY with point in all messages of the current thread."
+  `(save-excursion
     (goto-char (point-min))
     (while (not (eobp))
-      (if markread
-	  (notmuch-show-remove-tag "unread" "inbox")
-	(notmuch-show-remove-tag "inbox"))
+      ,@body
       (if (not (eobp))
 	  (forward-char))
       (if (not (re-search-forward notmuch-show-message-begin-regexp nil t))
-	  (goto-char (point-max)))))
+	  (goto-char (point-max))))))
+
+(defun notmuch-show-archive-thread-maybe-mark-read (markread)
+  (notmuch-show-forall-in-thread
+      (if markread
+	  (notmuch-show-remove-tag "unread" "inbox")
+	(notmuch-show-remove-tag "inbox")))
   (let ((parent-buffer notmuch-show-parent-buffer))
     (kill-this-buffer)
     (if parent-buffer
-- 
1.6.5


This first patch is helpful for factorizing out code. Basically, it allows to
apply a "message-only" command to all the thread.

From 0073152e3fa7dd11d88de28e87eec7762cdbbbeb Mon Sep 17 00:00:00 2001
From: Matthieu Lemerre <racin@racin.rez-gif.supelec.fr>
Date: Thu, 25 Feb 2010 00:25:51 +0100
Subject: [PATCH 2/2] Add support for deletion in the emacs interface

---
 notmuch.el |   56 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index 5d7342a..0285573 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -92,6 +92,8 @@
     (define-key map "x" 'notmuch-show-archive-thread-then-exit)
     (define-key map "A" 'notmuch-show-mark-read-then-archive-thread)
     (define-key map "a" 'notmuch-show-archive-thread)
+    (define-key map "d" 'notmuch-show-delete-thread)
+    (define-key map "D" 'notmuch-show-delete-message)
     (define-key map "p" 'notmuch-show-previous-message)
     (define-key map "N" 'notmuch-show-mark-read-then-next-open-message)
     (define-key map "n" 'notmuch-show-next-message)
@@ -380,6 +382,23 @@ buffer."
   (notmuch-show-archive-thread)
   (kill-this-buffer))
 
+(defun notmuch-show-delete-message ()
+  "Delete current message (sets its deleted tag)."
+  (interactive)
+  (notmuch-show-add-tag "deleted"))
+
+(defun notmuch-show-delete-thread()
+  "Delete each message in thread."
+  (interactive)
+  (notmuch-show-forall-in-thread
+   (notmuch-show-delete-message)))
+
+(defun notmuch-show-delete-thread-and-exit()
+  "Delete each message in thread, then exit back to search results."
+  (interactive)
+  (notmuch-show-delete-thread)
+  (kill-this-buffer))
+
 (defun notmuch-show-mark-read-then-archive-then-exit ()
   "Remove unread tags from thread, then archive and exit to search results."
   (interactive)
@@ -1227,6 +1246,7 @@ matching this search term are shown if non-nil. "
     (define-key map [mouse-1] 'notmuch-search-show-thread)
     (define-key map "*" 'notmuch-search-operate-all)
     (define-key map "a" 'notmuch-search-archive-thread)
+    (define-key map "d" 'notmuch-search-delete-thread)
     (define-key map "-" 'notmuch-search-remove-tag)
     (define-key map "+" 'notmuch-search-add-tag)
     (define-key map (kbd "RET") 'notmuch-search-show-thread)
@@ -1235,6 +1255,7 @@ matching this search term are shown if non-nil. "
 (fset 'notmuch-search-mode-map notmuch-search-mode-map)
 
 (defvar notmuch-search-query-string)
+(defvar notmuch-search-history nil)
 (defvar notmuch-search-oldest-first t
   "Show the oldest mail first in the search-mode")
 
@@ -1446,6 +1467,13 @@ This function advances the next thread when finished."
   (notmuch-search-remove-tag "inbox")
   (forward-line))
 
+(defun notmuch-search-delete-thread ()
+  "Mark the currently selected thread as deleted (set its \"deleted\" tag).
+This function advances the next thread when finished."
+  (interactive)
+  (notmuch-search-add-tag "deleted")
+  (forward-line))
+
 (defun notmuch-search-process-sentinel (proc msg)
   "Add a message to let user know when \"notmuch search\" exits"
   (let ((buffer (process-buffer proc))
@@ -1520,10 +1548,22 @@ characters as well as `_.+-'.
 	   (append action-split (list notmuch-search-query-string) nil))))
 
 ;;;###autoload
-(defun notmuch-search (query &optional oldest-first)
-  "Run \"notmuch search\" with the given query string and display results."
-  (interactive "sNotmuch search: ")
-  (let ((buffer (get-buffer-create (concat "*notmuch-search-" query "*"))))
+(defun notmuch-search (query &optional oldest-first include-deleted)
+  "Run \"notmuch search\" with the given query string and display results.
+
+With prefix argument, include deleted items.
+"
+  (interactive (let* ((prefix current-prefix-arg)
+		      (query (if prefix
+				 (read-string "Notmuch search (including deleted): "
+					      notmuch-search-query-string
+					      'notmuch-search-history)
+			       (read-string "Notmuch search: " nil
+					    'notmuch-search-history))))
+		 (list query nil prefix)))
+  (let ((real-query (if include-deleted query 
+		      (concat "not tag:deleted and (" query ")")))
+	(buffer (get-buffer-create (concat "*notmuch-search-" query "*"))))
     (switch-to-buffer buffer)
     (notmuch-search-mode)
     (set 'notmuch-search-query-string query)
@@ -1539,7 +1579,7 @@ characters as well as `_.+-'.
 	(let ((proc (start-process-shell-command
 		     "notmuch-search" buffer notmuch-command "search"
 		     (if oldest-first "--sort=oldest-first" "--sort=newest-first")
-		     (shell-quote-argument query))))
+		     (shell-quote-argument real-query))))
 	  (set-process-sentinel proc 'notmuch-search-process-sentinel)
 	  (set-process-filter proc 'notmuch-search-process-filter))))
     (run-hooks 'notmuch-search-hook)))
@@ -1587,7 +1627,7 @@ search."
 
 Runs a new search matching only messages that match both the
 current search results AND the additional query string provided."
-  (interactive "sFilter search: ")
+  (interactive "sFilter search:")
   (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)))
 
@@ -1630,7 +1670,9 @@ current search results AND that are tagged with the given tag."
 
 (fset 'notmuch-folder-mode-map notmuch-folder-mode-map)
 
-(defcustom notmuch-folders (quote (("inbox" . "tag:inbox") ("unread" . "tag:unread")))
+(defcustom notmuch-folders (quote (("inbox" . "tag:inbox") 
+				   ("unread" . "tag:unread")
+				   ("deleted" . "tag:deleted")))
   "List of searches for the notmuch folder view"
   :type '(alist :key-type (string) :value-type (string))
   :group 'notmuch)
-- 
1.6.5


This second patch is the reworked patch, after your comments.

> A couple of minor comments on the patch:
> 
> >      (define-key map "a" 'notmuch-search-archive-thread)
> > +    (define-key map "d" 'notmuch-search-mark-as-deleted)
> 
> For consistency, let's name this notmuch-search-delete-thread.
> 
> And we'll probably want a notmuch-show-delete-message function as well,
> no?

Did both. I have however a question: how to handle in the UI the
thread/message distinction? For now, I set "d" in notmuch-show buffer
to act as "delete the current thread", and "D" as "delete the current
message". I thought that as "d" meant in notmuch summary "delete the
current thread", the bindings would be more consistent.  But now I
wonder if this may be counter intuitive, and if we should use "d" for
"delete current message" and "D" for "delete current thread". What do
people think?

It would be nice to have, in general a convenient way to handle the
thread/message distinction in the UI (e.g. for applying other tags).

> 
> > +(defvar notmuch-search-history nil)
> 
> Excellent! I've wanted custom search history for a while, and just
> didn't know how to do it with (interactive "s"). It looks easy enough
> with read-string as you're doing here. But this is independent
> functionality, so would be preferred as an independent patch/commit.

In fact I needed this; that way when you do "C-u s", the previous
search is shown, and to include deleted items you just have to do "C-u
s RET".  So I made them in a single commit; but I can split them if
you really want to.

> 
> >    (forward-line))
> >  
> > +
> > +(defun notmuch-search-mark-as-deleted ()
> > +  "Mark the currently selected thread as deleted (set its \"deleted\" tag).
> > +This function advances the next thread when finished."
> > +  (interactive)
> > +  (notmuch-search-add-tag "deleted")
> > +  (forward-line))
> > +
> > +
> >  (defun notmuch-search-process-sentinel (proc msg)
> 
> Watch that extra whitespace. The convention is a single line of
> whitespace between each function.
> 

My bad. I did not see this in my review. Corrected this in the updated patch.

> And should we also archive the thread before removing the deleted tag?

I don't understand this. Do you mean: should we also archive the
thread before setting the deleted tag? I don't known why we should
bother to do it, as the tag is not show by the next results. 

I would tend to think that archiving should be an explicit action,
that should call a hook. For instance, I'd like my mailflow to be like
this:

- get mail with offlineimap => a maildir directory, indexed by notmuch

- mails stay in inbox until I archive it. That way I can still access
  it with IMAP.

- archiving puts an "archived" tag (and removes the inbox and unread
  tags), and move the mail to another directory (or uses git to
  archive the mail).

- deleting puts a deleted tag (but the messages stays inbox as long as
  I do not explicitely remove this).

The main reason is that many mail servers only allow small quotas, so
you have to carefully select which mail should stay inbox (only the
mail that you need external access).

In brief, this mail flow needs to delete threads but not to archive
it. I think that we could provide hooks, so that you can archive
mails when you delete them if you like to.

By the way in my patch commentary, you said that you planned to change
the "inbox" and "unread" treatments to be more explicit. Do you still
plan to do that? I can maybe also provide a patch.

> > +With prefix argument, include deleted items.
> 
> That's a pretty good interface I think.
> 
> Another approach would be to do something like what sup does---that
> would be to scan the search terms and if it contains "tag:deleted" and
> all then don't prepend the "not tag:deleted and" to the search
> string. The assumption there is that if the user is explicitly
> mentioning the deleted tag, then we should just rely on the user to
> explicitly describe how the tag should be treated.
> 
> That's perhaps not an unreasonable heuristic, and might be done even in
> addition to the prefix-argument approach. But that could be an
> additional commit, and I won't require it.

Hmm, that's what I did want to do initially. In that case, I think
that notmuch should be able to output parse trees from notmuch search
strings as JSON; this would help do the parsing in the various
implementations.

I also had this idea that may solve the "tag should be
orthogonal/command-line UI problem". We observe that "archived" is
contrary to "inbox", "read" contrary to "unread", "deleted" contrary
to "undeleted", and so on.

So it may be a good idea to have "pseudo-tags", that would help in the
interface (searching archived mails with search not tag:inbox is not
very intuitive...), as synonyms for "not tag:countrary-tag"

Then for each "pseudo-tag", notmuch could hard-code which is included
by default. Adding the other tags is easy: just add "and tag:deleted"
or "and tag:read" or "and tag:archived". Moreover, this would simplify
UI implementation as well, without requiring parsing of the strings.

Another, even simpler possibility would be to add a "--all" flag to
notmuch. Without it, it would omit some of the tags (like the deleted
ones), which would be convenient as a text interface. With it, it
would show all tags, which would be convenient for use with scripts
and UI, and mor in the "tags are orthogonal" spirit. Again, this would
not require to parse search strings, and imho would be much cleaner.

> > +  (interactive (let* ((prefix current-prefix-arg)
> > +                      (query (if prefix
> > +                                 (read-string "Notmuch search (including deleted): "
> > +                                              notmuch-search-query-string
> > +                                              'notmuch-search-history)
> > +                               (read-string "Notmuch search: " nil
> > +                                            'notmuch-search-history))))
> 
> Why is the second (initial-input) argument non-nil in one case, but nil
> in the other? The documentation for `read-string' says the argument is
> deprecated and should be nil in all new code.

The idea is that you do not have default search terms if you do
regular searchs. But if you want to include deleted items, then you
have the last search string. This way, you handle the common case when
you serach for a term, do not find it, then decide to try again with
deleted items.

Now, maybe the C-u interface is not such a good idea, and a toggle
button would be better. Don't know, but I find this interface
convenient.

> 
> > +                 (list query nil prefix)))
> > +  (let ((real-query (if include-deleted query
> > +                      (concat "not tag:deleted and (" query ")")))
> > +        (buffer (get-buffer-create (concat "*notmuch-search-" query
> > "*"))))
> 
> Does the include-deleted case actually work? I don't see anything in the
> code that sets this variable. (I'm just reviewing here--I haven't tested
> it manually).

This is the way interactive work.
(defun notmuch-search (query &optional oldest-first include-deleted)
...
+  (interactive (let* ((prefix current-prefix-arg)
...
+		 (list query nil prefix)))

The (list query nil prefix) at the end of the (interactive) form will
set query to query, nil to oldest-first, and prefix to
include-deleted.

> 
> > @@ -1351,7 +1374,6 @@ search."
> >  
> >  Runs a new search matching only messages that match both the
> >  current search results AND the additional query string provided."
> > -  (interactive "sFilter search: ")
> >    (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)))
> 
> Is this just an accidental chunk in the patch? I don't see why this
> function should become non-interactive now.

My bad, corrected that also.

Matthieu

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

* Re: [PATCH] Support for deletion (patch included)
  2010-02-25  0:00   ` racin
@ 2010-02-25 10:49     ` Sebastian Spaeth
  2010-03-01  9:09     ` Michal Sojka
  1 sibling, 0 replies; 7+ messages in thread
From: Sebastian Spaeth @ 2010-02-25 10:49 UTC (permalink / raw)
  To: racin, Carl Worth; +Cc: notmuch

I cannot comment on this patch, I just want to state that this
functionality can also be achieved with (id:87sk90ragj.fsf@jhu.edu)
"add functionality in notmuch search mode to add or remove tags by region"
and (id:1266408746-28549-1-git-send-email-Sebastian@SSpaeth.de)
"bind 'd' to new function notmuch-search-delete-thread-or-region"

I think that "add functionality in notmuch search mode to add or remove
tags by region" might be wanted functionality anyway.

Sebastian

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

* Re: [PATCH] Support for deletion (patch included)
       [not found] <829811857.5353531267112884804.JavaMail.root@zimbra1-e1.priv.proxad.net>
@ 2010-02-25 15:51 ` racin
  0 siblings, 0 replies; 7+ messages in thread
From: racin @ 2010-02-25 15:51 UTC (permalink / raw)
  To: Carl Worth; +Cc: notmuch

Carl: The patch in the mail has problems; apparently I have to manually add scissorlines to the mail for it
to be processed by git-am. I thought this was automatically added. (I hate the git UI -- nothing is consistent,
concepts have different names, the definition of scissor lines is as precise as "A line that mainly consists of scissors (either ">8" or "8<") and perforation (dash "-") --, but I guess we can get used to it after a while...)

I'll send you a proper patch as soon as I can. Meanwhile, I'm sure you have comments on this updated patch!

Matthieu

À: "Carl Worth" <cworth@cworth.org>
Cc: notmuch@notmuchmail.org
Envoyé: Jeudi 25 Février 2010 00h00:04 GMT +00:00 GMT - Grande-Bretagne, Irlande, Portugal
Objet: Re: [notmuch] [PATCH] Support for deletion (patch included)

Hi Carl,

> Could you also write a commit message describing what the patch does?
> The easiest way for me to apply that would be if you would create a git
> commit, then run "git format-patch origin/master" and mail the resulting
> files, (the "git send-email" command can be used here, or you can insert
> the files into a mail-composition buffer and modify them as needed).
> 

OK, here it is (comments below). I had trouble splitting the patches into a patch series; I
found git add -p, but isn't there a better interface for selecting patches?

From bdee9558d93bffb97c80632f522288e059deb7c2 Mon Sep 17 00:00:00 2001
From: Matthieu Lemerre <racin@racin.rez-gif.supelec.fr>
Date: Thu, 25 Feb 2010 00:24:24 +0100
Subject: [PATCH 1/2] Add and use notmuch-show-forall-in-thread macro

---
 notmuch.el |   17 +++++++++++------
 1 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index 6482170..5d7342a 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -321,17 +321,22 @@ pseudoheader summary"
 			 (cons (notmuch-show-get-message-id) nil)))
 	  (notmuch-show-set-tags (sort (set-difference tags toremove :test 'string=) 'string<))))))
 
-(defun notmuch-show-archive-thread-maybe-mark-read (markread)
-  (save-excursion
+(defmacro notmuch-show-forall-in-thread (&rest body)
+  "Executes BODY with point in all messages of the current thread."
+  `(save-excursion
     (goto-char (point-min))
     (while (not (eobp))
-      (if markread
-	  (notmuch-show-remove-tag "unread" "inbox")
-	(notmuch-show-remove-tag "inbox"))
+      ,@body
       (if (not (eobp))
 	  (forward-char))
       (if (not (re-search-forward notmuch-show-message-begin-regexp nil t))
-	  (goto-char (point-max)))))
+	  (goto-char (point-max))))))
+
+(defun notmuch-show-archive-thread-maybe-mark-read (markread)
+  (notmuch-show-forall-in-thread
+      (if markread
+	  (notmuch-show-remove-tag "unread" "inbox")
+	(notmuch-show-remove-tag "inbox")))
   (let ((parent-buffer notmuch-show-parent-buffer))
     (kill-this-buffer)
     (if parent-buffer
-- 
1.6.5


This first patch is helpful for factorizing out code. Basically, it allows to
apply a "message-only" command to all the thread.

From 0073152e3fa7dd11d88de28e87eec7762cdbbbeb Mon Sep 17 00:00:00 2001
From: Matthieu Lemerre <racin@racin.rez-gif.supelec.fr>
Date: Thu, 25 Feb 2010 00:25:51 +0100
Subject: [PATCH 2/2] Add support for deletion in the emacs interface

---
 notmuch.el |   56 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index 5d7342a..0285573 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -92,6 +92,8 @@
     (define-key map "x" 'notmuch-show-archive-thread-then-exit)
     (define-key map "A" 'notmuch-show-mark-read-then-archive-thread)
     (define-key map "a" 'notmuch-show-archive-thread)
+    (define-key map "d" 'notmuch-show-delete-thread)
+    (define-key map "D" 'notmuch-show-delete-message)
     (define-key map "p" 'notmuch-show-previous-message)
     (define-key map "N" 'notmuch-show-mark-read-then-next-open-message)
     (define-key map "n" 'notmuch-show-next-message)
@@ -380,6 +382,23 @@ buffer."
   (notmuch-show-archive-thread)
   (kill-this-buffer))
 
+(defun notmuch-show-delete-message ()
+  "Delete current message (sets its deleted tag)."
+  (interactive)
+  (notmuch-show-add-tag "deleted"))
+
+(defun notmuch-show-delete-thread()
+  "Delete each message in thread."
+  (interactive)
+  (notmuch-show-forall-in-thread
+   (notmuch-show-delete-message)))
+
+(defun notmuch-show-delete-thread-and-exit()
+  "Delete each message in thread, then exit back to search results."
+  (interactive)
+  (notmuch-show-delete-thread)
+  (kill-this-buffer))
+
 (defun notmuch-show-mark-read-then-archive-then-exit ()
   "Remove unread tags from thread, then archive and exit to search results."
   (interactive)
@@ -1227,6 +1246,7 @@ matching this search term are shown if non-nil. "
     (define-key map [mouse-1] 'notmuch-search-show-thread)
     (define-key map "*" 'notmuch-search-operate-all)
     (define-key map "a" 'notmuch-search-archive-thread)
+    (define-key map "d" 'notmuch-search-delete-thread)
     (define-key map "-" 'notmuch-search-remove-tag)
     (define-key map "+" 'notmuch-search-add-tag)
     (define-key map (kbd "RET") 'notmuch-search-show-thread)
@@ -1235,6 +1255,7 @@ matching this search term are shown if non-nil. "
 (fset 'notmuch-search-mode-map notmuch-search-mode-map)
 
 (defvar notmuch-search-query-string)
+(defvar notmuch-search-history nil)
 (defvar notmuch-search-oldest-first t
   "Show the oldest mail first in the search-mode")
 
@@ -1446,6 +1467,13 @@ This function advances the next thread when finished."
   (notmuch-search-remove-tag "inbox")
   (forward-line))
 
+(defun notmuch-search-delete-thread ()
+  "Mark the currently selected thread as deleted (set its \"deleted\" tag).
+This function advances the next thread when finished."
+  (interactive)
+  (notmuch-search-add-tag "deleted")
+  (forward-line))
+
 (defun notmuch-search-process-sentinel (proc msg)
   "Add a message to let user know when \"notmuch search\" exits"
   (let ((buffer (process-buffer proc))
@@ -1520,10 +1548,22 @@ characters as well as `_.+-'.
 	   (append action-split (list notmuch-search-query-string) nil))))
 
 ;;;###autoload
-(defun notmuch-search (query &optional oldest-first)
-  "Run \"notmuch search\" with the given query string and display results."
-  (interactive "sNotmuch search: ")
-  (let ((buffer (get-buffer-create (concat "*notmuch-search-" query "*"))))
+(defun notmuch-search (query &optional oldest-first include-deleted)
+  "Run \"notmuch search\" with the given query string and display results.
+
+With prefix argument, include deleted items.
+"
+  (interactive (let* ((prefix current-prefix-arg)
+		      (query (if prefix
+				 (read-string "Notmuch search (including deleted): "
+					      notmuch-search-query-string
+					      'notmuch-search-history)
+			       (read-string "Notmuch search: " nil
+					    'notmuch-search-history))))
+		 (list query nil prefix)))
+  (let ((real-query (if include-deleted query 
+		      (concat "not tag:deleted and (" query ")")))
+	(buffer (get-buffer-create (concat "*notmuch-search-" query "*"))))
     (switch-to-buffer buffer)
     (notmuch-search-mode)
     (set 'notmuch-search-query-string query)
@@ -1539,7 +1579,7 @@ characters as well as `_.+-'.
 	(let ((proc (start-process-shell-command
 		     "notmuch-search" buffer notmuch-command "search"
 		     (if oldest-first "--sort=oldest-first" "--sort=newest-first")
-		     (shell-quote-argument query))))
+		     (shell-quote-argument real-query))))
 	  (set-process-sentinel proc 'notmuch-search-process-sentinel)
 	  (set-process-filter proc 'notmuch-search-process-filter))))
     (run-hooks 'notmuch-search-hook)))
@@ -1587,7 +1627,7 @@ search."
 
 Runs a new search matching only messages that match both the
 current search results AND the additional query string provided."
-  (interactive "sFilter search: ")
+  (interactive "sFilter search:")
   (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)))
 
@@ -1630,7 +1670,9 @@ current search results AND that are tagged with the given tag."
 
 (fset 'notmuch-folder-mode-map notmuch-folder-mode-map)
 
-(defcustom notmuch-folders (quote (("inbox" . "tag:inbox") ("unread" . "tag:unread")))
+(defcustom notmuch-folders (quote (("inbox" . "tag:inbox") 
+				   ("unread" . "tag:unread")
+				   ("deleted" . "tag:deleted")))
   "List of searches for the notmuch folder view"
   :type '(alist :key-type (string) :value-type (string))
   :group 'notmuch)
-- 
1.6.5


This second patch is the reworked patch, after your comments.

> A couple of minor comments on the patch:
> 
> >      (define-key map "a" 'notmuch-search-archive-thread)
> > +    (define-key map "d" 'notmuch-search-mark-as-deleted)
> 
> For consistency, let's name this notmuch-search-delete-thread.
> 
> And we'll probably want a notmuch-show-delete-message function as well,
> no?

Did both. I have however a question: how to handle in the UI the
thread/message distinction? For now, I set "d" in notmuch-show buffer
to act as "delete the current thread", and "D" as "delete the current
message". I thought that as "d" meant in notmuch summary "delete the
current thread", the bindings would be more consistent.  But now I
wonder if this may be counter intuitive, and if we should use "d" for
"delete current message" and "D" for "delete current thread". What do
people think?

It would be nice to have, in general a convenient way to handle the
thread/message distinction in the UI (e.g. for applying other tags).

> 
> > +(defvar notmuch-search-history nil)
> 
> Excellent! I've wanted custom search history for a while, and just
> didn't know how to do it with (interactive "s"). It looks easy enough
> with read-string as you're doing here. But this is independent
> functionality, so would be preferred as an independent patch/commit.

In fact I needed this; that way when you do "C-u s", the previous
search is shown, and to include deleted items you just have to do "C-u
s RET".  So I made them in a single commit; but I can split them if
you really want to.

> 
> >    (forward-line))
> >  
> > +
> > +(defun notmuch-search-mark-as-deleted ()
> > +  "Mark the currently selected thread as deleted (set its \"deleted\" tag).
> > +This function advances the next thread when finished."
> > +  (interactive)
> > +  (notmuch-search-add-tag "deleted")
> > +  (forward-line))
> > +
> > +
> >  (defun notmuch-search-process-sentinel (proc msg)
> 
> Watch that extra whitespace. The convention is a single line of
> whitespace between each function.
> 

My bad. I did not see this in my review. Corrected this in the updated patch.

> And should we also archive the thread before removing the deleted tag?

I don't understand this. Do you mean: should we also archive the
thread before setting the deleted tag? I don't known why we should
bother to do it, as the tag is not show by the next results. 

I would tend to think that archiving should be an explicit action,
that should call a hook. For instance, I'd like my mailflow to be like
this:

- get mail with offlineimap => a maildir directory, indexed by notmuch

- mails stay in inbox until I archive it. That way I can still access
  it with IMAP.

- archiving puts an "archived" tag (and removes the inbox and unread
  tags), and move the mail to another directory (or uses git to
  archive the mail).

- deleting puts a deleted tag (but the messages stays inbox as long as
  I do not explicitely remove this).

The main reason is that many mail servers only allow small quotas, so
you have to carefully select which mail should stay inbox (only the
mail that you need external access).

In brief, this mail flow needs to delete threads but not to archive
it. I think that we could provide hooks, so that you can archive
mails when you delete them if you like to.

By the way in my patch commentary, you said that you planned to change
the "inbox" and "unread" treatments to be more explicit. Do you still
plan to do that? I can maybe also provide a patch.

> > +With prefix argument, include deleted items.
> 
> That's a pretty good interface I think.
> 
> Another approach would be to do something like what sup does---that
> would be to scan the search terms and if it contains "tag:deleted" and
> all then don't prepend the "not tag:deleted and" to the search
> string. The assumption there is that if the user is explicitly
> mentioning the deleted tag, then we should just rely on the user to
> explicitly describe how the tag should be treated.
> 
> That's perhaps not an unreasonable heuristic, and might be done even in
> addition to the prefix-argument approach. But that could be an
> additional commit, and I won't require it.

Hmm, that's what I did want to do initially. In that case, I think
that notmuch should be able to output parse trees from notmuch search
strings as JSON; this would help do the parsing in the various
implementations.

I also had this idea that may solve the "tag should be
orthogonal/command-line UI problem". We observe that "archived" is
contrary to "inbox", "read" contrary to "unread", "deleted" contrary
to "undeleted", and so on.

So it may be a good idea to have "pseudo-tags", that would help in the
interface (searching archived mails with search not tag:inbox is not
very intuitive...), as synonyms for "not tag:countrary-tag"

Then for each "pseudo-tag", notmuch could hard-code which is included
by default. Adding the other tags is easy: just add "and tag:deleted"
or "and tag:read" or "and tag:archived". Moreover, this would simplify
UI implementation as well, without requiring parsing of the strings.

Another, even simpler possibility would be to add a "--all" flag to
notmuch. Without it, it would omit some of the tags (like the deleted
ones), which would be convenient as a text interface. With it, it
would show all tags, which would be convenient for use with scripts
and UI, and mor in the "tags are orthogonal" spirit. Again, this would
not require to parse search strings, and imho would be much cleaner.

> > +  (interactive (let* ((prefix current-prefix-arg)
> > +                      (query (if prefix
> > +                                 (read-string "Notmuch search (including deleted): "
> > +                                              notmuch-search-query-string
> > +                                              'notmuch-search-history)
> > +                               (read-string "Notmuch search: " nil
> > +                                            'notmuch-search-history))))
> 
> Why is the second (initial-input) argument non-nil in one case, but nil
> in the other? The documentation for `read-string' says the argument is
> deprecated and should be nil in all new code.

The idea is that you do not have default search terms if you do
regular searchs. But if you want to include deleted items, then you
have the last search string. This way, you handle the common case when
you serach for a term, do not find it, then decide to try again with
deleted items.

Now, maybe the C-u interface is not such a good idea, and a toggle
button would be better. Don't know, but I find this interface
convenient.

> 
> > +                 (list query nil prefix)))
> > +  (let ((real-query (if include-deleted query
> > +                      (concat "not tag:deleted and (" query ")")))
> > +        (buffer (get-buffer-create (concat "*notmuch-search-" query
> > "*"))))
> 
> Does the include-deleted case actually work? I don't see anything in the
> code that sets this variable. (I'm just reviewing here--I haven't tested
> it manually).

This is the way interactive work.
(defun notmuch-search (query &optional oldest-first include-deleted)
...
+  (interactive (let* ((prefix current-prefix-arg)
...
+		 (list query nil prefix)))

The (list query nil prefix) at the end of the (interactive) form will
set query to query, nil to oldest-first, and prefix to
include-deleted.

> 
> > @@ -1351,7 +1374,6 @@ search."
> >  
> >  Runs a new search matching only messages that match both the
> >  current search results AND the additional query string provided."
> > -  (interactive "sFilter search: ")
> >    (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)))
> 
> Is this just an accidental chunk in the patch? I don't see why this
> function should become non-interactive now.

My bad, corrected that also.

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

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

* Re: [PATCH] Support for deletion (patch included)
       [not found] <1427711643.5760731267266834921.JavaMail.root@zimbra1-e1.priv.proxad.net>
@ 2010-02-27 10:34 ` racin
  0 siblings, 0 replies; 7+ messages in thread
From: racin @ 2010-02-27 10:34 UTC (permalink / raw)
  To: Carl Worth; +Cc: notmuch

[-- Attachment #1: Type: text/plain, Size: 804 bytes --]

Here they are; as I don't know how to include them in the body, I put the patches as attachments. I hope this 
will be convienient enough for you.


Matthieu

----- racin@free.fr a écrit :

> Carl: The patch in the mail has problems; apparently I have to
> manually add scissorlines to the mail for it
> to be processed by git-am. I thought this was automatically added. (I
> hate the git UI -- nothing is consistent,
> concepts have different names, the definition of scissor lines is as
> precise as "A line that mainly consists of scissors (either ">8" or
> "8<") and perforation (dash "-") --, but I guess we can get used to it
> after a while...)
> 
> I'll send you a proper patch as soon as I can. Meanwhile, I'm sure you
> have comments on this updated patch!
> 
> Matthieu
>

[-- Attachment #2: 0002-Add-support-for-deletion-in-the-emacs-interface.patch --]
[-- Type: text/x-diff, Size: 5933 bytes --]

From 0073152e3fa7dd11d88de28e87eec7762cdbbbeb Mon Sep 17 00:00:00 2001
From: Matthieu Lemerre <racin@free.fr>
Date: Thu, 25 Feb 2010 00:25:51 +0100
Subject: [PATCH 2/2] Add support for deletion in the emacs interface

Add "d" keybinding in notmuch-show and notmuch-summary to delete the current
thread. Adds "D" keybinding to delete the current message in notmuch-show.
Adds a "deleted" folder. Omit deleted items from searchs if no prefix arg.
Adds history management to make searching deleted items more convenient.

---
 notmuch.el |   56 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index 5d7342a..0285573 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -92,6 +92,8 @@
     (define-key map "x" 'notmuch-show-archive-thread-then-exit)
     (define-key map "A" 'notmuch-show-mark-read-then-archive-thread)
     (define-key map "a" 'notmuch-show-archive-thread)
+    (define-key map "d" 'notmuch-show-delete-thread)
+    (define-key map "D" 'notmuch-show-delete-message)
     (define-key map "p" 'notmuch-show-previous-message)
     (define-key map "N" 'notmuch-show-mark-read-then-next-open-message)
     (define-key map "n" 'notmuch-show-next-message)
@@ -380,6 +382,23 @@ buffer."
   (notmuch-show-archive-thread)
   (kill-this-buffer))
 
+(defun notmuch-show-delete-message ()
+  "Delete current message (sets its deleted tag)."
+  (interactive)
+  (notmuch-show-add-tag "deleted"))
+
+(defun notmuch-show-delete-thread()
+  "Delete each message in thread."
+  (interactive)
+  (notmuch-show-forall-in-thread
+   (notmuch-show-delete-message)))
+
+(defun notmuch-show-delete-thread-and-exit()
+  "Delete each message in thread, then exit back to search results."
+  (interactive)
+  (notmuch-show-delete-thread)
+  (kill-this-buffer))
+
 (defun notmuch-show-mark-read-then-archive-then-exit ()
   "Remove unread tags from thread, then archive and exit to search results."
   (interactive)
@@ -1227,6 +1246,7 @@ matching this search term are shown if non-nil. "
     (define-key map [mouse-1] 'notmuch-search-show-thread)
     (define-key map "*" 'notmuch-search-operate-all)
     (define-key map "a" 'notmuch-search-archive-thread)
+    (define-key map "d" 'notmuch-search-delete-thread)
     (define-key map "-" 'notmuch-search-remove-tag)
     (define-key map "+" 'notmuch-search-add-tag)
     (define-key map (kbd "RET") 'notmuch-search-show-thread)
@@ -1235,6 +1255,7 @@ matching this search term are shown if non-nil. "
 (fset 'notmuch-search-mode-map notmuch-search-mode-map)
 
 (defvar notmuch-search-query-string)
+(defvar notmuch-search-history nil)
 (defvar notmuch-search-oldest-first t
   "Show the oldest mail first in the search-mode")
 
@@ -1446,6 +1467,13 @@ This function advances the next thread when finished."
   (notmuch-search-remove-tag "inbox")
   (forward-line))
 
+(defun notmuch-search-delete-thread ()
+  "Mark the currently selected thread as deleted (set its \"deleted\" tag).
+This function advances the next thread when finished."
+  (interactive)
+  (notmuch-search-add-tag "deleted")
+  (forward-line))
+
 (defun notmuch-search-process-sentinel (proc msg)
   "Add a message to let user know when \"notmuch search\" exits"
   (let ((buffer (process-buffer proc))
@@ -1520,10 +1548,22 @@ characters as well as `_.+-'.
 	   (append action-split (list notmuch-search-query-string) nil))))
 
 ;;;###autoload
-(defun notmuch-search (query &optional oldest-first)
-  "Run \"notmuch search\" with the given query string and display results."
-  (interactive "sNotmuch search: ")
-  (let ((buffer (get-buffer-create (concat "*notmuch-search-" query "*"))))
+(defun notmuch-search (query &optional oldest-first include-deleted)
+  "Run \"notmuch search\" with the given query string and display results.
+
+With prefix argument, include deleted items.
+"
+  (interactive (let* ((prefix current-prefix-arg)
+		      (query (if prefix
+				 (read-string "Notmuch search (including deleted): "
+					      notmuch-search-query-string
+					      'notmuch-search-history)
+			       (read-string "Notmuch search: " nil
+					    'notmuch-search-history))))
+		 (list query nil prefix)))
+  (let ((real-query (if include-deleted query 
+		      (concat "not tag:deleted and (" query ")")))
+	(buffer (get-buffer-create (concat "*notmuch-search-" query "*"))))
     (switch-to-buffer buffer)
     (notmuch-search-mode)
     (set 'notmuch-search-query-string query)
@@ -1539,7 +1579,7 @@ characters as well as `_.+-'.
 	(let ((proc (start-process-shell-command
 		     "notmuch-search" buffer notmuch-command "search"
 		     (if oldest-first "--sort=oldest-first" "--sort=newest-first")
-		     (shell-quote-argument query))))
+		     (shell-quote-argument real-query))))
 	  (set-process-sentinel proc 'notmuch-search-process-sentinel)
 	  (set-process-filter proc 'notmuch-search-process-filter))))
     (run-hooks 'notmuch-search-hook)))
@@ -1587,7 +1627,7 @@ search."
 
 Runs a new search matching only messages that match both the
 current search results AND the additional query string provided."
-  (interactive "sFilter search: ")
+  (interactive "sFilter search:")
   (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)))
 
@@ -1630,7 +1670,9 @@ current search results AND that are tagged with the given tag."
 
 (fset 'notmuch-folder-mode-map notmuch-folder-mode-map)
 
-(defcustom notmuch-folders (quote (("inbox" . "tag:inbox") ("unread" . "tag:unread")))
+(defcustom notmuch-folders (quote (("inbox" . "tag:inbox") 
+				   ("unread" . "tag:unread")
+				   ("deleted" . "tag:deleted")))
   "List of searches for the notmuch folder view"
   :type '(alist :key-type (string) :value-type (string))
   :group 'notmuch)
-- 
1.6.5


[-- Attachment #3: 0001-Add-and-use-notmuch-show-forall-in-thread-macro.patch --]
[-- Type: text/x-diff, Size: 1580 bytes --]

From bdee9558d93bffb97c80632f522288e059deb7c2 Mon Sep 17 00:00:00 2001
From: Matthieu Lemerre <racin@free.fr>
Date: Thu, 25 Feb 2010 00:24:24 +0100
Subject: [PATCH 1/2] Add and use notmuch-show-forall-in-thread macro

This macro allows to apply a message-related command to every message
in a thread.

---
 notmuch.el |   17 +++++++++++------
 1 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index 6482170..5d7342a 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -321,17 +321,22 @@ pseudoheader summary"
 			 (cons (notmuch-show-get-message-id) nil)))
 	  (notmuch-show-set-tags (sort (set-difference tags toremove :test 'string=) 'string<))))))
 
-(defun notmuch-show-archive-thread-maybe-mark-read (markread)
-  (save-excursion
+(defmacro notmuch-show-forall-in-thread (&rest body)
+  "Executes BODY with point in all messages of the current thread."
+  `(save-excursion
     (goto-char (point-min))
     (while (not (eobp))
-      (if markread
-	  (notmuch-show-remove-tag "unread" "inbox")
-	(notmuch-show-remove-tag "inbox"))
+      ,@body
       (if (not (eobp))
 	  (forward-char))
       (if (not (re-search-forward notmuch-show-message-begin-regexp nil t))
-	  (goto-char (point-max)))))
+	  (goto-char (point-max))))))
+
+(defun notmuch-show-archive-thread-maybe-mark-read (markread)
+  (notmuch-show-forall-in-thread
+      (if markread
+	  (notmuch-show-remove-tag "unread" "inbox")
+	(notmuch-show-remove-tag "inbox")))
   (let ((parent-buffer notmuch-show-parent-buffer))
     (kill-this-buffer)
     (if parent-buffer
-- 
1.6.5


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

* Re: [PATCH] Support for deletion (patch included)
  2010-02-25  0:00   ` racin
  2010-02-25 10:49     ` Sebastian Spaeth
@ 2010-03-01  9:09     ` Michal Sojka
  1 sibling, 0 replies; 7+ messages in thread
From: Michal Sojka @ 2010-03-01  9:09 UTC (permalink / raw)
  To: racin, Carl Worth; +Cc: notmuch

On Thu, 25 Feb 2010 01:00:04 +0100 (CET), racin@free.fr wrote:
> Hi Carl,
> 
> > Could you also write a commit message describing what the patch does?
> > The easiest way for me to apply that would be if you would create a git
> > commit, then run "git format-patch origin/master" and mail the resulting
> > files, (the "git send-email" command can be used here, or you can insert
> > the files into a mail-composition buffer and modify them as needed).
> > 
> 
> OK, here it is (comments below). I had trouble splitting the patches into a patch series; I
> found git add -p, but isn't there a better interface for selecting
> patches?

What about "git gui"?

Michal

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

end of thread, other threads:[~2010-03-01  9:09 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1427711643.5760731267266834921.JavaMail.root@zimbra1-e1.priv.proxad.net>
2010-02-27 10:34 ` [PATCH] Support for deletion (patch included) racin
     [not found] <829811857.5353531267112884804.JavaMail.root@zimbra1-e1.priv.proxad.net>
2010-02-25 15:51 ` racin
2009-12-13 11:54 Matthieu Lemerre
2010-02-24 18:49 ` Carl Worth
2010-02-25  0:00   ` racin
2010-02-25 10:49     ` Sebastian Spaeth
2010-03-01  9:09     ` Michal Sojka

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).