Function: smie-config--guess
smie-config--guess is a byte-compiled function defined in smie.el.gz.
Signature
(smie-config--guess BEG END)
Source Code
;; Defined in /usr/src/emacs/lisp/emacs-lisp/smie.el.gz
(defun smie-config--guess (beg end)
(let ((otraces (make-hash-table :test #'equal))
(smie-config--buffer-local nil)
(smie-config--mode-local nil)
(pr (make-progress-reporter "Analyzing the buffer" beg end)))
;; First, lets get the indentation traces and offsets for the region.
(save-excursion
(goto-char beg)
(forward-line 0)
(while (< (point) end)
(skip-chars-forward " \t")
(unless (eolp) ;Skip empty lines.
(progress-reporter-update pr (point))
(let* ((itrace (smie-config--get-trace))
(nindent (car itrace))
(trace (mapcar #'cdr (cdr itrace)))
(cur (current-indentation)))
(when (numberp nindent) ;Skip `noindent' and friends.
(incf (gethash (cons (- cur nindent) trace) otraces 0)))))
(forward-line 1)))
(progress-reporter-done pr)
;; Second, compile the data. Our algorithm only knows how to adjust rules
;; where the smie-rules-function returns an integer. We call those
;; "adjustable sigs". We build a table mapping each adjustable sig
;; to its data, describing the total number of times we encountered it,
;; the offsets found, and the traces in which it was found.
(message "Guessing...")
(let ((sigs (make-hash-table :test #'equal)))
(maphash (lambda (otrace count)
(let ((offset (car otrace))
(trace (cdr otrace))
(double nil))
(let ((sigs trace))
(while sigs
(let ((sig (pop sigs)))
(if (and (integerp (nth 2 sig)) (member sig sigs))
(setq double t)))))
(if double
;; Disregard those traces where an adjustable sig
;; appears twice, because the rest of the code assumes
;; that adding a rule to add an offset N will change the
;; end result by N rather than 2*N or more.
nil
(dolist (sig trace)
(if (not (integerp (nth 2 sig)))
;; Disregard those sigs that return nil or a column,
;; because our algorithm doesn't know how to adjust
;; them anyway.
nil
(let ((sig-data (or (gethash sig sigs)
(let ((data (list 0 nil nil)))
(puthash sig data sigs)
data))))
(incf (nth 0 sig-data) count)
(push (cons count otrace) (nth 2 sig-data))
(let ((sig-off-data
(or (assq offset (nth 1 sig-data))
(let ((off-data (cons offset 0)))
(push off-data (nth 1 sig-data))
off-data))))
(incf (cdr sig-off-data) count))))))))
otraces)
;; Finally, guess the indentation rules.
(prog1
(smie-config--guess-1 sigs)
(message "Guessing...done")))))