[PATCH v2 0/2] cli: Allow true/false parameter for boolean

2012-03-13 Thread Austin Clements
Quoth Mark Walters on Mar 10 at 11:05 am:
> Hi
> 
> Here is a second version of a patch to allow parameters to boolean
> options on the command line. This version allows parameters
> (=true|false). My first version is at
> id:"1331244944-7960-1-git-send-email-markwalters1009 at gmail.com". Jani
> posted an alternative version there. Jani's version and this one are
> quite similar: the key difference is that this version abuses a
> notmuch_bool_t by setting it to -1 (to indicate that the parser has
> not set this option). This makes the code simpler but is definitely an
> abuse. I will discuss this further in replies to Jani's series.
> 
> Best wishes
> 
> Mark
> 
> Mark Walters (2):
>   cli: Parsing. Allow true/false parameter for boolean options.
>   cli: make --entire-thread=false work for format=json.

LGTM.  The one question I have is whether or not the resulting
non-entire-thread behavior of the JSON format is actually what we
*want*.  As a probably unintentional consequence of the current show
code, we get

# A message and its replies (show_messages)
thread_node = [
message?, # present if --entire-thread or matched
[thread_node*]# children of message
]

But would it be better to have

thread_node = [
message|null, # non-null if --entire-thread or matched
[thread_node*]# children of message
]

?  The latter is much more natural for consumers to work with
(checking whether the message matched or not is more natural and the
index of the child list doesn't change), but would require a little
more code in show to support.


[PATCH 2/2] lib: Add exclude query debug output

2012-03-13 Thread Austin Clements
---
 lib/query.cc |   10 --
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/lib/query.cc b/lib/query.cc
index 1e5e99a..53d505a 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -261,9 +261,12 @@ notmuch_query_search_messages (notmuch_query_t *query)
break;
}

-   if (_debug_query ())
+   if (_debug_query ()) {
+   fprintf (stderr, "Exclude query is:\n%s\n",
+exclude_query.get_description ().c_str ());
fprintf (stderr, "Final query is:\n%s\n",
 final_query.get_description ().c_str ());
+   }

enquire.set_query (final_query);

@@ -537,9 +540,12 @@ notmuch_query_count_messages (notmuch_query_t *query)
enquire.set_weighting_scheme(Xapian::BoolWeight());
enquire.set_docid_order(Xapian::Enquire::ASCENDING);

-   if (_debug_query ())
+   if (_debug_query ()) {
+   fprintf (stderr, "Exclude query is:\n%s\n",
+exclude_query.get_description ().c_str ());
fprintf (stderr, "Final query is:\n%s\n",
 final_query.get_description ().c_str ());
+   }

enquire.set_query (final_query);

-- 
1.7.7.3



[PATCH 1/2] lib: Expose query debug output via an environment variable

2012-03-13 Thread Austin Clements
Allow query debugging to be enabled at run-time by setting the
NOTMUCH_DEBUG_QUERY environment variable to a non-empty string.

Previously, enabling query debugging required recompiling, but parsed
queries are often useful for tracking down bugs in situations where
recompiling is inconvenient.
---
 lib/query.cc |   24 +++-
 1 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/lib/query.cc b/lib/query.cc
index ab18fbc..1e5e99a 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -64,15 +64,21 @@ _notmuch_doc_id_set_init (void *ctx,
  notmuch_doc_id_set_t *doc_ids,
  GArray *arr);

+static notmuch_bool_t
+_debug_query (void)
+{
+char *env = getenv ("NOTMUCH_DEBUG_QUERY");
+return (env && strcmp (env, "") != 0);
+}
+
 notmuch_query_t *
 notmuch_query_create (notmuch_database_t *notmuch,
  const char *query_string)
 {
 notmuch_query_t *query;

-#ifdef DEBUG_QUERY
-fprintf (stderr, "Query string is:\n%s\n", query_string);
-#endif
+if (_debug_query ())
+   fprintf (stderr, "Query string is:\n%s\n", query_string);

 query = talloc (NULL, notmuch_query_t);
 if (unlikely (query == NULL))
@@ -255,9 +261,9 @@ notmuch_query_search_messages (notmuch_query_t *query)
break;
}

-#if DEBUG_QUERY
-   fprintf (stderr, "Final query is:\n%s\n", 
final_query.get_description().c_str());
-#endif
+   if (_debug_query ())
+   fprintf (stderr, "Final query is:\n%s\n",
+final_query.get_description ().c_str ());

enquire.set_query (final_query);

@@ -531,9 +537,9 @@ notmuch_query_count_messages (notmuch_query_t *query)
enquire.set_weighting_scheme(Xapian::BoolWeight());
enquire.set_docid_order(Xapian::Enquire::ASCENDING);

-#if DEBUG_QUERY
-   fprintf (stderr, "Final query is:\n%s\n", 
final_query.get_description().c_str());
-#endif
+   if (_debug_query ())
+   fprintf (stderr, "Final query is:\n%s\n",
+final_query.get_description ().c_str ());

enquire.set_query (final_query);

-- 
1.7.7.3



[PATCH 0/2] Query debug improvements

2012-03-13 Thread Austin Clements
Two simple improvements for query debugging.



[PATCH v7.1 11/11] NEWS: news for reply enhancements

2012-03-13 Thread Adam Wolfe Gordon
---
 NEWS |   20 
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/NEWS b/NEWS
index a739914..46fb191 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,18 @@ Reply to sender
   to all. The feature is available through the new command line option
   --reply-to=(all|sender).

+JSON reply format
+
+  "notmuch reply" can now produce JSON output that contains the headers
+  for a reply message and full information about the original message
+  begin replied to. This allows MUAs to create replies intelligtently.
+  For example, an MUA that can parse HTML might quote HTML parts.
+
+  Calling notmuch reply with --format=json imposes the restriction that
+  only a single message is returned by the search, as replying to
+  multiple messages does not have a well-defined behavior. The default
+  retains its current behavior for multiple message replies.
+
 Tag exclusion

   Tags can be automatically excluded from search results by adding them
@@ -48,6 +60,14 @@ Reply to sender
   and search modes, 'r' has been bound to reply to sender, replacing
   reply to all, which now has key binding 'R'.

+Reply improvement using the JSON format
+
+  Emacs now uses the JSON reply format to create replies. It obeys
+  the customization variables message-citation-line-format and
+  message-citation-line-function when creating the first line of the
+  reply body, and it will quote HTML parts if no text/plain parts are
+  available.
+
 More flexible and consistent tagging operations

   All tagging operations ("+", "-", "*") now accept multiple tags with
-- 
1.7.5.4



[PATCH v7.1 10/11] emacs: Use the new JSON reply format and message-cite-original

2012-03-13 Thread Adam Wolfe Gordon
Use the new JSON reply format to create replies in emacs. Quote HTML
parts nicely by using mm-display-part to turn them into displayable
text, then quoting them with message-cite-original. This is very
useful for users who regularly receive HTML-only email.

Use message-mode's message-cite-original function to create the
quoted body for reply messages. In order to make this act like the
existing notmuch defaults, you will need to set the following in
your emacs configuration:

message-citation-line-format "On %a, %d %b %Y, %f wrote:"
message-citation-line-function 'message-insert-formatted-citation-line

The tests have been updated to reflect the (ugly) emacs default.
---
 emacs/notmuch-lib.el  |   30 
 emacs/notmuch-mua.el  |  124 +
 emacs/notmuch-show.el |   31 ++--
 test/emacs|8 ++--
 4 files changed, 123 insertions(+), 70 deletions(-)

diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 7e3f110..c146748 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -206,6 +206,36 @@ the user hasn't set this variable with the old or new 
value."
  (setq seq (nconc (delete elem seq) (list elem))
 seq))

+(defun notmuch-parts-filter-by-type (parts type)
+  "Given a list of message parts, return a list containing the ones matching
+the given type."
+  (remove-if-not
+   (lambda (part) (notmuch-match-content-type (plist-get part :content-type) 
type))
+   parts))
+
+;; Helper for parts which are generally not included in the default
+;; JSON output.
+(defun notmuch-get-bodypart-internal (message-id part-number process-crypto)
+  (let ((args '("show" "--format=raw"))
+   (part-arg (format "--part=%s" part-number)))
+(setq args (append args (list part-arg)))
+(if process-crypto
+   (setq args (append args '("--decrypt"
+(setq args (append args (list message-id)))
+(with-temp-buffer
+  (let ((coding-system-for-read 'no-conversion))
+   (progn
+ (apply 'call-process (append (list notmuch-command nil (list t nil) 
nil) args))
+ (buffer-string))
+
+(defun notmuch-get-bodypart-content (msg part nth process-crypto)
+  (or (plist-get part :content)
+  (notmuch-get-bodypart-internal (concat "id:" (plist-get msg :id)) nth 
process-crypto)))
+
+(defun notmuch-plist-to-alist (plist)
+  (loop for (key value . rest) on plist by #'cddr
+   collect (cons (substring (symbol-name key) 1) value)))
+
 ;; Compatibility functions for versions of emacs before emacs 23.
 ;;
 ;; Both functions here were copied from emacs 23 with the following copyright:
diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 13244eb..6aae3a0 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -19,11 +19,15 @@
 ;;
 ;; Authors: David Edmondson 

+(require 'json)
 (require 'message)
+(require 'format-spec)

 (require 'notmuch-lib)
 (require 'notmuch-address)

+(eval-when-compile (require 'cl))
+
 ;;

 (defcustom notmuch-mua-send-hook '(notmuch-mua-message-send-hook)
@@ -72,54 +76,92 @@ list."
(push header message-hidden-headers)))
notmuch-mua-hidden-headers))

+(defun notmuch-mua-get-quotable-parts (parts)
+  (loop for part in parts
+   if (notmuch-match-content-type (plist-get part :content-type) 
"multipart/alternative")
+ collect (let* ((subparts (plist-get part :content))
+   (types (mapcar (lambda (part) (plist-get part 
:content-type)) subparts))
+   (chosen-type (car (notmuch-multipart/alternative-choose 
types
+  (loop for part in (reverse subparts)
+if (notmuch-match-content-type (plist-get part 
:content-type) chosen-type)
+return part))
+   else if (notmuch-match-content-type (plist-get part :content-type) 
"multipart/*")
+ append (notmuch-mua-get-quotable-parts (plist-get part :content))
+   else if (notmuch-match-content-type (plist-get part :content-type) 
"text/*")
+ collect part))
+
 (defun notmuch-mua-reply (query-string  sender reply-all)
-  (let (headers
-   body
-   (args '("reply")))
-(if notmuch-show-process-crypto
-   (setq args (append args '("--decrypt"
+  (let ((args '("reply" "--format=json"))
+   reply
+   original)
+(when 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
-;; line and then the body.
+
+;; Get the reply object as JSON, and parse it into an elisp object.
 (with-temp-buffer
   (apply 'call-process (append (list notmuch-command nil (list t t) nil) 
args))
   

[PATCH v7.1 09/11] test: Add broken tests for new emacs reply functionality

2012-03-13 Thread Adam Wolfe Gordon
Add tests for creating nice replies to multipart messages, including
those with HTML parts. These tests are expected to fail for now.
---
 test/emacs |   97 
 1 files changed, 97 insertions(+), 0 deletions(-)

diff --git a/test/emacs b/test/emacs
index 29a489c..01afdb6 100755
--- a/test/emacs
+++ b/test/emacs
@@ -273,6 +273,103 @@ On 01 Jan 2000 12:00:00 -, Notmuch Test Suite 
 w
 EOF
 test_expect_equal_file OUTPUT EXPECTED

+test_begin_subtest "Reply within emacs to a multipart/mixed message"
+test_subtest_known_broken
+test_emacs '(notmuch-show "id:20091118002059.067214ed at hikari")
+   (notmuch-show-reply)
+   (test-output)'
+cat 
+Fcc: ${MAIL_DIR}/sent
+--text follows this line--
+Adrian Perez de Castro  writes:
+
+> Hello to all,
+>
+> I have just heard about Not Much today in some random Linux-related news
+> site (LWN?), my name is Adrian Perez and I work as systems administrator
+> (although I can do some code as well :P). I have always thought that the
+> ideas behind Sup were great, but after some time using it, I got tired of
+> the oddities that it has. I also do not like doing things like having to
+> install Ruby just for reading and sorting mails. Some time ago I thought
+> about doing something like Not Much and in fact I played a bit with the
+> Python+Xapian and the Python+Whoosh combinations, because I find relaxing
+> to code things in Python when I am not working and also it is installed
+> by default on most distribution. I got to have some mailboxes indexed and
+> basic searching working a couple of months ago. Lately I have been very
+> busy and had no time for coding, and them... boom! Not Much appears -- and
+> it is almost exactly what I was trying to do, but faster. I have been
+> playing a bit with Not Much today, and I think it has potential.
+>
+> Also, I would like to share one idea I had in mind, that you might find
+> interesting: One thing I have found very annoying is having to re-tag my
+> mail when the indexes get b0rked (it happened a couple of times to me while
+> using Sup), so I was planning to mails as read/unread and adding the tags
+> not just to the index, but to the mail text itself, e.g. by adding a
+> "X-Tags" header field or by reusing the "Keywords" one. This way, the index
+> could be totally recreated by re-reading the mail directories, and this
+> would also allow to a tools like OfflineIMAP [1] to get the mails into a
+> local maildir, tagging and indexing the mails with the e-mail reader and
+> then syncing back the messages with the "X-Tags" header to the IMAP server.
+> This would allow to use the mail reader from a different computer and still
+> have everything tagged finely.
+>
+> Best regards,
+>
+>
+> ---
+> [1] http://software.complete.org/software/projects/show/offlineimap
+>
+> -- 
+> Adrian Perez de Castro 
+> Igalia - Free Software Engineering
+> ___
+> notmuch mailing list
+> notmuch at notmuchmail.org
+> http://notmuchmail.org/mailman/listinfo/notmuch
+EOF
+test_expect_equal_file OUTPUT EXPECTED
+
+test_begin_subtest "Reply within emacs to a multipart/alternative message"
+test_subtest_known_broken
+test_emacs '(notmuch-show "id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a at 
mail.gmail.com")
+   (notmuch-show-reply)
+   (test-output)'
+cat  I saw the announcement this morning, and was very excited, as I had been
+> hoping sup would be turned into a library,
+> since I like the concept more than the UI (I'd rather an emacs interface).
+>
+> I did a preliminary compile which worked out fine, but
+> sysconf(_SC_SC_GETPW_R_SIZE_MAX) returns -1 on
+> FreeBSD, so notmuch_config_open segfaulted.
+>
+> Attached is a patch that supplies a default buffer size of 64 in cases where
+> -1 is returned.
+>
+> http://www.opengroup.org/austin/docs/austin_328.txt - seems to indicate this
+> is acceptable behavior,
+> and 
http://mail-index.netbsd.org/pkgsrc-bugs/2006/06/07/msg016808.htmlspecifically
+> uses 64 as the
+> buffer size.
+> ___
+> notmuch mailing list
+> notmuch at notmuchmail.org
+> http://notmuchmail.org/mailman/listinfo/notmuch
+EOF
+test_expect_equal_file OUTPUT EXPECTED
+
 test_begin_subtest "Quote MML tags in reply"
 message_id='test-emacs-mml-quoting at message.id'
 add_message [id]="$message_id" \
-- 
1.7.5.4



[PATCH v7.1 08/11] emacs: Factor out useful functions into notmuch-lib

2012-03-13 Thread Adam Wolfe Gordon
Move a few functions related to handling multipart/alternative parts
into notmuch-lib.el, so they can be used by future reply code.
---
 emacs/notmuch-lib.el  |   33 +
 emacs/notmuch-show.el |   24 ++--
 2 files changed, 35 insertions(+), 22 deletions(-)

diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index d315f76..7e3f110 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -21,6 +21,8 @@

 ;; This is an part of an emacs-based interface to the notmuch mail system.

+(eval-when-compile (require 'cl))
+
 (defvar notmuch-command "notmuch"
   "Command to run the notmuch binary.")

@@ -173,6 +175,37 @@ the user hasn't set this variable with the old or new 
value."
   (list 'when (< emacs-major-version 23)
form))

+(defun notmuch-split-content-type (content-type)
+  "Split content/type into 'content' and 'type'"
+  (split-string content-type "/"))
+
+(defun notmuch-match-content-type (t1 t2)
+  "Return t if t1 and t2 are matching content types, taking wildcards into 
account"
+  (let ((st1 (notmuch-split-content-type t1))
+   (st2 (notmuch-split-content-type t2)))
+(if (or (string= (cadr st1) "*")
+   (string= (cadr st2) "*"))
+   (string= (car st1) (car st2))
+  (string= t1 t2
+
+(defvar notmuch-multipart/alternative-discouraged
+  '(
+;; Avoid HTML parts.
+"text/html"
+;; multipart/related usually contain a text/html part and some associated 
graphics.
+"multipart/related"
+))
+
+(defun notmuch-multipart/alternative-choose (types)
+  "Return a list of preferred types from the given list of types"
+  ;; Based on `mm-preferred-alternative-precedence'.
+  (let ((seq types))
+(dolist (pref (reverse notmuch-multipart/alternative-discouraged))
+  (dolist (elem (copy-sequence seq))
+   (when (string-match pref elem)
+ (setq seq (nconc (delete elem seq) (list elem))
+seq))
+
 ;; Compatibility functions for versions of emacs before emacs 23.
 ;;
 ;; Both functions here were copied from emacs 23 with the following copyright:
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 4a60631..ed938bf 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -542,30 +542,13 @@ current buffer, if possible."
(mm-display-part handle)
t))

-(defvar notmuch-show-multipart/alternative-discouraged
-  '(
-;; Avoid HTML parts.
-"text/html"
-;; multipart/related usually contain a text/html part and some associated 
graphics.
-"multipart/related"
-))
-
 (defun notmuch-show-multipart/*-to-list (part)
   (mapcar (lambda (inner-part) (plist-get inner-part :content-type))
  (plist-get part :content)))

-(defun notmuch-show-multipart/alternative-choose (types)
-  ;; Based on `mm-preferred-alternative-precedence'.
-  (let ((seq types))
-(dolist (pref (reverse notmuch-show-multipart/alternative-discouraged))
-  (dolist (elem (copy-sequence seq))
-   (when (string-match pref elem)
- (setq seq (nconc (delete elem seq) (list elem))
-seq))
-
 (defun notmuch-show-insert-part-multipart/alternative (msg part content-type 
nth depth declared-type)
   (notmuch-show-insert-part-header nth declared-type content-type nil)
-  (let ((chosen-type (car (notmuch-show-multipart/alternative-choose 
(notmuch-show-multipart/*-to-list part
+  (let ((chosen-type (car (notmuch-multipart/alternative-choose 
(notmuch-show-multipart/*-to-list part
(inner-parts (plist-get part :content))
(start (point)))
 ;; This inserts all parts of the chosen type rather than just one,
@@ -808,9 +791,6 @@ current buffer, if possible."

 ;; Functions for determining how to handle MIME parts.

-(defun notmuch-show-split-content-type (content-type)
-  (split-string content-type "/"))
-
 (defun notmuch-show-handlers-for (content-type)
   "Return a list of content handlers for a part of type CONTENT-TYPE."
   (let (result)
@@ -821,7 +801,7 @@ current buffer, if possible."
  (list (intern (concat "notmuch-show-insert-part-*/*"))
(intern (concat
 "notmuch-show-insert-part-"
-(car (notmuch-show-split-content-type content-type))
+(car (notmuch-split-content-type content-type))
 "/*"))
(intern (concat "notmuch-show-insert-part-" content-type
 result))
-- 
1.7.5.4



[PATCH v7.1 07/11] man: Add --decrypt to reply flags

2012-03-13 Thread Adam Wolfe Gordon
---
 man/man1/notmuch-reply.1 |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1
index debc505..d9912c4 100644
--- a/man/man1/notmuch-reply.1
+++ b/man/man1/notmuch-reply.1
@@ -68,6 +68,16 @@ values from the first that contains something other than 
only the
 user's addresses.
 .RE
 .RE
+.RS
+.TP 4
+.B \-\-decrypt
+
+Decrypt any MIME encrypted parts found in the selected content
+(ie. "multipart/encrypted" parts). Status of the decryption will be
+reported (currently only supported with --format=json) and the
+multipart/encrypted part will be replaced by the decrypted
+content.
+.RE

 See \fBnotmuch-search-terms\fR(7)
 for details of the supported syntax for .
-- 
1.7.5.4



[PATCH v7.1 06/11] man: Update notmuch-reply man page for JSON format.

2012-03-13 Thread Adam Wolfe Gordon
---
 man/man1/notmuch-reply.1 |   10 --
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1
index 7ed7f0f..debc505 100644
--- a/man/man1/notmuch-reply.1
+++ b/man/man1/notmuch-reply.1
@@ -37,12 +37,17 @@ Supported options for
 include
 .RS
 .TP 4
-.BR \-\-format= ( default | headers\-only )
+.BR \-\-format= ( default | json | headers\-only )
 .RS
 .TP 4
 .BR default
 Includes subject and quoted message body.
 .TP
+.BR json
+Produces JSON output containing headers for a reply message and the
+contents of the original message. This output can be used by a client
+to create a reply message intelligently.
+.TP
 .BR headers\-only
 Only produces In\-Reply\-To, References, To, Cc, and Bcc headers.
 .RE
@@ -73,7 +78,8 @@ with a search string matching a single message, (such as
 id:), but it can be useful to reply to several messages at
 once. For example, when a series of patches are sent in a single
 thread, replying to the entire thread allows for the reply to comment
-on issue found in multiple patches.
+on issues found in multiple patches. The default format supports
+replying to multiple messages at once, but the JSON format does not.
 .RE
 .RE

-- 
1.7.5.4



[PATCH v7.1 05/11] schemata: Add documentation for JSON reply format.

2012-03-13 Thread Adam Wolfe Gordon
---
 devel/schemata |   27 +--
 1 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/devel/schemata b/devel/schemata
index 24ad775..728a46f 100644
--- a/devel/schemata
+++ b/devel/schemata
@@ -77,8 +77,9 @@ part = {
 content?:   string
 }

-# The headers of a message (format_headers_json with raw headers) or
-# a part (format_headers_message_part_json with pretty-printed headers)
+# The headers of a message (format_headers_json with raw headers
+# and reply = FALSE) or a part (format_headers_message_part_json
+# with pretty-printed headers)
 headers = {
 Subject:string,
 From:   string,
@@ -136,3 +137,25 @@ thread = {
   # matched and unmatched
 subject:string
 }
+
+notmuch reply schema
+
+
+reply = {
+# The headers of the constructed reply (format_headers_json with
+# raw headers and reply = TRUE)
+reply-headers: reply_headers,
+
+# As in the show format (format_part_json)
+original: message
+}
+
+reply_headers = {
+Subject:string,
+From:   string,
+To?:string,
+Cc?:string,
+Bcc?:   string,
+In-reply-to:string,
+References: string
+}
-- 
1.7.5.4



[PATCH v7.1 04/11] reply: Add a JSON reply format.

2012-03-13 Thread Adam Wolfe Gordon
This new JSON format for replies includes headers generated for a
reply message as well as the headers of the original message.  Using
this data, a client can intelligently create a reply. For example, the
emacs client will be able to create replies with quoted HTML parts by
parsing the HTML parts.
---
 notmuch-client.h |   14 ++
 notmuch-reply.c  |   49 +
 notmuch-show.c   |   29 +
 test/multipart   |1 -
 4 files changed, 80 insertions(+), 13 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index f4a62cc..270daff 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -62,13 +62,13 @@
 #define STRINGIFY(s) STRINGIFY_(s)
 #define STRINGIFY_(s) #s

-struct mime_node;
+typedef struct mime_node mime_node_t;
 struct notmuch_show_params;

 typedef struct notmuch_show_format {
 const char *message_set_start;
 void (*part) (const void *ctx,
- struct mime_node *node, int indent,
+ mime_node_t *node, int indent,
  const struct notmuch_show_params *params);
 const char *message_start;
 void (*message) (const void *ctx,
@@ -191,6 +191,12 @@ show_message_body (notmuch_message_t *message,
 notmuch_status_t
 show_one_part (const char *filename, int part);

+void
+format_part_json (const void *ctx, mime_node_t *node, notmuch_bool_t first);
+
+void
+format_headers_json (const void *ctx, GMimeMessage *message, notmuch_bool_t 
reply);
+
 char *
 json_quote_chararray (const void *ctx, const char *str, const size_t len);

@@ -288,7 +294,7 @@ debugger_is_active (void);
  * parts.  Message-type parts have one child, multipart-type parts
  * have multiple children, and leaf parts have zero children.
  */
-typedef struct mime_node {
+struct mime_node {
 /* The MIME object of this part.  This will be a GMimeMessage,
  * GMimePart, GMimeMultipart, or a subclass of one of these.
  *
@@ -351,7 +357,7 @@ typedef struct mime_node {
  * number to assign it (or -1 if unknown). */
 int next_child;
 int next_part_num;
-} mime_node_t;
+};

 /* Construct a new MIME node pointing to the root message part of
  * message.  If cryptoctx is non-NULL, it will be used to verify
diff --git a/notmuch-reply.c b/notmuch-reply.c
index f1478cc..e2b6c25 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -604,6 +604,51 @@ notmuch_reply_format_default(void *ctx,
 return 0;
 }

+static int
+notmuch_reply_format_json(void *ctx,
+ notmuch_config_t *config,
+ notmuch_query_t *query,
+ notmuch_show_params_t *params,
+ notmuch_bool_t reply_all)
+{
+GMimeMessage *reply;
+notmuch_messages_t *messages;
+notmuch_message_t *message;
+mime_node_t *node;
+
+if (notmuch_query_count_messages (query) != 1) {
+   fprintf (stderr, "Error: search term did not match precisely one 
message.\n");
+   return 1;
+}
+
+messages = notmuch_query_search_messages (query);
+message = notmuch_messages_get (messages);
+if (mime_node_open (ctx, message, params->cryptoctx, params->decrypt,
+   ) != NOTMUCH_STATUS_SUCCESS)
+   return 1;
+
+reply = create_reply_message (ctx, config, message, reply_all);
+if (!reply)
+   return 1;
+
+/* The headers of the reply message we've created */
+printf ("{\"reply-headers\": ");
+format_headers_json (ctx, reply, TRUE);
+g_object_unref (G_OBJECT (reply));
+reply = NULL;
+
+/* Start the original */
+printf (", \"original\": ");
+
+format_part_json (ctx, node, TRUE);
+
+/* End */
+printf ("}\n");
+notmuch_message_destroy (message);
+
+return 0;
+}
+
 /* This format is currently tuned for a git send-email --notmuch hook */
 static int
 notmuch_reply_format_headers_only(void *ctx,
@@ -666,6 +711,7 @@ notmuch_reply_format_headers_only(void *ctx,

 enum {
 FORMAT_DEFAULT,
+FORMAT_JSON,
 FORMAT_HEADERS_ONLY,
 };

@@ -685,6 +731,7 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 notmuch_opt_desc_t options[] = {
{ NOTMUCH_OPT_KEYWORD, , "format", 'f',
  (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT },
+ { "json", FORMAT_JSON },
  { "headers-only", FORMAT_HEADERS_ONLY },
  { 0, 0 } } },
{ NOTMUCH_OPT_KEYWORD, _all, "reply-to", 'r',
@@ -703,6 +750,8 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])

 if (format == FORMAT_HEADERS_ONLY)
reply_format_func = notmuch_reply_format_headers_only;
+else if (format == FORMAT_JSON)
+   reply_format_func = notmuch_reply_format_json;
 else
reply_format_func = notmuch_reply_format_default;

diff --git a/notmuch-show.c b/notmuch-show.c
index 05d51b2..cb3a427 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -291,8 

[PATCH v7.1 03/11] TODO: Add replying to multiple messages

2012-03-13 Thread Adam Wolfe Gordon
---
 devel/TODO |8 
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/devel/TODO b/devel/TODO
index 4dda6f4..7b750af 100644
--- a/devel/TODO
+++ b/devel/TODO
@@ -141,6 +141,14 @@ Simplify notmuch-reply to simply print the headers (we 
have the
 original values) rather than calling GMime (which encodes) and adding
 the confusing gmime-filter-headers.c code (which decodes).

+Properly handle replying to multiple messages. Currently, the JSON
+reply format only supports a single message, but the default reply
+format accepts searches returning multiple messages. The expected
+behavior of replying to multiple messages is not obvious, and there
+are multiple ideas that might make sense. Some consensus needs to be
+reached on this issue, and then both reply formats should be updated
+to be consistent.
+
 notmuch library
 ---
 Add support for custom flag<->tag mappings. In the notmuch
-- 
1.7.5.4



[PATCH v7.1 02/11] reply: Factor out reply creation

2012-03-13 Thread Adam Wolfe Gordon
Factor out the creation of a reply message based on an original
message so it can be shared by different reply formats.
---
 notmuch-reply.c |  104 --
 1 files changed, 62 insertions(+), 42 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index 6b244e6..f1478cc 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -505,6 +505,61 @@ guess_from_received_header (notmuch_config_t *config, 
notmuch_message_t *message
 return NULL;
 }

+static GMimeMessage *
+create_reply_message(void *ctx,
+notmuch_config_t *config,
+notmuch_message_t *message,
+notmuch_bool_t reply_all)
+{
+const char *subject, *from_addr = NULL;
+const char *in_reply_to, *orig_references, *references;
+
+/* The 1 means we want headers in a "pretty" order. */
+GMimeMessage *reply = g_mime_message_new (1);
+if (reply == NULL) {
+   fprintf (stderr, "Out of memory\n");
+   return NULL;
+}
+
+subject = notmuch_message_get_header (message, "subject");
+if (subject) {
+   if (strncasecmp (subject, "Re:", 3))
+   subject = talloc_asprintf (ctx, "Re: %s", subject);
+   g_mime_message_set_subject (reply, subject);
+}
+
+from_addr = add_recipients_from_message (reply, config,
+message, reply_all);
+
+if (from_addr == NULL)
+   from_addr = guess_from_received_header (config, message);
+
+if (from_addr == NULL)
+   from_addr = notmuch_config_get_user_primary_email (config);
+
+from_addr = talloc_asprintf (ctx, "%s <%s>",
+notmuch_config_get_user_name (config),
+from_addr);
+g_mime_object_set_header (GMIME_OBJECT (reply),
+ "From", from_addr);
+
+in_reply_to = talloc_asprintf (ctx, "<%s>",
+  notmuch_message_get_message_id (message));
+
+g_mime_object_set_header (GMIME_OBJECT (reply),
+ "In-Reply-To", in_reply_to);
+
+orig_references = notmuch_message_get_header (message, "references");
+references = talloc_asprintf (ctx, "%s%s%s",
+ orig_references ? orig_references : "",
+ orig_references ? " " : "",
+ in_reply_to);
+g_mime_object_set_header (GMIME_OBJECT (reply),
+ "References", references);
+
+return reply;
+}
+
 static int
 notmuch_reply_format_default(void *ctx,
 notmuch_config_t *config,
@@ -515,8 +570,6 @@ notmuch_reply_format_default(void *ctx,
 GMimeMessage *reply;
 notmuch_messages_t *messages;
 notmuch_message_t *message;
-const char *subject, *from_addr = NULL;
-const char *in_reply_to, *orig_references, *references;
 const notmuch_show_format_t *format = _reply;

 for (messages = notmuch_query_search_messages (query);
@@ -525,49 +578,16 @@ notmuch_reply_format_default(void *ctx,
 {
message = notmuch_messages_get (messages);

-   /* The 1 means we want headers in a "pretty" order. */
-   reply = g_mime_message_new (1);
-   if (reply == NULL) {
-   fprintf (stderr, "Out of memory\n");
-   return 1;
-   }
+   reply = create_reply_message (ctx, config, message, reply_all);

-   subject = notmuch_message_get_header (message, "subject");
-   if (subject) {
-   if (strncasecmp (subject, "Re:", 3))
-   subject = talloc_asprintf (ctx, "Re: %s", subject);
-   g_mime_message_set_subject (reply, subject);
+   /* If reply creation failed, we're out of memory, so don't
+* bother trying any more messages.
+*/
+   if (!reply) {
+   notmuch_message_destroy (message);
+   return 1;
}

-   from_addr = add_recipients_from_message (reply, config, message,
-reply_all);
-
-   if (from_addr == NULL)
-   from_addr = guess_from_received_header (config, message);
-
-   if (from_addr == NULL)
-   from_addr = notmuch_config_get_user_primary_email (config);
-
-   from_addr = talloc_asprintf (ctx, "%s <%s>",
-notmuch_config_get_user_name (config),
-from_addr);
-   g_mime_object_set_header (GMIME_OBJECT (reply),
- "From", from_addr);
-
-   in_reply_to = talloc_asprintf (ctx, "<%s>",
-notmuch_message_get_message_id (message));
-
-   g_mime_object_set_header (GMIME_OBJECT (reply),
- "In-Reply-To", in_reply_to);
-
-   orig_references = notmuch_message_get_header (message, "references");
-   references = talloc_asprintf (ctx, "%s%s%s",
- 

[PATCH v7.1 01/11] test: Add broken test for the new JSON reply format.

2012-03-13 Thread Adam Wolfe Gordon
---
 test/multipart |   53 +
 1 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/test/multipart b/test/multipart
index 53782c6..80d6e88 100755
--- a/test/multipart
+++ b/test/multipart
@@ -589,6 +589,59 @@ Non-text part: text/html
 EOF
 test_expect_equal_file OUTPUT EXPECTED

+test_begin_subtest "'notmuch reply' to a multipart message with json format"
+test_subtest_known_broken
+notmuch reply --format=json 'id:87liy5ap00.fsf at yoom.home.cworth.org' | 
notmuch_json_show_sanitize >OUTPUT
+cat ",
+ "References": " <87liy5ap00.fsf at yoom.home.cworth.org>"},
+ "original": {"id": "X",
+ "match": false,
+ "excluded": false,
+ "filename": "Y",
+ "timestamp": 978709437,
+ "date_relative": "2001-01-05",
+ "tags": ["attachment","inbox","signed","unread"],
+ "headers": {"Subject": "Multipart message",
+ "From": "Carl Worth ",
+ "To": "cworth at cworth.org",
+ "Date": "Fri,
+ 05 Jan 2001 15:43:57 +"},
+ "body": [{"id": 1,
+ "content-type": "multipart/signed",
+ "content": [{"id": 2,
+ "content-type": "multipart/mixed",
+ "content": [{"id": 3,
+ "content-type": "message/rfc822",
+ "content": [{"headers": {"Subject": "html message",
+ "From": "Carl Worth ",
+ "To": "cworth at cworth.org",
+ "Date": "Fri,
+ 05 Jan 2001 15:42:57 +"},
+ "body": [{"id": 4,
+ "content-type": "multipart/alternative",
+ "content": [{"id": 5,
+ "content-type": "text/html"},
+ {"id": 6,
+ "content-type": "text/plain",
+ "content": "This is an embedded message,
+ with a multipart/alternative part.\n"}]}]}]},
+ {"id": 7,
+ "content-type": "text/plain",
+ "filename": "Y",
+ "content": "This is a text attachment.\n"},
+ {"id": 8,
+ "content-type": "text/plain",
+ "content": "And this message is signed.\n\n-Carl\n"}]},
+ {"id": 9,
+ "content-type": "application/pgp-signature"}]}]}}
+EOF
+test_expect_equal_file OUTPUT EXPECTED
+
 test_begin_subtest "'notmuch show --part' does not corrupt a part with CRLF 
pair"
 notmuch show --format=raw --part=3 id:base64-part-with-crlf > crlf.out
 echo -n -e "\xEF\x0D\x0A" > crlf.expected
-- 
1.7.5.4



[PATCH v7.1 00/11] Reply enhancements, second attempt

2012-03-13 Thread Adam Wolfe Gordon
Hi everyone,

This is mostly a re-send of last night's series [1]. The only changes are:

* Fixed the emacs patch, where I had a rebase issue.
* Fixed the commit that re-added test/test-lib by accident.
* Fixed devel/schemata per Austin's review of the previous version.

Since this series seems to be getting close, I figured I'd add a NEWS entry
for good measure.

Thanks for all the reviews so far, and I hope this is almost ready!

[1] id:"1331525142-30539-1-git-send-email-awg+notmuch at xvx.ca"

Adam Wolfe Gordon (11):
  test: Add broken test for the new JSON reply format.
  reply: Factor out reply creation
  TODO: Add replying to multiple messages
  reply: Add a JSON reply format.
  schemata: Add documentation for JSON reply format.
  man: Update notmuch-reply man page for JSON format.
  man: Add --decrypt to reply flags
  emacs: Factor out useful functions into notmuch-lib
  test: Add broken tests for new emacs reply functionality
  emacs: Use the new JSON reply format and message-cite-original
  NEWS: news for reply enhancements

 NEWS |   20 ++
 devel/TODO   |8 +++
 devel/schemata   |   27 -
 emacs/notmuch-lib.el |   63 +++
 emacs/notmuch-mua.el |  124 +
 emacs/notmuch-show.el|   55 +++--
 man/man1/notmuch-reply.1 |   20 ++-
 notmuch-client.h |   14 +++-
 notmuch-reply.c  |  153 +-
 notmuch-show.c   |   29 ++---
 test/emacs   |  101 ++-
 test/multipart   |   52 
 12 files changed, 518 insertions(+), 148 deletions(-)

-- 
1.7.5.4



[PATCH] build: Require gmime >= 2.6.7

2012-03-13 Thread David Bremner
On Sun, 11 Mar 2012 22:29:46 -0300, David Bremner  wrote:
> From: Thomas Jost 
> 
> gmime-2.6 had a bug [1] which made it impossible to tell why a signature
> verification failed when the signer key was unavailable (empty "sigstatus" 
> field
> in the JSON output). Since 00b5623d the corresponding test is marked as broken
> when using gmime-2.6 (2.4 is fine).

After positive feedback from dkg and Domo, pushed, with a corresponding
update to debian/control. 

d


[PATCH] man: update SEE ALSO references in man pages

2012-03-13 Thread David Bremner
On Sun, 11 Mar 2012 23:36:16 +0200, Jani Nikula  wrote:
> Drop references to notmuch-part(1). Reference all man pages. Fix man
> page section of notmuch-dump(1).

pushed.  As jani says, we can certainly improve the cross references
later.

d


[PATCH 0/2] A bug in the exclude code

2012-03-13 Thread Austin Clements
On Mon, 12 Mar 2012 11:31:52 +, Mark Walters  
wrote:
> There is a bug in the exclude code (found by jrollins in the
> --with-excluded series) but also present in master.  None of the
> current tests were finding it so the first patch adds two tests.
> 
> The bug (and test failure) do not appear in all configuations: on my
> main test machine (an oldish debian testing 32bit userspace with a
> 64bit kernel and xapian 1.2.7) all tests pass. On my laptop (a recent
> debian testing 64bit userspace and xapian 1.2.8) one of the new tests
> fails.
> 
> The second patch fixes the behaviour for me but I don't see why it
> should make a difference: searches for A and not B should give the
> same results as A and not (A and B). It could be a bug in xapian, it
> could be that I am not allowed to reuse queries as I do (is query1 =
> query1 and query2 allowed?) or it could be some memory use bug on my
> part.
> 
> Anyway the "fix" is small which should help narrow down the actual
> cause.

LGTM.  Even if we don't totally understand the root cause here, this
change is the right thing to do anyway.

I think it's fine to go ahead and push this ahead of the other exclude
updates, though obviously those will need a little rebasing on top of
this.


[PATCH] man: update SEE ALSO references in man pages

2012-03-13 Thread Jani Nikula
On Tue, 13 Mar 2012 13:35:44 -0400, Austin Clements  wrote:
> Quoth Jani Nikula on Mar 11 at 11:36 pm:
> > Drop references to notmuch-part(1). Reference all man pages. Fix man
> > page section of notmuch-dump(1).
> 
> This LGTM, but is it actually what we want?  Referencing everything
> from everything seems to defeat the purpose.  I would expect
> notmuch(1) to reference everything, but the command manpages to only
> reference notmuch(1) and specific, related commands (e.g., dump and
> restore should reference each other; new should reference hooks;
> count, dump, reply, search, show, and tag should reference
> search-terms; and new, search, and reply should reference config).

Hi Austin, while I agree with you, I think I'll have to leave that bit
for another patch, another time (and possibly another author ;). My
purpose here was to just quickly fix the current references, for which
the logic was that all pages reference all other pages.

BR,
Jani.


[PATCH] man: update SEE ALSO references in man pages

2012-03-13 Thread Austin Clements
Quoth Jani Nikula on Mar 11 at 11:36 pm:
> Drop references to notmuch-part(1). Reference all man pages. Fix man
> page section of notmuch-dump(1).

This LGTM, but is it actually what we want?  Referencing everything
from everything seems to defeat the purpose.  I would expect
notmuch(1) to reference everything, but the command manpages to only
reference notmuch(1) and specific, related commands (e.g., dump and
restore should reference each other; new should reference hooks;
count, dump, reply, search, show, and tag should reference
search-terms; and new, search, and reply should reference config).


[PATCH v7 10/10] emacs: Use the new JSON reply format and message-cite-original

2012-03-13 Thread Austin Clements
Quoth Adam Wolfe Gordon on Mar 11 at 10:05 pm:
> Use the new JSON reply format to create replies in emacs. Quote HTML
> parts nicely by using mm-display-part to turn them into displayable
> text, then quoting them with message-cite-original. This is very
> useful for users who regularly receive HTML-only email.
> 
> Use message-mode's message-cite-original function to create the
> quoted body for reply messages. In order to make this act like the
> existing notmuch defaults, you will need to set the following in
> your emacs configuration:
> 
> message-citation-line-format "On %a, %d %b %Y, %f wrote:"
> message-citation-line-function 'message-insert-formatted-citation-line
> 
> The tests have been updated to reflect the (ugly) emacs default.

Hmm.  This patch looks the same as in v6, but your cover letter says
that you changed some things.


[PATCH v7 01/10] test: Add broken test for the new JSON reply format.

2012-03-13 Thread Austin Clements
Quoth Adam Wolfe Gordon on Mar 11 at 10:05 pm:
> ---
>  test/multipart |   53 +++
>  test/test-lib  | 1242 
> 
>  2 files changed, 1295 insertions(+), 0 deletions(-)
>  create mode 100755 test/test-lib
> 
> diff --git a/test/multipart b/test/multipart
> index 53782c6..80d6e88 100755
> --- a/test/multipart
> +++ b/test/multipart
> @@ -589,6 +589,59 @@ Non-text part: text/html
>  EOF
>  test_expect_equal_file OUTPUT EXPECTED
>  
> +test_begin_subtest "'notmuch reply' to a multipart message with json format"
> +test_subtest_known_broken
> +notmuch reply --format=json 'id:87liy5ap00.fsf at yoom.home.cworth.org' | 
> notmuch_json_show_sanitize >OUTPUT
> +cat  +{"reply-headers": {"Subject": "Re: Multipart message",
> + "From": "Notmuch Test Suite ",
> + "To": "Carl Worth ,
> + cworth at cworth.org",
> + "In-reply-to": "<87liy5ap00.fsf at yoom.home.cworth.org>",
> + "References": " <87liy5ap00.fsf at yoom.home.cworth.org>"},
> + "original": {"id": "X",
> + "match": false,
> + "excluded": false,
> + "filename": "Y",
> + "timestamp": 978709437,
> + "date_relative": "2001-01-05",
> + "tags": ["attachment","inbox","signed","unread"],
> + "headers": {"Subject": "Multipart message",
> + "From": "Carl Worth ",
> + "To": "cworth at cworth.org",
> + "Date": "Fri,
> + 05 Jan 2001 15:43:57 +"},
> + "body": [{"id": 1,
> + "content-type": "multipart/signed",
> + "content": [{"id": 2,
> + "content-type": "multipart/mixed",
> + "content": [{"id": 3,
> + "content-type": "message/rfc822",
> + "content": [{"headers": {"Subject": "html message",
> + "From": "Carl Worth ",
> + "To": "cworth at cworth.org",
> + "Date": "Fri,
> + 05 Jan 2001 15:42:57 +"},
> + "body": [{"id": 4,
> + "content-type": "multipart/alternative",
> + "content": [{"id": 5,
> + "content-type": "text/html"},
> + {"id": 6,
> + "content-type": "text/plain",
> + "content": "This is an embedded message,
> + with a multipart/alternative part.\n"}]}]}]},
> + {"id": 7,
> + "content-type": "text/plain",
> + "filename": "Y",
> + "content": "This is a text attachment.\n"},
> + {"id": 8,
> + "content-type": "text/plain",
> + "content": "And this message is signed.\n\n-Carl\n"}]},
> + {"id": 9,
> + "content-type": "application/pgp-signature"}]}]}}
> +EOF
> +test_expect_equal_file OUTPUT EXPECTED
> +
>  test_begin_subtest "'notmuch show --part' does not corrupt a part with CRLF 
> pair"
>  notmuch show --format=raw --part=3 id:base64-part-with-crlf > crlf.out
>  echo -n -e "\xEF\x0D\x0A" > crlf.expected
> diff --git a/test/test-lib b/test/test-lib
> new file mode 100755
> index 000..8158328
> --- /dev/null
> +++ b/test/test-lib

Spurious git add?  (IIRC, this is what test-lib.sh used to be called,
so I'd guess you have an old copy of this file laying around.)

> @@ -0,0 +1,1242 @@
> +#
> +# Copyright (c) 2005 Junio C Hamano
> +#
> +# This program is free software: you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation, either version 2 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program.  If not, see http://www.gnu.org/licenses/ .
> +
> +if [ ${BASH_VERSINFO[0]} -lt 4 ]; then
> +echo "Error: The notmuch test suite requires a bash version >= 4.0"
> +echo "due to use of associative arrays within the test suite."
> +echo "Please try again with a newer bash (or help us fix the"
> +echo "test suite to be more portable). Thanks."
> +exit 1
> +fi
> +
> +# if --tee was passed, write the output not only to the terminal, but
> +# additionally to the file test-results/$BASENAME.out, too.
> +case "$GIT_TEST_TEE_STARTED, $* " in
> +done,*)
> + # do not redirect again
> + ;;
> +*' --tee '*|*' --va'*)
> + mkdir -p test-results
> + BASE=test-results/$(basename "$0" .sh)
> + (GIT_TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1;
> +  echo $? > $BASE.exit) | tee $BASE.out
> + test "$(cat $BASE.exit)" = 0
> + exit
> + ;;
> +esac
> +
> +# Keep the original TERM for say_color and test_emacs
> +ORIGINAL_TERM=$TERM
> +
> +# For repeatability, reset the environment to known value.
> +LANG=C
> +LC_ALL=C
> +PAGER=cat
> +TZ=UTC
> +TERM=dumb
> +export LANG LC_ALL PAGER TERM TZ
> +GIT_TEST_CMP=${GIT_TEST_CMP:-diff -u}
> +TEST_EMACS=${TEST_EMACS:-${EMACS:-emacs}}
> +
> +# Protect ourselves from common misconfiguration to export
> +# CDPATH into the environment
> +unset CDPATH
> +
> +unset GREP_OPTIONS
> +
> +# Convenience
> +#
> +# A regexp to match 5 and 40 hexdigits
> 

[PATCH v7 10/10] emacs: Use the new JSON reply format and message-cite-original

2012-03-13 Thread Adam Wolfe Gordon
On Tue, Mar 13, 2012 at 11:02, Austin Clements  wrote:
> Hmm. ?This patch looks the same as in v6, but your cover letter says
> that you changed some things.

Damn, indeed. Looks like I rebased the changes into the wrong commit,
so they weren't included in this series.

Might be best to ignore this version of the series - I'll get this
figured out tonight and send a new version.


[PATCH v7 01/10] test: Add broken test for the new JSON reply format.

2012-03-13 Thread Adam Wolfe Gordon
On Tue, Mar 13, 2012 at 10:49, Austin Clements  wrote:
>> diff --git a/test/test-lib b/test/test-lib
>> new file mode 100755
>> index 000..8158328
>> --- /dev/null
>> +++ b/test/test-lib
>
> Spurious git add? ?(IIRC, this is what test-lib.sh used to be called,
> so I'd guess you have an old copy of this file laying around.)

Yep, looks like it. I wonder how I missed that.


[PATCH 0/2] A bug in the exclude code

2012-03-13 Thread Jameson Graef Rollins
On Mon, 12 Mar 2012 21:07:49 +, Mark Walters  
wrote:
> Just to emphasise the bug is already present in current master (just
> better hidden because of the defaults). Hence this pair of patches
> (unlike the first one I sent privately) are to current master rather
> than to the exclude the series (though they apply there to to modulo the
> minor change you mention).

Ok, I see.  I think we really need to see the rest of that patch series
applied to master, though, so if you could send a version compatible
with [0], and in-reply-to [0], that would awesome.

Thanks again, Mark.

jamie.

[0] id:"1330779918-28024-1-git-send-email-markwalters1009 at gmail.com"
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 835 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120313/74db347f/attachment.pgp>


[PATCH] build: Require gmime >= 2.6.7

2012-03-13 Thread Tomi Ollila
On Sun, 11 Mar 2012 22:29:46 -0300, David Bremner  wrote:
> From: Thomas Jost 
> 
> gmime-2.6 had a bug [1] which made it impossible to tell why a signature
> verification failed when the signer key was unavailable (empty "sigstatus" 
> field
> in the JSON output). Since 00b5623d the corresponding test is marked as broken
> when using gmime-2.6 (2.4 is fine).
> 
> This bug has been fixed in gmime 2.6.5, which is now the minimal gmime-2.6
> version required for building notmuch (gmime-2.4 is still available). As a
> consequence the version check in test/crypto can be removed.
> 
> [Added by db]
> 
> Although less unambigously a bug, Gmime 2.6 prior to 2.6.7 also was
> more strict about parsing, and rejected messages with initial "From "
> headers.  This restriction is relaxed in [2].  For reasons explained in [3],
> we want to keep this more relaxed parsing for now.
> 
> [1] https://bugzilla.gnome.org/show_bug.cgi?id=668085
> 
> [2] 
> http://git.gnome.org/browse/gmime/commit/?id=d311f576baf750476e06e9a1367a2dc1793ea7eb
> 
> [3] id:"1331385931-1610-1-git-send-email-david at tethera.net"
> ---
> 
> As an alternative to applying [3], I could apply this modified version of
> Thomas's patch. 

I propose this patch is applied. It is best to require the very latest of
gmime 2.6 version at this time (gmime 2.6 maturing...)

This will make id:"1331402091-15663-1-git-send-email-tom.prince at ualberta.net"
stale. It can be reworked by changing $IFS to something else in code.

(We might start requiring some gmime 2.4 versions to be present; For me
 some tests fail when using gmime 2.4.21 (with gmimg 2.4.25 all works ok) --
 and then Reworked Tom Prince's patch could be used to overrile this
 "restriction")

Tomi


>  configure   |4 +++-
>  test/crypto |2 --
>  2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/configure b/configure
> index dedb7d8..ee0ae73 100755
> --- a/configure
> +++ b/configure
> @@ -273,9 +273,11 @@ if [ ${have_xapian} = "0" ]; then
>  errors=$((errors + 1))
>  fi
>  
> +# If using GMime 2.6, we need to have a version >= 2.6.5 to avoid a
> +# crypto bug. We need 2.6.7 for permissive "From " header handling.
>  printf "Checking for GMime development files... "
>  have_gmime=0
> -for gmimepc in gmime-2.6 gmime-2.4; do
> +for gmimepc in 'gmime-2.6 >= 2.6.7' gmime-2.4; do
>  if pkg-config --exists $gmimepc; then
>   printf "Yes ($gmimepc).\n"
>   have_gmime=1
> diff --git a/test/crypto b/test/crypto
> index 1dbb60a..6723ef8 100755
> --- a/test/crypto
> +++ b/test/crypto
> @@ -104,8 +104,6 @@ test_expect_equal \
>  "$expected"
>  
>  test_begin_subtest "signature verification with signer key unavailable"
> -# this is broken with current versions of gmime-2.6
> -(ldd $(which notmuch) | grep -Fq gmime-2.6) && test_subtest_known_broken
>  # move the gnupghome temporarily out of the way
>  mv "${GNUPGHOME}"{,.bak}
>  output=$(notmuch show --format=json --verify subject:"test signed message 
> 001" \
> -- 
> 1.7.9.1
> 
> ___
> notmuch mailing list
> notmuch at notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch
> 


Re: [PATCH] build: Require gmime = 2.6.7

2012-03-13 Thread Tomi Ollila
On Sun, 11 Mar 2012 22:29:46 -0300, David Bremner da...@tethera.net wrote:
 From: Thomas Jost schno...@schnouki.net
 
 gmime-2.6 had a bug [1] which made it impossible to tell why a signature
 verification failed when the signer key was unavailable (empty sigstatus 
 field
 in the JSON output). Since 00b5623d the corresponding test is marked as broken
 when using gmime-2.6 (2.4 is fine).
 
 This bug has been fixed in gmime 2.6.5, which is now the minimal gmime-2.6
 version required for building notmuch (gmime-2.4 is still available). As a
 consequence the version check in test/crypto can be removed.
 
 [Added by db]
 
 Although less unambigously a bug, Gmime 2.6 prior to 2.6.7 also was
 more strict about parsing, and rejected messages with initial From 
 headers.  This restriction is relaxed in [2].  For reasons explained in [3],
 we want to keep this more relaxed parsing for now.
 
 [1] https://bugzilla.gnome.org/show_bug.cgi?id=668085
 
 [2] 
 http://git.gnome.org/browse/gmime/commit/?id=d311f576baf750476e06e9a1367a2dc1793ea7eb
 
 [3] id:1331385931-1610-1-git-send-email-da...@tethera.net
 ---
 
 As an alternative to applying [3], I could apply this modified version of
 Thomas's patch. 

I propose this patch is applied. It is best to require the very latest of
gmime 2.6 version at this time (gmime 2.6 maturing...)

This will make id:1331402091-15663-1-git-send-email-tom.pri...@ualberta.net
stale. It can be reworked by changing $IFS to something else in code.

(We might start requiring some gmime 2.4 versions to be present; For me
 some tests fail when using gmime 2.4.21 (with gmimg 2.4.25 all works ok) --
 and then Reworked Tom Prince's patch could be used to overrile this
 restriction)

Tomi


  configure   |4 +++-
  test/crypto |2 --
  2 files changed, 3 insertions(+), 3 deletions(-)
 
 diff --git a/configure b/configure
 index dedb7d8..ee0ae73 100755
 --- a/configure
 +++ b/configure
 @@ -273,9 +273,11 @@ if [ ${have_xapian} = 0 ]; then
  errors=$((errors + 1))
  fi
  
 +# If using GMime 2.6, we need to have a version = 2.6.5 to avoid a
 +# crypto bug. We need 2.6.7 for permissive From  header handling.
  printf Checking for GMime development files... 
  have_gmime=0
 -for gmimepc in gmime-2.6 gmime-2.4; do
 +for gmimepc in 'gmime-2.6 = 2.6.7' gmime-2.4; do
  if pkg-config --exists $gmimepc; then
   printf Yes ($gmimepc).\n
   have_gmime=1
 diff --git a/test/crypto b/test/crypto
 index 1dbb60a..6723ef8 100755
 --- a/test/crypto
 +++ b/test/crypto
 @@ -104,8 +104,6 @@ test_expect_equal \
  $expected
  
  test_begin_subtest signature verification with signer key unavailable
 -# this is broken with current versions of gmime-2.6
 -(ldd $(which notmuch) | grep -Fq gmime-2.6)  test_subtest_known_broken
  # move the gnupghome temporarily out of the way
  mv ${GNUPGHOME}{,.bak}
  output=$(notmuch show --format=json --verify subject:test signed message 
 001 \
 -- 
 1.7.9.1
 
 ___
 notmuch mailing list
 notmuch@notmuchmail.org
 http://notmuchmail.org/mailman/listinfo/notmuch
 
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v7 01/10] test: Add broken test for the new JSON reply format.

2012-03-13 Thread Austin Clements
Quoth Adam Wolfe Gordon on Mar 11 at 10:05 pm:
 ---
  test/multipart |   53 +++
  test/test-lib  | 1242 
 
  2 files changed, 1295 insertions(+), 0 deletions(-)
  create mode 100755 test/test-lib
 
 diff --git a/test/multipart b/test/multipart
 index 53782c6..80d6e88 100755
 --- a/test/multipart
 +++ b/test/multipart
 @@ -589,6 +589,59 @@ Non-text part: text/html
  EOF
  test_expect_equal_file OUTPUT EXPECTED
  
 +test_begin_subtest 'notmuch reply' to a multipart message with json format
 +test_subtest_known_broken
 +notmuch reply --format=json 'id:87liy5ap00@yoom.home.cworth.org' | 
 notmuch_json_show_sanitize OUTPUT
 +cat EOF EXPECTED
 +{reply-headers: {Subject: Re: Multipart message,
 + From: Notmuch Test Suite test_su...@notmuchmail.org,
 + To: Carl Worth cwo...@cworth.org,
 + cwo...@cworth.org,
 + In-reply-to: 87liy5ap00@yoom.home.cworth.org,
 + References:  87liy5ap00@yoom.home.cworth.org},
 + original: {id: X,
 + match: false,
 + excluded: false,
 + filename: Y,
 + timestamp: 978709437,
 + date_relative: 2001-01-05,
 + tags: [attachment,inbox,signed,unread],
 + headers: {Subject: Multipart message,
 + From: Carl Worth cwo...@cworth.org,
 + To: cwo...@cworth.org,
 + Date: Fri,
 + 05 Jan 2001 15:43:57 +},
 + body: [{id: 1,
 + content-type: multipart/signed,
 + content: [{id: 2,
 + content-type: multipart/mixed,
 + content: [{id: 3,
 + content-type: message/rfc822,
 + content: [{headers: {Subject: html message,
 + From: Carl Worth cwo...@cworth.org,
 + To: cwo...@cworth.org,
 + Date: Fri,
 + 05 Jan 2001 15:42:57 +},
 + body: [{id: 4,
 + content-type: multipart/alternative,
 + content: [{id: 5,
 + content-type: text/html},
 + {id: 6,
 + content-type: text/plain,
 + content: This is an embedded message,
 + with a multipart/alternative part.\n}]}]}]},
 + {id: 7,
 + content-type: text/plain,
 + filename: Y,
 + content: This is a text attachment.\n},
 + {id: 8,
 + content-type: text/plain,
 + content: And this message is signed.\n\n-Carl\n}]},
 + {id: 9,
 + content-type: application/pgp-signature}]}]}}
 +EOF
 +test_expect_equal_file OUTPUT EXPECTED
 +
  test_begin_subtest 'notmuch show --part' does not corrupt a part with CRLF 
 pair
  notmuch show --format=raw --part=3 id:base64-part-with-crlf  crlf.out
  echo -n -e \xEF\x0D\x0A  crlf.expected
 diff --git a/test/test-lib b/test/test-lib
 new file mode 100755
 index 000..8158328
 --- /dev/null
 +++ b/test/test-lib

Spurious git add?  (IIRC, this is what test-lib.sh used to be called,
so I'd guess you have an old copy of this file laying around.)

 @@ -0,0 +1,1242 @@
 +#
 +# Copyright (c) 2005 Junio C Hamano
 +#
 +# This program is free software: you can redistribute it and/or modify
 +# it under the terms of the GNU General Public License as published by
 +# the Free Software Foundation, either version 2 of the License, or
 +# (at your option) any later version.
 +#
 +# This program is distributed in the hope that it will be useful,
 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +# GNU General Public License for more details.
 +#
 +# You should have received a copy of the GNU General Public License
 +# along with this program.  If not, see http://www.gnu.org/licenses/ .
 +
 +if [ ${BASH_VERSINFO[0]} -lt 4 ]; then
 +echo Error: The notmuch test suite requires a bash version = 4.0
 +echo due to use of associative arrays within the test suite.
 +echo Please try again with a newer bash (or help us fix the
 +echo test suite to be more portable). Thanks.
 +exit 1
 +fi
 +
 +# if --tee was passed, write the output not only to the terminal, but
 +# additionally to the file test-results/$BASENAME.out, too.
 +case $GIT_TEST_TEE_STARTED, $*  in
 +done,*)
 + # do not redirect again
 + ;;
 +*' --tee '*|*' --va'*)
 + mkdir -p test-results
 + BASE=test-results/$(basename $0 .sh)
 + (GIT_TEST_TEE_STARTED=done ${SHELL-sh} $0 $@ 21;
 +  echo $?  $BASE.exit) | tee $BASE.out
 + test $(cat $BASE.exit) = 0
 + exit
 + ;;
 +esac
 +
 +# Keep the original TERM for say_color and test_emacs
 +ORIGINAL_TERM=$TERM
 +
 +# For repeatability, reset the environment to known value.
 +LANG=C
 +LC_ALL=C
 +PAGER=cat
 +TZ=UTC
 +TERM=dumb
 +export LANG LC_ALL PAGER TERM TZ
 +GIT_TEST_CMP=${GIT_TEST_CMP:-diff -u}
 +TEST_EMACS=${TEST_EMACS:-${EMACS:-emacs}}
 +
 +# Protect ourselves from common misconfiguration to export
 +# CDPATH into the environment
 +unset CDPATH
 +
 +unset GREP_OPTIONS
 +
 +# Convenience
 +#
 +# A regexp to match 5 and 40 hexdigits
 +_x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
 +_x40=$_x05$_x05$_x05$_x05$_x05$_x05$_x05$_x05
 +
 +_x04='[0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
 +_x32=$_x04$_x04$_x04$_x04$_x04$_x04$_x04$_x04
 +
 +# Each test should start with something like this, after copyright notices:
 +#
 +# test_description='Description of this 

Re: [PATCH v7 01/10] test: Add broken test for the new JSON reply format.

2012-03-13 Thread Adam Wolfe Gordon
On Tue, Mar 13, 2012 at 10:49, Austin Clements amdra...@mit.edu wrote:
 diff --git a/test/test-lib b/test/test-lib
 new file mode 100755
 index 000..8158328
 --- /dev/null
 +++ b/test/test-lib

 Spurious git add?  (IIRC, this is what test-lib.sh used to be called,
 so I'd guess you have an old copy of this file laying around.)

Yep, looks like it. I wonder how I missed that.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v7 10/10] emacs: Use the new JSON reply format and message-cite-original

2012-03-13 Thread Austin Clements
Quoth Adam Wolfe Gordon on Mar 11 at 10:05 pm:
 Use the new JSON reply format to create replies in emacs. Quote HTML
 parts nicely by using mm-display-part to turn them into displayable
 text, then quoting them with message-cite-original. This is very
 useful for users who regularly receive HTML-only email.
 
 Use message-mode's message-cite-original function to create the
 quoted body for reply messages. In order to make this act like the
 existing notmuch defaults, you will need to set the following in
 your emacs configuration:
 
 message-citation-line-format On %a, %d %b %Y, %f wrote:
 message-citation-line-function 'message-insert-formatted-citation-line
 
 The tests have been updated to reflect the (ugly) emacs default.

Hmm.  This patch looks the same as in v6, but your cover letter says
that you changed some things.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] man: update SEE ALSO references in man pages

2012-03-13 Thread Austin Clements
Quoth Jani Nikula on Mar 11 at 11:36 pm:
 Drop references to notmuch-part(1). Reference all man pages. Fix man
 page section of notmuch-dump(1).

This LGTM, but is it actually what we want?  Referencing everything
from everything seems to defeat the purpose.  I would expect
notmuch(1) to reference everything, but the command manpages to only
reference notmuch(1) and specific, related commands (e.g., dump and
restore should reference each other; new should reference hooks;
count, dump, reply, search, show, and tag should reference
search-terms; and new, search, and reply should reference config).
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 0/2] A bug in the exclude code

2012-03-13 Thread Jameson Graef Rollins
On Mon, 12 Mar 2012 21:07:49 +, Mark Walters markwalters1...@gmail.com 
wrote:
 Just to emphasise the bug is already present in current master (just
 better hidden because of the defaults). Hence this pair of patches
 (unlike the first one I sent privately) are to current master rather
 than to the exclude the series (though they apply there to to modulo the
 minor change you mention).

Ok, I see.  I think we really need to see the rest of that patch series
applied to master, though, so if you could send a version compatible
with [0], and in-reply-to [0], that would awesome.

Thanks again, Mark.

jamie.

[0] id:1330779918-28024-1-git-send-email-markwalters1...@gmail.com


pgpwElLNxtrI8.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v7 10/10] emacs: Use the new JSON reply format and message-cite-original

2012-03-13 Thread Adam Wolfe Gordon
On Tue, Mar 13, 2012 at 11:02, Austin Clements amdra...@mit.edu wrote:
 Hmm.  This patch looks the same as in v6, but your cover letter says
 that you changed some things.

Damn, indeed. Looks like I rebased the changes into the wrong commit,
so they weren't included in this series.

Might be best to ignore this version of the series - I'll get this
figured out tonight and send a new version.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] man: update SEE ALSO references in man pages

2012-03-13 Thread Jani Nikula
On Tue, 13 Mar 2012 13:35:44 -0400, Austin Clements amdra...@mit.edu wrote:
 Quoth Jani Nikula on Mar 11 at 11:36 pm:
  Drop references to notmuch-part(1). Reference all man pages. Fix man
  page section of notmuch-dump(1).
 
 This LGTM, but is it actually what we want?  Referencing everything
 from everything seems to defeat the purpose.  I would expect
 notmuch(1) to reference everything, but the command manpages to only
 reference notmuch(1) and specific, related commands (e.g., dump and
 restore should reference each other; new should reference hooks;
 count, dump, reply, search, show, and tag should reference
 search-terms; and new, search, and reply should reference config).

Hi Austin, while I agree with you, I think I'll have to leave that bit
for another patch, another time (and possibly another author ;). My
purpose here was to just quickly fix the current references, for which
the logic was that all pages reference all other pages.

BR,
Jani.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] man: update SEE ALSO references in man pages

2012-03-13 Thread David Bremner
On Sun, 11 Mar 2012 23:36:16 +0200, Jani Nikula j...@nikula.org wrote:
 Drop references to notmuch-part(1). Reference all man pages. Fix man
 page section of notmuch-dump(1).

pushed.  As jani says, we can certainly improve the cross references
later.

d
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] build: Require gmime = 2.6.7

2012-03-13 Thread David Bremner
On Sun, 11 Mar 2012 22:29:46 -0300, David Bremner da...@tethera.net wrote:
 From: Thomas Jost schno...@schnouki.net
 
 gmime-2.6 had a bug [1] which made it impossible to tell why a signature
 verification failed when the signer key was unavailable (empty sigstatus 
 field
 in the JSON output). Since 00b5623d the corresponding test is marked as broken
 when using gmime-2.6 (2.4 is fine).

After positive feedback from dkg and Domo, pushed, with a corresponding
update to debian/control. 

d
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 0/2] A bug in the exclude code

2012-03-13 Thread Austin Clements
On Mon, 12 Mar 2012 11:31:52 +, Mark Walters markwalters1...@gmail.com 
wrote:
 There is a bug in the exclude code (found by jrollins in the
 --with-excluded series) but also present in master.  None of the
 current tests were finding it so the first patch adds two tests.
 
 The bug (and test failure) do not appear in all configuations: on my
 main test machine (an oldish debian testing 32bit userspace with a
 64bit kernel and xapian 1.2.7) all tests pass. On my laptop (a recent
 debian testing 64bit userspace and xapian 1.2.8) one of the new tests
 fails.
 
 The second patch fixes the behaviour for me but I don't see why it
 should make a difference: searches for A and not B should give the
 same results as A and not (A and B). It could be a bug in xapian, it
 could be that I am not allowed to reuse queries as I do (is query1 =
 query1 and query2 allowed?) or it could be some memory use bug on my
 part.
 
 Anyway the fix is small which should help narrow down the actual
 cause.

LGTM.  Even if we don't totally understand the root cause here, this
change is the right thing to do anyway.

I think it's fine to go ahead and push this ahead of the other exclude
updates, though obviously those will need a little rebasing on top of
this.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 0/2] Query debug improvements

2012-03-13 Thread Austin Clements
Two simple improvements for query debugging.

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 1/2] lib: Expose query debug output via an environment variable

2012-03-13 Thread Austin Clements
Allow query debugging to be enabled at run-time by setting the
NOTMUCH_DEBUG_QUERY environment variable to a non-empty string.

Previously, enabling query debugging required recompiling, but parsed
queries are often useful for tracking down bugs in situations where
recompiling is inconvenient.
---
 lib/query.cc |   24 +++-
 1 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/lib/query.cc b/lib/query.cc
index ab18fbc..1e5e99a 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -64,15 +64,21 @@ _notmuch_doc_id_set_init (void *ctx,
  notmuch_doc_id_set_t *doc_ids,
  GArray *arr);
 
+static notmuch_bool_t
+_debug_query (void)
+{
+char *env = getenv (NOTMUCH_DEBUG_QUERY);
+return (env  strcmp (env, ) != 0);
+}
+
 notmuch_query_t *
 notmuch_query_create (notmuch_database_t *notmuch,
  const char *query_string)
 {
 notmuch_query_t *query;
 
-#ifdef DEBUG_QUERY
-fprintf (stderr, Query string is:\n%s\n, query_string);
-#endif
+if (_debug_query ())
+   fprintf (stderr, Query string is:\n%s\n, query_string);
 
 query = talloc (NULL, notmuch_query_t);
 if (unlikely (query == NULL))
@@ -255,9 +261,9 @@ notmuch_query_search_messages (notmuch_query_t *query)
break;
}
 
-#if DEBUG_QUERY
-   fprintf (stderr, Final query is:\n%s\n, 
final_query.get_description().c_str());
-#endif
+   if (_debug_query ())
+   fprintf (stderr, Final query is:\n%s\n,
+final_query.get_description ().c_str ());
 
enquire.set_query (final_query);
 
@@ -531,9 +537,9 @@ notmuch_query_count_messages (notmuch_query_t *query)
enquire.set_weighting_scheme(Xapian::BoolWeight());
enquire.set_docid_order(Xapian::Enquire::ASCENDING);
 
-#if DEBUG_QUERY
-   fprintf (stderr, Final query is:\n%s\n, 
final_query.get_description().c_str());
-#endif
+   if (_debug_query ())
+   fprintf (stderr, Final query is:\n%s\n,
+final_query.get_description ().c_str ());
 
enquire.set_query (final_query);
 
-- 
1.7.7.3

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 2/2] lib: Add exclude query debug output

2012-03-13 Thread Austin Clements
---
 lib/query.cc |   10 --
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/lib/query.cc b/lib/query.cc
index 1e5e99a..53d505a 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -261,9 +261,12 @@ notmuch_query_search_messages (notmuch_query_t *query)
break;
}
 
-   if (_debug_query ())
+   if (_debug_query ()) {
+   fprintf (stderr, Exclude query is:\n%s\n,
+exclude_query.get_description ().c_str ());
fprintf (stderr, Final query is:\n%s\n,
 final_query.get_description ().c_str ());
+   }
 
enquire.set_query (final_query);
 
@@ -537,9 +540,12 @@ notmuch_query_count_messages (notmuch_query_t *query)
enquire.set_weighting_scheme(Xapian::BoolWeight());
enquire.set_docid_order(Xapian::Enquire::ASCENDING);
 
-   if (_debug_query ())
+   if (_debug_query ()) {
+   fprintf (stderr, Exclude query is:\n%s\n,
+exclude_query.get_description ().c_str ());
fprintf (stderr, Final query is:\n%s\n,
 final_query.get_description ().c_str ());
+   }
 
enquire.set_query (final_query);
 
-- 
1.7.7.3

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v2 0/2] cli: Allow true/false parameter for boolean

2012-03-13 Thread Austin Clements
Quoth Mark Walters on Mar 10 at 11:05 am:
 Hi
 
 Here is a second version of a patch to allow parameters to boolean
 options on the command line. This version allows parameters
 (=true|false). My first version is at
 id:1331244944-7960-1-git-send-email-markwalters1...@gmail.com. Jani
 posted an alternative version there. Jani's version and this one are
 quite similar: the key difference is that this version abuses a
 notmuch_bool_t by setting it to -1 (to indicate that the parser has
 not set this option). This makes the code simpler but is definitely an
 abuse. I will discuss this further in replies to Jani's series.
 
 Best wishes
 
 Mark
 
 Mark Walters (2):
   cli: Parsing. Allow true/false parameter for boolean options.
   cli: make --entire-thread=false work for format=json.

LGTM.  The one question I have is whether or not the resulting
non-entire-thread behavior of the JSON format is actually what we
*want*.  As a probably unintentional consequence of the current show
code, we get

# A message and its replies (show_messages)
thread_node = [
message?, # present if --entire-thread or matched
[thread_node*]# children of message
]

But would it be better to have

thread_node = [
message|null, # non-null if --entire-thread or matched
[thread_node*]# children of message
]

?  The latter is much more natural for consumers to work with
(checking whether the message matched or not is more natural and the
index of the child list doesn't change), but would require a little
more code in show to support.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v7.1 01/11] test: Add broken test for the new JSON reply format.

2012-03-13 Thread Adam Wolfe Gordon
---
 test/multipart |   53 +
 1 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/test/multipart b/test/multipart
index 53782c6..80d6e88 100755
--- a/test/multipart
+++ b/test/multipart
@@ -589,6 +589,59 @@ Non-text part: text/html
 EOF
 test_expect_equal_file OUTPUT EXPECTED
 
+test_begin_subtest 'notmuch reply' to a multipart message with json format
+test_subtest_known_broken
+notmuch reply --format=json 'id:87liy5ap00@yoom.home.cworth.org' | 
notmuch_json_show_sanitize OUTPUT
+cat EOF EXPECTED
+{reply-headers: {Subject: Re: Multipart message,
+ From: Notmuch Test Suite test_su...@notmuchmail.org,
+ To: Carl Worth cwo...@cworth.org,
+ cwo...@cworth.org,
+ In-reply-to: 87liy5ap00@yoom.home.cworth.org,
+ References:  87liy5ap00@yoom.home.cworth.org},
+ original: {id: X,
+ match: false,
+ excluded: false,
+ filename: Y,
+ timestamp: 978709437,
+ date_relative: 2001-01-05,
+ tags: [attachment,inbox,signed,unread],
+ headers: {Subject: Multipart message,
+ From: Carl Worth cwo...@cworth.org,
+ To: cwo...@cworth.org,
+ Date: Fri,
+ 05 Jan 2001 15:43:57 +},
+ body: [{id: 1,
+ content-type: multipart/signed,
+ content: [{id: 2,
+ content-type: multipart/mixed,
+ content: [{id: 3,
+ content-type: message/rfc822,
+ content: [{headers: {Subject: html message,
+ From: Carl Worth cwo...@cworth.org,
+ To: cwo...@cworth.org,
+ Date: Fri,
+ 05 Jan 2001 15:42:57 +},
+ body: [{id: 4,
+ content-type: multipart/alternative,
+ content: [{id: 5,
+ content-type: text/html},
+ {id: 6,
+ content-type: text/plain,
+ content: This is an embedded message,
+ with a multipart/alternative part.\n}]}]}]},
+ {id: 7,
+ content-type: text/plain,
+ filename: Y,
+ content: This is a text attachment.\n},
+ {id: 8,
+ content-type: text/plain,
+ content: And this message is signed.\n\n-Carl\n}]},
+ {id: 9,
+ content-type: application/pgp-signature}]}]}}
+EOF
+test_expect_equal_file OUTPUT EXPECTED
+
 test_begin_subtest 'notmuch show --part' does not corrupt a part with CRLF 
pair
 notmuch show --format=raw --part=3 id:base64-part-with-crlf  crlf.out
 echo -n -e \xEF\x0D\x0A  crlf.expected
-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v7.1 02/11] reply: Factor out reply creation

2012-03-13 Thread Adam Wolfe Gordon
Factor out the creation of a reply message based on an original
message so it can be shared by different reply formats.
---
 notmuch-reply.c |  104 --
 1 files changed, 62 insertions(+), 42 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index 6b244e6..f1478cc 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -505,6 +505,61 @@ guess_from_received_header (notmuch_config_t *config, 
notmuch_message_t *message
 return NULL;
 }
 
+static GMimeMessage *
+create_reply_message(void *ctx,
+notmuch_config_t *config,
+notmuch_message_t *message,
+notmuch_bool_t reply_all)
+{
+const char *subject, *from_addr = NULL;
+const char *in_reply_to, *orig_references, *references;
+
+/* The 1 means we want headers in a pretty order. */
+GMimeMessage *reply = g_mime_message_new (1);
+if (reply == NULL) {
+   fprintf (stderr, Out of memory\n);
+   return NULL;
+}
+
+subject = notmuch_message_get_header (message, subject);
+if (subject) {
+   if (strncasecmp (subject, Re:, 3))
+   subject = talloc_asprintf (ctx, Re: %s, subject);
+   g_mime_message_set_subject (reply, subject);
+}
+
+from_addr = add_recipients_from_message (reply, config,
+message, reply_all);
+
+if (from_addr == NULL)
+   from_addr = guess_from_received_header (config, message);
+
+if (from_addr == NULL)
+   from_addr = notmuch_config_get_user_primary_email (config);
+
+from_addr = talloc_asprintf (ctx, %s %s,
+notmuch_config_get_user_name (config),
+from_addr);
+g_mime_object_set_header (GMIME_OBJECT (reply),
+ From, from_addr);
+
+in_reply_to = talloc_asprintf (ctx, %s,
+  notmuch_message_get_message_id (message));
+
+g_mime_object_set_header (GMIME_OBJECT (reply),
+ In-Reply-To, in_reply_to);
+
+orig_references = notmuch_message_get_header (message, references);
+references = talloc_asprintf (ctx, %s%s%s,
+ orig_references ? orig_references : ,
+ orig_references ?   : ,
+ in_reply_to);
+g_mime_object_set_header (GMIME_OBJECT (reply),
+ References, references);
+
+return reply;
+}
+
 static int
 notmuch_reply_format_default(void *ctx,
 notmuch_config_t *config,
@@ -515,8 +570,6 @@ notmuch_reply_format_default(void *ctx,
 GMimeMessage *reply;
 notmuch_messages_t *messages;
 notmuch_message_t *message;
-const char *subject, *from_addr = NULL;
-const char *in_reply_to, *orig_references, *references;
 const notmuch_show_format_t *format = format_reply;
 
 for (messages = notmuch_query_search_messages (query);
@@ -525,49 +578,16 @@ notmuch_reply_format_default(void *ctx,
 {
message = notmuch_messages_get (messages);
 
-   /* The 1 means we want headers in a pretty order. */
-   reply = g_mime_message_new (1);
-   if (reply == NULL) {
-   fprintf (stderr, Out of memory\n);
-   return 1;
-   }
+   reply = create_reply_message (ctx, config, message, reply_all);
 
-   subject = notmuch_message_get_header (message, subject);
-   if (subject) {
-   if (strncasecmp (subject, Re:, 3))
-   subject = talloc_asprintf (ctx, Re: %s, subject);
-   g_mime_message_set_subject (reply, subject);
+   /* If reply creation failed, we're out of memory, so don't
+* bother trying any more messages.
+*/
+   if (!reply) {
+   notmuch_message_destroy (message);
+   return 1;
}
 
-   from_addr = add_recipients_from_message (reply, config, message,
-reply_all);
-
-   if (from_addr == NULL)
-   from_addr = guess_from_received_header (config, message);
-
-   if (from_addr == NULL)
-   from_addr = notmuch_config_get_user_primary_email (config);
-
-   from_addr = talloc_asprintf (ctx, %s %s,
-notmuch_config_get_user_name (config),
-from_addr);
-   g_mime_object_set_header (GMIME_OBJECT (reply),
- From, from_addr);
-
-   in_reply_to = talloc_asprintf (ctx, %s,
-notmuch_message_get_message_id (message));
-
-   g_mime_object_set_header (GMIME_OBJECT (reply),
- In-Reply-To, in_reply_to);
-
-   orig_references = notmuch_message_get_header (message, references);
-   references = talloc_asprintf (ctx, %s%s%s,
- orig_references ? orig_references : ,
- 

[PATCH v7.1 11/11] NEWS: news for reply enhancements

2012-03-13 Thread Adam Wolfe Gordon
---
 NEWS |   20 
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/NEWS b/NEWS
index a739914..46fb191 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,18 @@ Reply to sender
   to all. The feature is available through the new command line option
   --reply-to=(all|sender).
 
+JSON reply format
+
+  notmuch reply can now produce JSON output that contains the headers
+  for a reply message and full information about the original message
+  begin replied to. This allows MUAs to create replies intelligtently.
+  For example, an MUA that can parse HTML might quote HTML parts.
+
+  Calling notmuch reply with --format=json imposes the restriction that
+  only a single message is returned by the search, as replying to
+  multiple messages does not have a well-defined behavior. The default
+  retains its current behavior for multiple message replies.
+
 Tag exclusion
 
   Tags can be automatically excluded from search results by adding them
@@ -48,6 +60,14 @@ Reply to sender
   and search modes, 'r' has been bound to reply to sender, replacing
   reply to all, which now has key binding 'R'.
 
+Reply improvement using the JSON format
+
+  Emacs now uses the JSON reply format to create replies. It obeys
+  the customization variables message-citation-line-format and
+  message-citation-line-function when creating the first line of the
+  reply body, and it will quote HTML parts if no text/plain parts are
+  available.
+
 More flexible and consistent tagging operations
 
   All tagging operations (+, -, *) now accept multiple tags with
-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v7.1 09/11] test: Add broken tests for new emacs reply functionality

2012-03-13 Thread Adam Wolfe Gordon
Add tests for creating nice replies to multipart messages, including
those with HTML parts. These tests are expected to fail for now.
---
 test/emacs |   97 
 1 files changed, 97 insertions(+), 0 deletions(-)

diff --git a/test/emacs b/test/emacs
index 29a489c..01afdb6 100755
--- a/test/emacs
+++ b/test/emacs
@@ -273,6 +273,103 @@ On 01 Jan 2000 12:00:00 -, Notmuch Test Suite 
test_su...@notmuchmail.org w
 EOF
 test_expect_equal_file OUTPUT EXPECTED
 
+test_begin_subtest Reply within emacs to a multipart/mixed message
+test_subtest_known_broken
+test_emacs '(notmuch-show id:20091118002059.067214ed@hikari)
+   (notmuch-show-reply)
+   (test-output)'
+cat EOF EXPECTED
+From: Notmuch Test Suite test_su...@notmuchmail.org
+To: Adrian Perez de Castro ape...@igalia.com, notmuch@notmuchmail.org
+Subject: Re: [notmuch] Introducing myself
+In-Reply-To: 20091118002059.067214ed@hikari
+Fcc: ${MAIL_DIR}/sent
+--text follows this line--
+Adrian Perez de Castro ape...@igalia.com writes:
+
+ Hello to all,
+
+ I have just heard about Not Much today in some random Linux-related news
+ site (LWN?), my name is Adrian Perez and I work as systems administrator
+ (although I can do some code as well :P). I have always thought that the
+ ideas behind Sup were great, but after some time using it, I got tired of
+ the oddities that it has. I also do not like doing things like having to
+ install Ruby just for reading and sorting mails. Some time ago I thought
+ about doing something like Not Much and in fact I played a bit with the
+ Python+Xapian and the Python+Whoosh combinations, because I find relaxing
+ to code things in Python when I am not working and also it is installed
+ by default on most distribution. I got to have some mailboxes indexed and
+ basic searching working a couple of months ago. Lately I have been very
+ busy and had no time for coding, and them... boom! Not Much appears -- and
+ it is almost exactly what I was trying to do, but faster. I have been
+ playing a bit with Not Much today, and I think it has potential.
+
+ Also, I would like to share one idea I had in mind, that you might find
+ interesting: One thing I have found very annoying is having to re-tag my
+ mail when the indexes get b0rked (it happened a couple of times to me while
+ using Sup), so I was planning to mails as read/unread and adding the tags
+ not just to the index, but to the mail text itself, e.g. by adding a
+ X-Tags header field or by reusing the Keywords one. This way, the index
+ could be totally recreated by re-reading the mail directories, and this
+ would also allow to a tools like OfflineIMAP [1] to get the mails into a
+ local maildir, tagging and indexing the mails with the e-mail reader and
+ then syncing back the messages with the X-Tags header to the IMAP server.
+ This would allow to use the mail reader from a different computer and still
+ have everything tagged finely.
+
+ Best regards,
+
+
+ ---
+ [1] http://software.complete.org/software/projects/show/offlineimap
+
+ -- 
+ Adrian Perez de Castro ape...@igalia.com
+ Igalia - Free Software Engineering
+ ___
+ notmuch mailing list
+ notmuch@notmuchmail.org
+ http://notmuchmail.org/mailman/listinfo/notmuch
+EOF
+test_expect_equal_file OUTPUT EXPECTED
+
+test_begin_subtest Reply within emacs to a multipart/alternative message
+test_subtest_known_broken
+test_emacs '(notmuch-show 
id:cf0c4d610911171136h1713aa59w9cf9aa31f052a...@mail.gmail.com)
+   (notmuch-show-reply)
+   (test-output)'
+cat EOF EXPECTED
+From: Notmuch Test Suite test_su...@notmuchmail.org
+To: Alex Botero-Lowry alex.boterolo...@gmail.com, notmuch@notmuchmail.org
+Subject: Re: [notmuch] preliminary FreeBSD support
+In-Reply-To: cf0c4d610911171136h1713aa59w9cf9aa31f052a...@mail.gmail.com
+Fcc: ${MAIL_DIR}/sent
+--text follows this line--
+Alex Botero-Lowry alex.boterolo...@gmail.com writes:
+
+ I saw the announcement this morning, and was very excited, as I had been
+ hoping sup would be turned into a library,
+ since I like the concept more than the UI (I'd rather an emacs interface).
+
+ I did a preliminary compile which worked out fine, but
+ sysconf(_SC_SC_GETPW_R_SIZE_MAX) returns -1 on
+ FreeBSD, so notmuch_config_open segfaulted.
+
+ Attached is a patch that supplies a default buffer size of 64 in cases where
+ -1 is returned.
+
+ http://www.opengroup.org/austin/docs/austin_328.txt - seems to indicate this
+ is acceptable behavior,
+ and 
http://mail-index.netbsd.org/pkgsrc-bugs/2006/06/07/msg016808.htmlspecifically
+ uses 64 as the
+ buffer size.
+ ___
+ notmuch mailing list
+ notmuch@notmuchmail.org
+ http://notmuchmail.org/mailman/listinfo/notmuch
+EOF
+test_expect_equal_file OUTPUT EXPECTED
+
 test_begin_subtest Quote MML tags in reply
 message_id='test-emacs-mml-quot...@message.id'
 add_message 

[PATCH v7.1 08/11] emacs: Factor out useful functions into notmuch-lib

2012-03-13 Thread Adam Wolfe Gordon
Move a few functions related to handling multipart/alternative parts
into notmuch-lib.el, so they can be used by future reply code.
---
 emacs/notmuch-lib.el  |   33 +
 emacs/notmuch-show.el |   24 ++--
 2 files changed, 35 insertions(+), 22 deletions(-)

diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index d315f76..7e3f110 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -21,6 +21,8 @@
 
 ;; This is an part of an emacs-based interface to the notmuch mail system.
 
+(eval-when-compile (require 'cl))
+
 (defvar notmuch-command notmuch
   Command to run the notmuch binary.)
 
@@ -173,6 +175,37 @@ the user hasn't set this variable with the old or new 
value.
   (list 'when ( emacs-major-version 23)
form))
 
+(defun notmuch-split-content-type (content-type)
+  Split content/type into 'content' and 'type'
+  (split-string content-type /))
+
+(defun notmuch-match-content-type (t1 t2)
+  Return t if t1 and t2 are matching content types, taking wildcards into 
account
+  (let ((st1 (notmuch-split-content-type t1))
+   (st2 (notmuch-split-content-type t2)))
+(if (or (string= (cadr st1) *)
+   (string= (cadr st2) *))
+   (string= (car st1) (car st2))
+  (string= t1 t2
+
+(defvar notmuch-multipart/alternative-discouraged
+  '(
+;; Avoid HTML parts.
+text/html
+;; multipart/related usually contain a text/html part and some associated 
graphics.
+multipart/related
+))
+
+(defun notmuch-multipart/alternative-choose (types)
+  Return a list of preferred types from the given list of types
+  ;; Based on `mm-preferred-alternative-precedence'.
+  (let ((seq types))
+(dolist (pref (reverse notmuch-multipart/alternative-discouraged))
+  (dolist (elem (copy-sequence seq))
+   (when (string-match pref elem)
+ (setq seq (nconc (delete elem seq) (list elem))
+seq))
+
 ;; Compatibility functions for versions of emacs before emacs 23.
 ;;
 ;; Both functions here were copied from emacs 23 with the following copyright:
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 4a60631..ed938bf 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -542,30 +542,13 @@ current buffer, if possible.
(mm-display-part handle)
t))
 
-(defvar notmuch-show-multipart/alternative-discouraged
-  '(
-;; Avoid HTML parts.
-text/html
-;; multipart/related usually contain a text/html part and some associated 
graphics.
-multipart/related
-))
-
 (defun notmuch-show-multipart/*-to-list (part)
   (mapcar (lambda (inner-part) (plist-get inner-part :content-type))
  (plist-get part :content)))
 
-(defun notmuch-show-multipart/alternative-choose (types)
-  ;; Based on `mm-preferred-alternative-precedence'.
-  (let ((seq types))
-(dolist (pref (reverse notmuch-show-multipart/alternative-discouraged))
-  (dolist (elem (copy-sequence seq))
-   (when (string-match pref elem)
- (setq seq (nconc (delete elem seq) (list elem))
-seq))
-
 (defun notmuch-show-insert-part-multipart/alternative (msg part content-type 
nth depth declared-type)
   (notmuch-show-insert-part-header nth declared-type content-type nil)
-  (let ((chosen-type (car (notmuch-show-multipart/alternative-choose 
(notmuch-show-multipart/*-to-list part
+  (let ((chosen-type (car (notmuch-multipart/alternative-choose 
(notmuch-show-multipart/*-to-list part
(inner-parts (plist-get part :content))
(start (point)))
 ;; This inserts all parts of the chosen type rather than just one,
@@ -808,9 +791,6 @@ current buffer, if possible.
 
 ;; Functions for determining how to handle MIME parts.
 
-(defun notmuch-show-split-content-type (content-type)
-  (split-string content-type /))
-
 (defun notmuch-show-handlers-for (content-type)
   Return a list of content handlers for a part of type CONTENT-TYPE.
   (let (result)
@@ -821,7 +801,7 @@ current buffer, if possible.
  (list (intern (concat notmuch-show-insert-part-*/*))
(intern (concat
 notmuch-show-insert-part-
-(car (notmuch-show-split-content-type content-type))
+(car (notmuch-split-content-type content-type))
 /*))
(intern (concat notmuch-show-insert-part- content-type
 result))
-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v7.1 04/11] reply: Add a JSON reply format.

2012-03-13 Thread Adam Wolfe Gordon
This new JSON format for replies includes headers generated for a
reply message as well as the headers of the original message.  Using
this data, a client can intelligently create a reply. For example, the
emacs client will be able to create replies with quoted HTML parts by
parsing the HTML parts.
---
 notmuch-client.h |   14 ++
 notmuch-reply.c  |   49 +
 notmuch-show.c   |   29 +
 test/multipart   |1 -
 4 files changed, 80 insertions(+), 13 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index f4a62cc..270daff 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -62,13 +62,13 @@
 #define STRINGIFY(s) STRINGIFY_(s)
 #define STRINGIFY_(s) #s
 
-struct mime_node;
+typedef struct mime_node mime_node_t;
 struct notmuch_show_params;
 
 typedef struct notmuch_show_format {
 const char *message_set_start;
 void (*part) (const void *ctx,
- struct mime_node *node, int indent,
+ mime_node_t *node, int indent,
  const struct notmuch_show_params *params);
 const char *message_start;
 void (*message) (const void *ctx,
@@ -191,6 +191,12 @@ show_message_body (notmuch_message_t *message,
 notmuch_status_t
 show_one_part (const char *filename, int part);
 
+void
+format_part_json (const void *ctx, mime_node_t *node, notmuch_bool_t first);
+
+void
+format_headers_json (const void *ctx, GMimeMessage *message, notmuch_bool_t 
reply);
+
 char *
 json_quote_chararray (const void *ctx, const char *str, const size_t len);
 
@@ -288,7 +294,7 @@ debugger_is_active (void);
  * parts.  Message-type parts have one child, multipart-type parts
  * have multiple children, and leaf parts have zero children.
  */
-typedef struct mime_node {
+struct mime_node {
 /* The MIME object of this part.  This will be a GMimeMessage,
  * GMimePart, GMimeMultipart, or a subclass of one of these.
  *
@@ -351,7 +357,7 @@ typedef struct mime_node {
  * number to assign it (or -1 if unknown). */
 int next_child;
 int next_part_num;
-} mime_node_t;
+};
 
 /* Construct a new MIME node pointing to the root message part of
  * message.  If cryptoctx is non-NULL, it will be used to verify
diff --git a/notmuch-reply.c b/notmuch-reply.c
index f1478cc..e2b6c25 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -604,6 +604,51 @@ notmuch_reply_format_default(void *ctx,
 return 0;
 }
 
+static int
+notmuch_reply_format_json(void *ctx,
+ notmuch_config_t *config,
+ notmuch_query_t *query,
+ notmuch_show_params_t *params,
+ notmuch_bool_t reply_all)
+{
+GMimeMessage *reply;
+notmuch_messages_t *messages;
+notmuch_message_t *message;
+mime_node_t *node;
+
+if (notmuch_query_count_messages (query) != 1) {
+   fprintf (stderr, Error: search term did not match precisely one 
message.\n);
+   return 1;
+}
+
+messages = notmuch_query_search_messages (query);
+message = notmuch_messages_get (messages);
+if (mime_node_open (ctx, message, params-cryptoctx, params-decrypt,
+   node) != NOTMUCH_STATUS_SUCCESS)
+   return 1;
+
+reply = create_reply_message (ctx, config, message, reply_all);
+if (!reply)
+   return 1;
+
+/* The headers of the reply message we've created */
+printf ({\reply-headers\: );
+format_headers_json (ctx, reply, TRUE);
+g_object_unref (G_OBJECT (reply));
+reply = NULL;
+
+/* Start the original */
+printf (, \original\: );
+
+format_part_json (ctx, node, TRUE);
+
+/* End */
+printf (}\n);
+notmuch_message_destroy (message);
+
+return 0;
+}
+
 /* This format is currently tuned for a git send-email --notmuch hook */
 static int
 notmuch_reply_format_headers_only(void *ctx,
@@ -666,6 +711,7 @@ notmuch_reply_format_headers_only(void *ctx,
 
 enum {
 FORMAT_DEFAULT,
+FORMAT_JSON,
 FORMAT_HEADERS_ONLY,
 };
 
@@ -685,6 +731,7 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 notmuch_opt_desc_t options[] = {
{ NOTMUCH_OPT_KEYWORD, format, format, 'f',
  (notmuch_keyword_t []){ { default, FORMAT_DEFAULT },
+ { json, FORMAT_JSON },
  { headers-only, FORMAT_HEADERS_ONLY },
  { 0, 0 } } },
{ NOTMUCH_OPT_KEYWORD, reply_all, reply-to, 'r',
@@ -703,6 +750,8 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 
 if (format == FORMAT_HEADERS_ONLY)
reply_format_func = notmuch_reply_format_headers_only;
+else if (format == FORMAT_JSON)
+   reply_format_func = notmuch_reply_format_json;
 else
reply_format_func = notmuch_reply_format_default;
 
diff --git a/notmuch-show.c b/notmuch-show.c
index 05d51b2..cb3a427 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -291,8 

[PATCH v7.1 06/11] man: Update notmuch-reply man page for JSON format.

2012-03-13 Thread Adam Wolfe Gordon
---
 man/man1/notmuch-reply.1 |   10 --
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1
index 7ed7f0f..debc505 100644
--- a/man/man1/notmuch-reply.1
+++ b/man/man1/notmuch-reply.1
@@ -37,12 +37,17 @@ Supported options for
 include
 .RS
 .TP 4
-.BR \-\-format= ( default | headers\-only )
+.BR \-\-format= ( default | json | headers\-only )
 .RS
 .TP 4
 .BR default
 Includes subject and quoted message body.
 .TP
+.BR json
+Produces JSON output containing headers for a reply message and the
+contents of the original message. This output can be used by a client
+to create a reply message intelligently.
+.TP
 .BR headers\-only
 Only produces In\-Reply\-To, References, To, Cc, and Bcc headers.
 .RE
@@ -73,7 +78,8 @@ with a search string matching a single message, (such as
 id:message-id), but it can be useful to reply to several messages at
 once. For example, when a series of patches are sent in a single
 thread, replying to the entire thread allows for the reply to comment
-on issue found in multiple patches.
+on issues found in multiple patches. The default format supports
+replying to multiple messages at once, but the JSON format does not.
 .RE
 .RE
 
-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v7.1 07/11] man: Add --decrypt to reply flags

2012-03-13 Thread Adam Wolfe Gordon
---
 man/man1/notmuch-reply.1 |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1
index debc505..d9912c4 100644
--- a/man/man1/notmuch-reply.1
+++ b/man/man1/notmuch-reply.1
@@ -68,6 +68,16 @@ values from the first that contains something other than 
only the
 user's addresses.
 .RE
 .RE
+.RS
+.TP 4
+.B \-\-decrypt
+
+Decrypt any MIME encrypted parts found in the selected content
+(ie. multipart/encrypted parts). Status of the decryption will be
+reported (currently only supported with --format=json) and the
+multipart/encrypted part will be replaced by the decrypted
+content.
+.RE
 
 See \fBnotmuch-search-terms\fR(7)
 for details of the supported syntax for search-terms.
-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v7.1 10/11] emacs: Use the new JSON reply format and message-cite-original

2012-03-13 Thread Adam Wolfe Gordon
Use the new JSON reply format to create replies in emacs. Quote HTML
parts nicely by using mm-display-part to turn them into displayable
text, then quoting them with message-cite-original. This is very
useful for users who regularly receive HTML-only email.

Use message-mode's message-cite-original function to create the
quoted body for reply messages. In order to make this act like the
existing notmuch defaults, you will need to set the following in
your emacs configuration:

message-citation-line-format On %a, %d %b %Y, %f wrote:
message-citation-line-function 'message-insert-formatted-citation-line

The tests have been updated to reflect the (ugly) emacs default.
---
 emacs/notmuch-lib.el  |   30 
 emacs/notmuch-mua.el  |  124 +
 emacs/notmuch-show.el |   31 ++--
 test/emacs|8 ++--
 4 files changed, 123 insertions(+), 70 deletions(-)

diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 7e3f110..c146748 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -206,6 +206,36 @@ the user hasn't set this variable with the old or new 
value.
  (setq seq (nconc (delete elem seq) (list elem))
 seq))
 
+(defun notmuch-parts-filter-by-type (parts type)
+  Given a list of message parts, return a list containing the ones matching
+the given type.
+  (remove-if-not
+   (lambda (part) (notmuch-match-content-type (plist-get part :content-type) 
type))
+   parts))
+
+;; Helper for parts which are generally not included in the default
+;; JSON output.
+(defun notmuch-get-bodypart-internal (message-id part-number process-crypto)
+  (let ((args '(show --format=raw))
+   (part-arg (format --part=%s part-number)))
+(setq args (append args (list part-arg)))
+(if process-crypto
+   (setq args (append args '(--decrypt
+(setq args (append args (list message-id)))
+(with-temp-buffer
+  (let ((coding-system-for-read 'no-conversion))
+   (progn
+ (apply 'call-process (append (list notmuch-command nil (list t nil) 
nil) args))
+ (buffer-string))
+
+(defun notmuch-get-bodypart-content (msg part nth process-crypto)
+  (or (plist-get part :content)
+  (notmuch-get-bodypart-internal (concat id: (plist-get msg :id)) nth 
process-crypto)))
+
+(defun notmuch-plist-to-alist (plist)
+  (loop for (key value . rest) on plist by #'cddr
+   collect (cons (substring (symbol-name key) 1) value)))
+
 ;; Compatibility functions for versions of emacs before emacs 23.
 ;;
 ;; Both functions here were copied from emacs 23 with the following copyright:
diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 13244eb..6aae3a0 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -19,11 +19,15 @@
 ;;
 ;; Authors: David Edmondson d...@dme.org
 
+(require 'json)
 (require 'message)
+(require 'format-spec)
 
 (require 'notmuch-lib)
 (require 'notmuch-address)
 
+(eval-when-compile (require 'cl))
+
 ;;
 
 (defcustom notmuch-mua-send-hook '(notmuch-mua-message-send-hook)
@@ -72,54 +76,92 @@ list.
(push header message-hidden-headers)))
notmuch-mua-hidden-headers))
 
+(defun notmuch-mua-get-quotable-parts (parts)
+  (loop for part in parts
+   if (notmuch-match-content-type (plist-get part :content-type) 
multipart/alternative)
+ collect (let* ((subparts (plist-get part :content))
+   (types (mapcar (lambda (part) (plist-get part 
:content-type)) subparts))
+   (chosen-type (car (notmuch-multipart/alternative-choose 
types
+  (loop for part in (reverse subparts)
+if (notmuch-match-content-type (plist-get part 
:content-type) chosen-type)
+return part))
+   else if (notmuch-match-content-type (plist-get part :content-type) 
multipart/*)
+ append (notmuch-mua-get-quotable-parts (plist-get part :content))
+   else if (notmuch-match-content-type (plist-get part :content-type) 
text/*)
+ collect part))
+
 (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
+  (let ((args '(reply --format=json))
+   reply
+   original)
+(when 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
-;; line and then the body.
+
+;; Get the reply object as JSON, and parse it into an elisp object.
 (with-temp-buffer
   (apply 'call-process (append (list notmuch-command nil (list t t) nil) 
args))
   (goto-char 

[PATCH v7.1 05/11] schemata: Add documentation for JSON reply format.

2012-03-13 Thread Adam Wolfe Gordon
---
 devel/schemata |   27 +--
 1 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/devel/schemata b/devel/schemata
index 24ad775..728a46f 100644
--- a/devel/schemata
+++ b/devel/schemata
@@ -77,8 +77,9 @@ part = {
 content?:   string
 }
 
-# The headers of a message (format_headers_json with raw headers) or
-# a part (format_headers_message_part_json with pretty-printed headers)
+# The headers of a message (format_headers_json with raw headers
+# and reply = FALSE) or a part (format_headers_message_part_json
+# with pretty-printed headers)
 headers = {
 Subject:string,
 From:   string,
@@ -136,3 +137,25 @@ thread = {
   # matched and unmatched
 subject:string
 }
+
+notmuch reply schema
+
+
+reply = {
+# The headers of the constructed reply (format_headers_json with
+# raw headers and reply = TRUE)
+reply-headers: reply_headers,
+
+# As in the show format (format_part_json)
+original: message
+}
+
+reply_headers = {
+Subject:string,
+From:   string,
+To?:string,
+Cc?:string,
+Bcc?:   string,
+In-reply-to:string,
+References: string
+}
-- 
1.7.5.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch