Re: [PATCH] Fix typo in Message.maildir_flags_to_tags
[notmuch-archives.git] / 60 / ee9f0ca66f5487d77485f6424ed92ff0ea99ce
1 Return-Path: <jani@nikula.org>\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 6218F431FB6\r
6         for <notmuch@notmuchmail.org>; Tue, 10 Jan 2012 11:54:22 -0800 (PST)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References"\r
9 X-Spam-Flag: NO\r
10 X-Spam-Score: -0.7\r
11 X-Spam-Level: \r
12 X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
13         tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
14 Received: from olra.theworths.org ([127.0.0.1])\r
15         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
16         with ESMTP id 3MuHkYAj6HfT for <notmuch@notmuchmail.org>;\r
17         Tue, 10 Jan 2012 11:54:21 -0800 (PST)\r
18 Received: from mail-ee0-f53.google.com (mail-ee0-f53.google.com\r
19  [74.125.83.53])        (using TLSv1 with cipher RC4-SHA (128/128 bits))        (No client\r
20  certificate requested) by olra.theworths.org (Postfix) with ESMTPS id\r
21  D9C82429E27    for <notmuch@notmuchmail.org>; Tue, 10 Jan 2012 11:54:20 -0800\r
22  (PST)\r
23 Received: by mail-ee0-f53.google.com with SMTP id e51so593109eek.26\r
24         for <notmuch@notmuchmail.org>; Tue, 10 Jan 2012 11:54:20 -0800 (PST)\r
25 Received: by 10.213.32.204 with SMTP id e12mr567356ebd.128.1326225260381;\r
26         Tue, 10 Jan 2012 11:54:20 -0800 (PST)\r
27 Received: from localhost (dsl-hkibrasgw4-fe5cdc00-23.dhcp.inet.fi.\r
28         [80.220.92.23])\r
29         by mx.google.com with ESMTPS id s16sm308127178eef.2.2012.01.10.11.54.18\r
30         (version=SSLv3 cipher=OTHER); Tue, 10 Jan 2012 11:54:19 -0800 (PST)\r
31 From: Jani Nikula <jani@nikula.org>\r
32 To: notmuch@notmuchmail.org\r
33 Subject: [PATCH v3 1/4] cli: add support for replying just to the sender in\r
34         "notmuch reply"\r
35 Date: Tue, 10 Jan 2012 21:54:01 +0200\r
36 Message-Id:\r
37  <d32e63c8115b1f2868acf96c83b30697be88ff10.1326224339.git.jani@nikula.org>\r
38 X-Mailer: git-send-email 1.7.5.4\r
39 In-Reply-To: <cover.1326224339.git.jani@nikula.org>\r
40 References: <cover.1326224339.git.jani@nikula.org>\r
41 In-Reply-To: <cover.1326224339.git.jani@nikula.org>\r
42 References: <cover.1325794371.git.jani@nikula.org>\r
43         <cover.1326224339.git.jani@nikula.org>\r
44 X-BeenThere: notmuch@notmuchmail.org\r
45 X-Mailman-Version: 2.1.13\r
46 Precedence: list\r
47 List-Id: "Use and development of the notmuch mail system."\r
48         <notmuch.notmuchmail.org>\r
49 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
50         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
51 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
52 List-Post: <mailto:notmuch@notmuchmail.org>\r
53 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
54 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
55         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
56 X-List-Received-Date: Tue, 10 Jan 2012 19:54:22 -0000\r
57 \r
58 Add new option --reply-to=(all|sender) to "notmuch reply" to select whether\r
59 to reply to all (sender and all recipients), or just sender. Reply to all\r
60 remains the default.\r
61 \r
62 Credits to Mark Walters <markwalters1009@gmail.com> for his similar earlier\r
63 work where I picked up the basic idea of handling reply-to-sender in\r
64 add_recipients_from_message(). All bugs are mine, though.\r
65 \r
66 Signed-off-by: Jani Nikula <jani@nikula.org>\r
67 \r
68 ---\r
69 \r
70 Settled on --reply-to=(all|sender) per Carl's earlier suggestion\r
71 (id:87pqn5cg4g.fsf@yoom.home.cworth.org) and David's approval on IRC.\r
72 ---\r
73  man/man1/notmuch-reply.1 |   28 +++++++++++++++---\r
74  notmuch-reply.c          |   70 ++++++++++++++++++++++++++++++++++-----------\r
75  2 files changed, 76 insertions(+), 22 deletions(-)\r
76 \r
77 diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1\r
78 index db464d8..5160ece 100644\r
79 --- a/man/man1/notmuch-reply.1\r
80 +++ b/man/man1/notmuch-reply.1\r
81 @@ -14,11 +14,13 @@ Constructs a reply template for a set of messages.\r
82  To make replying to email easier,\r
83  .B notmuch reply\r
84  takes an existing set of messages and constructs a suitable mail\r
85 -template. The Reply-to header (if any, otherwise From:) is used for\r
86 -the To: address. Vales from the To: and Cc: headers are copied, but\r
87 -not including any of the current user's email addresses (as configured\r
88 -in primary_mail or other_email in the .notmuch\-config file) in the\r
89 -recipient list\r
90 +template. The Reply-to: header (if any, otherwise From:) is used for\r
91 +the To: address. Unless\r
92 +.BR \-\-reply-to=sender\r
93 +is specified, values from the To: and Cc: headers are copied, but not\r
94 +including any of the current user's email addresses (as configured in\r
95 +primary_mail or other_email in the .notmuch\-config file) in the\r
96 +recipient list.\r
97  \r
98  It also builds a suitable new subject, including Re: at the front (if\r
99  not already present), and adding the message IDs of the messages being\r
100 @@ -45,6 +47,22 @@ Includes subject and quoted message body.\r
101  Only produces In\-Reply\-To, References, To, Cc, and Bcc headers.\r
102  .RE\r
103  .RE\r
104 +.RS\r
105 +.TP 4\r
106 +.BR \-\-reply\-to= ( all | sender )\r
107 +.RS\r
108 +.TP 4\r
109 +.BR all " (default)"\r
110 +Replies to all addresses.\r
111 +.TP 4\r
112 +.BR sender\r
113 +Replies only to the sender. If replying to user's own message\r
114 +(Reply-to: or From: header is one of the user's configured email\r
115 +addresses), try To:, Cc:, and Bcc: headers in this order, and copy\r
116 +values from the first that contains something other than only the\r
117 +user's addresses.\r
118 +.RE\r
119 +.RE\r
120  \r
121  See \fBnotmuch-search-terms\fR(7)\r
122  for details of the supported syntax for <search-terms>.\r
123 diff --git a/notmuch-reply.c b/notmuch-reply.c\r
124 index 000f6da..7b785a7 100644\r
125 --- a/notmuch-reply.c\r
126 +++ b/notmuch-reply.c\r
127 @@ -170,7 +170,7 @@ address_is_users (const char *address, notmuch_config_t *config)\r
128  \r
129  /* For each address in 'list' that is not configured as one of the\r
130   * user's addresses in 'config', add that address to 'message' as an\r
131 - * address of 'type'.\r
132 + * address of 'type', if 'add' is true.\r
133   *\r
134   * The first address encountered that *is* the user's address will be\r
135   * returned, (otherwise NULL is returned).\r
136 @@ -179,7 +179,8 @@ static const char *\r
137  add_recipients_for_address_list (GMimeMessage *message,\r
138                                  notmuch_config_t *config,\r
139                                  GMimeRecipientType type,\r
140 -                                InternetAddressList *list)\r
141 +                                InternetAddressList *list,\r
142 +                                notmuch_bool_t add)\r
143  {\r
144      InternetAddress *address;\r
145      int i;\r
146 @@ -197,7 +198,7 @@ add_recipients_for_address_list (GMimeMessage *message,\r
147                 continue;\r
148  \r
149             add_recipients_for_address_list (message, config,\r
150 -                                            type, group_list);\r
151 +                                            type, group_list, add);\r
152         } else {\r
153             InternetAddressMailbox *mailbox;\r
154             const char *name;\r
155 @@ -211,7 +212,7 @@ add_recipients_for_address_list (GMimeMessage *message,\r
156             if (address_is_users (addr, config)) {\r
157                 if (ret == NULL)\r
158                     ret = addr;\r
159 -           } else {\r
160 +           } else if (add) {\r
161                 g_mime_message_add_recipient (message, type, name, addr);\r
162             }\r
163         }\r
164 @@ -222,7 +223,7 @@ add_recipients_for_address_list (GMimeMessage *message,\r
165  \r
166  /* For each address in 'recipients' that is not configured as one of\r
167   * the user's addresses in 'config', add that address to 'message' as\r
168 - * an address of 'type'.\r
169 + * an address of 'type', if 'add' is true.\r
170   *\r
171   * The first address encountered that *is* the user's address will be\r
172   * returned, (otherwise NULL is returned).\r
173 @@ -231,7 +232,8 @@ static const char *\r
174  add_recipients_for_string (GMimeMessage *message,\r
175                            notmuch_config_t *config,\r
176                            GMimeRecipientType type,\r
177 -                          const char *recipients)\r
178 +                          const char *recipients,\r
179 +                          notmuch_bool_t add)\r
180  {\r
181      InternetAddressList *list;\r
182  \r
183 @@ -242,7 +244,7 @@ add_recipients_for_string (GMimeMessage *message,\r
184      if (list == NULL)\r
185         return NULL;\r
186  \r
187 -    return add_recipients_for_address_list (message, config, type, list);\r
188 +    return add_recipients_for_address_list (message, config, type, list, add);\r
189  }\r
190  \r
191  /* Does the address in the Reply-To header of 'message' already appear\r
192 @@ -286,13 +288,19 @@ reply_to_header_is_redundant (notmuch_message_t *message)\r
193  \r
194  /* Augments the recipients of reply from the headers of message.\r
195   *\r
196 + * If 'reply_all' is true, use sender and all recipients, otherwise use the\r
197 + * first header that contains something other than the user's addresses\r
198 + * (typically this would be reply-to-sender, but also handles reply to user's\r
199 + * own message in a sensible way).\r
200 + *\r
201   * If any of the user's addresses were found in these headers, the first\r
202   * of these returned, otherwise NULL is returned.\r
203   */\r
204  static const char *\r
205  add_recipients_from_message (GMimeMessage *reply,\r
206                              notmuch_config_t *config,\r
207 -                            notmuch_message_t *message)\r
208 +                            notmuch_message_t *message,\r
209 +                            notmuch_bool_t reply_all)\r
210  {\r
211      struct {\r
212         const char *header;\r
213 @@ -305,6 +313,7 @@ add_recipients_from_message (GMimeMessage *reply,\r
214         { "bcc",        NULL, GMIME_RECIPIENT_TYPE_BCC }\r
215      };\r
216      const char *from_addr = NULL;\r
217 +    notmuch_bool_t add_recipients = TRUE;\r
218      unsigned int i;\r
219  \r
220      /* Some mailing lists munge the Reply-To header despite it being A Bad\r
221 @@ -325,6 +334,7 @@ add_recipients_from_message (GMimeMessage *reply,\r
222  \r
223      for (i = 0; i < ARRAY_SIZE (reply_to_map); i++) {\r
224         const char *addr, *recipients;\r
225 +       GMimeRecipientType recipient_type = reply_to_map[i].recipient_type;\r
226  \r
227         recipients = notmuch_message_get_header (message,\r
228                                                  reply_to_map[i].header);\r
229 @@ -332,11 +342,29 @@ add_recipients_from_message (GMimeMessage *reply,\r
230             recipients = notmuch_message_get_header (message,\r
231                                                      reply_to_map[i].fallback);\r
232  \r
233 -       addr = add_recipients_for_string (reply, config,\r
234 -                                         reply_to_map[i].recipient_type,\r
235 -                                         recipients);\r
236 +       addr = add_recipients_for_string (reply, config, recipient_type,\r
237 +                                         recipients, add_recipients);\r
238 +\r
239         if (from_addr == NULL)\r
240             from_addr = addr;\r
241 +\r
242 +       if (!reply_all) {\r
243 +           /* Stop adding new recipients in reply-to-sender mode if we have\r
244 +            * added some recipient(s) above.\r
245 +            *\r
246 +            * This also handles the case of user replying to his own message,\r
247 +            * where reply-to/from is not a recipient. In this case there may be\r
248 +            * more than one recipient even if not replying to all.\r
249 +            */\r
250 +           InternetAddressList *list;\r
251 +           list = g_mime_message_get_recipients (reply, recipient_type);\r
252 +           if (list && internet_address_list_length (list))\r
253 +               add_recipients = FALSE;\r
254 +\r
255 +           /* Check if we've got a from address and all recipients we need. */\r
256 +           if (!add_recipients && from_addr)\r
257 +               break;\r
258 +       }\r
259      }\r
260  \r
261      return from_addr;\r
262 @@ -480,7 +508,8 @@ static int\r
263  notmuch_reply_format_default(void *ctx,\r
264                              notmuch_config_t *config,\r
265                              notmuch_query_t *query,\r
266 -                            notmuch_show_params_t *params)\r
267 +                            notmuch_show_params_t *params,\r
268 +                            notmuch_bool_t reply_all)\r
269  {\r
270      GMimeMessage *reply;\r
271      notmuch_messages_t *messages;\r
272 @@ -509,7 +538,8 @@ notmuch_reply_format_default(void *ctx,\r
273             g_mime_message_set_subject (reply, subject);\r
274         }\r
275  \r
276 -       from_addr = add_recipients_from_message (reply, config, message);\r
277 +       from_addr = add_recipients_from_message (reply, config, message,\r
278 +                                                reply_all);\r
279  \r
280         if (from_addr == NULL)\r
281             from_addr = guess_from_received_header (config, message);\r
282 @@ -558,7 +588,8 @@ static int\r
283  notmuch_reply_format_headers_only(void *ctx,\r
284                                   notmuch_config_t *config,\r
285                                   notmuch_query_t *query,\r
286 -                                 unused (notmuch_show_params_t *params))\r
287 +                                 unused (notmuch_show_params_t *params),\r
288 +                                 notmuch_bool_t reply_all)\r
289  {\r
290      GMimeMessage *reply;\r
291      notmuch_messages_t *messages;\r
292 @@ -598,7 +629,7 @@ notmuch_reply_format_headers_only(void *ctx,\r
293         g_mime_object_set_header (GMIME_OBJECT (reply),\r
294                                   "References", references);\r
295  \r
296 -       (void)add_recipients_from_message (reply, config, message);\r
297 +       (void)add_recipients_from_message (reply, config, message, reply_all);\r
298  \r
299         reply_headers = g_mime_object_to_string (GMIME_OBJECT (reply));\r
300         printf ("%s", reply_headers);\r
301 @@ -625,9 +656,10 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])\r
302      notmuch_query_t *query;\r
303      char *query_string;\r
304      int opt_index, ret = 0;\r
305 -    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params);\r
306 +    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params, notmuch_bool_t reply_all);\r
307      notmuch_show_params_t params = { .part = -1 };\r
308      int format = FORMAT_DEFAULT;\r
309 +    int reply_all = TRUE;\r
310      notmuch_bool_t decrypt = FALSE;\r
311  \r
312      notmuch_opt_desc_t options[] = {\r
313 @@ -635,6 +667,10 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])\r
314           (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT },\r
315                                   { "headers-only", FORMAT_HEADERS_ONLY },\r
316                                   { 0, 0 } } },\r
317 +       { NOTMUCH_OPT_KEYWORD, &reply_all, "reply-to", 'r',\r
318 +         (notmuch_keyword_t []){ { "all", TRUE },\r
319 +                                 { "sender", FALSE },\r
320 +                                 { 0, 0 } } },\r
321         { NOTMUCH_OPT_BOOLEAN, &decrypt, "decrypt", 'd', 0 },\r
322         { 0, 0, 0, 0, 0 }\r
323      };\r
324 @@ -688,7 +724,7 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])\r
325         return 1;\r
326      }\r
327  \r
328 -    if (reply_format_func (ctx, config, query, &params) != 0)\r
329 +    if (reply_format_func (ctx, config, query, &params, reply_all) != 0)\r
330         return 1;\r
331  \r
332      notmuch_query_destroy (query);\r
333 -- \r
334 1.7.5.4\r
335 \r