1 Return-Path: <too@guru-group.fi>
\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 135EB431FAF
\r
6 for <notmuch@notmuchmail.org>; Sat, 6 Jul 2013 05:50:08 -0700 (PDT)
\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 tests=[none]
\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 IPZ2o3s9-aga for <notmuch@notmuchmail.org>;
\r
16 Sat, 6 Jul 2013 05:49:59 -0700 (PDT)
\r
17 Received: from guru.guru-group.fi (guru.guru-group.fi [46.183.73.34])
\r
18 by olra.theworths.org (Postfix) with ESMTP id 8466A431FAE
\r
19 for <notmuch@notmuchmail.org>; Sat, 6 Jul 2013 05:49:59 -0700 (PDT)
\r
20 Received: by guru.guru-group.fi (Postfix, from userid 501)
\r
21 id 166711000CF; Sat, 6 Jul 2013 15:49:53 +0300 (EEST)
\r
22 From: Tomi Ollila <tomi.ollila@iki.fi>
\r
23 To: notmuch@notmuchmail.org
\r
24 Subject: [PATCH 1/1] emacs: dropped rest of now-unused JSON functionality
\r
25 Date: Sat, 6 Jul 2013 15:49:51 +0300
\r
26 Message-Id: <1373114991-301-1-git-send-email-tomi.ollila@iki.fi>
\r
27 X-Mailer: git-send-email 1.8.0
\r
28 Cc: tomi.ollila@iki.fi
\r
29 X-BeenThere: notmuch@notmuchmail.org
\r
30 X-Mailman-Version: 2.1.13
\r
32 List-Id: "Use and development of the notmuch mail system."
\r
33 <notmuch.notmuchmail.org>
\r
34 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
35 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
36 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
37 List-Post: <mailto:notmuch@notmuchmail.org>
\r
38 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
39 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
40 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
41 X-List-Received-Date: Sat, 06 Jul 2013 12:50:08 -0000
\r
43 Notmuch cli provides all structured data previously provided
\r
44 in json format now in s-expression format, rendering all current
\r
45 json functionality obsolete.
\r
48 grep -ri json emacs prints no results
\r
49 All 571 tests passed.
\r
51 This patch should speed up Austin to create github repo for the
\r
52 incremental json parser ;D
\r
54 emacs/notmuch-lib.el | 268 +------------------------------------------------
\r
55 emacs/notmuch-mua.el | 3 +-
\r
56 emacs/notmuch-query.el | 1 -
\r
57 emacs/notmuch-show.el | 2 +-
\r
58 4 files changed, 3 insertions(+), 271 deletions(-)
\r
60 diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
\r
61 index 8deb7de..4796f17 100644
\r
62 --- a/emacs/notmuch-lib.el
\r
63 +++ b/emacs/notmuch-lib.el
\r
67 (require 'mm-decode)
\r
71 (defvar notmuch-command "notmuch"
\r
72 @@ -258,7 +257,7 @@ the given type."
\r
75 ;; Helper for parts which are generally not included in the default
\r
78 (defun notmuch-get-bodypart-internal (query part-number process-crypto)
\r
79 (let ((args '("show" "--format=raw"))
\r
80 (part-arg (format "--part=%s" part-number)))
\r
81 @@ -559,271 +558,6 @@ status."
\r
82 (defvar notmuch-show-process-crypto nil)
\r
83 (make-variable-buffer-local 'notmuch-show-process-crypto)
\r
85 -;; Incremental JSON parsing
\r
87 -;; These two variables are internal variables to the parsing
\r
88 -;; routines. They are always used buffer local but need to be declared
\r
89 -;; globally to avoid compiler warnings.
\r
91 -(defvar notmuch-json-parser nil
\r
92 - "Internal incremental JSON parser object: local to the buffer being parsed.")
\r
94 -(defvar notmuch-json-state nil
\r
95 - "State of the internal JSON parser: local to the buffer being parsed.")
\r
97 -(defun notmuch-json-create-parser (buffer)
\r
98 - "Return a streaming JSON parser that consumes input from BUFFER.
\r
100 -This parser is designed to read streaming JSON whose structure is
\r
101 -known to the caller. Like a typical JSON parsing interface, it
\r
102 -provides a function to read a complete JSON value from the input.
\r
103 -However, it extends this with an additional function that
\r
104 -requires the next value in the input to be a compound value and
\r
105 -descends into it, allowing its elements to be read one at a time
\r
106 -or further descended into. Both functions can return 'retry to
\r
107 -indicate that not enough input is available.
\r
109 -The parser always consumes input from BUFFER's point. Hence, the
\r
110 -caller is allowed to delete and data before point and may
\r
111 -resynchronize after an error by moving point."
\r
114 - ;; Terminator stack: a stack of characters that indicate the
\r
115 - ;; end of the compound values enclosing point
\r
118 - ;; * 'expect-value if the next token must be a value, but a
\r
119 - ;; value has not yet been reached
\r
120 - ;; * 'value if point is at the beginning of a value
\r
121 - ;; * 'expect-comma if the next token must be a comma
\r
123 - ;; Allow terminator: non-nil if the next token may be a
\r
126 - ;; Partial parse position: If state is 'value, a marker for
\r
127 - ;; the position of the partial parser or nil if no partial
\r
128 - ;; parsing has happened yet
\r
130 - ;; Partial parse state: If state is 'value, the current
\r
131 - ;; `parse-partial-sexp' state
\r
134 -(defmacro notmuch-json-buffer (jp) `(first ,jp))
\r
135 -(defmacro notmuch-json-term-stack (jp) `(second ,jp))
\r
136 -(defmacro notmuch-json-next (jp) `(third ,jp))
\r
137 -(defmacro notmuch-json-allow-term (jp) `(fourth ,jp))
\r
138 -(defmacro notmuch-json-partial-pos (jp) `(fifth ,jp))
\r
139 -(defmacro notmuch-json-partial-state (jp) `(sixth ,jp))
\r
141 -(defvar notmuch-json-syntax-table
\r
142 - (let ((table (make-syntax-table)))
\r
143 - ;; The standard syntax table is what we need except that "." needs
\r
144 - ;; to have word syntax instead of punctuation syntax.
\r
145 - (modify-syntax-entry ?. "w" table)
\r
147 - "Syntax table used for incremental JSON parsing.")
\r
149 -(defun notmuch-json-scan-to-value (jp)
\r
150 - ;; Helper function that consumes separators, terminators, and
\r
151 - ;; whitespace from point. Returns nil if it successfully reached
\r
152 - ;; the beginning of a value, 'end if it consumed a terminator, or
\r
153 - ;; 'retry if not enough input was available to reach a value. Upon
\r
154 - ;; nil return, (notmuch-json-next jp) is always 'value.
\r
156 - (if (eq (notmuch-json-next jp) 'value)
\r
157 - ;; We're already at a value
\r
159 - ;; Drive the state toward 'expect-value
\r
160 - (skip-chars-forward " \t\r\n")
\r
161 - (or (when (eobp) 'retry)
\r
162 - ;; Test for the terminator for the current compound
\r
163 - (when (and (notmuch-json-allow-term jp)
\r
164 - (eq (char-after) (car (notmuch-json-term-stack jp))))
\r
165 - ;; Consume it and expect a comma or terminator next
\r
167 - (setf (notmuch-json-term-stack jp) (cdr (notmuch-json-term-stack jp))
\r
168 - (notmuch-json-next jp) 'expect-comma
\r
169 - (notmuch-json-allow-term jp) t)
\r
171 - ;; Test for a separator
\r
172 - (when (eq (notmuch-json-next jp) 'expect-comma)
\r
173 - (when (/= (char-after) ?,)
\r
174 - (signal 'json-readtable-error (list "expected ','")))
\r
175 - ;; Consume it, switch to 'expect-value, and disallow a
\r
178 - (skip-chars-forward " \t\r\n")
\r
179 - (setf (notmuch-json-next jp) 'expect-value
\r
180 - (notmuch-json-allow-term jp) nil)
\r
181 - ;; We moved point, so test for eobp again and fall through
\r
182 - ;; to the next test if there's more input
\r
183 - (when (eobp) 'retry))
\r
184 - ;; Next must be 'expect-value and we know this isn't
\r
185 - ;; whitespace, EOB, or a terminator, so point must be on a
\r
188 - (assert (eq (notmuch-json-next jp) 'expect-value))
\r
189 - (setf (notmuch-json-next jp) 'value)
\r
192 -(defun notmuch-json-begin-compound (jp)
\r
193 - "Parse the beginning of a compound value and traverse inside it.
\r
195 -Returns 'retry if there is insufficient input to parse the
\r
196 -beginning of the compound. If this is able to parse the
\r
197 -beginning of a compound, it moves point past the token that opens
\r
198 -the compound and returns t. Later calls to `notmuch-json-read'
\r
199 -will return the compound's elements.
\r
201 -Entering JSON objects is currently unimplemented."
\r
203 - (with-current-buffer (notmuch-json-buffer jp)
\r
204 - ;; Disallow terminators
\r
205 - (setf (notmuch-json-allow-term jp) nil)
\r
206 - ;; Save "next" so we can restore it if there's a syntax error
\r
207 - (let ((saved-next (notmuch-json-next jp)))
\r
208 - (or (notmuch-json-scan-to-value jp)
\r
209 - (if (/= (char-after) ?\[)
\r
211 - (setf (notmuch-json-next jp) saved-next)
\r
212 - (signal 'json-readtable-error (list "expected '['")))
\r
214 - (push ?\] (notmuch-json-term-stack jp))
\r
215 - ;; Expect a value or terminator next
\r
216 - (setf (notmuch-json-next jp) 'expect-value
\r
217 - (notmuch-json-allow-term jp) t)
\r
220 -(defun notmuch-json-read (jp)
\r
221 - "Parse the value at point in JP's buffer.
\r
223 -Returns 'retry if there is insufficient input to parse a complete
\r
224 -JSON value (though it may still move point over separators or
\r
225 -whitespace). If the parser is currently inside a compound value
\r
226 -and the next token ends the list or object, this moves point just
\r
227 -past the terminator and returns 'end. Otherwise, this moves
\r
228 -point to just past the end of the value and returns the value."
\r
230 - (with-current-buffer (notmuch-json-buffer jp)
\r
232 - ;; Get to a value state
\r
233 - (notmuch-json-scan-to-value jp)
\r
235 - ;; Can we parse a complete value?
\r
237 - (if (looking-at "[-+0-9tfn]")
\r
238 - ;; This is a number or a keyword, so the partial
\r
239 - ;; parser isn't going to help us because a truncated
\r
240 - ;; number or keyword looks like a complete symbol to
\r
241 - ;; it. Look for something that clearly ends it.
\r
243 - (skip-chars-forward "^]},: \t\r\n")
\r
246 - ;; We're looking at a string, object, or array, which we
\r
247 - ;; can partial parse. If we just reached the value, set
\r
248 - ;; up the partial parser.
\r
249 - (when (null (notmuch-json-partial-state jp))
\r
250 - (setf (notmuch-json-partial-pos jp) (point-marker)))
\r
252 - ;; Extend the partial parse until we either reach EOB or
\r
253 - ;; get the whole value
\r
256 - (with-syntax-table notmuch-json-syntax-table
\r
257 - (parse-partial-sexp
\r
258 - (notmuch-json-partial-pos jp) (point-max) 0 nil
\r
259 - (notmuch-json-partial-state jp)))))
\r
260 - ;; A complete value is available if we've reached
\r
261 - ;; depth 0 or less and encountered a complete
\r
262 - ;; subexpression.
\r
263 - (if (and (<= (first pstate) 0) (third pstate))
\r
265 - ;; Not complete. Update the partial parser state
\r
266 - (setf (notmuch-json-partial-pos jp) (point-marker)
\r
267 - (notmuch-json-partial-state jp) pstate)
\r
270 - (if (not complete)
\r
272 - ;; We have a value. Reset the partial parse state and expect
\r
273 - ;; a comma or terminator after the value.
\r
274 - (setf (notmuch-json-next jp) 'expect-comma
\r
275 - (notmuch-json-allow-term jp) t
\r
276 - (notmuch-json-partial-pos jp) nil
\r
277 - (notmuch-json-partial-state jp) nil)
\r
278 - ;; Parse the value
\r
279 - (let ((json-object-type 'plist)
\r
280 - (json-array-type 'list)
\r
281 - (json-false nil))
\r
282 - (json-read)))))))
\r
284 -(defun notmuch-json-eof (jp)
\r
285 - "Signal a json-error if there is more data in JP's buffer.
\r
287 -Moves point to the beginning of any trailing data or to the end
\r
288 -of the buffer if there is only trailing whitespace."
\r
290 - (with-current-buffer (notmuch-json-buffer jp)
\r
291 - (skip-chars-forward " \t\r\n")
\r
293 - (signal 'json-error (list "Trailing garbage following JSON data")))))
\r
295 -(defun notmuch-json-parse-partial-list (result-function error-function results-buf)
\r
296 - "Parse a partial JSON list from current buffer.
\r
298 -This function consumes a JSON list from the current buffer,
\r
299 -applying RESULT-FUNCTION in buffer RESULT-BUFFER to each complete
\r
300 -value in the list. It operates incrementally and should be
\r
301 -called whenever the buffer has been extended with additional
\r
304 -If there is a syntax error, this will attempt to resynchronize
\r
305 -with the input and will apply ERROR-FUNCTION in buffer
\r
306 -RESULT-BUFFER to any input that was skipped.
\r
308 -It sets up all the needed internal variables: the caller just
\r
309 -needs to call it with point in the same place that the parser
\r
312 - (unless (local-variable-p 'notmuch-json-parser)
\r
313 - (set (make-local-variable 'notmuch-json-parser)
\r
314 - (notmuch-json-create-parser (current-buffer)))
\r
315 - (set (make-local-variable 'notmuch-json-state) 'begin))
\r
316 - (while (not done)
\r
317 - (condition-case nil
\r
318 - (case notmuch-json-state
\r
320 - ;; Enter the results list
\r
321 - (if (eq (notmuch-json-begin-compound
\r
322 - notmuch-json-parser) 'retry)
\r
324 - (setq notmuch-json-state 'result)))
\r
326 - ;; Parse a result
\r
327 - (let ((result (notmuch-json-read notmuch-json-parser)))
\r
329 - ((retry) (setq done t))
\r
330 - ((end) (setq notmuch-json-state 'end))
\r
331 - (otherwise (with-current-buffer results-buf
\r
332 - (funcall result-function result))))))
\r
334 - ;; Any trailing data is unexpected
\r
335 - (notmuch-json-eof notmuch-json-parser)
\r
338 - ;; Do our best to resynchronize and ensure forward
\r
340 - (let ((bad (buffer-substring (line-beginning-position)
\r
341 - (line-end-position))))
\r
343 - (with-current-buffer results-buf
\r
344 - (funcall error-function "%s" bad))))))
\r
345 - ;; Clear out what we've parsed
\r
346 - (delete-region (point-min) (point))))
\r
351 (provide 'notmuch-lib)
\r
353 diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
\r
354 index 329d342..2baae5f 100644
\r
355 --- a/emacs/notmuch-mua.el
\r
356 +++ b/emacs/notmuch-mua.el
\r
359 ;; Authors: David Edmondson <dme@dme.org>
\r
364 (require 'format-spec)
\r
365 @@ -157,7 +156,7 @@ list."
\r
366 (setq args (append args '("--reply-to=sender"))))
\r
367 (setq args (append args (list query-string)))
\r
369 - ;; Get the reply object as JSON, and parse it into an elisp object.
\r
370 + ;; Get the reply object as SEXP, and parse it into an elisp object.
\r
371 (setq reply (apply #'notmuch-call-notmuch-sexp args))
\r
373 ;; Extract the original message to simplify the following code.
\r
374 diff --git a/emacs/notmuch-query.el b/emacs/notmuch-query.el
\r
375 index 51d427f..d1daffc 100644
\r
376 --- a/emacs/notmuch-query.el
\r
377 +++ b/emacs/notmuch-query.el
\r
379 ;; Authors: David Bremner <david@tethera.net>
\r
381 (require 'notmuch-lib)
\r
384 (defun notmuch-query-get-threads (search-terms)
\r
385 "Return a list of threads of messages matching SEARCH-TERMS.
\r
386 diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
\r
387 index e5de977..c4e0a99 100644
\r
388 --- a/emacs/notmuch-show.el
\r
389 +++ b/emacs/notmuch-show.el
\r
390 @@ -2042,7 +2042,7 @@ the user (see `notmuch-show-stash-mlarchive-link-alist')."
\r
391 (with-current-buffer buf
\r
392 (setq notmuch-show-process-crypto process-crypto)
\r
393 ;; Always acquires the part via `notmuch part', even if it is
\r
394 - ;; available in the JSON output.
\r
395 + ;; available in the SEXP output.
\r
396 (insert (notmuch-get-bodypart-internal message-id nth notmuch-show-process-crypto)))
\r