Another useful Emacs function - Balanced Comments
Friday, December 5, 2003
Here's another Emacs Lisp function that I find useful when programming in Scheme or CL:
(defun insert-balanced-comments (arg) "Insert a set of balanced comments around the s-expression containing the point. If this command is invoked repeatedly (without any other command occurring between invocations), the comment progressively moves outward over enclosing expressions." (interactive "*p") (save-excursion (when (eq last-command this-command) (when (search-backward "#|" nil t) (save-excursion (delete-char 2) (while (and (< (point) (point-max)) (not (looking-at " *|#"))) (forward-sexp)) (replace-match "")))) (while (> arg 0) (backward-char 1) (cond ((looking-at ")") (incf arg)) ((looking-at "(") (decf arg)))) (insert "#|") (forward-sexp) (insert "|#")))This is code that was adapted from code originally written by Paul Foley. It comments out an s-expression using multi-line comments. I bind the comment function to "C-c ;" and the un-comment function to "C-c :" with the following:(defun remove-balanced-comments () "Remove a set of balanced comments enclosing point." (interactive "*") (save-excursion (when (search-backward "#|" nil t) (delete-char 2) (while (and (< (point) (point-max)) (not (looking-at " *|#"))) (forward-sexp)) (replace-match ""))))
(add-hook 'scheme-mode-hook (lambda () (interactive) (define-key scheme-mode-map [(control c) (;)] 'insert-balanced-comments) (define-key scheme-mode-map [(control c) (:)] 'remove-balanced-comments)))Here are the rules:
- When the insert-balanced-comments function is invoked, it will comment out the s-expression that the cursor is enclosed in.
- If the function is evoked again immediately afterwards, the comment will move out an s-expression.
- If a prefix key is used, it will comment out the s-expression that is "prefix-argument" away from the cursor.
- When the remove-balanced-comments function is invoked, it will un-comment the nearest enclosing s-expression.
;; assume in all the following examples that the cursor is on the "4" (+ 1 (+ 2 (+ 3 4)));; after pressing "C-c ;" this is the result: (+ 1 (+ 2 #|(+ 3 4)|#))
;; press "C-c ;" again and the comment moves "outwards" (+ 1 #|(+ 2 (+ 3 4))|#)
;; alternatively, you could have just pressed "C-u 2 C-c ;" (+ 1 #|(+ 2 (+ 3 4))|#)
;; pressing "C-c :" removes the comment (+ 1 (+ 2 (+ 3 4)))

