Re: [feature request] emacs: use `notmuch insert` for FCC
[notmuch-archives.git] / 8f / ae9eed306fdf3fad36df9ebf5bf3b08a9479e0
1 Return-Path: <tomi.ollila@iki.fi>\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 4CD04431FC0\r
6         for <notmuch@notmuchmail.org>; Mon,  6 Oct 2014 11:56:31 -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\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]\r
12         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 iPIP+F4mailb for <notmuch@notmuchmail.org>;\r
16         Mon,  6 Oct 2014 11:56:27 -0700 (PDT)\r
17 Received: from guru.guru-group.fi (guru.guru-group.fi [46.183.73.34])\r
18         by olra.theworths.org (Postfix) with ESMTP id 42089431FBF\r
19         for <notmuch@notmuchmail.org>; Mon,  6 Oct 2014 11:56:27 -0700 (PDT)\r
20 Received: from guru.guru-group.fi (localhost [IPv6:::1])\r
21         by guru.guru-group.fi (Postfix) with ESMTP id 946B410009D;\r
22         Mon,  6 Oct 2014 21:56:11 +0300 (EEST)\r
23 From: Tomi Ollila <tomi.ollila@iki.fi>\r
24 To: Michal Sojka <sojkam1@fel.cvut.cz>, notmuch@notmuchmail.org\r
25 Subject: Re: [PATCH v2 2/4] cli: Extend the search command for\r
26         --output=addresses      and similar\r
27 In-Reply-To: <1412542319-20017-3-git-send-email-sojkam1@fel.cvut.cz>\r
28 References: <874mvqxrnp.fsf@nikula.org>\r
29         <1412542319-20017-1-git-send-email-sojkam1@fel.cvut.cz>\r
30         <1412542319-20017-3-git-send-email-sojkam1@fel.cvut.cz>\r
31 User-Agent: Notmuch/0.18.1+130~ga61922f (http://notmuchmail.org) Emacs/24.3.1\r
32         (x86_64-unknown-linux-gnu)\r
33 X-Face: HhBM'cA~<r"^Xv\KRN0P{vn'Y"Kd;zg_y3S[4)KSN~s?O\"QPoL\r
34         $[Xv_BD:i/F$WiEWax}R(MPS`^UaptOGD`*/=@\1lKoVa9tnrg0TW?"r7aRtgk[F\r
35         !)g;OY^,BjTbr)Np:%c_o'jj,Z\r
36 Date: Mon, 06 Oct 2014 21:56:11 +0300\r
37 Message-ID: <m24mvht4c4.fsf@guru.guru-group.fi>\r
38 MIME-Version: 1.0\r
39 Content-Type: text/plain; charset=utf-8\r
40 Content-Transfer-Encoding: quoted-printable\r
41 X-BeenThere: notmuch@notmuchmail.org\r
42 X-Mailman-Version: 2.1.13\r
43 Precedence: list\r
44 List-Id: "Use and development of the notmuch mail system."\r
45         <notmuch.notmuchmail.org>\r
46 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
47         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
48 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
49 List-Post: <mailto:notmuch@notmuchmail.org>\r
50 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
51 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
52         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
53 X-List-Received-Date: Mon, 06 Oct 2014 18:56:31 -0000\r
54 \r
55 On Sun, Oct 05 2014, Michal Sojka <sojkam1@fel.cvut.cz> wrote:\r
56 \r
57 > The new outputs allow printing senders, recipients or both of matching\r
58 > messages.\r
59 >\r
60 > This code based on a patch from Jani Nikula.\r
61 \r
62 OK, IMO...\r
63 \r
64 1/4 OK\r
65 \r
66 Before 2/4 add support for 'flag' arguments, drop the --output=3Daddresses\r
67 option which is now done as --output=3Dsender --output=3Drecipients\r
68 \r
69 \r
70 In deduplication comment did not describe the deduplication at all...\r
71 so I looked a bit into the code now... the Default you described was\r
72 that with "John Doe" <john.doe@example.com> and "John Doe" <JOHN.DOE@EXAMPL=\r
73 E.COM>=20\r
74 only one was printed (but not which one). Secondly, what happens\r
75 with "Doe, John" <john.doe@example.com> and "John Doe" <JOHN.DOE@EXAMPLE.CO=\r
76 M>...\r
77 ah, it is same as *addr* with case-insensitive address.\r
78 \r
79 Sorry, but IMO these options are a bit strange.\r
80 \r
81 Not to go to choose which one to choose (first, last, most common) instead\r
82 of the suggested options these should be the ones:\r
83 \r
84 1) "John Doe" <john.doe@example.com> and "John Doe" <JOHN.DOE@EXAMPLE.COM>:=\r
85 =20\r
86 only one printed, but if either were "Dr. John Doe", both of these are prin=\r
87 ted\r
88 (this as default).\r
89 \r
90 2) same as above, but only make case-insensitive address match -- i.e. in\r
91 the 2 above cases in option 1, print only one.\r
92 \r
93 (and same name but different address to perhaps never been an option...)\r
94 \r
95 I might like to have option that does case-sensitive address match, In\r
96 those cases I don't know the recipient's culture and the email he sent\r
97 to me used format <Foo.Bar@example.org> (and not knowing which one is the\r
98 first and which last name (or whatever names these are) -- just to reply\r
99 in same case format in respect...\r
100 \r
101 \r
102 Tomi\r
103 \r
104 \r
105 > ---\r
106 >  completion/notmuch-completion.bash |   2 +-\r
107 >  completion/notmuch-completion.zsh  |   3 +-\r
108 >  doc/man1/notmuch-search.rst        |  22 +++++++-\r
109 >  notmuch-search.c                   | 100 +++++++++++++++++++++++++++++++=\r
110 +++---\r
111 >  test/T090-search-output.sh         |  64 ++++++++++++++++++++++++\r
112 >  5 files changed, 182 insertions(+), 9 deletions(-)\r
113 >\r
114 > diff --git a/completion/notmuch-completion.bash b/completion/notmuch-comp=\r
115 letion.bash\r
116 > index 0571dc9..c37ddf5 100644\r
117 > --- a/completion/notmuch-completion.bash\r
118 > +++ b/completion/notmuch-completion.bash\r
119 > @@ -294,7 +294,7 @@ _notmuch_search()\r
120 >           return\r
121 >           ;;\r
122 >       --output)\r
123 > -         COMPREPLY=3D( $( compgen -W "summary threads messages files tags" -=\r
124 - "${cur}" ) )\r
125 > +         COMPREPLY=3D( $( compgen -W "summary threads messages files tags se=\r
126 nder recipients addresses" -- "${cur}" ) )\r
127 >           return\r
128 >           ;;\r
129 >       --sort)\r
130 > diff --git a/completion/notmuch-completion.zsh b/completion/notmuch-compl=\r
131 etion.zsh\r
132 > index 67a9aba..bff8fd5 100644\r
133 > --- a/completion/notmuch-completion.zsh\r
134 > +++ b/completion/notmuch-completion.zsh\r
135 > @@ -52,7 +52,8 @@ _notmuch_search()\r
136 >    _arguments -s : \\r
137 >      '--max-threads=3D[display only the first x threads from the search r=\r
138 esults]:number of threads to show: ' \\r
139 >      '--first=3D[omit the first x threads from the search results]:number=\r
140  of threads to omit: ' \\r
141 > -    '--sort=3D[sort results]:sorting:((newest-first\:"reverse chronologi=\r
142 cal order" oldest-first\:"chronological order"))'\r
143 > +    '--sort=3D[sort results]:sorting:((newest-first\:"reverse chronologi=\r
144 cal order" oldest-first\:"chronological order"))' \\r
145 > +    '--output=3D[select what to output]:output:((summary threads message=\r
146 s files tags sender recipients addresses))'\r
147 >  }\r
148 >=20=20\r
149 >  _notmuch()\r
150 > diff --git a/doc/man1/notmuch-search.rst b/doc/man1/notmuch-search.rst\r
151 > index 90160f2..3447820 100644\r
152 > --- a/doc/man1/notmuch-search.rst\r
153 > +++ b/doc/man1/notmuch-search.rst\r
154 > @@ -35,7 +35,7 @@ Supported options for **search** include\r
155 >          intended for programs that invoke **notmuch(1)** internally. If\r
156 >          omitted, the latest supported version will be used.\r
157 >=20=20\r
158 > -    ``--output=3D(summary|threads|messages|files|tags)``\r
159 > +    ``--output=3D(summary|threads|messages|files|tags|sender|recipients|=\r
160 addresses)``\r
161 >=20=20\r
162 >          **summary**\r
163 >              Output a summary of each thread with any message matching\r
164 > @@ -78,6 +78,26 @@ Supported options for **search** include\r
165 >              by null characters (--format=3Dtext0), as a JSON array\r
166 >              (--format=3Djson), or as an S-Expression list (--format=3Dse=\r
167 xp).\r
168 >=20=20\r
169 > +     **sender**\r
170 > +            Output all addresses from the *From* header that appear on\r
171 > +            any message matching the search terms, either one per line\r
172 > +            (--format=3Dtext), separated by null characters\r
173 > +            (--format=3Dtext0), as a JSON array (--format=3Djson), or as\r
174 > +            an S-Expression list (--format=3Dsexp).\r
175 > +\r
176 > +         Note: Searching for **sender** should be much faster than\r
177 > +         searching for **recipients** or **addresses**, because\r
178 > +         sender addresses are cached directly in the database\r
179 > +         whereas other addresses need to be fetched from message\r
180 > +         files.\r
181 > +\r
182 > +     **recipients**\r
183 > +            Like **sender** but for addresses from *To*, *Cc* and\r
184 > +         *Bcc* headers.\r
185 > +\r
186 > +     **addresses**\r
187 > +         Like **sender** and **recipients** together.\r
188 > +\r
189 >      ``--sort=3D``\ (**newest-first**\ \|\ **oldest-first**)\r
190 >          This option can be used to present results in either\r
191 >          chronological order (**oldest-first**) or reverse chronological\r
192 > diff --git a/notmuch-search.c b/notmuch-search.c\r
193 > index 5ac2a26..0614f10 100644\r
194 > --- a/notmuch-search.c\r
195 > +++ b/notmuch-search.c\r
196 > @@ -23,11 +23,14 @@\r
197 >  #include "string-util.h"\r
198 >=20=20\r
199 >  typedef enum {\r
200 > -    OUTPUT_SUMMARY,\r
201 > -    OUTPUT_THREADS,\r
202 > -    OUTPUT_MESSAGES,\r
203 > -    OUTPUT_FILES,\r
204 > -    OUTPUT_TAGS\r
205 > +    OUTPUT_SUMMARY   =3D 1 << 0,\r
206 > +    OUTPUT_THREADS   =3D 1 << 1,\r
207 > +    OUTPUT_MESSAGES  =3D 1 << 2,\r
208 > +    OUTPUT_FILES     =3D 1 << 3,\r
209 > +    OUTPUT_TAGS              =3D 1 << 4,\r
210 > +    OUTPUT_SENDER    =3D 1 << 5,\r
211 > +    OUTPUT_RECIPIENTS        =3D 1 << 6,\r
212 > +    OUTPUT_ADDRESSES =3D OUTPUT_SENDER | OUTPUT_RECIPIENTS,\r
213 >  } output_t;\r
214 >=20=20\r
215 >  typedef struct {\r
216 > @@ -220,6 +223,67 @@ do_search_threads (search_options_t *o)\r
217 >      return 0;\r
218 >  }\r
219 >=20=20\r
220 > +static void\r
221 > +print_address_list (const search_options_t *o, InternetAddressList *list)\r
222 > +{\r
223 > +    InternetAddress *address;\r
224 > +    int i;\r
225 > +\r
226 > +    for (i =3D 0; i < internet_address_list_length (list); i++) {\r
227 > +     address =3D internet_address_list_get_address (list, i);\r
228 > +     if (INTERNET_ADDRESS_IS_GROUP (address)) {\r
229 > +         InternetAddressGroup *group;\r
230 > +         InternetAddressList *group_list;\r
231 > +\r
232 > +         group =3D INTERNET_ADDRESS_GROUP (address);\r
233 > +         group_list =3D internet_address_group_get_members (group);\r
234 > +         if (group_list =3D=3D NULL)\r
235 > +             continue;\r
236 > +\r
237 > +         print_address_list (o, group_list);\r
238 > +     } else {\r
239 > +         InternetAddressMailbox *mailbox;\r
240 > +         const char *name;\r
241 > +         const char *addr;\r
242 > +         char *full_address;\r
243 > +\r
244 > +         mailbox =3D INTERNET_ADDRESS_MAILBOX (address);\r
245 > +\r
246 > +         name =3D internet_address_get_name (address);\r
247 > +         addr =3D internet_address_mailbox_get_addr (mailbox);\r
248 > +\r
249 > +         if (name && *name)\r
250 > +             full_address =3D talloc_asprintf (o->format, "%s <%s>", name, addr);\r
251 > +         else\r
252 > +             full_address =3D talloc_strdup (o->format, addr);\r
253 > +\r
254 > +         if (!full_address) {\r
255 > +             fprintf (stderr, "Error: out of memory\n");\r
256 > +             break;\r
257 > +         }\r
258 > +         o->format->string (o->format, full_address);\r
259 > +         o->format->separator (o->format);\r
260 > +\r
261 > +         talloc_free (full_address);\r
262 > +     }\r
263 > +    }\r
264 > +}\r
265 > +\r
266 > +static void\r
267 > +print_address_string (const search_options_t *o, const char *recipients)\r
268 > +{\r
269 > +    InternetAddressList *list;\r
270 > +\r
271 > +    if (recipients =3D=3D NULL)\r
272 > +     return;\r
273 > +\r
274 > +    list =3D internet_address_list_parse_string (recipients);\r
275 > +    if (list =3D=3D NULL)\r
276 > +     return;\r
277 > +\r
278 > +    print_address_list (o, list);\r
279 > +}\r
280 > +\r
281 >  static int\r
282 >  do_search_messages (search_options_t *o)\r
283 >  {\r
284 > @@ -266,11 +330,29 @@ do_search_messages (search_options_t *o)\r
285 >=20=20=09=20=20=20=20\r
286 >           notmuch_filenames_destroy( filenames );\r
287 >=20=20\r
288 > -     } else { /* output =3D=3D OUTPUT_MESSAGES */\r
289 > +     } else if (o->output =3D=3D OUTPUT_MESSAGES) {\r
290 >           format->set_prefix (format, "id");\r
291 >           format->string (format,\r
292 >                           notmuch_message_get_message_id (message));\r
293 >           format->separator (format);\r
294 > +     } else {\r
295 > +         if (o->output & OUTPUT_SENDER) {\r
296 > +             const char *addrs;\r
297 > +\r
298 > +             addrs =3D notmuch_message_get_header (message, "from");\r
299 > +             print_address_string (o, addrs);\r
300 > +         }\r
301 > +\r
302 > +         if (o->output & OUTPUT_RECIPIENTS) {\r
303 > +             const char *hdrs[] =3D { "to", "cc", "bcc" };\r
304 > +             const char *addrs;\r
305 > +             size_t j;\r
306 > +\r
307 > +             for (j =3D 0; j < ARRAY_SIZE (hdrs); j++) {\r
308 > +                 addrs =3D notmuch_message_get_header (message, hdrs[j]);\r
309 > +                 print_address_string (o, addrs);\r
310 > +             }\r
311 > +         }\r
312 >       }\r
313 >=20=20\r
314 >       notmuch_message_destroy (message);\r
315 > @@ -370,6 +452,9 @@ notmuch_search_command (notmuch_config_t *config, int=\r
316  argc, char *argv[])\r
317 >         (notmuch_keyword_t []){ { "summary", OUTPUT_SUMMARY },\r
318 >                                 { "threads", OUTPUT_THREADS },\r
319 >                                 { "messages", OUTPUT_MESSAGES },\r
320 > +                               { "sender", OUTPUT_SENDER },\r
321 > +                               { "recipients", OUTPUT_RECIPIENTS },\r
322 > +                               { "addresses", OUTPUT_ADDRESSES },\r
323 >                                 { "files", OUTPUT_FILES },\r
324 >                                 { "tags", OUTPUT_TAGS },\r
325 >                                 { 0, 0 } } },\r
326 > @@ -461,6 +546,9 @@ notmuch_search_command (notmuch_config_t *config, int=\r
327  argc, char *argv[])\r
328 >       ret =3D do_search_threads (&o);\r
329 >       break;\r
330 >      case OUTPUT_MESSAGES:\r
331 > +    case OUTPUT_SENDER:\r
332 > +    case OUTPUT_RECIPIENTS:\r
333 > +    case OUTPUT_ADDRESSES:\r
334 >      case OUTPUT_FILES:\r
335 >       ret =3D do_search_messages (&o);\r
336 >       break;\r
337 > diff --git a/test/T090-search-output.sh b/test/T090-search-output.sh\r
338 > index 947d572..5458de1 100755\r
339 > --- a/test/T090-search-output.sh\r
340 > +++ b/test/T090-search-output.sh\r
341 > @@ -387,6 +387,70 @@ cat <<EOF >EXPECTED\r
342 >  EOF\r
343 >  test_expect_equal_file OUTPUT EXPECTED\r
344 >=20=20\r
345 > +test_begin_subtest "--output=3Dsender"\r
346 > +notmuch search --output=3Dsender '*' | sort | uniq --count >OUTPUT\r
347 > +cat <<EOF >EXPECTED\r
348 > +      1 Adrian Perez de Castro <aperez@igalia.com>\r
349 > +      2 Alex Botero-Lowry <alex.boterolowry@gmail.com>\r
350 > +      4 Alexander Botero-Lowry <alex.boterolowry@gmail.com>\r
351 > +      1 Aron Griffis <agriffis@n01se.net>\r
352 > +     12 Carl Worth <cworth@cworth.org>\r
353 > +      1 Chris Wilson <chris@chris-wilson.co.uk>\r
354 > +      1 Fran=C3=A7ois Boulogne <boulogne.f@gmail.com>\r
355 > +      1 Ingmar Vanhassel <ingmar@exherbo.org>\r
356 > +      1 Israel Herraiz <isra@herraiz.org>\r
357 > +      4 Jan Janak <jan@ryngle.com>\r
358 > +      2 Jjgod Jiang <gzjjgod@gmail.com>\r
359 > +      7 Keith Packard <keithp@keithp.com>\r
360 > +      5 Lars Kellogg-Stedman <lars@seas.harvard.edu>\r
361 > +      5 Mikhail Gusarov <dottedmag@dottedmag.net>\r
362 > +      1 Olivier Berger <olivier.berger@it-sudparis.eu>\r
363 > +      1 Rolland Santimano <rollandsantimano@yahoo.com>\r
364 > +      3 Stewart Smith <stewart@flamingspork.com>\r
365 > +EOF\r
366 > +test_expect_equal_file OUTPUT EXPECTED\r
367 > +\r
368 > +test_begin_subtest "--output=3Drecipients"\r
369 > +notmuch search --output=3Drecipients '*' | sort | uniq --count >OUTPUT\r
370 > +cat <<EOF >EXPECTED\r
371 > +      1 Allan McRae <allan@archlinux.org>\r
372 > +      1 Discussion about the Arch User Repository (AUR) <aur-general@arc=\r
373 hlinux.org>\r
374 > +      1 Keith Packard <keithp@keithp.com>\r
375 > +      1 Mikhail Gusarov <dottedmag@dottedmag.net>\r
376 > +      2 notmuch <notmuch@notmuchmail.org>\r
377 > +     48 notmuch@notmuchmail.org\r
378 > +      1 olivier.berger@it-sudparis.eu\r
379 > +EOF\r
380 > +test_expect_equal_file OUTPUT EXPECTED\r
381 > +\r
382 > +test_begin_subtest "--output=3Daddresses"\r
383 > +notmuch search --output=3Daddresses '*' | sort | uniq --count >OUTPUT\r
384 > +cat <<EOF >EXPECTED\r
385 > +      1 Adrian Perez de Castro <aperez@igalia.com>\r
386 > +      2 Alex Botero-Lowry <alex.boterolowry@gmail.com>\r
387 > +      4 Alexander Botero-Lowry <alex.boterolowry@gmail.com>\r
388 > +      1 Allan McRae <allan@archlinux.org>\r
389 > +      1 Aron Griffis <agriffis@n01se.net>\r
390 > +     12 Carl Worth <cworth@cworth.org>\r
391 > +      1 Chris Wilson <chris@chris-wilson.co.uk>\r
392 > +      1 Discussion about the Arch User Repository (AUR) <aur-general@arc=\r
393 hlinux.org>\r
394 > +      1 Fran=C3=A7ois Boulogne <boulogne.f@gmail.com>\r
395 > +      1 Ingmar Vanhassel <ingmar@exherbo.org>\r
396 > +      1 Israel Herraiz <isra@herraiz.org>\r
397 > +      4 Jan Janak <jan@ryngle.com>\r
398 > +      2 Jjgod Jiang <gzjjgod@gmail.com>\r
399 > +      8 Keith Packard <keithp@keithp.com>\r
400 > +      5 Lars Kellogg-Stedman <lars@seas.harvard.edu>\r
401 > +      6 Mikhail Gusarov <dottedmag@dottedmag.net>\r
402 > +      1 Olivier Berger <olivier.berger@it-sudparis.eu>\r
403 > +      1 Rolland Santimano <rollandsantimano@yahoo.com>\r
404 > +      3 Stewart Smith <stewart@flamingspork.com>\r
405 > +      2 notmuch <notmuch@notmuchmail.org>\r
406 > +     48 notmuch@notmuchmail.org\r
407 > +      1 olivier.berger@it-sudparis.eu\r
408 > +EOF\r
409 > +test_expect_equal_file OUTPUT EXPECTED\r
410 > +\r
411 >  test_begin_subtest "sanitize output for quoted-printable line-breaks in =\r
412 author and subject"\r
413 >  add_message "[subject]=3D'two =3D?ISO-8859-1?Q?line=3D0A_subject?=3D\r
414 >       headers'"\r
415 > --=20\r
416 > 2.1.1\r
417 >\r
418 > _______________________________________________\r
419 > notmuch mailing list\r
420 > notmuch@notmuchmail.org\r
421 > http://notmuchmail.org/mailman/listinfo/notmuch\r