Re: [PATCH 9/9] add has: query prefix to search for specific properties
[notmuch-archives.git] / 7a / 9481f36c78f4258b9fed70fa6bbc07091ff36b
1 Return-Path: <amdragon@mit.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 3B0D0431FBD\r
6         for <notmuch@notmuchmail.org>; Sat, 14 Jul 2012 16:02:28 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -0.7\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
12         tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\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 VLW9yq+XE6wt for <notmuch@notmuchmail.org>;\r
16         Sat, 14 Jul 2012 16:02:27 -0700 (PDT)\r
17 Received: from dmz-mailsec-scanner-6.mit.edu (DMZ-MAILSEC-SCANNER-6.MIT.EDU\r
18         [18.7.68.35])\r
19         by olra.theworths.org (Postfix) with ESMTP id 9F019431FBC\r
20         for <notmuch@notmuchmail.org>; Sat, 14 Jul 2012 16:02:26 -0700 (PDT)\r
21 X-AuditID: 12074423-b7f396d0000008f4-d7-5001fa82b116\r
22 Received: from mailhub-auth-1.mit.edu ( [18.9.21.35])\r
23         by dmz-mailsec-scanner-6.mit.edu (Symantec Messaging Gateway) with SMTP\r
24         id 85.26.02292.28AF1005; Sat, 14 Jul 2012 19:02:26 -0400 (EDT)\r
25 Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103])\r
26         by mailhub-auth-1.mit.edu (8.13.8/8.9.2) with ESMTP id q6EN2PjU015442; \r
27         Sat, 14 Jul 2012 19:02:25 -0400\r
28 Received: from drake.dyndns.org\r
29         (209-6-116-242.c3-0.arl-ubr1.sbo-arl.ma.cable.rcn.com\r
30         [209.6.116.242]) (authenticated bits=0)\r
31         (User authenticated as amdragon@ATHENA.MIT.EDU)\r
32         by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id q6EN2NrC008492\r
33         (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT);\r
34         Sat, 14 Jul 2012 19:02:24 -0400 (EDT)\r
35 Received: from amthrax by drake.dyndns.org with local (Exim 4.77)\r
36         (envelope-from <amdragon@mit.edu>)\r
37         id 1SqBLz-0002G1-Md; Sat, 14 Jul 2012 19:02:23 -0400\r
38 From: Austin Clements <amdragon@MIT.EDU>\r
39 To: notmuch@notmuchmail.org\r
40 Subject: [PATCH v3 0/8] emacs: JSON-based search cleanups\r
41 Date: Sat, 14 Jul 2012 19:02:12 -0400\r
42 Message-Id: <1342306940-7499-1-git-send-email-amdragon@mit.edu>\r
43 X-Mailer: git-send-email 1.7.10\r
44 In-Reply-To: <1342140319-19859-1-git-send-email-amdragon@mit.edu>\r
45 References: <1342140319-19859-1-git-send-email-amdragon@mit.edu>\r
46 X-Brightmail-Tracker:\r
47  H4sIAAAAAAAAA+NgFjrCIsWRmVeSWpSXmKPExsUixCmqrNv0izHA4MoOFos9+7wsVs/lsbh+\r
48         cyazA7PH3dNcHjtn3WX3eLbqFnMAcxSXTUpqTmZZapG+XQJXxq+Tn1gL+vUqmne0sTYwvlLp\r
49         YuTkkBAwkfi+4xgThC0mceHeerYuRi4OIYF9jBL/pjxih3A2MEpsnXKcEaRKSOARk8SP2fIQ\r
50         ibmMEg9v7mIDSbAJaEhs278crEhEQFpi593ZrCA2s4ClxPfWe2BxYSD73vQ/YOtYBFQlNm/t\r
51         ZQaxeQXsJTpOH2GGOENe4un9PrCZnAKOEhu+XGCFWOwg0XhsJvMERv4FjAyrGGVTcqt0cxMz\r
52         c4pTk3WLkxPz8lKLdM30cjNL9FJTSjcxggKL3UV5B+Ofg0qHGAU4GJV4eJP8GQKEWBPLiitz\r
53         DzFKcjApifK+/skYIMSXlJ9SmZFYnBFfVJqTWnyIUYKDWUmEV+IrUI43JbGyKrUoHyYlzcGi\r
54         JM57LeWmv5BAemJJanZqakFqEUxWhoNDSYL3FchQwaLU9NSKtMycEoQ0EwcnyHAeoOEnQWp4\r
55         iwsSc4sz0yHypxgVpcQhEgIgiYzSPLheWOS/YhQHekWY9yFIFQ8wacB1vwIazAQ0eNbPf/5A\r
56         g0sSEVJSDYy8DF9dnI68Zzsh80js2AK99fUv/RuUs+8XLYxZeGJeYdKl/y5n06NnVGYzKJ++\r
57         w7/2ngnfnGoLQ+NZhvw3Fz54WLN4OzvjPolpoXa5oknJzr/+WFrJzG9at1SO2ZF3y8Q/kxZO\r
58         ODs368Hlr96hmteTfkaETO6+159+XcPfg5Etyqg43eB0+HclluKMREMt5qLiRADK7bRy1wIA        AA==\r
59 X-BeenThere: notmuch@notmuchmail.org\r
60 X-Mailman-Version: 2.1.13\r
61 Precedence: list\r
62 List-Id: "Use and development of the notmuch mail system."\r
63         <notmuch.notmuchmail.org>\r
64 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
65         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
66 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
67 List-Post: <mailto:notmuch@notmuchmail.org>\r
68 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
69 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
70         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
71 X-List-Received-Date: Sat, 14 Jul 2012 23:02:28 -0000\r
72 \r
73 This version swaps out the notmuch-search-do-results macro for a\r
74 higher-order function, notmuch-search-foreach-result.  This requires\r
75 less squiting to understand and clearly distinguishes the arguments\r
76 passed in to the function from the arguments passed to the callback.\r
77 This version also updates the docstring for\r
78 notmuch-search-result-format to mention that multi-line result formats\r
79 work and how to enter them, and it adds a NEWS patch.\r
80 \r
81 Diff from v2:\r
82 \r
83 diff --git a/NEWS b/NEWS\r
84 index a1a6e93..7b33f0d 100644\r
85 --- a/NEWS\r
86 +++ b/NEWS\r
87 @@ -17,6 +17,20 @@ Maildir tag synchronization\r
88  Emacs Interface\r
89  ---------------\r
90  \r
91 +Search results now get re-colored when tags are updated\r
92 +\r
93 +The formatting of tags in search results can now be customized\r
94 +\r
95 +  Previously, attempting to change the format of tags in\r
96 +  `notmuch-search-result-format` would usually break tagging from\r
97 +  search-mode.  We no longer make assumptions about the format.\r
98 +\r
99 +Multi-line search result formats are now supported\r
100 +\r
101 +  It is now possible to embed newlines in\r
102 +  `notmuch-search-result-format` to make individual search results\r
103 +  span multiple lines.\r
104 +\r
105  Search now uses the JSON format internally\r
106  \r
107    This should address problems with unusual characters in authors and\r
108 diff --git a/emacs/notmuch.el b/emacs/notmuch.el\r
109 index 7302fa7..ec760dc 100644\r
110 --- a/emacs/notmuch.el\r
111 +++ b/emacs/notmuch.el\r
112 @@ -69,7 +69,13 @@\r
113         date, count, authors, subject, tags\r
114  For example:\r
115         (setq notmuch-search-result-format \(\(\"authors\" . \"%-40s\"\)\r
116 -                                            \(\"subject\" . \"%s\"\)\)\)"\r
117 +                                            \(\"subject\" . \"%s\"\)\)\)\r
118 +Line breaks are permitted in format strings.  Note that a line\r
119 +break at the end of an \"authors\" field will get elided if the\r
120 +authors list is long; place it instead at the beginning of the\r
121 +following field.  To enter a line break when setting this\r
122 +variable with setq, use \\n.  To enter a line break in customize,\r
123 +press \\[quoted-insert] C-j."\r
124    :type '(alist :key-type (string) :value-type (string))\r
125    :group 'notmuch-search)\r
126  \r
127 @@ -433,32 +439,39 @@ returns nil"\r
128      (next-single-property-change (or pos (point)) 'notmuch-search-result\r
129                                  nil (point-max))))\r
130  \r
131 -(defmacro notmuch-search-do-results (beg end pos-sym &rest body)\r
132 -  "Invoke BODY for each result between BEG and END.\r
133 -\r
134 -POS-SYM will be bound to the point at the beginning of the\r
135 -current result."\r
136 -  (declare (indent 3))\r
137 -  (let ((end-sym (make-symbol "end"))\r
138 -       (first-sym (make-symbol "first")))\r
139 -    `(let ((,pos-sym (notmuch-search-result-beginning ,beg))\r
140 -          ;; End must be a marker in case body changes the text\r
141 -          (,end-sym (copy-marker ,end))\r
142 -          ;; Make sure we examine one result, even if (= beg end)\r
143 -          (,first-sym t))\r
144 -       ;; We have to be careful if the region extends beyond the\r
145 -       ;; results.  In this case, pos could be null or there could be\r
146 -       ;; no result at pos.\r
147 -       (while (and ,pos-sym (or (< ,pos-sym ,end-sym) ,first-sym))\r
148 -        (when (notmuch-search-get-result ,pos-sym)\r
149 -          ,@body)\r
150 -        (setq ,pos-sym (notmuch-search-result-end ,pos-sym)\r
151 -              ,first-sym nil)))))\r
152 +(defun notmuch-search-foreach-result (beg end function)\r
153 +  "Invoke FUNCTION for each result between BEG and END.\r
154 +\r
155 +FUNCTION should take one argument.  It will be applied to the\r
156 +character position of the beginning of each result that overlaps\r
157 +the region between points BEG and END.  As a special case, if (=\r
158 +BEG END), FUNCTION will be applied to the result containing point\r
159 +BEG."\r
160 +\r
161 +  (lexical-let ((pos (notmuch-search-result-beginning beg))\r
162 +               ;; End must be a marker in case function changes the\r
163 +               ;; text.\r
164 +               (end (copy-marker end))\r
165 +               ;; Make sure we examine at least one result, even if\r
166 +               ;; (= beg end).\r
167 +               (first t))\r
168 +    ;; We have to be careful if the region extends beyond the results.\r
169 +    ;; In this case, pos could be null or there could be no result at\r
170 +    ;; pos.\r
171 +    (while (and pos (or (< pos end) first))\r
172 +      (when (notmuch-search-get-result pos)\r
173 +       (funcall function pos))\r
174 +      (setq pos (notmuch-search-result-end pos)\r
175 +           first nil))))\r
176 +;; Unindent the function argument of notmuch-search-foreach-result so\r
177 +;; the indentation of callers doesn't get out of hand.\r
178 +(put 'notmuch-search-foreach-result 'lisp-indent-function 2)\r
179  \r
180  (defun notmuch-search-properties-in-region (property beg end)\r
181    (let (output)\r
182 -    (notmuch-search-do-results beg end pos\r
183 -      (push (plist-get (notmuch-search-get-result pos) property) output))\r
184 +    (notmuch-search-foreach-result beg end\r
185 +      (lambda (pos)\r
186 +       (push (plist-get (notmuch-search-get-result pos) property) output)))\r
187      output))\r
188  \r
189  (defun notmuch-search-find-thread-id ()\r
190 @@ -542,18 +555,20 @@ and will also appear in a buffer named \"*Notmuch errors*\"."\r
191  \r
192  (defun notmuch-search-get-tags-region (beg end)\r
193    (let (output)\r
194 -    (notmuch-search-do-results beg end pos\r
195 -      (setq output (append output (notmuch-search-get-tags pos))))\r
196 +    (notmuch-search-foreach-result beg end\r
197 +      (lambda (pos)\r
198 +       (setq output (append output (notmuch-search-get-tags pos)))))\r
199      output))\r
200  \r
201  (defun notmuch-search-tag-region (beg end &optional tag-changes)\r
202    "Change tags for threads in the given region."\r
203    (let ((search-string (notmuch-search-find-thread-id-region-search beg end)))\r
204      (setq tag-changes (funcall 'notmuch-tag search-string tag-changes))\r
205 -    (notmuch-search-do-results beg end pos\r
206 -      (notmuch-search-set-tags\r
207 -       (notmuch-update-tags (notmuch-search-get-tags pos) tag-changes)\r
208 -       pos))))\r
209 +    (notmuch-search-foreach-result beg end\r
210 +      (lambda (pos)\r
211 +       (notmuch-search-set-tags\r
212 +        (notmuch-update-tags (notmuch-search-get-tags pos) tag-changes)\r
213 +        pos)))))\r
214  \r
215  (defun notmuch-search-tag (&optional tag-changes)\r
216    "Change tags for the currently selected thread or region.\r
217 \r
218 \r