Function: smie-close-block
smie-close-block is an interactive and byte-compiled function defined
in smie.el.gz.
Signature
(smie-close-block)
Documentation
Close the closest surrounding block.
Key Bindings
Source Code
;; Defined in /usr/src/emacs/lisp/emacs-lisp/smie.el.gz
(defun smie-close-block ()
"Close the closest surrounding block."
(interactive)
(let ((closer
(save-excursion
(backward-up-list 1)
(if (looking-at "\\s(")
(string (cdr (syntax-after (point))))
(let* ((open (funcall smie-forward-token-function))
(closer (cdr (assoc open smie-closer-alist)))
(levels (list (assoc open smie-grammar)))
(seen '())
(found '()))
(cond
;; Even if we improve the auto-computation of closers,
;; there are still cases where we need manual
;; intervention, e.g. for Octave's use of `until'
;; as a pseudo-closer of `do'.
(closer)
((or (equal levels '(nil)) (numberp (nth 1 (car levels))))
(error "Doesn't look like a block"))
(t
;; Now that smie-setup automatically sets smie-closer-alist
;; from the BNF, this is not really needed any more.
(while levels
(let ((level (pop levels)))
(dolist (other smie-grammar)
(when (and (eq (nth 2 level) (nth 1 other))
(not (memq other seen)))
(push other seen)
(if (numberp (nth 2 other))
(push other levels)
(push (car other) found))))))
(cond
((null found) (error "No known closer for opener %s" open))
;; What should we do if there are various closers?
(t (car found))))))))))
(unless (save-excursion (skip-chars-backward " \t") (bolp))
(newline))
(insert closer)
(if (save-excursion (skip-chars-forward " \t") (eolp))
(indent-according-to-mode)
(reindent-then-newline-and-indent))))