[slime-devel] close-all-sexp for SLIME
Michael Weber
michaelw+slime at foldr.org
Mon Jan 19 10:17:34 UTC 2004
Hi,
Attached is a function for SLIME which when run automatically balances
all open sexps at point. It is similar to ILISP's CLOSE-ALL-LISP,
which is bound to C-c ] or M-], I think, but smaller and easier to
understand.
It is a little smarter than C-<Ret> in slime-repl, handles comments,
reformats trailing right parens into one line, and DWIM when a region
is active.
Strings are not yet handled because it can be quite costly, I think.
Take it if you like it :) (License is same as SLIME.)
Cheers,
Michael
--
/~\ ASCII ribbon | "If we knew what it was we were doing, it would not be
\ / campaign | called research, would it?"
X against | -- Albert Einstein
/ \ HTML mail |
-------------- next part --------------
(defvar *slime-comment-start-regexp*
"\\(\\(^\\|[^\n\\\\]\\)\\([\\\\][\\\\]\\)*\\);+[ \t]*"
"Regexp to match the start of a comment.")
(defun slime-beginning-of-comment ()
"Move point to beginning of comment.
If point is inside a comment move to beginning of comment and return point.
Otherwise leave point unchanged and return NIL."
(let ((boundary (point)))
(beginning-of-line)
(cond ((re-search-forward *slime-comment-start-regexp* boundary t)
(point))
(t (goto-char boundary)
nil))))
(defun slime-close-all-sexp (&optional beg end)
"Balance parentheses of open s-expressions at point.
Insert enough right parentheses to balance unmatched left parentheses.
Delete extra left parentheses. Reformat trailing parentheses
Lisp-stylishly.
If buffer positions BEG and END are given, operate on this region.
Otherwise, if region is active, operate on region.
Otherwise, bound operation by top-level s-expressions or comment at
first column."
(interactive)
(let ((sexp-level 0)
point)
(save-excursion
(save-restriction
;; operate on region if active
(ignore-errors
(narrow-to-region (or beg (mark)) (or end (point)))
(goto-char (point-max)))
;; skip over closing parens, but not into comment
(skip-chars-backward ") \t\n")
(when (slime-beginning-of-comment)
(forward-line)
(skip-chars-forward " \t"))
(setq point (point))
;; count sexps until either '(' or comment is found at first column
(while (and (not (looking-at "^[(;]"))
(ignore-errors (backward-up-list 1) t))
(incf sexp-level))))
(when (> sexp-level 0)
;; insert correct number of right parens
(goto-char point)
(dotimes (i sexp-level) (insert ")"))
;; delete extra right parens
(setq point (point))
(skip-chars-forward " \t\n)")
(skip-chars-backward " \t\n")
(delete-region point (point)))))
More information about the slime-devel
mailing list