1 Return-Path: <dme@dme.org>
\r
2 X-Original-To: notmuch@notmuchmail.org
\r
3 Delivered-To: notmuch@notmuchmail.org
\r
4 Received: from localhost (localhost [127.0.0.1])
\r
5 by olra.theworths.org (Postfix) with ESMTP id A2480431FB5
\r
6 for <notmuch@notmuchmail.org>; Mon, 29 Nov 2010 02:30:44 -0800 (PST)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=0 tagged_above=-999 required=5
\r
12 tests=[RCVD_IN_DNSWL_NONE=-0.0001] autolearn=disabled
\r
13 Received: from olra.theworths.org ([127.0.0.1])
\r
14 by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)
\r
15 with ESMTP id SgaAQyo4cs5B for <notmuch@notmuchmail.org>;
\r
16 Mon, 29 Nov 2010 02:30:43 -0800 (PST)
\r
17 Received: from mail-wy0-f181.google.com (mail-wy0-f181.google.com
\r
19 by olra.theworths.org (Postfix) with ESMTP id 713B441A547
\r
20 for <notmuch@notmuchmail.org>; Mon, 29 Nov 2010 02:30:43 -0800 (PST)
\r
21 Received: by wyf22 with SMTP id 22so4656184wyf.26
\r
22 for <notmuch@notmuchmail.org>; Mon, 29 Nov 2010 02:30:41 -0800 (PST)
\r
23 Received: by 10.216.239.199 with SMTP id c49mr4762944wer.12.1291026641780;
\r
24 Mon, 29 Nov 2010 02:30:41 -0800 (PST)
\r
25 Received: from ut.hh.sledj.net (host81-149-164-25.in-addr.btopenworld.com
\r
27 by mx.google.com with ESMTPS id o43sm2294205weq.47.2010.11.29.02.30.40
\r
28 (version=TLSv1/SSLv3 cipher=RC4-MD5);
\r
29 Mon, 29 Nov 2010 02:30:40 -0800 (PST)
\r
30 Received: by ut.hh.sledj.net (Postfix, from userid 1000)
\r
31 id E5629594245; Mon, 29 Nov 2010 10:30:07 +0000 (GMT)
\r
32 From: David Edmondson <dme@dme.org>
\r
33 To: notmuch@notmuchmail.org
\r
34 Subject: [PATCH 3/3] emacs: Use JSON output for search.
\r
35 Date: Mon, 29 Nov 2010 10:29:59 +0000
\r
36 Message-Id: <1291026599-14795-4-git-send-email-dme@dme.org>
\r
37 X-Mailer: git-send-email 1.7.2.3
\r
38 In-Reply-To: <1291026599-14795-1-git-send-email-dme@dme.org>
\r
39 References: <1291026599-14795-1-git-send-email-dme@dme.org>
\r
40 X-BeenThere: notmuch@notmuchmail.org
\r
41 X-Mailman-Version: 2.1.13
\r
43 List-Id: "Use and development of the notmuch mail system."
\r
44 <notmuch.notmuchmail.org>
\r
45 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
46 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
47 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
48 List-Post: <mailto:notmuch@notmuchmail.org>
\r
49 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
50 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
51 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
52 X-List-Received-Date: Mon, 29 Nov 2010 10:30:44 -0000
\r
54 Switch to using the JSON format output of `notmuch search' to avoid
\r
55 problems parsing the output text. In particular, a comma in the name
\r
56 of an author would confuse the previous implementation.
\r
58 emacs/notmuch.el | 114 +++++++++++++++++++++++++++++++++++++-----------------
\r
59 1 files changed, 78 insertions(+), 36 deletions(-)
\r
61 diff --git a/emacs/notmuch.el b/emacs/notmuch.el
\r
62 index 5933747..bde8c47 100644
\r
63 --- a/emacs/notmuch.el
\r
64 +++ b/emacs/notmuch.el
\r
66 (eval-when-compile (require 'cl))
\r
71 (require 'notmuch-lib)
\r
72 (require 'notmuch-show)
\r
73 @@ -698,40 +699,81 @@ foreground and blue background."
\r
74 do (notmuch-search-insert-field field date count authors subject tags)))
\r
77 +(defun notmuch-search-process-insert-object (object)
\r
78 + (let* ((thread-id (concat "thread:" (cdr (assoc 'thread object))))
\r
79 + (date (format "%12s" (cdr (assoc 'date_relative object))))
\r
80 + (count (format "[%d/%d]"
\r
81 + (cdr (assoc 'matched object))
\r
82 + (cdr (assoc 'total object))))
\r
83 + (authors (cdr (assoc 'authors object)))
\r
84 + (subject (cdr (assoc 'subject object)))
\r
85 + (tag-list (cdr (assoc 'tags object)))
\r
86 + (tags (mapconcat 'identity tag-list " "))
\r
87 + (beg (point-marker)))
\r
88 + (notmuch-search-show-result date count authors subject tags)
\r
89 + (notmuch-search-color-line beg (point-marker) tag-list)
\r
90 + (put-text-property beg (point-marker) 'notmuch-search-thread-id thread-id)
\r
91 + (put-text-property beg (point-marker) 'notmuch-search-authors authors)
\r
92 + (put-text-property beg (point-marker) 'notmuch-search-subject subject)))
\r
94 +(defvar notmuch-search-parse-start nil)
\r
95 +(make-variable-buffer-local 'notmuch-show-parse-start)
\r
97 +(defun notmuch-search-process-insert (proc buffer string)
\r
98 + (with-current-buffer buffer
\r
99 + (let ((inhibit-read-only t)
\r
100 + (inhibit-redisplay t)
\r
101 + ;; Vectors are not as useful here.
\r
102 + (json-array-type 'list)
\r
105 + ;; Insert the text, advancing the process marker
\r
106 + (goto-char (point-max))
\r
108 + (set-marker (process-mark proc) (point)))
\r
111 + (goto-char notmuch-search-parse-start)
\r
112 + (condition-case nil
\r
115 + ;; Opening bracket or comma separator between
\r
117 + ((or (char-equal (json-peek) ?\[)
\r
118 + (char-equal (json-peek) ?\,))
\r
120 + (delete-region notmuch-search-parse-start (point))
\r
123 + ;; Closing array.
\r
124 + ((char-equal (json-peek) ?\])
\r
125 + ;; Consume both the closing bracket and any trailing
\r
126 + ;; whitespace (typically a carriage return).
\r
128 + (json-skip-whitespace)
\r
129 + (delete-region notmuch-search-parse-start (point))
\r
132 + ;; Single object.
\r
133 + ((setq object (json-read-object))
\r
134 + ;; Delete the object that we consumed.
\r
135 + (delete-region notmuch-search-parse-start (point))
\r
136 + ;; Insert the corresponding results.
\r
137 + (notmuch-search-process-insert-object object)
\r
139 + ;; Consume any white space between terms.
\r
140 + (let ((p (point)))
\r
141 + (json-skip-whitespace)
\r
142 + (delete-region p (point)))
\r
143 + ;; Remember where we got up to.
\r
144 + (setq notmuch-search-parse-start (point)))
\r
147 (defun notmuch-search-process-filter (proc string)
\r
148 - "Process and filter the output of \"notmuch search\""
\r
149 - (let ((buffer (process-buffer proc))
\r
150 - (found-target nil))
\r
151 + "Process and filter the output of `notmuch search'."
\r
152 + (let ((buffer (process-buffer proc)))
\r
153 (if (buffer-live-p buffer)
\r
154 - (with-current-buffer buffer
\r
158 - (inhibit-read-only t))
\r
160 - (if (string-match "^\\(thread:[0-9A-Fa-f]*\\) \\([^][]*\\) \\(\\[[0-9/]*\\]\\) \\([^;]*\\); \\(.*\\) (\\([^()]*\\))$" string line)
\r
161 - (let* ((thread-id (match-string 1 string))
\r
162 - (date (match-string 2 string))
\r
163 - (count (match-string 3 string))
\r
164 - (authors (match-string 4 string))
\r
165 - (subject (match-string 5 string))
\r
166 - (tags (match-string 6 string))
\r
167 - (tag-list (if tags (save-match-data (split-string tags)))))
\r
168 - (goto-char (point-max))
\r
169 - (let ((beg (point-marker)))
\r
170 - (notmuch-search-show-result date count authors subject tags)
\r
171 - (notmuch-search-color-line beg (point-marker) tag-list)
\r
172 - (put-text-property beg (point-marker) 'notmuch-search-thread-id thread-id)
\r
173 - (put-text-property beg (point-marker) 'notmuch-search-authors authors)
\r
174 - (put-text-property beg (point-marker) 'notmuch-search-subject subject)
\r
175 - (if (string= thread-id notmuch-search-target-thread)
\r
177 - (set 'found-target beg)
\r
178 - (set 'notmuch-search-target-thread "found"))))
\r
179 - (set 'line (match-end 0)))
\r
180 - (set 'more nil)))))
\r
182 - (goto-char found-target)))
\r
183 + (notmuch-search-process-insert proc buffer string)
\r
184 (delete-process proc))))
\r
186 (defun notmuch-search-operate-all (action)
\r
187 @@ -806,15 +848,15 @@ The optional parameters are used as follows:
\r
188 (set 'notmuch-search-continuation continuation)
\r
189 (let ((proc (get-buffer-process (current-buffer)))
\r
190 (inhibit-read-only t))
\r
192 - (error "notmuch search process already running for query `%s'" query)
\r
195 + (error "notmuch search process already running for query `%s'" query))
\r
197 - (goto-char (point-min))
\r
198 + (setq notmuch-search-parse-start (point-min))
\r
200 (let ((proc (start-process
\r
201 "notmuch-search" buffer
\r
202 notmuch-command "search"
\r
205 "--sort=oldest-first"
\r
206 "--sort=newest-first")
\r