Clementson's Blog

Bits and pieces (mostly Lisp-related) that I collect from the ether.

December 2003
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Nov  Jan

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

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

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:
(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:Probably better if I give an example. Given the following code:
;; 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)))

emacs Copyright © 2004 by Bill Clementson