Re: [PATCH] emacs: wash: make word-wrap bound message width
[notmuch-archives.git] / 8f / ba3cb4734b76f1574e57526675e721ddf1313c
1 Return-Path: <awg@lagos.xvx.ca>\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 CD3BF429E32\r
6         for <notmuch@notmuchmail.org>; Mon, 16 Jan 2012 10:13:55 -0800 (PST)\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\r
12         tests=[RCVD_IN_DNSWL_NONE=-0.0001] 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 dN726q9zcsE3 for <notmuch@notmuchmail.org>;\r
16         Mon, 16 Jan 2012 10:13:51 -0800 (PST)\r
17 Received: from idcmail-mo1so.shaw.ca (idcmail-mo1so.shaw.ca [24.71.223.10])\r
18         by olra.theworths.org (Postfix) with ESMTP id 71599431FAF\r
19         for <notmuch@notmuchmail.org>; Mon, 16 Jan 2012 10:13:51 -0800 (PST)\r
20 Received: from pd4ml3so-ssvc.prod.shaw.ca ([10.0.141.150])\r
21         by pd4mo1so-svcs.prod.shaw.ca with ESMTP; 16 Jan 2012 11:13:51 -0700\r
22 X-Cloudmark-SP-Filtered: true\r
23 X-Cloudmark-SP-Result: v=1.1 cv=b/gStvK98Bs6YfhBwCpxRApoLO2qoBYaarCtclPE+68=\r
24         c=1 sm=1\r
25         a=lLI09cVVNRQA:10 a=BLceEmwcHowA:10 a=yQp6g8lIsgqumF79BAsFDg==:17\r
26         a=z0yAGGARn2UZrTcHzMYA:9 a=kfhJ8YOzeKj4naP4xKsA:7\r
27         a=HpAAvcLHHh0Zw7uRqdWCyQ==:117\r
28 Received: from unknown (HELO lagos.xvx.ca) ([96.52.216.56])\r
29         by pd4ml3so-dmz.prod.shaw.ca with ESMTP; 16 Jan 2012 11:13:51 -0700\r
30 Received: by lagos.xvx.ca (Postfix, from userid 1000)\r
31         id D22E18004208; Mon, 16 Jan 2012 11:13:50 -0700 (MST)\r
32 From: Adam Wolfe Gordon <awg+notmuch@xvx.ca>\r
33 To: notmuch@notmuchmail.org\r
34 Subject: [PATCH v2 2/4] reply: Add a JSON reply format.\r
35 Date: Mon, 16 Jan 2012 11:13:21 -0700\r
36 Message-Id: <1326737603-21166-3-git-send-email-awg+notmuch@xvx.ca>\r
37 X-Mailer: git-send-email 1.7.5.4\r
38 In-Reply-To: <1326737603-21166-1-git-send-email-awg+notmuch@xvx.ca>\r
39 References: <1326737603-21166-1-git-send-email-awg+notmuch@xvx.ca>\r
40 X-BeenThere: notmuch@notmuchmail.org\r
41 X-Mailman-Version: 2.1.13\r
42 Precedence: list\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, 16 Jan 2012 18:13:56 -0000\r
53 \r
54 This new JSON format for replies includes headers generated for a reply\r
55 message as well as the headers and all text parts of the original message.\r
56 Using this data, a client can intelligently create a reply. For example,\r
57 the emacs client will be able to create replies with quoted HTML parts by\r
58 parsing the HTML parts using w3m.\r
59 ---\r
60  notmuch-reply.c |  313 ++++++++++++++++++++++++++++++++++++++++++++-----------\r
61  1 files changed, 253 insertions(+), 60 deletions(-)\r
62 \r
63 diff --git a/notmuch-reply.c b/notmuch-reply.c\r
64 index da3acce..f5a5dcf 100644\r
65 --- a/notmuch-reply.c\r
66 +++ b/notmuch-reply.c\r
67 @@ -30,6 +30,15 @@ reply_headers_message_part (GMimeMessage *message);\r
68  static void\r
69  reply_part_content (GMimeObject *part);\r
70  \r
71 +static void\r
72 +reply_part_start_json (GMimeObject *part, int *part_count);\r
73 +\r
74 +static void\r
75 +reply_part_content_json (GMimeObject *part);\r
76 +\r
77 +static void\r
78 +reply_part_end_json (GMimeObject *part);\r
79 +\r
80  static const notmuch_show_format_t format_reply = {\r
81      "",\r
82         "", NULL,\r
83 @@ -46,6 +55,22 @@ static const notmuch_show_format_t format_reply = {\r
84      ""\r
85  };\r
86  \r
87 +static const notmuch_show_format_t format_json = {\r
88 +    "",\r
89 +       "", NULL,\r
90 +           "", NULL, NULL, "",\r
91 +           "",\r
92 +               reply_part_start_json,\r
93 +               NULL,\r
94 +               NULL,\r
95 +               reply_part_content_json,\r
96 +               reply_part_end_json,\r
97 +               "",\r
98 +           "",\r
99 +       "", "",\r
100 +    ""\r
101 +};\r
102 +\r
103  static void\r
104  show_reply_headers (GMimeMessage *message)\r
105  {\r
106 @@ -54,14 +79,14 @@ show_reply_headers (GMimeMessage *message)\r
107      stream_stdout = g_mime_stream_file_new (stdout);\r
108      if (stream_stdout) {\r
109         g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE);\r
110 -       stream_filter = g_mime_stream_filter_new(stream_stdout);\r
111 +       stream_filter = g_mime_stream_filter_new (stream_stdout);\r
112         if (stream_filter) {\r
113 -               g_mime_stream_filter_add(GMIME_STREAM_FILTER(stream_filter),\r
114 -                                        g_mime_filter_headers_new());\r
115 -               g_mime_object_write_to_stream(GMIME_OBJECT(message), stream_filter);\r
116 -               g_object_unref(stream_filter);\r
117 +               g_mime_stream_filter_add (GMIME_STREAM_FILTER(stream_filter),\r
118 +                                         g_mime_filter_headers_new());\r
119 +               g_mime_object_write_to_stream (GMIME_OBJECT(message), stream_filter);\r
120 +               g_object_unref (stream_filter);\r
121         }\r
122 -       g_object_unref(stream_stdout);\r
123 +       g_object_unref (stream_stdout);\r
124      }\r
125  }\r
126  \r
127 @@ -86,6 +111,17 @@ reply_headers_message_part (GMimeMessage *message)\r
128      printf ("> Date: %s\n", g_mime_message_get_date_as_string (message));\r
129  }\r
130  \r
131 +static notmuch_bool_t\r
132 +reply_check_part_type (GMimeObject *part, const char *type, const char *subtype,\r
133 +                      const char *disposition)\r
134 +{\r
135 +    GMimeContentType *content_type = g_mime_object_get_content_type (GMIME_OBJECT (part));\r
136 +    GMimeContentDisposition *part_disposition = g_mime_object_get_content_disposition (part);\r
137 +\r
138 +    return (g_mime_content_type_is_type (content_type, type, subtype) &&\r
139 +           (!part_disposition ||\r
140 +            strcmp (part_disposition->disposition, disposition) == 0));\r
141 +}\r
142  \r
143  static void\r
144  reply_part_content (GMimeObject *part)\r
145 @@ -108,32 +144,29 @@ reply_part_content (GMimeObject *part)\r
146      {\r
147         GMimeStream *stream_stdout = NULL, *stream_filter = NULL;\r
148         GMimeDataWrapper *wrapper;\r
149 -       const char *charset;\r
150 -\r
151 -       charset = g_mime_object_get_content_type_parameter (part, "charset");\r
152         stream_stdout = g_mime_stream_file_new (stdout);\r
153         if (stream_stdout) {\r
154             g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE);\r
155 -           stream_filter = g_mime_stream_filter_new(stream_stdout);\r
156 -           if (charset) {\r
157 -               g_mime_stream_filter_add(GMIME_STREAM_FILTER(stream_filter),\r
158 -                                        g_mime_filter_charset_new(charset, "UTF-8"));\r
159 -           }\r
160 +           stream_filter = g_mime_stream_filter_new (stream_stdout);\r
161 +\r
162 +           const char *charset = g_mime_object_get_content_type_parameter (part, "charset");\r
163 +           if (charset)\r
164 +               g_mime_stream_filter_add(GMIME_STREAM_FILTER (stream_filter),\r
165 +                                        g_mime_filter_charset_new (charset, "UTF-8"));\r
166         }\r
167 -       g_mime_stream_filter_add(GMIME_STREAM_FILTER(stream_filter),\r
168 -                                g_mime_filter_reply_new(TRUE));\r
169 +       g_mime_stream_filter_add (GMIME_STREAM_FILTER (stream_filter),\r
170 +                                 g_mime_filter_reply_new (TRUE));\r
171         wrapper = g_mime_part_get_content_object (GMIME_PART (part));\r
172         if (wrapper && stream_filter)\r
173             g_mime_data_wrapper_write_to_stream (wrapper, stream_filter);\r
174         if (stream_filter)\r
175 -           g_object_unref(stream_filter);\r
176 +           g_object_unref (stream_filter);\r
177         if (stream_stdout)\r
178 -           g_object_unref(stream_stdout);\r
179 +           g_object_unref (stream_stdout);\r
180      }\r
181      else\r
182      {\r
183 -       if (disposition &&\r
184 -           strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0)\r
185 +       if (disposition && strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0)\r
186         {\r
187             const char *filename = g_mime_part_get_filename (GMIME_PART (part));\r
188             printf ("Attachment: %s (%s)\n", filename,\r
189 @@ -147,6 +180,67 @@ reply_part_content (GMimeObject *part)\r
190      }\r
191  }\r
192  \r
193 +static void\r
194 +reply_part_start_json (GMimeObject *part, unused (int *part_count))\r
195 +{\r
196 +    if (reply_check_part_type (part, "text", "*", GMIME_DISPOSITION_INLINE))\r
197 +       printf ("{ ");\r
198 +}\r
199 +\r
200 +static void\r
201 +reply_part_end_json (GMimeObject *part)\r
202 +{\r
203 +    if (reply_check_part_type (part, "text", "*", GMIME_DISPOSITION_INLINE))\r
204 +       printf ("}, ");\r
205 +}\r
206 +\r
207 +static void\r
208 +reply_part_content_json (GMimeObject *part)\r
209 +{\r
210 +    GMimeContentType *content_type = g_mime_object_get_content_type (GMIME_OBJECT (part));\r
211 +    void *ctx = talloc_new (NULL);\r
212 +\r
213 +    /* We only care about inline text parts for reply purposes */\r
214 +    if (reply_check_part_type (part, "text", "*", GMIME_DISPOSITION_INLINE))\r
215 +    {\r
216 +       GMimeDataWrapper *wrapper;\r
217 +       GByteArray *part_content;\r
218 +\r
219 +       printf ("\"content-type\": %s, \"content\": ",\r
220 +              json_quote_str (ctx, g_mime_content_type_to_string (content_type)));\r
221 +\r
222 +       wrapper = g_mime_part_get_content_object (GMIME_PART (part));\r
223 +       if (wrapper)\r
224 +       {\r
225 +           const char *charset = g_mime_object_get_content_type_parameter (part, "charset");\r
226 +           GMimeStream *stream_memory = g_mime_stream_mem_new ();\r
227 +           if (stream_memory) {\r
228 +               GMimeStream *stream_filter = NULL;\r
229 +               stream_filter = g_mime_stream_filter_new (stream_memory);\r
230 +               if (charset) {\r
231 +                   g_mime_stream_filter_add (GMIME_STREAM_FILTER (stream_filter),\r
232 +                                             g_mime_filter_charset_new (charset, "UTF-8"));\r
233 +               }\r
234 +\r
235 +               if (stream_filter)\r
236 +               {\r
237 +                   g_mime_data_wrapper_write_to_stream (wrapper, stream_filter);\r
238 +                   part_content = g_mime_stream_mem_get_byte_array (GMIME_STREAM_MEM (stream_memory));\r
239 +\r
240 +                   printf ("%s", json_quote_chararray (ctx, (char *) part_content->data, part_content->len));\r
241 +               }\r
242 +               if (stream_filter)\r
243 +                   g_object_unref (stream_filter);\r
244 +           }\r
245 +\r
246 +           if (stream_memory)\r
247 +               g_object_unref (stream_memory);\r
248 +       }\r
249 +    }\r
250 +\r
251 +    talloc_free (ctx);\r
252 +}\r
253 +\r
254  /* Is the given address configured as one of the user's "personal" or\r
255   * "other" addresses. */\r
256  static int\r
257 @@ -505,6 +599,61 @@ guess_from_received_header (notmuch_config_t *config, notmuch_message_t *message\r
258      return NULL;\r
259  }\r
260  \r
261 +static GMimeMessage *\r
262 +create_reply_message(void *ctx,\r
263 +                    notmuch_config_t *config,\r
264 +                    notmuch_message_t *message,\r
265 +                    notmuch_bool_t reply_all)\r
266 +{\r
267 +    const char *subject, *from_addr = NULL;\r
268 +    const char *in_reply_to, *orig_references, *references;\r
269 +\r
270 +    /* The 1 means we want headers in a "pretty" order. */\r
271 +    GMimeMessage *reply = g_mime_message_new (1);\r
272 +    if (reply == NULL) {\r
273 +       fprintf (stderr, "Out of memory\n");\r
274 +       return NULL;\r
275 +    }\r
276 +\r
277 +    subject = notmuch_message_get_header (message, "subject");\r
278 +    if (subject) {\r
279 +       if (strncasecmp (subject, "Re:", 3))\r
280 +           subject = talloc_asprintf (ctx, "Re: %s", subject);\r
281 +       g_mime_message_set_subject (reply, subject);\r
282 +    }\r
283 +\r
284 +    from_addr = add_recipients_from_message (reply, config,\r
285 +                                            message, reply_all);\r
286 +\r
287 +    if (from_addr == NULL)\r
288 +       from_addr = guess_from_received_header (config, message);\r
289 +\r
290 +    if (from_addr == NULL)\r
291 +       from_addr = notmuch_config_get_user_primary_email (config);\r
292 +\r
293 +    from_addr = talloc_asprintf (ctx, "%s <%s>",\r
294 +                                notmuch_config_get_user_name (config),\r
295 +                                from_addr);\r
296 +    g_mime_object_set_header (GMIME_OBJECT (reply),\r
297 +                             "From", from_addr);\r
298 +\r
299 +    in_reply_to = talloc_asprintf (ctx, "<%s>",\r
300 +                                  notmuch_message_get_message_id (message));\r
301 +\r
302 +    g_mime_object_set_header (GMIME_OBJECT (reply),\r
303 +                             "In-Reply-To", in_reply_to);\r
304 +\r
305 +    orig_references = notmuch_message_get_header (message, "references");\r
306 +    references = talloc_asprintf (ctx, "%s%s%s",\r
307 +                                 orig_references ? orig_references : "",\r
308 +                                 orig_references ? " " : "",\r
309 +                                 in_reply_to);\r
310 +    g_mime_object_set_header (GMIME_OBJECT (reply),\r
311 +                             "References", references);\r
312 +\r
313 +    return reply;\r
314 +}\r
315 +\r
316  static int\r
317  notmuch_reply_format_default(void *ctx,\r
318                              notmuch_config_t *config,\r
319 @@ -515,8 +664,6 @@ notmuch_reply_format_default(void *ctx,\r
320      GMimeMessage *reply;\r
321      notmuch_messages_t *messages;\r
322      notmuch_message_t *message;\r
323 -    const char *subject, *from_addr = NULL;\r
324 -    const char *in_reply_to, *orig_references, *references;\r
325      const notmuch_show_format_t *format = &format_reply;\r
326  \r
327      for (messages = notmuch_query_search_messages (query);\r
328 @@ -525,62 +672,104 @@ notmuch_reply_format_default(void *ctx,\r
329      {\r
330         message = notmuch_messages_get (messages);\r
331  \r
332 -       /* The 1 means we want headers in a "pretty" order. */\r
333 -       reply = g_mime_message_new (1);\r
334 -       if (reply == NULL) {\r
335 -           fprintf (stderr, "Out of memory\n");\r
336 -           return 1;\r
337 -       }\r
338 +       reply = create_reply_message (ctx, config, message, reply_all);\r
339  \r
340 -       subject = notmuch_message_get_header (message, "subject");\r
341 -       if (subject) {\r
342 -           if (strncasecmp (subject, "Re:", 3))\r
343 -               subject = talloc_asprintf (ctx, "Re: %s", subject);\r
344 -           g_mime_message_set_subject (reply, subject);\r
345 -       }\r
346 +       if (!reply)\r
347 +           continue;\r
348  \r
349 -       from_addr = add_recipients_from_message (reply, config, message,\r
350 -                                                reply_all);\r
351 +       show_reply_headers (reply);\r
352  \r
353 -       if (from_addr == NULL)\r
354 -           from_addr = guess_from_received_header (config, message);\r
355 +       g_object_unref (G_OBJECT (reply));\r
356 +       reply = NULL;\r
357  \r
358 -       if (from_addr == NULL)\r
359 -           from_addr = notmuch_config_get_user_primary_email (config);\r
360 +       printf ("On %s, %s wrote:\n",\r
361 +               notmuch_message_get_header (message, "date"),\r
362 +               notmuch_message_get_header (message, "from"));\r
363  \r
364 -       from_addr = talloc_asprintf (ctx, "%s <%s>",\r
365 -                                    notmuch_config_get_user_name (config),\r
366 -                                    from_addr);\r
367 -       g_mime_object_set_header (GMIME_OBJECT (reply),\r
368 -                                 "From", from_addr);\r
369 +       show_message_body (message, format, params);\r
370  \r
371 -       in_reply_to = talloc_asprintf (ctx, "<%s>",\r
372 -                            notmuch_message_get_message_id (message));\r
373 +       notmuch_message_destroy (message);\r
374 +    }\r
375 +    return 0;\r
376 +}\r
377  \r
378 -       g_mime_object_set_header (GMIME_OBJECT (reply),\r
379 -                                 "In-Reply-To", in_reply_to);\r
380 +static int\r
381 +notmuch_reply_format_json(void *ctx,\r
382 +                         notmuch_config_t *config,\r
383 +                         notmuch_query_t *query,\r
384 +                         unused (notmuch_show_params_t *params),\r
385 +                         notmuch_bool_t reply_all)\r
386 +{\r
387 +    GMimeMessage *reply;\r
388 +    notmuch_messages_t *messages;\r
389 +    notmuch_message_t *message;\r
390 +    const notmuch_show_format_t *format = &format_json;\r
391  \r
392 -       orig_references = notmuch_message_get_header (message, "references");\r
393 -       references = talloc_asprintf (ctx, "%s%s%s",\r
394 -                                     orig_references ? orig_references : "",\r
395 -                                     orig_references ? " " : "",\r
396 -                                     in_reply_to);\r
397 -       g_mime_object_set_header (GMIME_OBJECT (reply),\r
398 -                                 "References", references);\r
399 +    const char *reply_headers[] = {"from", "to", "subject", "in-reply-to", "references"};\r
400 +    const char *orig_headers[] = {"from", "to", "cc", "subject", "date", "in-reply-to", "references"};\r
401 +    unsigned int hidx;\r
402  \r
403 -       show_reply_headers (reply);\r
404 +    /* Start array of reply objects */\r
405 +    printf ("[");\r
406 +\r
407 +    for (messages = notmuch_query_search_messages (query);\r
408 +        notmuch_messages_valid (messages);\r
409 +        notmuch_messages_move_to_next (messages))\r
410 +    {\r
411 +       /* Start a reply object */\r
412 +       printf ("{ \"reply\": { \"headers\": { ");\r
413 +\r
414 +       message = notmuch_messages_get (messages);\r
415 +\r
416 +       reply = create_reply_message (ctx, config, message, reply_all);\r
417 +       if (!reply)\r
418 +           continue;\r
419 +\r
420 +       for (hidx = 0; hidx < ARRAY_SIZE (reply_headers); hidx++)\r
421 +       {\r
422 +           if (hidx)\r
423 +               printf (", ");\r
424 +\r
425 +           printf ("%s: %s", json_quote_str (ctx, reply_headers[hidx]),\r
426 +                   json_quote_str (ctx, g_mime_object_get_header (GMIME_OBJECT (reply), reply_headers[hidx])));\r
427 +       }\r
428  \r
429         g_object_unref (G_OBJECT (reply));\r
430         reply = NULL;\r
431  \r
432 -       printf ("On %s, %s wrote:\n",\r
433 -               notmuch_message_get_header (message, "date"),\r
434 -               notmuch_message_get_header (message, "from"));\r
435 +       /* Done the headers for the reply, which has no body parts */\r
436 +       printf ("} }");\r
437 +\r
438 +       /* Start the original */\r
439 +       printf (", \"original\": { \"headers\": { ");\r
440 +\r
441 +       for (hidx = 0; hidx < ARRAY_SIZE (orig_headers); hidx++)\r
442 +       {\r
443 +           if (hidx)\r
444 +               printf (", ");\r
445 +\r
446 +           printf ("%s: %s", json_quote_str (ctx, orig_headers[hidx]),\r
447 +                   json_quote_str (ctx, notmuch_message_get_header (message, orig_headers[hidx])));\r
448 +       }\r
449 +\r
450 +       /* End headers */\r
451 +       printf (" }, \"body\": [ ");\r
452  \r
453 +       /* Show body parts */\r
454         show_message_body (message, format, params);\r
455  \r
456         notmuch_message_destroy (message);\r
457 +\r
458 +       /* Done the original */\r
459 +       printf ("{} ] }");\r
460 +\r
461 +       /* End the reply object. */\r
462 +       printf (" }, ");\r
463      }\r
464 +\r
465 +    /* End array of reply objects */\r
466 +    printf ("{} ]\n");\r
467 +\r
468      return 0;\r
469  }\r
470  \r
471 @@ -646,6 +835,7 @@ notmuch_reply_format_headers_only(void *ctx,\r
472  \r
473  enum {\r
474      FORMAT_DEFAULT,\r
475 +    FORMAT_JSON,\r
476      FORMAT_HEADERS_ONLY,\r
477  };\r
478  \r
479 @@ -666,6 +856,7 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])\r
480      notmuch_opt_desc_t options[] = {\r
481         { NOTMUCH_OPT_KEYWORD, &format, "format", 'f',\r
482           (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT },\r
483 +                                 { "json", FORMAT_JSON },\r
484                                   { "headers-only", FORMAT_HEADERS_ONLY },\r
485                                   { 0, 0 } } },\r
486         { NOTMUCH_OPT_KEYWORD, &reply_all, "reply-to", 'r',\r
487 @@ -684,6 +875,8 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])\r
488  \r
489      if (format == FORMAT_HEADERS_ONLY)\r
490         reply_format_func = notmuch_reply_format_headers_only;\r
491 +    else if (format == FORMAT_JSON)\r
492 +       reply_format_func = notmuch_reply_format_json;\r
493      else\r
494         reply_format_func = notmuch_reply_format_default;\r
495  \r
496 -- \r
497 1.7.5.4\r
498 \r