[slime-devel] renaming symbols locally

Nikodemus Siivola nikodemus at random-state.net
Sat Jun 27 12:04:49 UTC 2009


I got fed up doing this manually, and wrote the following. I'm know
there are pre-existing versions and this isn't probably the best one,
but it has one feature I missed: it checks for conflict potential
before starting the renaming.

Something like this would be nice to have in Slime, I think. Is there
a contrib that would be appropriate for this? Also, this is way too
deep in elisp-land for me to feel quite confident that this is a sane
way to do this.

(defun ns:slime-rename-symbol-in-defun (old new)
  "Replace `old' with `new' in the current defun."
  (interactive "sSymbol to replace: \nsSymbol to replace with: ")
  (catch 'abort
    (let ((count 0))
      (save-excursion
        (destructuring-bind (start end) (slime-region-for-defun-at-point)
          ;; First scan to see if we have conflicts...
          (let ((size (length new))
                (p start))
            (goto-char start)
            ;; KLUDGE: no forward-op for slime-symbols, but this gets most
            ;; things right when used with SLIME-SYMBOL-AT-POINT.
            (forward-thing 'symbol)
            (loop while (and (< (point) end) (> (point) p))
                  do
                  (let ((symbol (slime-symbol-at-point)))
                    (when (equalp symbol new)
                      (slime-beginning-of-symbol)
                      (when (ns:slime-highlight-y-or-n-p
                             (format "Pre-existing %s, abort? " new)
                             (point) (+ (point) size))
                        (throw 'abort nil))
                      (slime-end-of-symbol)))
                  (setf p (point))
                  (forward-thing 'symbol)))
          ;; ...then scan again to replace.
          (let ((size (length old))
                (p start))
            (goto-char start)
            (forward-thing 'symbol)
            (loop while (and (< (point) end) (> (point) p))
                  do
                  (let ((symbol (slime-symbol-at-point)))
                    (when (equalp symbol old)
                      (slime-beginning-of-symbol)
                      (when (ns:slime-highlight-y-or-n-p
                             "Rename? " (point) (+ (point) size))
                        (delete-char size)
                        (insert-string new)
                        (incf count))
                      (slime-end-of-symbol)))
                  (setf p (point))
                  (forward-thing 'symbol))))
        (message "%d occurrances of %s replaced with %s" count old new)
        t))))

(defun ns:slime-highlight-y-or-n-p (string start end)
  "Ask a y-or-n-p question using `string' with the region delimited by `start'
and `end' highlighted."
  (let (hilite)
    (unwind-protect
        (progn
          (setf hilite (make-overlay start end))
          (overlay-put hilite 'face 'slime-highlight-face)
          (y-or-n-p string))
      (when hilite
        (delete-overlay hilite)))))

Cheers,

 -- Nikodemus




More information about the slime-devel mailing list