]> git.eshelyaron.com Git - emacs.git/commitdiff
Add refactor backend for 'emacs-lisp-mode'
authorEshel Yaron <me@eshelyaron.com>
Thu, 8 Aug 2024 17:10:50 +0000 (19:10 +0200)
committerEshel Yaron <me@eshelyaron.com>
Sun, 11 Aug 2024 07:19:07 +0000 (09:19 +0200)
lisp/progmodes/elisp-mode.el
lisp/progmodes/refactor-elisp.el [new file with mode: 0644]
lisp/progmodes/refactor.el

index 95633bd248fb892023d79fd5910a5592132caf6c..3c9f80d7c4b3eddde49d638de857ddb478244732 100644 (file)
@@ -369,6 +369,7 @@ be used instead.
   (add-hook 'flymake-diagnostic-functions #'elisp-flymake-checkdoc nil t)
   (add-hook 'flymake-diagnostic-functions
               #'elisp-flymake-byte-compile nil t)
+  (add-hook 'refactor-backend-functions #'elisp-refactor-backend nil t)
   (add-hook 'context-menu-functions #'elisp-context-menu 10 t))
 
 ;; Font-locking support.
diff --git a/lisp/progmodes/refactor-elisp.el b/lisp/progmodes/refactor-elisp.el
new file mode 100644 (file)
index 0000000..fb6310d
--- /dev/null
@@ -0,0 +1,59 @@
+;;; refactor-elisp.el --- Refactoring backend for Emacs Lisp   -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2024  Eshel Yaron
+
+;; Author: Eshel Yaron <me@eshelyaron.com>
+;; Keywords: tools
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'refactor)
+
+;;;###autoload
+(defun elisp-refactor-backend () '(elisp rename))
+
+(cl-defmethod refactor-backend-read-scoped-identifier ((_backend (eql elisp)))
+  (let ((all (scope (save-excursion
+                      (beginning-of-defun)
+                      (read-positioning-symbols (current-buffer))))))
+    (seq-some
+     (pcase-lambda (`(,beg ,len ,bin))
+       (and bin (<= beg (point) (+ beg len))
+            (list (buffer-substring-no-properties beg (+ beg len)))))
+     all)))
+
+(cl-defmethod refactor-backend-rename-edits ((_backend (eql elisp)) _old new (_scope (eql nil)))
+  (let* ((all (scope (save-excursion
+                       (beginning-of-defun)
+                       (read-positioning-symbols (current-buffer)))))
+         (dec (seq-some
+               (pcase-lambda (`(,beg ,len ,bin))
+                 (when (<= beg (point) (+ beg len)) bin))
+               all)))
+    (list
+     (cons (current-buffer)
+           (seq-keep
+            (pcase-lambda (`(,beg ,len ,bin))
+              (when (equal bin dec)
+                (list beg (+ beg len) new)))
+            all)))))
+
+(provide 'refactor-elisp)
+;;; refactor-elisp.el ends here
index 108f98432efa16d4c4b1e215f2bc06b9c9fbf579..560e98feff249056386baf5aedb23aa0988a9f84 100644 (file)
@@ -73,9 +73,9 @@ The default value is the string \"Renaming \\\"%o\\\" to \\\"%n\\\" in %s.\""
   "Special hook for choosing a refactor backend to use in the current context.
 
 Each function on this hook is called in turn with no arguments, and
-should return either nil to mean that it is not applicable, or a cons
-cell (BACKEND . OPS) where BACKEND refactor backend, a value used for
-dispatching the generic functions, and OPS is a list of refactoring
+should return either nil to say that it is not applicable, or a cons
+cell (BACKEND . OPS) where BACKEND is a refactor backend, a value used
+for dispatching the generic functions, and OPS is a list of refactoring
 operations that BACKEND supports.")
 
 (defun refactor-backends ()
@@ -221,7 +221,7 @@ argument is the token corresponding to that text replacement.")
   (dolist (buffer-reps edits)
     (with-current-buffer (car buffer-reps)
       (atomic-change-group
-        (let* ((change-group (prepare-change-group)))
+        (let ((change-group (prepare-change-group)))
           (refactor--apply-replacements (cdr buffer-reps))
           (undo-amalgamate-change-group change-group))))))