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 49148431FAF
\r
6 for <notmuch@notmuchmail.org>; Mon, 13 Oct 2014 12:01:24 -0700 (PDT)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]
\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 1xQpcXesZ2EW for <notmuch@notmuchmail.org>;
\r
16 Mon, 13 Oct 2014 12:01:20 -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 DB1EC431FAE
\r
19 for <notmuch@notmuchmail.org>; Mon, 13 Oct 2014 12:01:19 -0700 (PDT)
\r
20 Received: from guru.guru-group.fi (localhost [IPv6:::1])
\r
21 by guru.guru-group.fi (Postfix) with ESMTP id 148DB100090;
\r
22 Mon, 13 Oct 2014 22:00:59 +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 v3 3/4] cli: Extend the search command for
\r
26 --output={sender, recipients}
\r
27 In-Reply-To: <1413150093-8383-4-git-send-email-sojkam1@fel.cvut.cz>
\r
28 References: <87zjd51phx.fsf@steelpick.2x.cz>
\r
29 <1413150093-8383-1-git-send-email-sojkam1@fel.cvut.cz>
\r
30 <1413150093-8383-4-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, 13 Oct 2014 22:00:58 +0300
\r
37 Message-ID: <m238arrdzp.fsf@guru.guru-group.fi>
\r
39 Content-Type: text/plain
\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: Mon, 13 Oct 2014 19:01:24 -0000
\r
54 On Mon, Oct 13 2014, Michal Sojka <sojkam1@fel.cvut.cz> wrote:
\r
56 > The new outputs allow printing senders, recipients or both of matching
\r
57 > messages. The --output option is converted from "keyword" argument to
\r
58 > "flags" argument, which means that the user can use --output=sender and
\r
59 > --output=recipients simultaneously, to print both. Other combinations
\r
62 > This code based on a patch from Jani Nikula.
\r
64 > completion/notmuch-completion.bash | 2 +-
\r
65 > completion/notmuch-completion.zsh | 3 +-
\r
66 > doc/man1/notmuch-search.rst | 22 +++++++-
\r
67 > notmuch-search.c | 110 ++++++++++++++++++++++++++++++++++---
\r
68 > test/T090-search-output.sh | 64 +++++++++++++++++++++
\r
69 > 5 files changed, 189 insertions(+), 12 deletions(-)
\r
71 > diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash
\r
72 > index 0571dc9..cfbd389 100644
\r
73 > --- a/completion/notmuch-completion.bash
\r
74 > +++ b/completion/notmuch-completion.bash
\r
75 > @@ -294,7 +294,7 @@ _notmuch_search()
\r
79 > - COMPREPLY=( $( compgen -W "summary threads messages files tags" -- "${cur}" ) )
\r
80 > + COMPREPLY=( $( compgen -W "summary threads messages files tags sender recipients" -- "${cur}" ) )
\r
84 > diff --git a/completion/notmuch-completion.zsh b/completion/notmuch-completion.zsh
\r
85 > index 67a9aba..3e52a00 100644
\r
86 > --- a/completion/notmuch-completion.zsh
\r
87 > +++ b/completion/notmuch-completion.zsh
\r
88 > @@ -52,7 +52,8 @@ _notmuch_search()
\r
90 > '--max-threads=[display only the first x threads from the search results]:number of threads to show: ' \
\r
91 > '--first=[omit the first x threads from the search results]:number of threads to omit: ' \
\r
92 > - '--sort=[sort results]:sorting:((newest-first\:"reverse chronological order" oldest-first\:"chronological order"))'
\r
93 > + '--sort=[sort results]:sorting:((newest-first\:"reverse chronological order" oldest-first\:"chronological order"))' \
\r
94 > + '--output=[select what to output]:output:((summary threads messages files tags sender recipients))'
\r
98 > diff --git a/doc/man1/notmuch-search.rst b/doc/man1/notmuch-search.rst
\r
99 > index 90160f2..c9d38b1 100644
\r
100 > --- a/doc/man1/notmuch-search.rst
\r
101 > +++ b/doc/man1/notmuch-search.rst
\r
102 > @@ -35,7 +35,7 @@ Supported options for **search** include
\r
103 > intended for programs that invoke **notmuch(1)** internally. If
\r
104 > omitted, the latest supported version will be used.
\r
106 > - ``--output=(summary|threads|messages|files|tags)``
\r
107 > + ``--output=(summary|threads|messages|files|tags|sender|recipients)``
\r
110 > Output a summary of each thread with any message matching
\r
111 > @@ -78,6 +78,26 @@ Supported options for **search** include
\r
112 > by null characters (--format=text0), as a JSON array
\r
113 > (--format=json), or as an S-Expression list (--format=sexp).
\r
116 > + Output all addresses from the *From* header that appear on
\r
117 > + any message matching the search terms, either one per line
\r
118 > + (--format=text), separated by null characters
\r
119 > + (--format=text0), as a JSON array (--format=json), or as
\r
120 > + an S-Expression list (--format=sexp).
\r
122 > + Note: Searching for **sender** should be much faster than
\r
123 > + searching for **recipients**, because sender addresses are
\r
124 > + cached directly in the database whereas other addresses
\r
125 > + need to be fetched from message files.
\r
128 > + Like **sender** but for addresses from *To*, *Cc* and
\r
131 > + This option can be given multiple times to combine different
\r
132 > + outputs. Curently, this is only supported for **sender** and
\r
133 > + **recipients** outputs.
\r
135 > ``--sort=``\ (**newest-first**\ \|\ **oldest-first**)
\r
136 > This option can be used to present results in either
\r
137 > chronological order (**oldest-first**) or reverse chronological
\r
138 > diff --git a/notmuch-search.c b/notmuch-search.c
\r
139 > index 5ac2a26..74588f8 100644
\r
140 > --- a/notmuch-search.c
\r
141 > +++ b/notmuch-search.c
\r
142 > @@ -23,11 +23,14 @@
\r
143 > #include "string-util.h"
\r
146 > - OUTPUT_SUMMARY,
\r
147 > - OUTPUT_THREADS,
\r
148 > - OUTPUT_MESSAGES,
\r
151 > + OUTPUT_SUMMARY = 1 << 0,
\r
152 > + OUTPUT_THREADS = 1 << 1,
\r
153 > + OUTPUT_MESSAGES = 1 << 2,
\r
154 > + OUTPUT_FILES = 1 << 3,
\r
155 > + OUTPUT_TAGS = 1 << 4,
\r
156 > + OUTPUT_SENDER = 1 << 5,
\r
157 > + OUTPUT_RECIPIENTS = 1 << 6,
\r
158 > + OUTPUT_ADDRESSES = OUTPUT_SENDER | OUTPUT_RECIPIENTS,
\r
160 leftover, like mentioned below (this comment added just before sending)
\r
165 > @@ -220,6 +223,67 @@ do_search_threads (search_options_t *o)
\r
170 > +print_address_list (const search_options_t *o, InternetAddressList *list)
\r
172 > + InternetAddress *address;
\r
175 > + for (i = 0; i < internet_address_list_length (list); i++) {
\r
176 > + address = internet_address_list_get_address (list, i);
\r
177 > + if (INTERNET_ADDRESS_IS_GROUP (address)) {
\r
178 > + InternetAddressGroup *group;
\r
179 > + InternetAddressList *group_list;
\r
181 > + group = INTERNET_ADDRESS_GROUP (address);
\r
182 > + group_list = internet_address_group_get_members (group);
\r
183 > + if (group_list == NULL)
\r
186 > + print_address_list (o, group_list);
\r
188 > + InternetAddressMailbox *mailbox;
\r
189 > + const char *name;
\r
190 > + const char *addr;
\r
191 > + char *full_address;
\r
193 > + mailbox = INTERNET_ADDRESS_MAILBOX (address);
\r
195 > + name = internet_address_get_name (address);
\r
196 > + addr = internet_address_mailbox_get_addr (mailbox);
\r
198 > + if (name && *name)
\r
199 > + full_address = talloc_asprintf (o->format, "%s <%s>", name, addr);
\r
201 > + full_address = talloc_strdup (o->format, addr);
\r
203 > + if (!full_address) {
\r
205 Apart from minor style issue like space after ! and the leftover ADDRESSES
\r
206 parts (w/o that I would not have commented about !<SPC>) the first 3
\r
207 patches look pretty good to me. I have not tested those yet.
\r
209 But we keep to have some disagreement w/ unique/duplicate/filter-by
\r
212 I (currently) rest the case of first/last/most common handling to just
\r
213 how the --sort=(newest-first|oldest-first) affects the order...
\r
215 Let's consider the following list of output if no /deduplication/ is done:
\r
217 John Doe <john@example.com>
\r
218 Dr. John Doe <john@example.com>
\r
219 John Doe <JOHN@EXAMPLE.COM>
\r
220 John Doe <john@doe.name>
\r
221 Dr. John Doe <john@doe.name>
\r
222 John Doe <JOHN@doe.name.example.com>
\r
223 John Doe <john@doe.name>
\r
224 Dr. John Doe <john@example.com>
\r
225 Dr. John Doe <john@example.com>
\r
226 Dr. John Doe <john@doe.name>
\r
227 John Doe <john@example.com>
\r
228 John Doe <john@doe.name.example.com>
\r
230 To stir the pool a little more, this could be the output when
\r
231 --duplicate=all (the default) is given.
\r
233 With --duplicate=none the output could be (first match by unique
\r
234 case-insensitive address):
\r
236 John Doe <john@example.com>
\r
237 John Doe <john@doe.name>
\r
238 John Doe <john@doe.name.example.com>
\r
240 (many people may have the same name, but email address is unique per person
\r
241 -- therefore I think 'none' limiting that just to John Doe <john@example.com>
\r
242 would be too little)
\r
244 and with --duplicate=address
\r
246 John Doe <john@example.com>
\r
247 Dr. John Doe <john@example.com>
\r
248 John Doe <john@doe.name>
\r
249 Dr. John Doe <john@doe.name>
\r
250 John Doe <JOHN@doe.name.example.com>
\r
252 (from this output user can choose how the recipient is to be called
\r
253 (like "pseudonyms" mentioned in id:20141010113202.GE28601@TP_L520.localdomain )
\r
254 when sending email)
\r
256 and --duplicate=address-casesensitive
\r
258 John Doe <john@example.com>
\r
259 Dr. John Doe <john@example.com>
\r
260 John Doe <JOHN@EXAMPLE.COM>
\r
261 John Doe <john@doe.name>
\r
262 Dr. John Doe <john@doe.name>
\r
263 John Doe <JOHN@doe.name.example.com>
\r
264 John Doe <john@doe.name.example.com>
\r
266 This reuse of --duplicate was thought out after Jani's irc mention of it.
\r
267 This scheme would leave no room tho the filter-by=name suggestion -- for
\r
268 completeness that would make this look:
\r
270 John Doe <john@example.com>
\r
271 Dr. John Doe <john@example.com>
\r
273 This doesn't look too bad in this particular case but not having ability to
\r
274 see all potential addresses (perhaps the only working address is now
\r
275 hidden) isn't not much for general use. Well, maybe for some specific use
\r
276 --duplicate=no-unique-addresses could be useful :O
\r
278 Ok, this took an hour to get written to (w/ some interruptions). Healthy
\r
279 criticism appreciated :D
\r
283 // stuff deleted before some 'ADDRESSES' leftover...
\r
285 > @@ -455,18 +542,23 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
\r
288 > switch (o.output) {
\r
290 > case OUTPUT_SUMMARY:
\r
291 > case OUTPUT_THREADS:
\r
292 > ret = do_search_threads (&o);
\r
294 > case OUTPUT_MESSAGES:
\r
295 > + case OUTPUT_SENDER:
\r
296 > + case OUTPUT_RECIPIENTS:
\r
297 > + case OUTPUT_ADDRESSES:
\r
298 > case OUTPUT_FILES:
\r
299 > ret = do_search_messages (&o);
\r
301 > case OUTPUT_TAGS:
\r
302 > ret = do_search_tags (notmuch, o.format, o.query);
\r
305 > + fprintf (stderr, "Error: the combination of outputs is not supported.\n");
\r
309 > notmuch_query_destroy (o.query);
\r