1 Return-Path: <prvs=jrosenthal=629a2d701@jhu.edu>
\r
2 X-Original-To: notmuch@notmuchmail.org
\r
3 Delivered-To: notmuch@notmuchmail.org
\r
4 Received: from localhost (localhost [127.0.0.1])
\r
5 by olra.theworths.org (Postfix) with ESMTP id 84CB9431FBC
\r
6 for <notmuch@notmuchmail.org>; Wed, 20 Jan 2010 13:58:15 -0800 (PST)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=-3.999 tagged_above=-999 required=5
\r
12 tests=[BAYES_50=0.001, RCVD_IN_DNSWL_MED=-4] autolearn=ham
\r
13 Received: from olra.theworths.org ([127.0.0.1])
\r
14 by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)
\r
15 with ESMTP id YxTNh47KGfg8 for <notmuch@notmuchmail.org>;
\r
16 Wed, 20 Jan 2010 13:58:14 -0800 (PST)
\r
17 X-Greylist: delayed 3603 seconds by postgrey-1.32 at olra;
\r
18 Wed, 20 Jan 2010 13:58:14 PST
\r
19 Received: from ipex1.johnshopkins.edu (ipex1.johnshopkins.edu [162.129.8.141])
\r
20 by olra.theworths.org (Postfix) with ESMTP id 631CE431FAE
\r
21 for <notmuch@notmuchmail.org>; Wed, 20 Jan 2010 13:58:14 -0800 (PST)
\r
22 X-IronPort-Anti-Spam-Filtered: true
\r
23 X-IronPort-Anti-Spam-Result: AsoEAG39VkuA3DZF/2dsb2JhbACQGwG9UIVJhnaCLoIIBA
\r
24 X-IronPort-AV: E=Sophos;i="4.49,312,1262581200"; d="scan'208";a="288755396"
\r
25 Received: from watt.gilman.jhu.edu ([128.220.54.69])
\r
26 by ipex1.johnshopkins.edu with ESMTP/TLS/ADH-AES256-SHA;
\r
27 20 Jan 2010 15:58:11 -0500
\r
28 Received: by watt.gilman.jhu.edu (Postfix, from userid 502)
\r
29 id B6C6A3E39C9; Wed, 20 Jan 2010 15:58:10 -0500 (EST)
\r
30 From: Jesse Rosenthal <jrosenthal@jhu.edu>
\r
31 To: notmuch@notmuchmail.org
\r
32 Date: Wed, 20 Jan 2010 15:58:10 -0500
\r
33 Message-ID: <m1636w7au5.fsf@watt.gilman.jhu.edu>
\r
35 Content-Type: text/plain; charset=us-ascii
\r
36 X-Mailman-Approved-At: Thu, 21 Jan 2010 01:01:16 -0800
\r
37 Cc: jrosenthal@jhu.edu
\r
38 Subject: [notmuch] [PATCH] notmuch.el: add functionality to add or remove
\r
40 X-BeenThere: notmuch@notmuchmail.org
\r
41 X-Mailman-Version: 2.1.13
\r
43 List-Id: "Use and development of the notmuch mail system."
\r
44 <notmuch.notmuchmail.org>
\r
45 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
46 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
47 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
48 List-Post: <mailto:notmuch@notmuchmail.org>
\r
49 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
50 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
51 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
52 X-List-Received-Date: Wed, 20 Jan 2010 21:58:15 -0000
\r
55 This patch adds `-region' versions of the `notmuch-search-' commands to find properties. It also splits up `notmuch-add/remove-tags' into both a `-thread' and a `-region' version. (This makes us modify `notmuch-search-archive-thread' to use the `notmuch-search-remove-tag-thread' function, instead of `notmuch-search-remove-tag', for consistency.) The add/remove-tag command called by pressing `+' or `-' will then choose accordingly, based on whether region is active.
\r
57 notmuch.el | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
\r
58 1 files changed, 84 insertions(+), 11 deletions(-)
\r
60 diff --git a/notmuch.el b/notmuch.el
\r
61 index 97914f2..e333f24 100644
\r
64 @@ -1117,18 +1117,41 @@ Complete list of currently available key bindings:
\r
65 (set (make-local-variable 'font-lock-defaults)
\r
66 '(notmuch-search-font-lock-keywords t)))
\r
68 +(defun notmuch-search-properties-in-region (property beg end)
\r
70 + (let ((output nil)
\r
71 + (last-line (line-number-at-pos end)))
\r
73 + (beginning-of-line)
\r
74 + (while (<= (line-number-at-pos) last-line)
\r
75 + (setq output (cons (get-text-property (point) property) output))
\r
79 (defun notmuch-search-find-thread-id ()
\r
80 "Return the thread for the current thread"
\r
81 (get-text-property (point) 'notmuch-search-thread-id))
\r
83 +(defun notmuch-search-find-thread-id-region (beg end)
\r
84 + "Return a list of threads for the current region"
\r
85 + (notmuch-search-properties-in-region 'notmuch-search-thread-id beg end))
\r
87 (defun notmuch-search-find-authors ()
\r
88 "Return the authors for the current thread"
\r
89 (get-text-property (point) 'notmuch-search-authors))
\r
91 +(defun notmuch-search-find-authors-region (beg end)
\r
92 + "Return a list of authors for the current region"
\r
93 + (notmuch-search-properties-in-region notmuch-search-authors beg end))
\r
95 (defun notmuch-search-find-subject ()
\r
96 "Return the subject for the current thread"
\r
97 (get-text-property (point) 'notmuch-search-subject))
\r
99 +(defun notmuch-search-find-subject-region (beg end)
\r
100 + "Return a list of authors for the current region"
\r
101 + (notmuch-search-properties-in-region notmuch-search-subject beg end))
\r
103 (defun notmuch-search-show-thread ()
\r
104 "Display the currently selected thread."
\r
106 @@ -1173,6 +1196,14 @@ and will also appear in a buffer named \"*Notmuch errors*\"."
\r
107 (delete-region beg end)
\r
108 (insert (mapconcat 'identity tags " "))))))
\r
110 +(defun notmuch-search-set-tags-region (tags beg end)
\r
112 + (let ((last-line (line-number-at-pos end)))
\r
114 + (while (<= (line-number-at-pos) last-line)
\r
115 + (notmuch-search-set-tags tags)
\r
116 + (forward-line)))))
\r
118 (defun notmuch-search-get-tags ()
\r
121 @@ -1182,32 +1213,74 @@ and will also appear in a buffer named \"*Notmuch errors*\"."
\r
122 (let ((end (- (point) 1)))
\r
123 (split-string (buffer-substring beg end))))))
\r
125 +(defun notmuch-search-get-tags-region (beg end)
\r
127 + (let ((output nil)
\r
128 + (last-line (line-number-at-pos end)))
\r
130 + (while (<= (line-number-at-pos) last-line)
\r
131 + (setq output (append output (notmuch-search-get-tags)))
\r
132 + (forward-line 1))
\r
135 +(defun notmuch-search-add-tag-thread (tag)
\r
136 + (notmuch-call-notmuch-process "tag" (concat "+" tag) (notmuch-search-find-thread-id))
\r
137 + (notmuch-search-set-tags (delete-dups (sort (cons tag (notmuch-search-get-tags)) 'string<))))
\r
139 +(defun notmuch-search-add-tag-region (tag beg end)
\r
140 + (let ((search-id-string (mapconcat 'identity (notmuch-search-find-thread-id-region beg end) " or ")))
\r
141 + (notmuch-call-notmuch-process "tag" (concat "+" tag) search-id-string)
\r
142 + (notmuch-search-set-tags-region (delete-dups (sort (cons tag (notmuch-search-get-tags-region beg end)) 'string<)) beg end)))
\r
144 +(defun notmuch-search-remove-tag-thread (tag)
\r
145 + (notmuch-call-notmuch-process "tag" (concat "-" tag) (notmuch-search-find-thread-id))
\r
146 + (notmuch-search-set-tags (delete tag (notmuch-search-get-tags))))
\r
148 +(defun notmuch-search-remove-tag-region (tag beg end)
\r
149 + (let ((search-id-string (mapconcat 'identity (notmuch-search-find-thread-id-region beg end) " or ")))
\r
150 + (notmuch-call-notmuch-process "tag" (concat "-" tag) search-id-string)
\r
151 + (notmuch-search-set-tags-region (delete tag (notmuch-search-get-tags-region beg end)) beg end)))
\r
153 (defun notmuch-search-add-tag (tag)
\r
154 - "Add a tag to the currently selected thread.
\r
155 + "Add a tag to the currently selected thread or region.
\r
157 -The tag is added to messages in the currently selected thread
\r
158 -which match the current search terms."
\r
159 +The tag is added to messages in the currently selected thread or
\r
160 +region which match the current search terms."
\r
162 (list (notmuch-select-tag-with-completion "Tag to add: ")))
\r
163 - (notmuch-call-notmuch-process "tag" (concat "+" tag) (notmuch-search-find-thread-id))
\r
164 - (notmuch-search-set-tags (delete-dups (sort (cons tag (notmuch-search-get-tags)) 'string<))))
\r
166 + (if (region-active-p)
\r
167 + (let* ((beg (region-beginning))
\r
168 + (end (region-end)))
\r
169 + (notmuch-search-add-tag-region tag beg end))
\r
170 + (notmuch-search-add-tag-thread tag))))
\r
172 (defun notmuch-search-remove-tag (tag)
\r
173 - "Remove a tag from the currently selected thread.
\r
174 + "Remove a tag from the currently selected thread or region.
\r
176 The tag is removed from messages in the currently selected thread
\r
177 -which match the current search terms."
\r
178 +or region which match the current search terms."
\r
180 - (list (notmuch-select-tag-with-completion "Tag to remove: " (notmuch-search-find-thread-id))))
\r
181 - (notmuch-call-notmuch-process "tag" (concat "-" tag) (notmuch-search-find-thread-id))
\r
182 - (notmuch-search-set-tags (delete tag (notmuch-search-get-tags))))
\r
183 + (list (notmuch-select-tag-with-completion
\r
184 + "Tag to remove: "
\r
185 + (if (region-active-p)
\r
186 + (mapconcat 'identity
\r
187 + (notmuch-search-find-thread-id-region (region-beginning) (region-end))
\r
189 + (notmuch-search-find-thread-id)))))
\r
191 + (if (region-active-p)
\r
192 + (let* ((beg (region-beginning))
\r
193 + (end (region-end)))
\r
194 + (notmuch-search-remove-tag-region tag beg end))
\r
195 + (notmuch-search-remove-tag-thread tag))))
\r
197 (defun notmuch-search-archive-thread ()
\r
198 "Archive the currently selected thread (remove its \"inbox\" tag).
\r
200 This function advances the next thread when finished."
\r
202 - (notmuch-search-remove-tag "inbox")
\r
203 + (notmuch-search-remove-tag-thread "inbox")
\r
206 (defun notmuch-search-process-sentinel (proc msg)
\r