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))))