]> git.notmuchmail.org Git - notmuch/blobdiff - emacs/notmuch-parser.el
emacs: Add new option notmuch-search-hide-excluded
[notmuch] / emacs / notmuch-parser.el
index bb0379c102f653c2df12b08afd012186f3003a3e..710c60e15ec12c7b3f5d6ca02d869d5be45f03d6 100644 (file)
@@ -1,4 +1,4 @@
-;;; notmuch-parser.el --- streaming S-expression parser
+;;; notmuch-parser.el --- streaming S-expression parser  -*- lexical-binding: t -*-
 ;;
 ;; Copyright © Austin Clements
 ;;
@@ -21,7 +21,9 @@
 
 ;;; Code:
 
-(require 'cl)
+(require 'cl-lib)
+(require 'pcase)
+(require 'subr-x)
 
 (defun notmuch-sexp-create-parser ()
   "Return a new streaming S-expression parser.
@@ -33,19 +35,15 @@ complete S-expression from the input.  However, it extends this
 with an additional function that requires the next value in the
 input to be a list and descends into it, allowing its elements to
 be read one at a time or further descended into.  Both functions
-can return 'retry to indicate that not enough input is available.
+can return \\='retry to indicate that not enough input is available.
 
 The parser always consumes input from point in the current
 buffer.  Hence, the caller is allowed to delete any data before
 point and may resynchronize after an error by moving point."
-
   (vector 'notmuch-sexp-parser
-         ;; List depth
-         0
-         ;; Partial parse position marker
-         nil
-         ;; Partial parse state
-         nil))
+         0     ; List depth
+         nil   ; Partial parse position marker
+         nil)) ; Partial parse state
 
 (defmacro notmuch-sexp--depth (sp)         `(aref ,sp 1))
 (defmacro notmuch-sexp--partial-pos (sp)   `(aref ,sp 2))
@@ -54,13 +52,12 @@ point and may resynchronize after an error by moving point."
 (defun notmuch-sexp-read (sp)
   "Consume and return the value at point in the current buffer.
 
-Returns 'retry if there is insufficient input to parse a complete
+Returns \\='retry if there is insufficient input to parse a complete
 value (though it may still move point over whitespace).  If the
 parser is currently inside a list and the next token ends the
-list, this moves point just past the terminator and returns 'end.
+list, this moves point just past the terminator and returns \\='end.
 Otherwise, this moves point to just past the end of the value and
 returns the value."
-
   (skip-chars-forward " \n\r\t")
   (cond ((eobp) 'retry)
        ((= (char-after) ?\))
@@ -70,7 +67,7 @@ returns the value."
             ;; error to be consistent with all other code paths.
             (read (current-buffer))
           ;; Go up a level and return an end token
-          (decf (notmuch-sexp--depth sp))
+          (cl-decf (notmuch-sexp--depth sp))
           (forward-char)
           'end))
        ((= (char-after) ?\()
@@ -80,7 +77,7 @@ returns the value."
         ;; parse, extend the partial parse to figure out when we
         ;; have a complete list.
         (catch 'return
-          (when (null (notmuch-sexp--partial-state sp))
+          (unless (notmuch-sexp--partial-state sp)
             (let ((start (point)))
               (condition-case nil
                   (throw 'return (read (current-buffer)))
@@ -94,8 +91,8 @@ returns the value."
                                  (notmuch-sexp--partial-state sp)))
                      ;; A complete value is available if we've
                      ;; reached depth 0.
-                     (depth (first new-state)))
-                (assert (>= depth 0))
+                     (depth (car new-state)))
+                (cl-assert (>= depth 0))
                 (if (= depth 0)
                     ;; Reset partial parse state
                     (setf (notmuch-sexp--partial-state sp) nil
@@ -128,34 +125,23 @@ returns the value."
 (defun notmuch-sexp-begin-list (sp)
   "Parse the beginning of a list value and enter the list.
 
-Returns 'retry if there is insufficient input to parse the
+Returns \\='retry if there is insufficient input to parse the
 beginning of the list.  If this is able to parse the beginning of
 a list, it moves point past the token that opens the list and
 returns t.  Later calls to `notmuch-sexp-read' will return the
 elements inside the list.  If the input in buffer is not the
 beginning of a list, throw invalid-read-syntax."
-
   (skip-chars-forward " \n\r\t")
   (cond ((eobp) 'retry)
        ((= (char-after) ?\()
         (forward-char)
-        (incf (notmuch-sexp--depth sp))
+        (cl-incf (notmuch-sexp--depth sp))
         t)
        (t
         ;; Skip over the bad character like `read' does
         (forward-char)
         (signal 'invalid-read-syntax (list (string (char-before)))))))
 
-(defun notmuch-sexp-eof (sp)
-  "Signal an error if there is more data in SP's buffer.
-
-Moves point to the beginning of any trailing data or to the end
-of the buffer if there is only trailing whitespace."
-
-  (skip-chars-forward " \n\r\t")
-  (unless (eobp)
-    (error "Trailing garbage following expression")))
-
 (defvar notmuch-sexp--parser nil
   "The buffer-local notmuch-sexp-parser instance.
 
@@ -173,15 +159,13 @@ complete value in the list.  It operates incrementally and should
 be called whenever the input buffer has been extended with
 additional data.  The caller just needs to ensure it does not
 move point in the input buffer."
-
   ;; Set up the initial state
   (unless (local-variable-p 'notmuch-sexp--parser)
-    (set (make-local-variable 'notmuch-sexp--parser)
-        (notmuch-sexp-create-parser))
-    (set (make-local-variable 'notmuch-sexp--state) 'begin))
+    (setq-local notmuch-sexp--parser (notmuch-sexp-create-parser))
+    (setq-local notmuch-sexp--state 'begin))
   (let (done)
     (while (not done)
-      (case notmuch-sexp--state
+      (cl-case notmuch-sexp--state
        (begin
         ;; Enter the list
         (if (eq (notmuch-sexp-begin-list notmuch-sexp--parser) 'retry)
@@ -190,22 +174,21 @@ move point in the input buffer."
        (result
         ;; Parse a result
         (let ((result (notmuch-sexp-read notmuch-sexp--parser)))
-          (case result
+          (cl-case result
             (retry (setq done t))
             (end   (setq notmuch-sexp--state 'end))
             (t     (with-current-buffer result-buffer
                      (funcall result-function result))))))
        (end
-        ;; Any trailing data is unexpected
-        (notmuch-sexp-eof notmuch-sexp--parser)
+        ;; Skip over trailing whitespace.
+        (skip-chars-forward " \n\r\t")
+        ;; Any trailing data is unexpected.
+        (unless (eobp)
+          (error "Trailing garbage following expression"))
         (setq done t)))))
   ;; Clear out what we've parsed
   (delete-region (point-min) (point)))
 
 (provide 'notmuch-parser)
 
-;; Local Variables:
-;; byte-compile-warnings: (not cl-functions)
-;; End:
-
 ;;; notmuch-parser.el ends here