[plt-scheme] Re: Useful Emacs code when working with PLT Scheme

From: Eli Barzilay (eli at barzilay.org)
Date: Mon Dec 8 01:00:01 EST 2003

On Dec  7, Bill Clementson wrote:
> Although it is true that the "#;" syntax does the same
> thing as "#|...|#" (but without a closing comment
> delimiter), the insert-balanced-comment function
> allows you to comment out an enclosing s-expression
> without moving to the start of the s-expression (or
> comment out a higher-level enclosing s-expression with
> a prefix arg or a repeat of the command). If one
> prefered the "#;" syntax over the "#|...|#" syntax,
> the function could be easily modified to use that
> instead.

I think it is preferable, but over the years I found that learning new
keys for new tricks is really expensive -- so I settle for a good
keyboard macro when repetitious tasks are involved, otherwise, I'd
just go to the beginning of the expression...

> A minor issue if one chose to do this would
> be that they would have to add a font-lock regexp to
> cater for "#;" style comments. 

Well, that would be hard, since it's not a simple regexp...

> Are there any snippets that are Scheme (or PLT)
> specific that you would like to share? I am always on
> the lookout for things that make my life easier. :-)

Well, below I have something that might be useful -- I use it to edit
Swindle documentation comments.  If you're in a line with a ";;>"
prefix and use it, it will copy the ";;>" region to a new buffer
(linked to the old one via hooks) that lets you edit the comment text
in text mode.

> Incidentally, I thought that your electric-not.el code
> was very time-saving; however, I am most interested in
> Scheme-specific code snippets.

(If you're looking at these things, then you should see macro-keys for
something really useful.)

;; Code for editing Swindle comments
(defvar swindle-comment-prefix ";;>")
(defvar swindle-comment-text nil)
(defvar swindle-edit-comment-data nil)
(defun swindle-edit-comment ()
  (if swindle-edit-comment-data
    (let* ((data    swindle-edit-comment-data)
           (text    (buffer-substring-no-properties (point-min) (point-max)))
           (origbuf (nth 0 data))
           (origtxt (nth 1 data))
           (beg     (nth 2 data))
           (end     (nth 3 data))
           (wconf   (nth 4 data))
           (offset  (swindle-edit-comment-sync)))
      (let ((kill-buffer-hook kill-buffer-hook))
        (remove-hook 'kill-buffer-hook 'swindle-edit-comment-killed)
        (setq buffer-file-name nil)
        (kill-buffer (current-buffer)))
      (set-window-configuration wconf)
      (switch-to-buffer origbuf)
      (goto-char (+ beg offset)))
    (let ((wconf   (current-window-configuration))
          (oldbuf  (current-buffer))
          (newbuf  (get-buffer-create (concat (buffer-name) ": *comment* ")))
          (modif   (buffer-modified-p))
          (p (point)) beg end text origtext)
      (forward-line 0)
      (when (looking-at swindle-comment-prefix)
        (while (and (not (bobp)) (looking-at swindle-comment-prefix))
          (forward-line -1))
        (unless (looking-at swindle-comment-prefix)
          (forward-line 1)))
      (setq beg (point-marker))
      (goto-char p)
      (forward-line 0)
      (while (and (not (eobp)) (looking-at swindle-comment-prefix))
        (forward-line 1))
      (setq end (point-marker))
      (goto-char p)
      (setq origtext (buffer-substring-no-properties beg end))
        (insert origtext)
        (goto-char (+ (- p beg) (point-min)))
        (let ((m (point-marker)) (re (concat "^" swindle-comment-prefix " ?")))
          (goto-char (point-min))
          (while (re-search-forward re nil t)
            (replace-match "" nil nil))
          (setq p (- m (point-min)) text (buffer-string))))
      (pop-to-buffer newbuf)
      (insert text)
      (auto-fill-mode 1)
      (setq fill-column 72)
      (set-buffer-modified-p modif)
      (set (make-local-variable 'swindle-edit-comment-data)
           (list oldbuf origtext beg end wconf))
      (setq buffer-file-name (buffer-name)) ; avoid asking for a name on save
      (add-hook 'local-write-file-hooks
                (lambda ()
                    (set-buffer (car swindle-edit-comment-data))
      (goto-char (+ p (point-min))))))
(defun swindle-edit-comment-sync ()
  (if swindle-edit-comment-data
    (let* ((data    swindle-edit-comment-data)
           (text    (buffer-substring-no-properties (point-min) (point-max)))
           (offset  (- (point) (point-min)))
           (origbuf (nth 0 data))
           (origtxt (nth 1 data))
           (beg     (nth 2 data))
           (end     (nth 3 data)))
        (insert text)
        (goto-char (+ offset (point-min)))
        (let ((m (point-marker)))
          (goto-char (point-max))
          (unless (bolp) (insert "\n"))
          (goto-char (point-min))
          (while (and (re-search-forward "^" nil t) (not (eobp)))
            (insert swindle-comment-prefix)
            (unless (or (eolp) (eq (char-after) ?>)) (insert " ")))
          (setq offset (- m (point-min)) text (buffer-string))))
        (set-buffer origbuf)
          (unless (equal (buffer-substring-no-properties beg end) origtxt)
            (setq swindle-comment-text text)
            (error (concat "Comment contents modified -- abort.  "
                           "(Old text saved in `swindle-comment-text').")))
          (goto-char beg)
          (unless (equal origtxt text)
            (delete-region beg end)
            (insert text)
            (setcar (nthcdr 3 data) (point-marker)))
          (setcar (cdr data) text)))
      (set-buffer-modified-p nil)
    (error "This is not a swindle-edit-comment buffer")))
(add-hook 'kill-buffer-hook 'swindle-edit-comment-killed)
(defun swindle-edit-comment-killed ()
  (when swindle-edit-comment-data (swindle-edit-comment)))
(global-set-key [(control shift ?z)] 'swindle-edit-comment)

          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!

Posted on the users mailing list.