unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [PATCH 0/4] notmuch reply bugfix & reply to sender only
@ 2012-01-05 20:25 Jani Nikula
  2012-01-05 20:25 ` [PATCH 1/4] cli: fix use of uninitialized variable in "notmuch reply" Jani Nikula
                   ` (31 more replies)
  0 siblings, 32 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-05 20:25 UTC (permalink / raw)
  To: notmuch, david

Hi all -

Patch 1 is a bugfix worth considering for release branch independently. Included
in the same patchset as the following ones depend on it.

The rest of the patches add reply-to-sender (as opposed to reply-to-all)
functionality to "notmuch reply" and emacs.

Bikeshedding topic #1: How about making replying to just the sender the default
in "notmuch reply", and having --reply-all option (instead of --no-reply-all)?

Bikeshedding topic #2: How about binding 'r' to reply to just the sender by
default, and making 'R' reply-all (instead of vice versa)?

Obviously, this set is missing tests and documentation, but I'd like to get the
first round of review and the above topics settled first. :)


BR,
Jani.


Jani Nikula (4):
  cli: fix use of uninitialized variable in "notmuch reply"
  cli: convert "notmuch reply" to use the new argument parser
  cli: add support for replying just to the sender in "notmuch reply"
  emacs: add support for replying just to the sender of messages and
    threads

 emacs/notmuch-mua.el  |    8 ++-
 emacs/notmuch-show.el |   12 ++++-
 emacs/notmuch.el      |   11 ++++-
 notmuch-reply.c       |  129 ++++++++++++++++++++++++++----------------------
 4 files changed, 93 insertions(+), 67 deletions(-)

-- 
1.7.5.4

^ permalink raw reply	[flat|nested] 81+ messages in thread

* [PATCH 1/4] cli: fix use of uninitialized variable in "notmuch reply"
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
@ 2012-01-05 20:25 ` Jani Nikula
  2012-01-06  3:22   ` David Bremner
  2012-01-07  3:52   ` David Bremner
  2012-01-05 20:25 ` [PATCH 2/4] cli: convert "notmuch reply" to use the new argument parser Jani Nikula
                   ` (30 subsequent siblings)
  31 siblings, 2 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-05 20:25 UTC (permalink / raw)
  To: notmuch, david

notmuch_show_params_t params is only initialized partially in
notmuch_reply_command(). The only field that is used uninitialized is
params.decrypt. It is usually non-zero, making "notmuch reply" on encrypted
messages work by coincidence.

Initialize params properly, and set params.decrypt as needed.

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 notmuch-reply.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index f8d5f64..1f33a86 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -621,11 +621,9 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
     char *opt, *query_string;
     int i, ret = 0;
     int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params);
-    notmuch_show_params_t params;
+    notmuch_show_params_t params = { .part = -1 };
 
     reply_format_func = notmuch_reply_format_default;
-    params.part = -1;
-    params.cryptoctx = NULL;
 
     argc--; argv++; /* skip subcommand argument */
 
@@ -647,10 +645,12 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 	} else if ((STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
 	    if (params.cryptoctx == NULL) {
 		GMimeSession* session = g_object_new(g_mime_session_get_type(), NULL);
-		if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, "gpg")))
+		if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, "gpg"))) {
 		    fprintf (stderr, "Failed to construct gpg context.\n");
-		else
+		} else {
+		    params.decrypt = TRUE;
 		    g_mime_gpg_context_set_always_trust((GMimeGpgContext*)params.cryptoctx, FALSE);
+		}
 		g_object_unref (session);
 		session = NULL;
 	    }
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 2/4] cli: convert "notmuch reply" to use the new argument parser
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
  2012-01-05 20:25 ` [PATCH 1/4] cli: fix use of uninitialized variable in "notmuch reply" Jani Nikula
@ 2012-01-05 20:25 ` Jani Nikula
  2012-01-05 20:25 ` [PATCH 3/4] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
                   ` (29 subsequent siblings)
  31 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-05 20:25 UTC (permalink / raw)
  To: notmuch, david

Use the new notmuch argument parser to handle arguments in "notmuch
reply". There should be no functional changes.

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 notmuch-reply.c |   75 +++++++++++++++++++++++++++----------------------------
 1 files changed, 37 insertions(+), 38 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index 1f33a86..000f6da 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -612,62 +612,61 @@ notmuch_reply_format_headers_only(void *ctx,
     return 0;
 }
 
+enum {
+    FORMAT_DEFAULT,
+    FORMAT_HEADERS_ONLY,
+};
+
 int
 notmuch_reply_command (void *ctx, int argc, char *argv[])
 {
     notmuch_config_t *config;
     notmuch_database_t *notmuch;
     notmuch_query_t *query;
-    char *opt, *query_string;
-    int i, ret = 0;
+    char *query_string;
+    int opt_index, ret = 0;
     int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params);
     notmuch_show_params_t params = { .part = -1 };
+    int format = FORMAT_DEFAULT;
+    notmuch_bool_t decrypt = FALSE;
+
+    notmuch_opt_desc_t options[] = {
+	{ NOTMUCH_OPT_KEYWORD, &format, "format", 'f',
+	  (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT },
+				  { "headers-only", FORMAT_HEADERS_ONLY },
+				  { 0, 0 } } },
+	{ NOTMUCH_OPT_BOOLEAN, &decrypt, "decrypt", 'd', 0 },
+	{ 0, 0, 0, 0, 0 }
+    };
 
-    reply_format_func = notmuch_reply_format_default;
-
-    argc--; argv++; /* skip subcommand argument */
+    opt_index = parse_arguments (argc, argv, options, 1);
+    if (opt_index < 0) {
+	/* diagnostics already printed */
+	return 1;
+    }
 
-    for (i = 0; i < argc && argv[i][0] == '-'; i++) {
-	if (strcmp (argv[i], "--") == 0) {
-	    i++;
-	    break;
-	}
-        if (STRNCMP_LITERAL (argv[i], "--format=") == 0) {
-	    opt = argv[i] + sizeof ("--format=") - 1;
-	    if (strcmp (opt, "default") == 0) {
-		reply_format_func = notmuch_reply_format_default;
-	    } else if (strcmp (opt, "headers-only") == 0) {
-		reply_format_func = notmuch_reply_format_headers_only;
-	    } else {
-		fprintf (stderr, "Invalid value for --format: %s\n", opt);
-		return 1;
-	    }
-	} else if ((STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
-	    if (params.cryptoctx == NULL) {
-		GMimeSession* session = g_object_new(g_mime_session_get_type(), NULL);
-		if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, "gpg"))) {
-		    fprintf (stderr, "Failed to construct gpg context.\n");
-		} else {
-		    params.decrypt = TRUE;
-		    g_mime_gpg_context_set_always_trust((GMimeGpgContext*)params.cryptoctx, FALSE);
-		}
-		g_object_unref (session);
-		session = NULL;
-	    }
+    if (format == FORMAT_HEADERS_ONLY)
+	reply_format_func = notmuch_reply_format_headers_only;
+    else
+	reply_format_func = notmuch_reply_format_default;
+
+    if (decrypt) {
+	GMimeSession* session = g_object_new (g_mime_session_get_type(), NULL);
+	params.cryptoctx = g_mime_gpg_context_new (session, "gpg");
+	if (params.cryptoctx) {
+	    g_mime_gpg_context_set_always_trust ((GMimeGpgContext*) params.cryptoctx, FALSE);
+	    params.decrypt = TRUE;
 	} else {
-	    fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
-	    return 1;
+	    fprintf (stderr, "Failed to construct gpg context.\n");
 	}
+	g_object_unref (session);
     }
 
-    argc -= i;
-    argv += i;
-
     config = notmuch_config_open (ctx, NULL, NULL);
     if (config == NULL)
 	return 1;
 
-    query_string = query_string_from_args (ctx, argc, argv);
+    query_string = query_string_from_args (ctx, argc-opt_index, argv+opt_index);
     if (query_string == NULL) {
 	fprintf (stderr, "Out of memory\n");
 	return 1;
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 3/4] cli: add support for replying just to the sender in "notmuch reply"
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
  2012-01-05 20:25 ` [PATCH 1/4] cli: fix use of uninitialized variable in "notmuch reply" Jani Nikula
  2012-01-05 20:25 ` [PATCH 2/4] cli: convert "notmuch reply" to use the new argument parser Jani Nikula
@ 2012-01-05 20:25 ` Jani Nikula
  2012-01-05 20:25 ` [PATCH 4/4] emacs: add support for replying just to the sender of messages and threads Jani Nikula
                   ` (28 subsequent siblings)
  31 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-05 20:25 UTC (permalink / raw)
  To: notmuch, david

Add new option --no-reply-all to "notmuch reply" to reply just to the
sender instead of sender and all recipients.

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 notmuch-reply.c |   52 ++++++++++++++++++++++++++++++++--------------------
 1 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index 000f6da..57458ec 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -170,7 +170,7 @@ address_is_users (const char *address, notmuch_config_t *config)
 
 /* For each address in 'list' that is not configured as one of the
  * user's addresses in 'config', add that address to 'message' as an
- * address of 'type'.
+ * address of 'type', if 'add' is true.
  *
  * The first address encountered that *is* the user's address will be
  * returned, (otherwise NULL is returned).
@@ -179,7 +179,8 @@ static const char *
 add_recipients_for_address_list (GMimeMessage *message,
 				 notmuch_config_t *config,
 				 GMimeRecipientType type,
-				 InternetAddressList *list)
+				 InternetAddressList *list,
+				 notmuch_bool_t add)
 {
     InternetAddress *address;
     int i;
@@ -197,7 +198,7 @@ add_recipients_for_address_list (GMimeMessage *message,
 		continue;
 
 	    add_recipients_for_address_list (message, config,
-					     type, group_list);
+					     type, group_list, add);
 	} else {
 	    InternetAddressMailbox *mailbox;
 	    const char *name;
@@ -211,7 +212,7 @@ add_recipients_for_address_list (GMimeMessage *message,
 	    if (address_is_users (addr, config)) {
 		if (ret == NULL)
 		    ret = addr;
-	    } else {
+	    } else if (add) {
 		g_mime_message_add_recipient (message, type, name, addr);
 	    }
 	}
@@ -222,7 +223,7 @@ add_recipients_for_address_list (GMimeMessage *message,
 
 /* For each address in 'recipients' that is not configured as one of
  * the user's addresses in 'config', add that address to 'message' as
- * an address of 'type'.
+ * an address of 'type', if 'add' is true.
  *
  * The first address encountered that *is* the user's address will be
  * returned, (otherwise NULL is returned).
@@ -231,7 +232,8 @@ static const char *
 add_recipients_for_string (GMimeMessage *message,
 			   notmuch_config_t *config,
 			   GMimeRecipientType type,
-			   const char *recipients)
+			   const char *recipients,
+			   notmuch_bool_t add)
 {
     InternetAddressList *list;
 
@@ -242,7 +244,7 @@ add_recipients_for_string (GMimeMessage *message,
     if (list == NULL)
 	return NULL;
 
-    return add_recipients_for_address_list (message, config, type, list);
+    return add_recipients_for_address_list (message, config, type, list, add);
 }
 
 /* Does the address in the Reply-To header of 'message' already appear
@@ -284,7 +286,9 @@ reply_to_header_is_redundant (notmuch_message_t *message)
     return 0;
 }
 
-/* Augments the recipients of reply from the headers of message.
+/* Augments the recipients of reply from the headers of message. If 'reply_all'
+ * is true, use sender and all recipients, otherwise use just the sender
+ * ("reply-to" or "from" headers).
  *
  * If any of the user's addresses were found in these headers, the first
  * of these returned, otherwise NULL is returned.
@@ -292,17 +296,19 @@ reply_to_header_is_redundant (notmuch_message_t *message)
 static const char *
 add_recipients_from_message (GMimeMessage *reply,
 			     notmuch_config_t *config,
-			     notmuch_message_t *message)
+			     notmuch_message_t *message,
+			     notmuch_bool_t reply_all)
 {
     struct {
 	const char *header;
 	const char *fallback;
 	GMimeRecipientType recipient_type;
+	notmuch_bool_t always; /* use entry when not reply_all */
     } reply_to_map[] = {
-	{ "reply-to", "from", GMIME_RECIPIENT_TYPE_TO  },
-	{ "to",         NULL, GMIME_RECIPIENT_TYPE_TO  },
-	{ "cc",         NULL, GMIME_RECIPIENT_TYPE_CC  },
-	{ "bcc",        NULL, GMIME_RECIPIENT_TYPE_BCC }
+	{ "reply-to", "from", GMIME_RECIPIENT_TYPE_TO,	TRUE },
+	{ "to",         NULL, GMIME_RECIPIENT_TYPE_TO,	FALSE },
+	{ "cc",         NULL, GMIME_RECIPIENT_TYPE_CC,	FALSE },
+	{ "bcc",        NULL, GMIME_RECIPIENT_TYPE_BCC,	FALSE }
     };
     const char *from_addr = NULL;
     unsigned int i;
@@ -334,7 +340,8 @@ add_recipients_from_message (GMimeMessage *reply,
 
 	addr = add_recipients_for_string (reply, config,
 					  reply_to_map[i].recipient_type,
-					  recipients);
+					  recipients,
+					  reply_all || reply_to_map[i].always);
 	if (from_addr == NULL)
 	    from_addr = addr;
     }
@@ -480,7 +487,8 @@ static int
 notmuch_reply_format_default(void *ctx,
 			     notmuch_config_t *config,
 			     notmuch_query_t *query,
-			     notmuch_show_params_t *params)
+			     notmuch_show_params_t *params,
+			     notmuch_bool_t reply_all)
 {
     GMimeMessage *reply;
     notmuch_messages_t *messages;
@@ -509,7 +517,8 @@ notmuch_reply_format_default(void *ctx,
 	    g_mime_message_set_subject (reply, subject);
 	}
 
-	from_addr = add_recipients_from_message (reply, config, message);
+	from_addr = add_recipients_from_message (reply, config, message,
+						 reply_all);
 
 	if (from_addr == NULL)
 	    from_addr = guess_from_received_header (config, message);
@@ -558,7 +567,8 @@ static int
 notmuch_reply_format_headers_only(void *ctx,
 				  notmuch_config_t *config,
 				  notmuch_query_t *query,
-				  unused (notmuch_show_params_t *params))
+				  unused (notmuch_show_params_t *params),
+				  notmuch_bool_t reply_all)
 {
     GMimeMessage *reply;
     notmuch_messages_t *messages;
@@ -598,7 +608,7 @@ notmuch_reply_format_headers_only(void *ctx,
 	g_mime_object_set_header (GMIME_OBJECT (reply),
 				  "References", references);
 
-	(void)add_recipients_from_message (reply, config, message);
+	(void)add_recipients_from_message (reply, config, message, reply_all);
 
 	reply_headers = g_mime_object_to_string (GMIME_OBJECT (reply));
 	printf ("%s", reply_headers);
@@ -625,10 +635,11 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
     notmuch_query_t *query;
     char *query_string;
     int opt_index, ret = 0;
-    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params);
+    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params, notmuch_bool_t reply_all);
     notmuch_show_params_t params = { .part = -1 };
     int format = FORMAT_DEFAULT;
     notmuch_bool_t decrypt = FALSE;
+    notmuch_bool_t no_reply_all = FALSE;
 
     notmuch_opt_desc_t options[] = {
 	{ NOTMUCH_OPT_KEYWORD, &format, "format", 'f',
@@ -636,6 +647,7 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 				  { "headers-only", FORMAT_HEADERS_ONLY },
 				  { 0, 0 } } },
 	{ NOTMUCH_OPT_BOOLEAN, &decrypt, "decrypt", 'd', 0 },
+	{ NOTMUCH_OPT_BOOLEAN, &no_reply_all, "no-reply-all", 'r', 0 },
 	{ 0, 0, 0, 0, 0 }
     };
 
@@ -688,7 +700,7 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 	return 1;
     }
 
-    if (reply_format_func (ctx, config, query, &params) != 0)
+    if (reply_format_func (ctx, config, query, &params, !no_reply_all) != 0)
 	return 1;
 
     notmuch_query_destroy (query);
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 4/4] emacs: add support for replying just to the sender of messages and threads
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (2 preceding siblings ...)
  2012-01-05 20:25 ` [PATCH 3/4] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
@ 2012-01-05 20:25 ` Jani Nikula
  2012-01-05 20:33 ` [PATCH 0/4] notmuch reply bugfix & reply to sender only Jameson Graef Rollins
                   ` (27 subsequent siblings)
  31 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-05 20:25 UTC (permalink / raw)
  To: notmuch, david

Make the search and show reply functions reply just to the sender, and
provide reply-all counterparts to reply to all. Add key binding 'R' to
reply to sender, while keeping 'r' as reply-to-all, both in search and show
views.

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 emacs/notmuch-mua.el  |    8 +++++---
 emacs/notmuch-show.el |   12 +++++++++---
 emacs/notmuch.el      |   11 +++++++++--
 3 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 7114e48..3cdf360 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -71,12 +71,14 @@ list."
 	    (push header message-hidden-headers)))
 	notmuch-mua-hidden-headers))
 
-(defun notmuch-mua-reply (query-string &optional sender)
+(defun notmuch-mua-reply (query-string &optional reply-all sender)
   (let (headers
 	body
 	(args '("reply")))
     (if notmuch-show-process-crypto
 	(setq args (append args '("--decrypt"))))
+    (unless reply-all
+      (setq args (append args '("--no-reply-all"))))
     (setq args (append args (list query-string)))
     ;; This make assumptions about the output of `notmuch reply', but
     ;; really only that the headers come first followed by a blank
@@ -217,13 +219,13 @@ the From: address first."
 	(notmuch-mua-forward-message))
     (notmuch-mua-forward-message)))
 
-(defun notmuch-mua-new-reply (query-string &optional prompt-for-sender)
+(defun notmuch-mua-new-reply (query-string &optional reply-all prompt-for-sender)
   "Invoke the notmuch reply window."
   (interactive "P")
   (let ((sender
 	 (when prompt-for-sender
 	   (notmuch-mua-prompt-for-sender))))
-    (notmuch-mua-reply query-string sender)))
+    (notmuch-mua-reply query-string reply-all sender)))
 
 (defun notmuch-mua-send-and-exit (&optional arg)
   (interactive "P")
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 5502efd..6f812d8 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -932,7 +932,8 @@ thread id.  If a prefix is given, crypto processing is toggled."
 	(define-key map "s" 'notmuch-search)
 	(define-key map "m" 'notmuch-mua-new-mail)
 	(define-key map "f" 'notmuch-show-forward-message)
-	(define-key map "r" 'notmuch-show-reply)
+	(define-key map "r" 'notmuch-show-reply-all)
+	(define-key map "R" 'notmuch-show-reply)
 	(define-key map "|" 'notmuch-show-pipe-message)
 	(define-key map "w" 'notmuch-show-save-attachments)
 	(define-key map "V" 'notmuch-show-view-raw-message)
@@ -1237,9 +1238,14 @@ any effects from previous calls to
       (notmuch-show-previous-message)))))
 
 (defun notmuch-show-reply (&optional prompt-for-sender)
-  "Reply to the current message."
+  "Reply to the sender of the current message."
   (interactive "P")
-  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender))
+  (notmuch-mua-new-reply (notmuch-show-get-message-id) nil prompt-for-sender))
+
+(defun notmuch-show-reply-all (&optional prompt-for-sender)
+  "Reply to the sender and all recipients of the current message."
+  (interactive "P")
+  (notmuch-mua-new-reply (notmuch-show-get-message-id) t prompt-for-sender))
 
 (defun notmuch-show-forward-message (&optional prompt-for-sender)
   "Forward the current message."
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index fde2377..bd1fd4f 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -206,7 +206,8 @@ For a mouse binding, return nil."
     (define-key map ">" 'notmuch-search-last-thread)
     (define-key map "p" 'notmuch-search-previous-thread)
     (define-key map "n" 'notmuch-search-next-thread)
-    (define-key map "r" 'notmuch-search-reply-to-thread)
+    (define-key map "r" 'notmuch-search-reply-all-to-thread)
+    (define-key map "R" 'notmuch-search-reply-to-thread)
     (define-key map "m" 'notmuch-mua-new-mail)
     (define-key map "s" 'notmuch-search)
     (define-key map "o" 'notmuch-search-toggle-order)
@@ -444,7 +445,13 @@ Complete list of currently available key bindings:
   "Begin composing a reply to the entire current thread in a new buffer."
   (interactive "P")
   (let ((message-id (notmuch-search-find-thread-id)))
-    (notmuch-mua-new-reply message-id prompt-for-sender)))
+    (notmuch-mua-new-reply message-id nil prompt-for-sender)))
+
+(defun notmuch-search-reply-all-to-thread (&optional prompt-for-sender)
+  "Begin composing a reply-all to the entire current thread in a new buffer."
+  (interactive "P")
+  (let ((message-id (notmuch-search-find-thread-id)))
+    (notmuch-mua-new-reply message-id t prompt-for-sender)))
 
 (defun notmuch-call-notmuch-process (&rest args)
   "Synchronously invoke \"notmuch\" with the given list of arguments.
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* Re: [PATCH 0/4] notmuch reply bugfix & reply to sender only
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (3 preceding siblings ...)
  2012-01-05 20:25 ` [PATCH 4/4] emacs: add support for replying just to the sender of messages and threads Jani Nikula
@ 2012-01-05 20:33 ` Jameson Graef Rollins
  2012-01-07 19:25   ` Mueen Nawaz
  2012-01-05 22:01 ` Mark Walters
                   ` (26 subsequent siblings)
  31 siblings, 1 reply; 81+ messages in thread
From: Jameson Graef Rollins @ 2012-01-05 20:33 UTC (permalink / raw)
  To: Jani Nikula, notmuch, david

[-- Attachment #1: Type: text/plain, Size: 711 bytes --]

On Thu,  5 Jan 2012 22:25:11 +0200, Jani Nikula <jani@nikula.org> wrote:
> Bikeshedding topic #1: How about making replying to just the sender the default
> in "notmuch reply", and having --reply-all option (instead of --no-reply-all)?
> 
> Bikeshedding topic #2: How about binding 'r' to reply to just the sender by
> default, and making 'R' reply-all (instead of vice versa)?

I personally like both of these suggestions, and would not be bothered
by the changed default, so I support both of these changes.

Maybe we could just use '--all', instead of '--reply-all'?  The 'reply'
part seems kind of redundant with the command:

notmuch reply --all

vs.

notmuch reply --reply-all

jamie.

[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 0/4] notmuch reply bugfix & reply to sender only
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (4 preceding siblings ...)
  2012-01-05 20:33 ` [PATCH 0/4] notmuch reply bugfix & reply to sender only Jameson Graef Rollins
@ 2012-01-05 22:01 ` Mark Walters
  2012-01-06 12:34   ` Jani Nikula
  2012-01-06  0:01 ` Adam Wolfe Gordon
                   ` (25 subsequent siblings)
  31 siblings, 1 reply; 81+ messages in thread
From: Mark Walters @ 2012-01-05 22:01 UTC (permalink / raw)
  To: Jani Nikula, notmuch, david


Hello


> Bikeshedding topic #1: How about making replying to just the sender the default
> in "notmuch reply", and having --reply-all option (instead of --no-reply-all)?

In id:"87pqn5cg4g.fsf@yoom.home.cworth.org" cworth suggested using
--reply-to=sender vs. --reply-to=all (keeping the latter the default).

(This was in response to a patch set I submitted implementing a
reply-to-sender option (*))

> Bikeshedding topic #2: How about binding 'r' to reply to just the sender by
> default, and making 'R' reply-all (instead of vice versa)?

Personally I would prefer this but it is easy to customise.

However, one more significant choice is what to do on reply-to-sender to
an email from the user himself. My patch used the following logic: look
at the reply-to, from , to, cc lines until you find a non-user address
and use that line for the reply. My recollection is that this is roughly
what mutt does.

At least for the common "from user" cases mutt does 
reply-to-one : just to to: person
group-reply: to to: and cc: people

Best wishes

Mark

(*) I have a version of that patch-set which applies to master if that
would be useful to anyone, and I recently started writing tests in
preparation for re-submitting.

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 0/4] notmuch reply bugfix & reply to sender only
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (5 preceding siblings ...)
  2012-01-05 22:01 ` Mark Walters
@ 2012-01-06  0:01 ` Adam Wolfe Gordon
  2012-01-06 22:11   ` Tomi Ollila
  2012-01-06  8:54 ` David Edmondson
                   ` (24 subsequent siblings)
  31 siblings, 1 reply; 81+ messages in thread
From: Adam Wolfe Gordon @ 2012-01-06  0:01 UTC (permalink / raw)
  To: Jani Nikula; +Cc: notmuch

On Thu, Jan 5, 2012 at 13:25, Jani Nikula <jani@nikula.org> wrote:
> Bikeshedding topic #1: How about making replying to just the sender the default
> in "notmuch reply", and having --reply-all option (instead of --no-reply-all)?
>
> Bikeshedding topic #2: How about binding 'r' to reply to just the sender by
> default, and making 'R' reply-all (instead of vice versa)?

I like both these suggestions.  This would bring the notmuch behavior
in line with gmail, which is what I tend to expect.

Mark Walters brings up a good point, that there is a question of what
to do when the user tries to reply to their own email.  When I do
this, what I intend is to send another email to the last person I
emailed in the thread, so I think the suggested heuristic of looking
at other headers would work.  But, maybe others have a different
expectation in this case?

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 1/4] cli: fix use of uninitialized variable in "notmuch reply"
  2012-01-05 20:25 ` [PATCH 1/4] cli: fix use of uninitialized variable in "notmuch reply" Jani Nikula
@ 2012-01-06  3:22   ` David Bremner
  2012-01-06  8:11     ` Jani Nikula
  2012-01-07  3:52   ` David Bremner
  1 sibling, 1 reply; 81+ messages in thread
From: David Bremner @ 2012-01-06  3:22 UTC (permalink / raw)
  To: Jani Nikula, notmuch

On Thu,  5 Jan 2012 22:25:12 +0200, Jani Nikula <jani@nikula.org> wrote:
> -    notmuch_show_params_t params;
> +    notmuch_show_params_t params = { .part = -1 };
>  
>      reply_format_func = notmuch_reply_format_default;
> -    params.part = -1;

Do I understand correctly that this is just a style change, or do you
rely on some c99(?) behaviour of initializing the other elements to 0?

d

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 1/4] cli: fix use of uninitialized variable in "notmuch reply"
  2012-01-06  3:22   ` David Bremner
@ 2012-01-06  8:11     ` Jani Nikula
  2012-01-06 11:57       ` David Bremner
  0 siblings, 1 reply; 81+ messages in thread
From: Jani Nikula @ 2012-01-06  8:11 UTC (permalink / raw)
  To: David Bremner, notmuch

On Thu, 05 Jan 2012 23:22:34 -0400, David Bremner <david@tethera.net> wrote:
> On Thu,  5 Jan 2012 22:25:12 +0200, Jani Nikula <jani@nikula.org> wrote:
> > -    notmuch_show_params_t params;
> > +    notmuch_show_params_t params = { .part = -1 };
> >  
> >      reply_format_func = notmuch_reply_format_default;
> > -    params.part = -1;
> 
> Do I understand correctly that this is just a style change, or do you
> rely on some c99(?) behaviour of initializing the other elements to 0?

It is not just a style change, and initializing a struct partially
initializes the rest of the elements to 0. That's not C99 specific
behaviour, though using the designated initializer to initialize .part
to -1 is.

All of these result in the same value for params:

	notmuch_show_params_t params = { .part = -1 };

	notmuch_show_params_t params = { 0, 0, -1 };

	notmuch_show_params_t params = { 0, 0, -1, NULL, 0 };

	notmuch_show_params_t params = { 0 };
	params.part = -1;

IMHO the first is cleanest and unaffected by changes in
notmuch_show_params_t, though might be surprising if you're not (yet)
used to C99 designated initializers.

In any case, in the current implementation only .part and .cryptoctx are
initialized, and the rest of the fields are random. This needs to be
fixed one way or another.


BR,
Jani.

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 0/4] notmuch reply bugfix & reply to sender only
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (6 preceding siblings ...)
  2012-01-06  0:01 ` Adam Wolfe Gordon
@ 2012-01-06  8:54 ` David Edmondson
  2012-01-08 21:48 ` [PATCH v2 0/6] reply to sender Jani Nikula
                   ` (23 subsequent siblings)
  31 siblings, 0 replies; 81+ messages in thread
From: David Edmondson @ 2012-01-06  8:54 UTC (permalink / raw)
  To: Jani Nikula, notmuch, david

[-- Attachment #1: Type: text/plain, Size: 458 bytes --]

On Thu,  5 Jan 2012 22:25:11 +0200, Jani Nikula <jani@nikula.org> wrote:
> Bikeshedding topic #1: How about making replying to just the sender the default
> in "notmuch reply", and having --reply-all option (instead of --no-reply-all)?

No strong opinion (I hardly ever use the CLI directly).

> Bikeshedding topic #2: How about binding 'r' to reply to just the sender by
> default, and making 'R' reply-all (instead of vice versa)?

I'd be happy with that.

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 1/4] cli: fix use of uninitialized variable in "notmuch reply"
  2012-01-06  8:11     ` Jani Nikula
@ 2012-01-06 11:57       ` David Bremner
  0 siblings, 0 replies; 81+ messages in thread
From: David Bremner @ 2012-01-06 11:57 UTC (permalink / raw)
  To: Jani Nikula, notmuch

On Fri, 06 Jan 2012 10:11:42 +0200, Jani Nikula <jani@nikula.org> wrote:

> IMHO the first is cleanest and unaffected by changes in
> notmuch_show_params_t, though might be surprising if you're not (yet)
> used to C99 designated initializers.

Obviously not ;). It would nice to have a consensus about the use of C99
features in the notmuch code. Personally I think it's fine, but I know
we have had some back and forth about e.g. mid-block variable declarations.

> In any case, in the current implementation only .part and .cryptoctx are
> initialized, and the rest of the fields are random. This needs to be
> fixed one way or another.

Agreed.

d

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 0/4] notmuch reply bugfix & reply to sender only
  2012-01-05 22:01 ` Mark Walters
@ 2012-01-06 12:34   ` Jani Nikula
  2012-01-06 13:32     ` Mark Walters
  2012-01-06 14:20     ` [PATCH 0/4] notmuch reply bugfix & reply to sender only Mark Walters
  0 siblings, 2 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-06 12:34 UTC (permalink / raw)
  To: Mark Walters, notmuch, david


Hi Mark -

On Thu, 05 Jan 2012 22:01:30 +0000, Mark Walters <markwalters1009@gmail.com> wrote:
> > Bikeshedding topic #1: How about making replying to just the sender the default
> > in "notmuch reply", and having --reply-all option (instead of --no-reply-all)?
> 
> In id:"87pqn5cg4g.fsf@yoom.home.cworth.org" cworth suggested using
> --reply-to=sender vs. --reply-to=all (keeping the latter the default).

That is a sound proposal too, leaving room for extension if such need
might arise.

> However, one more significant choice is what to do on reply-to-sender to
> an email from the user himself. My patch used the following logic: look
> at the reply-to, from , to, cc lines until you find a non-user address
> and use that line for the reply. My recollection is that this is roughly
> what mutt does.

That is a very good point, and one that my patch fails to address.

> (*) I have a version of that patch-set which applies to master if that
> would be useful to anyone, and I recently started writing tests in
> preparation for re-submitting.

Ah, it's old, no wonder I didn't know about it. Looking at the v2 of it
that I found gmane, it looks like the approach is roughly the same.

I think me passing the 'add' parameter makes things a bit more obvious
and explicit, while your use of "g_mime_message_get_all_recipients
(reply) == NULL" might be more robust (including handling reply to
user's own message). Switching to new style argument parsing is probably
something David will insist on, and that's a ready, independent patch in
my set. On emacs side I think my patch is just slightly cleaner, but no
big difference.

How about you post what you have now as a reply to this thread, and let
others be the judge? I really don't mind whether it's you or I who
finishes this as long as we get the feature, and preferrably combining
the best of what we both have. I'm also open to splitting this between
you and me; just let me know what you think.


BR,
Jani.

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 0/4] notmuch reply bugfix & reply to sender only
  2012-01-06 12:34   ` Jani Nikula
@ 2012-01-06 13:32     ` Mark Walters
  2012-01-06 13:34       ` [PATCH 1/4] Add the option "--reply-to" to notmuch reply Mark Walters
                         ` (3 more replies)
  2012-01-06 14:20     ` [PATCH 0/4] notmuch reply bugfix & reply to sender only Mark Walters
  1 sibling, 4 replies; 81+ messages in thread
From: Mark Walters @ 2012-01-06 13:32 UTC (permalink / raw)
  To: Jani Nikula, notmuch, david



> That is a very good point, and one that my patch fails to address.
> 
> > (*) I have a version of that patch-set which applies to master if that
> > would be useful to anyone, and I recently started writing tests in
> > preparation for re-submitting.
> 
> Ah, it's old, no wonder I didn't know about it. Looking at the v2 of it
> that I found gmane, it looks like the approach is roughly the same.
> 
> I think me passing the 'add' parameter makes things a bit more obvious
> and explicit, while your use of "g_mime_message_get_all_recipients
> (reply) == NULL" might be more robust (including handling reply to
> user's own message). Switching to new style argument parsing is probably
> something David will insist on, and that's a ready, independent patch in
> my set. On emacs side I think my patch is just slightly cleaner, but no
> big difference.

I have not had a chance to look at your code yet: I will try to do so
this afternoon.

> How about you post what you have now as a reply to this thread, and let
> others be the judge? I really don't mind whether it's you or I who
> finishes this as long as we get the feature, and preferrably combining
> the best of what we both have. I'm also open to splitting this between
> you and me; just let me know what you think.

I will post it as a reply to this message. I don't mind which version
goes in either (but it would  be nice if some version did!)

Best wishes

Mark

^ permalink raw reply	[flat|nested] 81+ messages in thread

* [PATCH 1/4] Add the option "--reply-to" to notmuch reply.
  2012-01-06 13:32     ` Mark Walters
@ 2012-01-06 13:34       ` Mark Walters
  2012-01-08 12:47         ` Jani Nikula
  2012-01-06 13:34       ` [PATCH 2/4] Update the man page for notmuch-reply to give the syntax for the --reply-to option Mark Walters
                         ` (2 subsequent siblings)
  3 siblings, 1 reply; 81+ messages in thread
From: Mark Walters @ 2012-01-06 13:34 UTC (permalink / raw)
  To: Jani Nikula, notmuch, david

    Possible values for this option are "sender" which replies just to
    sender and "all" (the default).

    More precisely reply to sender follows these rules:
    reply only to sender unless it was the user
    reply only to all people on the "to" line unless they were all the user
    reply to all people on the "cc" line

    Implementation details

    We continue parsing addresses beyond the ones we reply to because
    we want to make sure the from address is correct. (At the very least it
    is the same as it would be if we replied to all.)

    We overload the message variable in add_recipients_for_address_list so
    if it is NULL we parse the address (looking for the users address)
    but do not add to the message recipients list

    We add the variable reply_to_all to the function chain to keep track
    of whether we should reply to everyone.
---
 notmuch-reply.c |   48 +++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index f8d5f64..9a77fe6 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -212,7 +212,8 @@ add_recipients_for_address_list (GMimeMessage *message,
 		if (ret == NULL)
 		    ret = addr;
 	    } else {
-		g_mime_message_add_recipient (message, type, name, addr);
+		 if (message)
+		      g_mime_message_add_recipient (message, type, name, addr);
 	    }
 	}
     }
@@ -292,7 +293,8 @@ reply_to_header_is_redundant (notmuch_message_t *message)
 static const char *
 add_recipients_from_message (GMimeMessage *reply,
 			     notmuch_config_t *config,
-			     notmuch_message_t *message)
+			     notmuch_message_t *message,
+			     int reply_to_all)
 {
     struct {
 	const char *header;
@@ -332,9 +334,20 @@ add_recipients_from_message (GMimeMessage *reply,
 	    recipients = notmuch_message_get_header (message,
 						     reply_to_map[i].fallback);
 
-	addr = add_recipients_for_string (reply, config,
-					  reply_to_map[i].recipient_type,
-					  recipients);
+
+	/* We add the addresses if we are replying to all or we have not yet found
+	 * a non-user address. We have to keep parsing to make sure we do find the
+	 * correct from address for the user, but we pass a NULL message
+	 */
+	if ((reply_to_all) || (g_mime_message_get_all_recipients (reply) == NULL))
+	    addr = add_recipients_for_string (reply, config,
+					      reply_to_map[i].recipient_type,
+					      recipients);
+	else
+	     addr = add_recipients_for_string (NULL, config,
+					       reply_to_map[i].recipient_type,
+					       recipients);
+
 	if (from_addr == NULL)
 	    from_addr = addr;
     }
@@ -480,7 +493,8 @@ static int
 notmuch_reply_format_default(void *ctx,
 			     notmuch_config_t *config,
 			     notmuch_query_t *query,
-			     notmuch_show_params_t *params)
+			     notmuch_show_params_t *params,
+			     int reply_to_all)
 {
     GMimeMessage *reply;
     notmuch_messages_t *messages;
@@ -509,7 +523,7 @@ notmuch_reply_format_default(void *ctx,
 	    g_mime_message_set_subject (reply, subject);
 	}
 
-	from_addr = add_recipients_from_message (reply, config, message);
+	from_addr = add_recipients_from_message (reply, config, message, reply_to_all);
 
 	if (from_addr == NULL)
 	    from_addr = guess_from_received_header (config, message);
@@ -558,7 +572,8 @@ static int
 notmuch_reply_format_headers_only(void *ctx,
 				  notmuch_config_t *config,
 				  notmuch_query_t *query,
-				  unused (notmuch_show_params_t *params))
+				  unused (notmuch_show_params_t *params),
+				  int reply_to_all)
 {
     GMimeMessage *reply;
     notmuch_messages_t *messages;
@@ -598,7 +613,7 @@ notmuch_reply_format_headers_only(void *ctx,
 	g_mime_object_set_header (GMIME_OBJECT (reply),
 				  "References", references);
 
-	(void)add_recipients_from_message (reply, config, message);
+	(void)add_recipients_from_message (reply, config, message, reply_to_all);
 
 	reply_headers = g_mime_object_to_string (GMIME_OBJECT (reply));
 	printf ("%s", reply_headers);
@@ -620,7 +635,8 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
     notmuch_query_t *query;
     char *opt, *query_string;
     int i, ret = 0;
-    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params);
+    int reply_to_all = 1;
+    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params, int reply_to_all);
     notmuch_show_params_t params;
 
     reply_format_func = notmuch_reply_format_default;
@@ -654,6 +670,16 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 		g_object_unref (session);
 		session = NULL;
 	    }
+	} else if (STRNCMP_LITERAL (argv[i], "--reply-to=") == 0) {
+	    opt = argv[i] + sizeof ("--reply-to=") - 1;
+	    if (strcmp (opt, "sender") == 0) {
+		 reply_to_all = 0;
+	    } else if (strcmp (opt, "all") == 0) {
+		 reply_to_all = 1;
+	    } else {
+		 fprintf (stderr, "Invalid value for --reply-to: %s\n", opt);
+		 return 1;
+	    }
 	} else {
 	    fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
 	    return 1;
@@ -689,7 +715,7 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 	return 1;
     }
 
-    if (reply_format_func (ctx, config, query, &params) != 0)
+    if (reply_format_func (ctx, config, query, &params, reply_to_all) != 0)
 	return 1;
 
     notmuch_query_destroy (query);
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 2/4] Update the man page for notmuch-reply to give the syntax for the --reply-to option.
  2012-01-06 13:32     ` Mark Walters
  2012-01-06 13:34       ` [PATCH 1/4] Add the option "--reply-to" to notmuch reply Mark Walters
@ 2012-01-06 13:34       ` Mark Walters
  2012-01-06 13:34       ` [PATCH 3/4] Emacs changes for reply-to-sender Mark Walters
  2012-01-06 13:34       ` [PATCH 4/4] add tests " Mark Walters
  3 siblings, 0 replies; 81+ messages in thread
From: Mark Walters @ 2012-01-06 13:34 UTC (permalink / raw)
  To: Jani Nikula, notmuch, david

---
 man/man1/notmuch-reply.1 |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1
index 099d808..13cc72c 100644
--- a/man/man1/notmuch-reply.1
+++ b/man/man1/notmuch-reply.1
@@ -45,6 +45,19 @@ Includes subject and quoted message body.
 Only produces In\-Reply\-To, References, To, Cc, and Bcc headers.
 .RE
 .RE
+.RS
+.TP 4
+.BR \-\-reply\-to= ( sender | all )
+.RS
+.TP 4
+.BR sender
+Replies only to the sender (or to all addresses in the To header if
+the sending address is one of the user's email addresses).
+.TP
+.BR all " (default)"
+Replies to all addresses.
+.RE
+.RE
 
 See \fBnotmuch-search-terms\fR(7)
 for details of the supported syntax for <search-terms>.
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 3/4] Emacs changes for reply-to-sender
  2012-01-06 13:32     ` Mark Walters
  2012-01-06 13:34       ` [PATCH 1/4] Add the option "--reply-to" to notmuch reply Mark Walters
  2012-01-06 13:34       ` [PATCH 2/4] Update the man page for notmuch-reply to give the syntax for the --reply-to option Mark Walters
@ 2012-01-06 13:34       ` Mark Walters
  2012-01-06 13:34       ` [PATCH 4/4] add tests " Mark Walters
  3 siblings, 0 replies; 81+ messages in thread
From: Mark Walters @ 2012-01-06 13:34 UTC (permalink / raw)
  To: Jani Nikula, notmuch, david

    Reply to sender is currently bound to R
---
 emacs/notmuch-mua.el  |    8 +++++---
 emacs/notmuch-show.el |    8 +++++++-
 emacs/notmuch.el      |    2 +-
 3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 7114e48..7171210 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -71,12 +71,14 @@ list."
 	    (push header message-hidden-headers)))
 	notmuch-mua-hidden-headers))
 
-(defun notmuch-mua-reply (query-string &optional sender)
+(defun notmuch-mua-reply (query-string option-string &optional sender)
   (let (headers
 	body
 	(args '("reply")))
     (if notmuch-show-process-crypto
 	(setq args (append args '("--decrypt"))))
+    (if option-string
+	(setq args (append args (list option-string))))
     (setq args (append args (list query-string)))
     ;; This make assumptions about the output of `notmuch reply', but
     ;; really only that the headers come first followed by a blank
@@ -217,13 +219,13 @@ the From: address first."
 	(notmuch-mua-forward-message))
     (notmuch-mua-forward-message)))
 
-(defun notmuch-mua-new-reply (query-string &optional prompt-for-sender)
+(defun notmuch-mua-new-reply (query-string option-string &optional prompt-for-sender)
   "Invoke the notmuch reply window."
   (interactive "P")
   (let ((sender
 	 (when prompt-for-sender
 	   (notmuch-mua-prompt-for-sender))))
-    (notmuch-mua-reply query-string sender)))
+    (notmuch-mua-reply query-string option-string sender)))
 
 (defun notmuch-mua-send-and-exit (&optional arg)
   (interactive "P")
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 5502efd..40bea0c 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -933,6 +933,7 @@ thread id.  If a prefix is given, crypto processing is toggled."
 	(define-key map "m" 'notmuch-mua-new-mail)
 	(define-key map "f" 'notmuch-show-forward-message)
 	(define-key map "r" 'notmuch-show-reply)
+	(define-key map "R" 'notmuch-show-reply-sender)
 	(define-key map "|" 'notmuch-show-pipe-message)
 	(define-key map "w" 'notmuch-show-save-attachments)
 	(define-key map "V" 'notmuch-show-view-raw-message)
@@ -1239,7 +1240,12 @@ any effects from previous calls to
 (defun notmuch-show-reply (&optional prompt-for-sender)
   "Reply to the current message."
   (interactive "P")
-  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender))
+  (notmuch-mua-new-reply (notmuch-show-get-message-id) nil prompt-for-sender))
+
+(defun notmuch-show-reply-sender (&optional prompt-for-sender)
+  "Reply to the current message but only to sender."
+  (interactive "P")
+  (notmuch-mua-new-reply (notmuch-show-get-message-id) "--reply-to=sender" prompt-for-sender))
 
 (defun notmuch-show-forward-message (&optional prompt-for-sender)
   "Forward the current message."
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index fde2377..022b867 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -444,7 +444,7 @@ Complete list of currently available key bindings:
   "Begin composing a reply to the entire current thread in a new buffer."
   (interactive "P")
   (let ((message-id (notmuch-search-find-thread-id)))
-    (notmuch-mua-new-reply message-id prompt-for-sender)))
+    (notmuch-mua-new-reply message-id nil prompt-for-sender)))
 
 (defun notmuch-call-notmuch-process (&rest args)
   "Synchronously invoke \"notmuch\" with the given list of arguments.
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 4/4] add tests for reply-to-sender
  2012-01-06 13:32     ` Mark Walters
                         ` (2 preceding siblings ...)
  2012-01-06 13:34       ` [PATCH 3/4] Emacs changes for reply-to-sender Mark Walters
@ 2012-01-06 13:34       ` Mark Walters
  3 siblings, 0 replies; 81+ messages in thread
From: Mark Walters @ 2012-01-06 13:34 UTC (permalink / raw)
  To: Jani Nikula, notmuch, david

---
 test/notmuch-test    |    1 +
 test/reply-to-sender |  209 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 210 insertions(+), 0 deletions(-)
 create mode 100755 test/reply-to-sender

diff --git a/test/notmuch-test b/test/notmuch-test
index e40ef86..6a99ae3 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -33,6 +33,7 @@ TESTS="
   thread-naming
   raw
   reply
+  reply-to-sender
   dump-restore
   uuencode
   thread-order
diff --git a/test/reply-to-sender b/test/reply-to-sender
new file mode 100755
index 0000000..c7d15bb
--- /dev/null
+++ b/test/reply-to-sender
@@ -0,0 +1,209 @@
+#!/usr/bin/env bash
+test_description="\"notmuch reply --reply-to=sender\" in several variations"
+. ./test-lib.sh
+
+test_begin_subtest "Basic reply-to-sender"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="basic reply-to-sender test"'
+
+output=$(notmuch reply --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> basic reply-to-sender test"
+
+test_begin_subtest "From Us, Basic reply to message"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[to]="Recipient <recipient@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="basic reply-to-from-us test"'
+
+output=$(notmuch reply --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Recipient <recipient@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> basic reply-to-from-us test"
+
+test_begin_subtest "Multiple recipients"
+add_message '[from]="Sender <sender@example.com>"' \
+            '[to]="test_suite@notmuchmail.org, Someone Else <someone@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="Multiple recipients"'
+
+output=$(notmuch reply  --reply-to=sender  id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> Multiple recipients"
+
+test_begin_subtest "From Us, Multiple TO recipients"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[to]="Recipient <recipient@example.com>, Someone Else <someone@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="From Us, Multiple TO recipients"'
+
+output=$(notmuch reply  --reply-to=sender  id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Recipient <recipient@example.com>, Someone Else <someone@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> From Us, Multiple TO recipients"
+
+test_begin_subtest "Reply with CC"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+            '[cc]="Other Parties <cc@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> reply with CC"
+
+test_begin_subtest "From Us, Reply with CC"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[to]="Recipient <recipient@example.com>"' \
+            '[cc]="Other Parties <cc@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Recipient <recipient@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> reply with CC"
+
+test_begin_subtest "From Us, Reply no TO but with CC"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[cc]="Other Parties <cc@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+Cc: Other Parties <cc@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> reply with CC"
+
+test_begin_subtest "Reply from alternate address"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite_other@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply from alternate address"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite_other@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> reply from alternate address"
+
+test_begin_subtest "Support for Reply-To"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="support for reply-to"' \
+            '[reply-to]="Sender <elsewhere@example.com>"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <elsewhere@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> support for reply-to"
+
+test_begin_subtest "Support for Reply-To with multiple recipients"
+add_message '[from]="Sender <sender@example.com>"' \
+            '[to]="test_suite@notmuchmail.org, Someone Else <someone@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="support for reply-to with multiple recipients"' \
+            '[reply-to]="Sender <elsewhere@example.com>"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <elsewhere@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> support for reply-to with multiple recipients"
+
+test_begin_subtest "Un-munging Reply-To"
+add_message '[from]="Sender <sender@example.com>"' \
+            '[to]="Some List <list@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="Un-munging Reply-To"' \
+            '[reply-to]="Evil Munging List <list@example.com>"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> Un-munging Reply-To"
+
+test_begin_subtest "Message with header of exactly 200 bytes"
+add_message '[subject]="This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces"' \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="200-byte header"'
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> 200-byte header"
+test_done
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* Re: [PATCH 0/4] notmuch reply bugfix & reply to sender only
  2012-01-06 12:34   ` Jani Nikula
  2012-01-06 13:32     ` Mark Walters
@ 2012-01-06 14:20     ` Mark Walters
  1 sibling, 0 replies; 81+ messages in thread
From: Mark Walters @ 2012-01-06 14:20 UTC (permalink / raw)
  To: Jani Nikula, notmuch, david


Hello

I have now compared the two patch sets. They seem very similar but I
think yours is a little bit nicer in all respects except I prefer my
use of "g_mime_message_get_all_recipients (reply) == NULL".

However, one case that is slightly less clear with my approach is
what to do about reply-to-thread (or indeed any reply to more than one
message). I did not add a reply-to-thread not_all option as I wasn't
sure what it should do. Perhaps we could even make reply-to-one return
an error if the search gives more than one message? 

Best wishes

Mark

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 0/4] notmuch reply bugfix & reply to sender only
  2012-01-06  0:01 ` Adam Wolfe Gordon
@ 2012-01-06 22:11   ` Tomi Ollila
  0 siblings, 0 replies; 81+ messages in thread
From: Tomi Ollila @ 2012-01-06 22:11 UTC (permalink / raw)
  To: Adam Wolfe Gordon, Jani Nikula; +Cc: notmuch

On Thu, 5 Jan 2012 17:01:44 -0700, Adam Wolfe Gordon <awg+notmuch@xvx.ca> wrote:
> On Thu, Jan 5, 2012 at 13:25, Jani Nikula <jani@nikula.org> wrote:
> > Bikeshedding topic #1: How about making replying to just the sender the default
> > in "notmuch reply", and having --reply-all option (instead of --no-reply-all)?
> >
> > Bikeshedding topic #2: How about binding 'r' to reply to just the sender by
> > default, and making 'R' reply-all (instead of vice versa)?
> 
> I like both these suggestions.  This would bring the notmuch behavior
> in line with gmail, which is what I tend to expect.

I'd like that. I've already once sent a 'group reply' when I intended
to sent to only one.

+1 for changing 'r' reply sender and 'R' reply all in emacs MUA.

> Mark Walters brings up a good point, that there is a question of what
> to do when the user tries to reply to their own email.  When I do
> this, what I intend is to send another email to the last person I
> emailed in the thread, so I think the suggested heuristic of looking
> at other headers would work.  But, maybe others have a different
> expectation in this case?

Hmm, let's see there was 'Some User(TM)' sending email, and I reply all
to that. If I reply (to sender) to the email I just sent, The recipient
could be 'Some User(TM)' instead of me. Interesting possibility.

Tomi

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 1/4] cli: fix use of uninitialized variable in "notmuch reply"
  2012-01-05 20:25 ` [PATCH 1/4] cli: fix use of uninitialized variable in "notmuch reply" Jani Nikula
  2012-01-06  3:22   ` David Bremner
@ 2012-01-07  3:52   ` David Bremner
  2012-01-07  7:31     ` Jani Nikula
  1 sibling, 1 reply; 81+ messages in thread
From: David Bremner @ 2012-01-07  3:52 UTC (permalink / raw)
  To: Jani Nikula, notmuch

On Thu,  5 Jan 2012 22:25:12 +0200, Jani Nikula <jani@nikula.org> wrote:
> notmuch_show_params_t params is only initialized partially in
> notmuch_reply_command(). The only field that is used uninitialized is
> params.decrypt. It is usually non-zero, making "notmuch reply" on encrypted
> messages work by coincidence.

Hi Jani;

I get one test failure with this patch on current master:

 FAIL   Reply within emacs
	--- emacs.24.expected	2012-01-07 03:47:50.000000000 +0000
	+++ emacs.24.output	2012-01-07 03:47:50.000000000 +0000
	@@ -1,5 +1,5 @@
	 From: Notmuch Test Suite <test_suite@notmuchmail.org>
	-To: user@example.com
	+To: 
	 Subject: Re: Testing message sent via SMTP
	 In-Reply-To: <XXX>
	 Fcc: /tmp/notmuch-dev-bremner/test/tmp.emacs/mail/sent

d

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 1/4] cli: fix use of uninitialized variable in "notmuch reply"
  2012-01-07  3:52   ` David Bremner
@ 2012-01-07  7:31     ` Jani Nikula
  2012-01-07 11:57       ` Mark Walters
  2012-01-07 12:14       ` David Bremner
  0 siblings, 2 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-07  7:31 UTC (permalink / raw)
  To: David Bremner; +Cc: notmuch

[-- Attachment #1: Type: text/plain, Size: 1061 bytes --]

On Jan 7, 2012 5:52 AM, "David Bremner" <david@tethera.net> wrote:
>
> On Thu,  5 Jan 2012 22:25:12 +0200, Jani Nikula <jani@nikula.org> wrote:
> > notmuch_show_params_t params is only initialized partially in
> > notmuch_reply_command(). The only field that is used uninitialized is
> > params.decrypt. It is usually non-zero, making "notmuch reply" on
encrypted
> > messages work by coincidence.
>
> Hi Jani;
>
> I get one test failure with this patch on current master:

Can't investigate right now, but did you try with just patch 1/4? (I really
should have separated the bug fix from the rest.)

J.

>
>  FAIL   Reply within emacs
>        --- emacs.24.expected   2012-01-07 03:47:50.000000000 +0000
>        +++ emacs.24.output     2012-01-07 03:47:50.000000000 +0000
>        @@ -1,5 +1,5 @@
>         From: Notmuch Test Suite <test_suite@notmuchmail.org>
>        -To: user@example.com
>        +To:
>         Subject: Re: Testing message sent via SMTP
>         In-Reply-To: <XXX>
>         Fcc: /tmp/notmuch-dev-bremner/test/tmp.emacs/mail/sent
>
> d

[-- Attachment #2: Type: text/html, Size: 1553 bytes --]

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 1/4] cli: fix use of uninitialized variable in "notmuch reply"
  2012-01-07  7:31     ` Jani Nikula
@ 2012-01-07 11:57       ` Mark Walters
  2012-01-07 12:14       ` David Bremner
  1 sibling, 0 replies; 81+ messages in thread
From: Mark Walters @ 2012-01-07 11:57 UTC (permalink / raw)
  To: Jani Nikula, David Bremner; +Cc: notmuch


Hello

I do not get the failure with just 1/4 applied but do with all 4
applied. The trivial patch below fixes it, but it might not be the best
solution.

The failure occurs because Jani's patch changes the behavior of a couple
of emacs/notmuch internal functions: the function
notmuch-search-reply-to-thread is renamed to
notmuch-search-reply-all-to-thread and a new
notmuch-search-reply-to-thread function is added (which does reply to
sender) and a similar change for notmuch-show-reply-.. . Since the
keybindings are also remapped the user will not notice any difference.

However, if the user has any key-bindings etc in their .emacs file the
behaviour could change. It might be preferable to keep the existing
functions as they are and give the new reply-to-sender functions a new
name.

Best wishes

Mark


diff --git a/test/emacs b/test/emacs
index a06c223..5047d46 100755
--- a/test/emacs
+++ b/test/emacs
@@ -258,7 +258,7 @@ test_expect_equal_file OUTPUT EXPECTED
 test_begin_subtest "Reply within emacs"
 test_emacs '(notmuch-search "subject:\"testing message sent via SMTP\"")
 	    (notmuch-test-wait)
-	    (notmuch-search-reply-to-thread)
+	    (notmuch-search-reply-all-to-thread)
 	    (test-output)'
 sed -i -e 's/^In-Reply-To: <.*>$/In-Reply-To: <XXX>/' OUTPUT
 cat <<EOF >EXPECTED

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* Re: [PATCH 1/4] cli: fix use of uninitialized variable in "notmuch reply"
  2012-01-07  7:31     ` Jani Nikula
  2012-01-07 11:57       ` Mark Walters
@ 2012-01-07 12:14       ` David Bremner
  1 sibling, 0 replies; 81+ messages in thread
From: David Bremner @ 2012-01-07 12:14 UTC (permalink / raw)
  To: Jani Nikula; +Cc: notmuch

On Sat, 7 Jan 2012 09:31:35 +0200, Jani Nikula <jani@nikula.org> wrote:
> On Jan 7, 2012 5:52 AM, "David Bremner" <david@tethera.net> wrote:
> >
> > On Thu,  5 Jan 2012 22:25:12 +0200, Jani Nikula <jani@nikula.org> wrote:
> > > notmuch_show_params_t params is only initialized partially in
> > > notmuch_reply_command(). The only field that is used uninitialized is
> > > params.decrypt. It is usually non-zero, making "notmuch reply" on
> encrypted
> > > messages work by coincidence.
> >
> > Hi Jani;
> >
> > I get one test failure with this patch on current master:
> 
> Can't investigate right now, but did you try with just patch 1/4? (I really
> should have separated the bug fix from the rest.)
> 
> J.
> 

Hi Jani;

I _thought_ I was applying just that one patch, but I can't duplicate
the error now, so I might have messed up using dme's new "patch
application wizard". So, nevermind, sorry for the noise.

d

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 0/4] notmuch reply bugfix & reply to sender only
  2012-01-05 20:33 ` [PATCH 0/4] notmuch reply bugfix & reply to sender only Jameson Graef Rollins
@ 2012-01-07 19:25   ` Mueen Nawaz
  0 siblings, 0 replies; 81+ messages in thread
From: Mueen Nawaz @ 2012-01-07 19:25 UTC (permalink / raw)
  To: notmuch

Jameson Graef Rollins
<jrollins@finestructure.net> writes:

> On Thu,  5 Jan 2012 22:25:11 +0200, Jani Nikula <jani@nikula.org> wrote:
>> Bikeshedding topic #1: How about making replying to just the sender the default
>> in "notmuch reply", and having --reply-all option (instead of --no-reply-all)?
>> 
>> Bikeshedding topic #2: How about binding 'r' to reply to just the sender by
>> default, and making 'R' reply-all (instead of vice versa)?
>
> I personally like both of these suggestions, and would not be bothered
> by the changed default, so I support both of these changes.

I too feel that 'r' should reply only to sender, and 'R' should reply
all. Having reply-all as default is a pain.

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 1/4] Add the option "--reply-to" to notmuch reply.
  2012-01-06 13:34       ` [PATCH 1/4] Add the option "--reply-to" to notmuch reply Mark Walters
@ 2012-01-08 12:47         ` Jani Nikula
  2012-01-08 15:08           ` Mark Walters
  0 siblings, 1 reply; 81+ messages in thread
From: Jani Nikula @ 2012-01-08 12:47 UTC (permalink / raw)
  To: Mark Walters, notmuch, david

On Fri,  6 Jan 2012 13:34:14 +0000, Mark Walters <markwalters1009@gmail.com> wrote:
>     Possible values for this option are "sender" which replies just to
>     sender and "all" (the default).
> 
>     More precisely reply to sender follows these rules:
>     reply only to sender unless it was the user
>     reply only to all people on the "to" line unless they were all the user
>     reply to all people on the "cc" line
> 
>     Implementation details
> 
>     We continue parsing addresses beyond the ones we reply to because
>     we want to make sure the from address is correct. (At the very least it
>     is the same as it would be if we replied to all.)
> 
>     We overload the message variable in add_recipients_for_address_list so
>     if it is NULL we parse the address (looking for the users address)
>     but do not add to the message recipients list
> 
>     We add the variable reply_to_all to the function chain to keep track
>     of whether we should reply to everyone.
> ---
>  notmuch-reply.c |   48 +++++++++++++++++++++++++++++++++++++-----------
>  1 files changed, 37 insertions(+), 11 deletions(-)
> 
> diff --git a/notmuch-reply.c b/notmuch-reply.c
> index f8d5f64..9a77fe6 100644
> --- a/notmuch-reply.c
> +++ b/notmuch-reply.c
> @@ -212,7 +212,8 @@ add_recipients_for_address_list (GMimeMessage *message,
>  		if (ret == NULL)
>  		    ret = addr;
>  	    } else {
> -		g_mime_message_add_recipient (message, type, name, addr);
> +		 if (message)
> +		      g_mime_message_add_recipient (message, type, name, addr);
>  	    }
>  	}
>      }
> @@ -292,7 +293,8 @@ reply_to_header_is_redundant (notmuch_message_t *message)
>  static const char *
>  add_recipients_from_message (GMimeMessage *reply,
>  			     notmuch_config_t *config,
> -			     notmuch_message_t *message)
> +			     notmuch_message_t *message,
> +			     int reply_to_all)
>  {
>      struct {
>  	const char *header;
> @@ -332,9 +334,20 @@ add_recipients_from_message (GMimeMessage *reply,
>  	    recipients = notmuch_message_get_header (message,
>  						     reply_to_map[i].fallback);
>  
> -	addr = add_recipients_for_string (reply, config,
> -					  reply_to_map[i].recipient_type,
> -					  recipients);
> +
> +	/* We add the addresses if we are replying to all or we have not yet found
> +	 * a non-user address. We have to keep parsing to make sure we do find the
> +	 * correct from address for the user, but we pass a NULL message
> +	 */
> +	if ((reply_to_all) || (g_mime_message_get_all_recipients (reply) == NULL))

Looking into this, it occurred to me g_mime_message_get_all_recipients()
allocates a new InternetAddressList when the return value is
non-NULL. Thus this leaks memory. OTOH allocating and deallocating for
this purpose seems suboptimal. I'll think this over.

BR,
Jani.



> +	    addr = add_recipients_for_string (reply, config,
> +					      reply_to_map[i].recipient_type,
> +					      recipients);
> +	else
> +	     addr = add_recipients_for_string (NULL, config,
> +					       reply_to_map[i].recipient_type,
> +					       recipients);
> +
>  	if (from_addr == NULL)
>  	    from_addr = addr;
>      }
> @@ -480,7 +493,8 @@ static int
>  notmuch_reply_format_default(void *ctx,
>  			     notmuch_config_t *config,
>  			     notmuch_query_t *query,
> -			     notmuch_show_params_t *params)
> +			     notmuch_show_params_t *params,
> +			     int reply_to_all)
>  {
>      GMimeMessage *reply;
>      notmuch_messages_t *messages;
> @@ -509,7 +523,7 @@ notmuch_reply_format_default(void *ctx,
>  	    g_mime_message_set_subject (reply, subject);
>  	}
>  
> -	from_addr = add_recipients_from_message (reply, config, message);
> +	from_addr = add_recipients_from_message (reply, config, message, reply_to_all);
>  
>  	if (from_addr == NULL)
>  	    from_addr = guess_from_received_header (config, message);
> @@ -558,7 +572,8 @@ static int
>  notmuch_reply_format_headers_only(void *ctx,
>  				  notmuch_config_t *config,
>  				  notmuch_query_t *query,
> -				  unused (notmuch_show_params_t *params))
> +				  unused (notmuch_show_params_t *params),
> +				  int reply_to_all)
>  {
>      GMimeMessage *reply;
>      notmuch_messages_t *messages;
> @@ -598,7 +613,7 @@ notmuch_reply_format_headers_only(void *ctx,
>  	g_mime_object_set_header (GMIME_OBJECT (reply),
>  				  "References", references);
>  
> -	(void)add_recipients_from_message (reply, config, message);
> +	(void)add_recipients_from_message (reply, config, message, reply_to_all);
>  
>  	reply_headers = g_mime_object_to_string (GMIME_OBJECT (reply));
>  	printf ("%s", reply_headers);
> @@ -620,7 +635,8 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
>      notmuch_query_t *query;
>      char *opt, *query_string;
>      int i, ret = 0;
> -    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params);
> +    int reply_to_all = 1;
> +    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params, int reply_to_all);
>      notmuch_show_params_t params;
>  
>      reply_format_func = notmuch_reply_format_default;
> @@ -654,6 +670,16 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
>  		g_object_unref (session);
>  		session = NULL;
>  	    }
> +	} else if (STRNCMP_LITERAL (argv[i], "--reply-to=") == 0) {
> +	    opt = argv[i] + sizeof ("--reply-to=") - 1;
> +	    if (strcmp (opt, "sender") == 0) {
> +		 reply_to_all = 0;
> +	    } else if (strcmp (opt, "all") == 0) {
> +		 reply_to_all = 1;
> +	    } else {
> +		 fprintf (stderr, "Invalid value for --reply-to: %s\n", opt);
> +		 return 1;
> +	    }
>  	} else {
>  	    fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
>  	    return 1;
> @@ -689,7 +715,7 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
>  	return 1;
>      }
>  
> -    if (reply_format_func (ctx, config, query, &params) != 0)
> +    if (reply_format_func (ctx, config, query, &params, reply_to_all) != 0)
>  	return 1;
>  
>      notmuch_query_destroy (query);
> -- 
> 1.7.2.3
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 1/4] Add the option "--reply-to" to notmuch reply.
  2012-01-08 12:47         ` Jani Nikula
@ 2012-01-08 15:08           ` Mark Walters
  2012-01-08 16:11             ` Jani Nikula
  0 siblings, 1 reply; 81+ messages in thread
From: Mark Walters @ 2012-01-08 15:08 UTC (permalink / raw)
  To: Jani Nikula, notmuch, david


On Sun, 08 Jan 2012 14:47:33 +0200, Jani Nikula <jani@nikula.org> wrote:
> > +	/* We add the addresses if we are replying to all or we have not yet found
> > +	 * a non-user address. We have to keep parsing to make sure we do find the
> > +	 * correct from address for the user, but we pass a NULL message
> > +	 */
> > +	if ((reply_to_all) || (g_mime_message_get_all_recipients (reply) == NULL))
> 
> Looking into this, it occurred to me g_mime_message_get_all_recipients()
> allocates a new InternetAddressList when the return value is
> non-NULL. Thus this leaks memory. OTOH allocating and deallocating for
> this purpose seems suboptimal. I'll think this over.

If we are happy with reply-to-sender stopping at the to: line
(so if you reply-to-sender to an email which you sent and has no-one
(apart from possibly you) on the to: line it would not give any
recipients) then we only have two cases and we could do something like

add_recipients_for_string for reply-to:/from:

if return value is non-null then we were the sender so then

add_recipients_for_string for to:

and then stop regardless (well we want to carry on parsing headers to
find the correct from: address to use but not adding any more
recipients).

It feels a bit hackish (it relies on the fact that if we found our
address in the Reply-to:/From: line we didn't find anyone else's
address). 

I think replying to an email which we sent and which does not have any
other person on the to: line is sufficiently rare that it doesn't really
matter what we do in this case.

Best wishes

Mark

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 1/4] Add the option "--reply-to" to notmuch reply.
  2012-01-08 15:08           ` Mark Walters
@ 2012-01-08 16:11             ` Jani Nikula
  0 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-08 16:11 UTC (permalink / raw)
  To: Mark Walters, notmuch, david

On Sun, 08 Jan 2012 15:08:20 +0000, Mark Walters <markwalters1009@gmail.com> wrote:
> I think replying to an email which we sent and which does not have any
> other person on the to: line is sufficiently rare that it doesn't really
> matter what we do in this case.

I ended up fixing all of this properly. I'm hoping to send the patches
later today so you can have a look - the code will do a better job of
explaining itself than I'd do now. :)

BR,
Jani.

^ permalink raw reply	[flat|nested] 81+ messages in thread

* [PATCH v2 0/6] reply to sender
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (7 preceding siblings ...)
  2012-01-06  8:54 ` David Edmondson
@ 2012-01-08 21:48 ` Jani Nikula
  2012-01-09  8:22   ` David Edmondson
  2012-01-09 18:55   ` Dmitry Kurochkin
  2012-01-08 21:48 ` [PATCH v2 1/6] cli: fix use of uninitialized variable in "notmuch reply" Jani Nikula
                   ` (22 subsequent siblings)
  31 siblings, 2 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-08 21:48 UTC (permalink / raw)
  To: notmuch

Hi all, here's v2 of the reply-to-sender series.

Patches 1 & 2 are exactly the same as before.

Changes since first version:

- Patch 3: Settle on --reply-to=(all|sender) option for "notmuch
  reply". This was originally Carl Worth's suggestion, predates this
  patch set, and, as you'd expect, is in line with the rest of the
  CLI. Acked by David on IRC.

- Patch 3: Handle replying to user's own messages gracefully. Credits
  to Mark Walters for his earlier work on this.

- Patch 3: Update man page.

- Patch 4: Change emacs implementation to keep old function names for
  old reply-to-all functionality, and add new reply-to-sender versions
  for new functionality, instead of vice versa. Suggested by Mark
  Walters.

- Add patch 5 to change emacs keybindings, 'r' for reply-to-sender,
  'R' for reply-to-all. I think everyone was in favour of this.

- Add patch 6, written by Mark Winters, to test the cli.

Comments are, as always, welcome.


BR,
Jani.

Jani Nikula (5):
  cli: fix use of uninitialized variable in "notmuch reply"
  cli: convert "notmuch reply" to use the new argument parser
  cli: add support for replying just to the sender in "notmuch reply"
  emacs: add support for replying just to the sender
  emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all

Mark Walters (1):
  test: add tests for "notmuch reply" --reply-to=sender

 emacs/notmuch-mua.el     |    9 ++-
 emacs/notmuch-show.el    |   12 ++-
 emacs/notmuch.el         |   11 ++-
 man/man1/notmuch-reply.1 |   28 +++++-
 notmuch-reply.c          |  155 ++++++++++++++++++++++------------
 test/notmuch-test        |    1 +
 test/reply-to-sender     |  209 ++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 356 insertions(+), 69 deletions(-)
 create mode 100755 test/reply-to-sender

-- 
1.7.5.4

^ permalink raw reply	[flat|nested] 81+ messages in thread

* [PATCH v2 1/6] cli: fix use of uninitialized variable in "notmuch reply"
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (8 preceding siblings ...)
  2012-01-08 21:48 ` [PATCH v2 0/6] reply to sender Jani Nikula
@ 2012-01-08 21:48 ` Jani Nikula
  2012-01-08 21:48 ` [PATCH v2 2/6] cli: convert "notmuch reply" to use the new argument parser Jani Nikula
                   ` (21 subsequent siblings)
  31 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-08 21:48 UTC (permalink / raw)
  To: notmuch

notmuch_show_params_t params is only initialized partially in
notmuch_reply_command(). The only field that is used uninitialized is
params.decrypt. It is usually non-zero, making "notmuch reply" on encrypted
messages work by coincidence.

Initialize params properly, and set params.decrypt as needed.

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 notmuch-reply.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index f8d5f64..1f33a86 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -621,11 +621,9 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
     char *opt, *query_string;
     int i, ret = 0;
     int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params);
-    notmuch_show_params_t params;
+    notmuch_show_params_t params = { .part = -1 };
 
     reply_format_func = notmuch_reply_format_default;
-    params.part = -1;
-    params.cryptoctx = NULL;
 
     argc--; argv++; /* skip subcommand argument */
 
@@ -647,10 +645,12 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 	} else if ((STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
 	    if (params.cryptoctx == NULL) {
 		GMimeSession* session = g_object_new(g_mime_session_get_type(), NULL);
-		if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, "gpg")))
+		if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, "gpg"))) {
 		    fprintf (stderr, "Failed to construct gpg context.\n");
-		else
+		} else {
+		    params.decrypt = TRUE;
 		    g_mime_gpg_context_set_always_trust((GMimeGpgContext*)params.cryptoctx, FALSE);
+		}
 		g_object_unref (session);
 		session = NULL;
 	    }
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 2/6] cli: convert "notmuch reply" to use the new argument parser
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (9 preceding siblings ...)
  2012-01-08 21:48 ` [PATCH v2 1/6] cli: fix use of uninitialized variable in "notmuch reply" Jani Nikula
@ 2012-01-08 21:48 ` Jani Nikula
  2012-01-08 21:48 ` [PATCH v2 3/6] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
                   ` (20 subsequent siblings)
  31 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-08 21:48 UTC (permalink / raw)
  To: notmuch

Use the new notmuch argument parser to handle arguments in "notmuch
reply". There should be no functional changes.

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 notmuch-reply.c |   75 +++++++++++++++++++++++++++----------------------------
 1 files changed, 37 insertions(+), 38 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index 1f33a86..000f6da 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -612,62 +612,61 @@ notmuch_reply_format_headers_only(void *ctx,
     return 0;
 }
 
+enum {
+    FORMAT_DEFAULT,
+    FORMAT_HEADERS_ONLY,
+};
+
 int
 notmuch_reply_command (void *ctx, int argc, char *argv[])
 {
     notmuch_config_t *config;
     notmuch_database_t *notmuch;
     notmuch_query_t *query;
-    char *opt, *query_string;
-    int i, ret = 0;
+    char *query_string;
+    int opt_index, ret = 0;
     int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params);
     notmuch_show_params_t params = { .part = -1 };
+    int format = FORMAT_DEFAULT;
+    notmuch_bool_t decrypt = FALSE;
+
+    notmuch_opt_desc_t options[] = {
+	{ NOTMUCH_OPT_KEYWORD, &format, "format", 'f',
+	  (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT },
+				  { "headers-only", FORMAT_HEADERS_ONLY },
+				  { 0, 0 } } },
+	{ NOTMUCH_OPT_BOOLEAN, &decrypt, "decrypt", 'd', 0 },
+	{ 0, 0, 0, 0, 0 }
+    };
 
-    reply_format_func = notmuch_reply_format_default;
-
-    argc--; argv++; /* skip subcommand argument */
+    opt_index = parse_arguments (argc, argv, options, 1);
+    if (opt_index < 0) {
+	/* diagnostics already printed */
+	return 1;
+    }
 
-    for (i = 0; i < argc && argv[i][0] == '-'; i++) {
-	if (strcmp (argv[i], "--") == 0) {
-	    i++;
-	    break;
-	}
-        if (STRNCMP_LITERAL (argv[i], "--format=") == 0) {
-	    opt = argv[i] + sizeof ("--format=") - 1;
-	    if (strcmp (opt, "default") == 0) {
-		reply_format_func = notmuch_reply_format_default;
-	    } else if (strcmp (opt, "headers-only") == 0) {
-		reply_format_func = notmuch_reply_format_headers_only;
-	    } else {
-		fprintf (stderr, "Invalid value for --format: %s\n", opt);
-		return 1;
-	    }
-	} else if ((STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
-	    if (params.cryptoctx == NULL) {
-		GMimeSession* session = g_object_new(g_mime_session_get_type(), NULL);
-		if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, "gpg"))) {
-		    fprintf (stderr, "Failed to construct gpg context.\n");
-		} else {
-		    params.decrypt = TRUE;
-		    g_mime_gpg_context_set_always_trust((GMimeGpgContext*)params.cryptoctx, FALSE);
-		}
-		g_object_unref (session);
-		session = NULL;
-	    }
+    if (format == FORMAT_HEADERS_ONLY)
+	reply_format_func = notmuch_reply_format_headers_only;
+    else
+	reply_format_func = notmuch_reply_format_default;
+
+    if (decrypt) {
+	GMimeSession* session = g_object_new (g_mime_session_get_type(), NULL);
+	params.cryptoctx = g_mime_gpg_context_new (session, "gpg");
+	if (params.cryptoctx) {
+	    g_mime_gpg_context_set_always_trust ((GMimeGpgContext*) params.cryptoctx, FALSE);
+	    params.decrypt = TRUE;
 	} else {
-	    fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
-	    return 1;
+	    fprintf (stderr, "Failed to construct gpg context.\n");
 	}
+	g_object_unref (session);
     }
 
-    argc -= i;
-    argv += i;
-
     config = notmuch_config_open (ctx, NULL, NULL);
     if (config == NULL)
 	return 1;
 
-    query_string = query_string_from_args (ctx, argc, argv);
+    query_string = query_string_from_args (ctx, argc-opt_index, argv+opt_index);
     if (query_string == NULL) {
 	fprintf (stderr, "Out of memory\n");
 	return 1;
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 3/6] cli: add support for replying just to the sender in "notmuch reply"
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (10 preceding siblings ...)
  2012-01-08 21:48 ` [PATCH v2 2/6] cli: convert "notmuch reply" to use the new argument parser Jani Nikula
@ 2012-01-08 21:48 ` Jani Nikula
  2012-01-08 23:23   ` Mark Walters
  2012-01-08 21:48 ` [PATCH v2 4/6] emacs: add support for replying just to the sender Jani Nikula
                   ` (19 subsequent siblings)
  31 siblings, 1 reply; 81+ messages in thread
From: Jani Nikula @ 2012-01-08 21:48 UTC (permalink / raw)
  To: notmuch

Add new option --reply-to=(all|sender) to "notmuch reply" to select whether
to reply to all (sender and all recipients), or just sender. Reply to all
remains the default.

Credits to Mark Walters <markwalters1009@gmail.com> for his similar earlier
work where I picked up the basic idea of handling reply-to-sender in
add_recipients_from_message(). All bugs are mine, though.

Signed-off-by: Jani Nikula <jani@nikula.org>

---

Settled on --reply-to=(all|sender) per Carl's earlier suggestion
(id:87pqn5cg4g.fsf@yoom.home.cworth.org) and David's approval on IRC.
---
 man/man1/notmuch-reply.1 |   28 +++++++++++++---
 notmuch-reply.c          |   78 ++++++++++++++++++++++++++++++++++++----------
 2 files changed, 84 insertions(+), 22 deletions(-)

diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1
index 099d808..21afa35 100644
--- a/man/man1/notmuch-reply.1
+++ b/man/man1/notmuch-reply.1
@@ -14,11 +14,13 @@ Constructs a reply template for a set of messages.
 To make replying to email easier,
 .B notmuch reply
 takes an existing set of messages and constructs a suitable mail
-template. The Reply-to header (if any, otherwise From:) is used for
-the To: address. Vales from the To: and Cc: headers are copied, but
-not including any of the current user's email addresses (as configured
-in primary_mail or other_email in the .notmuch\-config file) in the
-recipient list
+template. The Reply-to: header (if any, otherwise From:) is used for
+the To: address. Unless
+.BR \-\-reply-to=sender
+is specified, values from the To: and Cc: headers are copied, but not
+including any of the current user's email addresses (as configured in
+primary_mail or other_email in the .notmuch\-config file) in the
+recipient list.
 
 It also builds a suitable new subject, including Re: at the front (if
 not already present), and adding the message IDs of the messages being
@@ -45,6 +47,22 @@ Includes subject and quoted message body.
 Only produces In\-Reply\-To, References, To, Cc, and Bcc headers.
 .RE
 .RE
+.RS
+.TP 4
+.BR \-\-reply\-to= ( all | sender )
+.RS
+.TP 4
+.BR all " (default)"
+Replies to all addresses.
+.TP 4
+.BR sender
+Replies only to the sender. If Reply-to: header (if any, otherwise
+From:) is any of the current user's configured email addresses
+(replying to user's own message), try To:, Cc:, and Bcc: headers in
+this order, and use the addresses in the first that contains something
+other than only the user's addresses for the To: address.
+.RE
+.RE
 
 See \fBnotmuch-search-terms\fR(7)
 for details of the supported syntax for <search-terms>.
diff --git a/notmuch-reply.c b/notmuch-reply.c
index 000f6da..71946b3 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -170,7 +170,7 @@ address_is_users (const char *address, notmuch_config_t *config)
 
 /* For each address in 'list' that is not configured as one of the
  * user's addresses in 'config', add that address to 'message' as an
- * address of 'type'.
+ * address of 'type', if 'add' is true.
  *
  * The first address encountered that *is* the user's address will be
  * returned, (otherwise NULL is returned).
@@ -179,7 +179,8 @@ static const char *
 add_recipients_for_address_list (GMimeMessage *message,
 				 notmuch_config_t *config,
 				 GMimeRecipientType type,
-				 InternetAddressList *list)
+				 InternetAddressList *list,
+				 notmuch_bool_t add)
 {
     InternetAddress *address;
     int i;
@@ -197,7 +198,7 @@ add_recipients_for_address_list (GMimeMessage *message,
 		continue;
 
 	    add_recipients_for_address_list (message, config,
-					     type, group_list);
+					     type, group_list, add);
 	} else {
 	    InternetAddressMailbox *mailbox;
 	    const char *name;
@@ -211,7 +212,7 @@ add_recipients_for_address_list (GMimeMessage *message,
 	    if (address_is_users (addr, config)) {
 		if (ret == NULL)
 		    ret = addr;
-	    } else {
+	    } else if (add) {
 		g_mime_message_add_recipient (message, type, name, addr);
 	    }
 	}
@@ -222,7 +223,7 @@ add_recipients_for_address_list (GMimeMessage *message,
 
 /* For each address in 'recipients' that is not configured as one of
  * the user's addresses in 'config', add that address to 'message' as
- * an address of 'type'.
+ * an address of 'type', if 'add' is true.
  *
  * The first address encountered that *is* the user's address will be
  * returned, (otherwise NULL is returned).
@@ -231,7 +232,8 @@ static const char *
 add_recipients_for_string (GMimeMessage *message,
 			   notmuch_config_t *config,
 			   GMimeRecipientType type,
-			   const char *recipients)
+			   const char *recipients,
+			   notmuch_bool_t add)
 {
     InternetAddressList *list;
 
@@ -242,7 +244,7 @@ add_recipients_for_string (GMimeMessage *message,
     if (list == NULL)
 	return NULL;
 
-    return add_recipients_for_address_list (message, config, type, list);
+    return add_recipients_for_address_list (message, config, type, list, add);
 }
 
 /* Does the address in the Reply-To header of 'message' already appear
@@ -286,13 +288,19 @@ reply_to_header_is_redundant (notmuch_message_t *message)
 
 /* Augments the recipients of reply from the headers of message.
  *
+ * If 'reply_all' is true, use sender and all recipients, otherwise use the
+ * first header that contains something other than the user's addresses
+ * (typically this would be reply-to-sender, but also handles reply to user's
+ * own message in a sensible way).
+ *
  * If any of the user's addresses were found in these headers, the first
  * of these returned, otherwise NULL is returned.
  */
 static const char *
 add_recipients_from_message (GMimeMessage *reply,
 			     notmuch_config_t *config,
-			     notmuch_message_t *message)
+			     notmuch_message_t *message,
+			     notmuch_bool_t reply_all)
 {
     struct {
 	const char *header;
@@ -305,6 +313,7 @@ add_recipients_from_message (GMimeMessage *reply,
 	{ "bcc",        NULL, GMIME_RECIPIENT_TYPE_BCC }
     };
     const char *from_addr = NULL;
+    notmuch_bool_t add_recipients = TRUE;
     unsigned int i;
 
     /* Some mailing lists munge the Reply-To header despite it being A Bad
@@ -325,6 +334,7 @@ add_recipients_from_message (GMimeMessage *reply,
 
     for (i = 0; i < ARRAY_SIZE (reply_to_map); i++) {
 	const char *addr, *recipients;
+	GMimeRecipientType recipient_type;
 
 	recipients = notmuch_message_get_header (message,
 						 reply_to_map[i].header);
@@ -332,11 +342,37 @@ add_recipients_from_message (GMimeMessage *reply,
 	    recipients = notmuch_message_get_header (message,
 						     reply_to_map[i].fallback);
 
-	addr = add_recipients_for_string (reply, config,
-					  reply_to_map[i].recipient_type,
-					  recipients);
+	/* Force recipient type in reply-to-sender mode just in case replying to
+	 * user's own message finds recipients in Cc/Bcc fields only.
+	 */
+	if (reply_all)
+	    recipient_type = reply_to_map[i].recipient_type;
+	else
+	    recipient_type = GMIME_RECIPIENT_TYPE_TO;
+
+	addr = add_recipients_for_string (reply, config, recipient_type,
+					  recipients, add_recipients);
+
 	if (from_addr == NULL)
 	    from_addr = addr;
+
+	if (!reply_all) {
+	    /* Stop adding new recipients in reply-to-sender mode if we have
+	     * added some recipient(s) above.
+	     *
+	     * This also handles the case of user replying to his own message,
+	     * where reply-to/from is not a recipient. In this case there may be
+	     * more than one recipient even if not replying to all.
+	     */
+	    InternetAddressList *list;
+	    list = g_mime_message_get_recipients (reply, recipient_type);
+	    if (list && internet_address_list_length (list))
+		add_recipients = FALSE;
+
+	    /* Check if we've got a from address and all recipients we need. */
+	    if (!add_recipients && from_addr)
+		break;
+	}
     }
 
     return from_addr;
@@ -480,7 +516,8 @@ static int
 notmuch_reply_format_default(void *ctx,
 			     notmuch_config_t *config,
 			     notmuch_query_t *query,
-			     notmuch_show_params_t *params)
+			     notmuch_show_params_t *params,
+			     notmuch_bool_t reply_all)
 {
     GMimeMessage *reply;
     notmuch_messages_t *messages;
@@ -509,7 +546,8 @@ notmuch_reply_format_default(void *ctx,
 	    g_mime_message_set_subject (reply, subject);
 	}
 
-	from_addr = add_recipients_from_message (reply, config, message);
+	from_addr = add_recipients_from_message (reply, config, message,
+						 reply_all);
 
 	if (from_addr == NULL)
 	    from_addr = guess_from_received_header (config, message);
@@ -558,7 +596,8 @@ static int
 notmuch_reply_format_headers_only(void *ctx,
 				  notmuch_config_t *config,
 				  notmuch_query_t *query,
-				  unused (notmuch_show_params_t *params))
+				  unused (notmuch_show_params_t *params),
+				  notmuch_bool_t reply_all)
 {
     GMimeMessage *reply;
     notmuch_messages_t *messages;
@@ -598,7 +637,7 @@ notmuch_reply_format_headers_only(void *ctx,
 	g_mime_object_set_header (GMIME_OBJECT (reply),
 				  "References", references);
 
-	(void)add_recipients_from_message (reply, config, message);
+	(void)add_recipients_from_message (reply, config, message, reply_all);
 
 	reply_headers = g_mime_object_to_string (GMIME_OBJECT (reply));
 	printf ("%s", reply_headers);
@@ -625,9 +664,10 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
     notmuch_query_t *query;
     char *query_string;
     int opt_index, ret = 0;
-    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params);
+    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params, notmuch_bool_t reply_all);
     notmuch_show_params_t params = { .part = -1 };
     int format = FORMAT_DEFAULT;
+    int reply_all = TRUE;
     notmuch_bool_t decrypt = FALSE;
 
     notmuch_opt_desc_t options[] = {
@@ -635,6 +675,10 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 	  (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT },
 				  { "headers-only", FORMAT_HEADERS_ONLY },
 				  { 0, 0 } } },
+	{ NOTMUCH_OPT_KEYWORD, &reply_all, "reply-to", 'r',
+	  (notmuch_keyword_t []){ { "all", TRUE },
+				  { "sender", FALSE },
+				  { 0, 0 } } },
 	{ NOTMUCH_OPT_BOOLEAN, &decrypt, "decrypt", 'd', 0 },
 	{ 0, 0, 0, 0, 0 }
     };
@@ -688,7 +732,7 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 	return 1;
     }
 
-    if (reply_format_func (ctx, config, query, &params) != 0)
+    if (reply_format_func (ctx, config, query, &params, reply_all) != 0)
 	return 1;
 
     notmuch_query_destroy (query);
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 4/6] emacs: add support for replying just to the sender
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (11 preceding siblings ...)
  2012-01-08 21:48 ` [PATCH v2 3/6] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
@ 2012-01-08 21:48 ` Jani Nikula
  2012-01-08 21:48 ` [PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all Jani Nikula
                   ` (18 subsequent siblings)
  31 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-08 21:48 UTC (permalink / raw)
  To: notmuch

Provide reply to sender counterparts to the search and show reply
functions. Add key binding 'R' to reply to sender, while keeping 'r' as
reply to all, both in search and show views.

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 emacs/notmuch-mua.el  |    9 ++++++---
 emacs/notmuch-show.el |   10 ++++++++--
 emacs/notmuch.el      |    9 ++++++++-
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 7114e48..5b15255 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -71,12 +71,15 @@ list."
 	    (push header message-hidden-headers)))
 	notmuch-mua-hidden-headers))
 
-(defun notmuch-mua-reply (query-string &optional sender)
+(defun notmuch-mua-reply (query-string &optional sender reply-all)
   (let (headers
 	body
 	(args '("reply")))
     (if notmuch-show-process-crypto
 	(setq args (append args '("--decrypt"))))
+    (if reply-all
+	(setq args (append args '("--reply-to=all")))
+      (setq args (append args '("--reply-to=sender"))))
     (setq args (append args (list query-string)))
     ;; This make assumptions about the output of `notmuch reply', but
     ;; really only that the headers come first followed by a blank
@@ -217,13 +220,13 @@ the From: address first."
 	(notmuch-mua-forward-message))
     (notmuch-mua-forward-message)))
 
-(defun notmuch-mua-new-reply (query-string &optional prompt-for-sender)
+(defun notmuch-mua-new-reply (query-string &optional prompt-for-sender reply-all)
   "Invoke the notmuch reply window."
   (interactive "P")
   (let ((sender
 	 (when prompt-for-sender
 	   (notmuch-mua-prompt-for-sender))))
-    (notmuch-mua-reply query-string sender)))
+    (notmuch-mua-reply query-string sender reply-all)))
 
 (defun notmuch-mua-send-and-exit (&optional arg)
   (interactive "P")
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 5502efd..96eea19 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -933,6 +933,7 @@ thread id.  If a prefix is given, crypto processing is toggled."
 	(define-key map "m" 'notmuch-mua-new-mail)
 	(define-key map "f" 'notmuch-show-forward-message)
 	(define-key map "r" 'notmuch-show-reply)
+	(define-key map "R" 'notmuch-show-reply-sender)
 	(define-key map "|" 'notmuch-show-pipe-message)
 	(define-key map "w" 'notmuch-show-save-attachments)
 	(define-key map "V" 'notmuch-show-view-raw-message)
@@ -1237,9 +1238,14 @@ any effects from previous calls to
       (notmuch-show-previous-message)))))
 
 (defun notmuch-show-reply (&optional prompt-for-sender)
-  "Reply to the current message."
+  "Reply to the sender and all recipients of the current message."
   (interactive "P")
-  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender))
+  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender t))
+
+(defun notmuch-show-reply-sender (&optional prompt-for-sender)
+  "Reply to the sender of the current message."
+  (interactive "P")
+  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender nil))
 
 (defun notmuch-show-forward-message (&optional prompt-for-sender)
   "Forward the current message."
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index fde2377..5974d6b 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -207,6 +207,7 @@ For a mouse binding, return nil."
     (define-key map "p" 'notmuch-search-previous-thread)
     (define-key map "n" 'notmuch-search-next-thread)
     (define-key map "r" 'notmuch-search-reply-to-thread)
+    (define-key map "R" 'notmuch-search-reply-to-thread-sender)
     (define-key map "m" 'notmuch-mua-new-mail)
     (define-key map "s" 'notmuch-search)
     (define-key map "o" 'notmuch-search-toggle-order)
@@ -441,10 +442,16 @@ Complete list of currently available key bindings:
       (error "End of search results"))))
 
 (defun notmuch-search-reply-to-thread (&optional prompt-for-sender)
+  "Begin composing a reply-all to the entire current thread in a new buffer."
+  (interactive "P")
+  (let ((message-id (notmuch-search-find-thread-id)))
+    (notmuch-mua-new-reply message-id prompt-for-sender t)))
+
+(defun notmuch-search-reply-to-thread-sender (&optional prompt-for-sender)
   "Begin composing a reply to the entire current thread in a new buffer."
   (interactive "P")
   (let ((message-id (notmuch-search-find-thread-id)))
-    (notmuch-mua-new-reply message-id prompt-for-sender)))
+    (notmuch-mua-new-reply message-id prompt-for-sender nil)))
 
 (defun notmuch-call-notmuch-process (&rest args)
   "Synchronously invoke \"notmuch\" with the given list of arguments.
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (12 preceding siblings ...)
  2012-01-08 21:48 ` [PATCH v2 4/6] emacs: add support for replying just to the sender Jani Nikula
@ 2012-01-08 21:48 ` Jani Nikula
  2012-01-08 22:01   ` Jeremy Nickurak
  2012-01-08 21:48 ` [PATCH v2 6/6] test: add tests for "notmuch reply" --reply-to=sender Jani Nikula
                   ` (17 subsequent siblings)
  31 siblings, 1 reply; 81+ messages in thread
From: Jani Nikula @ 2012-01-08 21:48 UTC (permalink / raw)
  To: notmuch

Change the default reply key bindings, making 'r' reply-to-sender and 'R'
reply-to-all.

Signed-off-by: Jani Nikula <jani@nikula.org>

---

It seemed to me that most people wanted this, and nobody spoke for keeping
the old binding now that we have reply-to-sender. This as a separate patch
so it's easy to drop if needed.
---
 emacs/notmuch-show.el |    4 ++--
 emacs/notmuch.el      |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 96eea19..8f8ea93 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -932,8 +932,8 @@ thread id.  If a prefix is given, crypto processing is toggled."
 	(define-key map "s" 'notmuch-search)
 	(define-key map "m" 'notmuch-mua-new-mail)
 	(define-key map "f" 'notmuch-show-forward-message)
-	(define-key map "r" 'notmuch-show-reply)
-	(define-key map "R" 'notmuch-show-reply-sender)
+	(define-key map "r" 'notmuch-show-reply-sender)
+	(define-key map "R" 'notmuch-show-reply)
 	(define-key map "|" 'notmuch-show-pipe-message)
 	(define-key map "w" 'notmuch-show-save-attachments)
 	(define-key map "V" 'notmuch-show-view-raw-message)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 5974d6b..e158138 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -206,8 +206,8 @@ For a mouse binding, return nil."
     (define-key map ">" 'notmuch-search-last-thread)
     (define-key map "p" 'notmuch-search-previous-thread)
     (define-key map "n" 'notmuch-search-next-thread)
-    (define-key map "r" 'notmuch-search-reply-to-thread)
-    (define-key map "R" 'notmuch-search-reply-to-thread-sender)
+    (define-key map "r" 'notmuch-search-reply-to-thread-sender)
+    (define-key map "R" 'notmuch-search-reply-to-thread)
     (define-key map "m" 'notmuch-mua-new-mail)
     (define-key map "s" 'notmuch-search)
     (define-key map "o" 'notmuch-search-toggle-order)
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 6/6] test: add tests for "notmuch reply" --reply-to=sender
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (13 preceding siblings ...)
  2012-01-08 21:48 ` [PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all Jani Nikula
@ 2012-01-08 21:48 ` Jani Nikula
  2012-01-10 19:54 ` [PATCH v3 0/4] reply to sender Jani Nikula
                   ` (16 subsequent siblings)
  31 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-08 21:48 UTC (permalink / raw)
  To: notmuch

From: Mark Walters <markwalters1009@gmail.com>

---

This is Mark's work; just a one line change by Jani to take into account a
minor change in replying to one's own message.
---
 test/notmuch-test    |    1 +
 test/reply-to-sender |  209 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 210 insertions(+), 0 deletions(-)
 create mode 100755 test/reply-to-sender

diff --git a/test/notmuch-test b/test/notmuch-test
index e40ef86..6a99ae3 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -33,6 +33,7 @@ TESTS="
   thread-naming
   raw
   reply
+  reply-to-sender
   dump-restore
   uuencode
   thread-order
diff --git a/test/reply-to-sender b/test/reply-to-sender
new file mode 100755
index 0000000..caceeb2
--- /dev/null
+++ b/test/reply-to-sender
@@ -0,0 +1,209 @@
+#!/usr/bin/env bash
+test_description="\"notmuch reply --reply-to=sender\" in several variations"
+. ./test-lib.sh
+
+test_begin_subtest "Basic reply-to-sender"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="basic reply-to-sender test"'
+
+output=$(notmuch reply --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> basic reply-to-sender test"
+
+test_begin_subtest "From Us, Basic reply to message"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[to]="Recipient <recipient@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="basic reply-to-from-us test"'
+
+output=$(notmuch reply --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Recipient <recipient@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> basic reply-to-from-us test"
+
+test_begin_subtest "Multiple recipients"
+add_message '[from]="Sender <sender@example.com>"' \
+            '[to]="test_suite@notmuchmail.org, Someone Else <someone@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="Multiple recipients"'
+
+output=$(notmuch reply  --reply-to=sender  id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> Multiple recipients"
+
+test_begin_subtest "From Us, Multiple TO recipients"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[to]="Recipient <recipient@example.com>, Someone Else <someone@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="From Us, Multiple TO recipients"'
+
+output=$(notmuch reply  --reply-to=sender  id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Recipient <recipient@example.com>, Someone Else <someone@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> From Us, Multiple TO recipients"
+
+test_begin_subtest "Reply with CC"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+            '[cc]="Other Parties <cc@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> reply with CC"
+
+test_begin_subtest "From Us, Reply with CC"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[to]="Recipient <recipient@example.com>"' \
+            '[cc]="Other Parties <cc@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Recipient <recipient@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> reply with CC"
+
+test_begin_subtest "From Us, Reply no TO but with CC"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[cc]="Other Parties <cc@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Other Parties <cc@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> reply with CC"
+
+test_begin_subtest "Reply from alternate address"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite_other@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply from alternate address"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite_other@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> reply from alternate address"
+
+test_begin_subtest "Support for Reply-To"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="support for reply-to"' \
+            '[reply-to]="Sender <elsewhere@example.com>"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <elsewhere@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> support for reply-to"
+
+test_begin_subtest "Support for Reply-To with multiple recipients"
+add_message '[from]="Sender <sender@example.com>"' \
+            '[to]="test_suite@notmuchmail.org, Someone Else <someone@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="support for reply-to with multiple recipients"' \
+            '[reply-to]="Sender <elsewhere@example.com>"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <elsewhere@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> support for reply-to with multiple recipients"
+
+test_begin_subtest "Un-munging Reply-To"
+add_message '[from]="Sender <sender@example.com>"' \
+            '[to]="Some List <list@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="Un-munging Reply-To"' \
+            '[reply-to]="Evil Munging List <list@example.com>"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> Un-munging Reply-To"
+
+test_begin_subtest "Message with header of exactly 200 bytes"
+add_message '[subject]="This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces"' \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="200-byte header"'
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> 200-byte header"
+test_done
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all
  2012-01-08 21:48 ` [PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all Jani Nikula
@ 2012-01-08 22:01   ` Jeremy Nickurak
  2012-01-08 23:32     ` Jameson Graef Rollins
  2012-01-09 14:10     ` is there a default reply function? (was: Re: [PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all) Gregor Zattler
  0 siblings, 2 replies; 81+ messages in thread
From: Jeremy Nickurak @ 2012-01-08 22:01 UTC (permalink / raw)
  To: Jani Nikula; +Cc: notmuch

On Sun, Jan 8, 2012 at 14:48, Jani Nikula <jani@nikula.org> wrote:
> It seemed to me that most people wanted this, and nobody spoke for keeping
> the old binding now that we have reply-to-sender. This as a separate patch
> so it's easy to drop if needed.

FWIW, I generally prefer reply-all as the default. In my experience,
when a message is sent to a bunch of people, it's usually treated as a
"forum" discussion where everybody wants to be in on everything. Also,
once you've started composing, it's much easier to delete people you
don't want included than to add people who are no longer referenced in
the new buffer at all.

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 3/6] cli: add support for replying just to the sender in "notmuch reply"
  2012-01-08 21:48 ` [PATCH v2 3/6] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
@ 2012-01-08 23:23   ` Mark Walters
  2012-01-09  9:41     ` Jani Nikula
  0 siblings, 1 reply; 81+ messages in thread
From: Mark Walters @ 2012-01-08 23:23 UTC (permalink / raw)
  To: Jani Nikula, notmuch


I like this version (of the whole series) but have two queries. (Note I
haven't actually tried it out yet: I have just been reading the code.)

> +	/* Force recipient type in reply-to-sender mode just in case replying to
> +	 * user's own message finds recipients in Cc/Bcc fields only.
> +	 */
> +	if (reply_all)
> +	    recipient_type = reply_to_map[i].recipient_type;
> +	else
> +	    recipient_type = GMIME_RECIPIENT_TYPE_TO;
> +
> +	addr = add_recipients_for_string (reply, config, recipient_type,
> +					  recipients, add_recipients);
> +

Why force the recipient type?  I do not think notmuch should ever move
bcc people onto a different header. I think that will bite someone when
it leaks information.

I would be happy with either empty headers or with the people staying
as bcc.

In the cc: case I have no preference (as those addresses are already
public) but I would suggest being consistent with bcc so either empty
headers or keep them in the cc line.

>     for (messages = notmuch_query_search_messages (query);
>         notmuch_messages_valid (messages);
>         notmuch_messages_move_to_next (messages))
>     {
[...]
>       (void)add_recipients_from_message (reply, config, message, reply_all);

Since the above logic is applied to each email individually I think
working out the recipients when replying to multiple emails (e.g.,
reply-to-sender on a thread) could be very confusing. Some of the people
being replied to will have been senders, some recipients (it is very
likely that the thread contains messages we sent), some could even be
cc, bcc people. Personally, I would have no idea what to expect from
reply-to-sender in this case.

(My personal choice would be not to allow notmuch-reply-to-sender if
multiple messages are specified. But I can obtain that by unbinding "r"
in the notmuch-search-mode-map keymap.)

Best wishes

Mark

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all
  2012-01-08 22:01   ` Jeremy Nickurak
@ 2012-01-08 23:32     ` Jameson Graef Rollins
  2012-01-08 23:56       ` Jeremy Nickurak
  2012-01-09 14:10     ` is there a default reply function? (was: Re: [PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all) Gregor Zattler
  1 sibling, 1 reply; 81+ messages in thread
From: Jameson Graef Rollins @ 2012-01-08 23:32 UTC (permalink / raw)
  To: Jeremy Nickurak, Jani Nikula; +Cc: notmuch

[-- Attachment #1: Type: text/plain, Size: 630 bytes --]

On Sun, 8 Jan 2012 15:01:30 -0700, Jeremy Nickurak <not-much@trk.nickurak.ca> wrote:
> FWIW, I generally prefer reply-all as the default. In my experience,
> when a message is sent to a bunch of people, it's usually treated as a
> "forum" discussion where everybody wants to be in on everything. Also,
> once you've started composing, it's much easier to delete people you
> don't want included than to add people who are no longer referenced in
> the new buffer at all.

That's a good point.  I think that maybe people are wanting to protect
against the accidental reply to all when you only mean to reply to the
sender.

jamie.

[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all
  2012-01-08 23:32     ` Jameson Graef Rollins
@ 2012-01-08 23:56       ` Jeremy Nickurak
  0 siblings, 0 replies; 81+ messages in thread
From: Jeremy Nickurak @ 2012-01-08 23:56 UTC (permalink / raw)
  To: Jameson Graef Rollins; +Cc: notmuch

On Sun, Jan 8, 2012 at 16:32, Jameson Graef Rollins
<jrollins@finestructure.net> wrote:
> That's a good point.  I think that maybe people are wanting to protect
> against the accidental reply to all when you only mean to reply to the
> sender.

Certainly a worthy cause. All I'm saying is I make the mistake in the
other direction more frequently ;)

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 0/6] reply to sender
  2012-01-08 21:48 ` [PATCH v2 0/6] reply to sender Jani Nikula
@ 2012-01-09  8:22   ` David Edmondson
  2012-01-09 18:55   ` Dmitry Kurochkin
  1 sibling, 0 replies; 81+ messages in thread
From: David Edmondson @ 2012-01-09  8:22 UTC (permalink / raw)
  To: Jani Nikula, notmuch

[-- Attachment #1: Type: text/plain, Size: 220 bytes --]

On Sun,  8 Jan 2012 23:48:29 +0200, Jani Nikula <jani@nikula.org> wrote:
>   emacs: add support for replying just to the sender
>   emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all

These both look fine to me.

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 3/6] cli: add support for replying just to the sender in "notmuch reply"
  2012-01-08 23:23   ` Mark Walters
@ 2012-01-09  9:41     ` Jani Nikula
  2012-01-09 11:13       ` Mark Walters
  0 siblings, 1 reply; 81+ messages in thread
From: Jani Nikula @ 2012-01-09  9:41 UTC (permalink / raw)
  To: Mark Walters, notmuch

On Sun, 08 Jan 2012 23:23:15 +0000, Mark Walters <markwalters1009@gmail.com> wrote:
> 
> I like this version (of the whole series) but have two queries. (Note I
> haven't actually tried it out yet: I have just been reading the code.)
> 
> > +	/* Force recipient type in reply-to-sender mode just in case replying to
> > +	 * user's own message finds recipients in Cc/Bcc fields only.
> > +	 */
> > +	if (reply_all)
> > +	    recipient_type = reply_to_map[i].recipient_type;
> > +	else
> > +	    recipient_type = GMIME_RECIPIENT_TYPE_TO;
> > +
> > +	addr = add_recipients_for_string (reply, config, recipient_type,
> > +					  recipients, add_recipients);
> > +
> 
> Why force the recipient type?  I do not think notmuch should ever move
> bcc people onto a different header. I think that will bite someone when
> it leaks information.
> 
> I would be happy with either empty headers or with the people staying
> as bcc.
> 
> In the cc: case I have no preference (as those addresses are already
> public) but I would suggest being consistent with bcc so either empty
> headers or keep them in the cc line.

I think you're right. I was trying to clean up a corner case in
reply-to-self, but probably over did it. I'll remove the recipient type
forcing altogether. Then it'll keep addresses in the same header as they
were.

> >     for (messages = notmuch_query_search_messages (query);
> >         notmuch_messages_valid (messages);
> >         notmuch_messages_move_to_next (messages))
> >     {
> [...]
> >       (void)add_recipients_from_message (reply, config, message, reply_all);
> 
> Since the above logic is applied to each email individually I think
> working out the recipients when replying to multiple emails (e.g.,
> reply-to-sender on a thread) could be very confusing. Some of the people
> being replied to will have been senders, some recipients (it is very
> likely that the thread contains messages we sent), some could even be
> cc, bcc people. Personally, I would have no idea what to expect from
> reply-to-sender in this case.
> 
> (My personal choice would be not to allow notmuch-reply-to-sender if
> multiple messages are specified. But I can obtain that by unbinding "r"
> in the notmuch-search-mode-map keymap.)

The reply-to-thread is a rare case anyway, regardless of reply-to-all or
reply-to-sender, and even the current implementation does not gather all
the recipients from all the messages. Try it out, it seems to me it does
not quite do what you think it does.

IMHO it should use oldest-first rather than newest-first sort order, and
I guess it should really go through the messages being replied to and
get the recipients from all of them. It's just out of scope for this
patch set to fix these. But if that gets fixed later, I would like the
reply-to-sender for multiple messages follow the logic of single-reply,
just with all the addresses put together.


BR,
Jani.

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 3/6] cli: add support for replying just to the sender in "notmuch reply"
  2012-01-09  9:41     ` Jani Nikula
@ 2012-01-09 11:13       ` Mark Walters
  0 siblings, 0 replies; 81+ messages in thread
From: Mark Walters @ 2012-01-09 11:13 UTC (permalink / raw)
  To: Jani Nikula; +Cc: notmuch

> 
> The reply-to-thread is a rare case anyway, regardless of reply-to-all or
> reply-to-sender, and even the current implementation does not gather all
> the recipients from all the messages. Try it out, it seems to me it does
> not quite do what you think it does.
> 
> IMHO it should use oldest-first rather than newest-first sort order, and
> I guess it should really go through the messages being replied to and
> get the recipients from all of them. It's just out of scope for this
> patch set to fix these. But if that gets fixed later, I would like the
> reply-to-sender for multiple messages follow the logic of single-reply,
> just with all the addresses put together.

I completely agree it's a rare case. Having tried the code (yours and
the original) it seems to be very strange:

In its current form it seems to be reply to people on newest message in
thread and include all the bodies with some spurious headers mixed
in. So your code is reply-to-sender applied to people on newest message
in thread, and include all the bodies with some slightly different
spurious headers mixed in.

I like your suggested solution.

Anyway it's a rare case; the current code is odd and yours is no odder
so I agree with leaving it for a later patch (if anyone cares enough!).

Best wishes

Mark

^ permalink raw reply	[flat|nested] 81+ messages in thread

* is there a default reply function? (was: Re: [PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all)
  2012-01-08 22:01   ` Jeremy Nickurak
  2012-01-08 23:32     ` Jameson Graef Rollins
@ 2012-01-09 14:10     ` Gregor Zattler
  1 sibling, 0 replies; 81+ messages in thread
From: Gregor Zattler @ 2012-01-09 14:10 UTC (permalink / raw)
  To: notmuch

Hi Jeremy, notmuch -developers,
* Jeremy Nickurak <not-much@trk.nickurak.ca> [08. Jan. 2012]:
> On Sun, Jan 8, 2012 at 14:48, Jani Nikula <jani@nikula.org> wrote:
>> It seemed to me that most people wanted this, and nobody spoke for keeping
>> the old binding now that we have reply-to-sender. This as a separate patch
>> so it's easy to drop if needed.
> 
> FWIW, I generally prefer reply-all as the default. 

Actually I think there is no default at all.  The perception of a
default here is because two different functions are on "r" and
"R" key respectively while the "r" key feels as a default.

Other MUAs have different key bindings:

message mode has "r" as reply and "w" as "wide-reply"
mutt         has "r" as reply and "g" as "group-reply" and "L" as list-reply

I prefer the mutt way of doing this with three different functions.

> In my experience,
> when a message is sent to a bunch of people, it's usually treated as a
> "forum" discussion where everybody wants to be in on
> everything. 

I think you are right for the majority of cases.  But last week I
got in trouble because I did exactly this.  Perhaps here it is
more important which mistake has more potential for disaster.
Both mistakes could be important but I think there is more
disaster potential in giving information to people who shouldn't
get it than the other way around.  In my perception an UI which clearly
distinguishes two or three reply-functions encourages to think
in advance about which to use.  But last week...

> Also,
> once you've started composing, it's much easier to delete people you
> don't want included than to add people who are no longer referenced in
> the new buffer at all.

True.

Ciao, Gregor
-- 
 -... --- .-. . -.. ..--.. ...-.-

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 0/6] reply to sender
  2012-01-08 21:48 ` [PATCH v2 0/6] reply to sender Jani Nikula
  2012-01-09  8:22   ` David Edmondson
@ 2012-01-09 18:55   ` Dmitry Kurochkin
  1 sibling, 0 replies; 81+ messages in thread
From: Dmitry Kurochkin @ 2012-01-09 18:55 UTC (permalink / raw)
  To: Jani Nikula, notmuch

Hi Jani.

I prefer to leave the Emacs UI default reply behavior as is.

Changing it in CLI would not affect me, but I think the default should
be the same as in the Emacs UI.

Regards,
  Dmitry

^ permalink raw reply	[flat|nested] 81+ messages in thread

* [PATCH v3 0/4] reply to sender
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (14 preceding siblings ...)
  2012-01-08 21:48 ` [PATCH v2 6/6] test: add tests for "notmuch reply" --reply-to=sender Jani Nikula
@ 2012-01-10 19:54 ` Jani Nikula
  2012-01-10 19:54 ` [PATCH v3 1/4] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
                   ` (15 subsequent siblings)
  31 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-10 19:54 UTC (permalink / raw)
  To: notmuch

Hi all, v3 of the reply-to-sender series.

Changes since v2:

- Patches 1 and 2 of the original series were pushed already.

- Patch 1: Don't force recipient type, based on comment by Mark
  (id:"877h11eq3g.fsf@qmul.ac.uk"). Fix man page accordinly, and clean
  up the wording a bit otherwise too.

- Patch 4: Fix according to above change, reverting back to Mark's
  original patch.

There have now been comments for and against patch 3 (rebinding 'r'
for reply-to-sender and 'R' for reply-to-all). Perhaps there are just
too many people that are used to 'r' for reply-to-all by now. I'll
just leave it up to David be the referee here. ;)


BR,
Jani.


Jani Nikula (3):
  cli: add support for replying just to the sender in "notmuch reply"
  emacs: add support for replying just to the sender
  emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all

Mark Walters (1):
  test: add tests for "notmuch reply" --reply-to=sender

 emacs/notmuch-mua.el     |    9 ++-
 emacs/notmuch-show.el    |   12 ++-
 emacs/notmuch.el         |   11 ++-
 man/man1/notmuch-reply.1 |   28 +++++-
 notmuch-reply.c          |   70 ++++++++++++----
 test/notmuch-test        |    1 +
 test/reply-to-sender     |  209 ++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 310 insertions(+), 30 deletions(-)
 create mode 100755 test/reply-to-sender

-- 
1.7.5.4

^ permalink raw reply	[flat|nested] 81+ messages in thread

* [PATCH v3 1/4] cli: add support for replying just to the sender in "notmuch reply"
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (15 preceding siblings ...)
  2012-01-10 19:54 ` [PATCH v3 0/4] reply to sender Jani Nikula
@ 2012-01-10 19:54 ` Jani Nikula
  2012-01-12  3:31   ` Austin Clements
  2012-01-10 19:54 ` [PATCH v3 2/4] emacs: add support for replying just to the sender Jani Nikula
                   ` (14 subsequent siblings)
  31 siblings, 1 reply; 81+ messages in thread
From: Jani Nikula @ 2012-01-10 19:54 UTC (permalink / raw)
  To: notmuch

Add new option --reply-to=(all|sender) to "notmuch reply" to select whether
to reply to all (sender and all recipients), or just sender. Reply to all
remains the default.

Credits to Mark Walters <markwalters1009@gmail.com> for his similar earlier
work where I picked up the basic idea of handling reply-to-sender in
add_recipients_from_message(). All bugs are mine, though.

Signed-off-by: Jani Nikula <jani@nikula.org>

---

Settled on --reply-to=(all|sender) per Carl's earlier suggestion
(id:87pqn5cg4g.fsf@yoom.home.cworth.org) and David's approval on IRC.
---
 man/man1/notmuch-reply.1 |   28 +++++++++++++++---
 notmuch-reply.c          |   70 ++++++++++++++++++++++++++++++++++-----------
 2 files changed, 76 insertions(+), 22 deletions(-)

diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1
index db464d8..5160ece 100644
--- a/man/man1/notmuch-reply.1
+++ b/man/man1/notmuch-reply.1
@@ -14,11 +14,13 @@ Constructs a reply template for a set of messages.
 To make replying to email easier,
 .B notmuch reply
 takes an existing set of messages and constructs a suitable mail
-template. The Reply-to header (if any, otherwise From:) is used for
-the To: address. Vales from the To: and Cc: headers are copied, but
-not including any of the current user's email addresses (as configured
-in primary_mail or other_email in the .notmuch\-config file) in the
-recipient list
+template. The Reply-to: header (if any, otherwise From:) is used for
+the To: address. Unless
+.BR \-\-reply-to=sender
+is specified, values from the To: and Cc: headers are copied, but not
+including any of the current user's email addresses (as configured in
+primary_mail or other_email in the .notmuch\-config file) in the
+recipient list.
 
 It also builds a suitable new subject, including Re: at the front (if
 not already present), and adding the message IDs of the messages being
@@ -45,6 +47,22 @@ Includes subject and quoted message body.
 Only produces In\-Reply\-To, References, To, Cc, and Bcc headers.
 .RE
 .RE
+.RS
+.TP 4
+.BR \-\-reply\-to= ( all | sender )
+.RS
+.TP 4
+.BR all " (default)"
+Replies to all addresses.
+.TP 4
+.BR sender
+Replies only to the sender. If replying to user's own message
+(Reply-to: or From: header is one of the user's configured email
+addresses), try To:, Cc:, and Bcc: headers in this order, and copy
+values from the first that contains something other than only the
+user's addresses.
+.RE
+.RE
 
 See \fBnotmuch-search-terms\fR(7)
 for details of the supported syntax for <search-terms>.
diff --git a/notmuch-reply.c b/notmuch-reply.c
index 000f6da..7b785a7 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -170,7 +170,7 @@ address_is_users (const char *address, notmuch_config_t *config)
 
 /* For each address in 'list' that is not configured as one of the
  * user's addresses in 'config', add that address to 'message' as an
- * address of 'type'.
+ * address of 'type', if 'add' is true.
  *
  * The first address encountered that *is* the user's address will be
  * returned, (otherwise NULL is returned).
@@ -179,7 +179,8 @@ static const char *
 add_recipients_for_address_list (GMimeMessage *message,
 				 notmuch_config_t *config,
 				 GMimeRecipientType type,
-				 InternetAddressList *list)
+				 InternetAddressList *list,
+				 notmuch_bool_t add)
 {
     InternetAddress *address;
     int i;
@@ -197,7 +198,7 @@ add_recipients_for_address_list (GMimeMessage *message,
 		continue;
 
 	    add_recipients_for_address_list (message, config,
-					     type, group_list);
+					     type, group_list, add);
 	} else {
 	    InternetAddressMailbox *mailbox;
 	    const char *name;
@@ -211,7 +212,7 @@ add_recipients_for_address_list (GMimeMessage *message,
 	    if (address_is_users (addr, config)) {
 		if (ret == NULL)
 		    ret = addr;
-	    } else {
+	    } else if (add) {
 		g_mime_message_add_recipient (message, type, name, addr);
 	    }
 	}
@@ -222,7 +223,7 @@ add_recipients_for_address_list (GMimeMessage *message,
 
 /* For each address in 'recipients' that is not configured as one of
  * the user's addresses in 'config', add that address to 'message' as
- * an address of 'type'.
+ * an address of 'type', if 'add' is true.
  *
  * The first address encountered that *is* the user's address will be
  * returned, (otherwise NULL is returned).
@@ -231,7 +232,8 @@ static const char *
 add_recipients_for_string (GMimeMessage *message,
 			   notmuch_config_t *config,
 			   GMimeRecipientType type,
-			   const char *recipients)
+			   const char *recipients,
+			   notmuch_bool_t add)
 {
     InternetAddressList *list;
 
@@ -242,7 +244,7 @@ add_recipients_for_string (GMimeMessage *message,
     if (list == NULL)
 	return NULL;
 
-    return add_recipients_for_address_list (message, config, type, list);
+    return add_recipients_for_address_list (message, config, type, list, add);
 }
 
 /* Does the address in the Reply-To header of 'message' already appear
@@ -286,13 +288,19 @@ reply_to_header_is_redundant (notmuch_message_t *message)
 
 /* Augments the recipients of reply from the headers of message.
  *
+ * If 'reply_all' is true, use sender and all recipients, otherwise use the
+ * first header that contains something other than the user's addresses
+ * (typically this would be reply-to-sender, but also handles reply to user's
+ * own message in a sensible way).
+ *
  * If any of the user's addresses were found in these headers, the first
  * of these returned, otherwise NULL is returned.
  */
 static const char *
 add_recipients_from_message (GMimeMessage *reply,
 			     notmuch_config_t *config,
-			     notmuch_message_t *message)
+			     notmuch_message_t *message,
+			     notmuch_bool_t reply_all)
 {
     struct {
 	const char *header;
@@ -305,6 +313,7 @@ add_recipients_from_message (GMimeMessage *reply,
 	{ "bcc",        NULL, GMIME_RECIPIENT_TYPE_BCC }
     };
     const char *from_addr = NULL;
+    notmuch_bool_t add_recipients = TRUE;
     unsigned int i;
 
     /* Some mailing lists munge the Reply-To header despite it being A Bad
@@ -325,6 +334,7 @@ add_recipients_from_message (GMimeMessage *reply,
 
     for (i = 0; i < ARRAY_SIZE (reply_to_map); i++) {
 	const char *addr, *recipients;
+	GMimeRecipientType recipient_type = reply_to_map[i].recipient_type;
 
 	recipients = notmuch_message_get_header (message,
 						 reply_to_map[i].header);
@@ -332,11 +342,29 @@ add_recipients_from_message (GMimeMessage *reply,
 	    recipients = notmuch_message_get_header (message,
 						     reply_to_map[i].fallback);
 
-	addr = add_recipients_for_string (reply, config,
-					  reply_to_map[i].recipient_type,
-					  recipients);
+	addr = add_recipients_for_string (reply, config, recipient_type,
+					  recipients, add_recipients);
+
 	if (from_addr == NULL)
 	    from_addr = addr;
+
+	if (!reply_all) {
+	    /* Stop adding new recipients in reply-to-sender mode if we have
+	     * added some recipient(s) above.
+	     *
+	     * This also handles the case of user replying to his own message,
+	     * where reply-to/from is not a recipient. In this case there may be
+	     * more than one recipient even if not replying to all.
+	     */
+	    InternetAddressList *list;
+	    list = g_mime_message_get_recipients (reply, recipient_type);
+	    if (list && internet_address_list_length (list))
+		add_recipients = FALSE;
+
+	    /* Check if we've got a from address and all recipients we need. */
+	    if (!add_recipients && from_addr)
+		break;
+	}
     }
 
     return from_addr;
@@ -480,7 +508,8 @@ static int
 notmuch_reply_format_default(void *ctx,
 			     notmuch_config_t *config,
 			     notmuch_query_t *query,
-			     notmuch_show_params_t *params)
+			     notmuch_show_params_t *params,
+			     notmuch_bool_t reply_all)
 {
     GMimeMessage *reply;
     notmuch_messages_t *messages;
@@ -509,7 +538,8 @@ notmuch_reply_format_default(void *ctx,
 	    g_mime_message_set_subject (reply, subject);
 	}
 
-	from_addr = add_recipients_from_message (reply, config, message);
+	from_addr = add_recipients_from_message (reply, config, message,
+						 reply_all);
 
 	if (from_addr == NULL)
 	    from_addr = guess_from_received_header (config, message);
@@ -558,7 +588,8 @@ static int
 notmuch_reply_format_headers_only(void *ctx,
 				  notmuch_config_t *config,
 				  notmuch_query_t *query,
-				  unused (notmuch_show_params_t *params))
+				  unused (notmuch_show_params_t *params),
+				  notmuch_bool_t reply_all)
 {
     GMimeMessage *reply;
     notmuch_messages_t *messages;
@@ -598,7 +629,7 @@ notmuch_reply_format_headers_only(void *ctx,
 	g_mime_object_set_header (GMIME_OBJECT (reply),
 				  "References", references);
 
-	(void)add_recipients_from_message (reply, config, message);
+	(void)add_recipients_from_message (reply, config, message, reply_all);
 
 	reply_headers = g_mime_object_to_string (GMIME_OBJECT (reply));
 	printf ("%s", reply_headers);
@@ -625,9 +656,10 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
     notmuch_query_t *query;
     char *query_string;
     int opt_index, ret = 0;
-    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params);
+    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params, notmuch_bool_t reply_all);
     notmuch_show_params_t params = { .part = -1 };
     int format = FORMAT_DEFAULT;
+    int reply_all = TRUE;
     notmuch_bool_t decrypt = FALSE;
 
     notmuch_opt_desc_t options[] = {
@@ -635,6 +667,10 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 	  (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT },
 				  { "headers-only", FORMAT_HEADERS_ONLY },
 				  { 0, 0 } } },
+	{ NOTMUCH_OPT_KEYWORD, &reply_all, "reply-to", 'r',
+	  (notmuch_keyword_t []){ { "all", TRUE },
+				  { "sender", FALSE },
+				  { 0, 0 } } },
 	{ NOTMUCH_OPT_BOOLEAN, &decrypt, "decrypt", 'd', 0 },
 	{ 0, 0, 0, 0, 0 }
     };
@@ -688,7 +724,7 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 	return 1;
     }
 
-    if (reply_format_func (ctx, config, query, &params) != 0)
+    if (reply_format_func (ctx, config, query, &params, reply_all) != 0)
 	return 1;
 
     notmuch_query_destroy (query);
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v3 2/4] emacs: add support for replying just to the sender
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (16 preceding siblings ...)
  2012-01-10 19:54 ` [PATCH v3 1/4] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
@ 2012-01-10 19:54 ` Jani Nikula
  2012-01-11  8:20   ` David Edmondson
  2012-01-10 19:54 ` [PATCH v3 3/4] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all Jani Nikula
                   ` (13 subsequent siblings)
  31 siblings, 1 reply; 81+ messages in thread
From: Jani Nikula @ 2012-01-10 19:54 UTC (permalink / raw)
  To: notmuch

Provide reply to sender counterparts to the search and show reply
functions. Add key binding 'R' to reply to sender, while keeping 'r' as
reply to all, both in search and show views.

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 emacs/notmuch-mua.el  |    9 ++++++---
 emacs/notmuch-show.el |   10 ++++++++--
 emacs/notmuch.el      |    9 ++++++++-
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 32e2e30..d8ab822 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -71,12 +71,15 @@ list."
 	    (push header message-hidden-headers)))
 	notmuch-mua-hidden-headers))
 
-(defun notmuch-mua-reply (query-string &optional sender)
+(defun notmuch-mua-reply (query-string &optional sender reply-all)
   (let (headers
 	body
 	(args '("reply")))
     (if notmuch-show-process-crypto
 	(setq args (append args '("--decrypt"))))
+    (if reply-all
+	(setq args (append args '("--reply-to=all")))
+      (setq args (append args '("--reply-to=sender"))))
     (setq args (append args (list query-string)))
     ;; This make assumptions about the output of `notmuch reply', but
     ;; really only that the headers come first followed by a blank
@@ -218,13 +221,13 @@ the From: address first."
 	(notmuch-mua-forward-message))
     (notmuch-mua-forward-message)))
 
-(defun notmuch-mua-new-reply (query-string &optional prompt-for-sender)
+(defun notmuch-mua-new-reply (query-string &optional prompt-for-sender reply-all)
   "Invoke the notmuch reply window."
   (interactive "P")
   (let ((sender
 	 (when prompt-for-sender
 	   (notmuch-mua-prompt-for-sender))))
-    (notmuch-mua-reply query-string sender)))
+    (notmuch-mua-reply query-string sender reply-all)))
 
 (defun notmuch-mua-send-and-exit (&optional arg)
   (interactive "P")
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 5502efd..96eea19 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -933,6 +933,7 @@ thread id.  If a prefix is given, crypto processing is toggled."
 	(define-key map "m" 'notmuch-mua-new-mail)
 	(define-key map "f" 'notmuch-show-forward-message)
 	(define-key map "r" 'notmuch-show-reply)
+	(define-key map "R" 'notmuch-show-reply-sender)
 	(define-key map "|" 'notmuch-show-pipe-message)
 	(define-key map "w" 'notmuch-show-save-attachments)
 	(define-key map "V" 'notmuch-show-view-raw-message)
@@ -1237,9 +1238,14 @@ any effects from previous calls to
       (notmuch-show-previous-message)))))
 
 (defun notmuch-show-reply (&optional prompt-for-sender)
-  "Reply to the current message."
+  "Reply to the sender and all recipients of the current message."
   (interactive "P")
-  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender))
+  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender t))
+
+(defun notmuch-show-reply-sender (&optional prompt-for-sender)
+  "Reply to the sender of the current message."
+  (interactive "P")
+  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender nil))
 
 (defun notmuch-show-forward-message (&optional prompt-for-sender)
   "Forward the current message."
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 1e61775..9ac2888 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -214,6 +214,7 @@ For a mouse binding, return nil."
     (define-key map "p" 'notmuch-search-previous-thread)
     (define-key map "n" 'notmuch-search-next-thread)
     (define-key map "r" 'notmuch-search-reply-to-thread)
+    (define-key map "R" 'notmuch-search-reply-to-thread-sender)
     (define-key map "m" 'notmuch-mua-new-mail)
     (define-key map "s" 'notmuch-search)
     (define-key map "o" 'notmuch-search-toggle-order)
@@ -448,10 +449,16 @@ Complete list of currently available key bindings:
       (message "End of search results."))))
 
 (defun notmuch-search-reply-to-thread (&optional prompt-for-sender)
+  "Begin composing a reply-all to the entire current thread in a new buffer."
+  (interactive "P")
+  (let ((message-id (notmuch-search-find-thread-id)))
+    (notmuch-mua-new-reply message-id prompt-for-sender t)))
+
+(defun notmuch-search-reply-to-thread-sender (&optional prompt-for-sender)
   "Begin composing a reply to the entire current thread in a new buffer."
   (interactive "P")
   (let ((message-id (notmuch-search-find-thread-id)))
-    (notmuch-mua-new-reply message-id prompt-for-sender)))
+    (notmuch-mua-new-reply message-id prompt-for-sender nil)))
 
 (defun notmuch-call-notmuch-process (&rest args)
   "Synchronously invoke \"notmuch\" with the given list of arguments.
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v3 3/4] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (17 preceding siblings ...)
  2012-01-10 19:54 ` [PATCH v3 2/4] emacs: add support for replying just to the sender Jani Nikula
@ 2012-01-10 19:54 ` Jani Nikula
  2012-01-11  8:21   ` David Edmondson
  2012-01-10 19:54 ` [PATCH v3 4/4] test: add tests for "notmuch reply" --reply-to=sender Jani Nikula
                   ` (12 subsequent siblings)
  31 siblings, 1 reply; 81+ messages in thread
From: Jani Nikula @ 2012-01-10 19:54 UTC (permalink / raw)
  To: notmuch

Change the default reply key bindings, making 'r' reply-to-sender and 'R'
reply-to-all.

Signed-off-by: Jani Nikula <jani@nikula.org>

---

There were mixed feelings about this. This as a separate patch so it's easy
to drop if needed.
---
 emacs/notmuch-show.el |    4 ++--
 emacs/notmuch.el      |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 96eea19..8f8ea93 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -932,8 +932,8 @@ thread id.  If a prefix is given, crypto processing is toggled."
 	(define-key map "s" 'notmuch-search)
 	(define-key map "m" 'notmuch-mua-new-mail)
 	(define-key map "f" 'notmuch-show-forward-message)
-	(define-key map "r" 'notmuch-show-reply)
-	(define-key map "R" 'notmuch-show-reply-sender)
+	(define-key map "r" 'notmuch-show-reply-sender)
+	(define-key map "R" 'notmuch-show-reply)
 	(define-key map "|" 'notmuch-show-pipe-message)
 	(define-key map "w" 'notmuch-show-save-attachments)
 	(define-key map "V" 'notmuch-show-view-raw-message)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 9ac2888..d952c41 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -213,8 +213,8 @@ For a mouse binding, return nil."
     (define-key map ">" 'notmuch-search-last-thread)
     (define-key map "p" 'notmuch-search-previous-thread)
     (define-key map "n" 'notmuch-search-next-thread)
-    (define-key map "r" 'notmuch-search-reply-to-thread)
-    (define-key map "R" 'notmuch-search-reply-to-thread-sender)
+    (define-key map "r" 'notmuch-search-reply-to-thread-sender)
+    (define-key map "R" 'notmuch-search-reply-to-thread)
     (define-key map "m" 'notmuch-mua-new-mail)
     (define-key map "s" 'notmuch-search)
     (define-key map "o" 'notmuch-search-toggle-order)
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v3 4/4] test: add tests for "notmuch reply" --reply-to=sender
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (18 preceding siblings ...)
  2012-01-10 19:54 ` [PATCH v3 3/4] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all Jani Nikula
@ 2012-01-10 19:54 ` Jani Nikula
  2012-01-12  3:50   ` Austin Clements
  2012-01-12 21:40 ` [PATCH v4 0/5] reply to sender Jani Nikula
                   ` (11 subsequent siblings)
  31 siblings, 1 reply; 81+ messages in thread
From: Jani Nikula @ 2012-01-10 19:54 UTC (permalink / raw)
  To: notmuch

From: Mark Walters <markwalters1009@gmail.com>

---
 test/notmuch-test    |    1 +
 test/reply-to-sender |  209 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 210 insertions(+), 0 deletions(-)
 create mode 100755 test/reply-to-sender

diff --git a/test/notmuch-test b/test/notmuch-test
index e40ef86..6a99ae3 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -33,6 +33,7 @@ TESTS="
   thread-naming
   raw
   reply
+  reply-to-sender
   dump-restore
   uuencode
   thread-order
diff --git a/test/reply-to-sender b/test/reply-to-sender
new file mode 100755
index 0000000..c7d15bb
--- /dev/null
+++ b/test/reply-to-sender
@@ -0,0 +1,209 @@
+#!/usr/bin/env bash
+test_description="\"notmuch reply --reply-to=sender\" in several variations"
+. ./test-lib.sh
+
+test_begin_subtest "Basic reply-to-sender"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="basic reply-to-sender test"'
+
+output=$(notmuch reply --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> basic reply-to-sender test"
+
+test_begin_subtest "From Us, Basic reply to message"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[to]="Recipient <recipient@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="basic reply-to-from-us test"'
+
+output=$(notmuch reply --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Recipient <recipient@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> basic reply-to-from-us test"
+
+test_begin_subtest "Multiple recipients"
+add_message '[from]="Sender <sender@example.com>"' \
+            '[to]="test_suite@notmuchmail.org, Someone Else <someone@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="Multiple recipients"'
+
+output=$(notmuch reply  --reply-to=sender  id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> Multiple recipients"
+
+test_begin_subtest "From Us, Multiple TO recipients"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[to]="Recipient <recipient@example.com>, Someone Else <someone@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="From Us, Multiple TO recipients"'
+
+output=$(notmuch reply  --reply-to=sender  id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Recipient <recipient@example.com>, Someone Else <someone@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> From Us, Multiple TO recipients"
+
+test_begin_subtest "Reply with CC"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+            '[cc]="Other Parties <cc@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> reply with CC"
+
+test_begin_subtest "From Us, Reply with CC"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[to]="Recipient <recipient@example.com>"' \
+            '[cc]="Other Parties <cc@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Recipient <recipient@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> reply with CC"
+
+test_begin_subtest "From Us, Reply no TO but with CC"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[cc]="Other Parties <cc@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+Cc: Other Parties <cc@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> reply with CC"
+
+test_begin_subtest "Reply from alternate address"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite_other@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply from alternate address"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite_other@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> reply from alternate address"
+
+test_begin_subtest "Support for Reply-To"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="support for reply-to"' \
+            '[reply-to]="Sender <elsewhere@example.com>"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <elsewhere@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> support for reply-to"
+
+test_begin_subtest "Support for Reply-To with multiple recipients"
+add_message '[from]="Sender <sender@example.com>"' \
+            '[to]="test_suite@notmuchmail.org, Someone Else <someone@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="support for reply-to with multiple recipients"' \
+            '[reply-to]="Sender <elsewhere@example.com>"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <elsewhere@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> support for reply-to with multiple recipients"
+
+test_begin_subtest "Un-munging Reply-To"
+add_message '[from]="Sender <sender@example.com>"' \
+            '[to]="Some List <list@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="Un-munging Reply-To"' \
+            '[reply-to]="Evil Munging List <list@example.com>"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> Un-munging Reply-To"
+
+test_begin_subtest "Message with header of exactly 200 bytes"
+add_message '[subject]="This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces"' \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="200-byte header"'
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> 200-byte header"
+test_done
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* Re: [PATCH v3 2/4] emacs: add support for replying just to the sender
  2012-01-10 19:54 ` [PATCH v3 2/4] emacs: add support for replying just to the sender Jani Nikula
@ 2012-01-11  8:20   ` David Edmondson
  2012-01-11  8:45     ` Jani Nikula
  2012-01-11 21:15     ` Aaron Ecay
  0 siblings, 2 replies; 81+ messages in thread
From: David Edmondson @ 2012-01-11  8:20 UTC (permalink / raw)
  To: Jani Nikula, notmuch

[-- Attachment #1: Type: text/plain, Size: 1171 bytes --]

On Tue, 10 Jan 2012 21:54:02 +0200, Jani Nikula <jani@nikula.org> wrote:
> Provide reply to sender counterparts to the search and show reply
> functions. Add key binding 'R' to reply to sender, while keeping 'r' as
> reply to all, both in search and show views.

All looks fine. My only comments are nits.

> -(defun notmuch-mua-reply (query-string &optional sender)
> +(defun notmuch-mua-reply (query-string &optional sender reply-all)
>    (let (headers
>  	body
>  	(args '("reply")))
>      (if notmuch-show-process-crypto
>  	(setq args (append args '("--decrypt"))))
> +    (if reply-all
> +	(setq args (append args '("--reply-to=all")))
> +      (setq args (append args '("--reply-to=sender"))))
>      (setq args (append args (list query-string)))

I don't like how this ends up. How about something like:

(defun notmuch-mua-reply (query-string &optional sender)
  (let (headers
	body
	(args (nconc (list "reply"
                           (concat "--reply-to="
                                   (if reply-all "all" "sender")))
		     (when notmuch-show-process-crypto
		       (list "--decrypt"))
		     (list query-string))))

But even that is not very nice.

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v3 3/4] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all
  2012-01-10 19:54 ` [PATCH v3 3/4] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all Jani Nikula
@ 2012-01-11  8:21   ` David Edmondson
  0 siblings, 0 replies; 81+ messages in thread
From: David Edmondson @ 2012-01-11  8:21 UTC (permalink / raw)
  To: Jani Nikula, notmuch

[-- Attachment #1: Type: text/plain, Size: 225 bytes --]

On Tue, 10 Jan 2012 21:54:03 +0200, Jani Nikula <jani@nikula.org> wrote:
> Change the default reply key bindings, making 'r' reply-to-sender and 'R'
> reply-to-all.

Code looks fine. I've no strong opinion about the binding.

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v3 2/4] emacs: add support for replying just to the sender
  2012-01-11  8:20   ` David Edmondson
@ 2012-01-11  8:45     ` Jani Nikula
  2012-01-11  9:08       ` David Edmondson
  2012-01-11 21:15     ` Aaron Ecay
  1 sibling, 1 reply; 81+ messages in thread
From: Jani Nikula @ 2012-01-11  8:45 UTC (permalink / raw)
  To: David Edmondson, notmuch

On Wed, 11 Jan 2012 08:20:56 +0000, David Edmondson <dme@dme.org> wrote:
> On Tue, 10 Jan 2012 21:54:02 +0200, Jani Nikula <jani@nikula.org> wrote:
> > Provide reply to sender counterparts to the search and show reply
> > functions. Add key binding 'R' to reply to sender, while keeping 'r' as
> > reply to all, both in search and show views.
> 
> All looks fine. My only comments are nits.
> 
> > -(defun notmuch-mua-reply (query-string &optional sender)
> > +(defun notmuch-mua-reply (query-string &optional sender reply-all)
> >    (let (headers
> >  	body
> >  	(args '("reply")))
> >      (if notmuch-show-process-crypto
> >  	(setq args (append args '("--decrypt"))))
> > +    (if reply-all
> > +	(setq args (append args '("--reply-to=all")))
> > +      (setq args (append args '("--reply-to=sender"))))
> >      (setq args (append args (list query-string)))
> 
> I don't like how this ends up. How about something like:
> 
> (defun notmuch-mua-reply (query-string &optional sender)
>   (let (headers
> 	body
> 	(args (nconc (list "reply"
>                            (concat "--reply-to="
>                                    (if reply-all "all" "sender")))
> 		     (when notmuch-show-process-crypto
> 		       (list "--decrypt"))
> 		     (list query-string))))
> 
> But even that is not very nice.

I think the original looks better, and is easier to grasp, even if it's
perhaps not as lispy. Besides, the last time you thought this was fine
(id:"cunehv91e05.fsf@hotblack-desiato.hh.sledj.net"), and the patch
hasn't changed since. ;)

BR,
Jani.

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v3 2/4] emacs: add support for replying just to the sender
  2012-01-11  8:45     ` Jani Nikula
@ 2012-01-11  9:08       ` David Edmondson
  0 siblings, 0 replies; 81+ messages in thread
From: David Edmondson @ 2012-01-11  9:08 UTC (permalink / raw)
  To: Jani Nikula, notmuch

[-- Attachment #1: Type: text/plain, Size: 337 bytes --]

On Wed, 11 Jan 2012 08:45:35 +0000, Jani Nikula <jani@nikula.org> wrote:
> I think the original looks better, and is easier to grasp, even if it's
> perhaps not as lispy. Besides, the last time you thought this was fine
> (id:"cunehv91e05.fsf@hotblack-desiato.hh.sledj.net"), and the patch
> hasn't changed since. ;)

Like I said, nits.

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v3 2/4] emacs: add support for replying just to the sender
  2012-01-11  8:20   ` David Edmondson
  2012-01-11  8:45     ` Jani Nikula
@ 2012-01-11 21:15     ` Aaron Ecay
  2012-01-11 22:08       ` Jani Nikula
  1 sibling, 1 reply; 81+ messages in thread
From: Aaron Ecay @ 2012-01-11 21:15 UTC (permalink / raw)
  To: David Edmondson, Jani Nikula, notmuch

On Wed, 11 Jan 2012 08:20:56 +0000, David Edmondson <dme@dme.org> wrote:
> On Tue, 10 Jan 2012 21:54:02 +0200, Jani Nikula <jani@nikula.org> wrote:
> > -(defun notmuch-mua-reply (query-string &optional sender)
> > +(defun notmuch-mua-reply (query-string &optional sender reply-all)
> >    (let (headers
> >  	body
> >  	(args '("reply")))
> >      (if notmuch-show-process-crypto
> >  	(setq args (append args '("--decrypt"))))
> > +    (if reply-all
> > +	(setq args (append args '("--reply-to=all")))
> > +      (setq args (append args '("--reply-to=sender"))))
> >      (setq args (append args (list query-string)))
> 
> I don't like how this ends up. How about something like:
> 
> (defun notmuch-mua-reply (query-string &optional sender)
>   (let (headers
> 	body
> 	(args (nconc (list "reply"
>                            (concat "--reply-to="
>                                    (if reply-all "all" "sender")))
> 		     (when notmuch-show-process-crypto
> 		       (list "--decrypt"))
> 		     (list query-string))))

What about using ‘format’:

(let (...
      (args (format "reply --reply-to=%s %s %s"
                    (if reply-all "all" "sender")
                    (if notmuch-show-process-crypto "--decrypt" "")
                    query-string)))
  ...)

It’s still not beautiful, but maybe it is better?

-- 
Aaron Ecay

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v3 2/4] emacs: add support for replying just to the sender
  2012-01-11 21:15     ` Aaron Ecay
@ 2012-01-11 22:08       ` Jani Nikula
  0 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-11 22:08 UTC (permalink / raw)
  To: Aaron Ecay, David Edmondson, notmuch

On Wed, 11 Jan 2012 16:15:30 -0500, Aaron Ecay <aaronecay@gmail.com> wrote:
> On Wed, 11 Jan 2012 08:20:56 +0000, David Edmondson <dme@dme.org> wrote:
> > On Tue, 10 Jan 2012 21:54:02 +0200, Jani Nikula <jani@nikula.org> wrote:
> > > -(defun notmuch-mua-reply (query-string &optional sender)
> > > +(defun notmuch-mua-reply (query-string &optional sender reply-all)
> > >    (let (headers
> > >  	body
> > >  	(args '("reply")))
> > >      (if notmuch-show-process-crypto
> > >  	(setq args (append args '("--decrypt"))))
> > > +    (if reply-all
> > > +	(setq args (append args '("--reply-to=all")))
> > > +      (setq args (append args '("--reply-to=sender"))))
> > >      (setq args (append args (list query-string)))
> > 
> > I don't like how this ends up. How about something like:
> > 
> > (defun notmuch-mua-reply (query-string &optional sender)
> >   (let (headers
> > 	body
> > 	(args (nconc (list "reply"
> >                            (concat "--reply-to="
> >                                    (if reply-all "all" "sender")))
> > 		     (when notmuch-show-process-crypto
> > 		       (list "--decrypt"))
> > 		     (list query-string))))
> 
> What about using ‘format’:
> 
> (let (...
>       (args (format "reply --reply-to=%s %s %s"
>                     (if reply-all "all" "sender")
>                     (if notmuch-show-process-crypto "--decrypt" "")
>                     query-string)))
>   ...)
> 
> It’s still not beautiful, but maybe it is better?

I don't think it works. The arguments to call-process need to be a list,
not a string.

BR,
Jani.

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v3 1/4] cli: add support for replying just to the sender in "notmuch reply"
  2012-01-10 19:54 ` [PATCH v3 1/4] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
@ 2012-01-12  3:31   ` Austin Clements
  0 siblings, 0 replies; 81+ messages in thread
From: Austin Clements @ 2012-01-12  3:31 UTC (permalink / raw)
  To: Jani Nikula; +Cc: notmuch

Quoth Jani Nikula on Jan 10 at  9:54 pm:
> Add new option --reply-to=(all|sender) to "notmuch reply" to select whether
> to reply to all (sender and all recipients), or just sender. Reply to all
> remains the default.
> 
> Credits to Mark Walters <markwalters1009@gmail.com> for his similar earlier
> work where I picked up the basic idea of handling reply-to-sender in
> add_recipients_from_message(). All bugs are mine, though.
> 
> Signed-off-by: Jani Nikula <jani@nikula.org>
> 
> ---
> 
> Settled on --reply-to=(all|sender) per Carl's earlier suggestion
> (id:87pqn5cg4g.fsf@yoom.home.cworth.org) and David's approval on IRC.
> ---
>  man/man1/notmuch-reply.1 |   28 +++++++++++++++---
>  notmuch-reply.c          |   70 ++++++++++++++++++++++++++++++++++-----------
>  2 files changed, 76 insertions(+), 22 deletions(-)
> 
> diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1
> index db464d8..5160ece 100644
> --- a/man/man1/notmuch-reply.1
> +++ b/man/man1/notmuch-reply.1
> @@ -14,11 +14,13 @@ Constructs a reply template for a set of messages.
>  To make replying to email easier,
>  .B notmuch reply
>  takes an existing set of messages and constructs a suitable mail
> -template. The Reply-to header (if any, otherwise From:) is used for
> -the To: address. Vales from the To: and Cc: headers are copied, but
> -not including any of the current user's email addresses (as configured
> -in primary_mail or other_email in the .notmuch\-config file) in the
> -recipient list
> +template. The Reply-to: header (if any, otherwise From:) is used for
> +the To: address. Unless
> +.BR \-\-reply-to=sender
> +is specified, values from the To: and Cc: headers are copied, but not
> +including any of the current user's email addresses (as configured in
> +primary_mail or other_email in the .notmuch\-config file) in the
> +recipient list.
>  
>  It also builds a suitable new subject, including Re: at the front (if
>  not already present), and adding the message IDs of the messages being
> @@ -45,6 +47,22 @@ Includes subject and quoted message body.
>  Only produces In\-Reply\-To, References, To, Cc, and Bcc headers.
>  .RE
>  .RE
> +.RS
> +.TP 4
> +.BR \-\-reply\-to= ( all | sender )
> +.RS
> +.TP 4
> +.BR all " (default)"
> +Replies to all addresses.
> +.TP 4
> +.BR sender
> +Replies only to the sender. If replying to user's own message
> +(Reply-to: or From: header is one of the user's configured email
> +addresses), try To:, Cc:, and Bcc: headers in this order, and copy
> +values from the first that contains something other than only the
> +user's addresses.
> +.RE
> +.RE
>  
>  See \fBnotmuch-search-terms\fR(7)
>  for details of the supported syntax for <search-terms>.
> diff --git a/notmuch-reply.c b/notmuch-reply.c
> index 000f6da..7b785a7 100644
> --- a/notmuch-reply.c
> +++ b/notmuch-reply.c
> @@ -170,7 +170,7 @@ address_is_users (const char *address, notmuch_config_t *config)
>  
>  /* For each address in 'list' that is not configured as one of the
>   * user's addresses in 'config', add that address to 'message' as an
> - * address of 'type'.
> + * address of 'type', if 'add' is true.

I puzzled over this for a while before I figured out what was actually
going on here.  I was confused because this comment makes it sound
like this function doesn't do what its name says if 'add' is false.
And, in fact, it doesn't!

I understand from an evolutionary standpoint why the code works this
way, but at the very least, I think the comment should call out this
peculiarity.  Better might be to rename the function, since it's now
more general purpose than adding recipients for an address list, and
possibly change its API slightly to reflect its generality.  Off the
top of my head, I'm thinking something like

/* Scan address list 'list'.
 *
 * If 'add' is non-NULL, then for each address in 'list' that is not
 * configured as one of the user's addresses in 'config', add that
 * address to 'message' as an address of 'type'.  If any addresses are
 * added, set *added_ret to TRUE.
 *
 * If one of the user's addresses is encountered in 'list' and
 * *user_addr_ret is not NULL, set *user_addr_ret to this address.
 */
static void
scan_address_list (InternetAddressList *list,
                   notmuch_config_t *config,
                   GMimeMessage *add, GMimeRecipientType add_type,
                   notmuch_bool_t *added_ret,
                   const char **user_addr_ret)

(The reason for added_ret is below.)  This would barely change the
code (in fact, it would simplify the handling of from_addr), but I
think it would make the function less misleading.

>   *
>   * The first address encountered that *is* the user's address will be
>   * returned, (otherwise NULL is returned).
> @@ -179,7 +179,8 @@ static const char *
>  add_recipients_for_address_list (GMimeMessage *message,
>  				 notmuch_config_t *config,
>  				 GMimeRecipientType type,
> -				 InternetAddressList *list)
> +				 InternetAddressList *list,
> +				 notmuch_bool_t add)
>  {
>      InternetAddress *address;
>      int i;
> @@ -197,7 +198,7 @@ add_recipients_for_address_list (GMimeMessage *message,
>  		continue;
>  
>  	    add_recipients_for_address_list (message, config,
> -					     type, group_list);
> +					     type, group_list, add);
>  	} else {
>  	    InternetAddressMailbox *mailbox;
>  	    const char *name;
> @@ -211,7 +212,7 @@ add_recipients_for_address_list (GMimeMessage *message,
>  	    if (address_is_users (addr, config)) {
>  		if (ret == NULL)
>  		    ret = addr;
> -	    } else {
> +	    } else if (add) {
>  		g_mime_message_add_recipient (message, type, name, addr);
>  	    }
>  	}
> @@ -222,7 +223,7 @@ add_recipients_for_address_list (GMimeMessage *message,
>  
>  /* For each address in 'recipients' that is not configured as one of
>   * the user's addresses in 'config', add that address to 'message' as
> - * an address of 'type'.
> + * an address of 'type', if 'add' is true.
>   *
>   * The first address encountered that *is* the user's address will be
>   * returned, (otherwise NULL is returned).
> @@ -231,7 +232,8 @@ static const char *
>  add_recipients_for_string (GMimeMessage *message,
>  			   notmuch_config_t *config,
>  			   GMimeRecipientType type,
> -			   const char *recipients)
> +			   const char *recipients,
> +			   notmuch_bool_t add)
>  {
>      InternetAddressList *list;
>  
> @@ -242,7 +244,7 @@ add_recipients_for_string (GMimeMessage *message,
>      if (list == NULL)
>  	return NULL;
>  
> -    return add_recipients_for_address_list (message, config, type, list);
> +    return add_recipients_for_address_list (message, config, type, list, add);
>  }
>  
>  /* Does the address in the Reply-To header of 'message' already appear
> @@ -286,13 +288,19 @@ reply_to_header_is_redundant (notmuch_message_t *message)
>  
>  /* Augments the recipients of reply from the headers of message.
>   *
> + * If 'reply_all' is true, use sender and all recipients, otherwise use the
> + * first header that contains something other than the user's addresses

Since there's no context here, perhaps you could elaborate on "first
header"?  Maybe ".. otherwise scan the reply-to, from, to, cc, and bcc
headers for the first that contains something other than the user's
addresses and add the recipients from this header (typically ..".

> + * (typically this would be reply-to-sender, but also handles reply to user's
> + * own message in a sensible way).
> + *
>   * If any of the user's addresses were found in these headers, the first
>   * of these returned, otherwise NULL is returned.
>   */
>  static const char *
>  add_recipients_from_message (GMimeMessage *reply,
>  			     notmuch_config_t *config,
> -			     notmuch_message_t *message)
> +			     notmuch_message_t *message,
> +			     notmuch_bool_t reply_all)
>  {
>      struct {
>  	const char *header;
> @@ -305,6 +313,7 @@ add_recipients_from_message (GMimeMessage *reply,
>  	{ "bcc",        NULL, GMIME_RECIPIENT_TYPE_BCC }
>      };
>      const char *from_addr = NULL;
> +    notmuch_bool_t add_recipients = TRUE;
>      unsigned int i;
>  
>      /* Some mailing lists munge the Reply-To header despite it being A Bad
> @@ -325,6 +334,7 @@ add_recipients_from_message (GMimeMessage *reply,
>  
>      for (i = 0; i < ARRAY_SIZE (reply_to_map); i++) {
>  	const char *addr, *recipients;
> +	GMimeRecipientType recipient_type = reply_to_map[i].recipient_type;
>  
>  	recipients = notmuch_message_get_header (message,
>  						 reply_to_map[i].header);
> @@ -332,11 +342,29 @@ add_recipients_from_message (GMimeMessage *reply,
>  	    recipients = notmuch_message_get_header (message,
>  						     reply_to_map[i].fallback);
>  
> -	addr = add_recipients_for_string (reply, config,
> -					  reply_to_map[i].recipient_type,
> -					  recipients);
> +	addr = add_recipients_for_string (reply, config, recipient_type,
> +					  recipients, add_recipients);
> +
>  	if (from_addr == NULL)
>  	    from_addr = addr;
> +
> +	if (!reply_all) {
> +	    /* Stop adding new recipients in reply-to-sender mode if we have
> +	     * added some recipient(s) above.
> +	     *
> +	     * This also handles the case of user replying to his own message,
> +	     * where reply-to/from is not a recipient. In this case there may be
> +	     * more than one recipient even if not replying to all.
> +	     */
> +	    InternetAddressList *list;
> +	    list = g_mime_message_get_recipients (reply, recipient_type);
> +	    if (list && internet_address_list_length (list))
> +		add_recipients = FALSE;

Is this different from just determining if add_recipients_for_string
added anything?  If not, maybe add_recipients_for_string (or
scan_address_list) could simply return whether or not it added any
recipients.

> +
> +	    /* Check if we've got a from address and all recipients we need. */
> +	    if (!add_recipients && from_addr)
> +		break;
> +	}
>      }
>  
>      return from_addr;
> @@ -480,7 +508,8 @@ static int
>  notmuch_reply_format_default(void *ctx,
>  			     notmuch_config_t *config,
>  			     notmuch_query_t *query,
> -			     notmuch_show_params_t *params)
> +			     notmuch_show_params_t *params,
> +			     notmuch_bool_t reply_all)
>  {
>      GMimeMessage *reply;
>      notmuch_messages_t *messages;
> @@ -509,7 +538,8 @@ notmuch_reply_format_default(void *ctx,
>  	    g_mime_message_set_subject (reply, subject);
>  	}
>  
> -	from_addr = add_recipients_from_message (reply, config, message);
> +	from_addr = add_recipients_from_message (reply, config, message,
> +						 reply_all);
>  
>  	if (from_addr == NULL)
>  	    from_addr = guess_from_received_header (config, message);
> @@ -558,7 +588,8 @@ static int
>  notmuch_reply_format_headers_only(void *ctx,
>  				  notmuch_config_t *config,
>  				  notmuch_query_t *query,
> -				  unused (notmuch_show_params_t *params))
> +				  unused (notmuch_show_params_t *params),
> +				  notmuch_bool_t reply_all)
>  {
>      GMimeMessage *reply;
>      notmuch_messages_t *messages;
> @@ -598,7 +629,7 @@ notmuch_reply_format_headers_only(void *ctx,
>  	g_mime_object_set_header (GMIME_OBJECT (reply),
>  				  "References", references);
>  
> -	(void)add_recipients_from_message (reply, config, message);
> +	(void)add_recipients_from_message (reply, config, message, reply_all);
>  
>  	reply_headers = g_mime_object_to_string (GMIME_OBJECT (reply));
>  	printf ("%s", reply_headers);
> @@ -625,9 +656,10 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
>      notmuch_query_t *query;
>      char *query_string;
>      int opt_index, ret = 0;
> -    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params);
> +    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params, notmuch_bool_t reply_all);
>      notmuch_show_params_t params = { .part = -1 };
>      int format = FORMAT_DEFAULT;
> +    int reply_all = TRUE;
>      notmuch_bool_t decrypt = FALSE;
>  
>      notmuch_opt_desc_t options[] = {
> @@ -635,6 +667,10 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
>  	  (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT },
>  				  { "headers-only", FORMAT_HEADERS_ONLY },
>  				  { 0, 0 } } },
> +	{ NOTMUCH_OPT_KEYWORD, &reply_all, "reply-to", 'r',
> +	  (notmuch_keyword_t []){ { "all", TRUE },
> +				  { "sender", FALSE },
> +				  { 0, 0 } } },
>  	{ NOTMUCH_OPT_BOOLEAN, &decrypt, "decrypt", 'd', 0 },
>  	{ 0, 0, 0, 0, 0 }
>      };
> @@ -688,7 +724,7 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
>  	return 1;
>      }
>  
> -    if (reply_format_func (ctx, config, query, &params) != 0)
> +    if (reply_format_func (ctx, config, query, &params, reply_all) != 0)
>  	return 1;
>  
>      notmuch_query_destroy (query);

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v3 4/4] test: add tests for "notmuch reply" --reply-to=sender
  2012-01-10 19:54 ` [PATCH v3 4/4] test: add tests for "notmuch reply" --reply-to=sender Jani Nikula
@ 2012-01-12  3:50   ` Austin Clements
  2012-01-12 12:59     ` Tomi Ollila
  0 siblings, 1 reply; 81+ messages in thread
From: Austin Clements @ 2012-01-12  3:50 UTC (permalink / raw)
  To: Jani Nikula; +Cc: notmuch

I'm not sure what the point of the last test is, but this patch
covered everything I could think of, so LGTM.

Quoth Jani Nikula on Jan 10 at  9:54 pm:
> From: Mark Walters <markwalters1009@gmail.com>
> 
> ---
>  test/notmuch-test    |    1 +
>  test/reply-to-sender |  209 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 210 insertions(+), 0 deletions(-)
>  create mode 100755 test/reply-to-sender
> 
> diff --git a/test/notmuch-test b/test/notmuch-test
> index e40ef86..6a99ae3 100755
> --- a/test/notmuch-test
> +++ b/test/notmuch-test
> @@ -33,6 +33,7 @@ TESTS="
>    thread-naming
>    raw
>    reply
> +  reply-to-sender
>    dump-restore
>    uuencode
>    thread-order
> diff --git a/test/reply-to-sender b/test/reply-to-sender
> new file mode 100755
> index 0000000..c7d15bb
> --- /dev/null
> +++ b/test/reply-to-sender
> @@ -0,0 +1,209 @@
> +#!/usr/bin/env bash
> +test_description="\"notmuch reply --reply-to=sender\" in several variations"
> +. ./test-lib.sh
> +
> +test_begin_subtest "Basic reply-to-sender"
> +add_message '[from]="Sender <sender@example.com>"' \
> +             [to]=test_suite@notmuchmail.org \
> +             [subject]=notmuch-reply-test \
> +            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
> +            '[body]="basic reply-to-sender test"'
> +
> +output=$(notmuch reply --reply-to=sender id:${gen_msg_id})
> +test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
> +Subject: Re: notmuch-reply-test
> +To: Sender <sender@example.com>
> +In-Reply-To: <${gen_msg_id}>
> +References: <${gen_msg_id}>
> +
> +On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
> +> basic reply-to-sender test"
> +
> +test_begin_subtest "From Us, Basic reply to message"
> +add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
> +            '[to]="Recipient <recipient@example.com>"' \
> +             [subject]=notmuch-reply-test \
> +            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
> +            '[body]="basic reply-to-from-us test"'
> +
> +output=$(notmuch reply --reply-to=sender id:${gen_msg_id})
> +test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
> +Subject: Re: notmuch-reply-test
> +To: Recipient <recipient@example.com>
> +In-Reply-To: <${gen_msg_id}>
> +References: <${gen_msg_id}>
> +
> +On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
> +> basic reply-to-from-us test"
> +
> +test_begin_subtest "Multiple recipients"
> +add_message '[from]="Sender <sender@example.com>"' \
> +            '[to]="test_suite@notmuchmail.org, Someone Else <someone@example.com>"' \
> +             [subject]=notmuch-reply-test \
> +            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
> +            '[body]="Multiple recipients"'
> +
> +output=$(notmuch reply  --reply-to=sender  id:${gen_msg_id})
> +test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
> +Subject: Re: notmuch-reply-test
> +To: Sender <sender@example.com>
> +In-Reply-To: <${gen_msg_id}>
> +References: <${gen_msg_id}>
> +
> +On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
> +> Multiple recipients"
> +
> +test_begin_subtest "From Us, Multiple TO recipients"
> +add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
> +            '[to]="Recipient <recipient@example.com>, Someone Else <someone@example.com>"' \
> +             [subject]=notmuch-reply-test \
> +            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
> +            '[body]="From Us, Multiple TO recipients"'
> +
> +output=$(notmuch reply  --reply-to=sender  id:${gen_msg_id})
> +test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
> +Subject: Re: notmuch-reply-test
> +To: Recipient <recipient@example.com>, Someone Else <someone@example.com>
> +In-Reply-To: <${gen_msg_id}>
> +References: <${gen_msg_id}>
> +
> +On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
> +> From Us, Multiple TO recipients"
> +
> +test_begin_subtest "Reply with CC"
> +add_message '[from]="Sender <sender@example.com>"' \
> +             [to]=test_suite@notmuchmail.org \
> +            '[cc]="Other Parties <cc@example.com>"' \
> +             [subject]=notmuch-reply-test \
> +            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
> +            '[body]="reply with CC"'
> +
> +output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
> +test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
> +Subject: Re: notmuch-reply-test
> +To: Sender <sender@example.com>
> +In-Reply-To: <${gen_msg_id}>
> +References: <${gen_msg_id}>
> +
> +On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
> +> reply with CC"
> +
> +test_begin_subtest "From Us, Reply with CC"
> +add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
> +            '[to]="Recipient <recipient@example.com>"' \
> +            '[cc]="Other Parties <cc@example.com>"' \
> +             [subject]=notmuch-reply-test \
> +            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
> +            '[body]="reply with CC"'
> +
> +output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
> +test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
> +Subject: Re: notmuch-reply-test
> +To: Recipient <recipient@example.com>
> +In-Reply-To: <${gen_msg_id}>
> +References: <${gen_msg_id}>
> +
> +On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
> +> reply with CC"
> +
> +test_begin_subtest "From Us, Reply no TO but with CC"
> +add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
> +            '[cc]="Other Parties <cc@example.com>"' \
> +             [subject]=notmuch-reply-test \
> +            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
> +            '[body]="reply with CC"'
> +
> +output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
> +test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
> +Subject: Re: notmuch-reply-test
> +Cc: Other Parties <cc@example.com>
> +In-Reply-To: <${gen_msg_id}>
> +References: <${gen_msg_id}>
> +
> +On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
> +> reply with CC"
> +
> +test_begin_subtest "Reply from alternate address"
> +add_message '[from]="Sender <sender@example.com>"' \
> +             [to]=test_suite_other@notmuchmail.org \
> +             [subject]=notmuch-reply-test \
> +            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
> +            '[body]="reply from alternate address"'
> +
> +output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
> +test_expect_equal "$output" "From: Notmuch Test Suite <test_suite_other@notmuchmail.org>
> +Subject: Re: notmuch-reply-test
> +To: Sender <sender@example.com>
> +In-Reply-To: <${gen_msg_id}>
> +References: <${gen_msg_id}>
> +
> +On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
> +> reply from alternate address"
> +
> +test_begin_subtest "Support for Reply-To"
> +add_message '[from]="Sender <sender@example.com>"' \
> +             [to]=test_suite@notmuchmail.org \
> +             [subject]=notmuch-reply-test \
> +            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
> +            '[body]="support for reply-to"' \
> +            '[reply-to]="Sender <elsewhere@example.com>"'
> +
> +output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
> +test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
> +Subject: Re: notmuch-reply-test
> +To: Sender <elsewhere@example.com>
> +In-Reply-To: <${gen_msg_id}>
> +References: <${gen_msg_id}>
> +
> +On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
> +> support for reply-to"
> +
> +test_begin_subtest "Support for Reply-To with multiple recipients"
> +add_message '[from]="Sender <sender@example.com>"' \
> +            '[to]="test_suite@notmuchmail.org, Someone Else <someone@example.com>"' \
> +             [subject]=notmuch-reply-test \
> +            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
> +            '[body]="support for reply-to with multiple recipients"' \
> +            '[reply-to]="Sender <elsewhere@example.com>"'
> +
> +output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
> +test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
> +Subject: Re: notmuch-reply-test
> +To: Sender <elsewhere@example.com>
> +In-Reply-To: <${gen_msg_id}>
> +References: <${gen_msg_id}>
> +
> +On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
> +> support for reply-to with multiple recipients"
> +
> +test_begin_subtest "Un-munging Reply-To"
> +add_message '[from]="Sender <sender@example.com>"' \
> +            '[to]="Some List <list@example.com>"' \
> +             [subject]=notmuch-reply-test \
> +            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
> +            '[body]="Un-munging Reply-To"' \
> +            '[reply-to]="Evil Munging List <list@example.com>"'
> +
> +output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
> +test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
> +Subject: Re: notmuch-reply-test
> +To: Sender <sender@example.com>
> +In-Reply-To: <${gen_msg_id}>
> +References: <${gen_msg_id}>
> +
> +On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
> +> Un-munging Reply-To"
> +
> +test_begin_subtest "Message with header of exactly 200 bytes"
> +add_message '[subject]="This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces"' \
> +            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
> +            '[body]="200-byte header"'
> +output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
> +test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
> +Subject: Re: This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces
> +In-Reply-To: <${gen_msg_id}>
> +References: <${gen_msg_id}>
> +
> +On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
> +> 200-byte header"
> +test_done

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v3 4/4] test: add tests for "notmuch reply" --reply-to=sender
  2012-01-12  3:50   ` Austin Clements
@ 2012-01-12 12:59     ` Tomi Ollila
  0 siblings, 0 replies; 81+ messages in thread
From: Tomi Ollila @ 2012-01-12 12:59 UTC (permalink / raw)
  To: Austin Clements, Jani Nikula; +Cc: notmuch

On Wed, 11 Jan 2012 22:50:32 -0500, Austin Clements <amdragon@MIT.EDU> wrote:
> I'm not sure what the point of the last test is, but this patch
> covered everything I could think of, so LGTM.

Maybe checking that long subject line (possibly split/join sometimes in the
process) keeps it's original form (?)

LGTM (and my opinion is that 'r' in emacs is changed to 'reply-to-sender'
-- more consistent with other clients and less error prone to use (note
that I've voted this already so this doesn't increase vote count there)). 

Tomi

^ permalink raw reply	[flat|nested] 81+ messages in thread

* [PATCH v4 0/5] reply to sender
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (19 preceding siblings ...)
  2012-01-10 19:54 ` [PATCH v3 4/4] test: add tests for "notmuch reply" --reply-to=sender Jani Nikula
@ 2012-01-12 21:40 ` Jani Nikula
  2012-01-12 21:40 ` [PATCH v4 1/5] cli: slightly refactor "notmuch reply" address scanning functions Jani Nikula
                   ` (10 subsequent siblings)
  31 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-12 21:40 UTC (permalink / raw)
  To: notmuch

Hi all, changes since v3:

Split the first patch into two, the first one refactoring the reply/from address
scanning, and the second one adding the actual reply-to-sender feature. This
addresses Austins comments in id:"20120112033146.GU20796@mit.edu" (and does
improve the code).

Patches 3-5 remain unchanged.


BR,
Jani.


Jani Nikula (4):
  cli: slightly refactor "notmuch reply" address scanning functions
  cli: add support for replying just to the sender in "notmuch reply"
  emacs: add support for replying just to the sender
  emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all

Mark Walters (1):
  test: add tests for "notmuch reply" --reply-to=sender

 emacs/notmuch-mua.el     |    9 ++-
 emacs/notmuch-show.el    |   12 ++-
 emacs/notmuch.el         |   11 ++-
 man/man1/notmuch-reply.1 |   28 +++++-
 notmuch-reply.c          |  122 +++++++++++++++++----------
 test/notmuch-test        |    1 +
 test/reply-to-sender     |  209 ++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 335 insertions(+), 57 deletions(-)
 create mode 100755 test/reply-to-sender

-- 
1.7.5.4

^ permalink raw reply	[flat|nested] 81+ messages in thread

* [PATCH v4 1/5] cli: slightly refactor "notmuch reply" address scanning functions
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (20 preceding siblings ...)
  2012-01-12 21:40 ` [PATCH v4 0/5] reply to sender Jani Nikula
@ 2012-01-12 21:40 ` Jani Nikula
  2012-01-12 21:59   ` Austin Clements
  2012-01-12 23:28   ` Mark Walters
  2012-01-12 21:40 ` [PATCH v4 2/5] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
                   ` (9 subsequent siblings)
  31 siblings, 2 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-12 21:40 UTC (permalink / raw)
  To: notmuch

Slightly refactor "notmuch reply" recipient and user from address scanning
functions in preparation for reply-to-sender feature.

Add support for not adding messages at all (just scan for user from
address), and returning the number of messages added.

No externally visible functional changes.

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 notmuch-reply.c |   74 ++++++++++++++++++++++++++++--------------------------
 1 files changed, 38 insertions(+), 36 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index 000f6da..4fae66f 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -168,22 +168,28 @@ address_is_users (const char *address, notmuch_config_t *config)
     return 0;
 }
 
-/* For each address in 'list' that is not configured as one of the
- * user's addresses in 'config', add that address to 'message' as an
- * address of 'type'.
+/* Scan addresses in 'list'.
  *
- * The first address encountered that *is* the user's address will be
- * returned, (otherwise NULL is returned).
+ * If 'message' is non-NULL, then for each address in 'list' that is not
+ * configured as one of the user's addresses in 'config', add that address to
+ * 'message' as an address of 'type'.
+ *
+ * If 'user_from' is non-NULL and *user_from is NULL, the first address
+ * encountered in 'list' that *is* the user's address will be set to *user_from.
+ *
+ * Return the number of addresses added to 'message'. (If 'message' is NULL, the
+ * function returns 0 by definition.)
  */
-static const char *
-add_recipients_for_address_list (GMimeMessage *message,
-				 notmuch_config_t *config,
-				 GMimeRecipientType type,
-				 InternetAddressList *list)
+static unsigned int
+scan_address_list (InternetAddressList *list,
+		   notmuch_config_t *config,
+		   GMimeMessage *message,
+		   GMimeRecipientType type,
+		   const char **user_from)
 {
     InternetAddress *address;
     int i;
-    const char *ret = NULL;
+    unsigned int n = 0;
 
     for (i = 0; i < internet_address_list_length (list); i++) {
 	address = internet_address_list_get_address (list, i);
@@ -196,8 +202,7 @@ add_recipients_for_address_list (GMimeMessage *message,
 	    if (group_list == NULL)
 		continue;
 
-	    add_recipients_for_address_list (message, config,
-					     type, group_list);
+	    n += scan_address_list (group_list, config, message, type, NULL);
 	} else {
 	    InternetAddressMailbox *mailbox;
 	    const char *name;
@@ -209,40 +214,40 @@ add_recipients_for_address_list (GMimeMessage *message,
 	    addr = internet_address_mailbox_get_addr (mailbox);
 
 	    if (address_is_users (addr, config)) {
-		if (ret == NULL)
-		    ret = addr;
-	    } else {
+		if (user_from && *user_from == NULL)
+		    *user_from = addr;
+	    } else if (message) {
 		g_mime_message_add_recipient (message, type, name, addr);
+		n++;
 	    }
 	}
     }
 
-    return ret;
+    return n;
 }
 
-/* For each address in 'recipients' that is not configured as one of
- * the user's addresses in 'config', add that address to 'message' as
- * an address of 'type'.
+/* Scan addresses in 'recipients'.
  *
- * The first address encountered that *is* the user's address will be
- * returned, (otherwise NULL is returned).
+ * See the documentation of scan_address_list() above. This function does
+ * exactly the same, but converts 'recipients' to an InternetAddressList first.
  */
-static const char *
-add_recipients_for_string (GMimeMessage *message,
-			   notmuch_config_t *config,
-			   GMimeRecipientType type,
-			   const char *recipients)
+static unsigned int
+scan_address_string (const char *recipients,
+		     notmuch_config_t *config,
+		     GMimeMessage *message,
+		     GMimeRecipientType type,
+		     const char **user_from)
 {
     InternetAddressList *list;
 
     if (recipients == NULL)
-	return NULL;
+	return 0;
 
     list = internet_address_list_parse_string (recipients);
     if (list == NULL)
-	return NULL;
+	return 0;
 
-    return add_recipients_for_address_list (message, config, type, list);
+    return scan_address_list (list, config, message, type, user_from);
 }
 
 /* Does the address in the Reply-To header of 'message' already appear
@@ -324,7 +329,7 @@ add_recipients_from_message (GMimeMessage *reply,
     }
 
     for (i = 0; i < ARRAY_SIZE (reply_to_map); i++) {
-	const char *addr, *recipients;
+	const char *recipients;
 
 	recipients = notmuch_message_get_header (message,
 						 reply_to_map[i].header);
@@ -332,11 +337,8 @@ add_recipients_from_message (GMimeMessage *reply,
 	    recipients = notmuch_message_get_header (message,
 						     reply_to_map[i].fallback);
 
-	addr = add_recipients_for_string (reply, config,
-					  reply_to_map[i].recipient_type,
-					  recipients);
-	if (from_addr == NULL)
-	    from_addr = addr;
+	scan_address_string (recipients, config, reply,
+			     reply_to_map[i].recipient_type, &from_addr);
     }
 
     return from_addr;
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v4 2/5] cli: add support for replying just to the sender in "notmuch reply"
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (21 preceding siblings ...)
  2012-01-12 21:40 ` [PATCH v4 1/5] cli: slightly refactor "notmuch reply" address scanning functions Jani Nikula
@ 2012-01-12 21:40 ` Jani Nikula
  2012-01-12 22:02   ` Austin Clements
  2012-01-12 23:46   ` Mark Walters
  2012-01-12 21:40 ` [PATCH v4 3/5] emacs: add support for replying just to the sender Jani Nikula
                   ` (8 subsequent siblings)
  31 siblings, 2 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-12 21:40 UTC (permalink / raw)
  To: notmuch

Add new option --reply-to=(all|sender) to "notmuch reply" to select whether
to reply to all (sender and all recipients), or just sender. Reply to all
remains the default.

Credits to Mark Walters <markwalters1009@gmail.com> for his similar earlier
work where I picked up the basic idea of handling reply-to-sender in
add_recipients_from_message(). All bugs are mine, though.

Signed-off-by: Jani Nikula <jani@nikula.org>

---

Settled on --reply-to=(all|sender) per Carl's earlier suggestion
(id:87pqn5cg4g.fsf@yoom.home.cworth.org) and David's approval on IRC.
---
 man/man1/notmuch-reply.1 |   28 ++++++++++++++++++++----
 notmuch-reply.c          |   52 +++++++++++++++++++++++++++++++++++++--------
 2 files changed, 65 insertions(+), 15 deletions(-)

diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1
index db464d8..5160ece 100644
--- a/man/man1/notmuch-reply.1
+++ b/man/man1/notmuch-reply.1
@@ -14,11 +14,13 @@ Constructs a reply template for a set of messages.
 To make replying to email easier,
 .B notmuch reply
 takes an existing set of messages and constructs a suitable mail
-template. The Reply-to header (if any, otherwise From:) is used for
-the To: address. Vales from the To: and Cc: headers are copied, but
-not including any of the current user's email addresses (as configured
-in primary_mail or other_email in the .notmuch\-config file) in the
-recipient list
+template. The Reply-to: header (if any, otherwise From:) is used for
+the To: address. Unless
+.BR \-\-reply-to=sender
+is specified, values from the To: and Cc: headers are copied, but not
+including any of the current user's email addresses (as configured in
+primary_mail or other_email in the .notmuch\-config file) in the
+recipient list.
 
 It also builds a suitable new subject, including Re: at the front (if
 not already present), and adding the message IDs of the messages being
@@ -45,6 +47,22 @@ Includes subject and quoted message body.
 Only produces In\-Reply\-To, References, To, Cc, and Bcc headers.
 .RE
 .RE
+.RS
+.TP 4
+.BR \-\-reply\-to= ( all | sender )
+.RS
+.TP 4
+.BR all " (default)"
+Replies to all addresses.
+.TP 4
+.BR sender
+Replies only to the sender. If replying to user's own message
+(Reply-to: or From: header is one of the user's configured email
+addresses), try To:, Cc:, and Bcc: headers in this order, and copy
+values from the first that contains something other than only the
+user's addresses.
+.RE
+.RE
 
 See \fBnotmuch-search-terms\fR(7)
 for details of the supported syntax for <search-terms>.
diff --git a/notmuch-reply.c b/notmuch-reply.c
index 4fae66f..b4c81de 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -289,7 +289,14 @@ reply_to_header_is_redundant (notmuch_message_t *message)
     return 0;
 }
 
-/* Augments the recipients of reply from the headers of message.
+/* Augment the recipients of 'reply' from the "Reply-to:", "From:", "To:",
+ * "Cc:", and "Bcc:" headers of 'message'.
+ *
+ * If 'reply_all' is true, use sender and all recipients, otherwise scan the
+ * headers for the first that contains something other than the user's addresses
+ * and add the recipients from this header (typically this would be
+ * reply-to-sender, but also handles reply to user's own message in a sensible
+ * way).
  *
  * If any of the user's addresses were found in these headers, the first
  * of these returned, otherwise NULL is returned.
@@ -297,7 +304,8 @@ reply_to_header_is_redundant (notmuch_message_t *message)
 static const char *
 add_recipients_from_message (GMimeMessage *reply,
 			     notmuch_config_t *config,
-			     notmuch_message_t *message)
+			     notmuch_message_t *message,
+			     notmuch_bool_t reply_all)
 {
     struct {
 	const char *header;
@@ -311,6 +319,7 @@ add_recipients_from_message (GMimeMessage *reply,
     };
     const char *from_addr = NULL;
     unsigned int i;
+    unsigned int n = 0;
 
     /* Some mailing lists munge the Reply-To header despite it being A Bad
      * Thing, see http://www.unicom.com/pw/reply-to-harmful.html
@@ -337,8 +346,23 @@ add_recipients_from_message (GMimeMessage *reply,
 	    recipients = notmuch_message_get_header (message,
 						     reply_to_map[i].fallback);
 
-	scan_address_string (recipients, config, reply,
-			     reply_to_map[i].recipient_type, &from_addr);
+	n += scan_address_string (recipients, config, reply,
+				  reply_to_map[i].recipient_type, &from_addr);
+
+	if (!reply_all && n) {
+	    /* Stop adding new recipients in reply-to-sender mode if we have
+	     * added some recipient(s) above.
+	     *
+	     * This also handles the case of user replying to his own message,
+	     * where reply-to/from is not a recipient. In this case there may be
+	     * more than one recipient even if not replying to all.
+	     */
+	    reply = NULL;
+
+	    /* From address and some recipients are enough, bail out. */
+	    if (from_addr)
+		break;
+	}
     }
 
     return from_addr;
@@ -482,7 +506,8 @@ static int
 notmuch_reply_format_default(void *ctx,
 			     notmuch_config_t *config,
 			     notmuch_query_t *query,
-			     notmuch_show_params_t *params)
+			     notmuch_show_params_t *params,
+			     notmuch_bool_t reply_all)
 {
     GMimeMessage *reply;
     notmuch_messages_t *messages;
@@ -511,7 +536,8 @@ notmuch_reply_format_default(void *ctx,
 	    g_mime_message_set_subject (reply, subject);
 	}
 
-	from_addr = add_recipients_from_message (reply, config, message);
+	from_addr = add_recipients_from_message (reply, config, message,
+						 reply_all);
 
 	if (from_addr == NULL)
 	    from_addr = guess_from_received_header (config, message);
@@ -560,7 +586,8 @@ static int
 notmuch_reply_format_headers_only(void *ctx,
 				  notmuch_config_t *config,
 				  notmuch_query_t *query,
-				  unused (notmuch_show_params_t *params))
+				  unused (notmuch_show_params_t *params),
+				  notmuch_bool_t reply_all)
 {
     GMimeMessage *reply;
     notmuch_messages_t *messages;
@@ -600,7 +627,7 @@ notmuch_reply_format_headers_only(void *ctx,
 	g_mime_object_set_header (GMIME_OBJECT (reply),
 				  "References", references);
 
-	(void)add_recipients_from_message (reply, config, message);
+	(void)add_recipients_from_message (reply, config, message, reply_all);
 
 	reply_headers = g_mime_object_to_string (GMIME_OBJECT (reply));
 	printf ("%s", reply_headers);
@@ -627,9 +654,10 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
     notmuch_query_t *query;
     char *query_string;
     int opt_index, ret = 0;
-    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params);
+    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params, notmuch_bool_t reply_all);
     notmuch_show_params_t params = { .part = -1 };
     int format = FORMAT_DEFAULT;
+    int reply_all = TRUE;
     notmuch_bool_t decrypt = FALSE;
 
     notmuch_opt_desc_t options[] = {
@@ -637,6 +665,10 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 	  (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT },
 				  { "headers-only", FORMAT_HEADERS_ONLY },
 				  { 0, 0 } } },
+	{ NOTMUCH_OPT_KEYWORD, &reply_all, "reply-to", 'r',
+	  (notmuch_keyword_t []){ { "all", TRUE },
+				  { "sender", FALSE },
+				  { 0, 0 } } },
 	{ NOTMUCH_OPT_BOOLEAN, &decrypt, "decrypt", 'd', 0 },
 	{ 0, 0, 0, 0, 0 }
     };
@@ -690,7 +722,7 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 	return 1;
     }
 
-    if (reply_format_func (ctx, config, query, &params) != 0)
+    if (reply_format_func (ctx, config, query, &params, reply_all) != 0)
 	return 1;
 
     notmuch_query_destroy (query);
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v4 3/5] emacs: add support for replying just to the sender
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (22 preceding siblings ...)
  2012-01-12 21:40 ` [PATCH v4 2/5] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
@ 2012-01-12 21:40 ` Jani Nikula
  2012-01-12 21:40 ` [PATCH v4 4/5] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all Jani Nikula
                   ` (7 subsequent siblings)
  31 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-12 21:40 UTC (permalink / raw)
  To: notmuch

Provide reply to sender counterparts to the search and show reply
functions. Add key binding 'R' to reply to sender, while keeping 'r' as
reply to all, both in search and show views.

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 emacs/notmuch-mua.el  |    9 ++++++---
 emacs/notmuch-show.el |   10 ++++++++--
 emacs/notmuch.el      |    9 ++++++++-
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 32e2e30..d8ab822 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -71,12 +71,15 @@ list."
 	    (push header message-hidden-headers)))
 	notmuch-mua-hidden-headers))
 
-(defun notmuch-mua-reply (query-string &optional sender)
+(defun notmuch-mua-reply (query-string &optional sender reply-all)
   (let (headers
 	body
 	(args '("reply")))
     (if notmuch-show-process-crypto
 	(setq args (append args '("--decrypt"))))
+    (if reply-all
+	(setq args (append args '("--reply-to=all")))
+      (setq args (append args '("--reply-to=sender"))))
     (setq args (append args (list query-string)))
     ;; This make assumptions about the output of `notmuch reply', but
     ;; really only that the headers come first followed by a blank
@@ -218,13 +221,13 @@ the From: address first."
 	(notmuch-mua-forward-message))
     (notmuch-mua-forward-message)))
 
-(defun notmuch-mua-new-reply (query-string &optional prompt-for-sender)
+(defun notmuch-mua-new-reply (query-string &optional prompt-for-sender reply-all)
   "Invoke the notmuch reply window."
   (interactive "P")
   (let ((sender
 	 (when prompt-for-sender
 	   (notmuch-mua-prompt-for-sender))))
-    (notmuch-mua-reply query-string sender)))
+    (notmuch-mua-reply query-string sender reply-all)))
 
 (defun notmuch-mua-send-and-exit (&optional arg)
   (interactive "P")
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 5502efd..96eea19 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -933,6 +933,7 @@ thread id.  If a prefix is given, crypto processing is toggled."
 	(define-key map "m" 'notmuch-mua-new-mail)
 	(define-key map "f" 'notmuch-show-forward-message)
 	(define-key map "r" 'notmuch-show-reply)
+	(define-key map "R" 'notmuch-show-reply-sender)
 	(define-key map "|" 'notmuch-show-pipe-message)
 	(define-key map "w" 'notmuch-show-save-attachments)
 	(define-key map "V" 'notmuch-show-view-raw-message)
@@ -1237,9 +1238,14 @@ any effects from previous calls to
       (notmuch-show-previous-message)))))
 
 (defun notmuch-show-reply (&optional prompt-for-sender)
-  "Reply to the current message."
+  "Reply to the sender and all recipients of the current message."
   (interactive "P")
-  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender))
+  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender t))
+
+(defun notmuch-show-reply-sender (&optional prompt-for-sender)
+  "Reply to the sender of the current message."
+  (interactive "P")
+  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender nil))
 
 (defun notmuch-show-forward-message (&optional prompt-for-sender)
   "Forward the current message."
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 1e61775..9ac2888 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -214,6 +214,7 @@ For a mouse binding, return nil."
     (define-key map "p" 'notmuch-search-previous-thread)
     (define-key map "n" 'notmuch-search-next-thread)
     (define-key map "r" 'notmuch-search-reply-to-thread)
+    (define-key map "R" 'notmuch-search-reply-to-thread-sender)
     (define-key map "m" 'notmuch-mua-new-mail)
     (define-key map "s" 'notmuch-search)
     (define-key map "o" 'notmuch-search-toggle-order)
@@ -448,10 +449,16 @@ Complete list of currently available key bindings:
       (message "End of search results."))))
 
 (defun notmuch-search-reply-to-thread (&optional prompt-for-sender)
+  "Begin composing a reply-all to the entire current thread in a new buffer."
+  (interactive "P")
+  (let ((message-id (notmuch-search-find-thread-id)))
+    (notmuch-mua-new-reply message-id prompt-for-sender t)))
+
+(defun notmuch-search-reply-to-thread-sender (&optional prompt-for-sender)
   "Begin composing a reply to the entire current thread in a new buffer."
   (interactive "P")
   (let ((message-id (notmuch-search-find-thread-id)))
-    (notmuch-mua-new-reply message-id prompt-for-sender)))
+    (notmuch-mua-new-reply message-id prompt-for-sender nil)))
 
 (defun notmuch-call-notmuch-process (&rest args)
   "Synchronously invoke \"notmuch\" with the given list of arguments.
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v4 4/5] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (23 preceding siblings ...)
  2012-01-12 21:40 ` [PATCH v4 3/5] emacs: add support for replying just to the sender Jani Nikula
@ 2012-01-12 21:40 ` Jani Nikula
  2012-01-12 21:40 ` [PATCH v4 5/5] test: add tests for "notmuch reply" --reply-to=sender Jani Nikula
                   ` (6 subsequent siblings)
  31 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-12 21:40 UTC (permalink / raw)
  To: notmuch

Change the default reply key bindings, making 'r' reply-to-sender and 'R'
reply-to-all.

Signed-off-by: Jani Nikula <jani@nikula.org>

---

There were mixed feelings about this. This as a separate patch so it's easy
to drop if needed.
---
 emacs/notmuch-show.el |    4 ++--
 emacs/notmuch.el      |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 96eea19..8f8ea93 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -932,8 +932,8 @@ thread id.  If a prefix is given, crypto processing is toggled."
 	(define-key map "s" 'notmuch-search)
 	(define-key map "m" 'notmuch-mua-new-mail)
 	(define-key map "f" 'notmuch-show-forward-message)
-	(define-key map "r" 'notmuch-show-reply)
-	(define-key map "R" 'notmuch-show-reply-sender)
+	(define-key map "r" 'notmuch-show-reply-sender)
+	(define-key map "R" 'notmuch-show-reply)
 	(define-key map "|" 'notmuch-show-pipe-message)
 	(define-key map "w" 'notmuch-show-save-attachments)
 	(define-key map "V" 'notmuch-show-view-raw-message)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 9ac2888..d952c41 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -213,8 +213,8 @@ For a mouse binding, return nil."
     (define-key map ">" 'notmuch-search-last-thread)
     (define-key map "p" 'notmuch-search-previous-thread)
     (define-key map "n" 'notmuch-search-next-thread)
-    (define-key map "r" 'notmuch-search-reply-to-thread)
-    (define-key map "R" 'notmuch-search-reply-to-thread-sender)
+    (define-key map "r" 'notmuch-search-reply-to-thread-sender)
+    (define-key map "R" 'notmuch-search-reply-to-thread)
     (define-key map "m" 'notmuch-mua-new-mail)
     (define-key map "s" 'notmuch-search)
     (define-key map "o" 'notmuch-search-toggle-order)
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v4 5/5] test: add tests for "notmuch reply" --reply-to=sender
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (24 preceding siblings ...)
  2012-01-12 21:40 ` [PATCH v4 4/5] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all Jani Nikula
@ 2012-01-12 21:40 ` Jani Nikula
  2012-01-14 14:46 ` [PATCH v5 0/5] reply to sender Jani Nikula
                   ` (5 subsequent siblings)
  31 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-12 21:40 UTC (permalink / raw)
  To: notmuch

From: Mark Walters <markwalters1009@gmail.com>

---
 test/notmuch-test    |    1 +
 test/reply-to-sender |  209 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 210 insertions(+), 0 deletions(-)
 create mode 100755 test/reply-to-sender

diff --git a/test/notmuch-test b/test/notmuch-test
index e40ef86..6a99ae3 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -33,6 +33,7 @@ TESTS="
   thread-naming
   raw
   reply
+  reply-to-sender
   dump-restore
   uuencode
   thread-order
diff --git a/test/reply-to-sender b/test/reply-to-sender
new file mode 100755
index 0000000..c7d15bb
--- /dev/null
+++ b/test/reply-to-sender
@@ -0,0 +1,209 @@
+#!/usr/bin/env bash
+test_description="\"notmuch reply --reply-to=sender\" in several variations"
+. ./test-lib.sh
+
+test_begin_subtest "Basic reply-to-sender"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="basic reply-to-sender test"'
+
+output=$(notmuch reply --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> basic reply-to-sender test"
+
+test_begin_subtest "From Us, Basic reply to message"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[to]="Recipient <recipient@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="basic reply-to-from-us test"'
+
+output=$(notmuch reply --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Recipient <recipient@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> basic reply-to-from-us test"
+
+test_begin_subtest "Multiple recipients"
+add_message '[from]="Sender <sender@example.com>"' \
+            '[to]="test_suite@notmuchmail.org, Someone Else <someone@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="Multiple recipients"'
+
+output=$(notmuch reply  --reply-to=sender  id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> Multiple recipients"
+
+test_begin_subtest "From Us, Multiple TO recipients"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[to]="Recipient <recipient@example.com>, Someone Else <someone@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="From Us, Multiple TO recipients"'
+
+output=$(notmuch reply  --reply-to=sender  id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Recipient <recipient@example.com>, Someone Else <someone@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> From Us, Multiple TO recipients"
+
+test_begin_subtest "Reply with CC"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+            '[cc]="Other Parties <cc@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> reply with CC"
+
+test_begin_subtest "From Us, Reply with CC"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[to]="Recipient <recipient@example.com>"' \
+            '[cc]="Other Parties <cc@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Recipient <recipient@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> reply with CC"
+
+test_begin_subtest "From Us, Reply no TO but with CC"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[cc]="Other Parties <cc@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+Cc: Other Parties <cc@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> reply with CC"
+
+test_begin_subtest "Reply from alternate address"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite_other@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply from alternate address"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite_other@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> reply from alternate address"
+
+test_begin_subtest "Support for Reply-To"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="support for reply-to"' \
+            '[reply-to]="Sender <elsewhere@example.com>"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <elsewhere@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> support for reply-to"
+
+test_begin_subtest "Support for Reply-To with multiple recipients"
+add_message '[from]="Sender <sender@example.com>"' \
+            '[to]="test_suite@notmuchmail.org, Someone Else <someone@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="support for reply-to with multiple recipients"' \
+            '[reply-to]="Sender <elsewhere@example.com>"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <elsewhere@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> support for reply-to with multiple recipients"
+
+test_begin_subtest "Un-munging Reply-To"
+add_message '[from]="Sender <sender@example.com>"' \
+            '[to]="Some List <list@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="Un-munging Reply-To"' \
+            '[reply-to]="Evil Munging List <list@example.com>"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> Un-munging Reply-To"
+
+test_begin_subtest "Message with header of exactly 200 bytes"
+add_message '[subject]="This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces"' \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="200-byte header"'
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> 200-byte header"
+test_done
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* Re: [PATCH v4 1/5] cli: slightly refactor "notmuch reply" address scanning functions
  2012-01-12 21:40 ` [PATCH v4 1/5] cli: slightly refactor "notmuch reply" address scanning functions Jani Nikula
@ 2012-01-12 21:59   ` Austin Clements
  2012-01-14 14:22     ` Jani Nikula
  2012-01-12 23:28   ` Mark Walters
  1 sibling, 1 reply; 81+ messages in thread
From: Austin Clements @ 2012-01-12 21:59 UTC (permalink / raw)
  To: Jani Nikula; +Cc: notmuch

LGTM.  One thing you could fix below (and a few comments), but not
enough alone to warrant a new version.

Quoth Jani Nikula on Jan 12 at 11:40 pm:
> Slightly refactor "notmuch reply" recipient and user from address scanning
> functions in preparation for reply-to-sender feature.
> 
> Add support for not adding messages at all (just scan for user from
> address), and returning the number of messages added.
> 
> No externally visible functional changes.
> 
> Signed-off-by: Jani Nikula <jani@nikula.org>
> ---
>  notmuch-reply.c |   74 ++++++++++++++++++++++++++++--------------------------
>  1 files changed, 38 insertions(+), 36 deletions(-)
> 
> diff --git a/notmuch-reply.c b/notmuch-reply.c
> index 000f6da..4fae66f 100644
> --- a/notmuch-reply.c
> +++ b/notmuch-reply.c
> @@ -168,22 +168,28 @@ address_is_users (const char *address, notmuch_config_t *config)
>      return 0;
>  }
>  
> -/* For each address in 'list' that is not configured as one of the
> - * user's addresses in 'config', add that address to 'message' as an
> - * address of 'type'.
> +/* Scan addresses in 'list'.
>   *
> - * The first address encountered that *is* the user's address will be
> - * returned, (otherwise NULL is returned).
> + * If 'message' is non-NULL, then for each address in 'list' that is not
> + * configured as one of the user's addresses in 'config', add that address to
> + * 'message' as an address of 'type'.
> + *
> + * If 'user_from' is non-NULL and *user_from is NULL, the first address
> + * encountered in 'list' that *is* the user's address will be set to *user_from.
> + *
> + * Return the number of addresses added to 'message'. (If 'message' is NULL, the
> + * function returns 0 by definition.)

Ah, I like the return value.  Better than adding an umpteenth argument
like I was suggesting.

>   */
> -static const char *
> -add_recipients_for_address_list (GMimeMessage *message,
> -				 notmuch_config_t *config,
> -				 GMimeRecipientType type,
> -				 InternetAddressList *list)
> +static unsigned int
> +scan_address_list (InternetAddressList *list,
> +		   notmuch_config_t *config,
> +		   GMimeMessage *message,
> +		   GMimeRecipientType type,
> +		   const char **user_from)
>  {
>      InternetAddress *address;
>      int i;
> -    const char *ret = NULL;
> +    unsigned int n = 0;
>  
>      for (i = 0; i < internet_address_list_length (list); i++) {
>  	address = internet_address_list_get_address (list, i);
> @@ -196,8 +202,7 @@ add_recipients_for_address_list (GMimeMessage *message,
>  	    if (group_list == NULL)
>  		continue;
>  
> -	    add_recipients_for_address_list (message, config,
> -					     type, group_list);
> +	    n += scan_address_list (group_list, config, message, type, NULL);

Should the NULL above be user_from?  You're being compatible with the
original code, which is the right thing to do in this patch, but the
new-found explicitness made me wonder if this is actually a bug.

>  	} else {
>  	    InternetAddressMailbox *mailbox;
>  	    const char *name;
> @@ -209,40 +214,40 @@ add_recipients_for_address_list (GMimeMessage *message,
>  	    addr = internet_address_mailbox_get_addr (mailbox);
>  
>  	    if (address_is_users (addr, config)) {
> -		if (ret == NULL)
> -		    ret = addr;
> -	    } else {
> +		if (user_from && *user_from == NULL)
> +		    *user_from = addr;
> +	    } else if (message) {
>  		g_mime_message_add_recipient (message, type, name, addr);
> +		n++;
>  	    }
>  	}
>      }
>  
> -    return ret;
> +    return n;
>  }
>  
> -/* For each address in 'recipients' that is not configured as one of
> - * the user's addresses in 'config', add that address to 'message' as
> - * an address of 'type'.
> +/* Scan addresses in 'recipients'.
>   *
> - * The first address encountered that *is* the user's address will be
> - * returned, (otherwise NULL is returned).
> + * See the documentation of scan_address_list() above. This function does
> + * exactly the same, but converts 'recipients' to an InternetAddressList first.

Just bikeshedding, but comments in the notmuch codebase almost
universally wrap at 72 columns, not 80 (based on 
egrep '[ /]\* .{70}' *.[ch]*)

>   */
> -static const char *
> -add_recipients_for_string (GMimeMessage *message,
> -			   notmuch_config_t *config,
> -			   GMimeRecipientType type,
> -			   const char *recipients)
> +static unsigned int
> +scan_address_string (const char *recipients,
> +		     notmuch_config_t *config,
> +		     GMimeMessage *message,
> +		     GMimeRecipientType type,
> +		     const char **user_from)
>  {
>      InternetAddressList *list;
>  
>      if (recipients == NULL)
> -	return NULL;
> +	return 0;
>  
>      list = internet_address_list_parse_string (recipients);
>      if (list == NULL)
> -	return NULL;
> +	return 0;
>  
> -    return add_recipients_for_address_list (message, config, type, list);
> +    return scan_address_list (list, config, message, type, user_from);
>  }
>  
>  /* Does the address in the Reply-To header of 'message' already appear
> @@ -324,7 +329,7 @@ add_recipients_from_message (GMimeMessage *reply,
>      }
>  
>      for (i = 0; i < ARRAY_SIZE (reply_to_map); i++) {
> -	const char *addr, *recipients;
> +	const char *recipients;
>  
>  	recipients = notmuch_message_get_header (message,
>  						 reply_to_map[i].header);
> @@ -332,11 +337,8 @@ add_recipients_from_message (GMimeMessage *reply,
>  	    recipients = notmuch_message_get_header (message,
>  						     reply_to_map[i].fallback);
>  
> -	addr = add_recipients_for_string (reply, config,
> -					  reply_to_map[i].recipient_type,
> -					  recipients);
> -	if (from_addr == NULL)
> -	    from_addr = addr;
> +	scan_address_string (recipients, config, reply,
> +			     reply_to_map[i].recipient_type, &from_addr);
>      }
>  
>      return from_addr;

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v4 2/5] cli: add support for replying just to the sender in "notmuch reply"
  2012-01-12 21:40 ` [PATCH v4 2/5] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
@ 2012-01-12 22:02   ` Austin Clements
  2012-01-12 23:46   ` Mark Walters
  1 sibling, 0 replies; 81+ messages in thread
From: Austin Clements @ 2012-01-12 22:02 UTC (permalink / raw)
  To: Jani Nikula; +Cc: notmuch

LGTM.  Again, one minor nit below, but not enough to hold up this
patch.

Quoth Jani Nikula on Jan 12 at 11:40 pm:
> Add new option --reply-to=(all|sender) to "notmuch reply" to select whether
> to reply to all (sender and all recipients), or just sender. Reply to all
> remains the default.
> 
> Credits to Mark Walters <markwalters1009@gmail.com> for his similar earlier
> work where I picked up the basic idea of handling reply-to-sender in
> add_recipients_from_message(). All bugs are mine, though.
> 
> Signed-off-by: Jani Nikula <jani@nikula.org>
> 
> ---
> 
> Settled on --reply-to=(all|sender) per Carl's earlier suggestion
> (id:87pqn5cg4g.fsf@yoom.home.cworth.org) and David's approval on IRC.
> ---
>  man/man1/notmuch-reply.1 |   28 ++++++++++++++++++++----
>  notmuch-reply.c          |   52 +++++++++++++++++++++++++++++++++++++--------
>  2 files changed, 65 insertions(+), 15 deletions(-)
> 
> diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1
> index db464d8..5160ece 100644
> --- a/man/man1/notmuch-reply.1
> +++ b/man/man1/notmuch-reply.1
> @@ -14,11 +14,13 @@ Constructs a reply template for a set of messages.
>  To make replying to email easier,
>  .B notmuch reply
>  takes an existing set of messages and constructs a suitable mail
> -template. The Reply-to header (if any, otherwise From:) is used for
> -the To: address. Vales from the To: and Cc: headers are copied, but
> -not including any of the current user's email addresses (as configured
> -in primary_mail or other_email in the .notmuch\-config file) in the
> -recipient list
> +template. The Reply-to: header (if any, otherwise From:) is used for
> +the To: address. Unless
> +.BR \-\-reply-to=sender
> +is specified, values from the To: and Cc: headers are copied, but not
> +including any of the current user's email addresses (as configured in
> +primary_mail or other_email in the .notmuch\-config file) in the
> +recipient list.
>  
>  It also builds a suitable new subject, including Re: at the front (if
>  not already present), and adding the message IDs of the messages being
> @@ -45,6 +47,22 @@ Includes subject and quoted message body.
>  Only produces In\-Reply\-To, References, To, Cc, and Bcc headers.
>  .RE
>  .RE
> +.RS
> +.TP 4
> +.BR \-\-reply\-to= ( all | sender )
> +.RS
> +.TP 4
> +.BR all " (default)"
> +Replies to all addresses.
> +.TP 4
> +.BR sender
> +Replies only to the sender. If replying to user's own message
> +(Reply-to: or From: header is one of the user's configured email
> +addresses), try To:, Cc:, and Bcc: headers in this order, and copy
> +values from the first that contains something other than only the
> +user's addresses.
> +.RE
> +.RE
>  
>  See \fBnotmuch-search-terms\fR(7)
>  for details of the supported syntax for <search-terms>.
> diff --git a/notmuch-reply.c b/notmuch-reply.c
> index 4fae66f..b4c81de 100644
> --- a/notmuch-reply.c
> +++ b/notmuch-reply.c
> @@ -289,7 +289,14 @@ reply_to_header_is_redundant (notmuch_message_t *message)
>      return 0;
>  }
>  
> -/* Augments the recipients of reply from the headers of message.
> +/* Augment the recipients of 'reply' from the "Reply-to:", "From:", "To:",
> + * "Cc:", and "Bcc:" headers of 'message'.
> + *
> + * If 'reply_all' is true, use sender and all recipients, otherwise scan the
> + * headers for the first that contains something other than the user's addresses
> + * and add the recipients from this header (typically this would be
> + * reply-to-sender, but also handles reply to user's own message in a sensible
> + * way).

Same comment about 80 column wrapping.

>   *
>   * If any of the user's addresses were found in these headers, the first
>   * of these returned, otherwise NULL is returned.
> @@ -297,7 +304,8 @@ reply_to_header_is_redundant (notmuch_message_t *message)
>  static const char *
>  add_recipients_from_message (GMimeMessage *reply,
>  			     notmuch_config_t *config,
> -			     notmuch_message_t *message)
> +			     notmuch_message_t *message,
> +			     notmuch_bool_t reply_all)
>  {
>      struct {
>  	const char *header;
> @@ -311,6 +319,7 @@ add_recipients_from_message (GMimeMessage *reply,
>      };
>      const char *from_addr = NULL;
>      unsigned int i;
> +    unsigned int n = 0;
>  
>      /* Some mailing lists munge the Reply-To header despite it being A Bad
>       * Thing, see http://www.unicom.com/pw/reply-to-harmful.html
> @@ -337,8 +346,23 @@ add_recipients_from_message (GMimeMessage *reply,
>  	    recipients = notmuch_message_get_header (message,
>  						     reply_to_map[i].fallback);
>  
> -	scan_address_string (recipients, config, reply,
> -			     reply_to_map[i].recipient_type, &from_addr);
> +	n += scan_address_string (recipients, config, reply,
> +				  reply_to_map[i].recipient_type, &from_addr);
> +
> +	if (!reply_all && n) {
> +	    /* Stop adding new recipients in reply-to-sender mode if we have
> +	     * added some recipient(s) above.
> +	     *
> +	     * This also handles the case of user replying to his own message,
> +	     * where reply-to/from is not a recipient. In this case there may be
> +	     * more than one recipient even if not replying to all.
> +	     */
> +	    reply = NULL;
> +
> +	    /* From address and some recipients are enough, bail out. */
> +	    if (from_addr)
> +		break;

Nifty.

> +	}
>      }
>  
>      return from_addr;
> @@ -482,7 +506,8 @@ static int
>  notmuch_reply_format_default(void *ctx,
>  			     notmuch_config_t *config,
>  			     notmuch_query_t *query,
> -			     notmuch_show_params_t *params)
> +			     notmuch_show_params_t *params,
> +			     notmuch_bool_t reply_all)
>  {
>      GMimeMessage *reply;
>      notmuch_messages_t *messages;
> @@ -511,7 +536,8 @@ notmuch_reply_format_default(void *ctx,
>  	    g_mime_message_set_subject (reply, subject);
>  	}
>  
> -	from_addr = add_recipients_from_message (reply, config, message);
> +	from_addr = add_recipients_from_message (reply, config, message,
> +						 reply_all);
>  
>  	if (from_addr == NULL)
>  	    from_addr = guess_from_received_header (config, message);
> @@ -560,7 +586,8 @@ static int
>  notmuch_reply_format_headers_only(void *ctx,
>  				  notmuch_config_t *config,
>  				  notmuch_query_t *query,
> -				  unused (notmuch_show_params_t *params))
> +				  unused (notmuch_show_params_t *params),
> +				  notmuch_bool_t reply_all)
>  {
>      GMimeMessage *reply;
>      notmuch_messages_t *messages;
> @@ -600,7 +627,7 @@ notmuch_reply_format_headers_only(void *ctx,
>  	g_mime_object_set_header (GMIME_OBJECT (reply),
>  				  "References", references);
>  
> -	(void)add_recipients_from_message (reply, config, message);
> +	(void)add_recipients_from_message (reply, config, message, reply_all);
>  
>  	reply_headers = g_mime_object_to_string (GMIME_OBJECT (reply));
>  	printf ("%s", reply_headers);
> @@ -627,9 +654,10 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
>      notmuch_query_t *query;
>      char *query_string;
>      int opt_index, ret = 0;
> -    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params);
> +    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params, notmuch_bool_t reply_all);
>      notmuch_show_params_t params = { .part = -1 };
>      int format = FORMAT_DEFAULT;
> +    int reply_all = TRUE;
>      notmuch_bool_t decrypt = FALSE;
>  
>      notmuch_opt_desc_t options[] = {
> @@ -637,6 +665,10 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
>  	  (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT },
>  				  { "headers-only", FORMAT_HEADERS_ONLY },
>  				  { 0, 0 } } },
> +	{ NOTMUCH_OPT_KEYWORD, &reply_all, "reply-to", 'r',
> +	  (notmuch_keyword_t []){ { "all", TRUE },
> +				  { "sender", FALSE },
> +				  { 0, 0 } } },
>  	{ NOTMUCH_OPT_BOOLEAN, &decrypt, "decrypt", 'd', 0 },
>  	{ 0, 0, 0, 0, 0 }
>      };
> @@ -690,7 +722,7 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
>  	return 1;
>      }
>  
> -    if (reply_format_func (ctx, config, query, &params) != 0)
> +    if (reply_format_func (ctx, config, query, &params, reply_all) != 0)
>  	return 1;
>  
>      notmuch_query_destroy (query);

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v4 1/5] cli: slightly refactor "notmuch reply" address scanning functions
  2012-01-12 21:40 ` [PATCH v4 1/5] cli: slightly refactor "notmuch reply" address scanning functions Jani Nikula
  2012-01-12 21:59   ` Austin Clements
@ 2012-01-12 23:28   ` Mark Walters
  1 sibling, 0 replies; 81+ messages in thread
From: Mark Walters @ 2012-01-12 23:28 UTC (permalink / raw)
  To: Jani Nikula, notmuch


This is nice.

Two very minor nits:

In your commit message you say

> Add support for not adding messages at all (just scan for user from
> address), and returning the number of messages added.

and I think both "messages" should "recipients".

> + * If 'user_from' is non-NULL and *user_from is NULL, the first address
> + * encountered in 'list' that *is* the user's address will be set to *user_from.

This reads oddly: you are setting *user_from to the first address...
(rather than the other way round)

Best wishes

Mark
 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v4 2/5] cli: add support for replying just to the sender in "notmuch reply"
  2012-01-12 21:40 ` [PATCH v4 2/5] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
  2012-01-12 22:02   ` Austin Clements
@ 2012-01-12 23:46   ` Mark Walters
  1 sibling, 0 replies; 81+ messages in thread
From: Mark Walters @ 2012-01-12 23:46 UTC (permalink / raw)
  To: Jani Nikula, notmuch


LGTM

Best wishes

Mark

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v4 1/5] cli: slightly refactor "notmuch reply" address scanning functions
  2012-01-12 21:59   ` Austin Clements
@ 2012-01-14 14:22     ` Jani Nikula
  0 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-14 14:22 UTC (permalink / raw)
  To: Austin Clements; +Cc: notmuch

On Thu, 12 Jan 2012 16:59:05 -0500, Austin Clements <amdragon@MIT.EDU> wrote:
> LGTM.  One thing you could fix below (and a few comments), but not
> enough alone to warrant a new version.
> 
> Quoth Jani Nikula on Jan 12 at 11:40 pm:
> > Slightly refactor "notmuch reply" recipient and user from address scanning
> > functions in preparation for reply-to-sender feature.
> > 
> > Add support for not adding messages at all (just scan for user from
> > address), and returning the number of messages added.
> > 
> > No externally visible functional changes.
> > 
> > Signed-off-by: Jani Nikula <jani@nikula.org>
> > ---
> >  notmuch-reply.c |   74 ++++++++++++++++++++++++++++--------------------------
> >  1 files changed, 38 insertions(+), 36 deletions(-)
> > 
> > diff --git a/notmuch-reply.c b/notmuch-reply.c
> > index 000f6da..4fae66f 100644
> > --- a/notmuch-reply.c
> > +++ b/notmuch-reply.c
> > @@ -168,22 +168,28 @@ address_is_users (const char *address, notmuch_config_t *config)
> >      return 0;
> >  }
> >  
> > -/* For each address in 'list' that is not configured as one of the
> > - * user's addresses in 'config', add that address to 'message' as an
> > - * address of 'type'.
> > +/* Scan addresses in 'list'.
> >   *
> > - * The first address encountered that *is* the user's address will be
> > - * returned, (otherwise NULL is returned).
> > + * If 'message' is non-NULL, then for each address in 'list' that is not
> > + * configured as one of the user's addresses in 'config', add that address to
> > + * 'message' as an address of 'type'.
> > + *
> > + * If 'user_from' is non-NULL and *user_from is NULL, the first address
> > + * encountered in 'list' that *is* the user's address will be set to *user_from.
> > + *
> > + * Return the number of addresses added to 'message'. (If 'message' is NULL, the
> > + * function returns 0 by definition.)
> 
> Ah, I like the return value.  Better than adding an umpteenth argument
> like I was suggesting.
> 
> >   */
> > -static const char *
> > -add_recipients_for_address_list (GMimeMessage *message,
> > -				 notmuch_config_t *config,
> > -				 GMimeRecipientType type,
> > -				 InternetAddressList *list)
> > +static unsigned int
> > +scan_address_list (InternetAddressList *list,
> > +		   notmuch_config_t *config,
> > +		   GMimeMessage *message,
> > +		   GMimeRecipientType type,
> > +		   const char **user_from)
> >  {
> >      InternetAddress *address;
> >      int i;
> > -    const char *ret = NULL;
> > +    unsigned int n = 0;
> >  
> >      for (i = 0; i < internet_address_list_length (list); i++) {
> >  	address = internet_address_list_get_address (list, i);
> > @@ -196,8 +202,7 @@ add_recipients_for_address_list (GMimeMessage *message,
> >  	    if (group_list == NULL)
> >  		continue;
> >  
> > -	    add_recipients_for_address_list (message, config,
> > -					     type, group_list);
> > +	    n += scan_address_list (group_list, config, message, type, NULL);
> 
> Should the NULL above be user_from?  You're being compatible with the
> original code, which is the right thing to do in this patch, but the
> new-found explicitness made me wonder if this is actually a bug.

I didn't even know what a group list was, and if [1] is accurate, I
don't think I've ever seen one either. This does smell like a bug, but
I'm doubtful if anyone would ever notice... Anyway, as you say, it
should be another patch, and independent of this series.

BR,
Jani.

[1] http://www.cs.tut.fi/~jkorpela/rfc/822addr.html

> 
> >  	} else {
> >  	    InternetAddressMailbox *mailbox;
> >  	    const char *name;
> > @@ -209,40 +214,40 @@ add_recipients_for_address_list (GMimeMessage *message,
> >  	    addr = internet_address_mailbox_get_addr (mailbox);
> >  
> >  	    if (address_is_users (addr, config)) {
> > -		if (ret == NULL)
> > -		    ret = addr;
> > -	    } else {
> > +		if (user_from && *user_from == NULL)
> > +		    *user_from = addr;
> > +	    } else if (message) {
> >  		g_mime_message_add_recipient (message, type, name, addr);
> > +		n++;
> >  	    }
> >  	}
> >      }
> >  
> > -    return ret;
> > +    return n;
> >  }
> >  
> > -/* For each address in 'recipients' that is not configured as one of
> > - * the user's addresses in 'config', add that address to 'message' as
> > - * an address of 'type'.
> > +/* Scan addresses in 'recipients'.
> >   *
> > - * The first address encountered that *is* the user's address will be
> > - * returned, (otherwise NULL is returned).
> > + * See the documentation of scan_address_list() above. This function does
> > + * exactly the same, but converts 'recipients' to an InternetAddressList first.
> 
> Just bikeshedding, but comments in the notmuch codebase almost
> universally wrap at 72 columns, not 80 (based on 
> egrep '[ /]\* .{70}' *.[ch]*)
> 
> >   */
> > -static const char *
> > -add_recipients_for_string (GMimeMessage *message,
> > -			   notmuch_config_t *config,
> > -			   GMimeRecipientType type,
> > -			   const char *recipients)
> > +static unsigned int
> > +scan_address_string (const char *recipients,
> > +		     notmuch_config_t *config,
> > +		     GMimeMessage *message,
> > +		     GMimeRecipientType type,
> > +		     const char **user_from)
> >  {
> >      InternetAddressList *list;
> >  
> >      if (recipients == NULL)
> > -	return NULL;
> > +	return 0;
> >  
> >      list = internet_address_list_parse_string (recipients);
> >      if (list == NULL)
> > -	return NULL;
> > +	return 0;
> >  
> > -    return add_recipients_for_address_list (message, config, type, list);
> > +    return scan_address_list (list, config, message, type, user_from);
> >  }
> >  
> >  /* Does the address in the Reply-To header of 'message' already appear
> > @@ -324,7 +329,7 @@ add_recipients_from_message (GMimeMessage *reply,
> >      }
> >  
> >      for (i = 0; i < ARRAY_SIZE (reply_to_map); i++) {
> > -	const char *addr, *recipients;
> > +	const char *recipients;
> >  
> >  	recipients = notmuch_message_get_header (message,
> >  						 reply_to_map[i].header);
> > @@ -332,11 +337,8 @@ add_recipients_from_message (GMimeMessage *reply,
> >  	    recipients = notmuch_message_get_header (message,
> >  						     reply_to_map[i].fallback);
> >  
> > -	addr = add_recipients_for_string (reply, config,
> > -					  reply_to_map[i].recipient_type,
> > -					  recipients);
> > -	if (from_addr == NULL)
> > -	    from_addr = addr;
> > +	scan_address_string (recipients, config, reply,
> > +			     reply_to_map[i].recipient_type, &from_addr);
> >      }
> >  
> >      return from_addr;

^ permalink raw reply	[flat|nested] 81+ messages in thread

* [PATCH v5 0/5] reply to sender
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (25 preceding siblings ...)
  2012-01-12 21:40 ` [PATCH v4 5/5] test: add tests for "notmuch reply" --reply-to=sender Jani Nikula
@ 2012-01-14 14:46 ` Jani Nikula
  2012-01-14 14:46 ` [PATCH v5 1/5] cli: slightly refactor "notmuch reply" address scanning functions Jani Nikula
                   ` (4 subsequent siblings)
  31 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-14 14:46 UTC (permalink / raw)
  To: notmuch

Hi all, hopefully the final round with only the comment and commit
message fixes to issues in patches 1 and 2 spotted by Austin and
Mark. Thanks again for a thorough review!

BR,
Jani.

Jani Nikula (4):
  cli: slightly refactor "notmuch reply" address scanning functions
  cli: add support for replying just to the sender in "notmuch reply"
  emacs: add support for replying just to the sender
  emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all

Mark Walters (1):
  test: add tests for "notmuch reply" --reply-to=sender

 emacs/notmuch-mua.el     |    9 ++-
 emacs/notmuch-show.el    |   12 ++-
 emacs/notmuch.el         |   11 ++-
 man/man1/notmuch-reply.1 |   28 +++++-
 notmuch-reply.c          |  129 ++++++++++++++++++----------
 test/notmuch-test        |    1 +
 test/reply-to-sender     |  209 ++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 340 insertions(+), 59 deletions(-)
 create mode 100755 test/reply-to-sender

-- 
1.7.5.4

^ permalink raw reply	[flat|nested] 81+ messages in thread

* [PATCH v5 1/5] cli: slightly refactor "notmuch reply" address scanning functions
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (26 preceding siblings ...)
  2012-01-14 14:46 ` [PATCH v5 0/5] reply to sender Jani Nikula
@ 2012-01-14 14:46 ` Jani Nikula
  2012-01-14 15:31   ` David Bremner
  2012-01-14 14:46 ` [PATCH v5 2/5] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
                   ` (3 subsequent siblings)
  31 siblings, 1 reply; 81+ messages in thread
From: Jani Nikula @ 2012-01-14 14:46 UTC (permalink / raw)
  To: notmuch

Slightly refactor "notmuch reply" recipient and user from address scanning
functions in preparation for reply-to-sender feature.

Add support for not adding recipients at all (just scan for user from
address), and returning the number of recipients added.

No externally visible functional changes.

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 notmuch-reply.c |   76 +++++++++++++++++++++++++++++--------------------------
 1 files changed, 40 insertions(+), 36 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index 000f6da..a8d6a94 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -168,22 +168,29 @@ address_is_users (const char *address, notmuch_config_t *config)
     return 0;
 }
 
-/* For each address in 'list' that is not configured as one of the
- * user's addresses in 'config', add that address to 'message' as an
- * address of 'type'.
+/* Scan addresses in 'list'.
  *
- * The first address encountered that *is* the user's address will be
- * returned, (otherwise NULL is returned).
+ * If 'message' is non-NULL, then for each address in 'list' that is
+ * not configured as one of the user's addresses in 'config', add that
+ * address to 'message' as an address of 'type'.
+ *
+ * If 'user_from' is non-NULL and *user_from is NULL, *user_from will
+ * be set to the first address encountered in 'list' that is the
+ * user's address.
+ *
+ * Return the number of addresses added to 'message'. (If 'message' is
+ * NULL, the function returns 0 by definition.)
  */
-static const char *
-add_recipients_for_address_list (GMimeMessage *message,
-				 notmuch_config_t *config,
-				 GMimeRecipientType type,
-				 InternetAddressList *list)
+static unsigned int
+scan_address_list (InternetAddressList *list,
+		   notmuch_config_t *config,
+		   GMimeMessage *message,
+		   GMimeRecipientType type,
+		   const char **user_from)
 {
     InternetAddress *address;
     int i;
-    const char *ret = NULL;
+    unsigned int n = 0;
 
     for (i = 0; i < internet_address_list_length (list); i++) {
 	address = internet_address_list_get_address (list, i);
@@ -196,8 +203,7 @@ add_recipients_for_address_list (GMimeMessage *message,
 	    if (group_list == NULL)
 		continue;
 
-	    add_recipients_for_address_list (message, config,
-					     type, group_list);
+	    n += scan_address_list (group_list, config, message, type, NULL);
 	} else {
 	    InternetAddressMailbox *mailbox;
 	    const char *name;
@@ -209,40 +215,41 @@ add_recipients_for_address_list (GMimeMessage *message,
 	    addr = internet_address_mailbox_get_addr (mailbox);
 
 	    if (address_is_users (addr, config)) {
-		if (ret == NULL)
-		    ret = addr;
-	    } else {
+		if (user_from && *user_from == NULL)
+		    *user_from = addr;
+	    } else if (message) {
 		g_mime_message_add_recipient (message, type, name, addr);
+		n++;
 	    }
 	}
     }
 
-    return ret;
+    return n;
 }
 
-/* For each address in 'recipients' that is not configured as one of
- * the user's addresses in 'config', add that address to 'message' as
- * an address of 'type'.
+/* Scan addresses in 'recipients'.
  *
- * The first address encountered that *is* the user's address will be
- * returned, (otherwise NULL is returned).
+ * See the documentation of scan_address_list() above. This function
+ * does exactly the same, but converts 'recipients' to an
+ * InternetAddressList first.
  */
-static const char *
-add_recipients_for_string (GMimeMessage *message,
-			   notmuch_config_t *config,
-			   GMimeRecipientType type,
-			   const char *recipients)
+static unsigned int
+scan_address_string (const char *recipients,
+		     notmuch_config_t *config,
+		     GMimeMessage *message,
+		     GMimeRecipientType type,
+		     const char **user_from)
 {
     InternetAddressList *list;
 
     if (recipients == NULL)
-	return NULL;
+	return 0;
 
     list = internet_address_list_parse_string (recipients);
     if (list == NULL)
-	return NULL;
+	return 0;
 
-    return add_recipients_for_address_list (message, config, type, list);
+    return scan_address_list (list, config, message, type, user_from);
 }
 
 /* Does the address in the Reply-To header of 'message' already appear
@@ -324,7 +331,7 @@ add_recipients_from_message (GMimeMessage *reply,
     }
 
     for (i = 0; i < ARRAY_SIZE (reply_to_map); i++) {
-	const char *addr, *recipients;
+	const char *recipients;
 
 	recipients = notmuch_message_get_header (message,
 						 reply_to_map[i].header);
@@ -332,11 +339,8 @@ add_recipients_from_message (GMimeMessage *reply,
 	    recipients = notmuch_message_get_header (message,
 						     reply_to_map[i].fallback);
 
-	addr = add_recipients_for_string (reply, config,
-					  reply_to_map[i].recipient_type,
-					  recipients);
-	if (from_addr == NULL)
-	    from_addr = addr;
+	scan_address_string (recipients, config, reply,
+			     reply_to_map[i].recipient_type, &from_addr);
     }
 
     return from_addr;
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v5 2/5] cli: add support for replying just to the sender in "notmuch reply"
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (27 preceding siblings ...)
  2012-01-14 14:46 ` [PATCH v5 1/5] cli: slightly refactor "notmuch reply" address scanning functions Jani Nikula
@ 2012-01-14 14:46 ` Jani Nikula
  2012-01-14 14:46 ` [PATCH v5 3/5] emacs: add support for replying just to the sender Jani Nikula
                   ` (2 subsequent siblings)
  31 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-14 14:46 UTC (permalink / raw)
  To: notmuch

Add new option --reply-to=(all|sender) to "notmuch reply" to select whether
to reply to all (sender and all recipients), or just sender. Reply to all
remains the default.

Credits to Mark Walters <markwalters1009@gmail.com> for his similar earlier
work where I picked up the basic idea of handling reply-to-sender in
add_recipients_from_message(). All bugs are mine, though.

Signed-off-by: Jani Nikula <jani@nikula.org>

---

Settled on --reply-to=(all|sender) per Carl's earlier suggestion
(id:87pqn5cg4g.fsf@yoom.home.cworth.org) and David's approval on IRC.
---
 man/man1/notmuch-reply.1 |   28 ++++++++++++++++++----
 notmuch-reply.c          |   57 ++++++++++++++++++++++++++++++++++++---------
 2 files changed, 68 insertions(+), 17 deletions(-)

diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1
index db464d8..5160ece 100644
--- a/man/man1/notmuch-reply.1
+++ b/man/man1/notmuch-reply.1
@@ -14,11 +14,13 @@ Constructs a reply template for a set of messages.
 To make replying to email easier,
 .B notmuch reply
 takes an existing set of messages and constructs a suitable mail
-template. The Reply-to header (if any, otherwise From:) is used for
-the To: address. Vales from the To: and Cc: headers are copied, but
-not including any of the current user's email addresses (as configured
-in primary_mail or other_email in the .notmuch\-config file) in the
-recipient list
+template. The Reply-to: header (if any, otherwise From:) is used for
+the To: address. Unless
+.BR \-\-reply-to=sender
+is specified, values from the To: and Cc: headers are copied, but not
+including any of the current user's email addresses (as configured in
+primary_mail or other_email in the .notmuch\-config file) in the
+recipient list.
 
 It also builds a suitable new subject, including Re: at the front (if
 not already present), and adding the message IDs of the messages being
@@ -45,6 +47,22 @@ Includes subject and quoted message body.
 Only produces In\-Reply\-To, References, To, Cc, and Bcc headers.
 .RE
 .RE
+.RS
+.TP 4
+.BR \-\-reply\-to= ( all | sender )
+.RS
+.TP 4
+.BR all " (default)"
+Replies to all addresses.
+.TP 4
+.BR sender
+Replies only to the sender. If replying to user's own message
+(Reply-to: or From: header is one of the user's configured email
+addresses), try To:, Cc:, and Bcc: headers in this order, and copy
+values from the first that contains something other than only the
+user's addresses.
+.RE
+.RE
 
 See \fBnotmuch-search-terms\fR(7)
 for details of the supported syntax for <search-terms>.
diff --git a/notmuch-reply.c b/notmuch-reply.c
index a8d6a94..da3acce 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -291,15 +291,23 @@ reply_to_header_is_redundant (notmuch_message_t *message)
     return 0;
 }
 
-/* Augments the recipients of reply from the headers of message.
+/* Augment the recipients of 'reply' from the "Reply-to:", "From:",
+ * "To:", "Cc:", and "Bcc:" headers of 'message'.
  *
- * If any of the user's addresses were found in these headers, the first
- * of these returned, otherwise NULL is returned.
+ * If 'reply_all' is true, use sender and all recipients, otherwise
+ * scan the headers for the first that contains something other than
+ * the user's addresses and add the recipients from this header
+ * (typically this would be reply-to-sender, but also handles reply to
+ * user's own message in a sensible way).
+ *
+ * If any of the user's addresses were found in these headers, the
+ * first of these returned, otherwise NULL is returned.
  */
 static const char *
 add_recipients_from_message (GMimeMessage *reply,
 			     notmuch_config_t *config,
-			     notmuch_message_t *message)
+			     notmuch_message_t *message,
+			     notmuch_bool_t reply_all)
 {
     struct {
 	const char *header;
@@ -313,6 +321,7 @@ add_recipients_from_message (GMimeMessage *reply,
     };
     const char *from_addr = NULL;
     unsigned int i;
+    unsigned int n = 0;
 
     /* Some mailing lists munge the Reply-To header despite it being A Bad
      * Thing, see http://www.unicom.com/pw/reply-to-harmful.html
@@ -339,8 +348,24 @@ add_recipients_from_message (GMimeMessage *reply,
 	    recipients = notmuch_message_get_header (message,
 						     reply_to_map[i].fallback);
 
-	scan_address_string (recipients, config, reply,
-			     reply_to_map[i].recipient_type, &from_addr);
+	n += scan_address_string (recipients, config, reply,
+				  reply_to_map[i].recipient_type, &from_addr);
+
+	if (!reply_all && n) {
+	    /* Stop adding new recipients in reply-to-sender mode if
+	     * we have added some recipient(s) above.
+	     *
+	     * This also handles the case of user replying to his own
+	     * message, where reply-to/from is not a recipient. In
+	     * this case there may be more than one recipient even if
+	     * not replying to all.
+	     */
+	    reply = NULL;
+
+	    /* From address and some recipients are enough, bail out. */
+	    if (from_addr)
+		break;
+	}
     }
 
     return from_addr;
@@ -484,7 +509,8 @@ static int
 notmuch_reply_format_default(void *ctx,
 			     notmuch_config_t *config,
 			     notmuch_query_t *query,
-			     notmuch_show_params_t *params)
+			     notmuch_show_params_t *params,
+			     notmuch_bool_t reply_all)
 {
     GMimeMessage *reply;
     notmuch_messages_t *messages;
@@ -513,7 +539,8 @@ notmuch_reply_format_default(void *ctx,
 	    g_mime_message_set_subject (reply, subject);
 	}
 
-	from_addr = add_recipients_from_message (reply, config, message);
+	from_addr = add_recipients_from_message (reply, config, message,
+						 reply_all);
 
 	if (from_addr == NULL)
 	    from_addr = guess_from_received_header (config, message);
@@ -562,7 +589,8 @@ static int
 notmuch_reply_format_headers_only(void *ctx,
 				  notmuch_config_t *config,
 				  notmuch_query_t *query,
-				  unused (notmuch_show_params_t *params))
+				  unused (notmuch_show_params_t *params),
+				  notmuch_bool_t reply_all)
 {
     GMimeMessage *reply;
     notmuch_messages_t *messages;
@@ -602,7 +630,7 @@ notmuch_reply_format_headers_only(void *ctx,
 	g_mime_object_set_header (GMIME_OBJECT (reply),
 				  "References", references);
 
-	(void)add_recipients_from_message (reply, config, message);
+	(void)add_recipients_from_message (reply, config, message, reply_all);
 
 	reply_headers = g_mime_object_to_string (GMIME_OBJECT (reply));
 	printf ("%s", reply_headers);
@@ -629,9 +657,10 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
     notmuch_query_t *query;
     char *query_string;
     int opt_index, ret = 0;
-    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params);
+    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params, notmuch_bool_t reply_all);
     notmuch_show_params_t params = { .part = -1 };
     int format = FORMAT_DEFAULT;
+    int reply_all = TRUE;
     notmuch_bool_t decrypt = FALSE;
 
     notmuch_opt_desc_t options[] = {
@@ -639,6 +668,10 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 	  (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT },
 				  { "headers-only", FORMAT_HEADERS_ONLY },
 				  { 0, 0 } } },
+	{ NOTMUCH_OPT_KEYWORD, &reply_all, "reply-to", 'r',
+	  (notmuch_keyword_t []){ { "all", TRUE },
+				  { "sender", FALSE },
+				  { 0, 0 } } },
 	{ NOTMUCH_OPT_BOOLEAN, &decrypt, "decrypt", 'd', 0 },
 	{ 0, 0, 0, 0, 0 }
     };
@@ -692,7 +725,7 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 	return 1;
     }
 
-    if (reply_format_func (ctx, config, query, &params) != 0)
+    if (reply_format_func (ctx, config, query, &params, reply_all) != 0)
 	return 1;
 
     notmuch_query_destroy (query);
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v5 3/5] emacs: add support for replying just to the sender
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (28 preceding siblings ...)
  2012-01-14 14:46 ` [PATCH v5 2/5] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
@ 2012-01-14 14:46 ` Jani Nikula
  2012-01-14 14:46 ` [PATCH v5 4/5] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all Jani Nikula
  2012-01-14 14:46 ` [PATCH v5 5/5] test: add tests for "notmuch reply" --reply-to=sender Jani Nikula
  31 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-14 14:46 UTC (permalink / raw)
  To: notmuch

Provide reply to sender counterparts to the search and show reply
functions. Add key binding 'R' to reply to sender, while keeping 'r' as
reply to all, both in search and show views.

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 emacs/notmuch-mua.el  |    9 ++++++---
 emacs/notmuch-show.el |   10 ++++++++--
 emacs/notmuch.el      |    9 ++++++++-
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 32e2e30..d8ab822 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -71,12 +71,15 @@ list."
 	    (push header message-hidden-headers)))
 	notmuch-mua-hidden-headers))
 
-(defun notmuch-mua-reply (query-string &optional sender)
+(defun notmuch-mua-reply (query-string &optional sender reply-all)
   (let (headers
 	body
 	(args '("reply")))
     (if notmuch-show-process-crypto
 	(setq args (append args '("--decrypt"))))
+    (if reply-all
+	(setq args (append args '("--reply-to=all")))
+      (setq args (append args '("--reply-to=sender"))))
     (setq args (append args (list query-string)))
     ;; This make assumptions about the output of `notmuch reply', but
     ;; really only that the headers come first followed by a blank
@@ -218,13 +221,13 @@ the From: address first."
 	(notmuch-mua-forward-message))
     (notmuch-mua-forward-message)))
 
-(defun notmuch-mua-new-reply (query-string &optional prompt-for-sender)
+(defun notmuch-mua-new-reply (query-string &optional prompt-for-sender reply-all)
   "Invoke the notmuch reply window."
   (interactive "P")
   (let ((sender
 	 (when prompt-for-sender
 	   (notmuch-mua-prompt-for-sender))))
-    (notmuch-mua-reply query-string sender)))
+    (notmuch-mua-reply query-string sender reply-all)))
 
 (defun notmuch-mua-send-and-exit (&optional arg)
   (interactive "P")
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 034db87..9031b82 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -934,6 +934,7 @@ thread id.  If a prefix is given, crypto processing is toggled."
 	(define-key map "m" 'notmuch-mua-new-mail)
 	(define-key map "f" 'notmuch-show-forward-message)
 	(define-key map "r" 'notmuch-show-reply)
+	(define-key map "R" 'notmuch-show-reply-sender)
 	(define-key map "|" 'notmuch-show-pipe-message)
 	(define-key map "w" 'notmuch-show-save-attachments)
 	(define-key map "V" 'notmuch-show-view-raw-message)
@@ -1238,9 +1239,14 @@ any effects from previous calls to
       (notmuch-show-previous-message)))))
 
 (defun notmuch-show-reply (&optional prompt-for-sender)
-  "Reply to the current message."
+  "Reply to the sender and all recipients of the current message."
   (interactive "P")
-  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender))
+  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender t))
+
+(defun notmuch-show-reply-sender (&optional prompt-for-sender)
+  "Reply to the sender of the current message."
+  (interactive "P")
+  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender nil))
 
 (defun notmuch-show-forward-message (&optional prompt-for-sender)
   "Forward the current message."
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 1e61775..9ac2888 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -214,6 +214,7 @@ For a mouse binding, return nil."
     (define-key map "p" 'notmuch-search-previous-thread)
     (define-key map "n" 'notmuch-search-next-thread)
     (define-key map "r" 'notmuch-search-reply-to-thread)
+    (define-key map "R" 'notmuch-search-reply-to-thread-sender)
     (define-key map "m" 'notmuch-mua-new-mail)
     (define-key map "s" 'notmuch-search)
     (define-key map "o" 'notmuch-search-toggle-order)
@@ -448,10 +449,16 @@ Complete list of currently available key bindings:
       (message "End of search results."))))
 
 (defun notmuch-search-reply-to-thread (&optional prompt-for-sender)
+  "Begin composing a reply-all to the entire current thread in a new buffer."
+  (interactive "P")
+  (let ((message-id (notmuch-search-find-thread-id)))
+    (notmuch-mua-new-reply message-id prompt-for-sender t)))
+
+(defun notmuch-search-reply-to-thread-sender (&optional prompt-for-sender)
   "Begin composing a reply to the entire current thread in a new buffer."
   (interactive "P")
   (let ((message-id (notmuch-search-find-thread-id)))
-    (notmuch-mua-new-reply message-id prompt-for-sender)))
+    (notmuch-mua-new-reply message-id prompt-for-sender nil)))
 
 (defun notmuch-call-notmuch-process (&rest args)
   "Synchronously invoke \"notmuch\" with the given list of arguments.
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v5 4/5] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (29 preceding siblings ...)
  2012-01-14 14:46 ` [PATCH v5 3/5] emacs: add support for replying just to the sender Jani Nikula
@ 2012-01-14 14:46 ` Jani Nikula
  2012-01-14 14:46 ` [PATCH v5 5/5] test: add tests for "notmuch reply" --reply-to=sender Jani Nikula
  31 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-14 14:46 UTC (permalink / raw)
  To: notmuch

Change the default reply key bindings, making 'r' reply-to-sender and 'R'
reply-to-all.

Signed-off-by: Jani Nikula <jani@nikula.org>

---

There were mixed feelings about this. This as a separate patch so it's easy
to drop if needed.
---
 emacs/notmuch-show.el |    4 ++--
 emacs/notmuch.el      |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 9031b82..03c1f6b 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -933,8 +933,8 @@ thread id.  If a prefix is given, crypto processing is toggled."
 	(define-key map "s" 'notmuch-search)
 	(define-key map "m" 'notmuch-mua-new-mail)
 	(define-key map "f" 'notmuch-show-forward-message)
-	(define-key map "r" 'notmuch-show-reply)
-	(define-key map "R" 'notmuch-show-reply-sender)
+	(define-key map "r" 'notmuch-show-reply-sender)
+	(define-key map "R" 'notmuch-show-reply)
 	(define-key map "|" 'notmuch-show-pipe-message)
 	(define-key map "w" 'notmuch-show-save-attachments)
 	(define-key map "V" 'notmuch-show-view-raw-message)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 9ac2888..d952c41 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -213,8 +213,8 @@ For a mouse binding, return nil."
     (define-key map ">" 'notmuch-search-last-thread)
     (define-key map "p" 'notmuch-search-previous-thread)
     (define-key map "n" 'notmuch-search-next-thread)
-    (define-key map "r" 'notmuch-search-reply-to-thread)
-    (define-key map "R" 'notmuch-search-reply-to-thread-sender)
+    (define-key map "r" 'notmuch-search-reply-to-thread-sender)
+    (define-key map "R" 'notmuch-search-reply-to-thread)
     (define-key map "m" 'notmuch-mua-new-mail)
     (define-key map "s" 'notmuch-search)
     (define-key map "o" 'notmuch-search-toggle-order)
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v5 5/5] test: add tests for "notmuch reply" --reply-to=sender
  2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
                   ` (30 preceding siblings ...)
  2012-01-14 14:46 ` [PATCH v5 4/5] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all Jani Nikula
@ 2012-01-14 14:46 ` Jani Nikula
  31 siblings, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-14 14:46 UTC (permalink / raw)
  To: notmuch

From: Mark Walters <markwalters1009@gmail.com>

---
 test/notmuch-test    |    1 +
 test/reply-to-sender |  209 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 210 insertions(+), 0 deletions(-)
 create mode 100755 test/reply-to-sender

diff --git a/test/notmuch-test b/test/notmuch-test
index e40ef86..6a99ae3 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -33,6 +33,7 @@ TESTS="
   thread-naming
   raw
   reply
+  reply-to-sender
   dump-restore
   uuencode
   thread-order
diff --git a/test/reply-to-sender b/test/reply-to-sender
new file mode 100755
index 0000000..c7d15bb
--- /dev/null
+++ b/test/reply-to-sender
@@ -0,0 +1,209 @@
+#!/usr/bin/env bash
+test_description="\"notmuch reply --reply-to=sender\" in several variations"
+. ./test-lib.sh
+
+test_begin_subtest "Basic reply-to-sender"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="basic reply-to-sender test"'
+
+output=$(notmuch reply --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> basic reply-to-sender test"
+
+test_begin_subtest "From Us, Basic reply to message"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[to]="Recipient <recipient@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="basic reply-to-from-us test"'
+
+output=$(notmuch reply --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Recipient <recipient@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> basic reply-to-from-us test"
+
+test_begin_subtest "Multiple recipients"
+add_message '[from]="Sender <sender@example.com>"' \
+            '[to]="test_suite@notmuchmail.org, Someone Else <someone@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="Multiple recipients"'
+
+output=$(notmuch reply  --reply-to=sender  id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> Multiple recipients"
+
+test_begin_subtest "From Us, Multiple TO recipients"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[to]="Recipient <recipient@example.com>, Someone Else <someone@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="From Us, Multiple TO recipients"'
+
+output=$(notmuch reply  --reply-to=sender  id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Recipient <recipient@example.com>, Someone Else <someone@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> From Us, Multiple TO recipients"
+
+test_begin_subtest "Reply with CC"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+            '[cc]="Other Parties <cc@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> reply with CC"
+
+test_begin_subtest "From Us, Reply with CC"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[to]="Recipient <recipient@example.com>"' \
+            '[cc]="Other Parties <cc@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Recipient <recipient@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> reply with CC"
+
+test_begin_subtest "From Us, Reply no TO but with CC"
+add_message '[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"' \
+            '[cc]="Other Parties <cc@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+Cc: Other Parties <cc@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> reply with CC"
+
+test_begin_subtest "Reply from alternate address"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite_other@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="reply from alternate address"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite_other@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> reply from alternate address"
+
+test_begin_subtest "Support for Reply-To"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="support for reply-to"' \
+            '[reply-to]="Sender <elsewhere@example.com>"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <elsewhere@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> support for reply-to"
+
+test_begin_subtest "Support for Reply-To with multiple recipients"
+add_message '[from]="Sender <sender@example.com>"' \
+            '[to]="test_suite@notmuchmail.org, Someone Else <someone@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="support for reply-to with multiple recipients"' \
+            '[reply-to]="Sender <elsewhere@example.com>"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <elsewhere@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> support for reply-to with multiple recipients"
+
+test_begin_subtest "Un-munging Reply-To"
+add_message '[from]="Sender <sender@example.com>"' \
+            '[to]="Some List <list@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="Un-munging Reply-To"' \
+            '[reply-to]="Evil Munging List <list@example.com>"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> Un-munging Reply-To"
+
+test_begin_subtest "Message with header of exactly 200 bytes"
+add_message '[subject]="This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces"' \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+            '[body]="200-byte header"'
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> 200-byte header"
+test_done
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 81+ messages in thread

* Re: [PATCH v5 1/5] cli: slightly refactor "notmuch reply" address scanning functions
  2012-01-14 14:46 ` [PATCH v5 1/5] cli: slightly refactor "notmuch reply" address scanning functions Jani Nikula
@ 2012-01-14 15:31   ` David Bremner
  2012-01-14 16:48     ` Jani Nikula
  2012-01-16 18:06     ` Dmitry Kurochkin
  0 siblings, 2 replies; 81+ messages in thread
From: David Bremner @ 2012-01-14 15:31 UTC (permalink / raw)
  To: Jani Nikula, notmuch

On Sat, 14 Jan 2012 16:46:15 +0200, Jani Nikula <jani@nikula.org> wrote:
> Slightly refactor "notmuch reply" recipient and user from address scanning
> functions in preparation for reply-to-sender feature.
> 

Pushed, bindings change and all.

This series definitely needs a NEWS item. 

Perhaps some kind soul could add a wiki entry explaining to people how
to swap the bindings, just in case there people who don't like the
"one-true-reply-bindings" (cough).

d

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v5 1/5] cli: slightly refactor "notmuch reply" address scanning functions
  2012-01-14 15:31   ` David Bremner
@ 2012-01-14 16:48     ` Jani Nikula
  2012-01-16 18:06     ` Dmitry Kurochkin
  1 sibling, 0 replies; 81+ messages in thread
From: Jani Nikula @ 2012-01-14 16:48 UTC (permalink / raw)
  To: David Bremner, notmuch


For those not on IRC:

On Sat, 14 Jan 2012 11:31:16 -0400, David Bremner <david@tethera.net> wrote:
> This series definitely needs a NEWS item. 

id:"1326559168-29178-1-git-send-email-jani@nikula.org"

> Perhaps some kind soul could add a wiki entry explaining to people how
> to swap the bindings, just in case there people who don't like the
> "one-true-reply-bindings" (cough).

http://notmuchmail.org/emacstips/#index7h2


BR,
Jani.

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v5 1/5] cli: slightly refactor "notmuch reply" address scanning functions
  2012-01-14 15:31   ` David Bremner
  2012-01-14 16:48     ` Jani Nikula
@ 2012-01-16 18:06     ` Dmitry Kurochkin
  2012-01-16 18:40       ` David Edmondson
                         ` (2 more replies)
  1 sibling, 3 replies; 81+ messages in thread
From: Dmitry Kurochkin @ 2012-01-16 18:06 UTC (permalink / raw)
  To: David Bremner, Jani Nikula, notmuch

Hello.

Since this patches got in, I have yet to send a single email to the
address(es) I intend to :( I am really used to the bindings and this
change is a pain.  From IRC discussion, it seems like I am not alone
here.

There was a proposal to change reply bindings to 'ra' and 'rs'.  When
'r' is pressed an appropriate help message can be given in the
minibuffer.  I like this proposal.  What do others think?

If others like it, how about reverting to the old bindings until the new
ones are implemented?

Regards,
  Dmitry

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v5 1/5] cli: slightly refactor "notmuch reply" address scanning functions
  2012-01-16 18:06     ` Dmitry Kurochkin
@ 2012-01-16 18:40       ` David Edmondson
  2012-01-16 19:26       ` David Bremner
  2012-01-16 19:32       ` Jameson Graef Rollins
  2 siblings, 0 replies; 81+ messages in thread
From: David Edmondson @ 2012-01-16 18:40 UTC (permalink / raw)
  To: Dmitry Kurochkin, David Bremner, Jani Nikula, notmuch

[-- Attachment #1: Type: text/plain, Size: 781 bytes --]

On Mon, 16 Jan 2012 22:06:15 +0400, Dmitry Kurochkin <dmitry.kurochkin@gmail.com> wrote:
> Hello.
> 
> Since this patches got in, I have yet to send a single email to the
> address(es) I intend to :( I am really used to the bindings and this
> change is a pain.  From IRC discussion, it seems like I am not alone
> here.
> 
> There was a proposal to change reply bindings to 'ra' and 'rs'.  When
> 'r' is pressed an appropriate help message can be given in the
> minibuffer.  I like this proposal.  What do others think?
> 
> If others like it, how about reverting to the old bindings until the new
> ones are implemented?

I'm inclined to push on for a while and see if it sticks. Previous
experience with this kind of change suggests that it takes a week or so.

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v5 1/5] cli: slightly refactor "notmuch reply" address scanning functions
  2012-01-16 18:06     ` Dmitry Kurochkin
  2012-01-16 18:40       ` David Edmondson
@ 2012-01-16 19:26       ` David Bremner
  2012-01-16 19:32       ` Jameson Graef Rollins
  2 siblings, 0 replies; 81+ messages in thread
From: David Bremner @ 2012-01-16 19:26 UTC (permalink / raw)
  To: Dmitry Kurochkin, Jani Nikula, notmuch

On Mon, 16 Jan 2012 22:06:15 +0400, Dmitry Kurochkin <dmitry.kurochkin@gmail.com> wrote:
> 
> If others like it, how about reverting to the old bindings until the new
> ones are implemented?
> 

Flip-flopping the bindings will just cause more confusion, in my opinion.

It is easy (and documented in the wiki) to customize the bindings
in your .emacs. 

So as a temporary measure, the latter seems simplest.

d

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v5 1/5] cli: slightly refactor "notmuch reply" address scanning functions
  2012-01-16 18:06     ` Dmitry Kurochkin
  2012-01-16 18:40       ` David Edmondson
  2012-01-16 19:26       ` David Bremner
@ 2012-01-16 19:32       ` Jameson Graef Rollins
  2 siblings, 0 replies; 81+ messages in thread
From: Jameson Graef Rollins @ 2012-01-16 19:32 UTC (permalink / raw)
  To: Dmitry Kurochkin, David Bremner, Jani Nikula, notmuch

[-- Attachment #1: Type: text/plain, Size: 831 bytes --]

On Mon, 16 Jan 2012 22:06:15 +0400, Dmitry Kurochkin <dmitry.kurochkin@gmail.com> wrote:
> Since this patches got in, I have yet to send a single email to the
> address(es) I intend to :( I am really used to the bindings and this
> change is a pain.  From IRC discussion, it seems like I am not alone
> here.

Yeah, this has bit me too much recently.

> There was a proposal to change reply bindings to 'ra' and 'rs'.  When
> 'r' is pressed an appropriate help message can be given in the
> minibuffer.  I like this proposal.  What do others think?

My first reaction to this proposal was "yuck".  Then I realized it might
just provide that extra split second to think about where you actually
want the reply to go, which might be a good thing.

Otherwise I could live with any option.  I can get used to the new
bindings.

jamie.

[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]

^ permalink raw reply	[flat|nested] 81+ messages in thread

end of thread, other threads:[~2012-01-16 19:32 UTC | newest]

Thread overview: 81+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-05 20:25 [PATCH 0/4] notmuch reply bugfix & reply to sender only Jani Nikula
2012-01-05 20:25 ` [PATCH 1/4] cli: fix use of uninitialized variable in "notmuch reply" Jani Nikula
2012-01-06  3:22   ` David Bremner
2012-01-06  8:11     ` Jani Nikula
2012-01-06 11:57       ` David Bremner
2012-01-07  3:52   ` David Bremner
2012-01-07  7:31     ` Jani Nikula
2012-01-07 11:57       ` Mark Walters
2012-01-07 12:14       ` David Bremner
2012-01-05 20:25 ` [PATCH 2/4] cli: convert "notmuch reply" to use the new argument parser Jani Nikula
2012-01-05 20:25 ` [PATCH 3/4] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
2012-01-05 20:25 ` [PATCH 4/4] emacs: add support for replying just to the sender of messages and threads Jani Nikula
2012-01-05 20:33 ` [PATCH 0/4] notmuch reply bugfix & reply to sender only Jameson Graef Rollins
2012-01-07 19:25   ` Mueen Nawaz
2012-01-05 22:01 ` Mark Walters
2012-01-06 12:34   ` Jani Nikula
2012-01-06 13:32     ` Mark Walters
2012-01-06 13:34       ` [PATCH 1/4] Add the option "--reply-to" to notmuch reply Mark Walters
2012-01-08 12:47         ` Jani Nikula
2012-01-08 15:08           ` Mark Walters
2012-01-08 16:11             ` Jani Nikula
2012-01-06 13:34       ` [PATCH 2/4] Update the man page for notmuch-reply to give the syntax for the --reply-to option Mark Walters
2012-01-06 13:34       ` [PATCH 3/4] Emacs changes for reply-to-sender Mark Walters
2012-01-06 13:34       ` [PATCH 4/4] add tests " Mark Walters
2012-01-06 14:20     ` [PATCH 0/4] notmuch reply bugfix & reply to sender only Mark Walters
2012-01-06  0:01 ` Adam Wolfe Gordon
2012-01-06 22:11   ` Tomi Ollila
2012-01-06  8:54 ` David Edmondson
2012-01-08 21:48 ` [PATCH v2 0/6] reply to sender Jani Nikula
2012-01-09  8:22   ` David Edmondson
2012-01-09 18:55   ` Dmitry Kurochkin
2012-01-08 21:48 ` [PATCH v2 1/6] cli: fix use of uninitialized variable in "notmuch reply" Jani Nikula
2012-01-08 21:48 ` [PATCH v2 2/6] cli: convert "notmuch reply" to use the new argument parser Jani Nikula
2012-01-08 21:48 ` [PATCH v2 3/6] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
2012-01-08 23:23   ` Mark Walters
2012-01-09  9:41     ` Jani Nikula
2012-01-09 11:13       ` Mark Walters
2012-01-08 21:48 ` [PATCH v2 4/6] emacs: add support for replying just to the sender Jani Nikula
2012-01-08 21:48 ` [PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all Jani Nikula
2012-01-08 22:01   ` Jeremy Nickurak
2012-01-08 23:32     ` Jameson Graef Rollins
2012-01-08 23:56       ` Jeremy Nickurak
2012-01-09 14:10     ` is there a default reply function? (was: Re: [PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all) Gregor Zattler
2012-01-08 21:48 ` [PATCH v2 6/6] test: add tests for "notmuch reply" --reply-to=sender Jani Nikula
2012-01-10 19:54 ` [PATCH v3 0/4] reply to sender Jani Nikula
2012-01-10 19:54 ` [PATCH v3 1/4] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
2012-01-12  3:31   ` Austin Clements
2012-01-10 19:54 ` [PATCH v3 2/4] emacs: add support for replying just to the sender Jani Nikula
2012-01-11  8:20   ` David Edmondson
2012-01-11  8:45     ` Jani Nikula
2012-01-11  9:08       ` David Edmondson
2012-01-11 21:15     ` Aaron Ecay
2012-01-11 22:08       ` Jani Nikula
2012-01-10 19:54 ` [PATCH v3 3/4] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all Jani Nikula
2012-01-11  8:21   ` David Edmondson
2012-01-10 19:54 ` [PATCH v3 4/4] test: add tests for "notmuch reply" --reply-to=sender Jani Nikula
2012-01-12  3:50   ` Austin Clements
2012-01-12 12:59     ` Tomi Ollila
2012-01-12 21:40 ` [PATCH v4 0/5] reply to sender Jani Nikula
2012-01-12 21:40 ` [PATCH v4 1/5] cli: slightly refactor "notmuch reply" address scanning functions Jani Nikula
2012-01-12 21:59   ` Austin Clements
2012-01-14 14:22     ` Jani Nikula
2012-01-12 23:28   ` Mark Walters
2012-01-12 21:40 ` [PATCH v4 2/5] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
2012-01-12 22:02   ` Austin Clements
2012-01-12 23:46   ` Mark Walters
2012-01-12 21:40 ` [PATCH v4 3/5] emacs: add support for replying just to the sender Jani Nikula
2012-01-12 21:40 ` [PATCH v4 4/5] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all Jani Nikula
2012-01-12 21:40 ` [PATCH v4 5/5] test: add tests for "notmuch reply" --reply-to=sender Jani Nikula
2012-01-14 14:46 ` [PATCH v5 0/5] reply to sender Jani Nikula
2012-01-14 14:46 ` [PATCH v5 1/5] cli: slightly refactor "notmuch reply" address scanning functions Jani Nikula
2012-01-14 15:31   ` David Bremner
2012-01-14 16:48     ` Jani Nikula
2012-01-16 18:06     ` Dmitry Kurochkin
2012-01-16 18:40       ` David Edmondson
2012-01-16 19:26       ` David Bremner
2012-01-16 19:32       ` Jameson Graef Rollins
2012-01-14 14:46 ` [PATCH v5 2/5] cli: add support for replying just to the sender in "notmuch reply" Jani Nikula
2012-01-14 14:46 ` [PATCH v5 3/5] emacs: add support for replying just to the sender Jani Nikula
2012-01-14 14:46 ` [PATCH v5 4/5] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all Jani Nikula
2012-01-14 14:46 ` [PATCH v5 5/5] test: add tests for "notmuch reply" --reply-to=sender Jani Nikula

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).