]> code.delx.au - gnu-emacs/blobdiff - lisp/emacs-lisp/smie.el
Merge from origin/emacs-24
[gnu-emacs] / lisp / emacs-lisp / smie.el
index 4f3f12d528533340e3b04ea42e4d999faf851981..1bc5eb287202a96db43624869df0d971b7905b68 100644 (file)
@@ -612,8 +612,11 @@ PREC2 is a table as returned by `smie-precs->prec2' or
              (cons (pcase (cdr x)
                      (`closer (cddr (assoc token table)))
                      (`opener (cdr (assoc token table))))))
-        (cl-assert (numberp (car cons)))
-        (setf (car cons) (list (car cons)))))
+        ;; `cons' can be nil for openers/closers which only contain
+        ;; "atomic" elements.
+        (when cons
+          (cl-assert (numberp (car cons)))
+          (setf (car cons) (list (car cons))))))
     (let ((ca (gethash :smie-closer-alist prec2)))
       (when ca (push (cons :smie-closer-alist ca) table)))
     ;; (smie-check-grammar table prec2 'step3)
@@ -632,14 +635,14 @@ e.g. a LEFT-LEVEL of nil means this is a token that behaves somewhat like
 an open-paren, whereas a RIGHT-LEVEL of nil would correspond to something
 like a close-paren.")
 
-(defvar smie-forward-token-function 'smie-default-forward-token
+(defvar smie-forward-token-function #'smie-default-forward-token
   "Function to scan forward for the next token.
 Called with no argument should return a token and move to its end.
 If no token is found, return nil or the empty string.
 It can return nil when bumping into a parenthesis, which lets SMIE
 use syntax-tables to handle them in efficient C code.")
 
-(defvar smie-backward-token-function 'smie-default-backward-token
+(defvar smie-backward-token-function #'smie-default-backward-token
   "Function to scan backward the previous token.
 Same calling convention as `smie-forward-token-function' except
 it should move backward to the beginning of the previous token.")
@@ -806,9 +809,9 @@ Possible return values:
   nil: we skipped over an identifier, matched parentheses, ..."
   (smie-next-sexp
    (indirect-function smie-backward-token-function)
-   (indirect-function 'backward-sexp)
-   (indirect-function 'smie-op-left)
-   (indirect-function 'smie-op-right)
+   (indirect-function #'backward-sexp)
+   (indirect-function #'smie-op-left)
+   (indirect-function #'smie-op-right)
    halfsexp))
 
 (defun smie-forward-sexp (&optional halfsexp)
@@ -827,9 +830,9 @@ Possible return values:
   nil: we skipped over an identifier, matched parentheses, ..."
   (smie-next-sexp
    (indirect-function smie-forward-token-function)
-   (indirect-function 'forward-sexp)
-   (indirect-function 'smie-op-right)
-   (indirect-function 'smie-op-left)
+   (indirect-function #'forward-sexp)
+   (indirect-function #'smie-op-right)
+   (indirect-function #'smie-op-left)
    halfsexp))
 
 ;;; Miscellaneous commands using the precedence parser.
@@ -1121,7 +1124,7 @@ OPENER is non-nil if TOKEN is an opener and nil if it's a closer."
   :type 'integer
   :group 'smie)
 
-(defvar smie-rules-function 'ignore
+(defvar smie-rules-function #'ignore
   "Function providing the indentation rules.
 It takes two arguments METHOD and ARG where the meaning of ARG
 and the expected return value depends on METHOD.
@@ -2121,41 +2124,45 @@ position corresponding to each rule."
                otraces)
 
       ;; Finally, guess the indentation rules.
-      (let ((ssigs nil)
-            (rules nil))
-        ;; Sort the sigs by frequency of occurrence.
-        (maphash (lambda (sig sig-data) (push (cons sig sig-data) ssigs)) sigs)
-        (setq ssigs (sort ssigs (lambda (sd1 sd2) (> (cadr sd1) (cadr sd2)))))
-        (while ssigs
-          (pcase-let ((`(,sig ,total ,off-alist ,cotraces) (pop ssigs)))
-            (cl-assert (= total (apply #'+ (mapcar #'cdr off-alist))))
-            (let* ((sorted-off-alist
-                    (sort off-alist (lambda (x y) (> (cdr x) (cdr y)))))
-                   (offset (caar sorted-off-alist)))
-              (if (zerop offset)
-                  ;; Nothing to do with this sig; indentation is
-                  ;; correct already.
-                  nil
-                (push (cons (+ offset (nth 2 sig)) sig) rules)
-                ;; Adjust the rest of the data.
-                (pcase-dolist ((and cotrace `(,count ,toffset . ,trace))
-                               cotraces)
-                  (setf (nth 1 cotrace) (- toffset offset))
-                  (dolist (sig trace)
-                    (let ((sig-data (cdr (assq sig ssigs))))
-                      (when sig-data
-                        (let* ((ooff-data (assq toffset (nth 1 sig-data)))
-                               (noffset (- toffset offset))
-                               (noff-data
-                                (or (assq noffset (nth 1 sig-data))
-                                    (let ((off-data (cons noffset 0)))
-                                      (push off-data (nth 1 sig-data))
-                                      off-data))))
-                          (cl-assert (>= (cdr ooff-data) count))
-                          (cl-decf (cdr ooff-data) count)
-                          (cl-incf (cdr noff-data) count))))))))))
-        (message "Guessing...done")
-        rules))))
+      (prog1
+         (smie-config--guess-1 sigs)
+        (message "Guessing...done")))))
+
+(defun smie-config--guess-1 (sigs)
+  (let ((ssigs nil)
+        (rules nil))
+    ;; Sort the sigs by frequency of occurrence.
+    (maphash (lambda (sig sig-data) (push (cons sig sig-data) ssigs)) sigs)
+    (setq ssigs (sort ssigs (lambda (sd1 sd2) (> (cadr sd1) (cadr sd2)))))
+    (while ssigs
+      (pcase-let ((`(,sig ,total ,off-alist ,cotraces) (pop ssigs)))
+        (cl-assert (= total (apply #'+ (mapcar #'cdr off-alist))))
+        (let* ((sorted-off-alist
+                (sort off-alist (lambda (x y) (> (cdr x) (cdr y)))))
+               (offset (caar sorted-off-alist)))
+          (if (zerop offset)
+              ;; Nothing to do with this sig; indentation is
+              ;; correct already.
+              nil
+            (push (cons (+ offset (nth 2 sig)) sig) rules)
+            ;; Adjust the rest of the data.
+            (pcase-dolist ((and cotrace `(,count ,toffset . ,trace))
+                           cotraces)
+              (setf (nth 1 cotrace) (- toffset offset))
+              (dolist (sig trace)
+                (let ((sig-data (cdr (assq sig ssigs))))
+                  (when sig-data
+                    (let* ((ooff-data (assq toffset (nth 1 sig-data)))
+                           (noffset (- toffset offset))
+                           (noff-data
+                            (or (assq noffset (nth 1 sig-data))
+                                (let ((off-data (cons noffset 0)))
+                                  (push off-data (nth 1 sig-data))
+                                  off-data))))
+                      (cl-assert (>= (cdr ooff-data) count))
+                      (cl-decf (cdr ooff-data) count)
+                      (cl-incf (cdr noff-data) count))))))))))
+    rules))
 
 (defun smie-config-guess ()
   "Try and figure out this buffer's indentation settings.