emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Adding refactoring capabilities to Emacs


From: Juri Linkov
Subject: Re: Adding refactoring capabilities to Emacs
Date: Mon, 04 Sep 2023 20:15:32 +0300
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/30.0.50 (x86_64-pc-linux-gnu)

> If we had a better UI for renaming than query-replace, we could plug it
> into project-find-regexp and xref-find-references' output buffers.

Thanks for mentioning query-replace.  I wished query-replace could do
something like what 'd' does for previewing changes before saving
the buffer with 'C-x s':

```
    (?d ,(lambda (buf)
           (if (null (buffer-file-name buf))
               (message "Not applicable: no file")
             (require 'diff)            ;for diff-no-select.
             (let ((diffbuf (diff-no-select (buffer-file-name buf) buf
                                            nil 'noasync)))
```

And now Eglot does this for previewing renaming.

So below is a command that does the same for replace-string.
Instead of boringly typing a long sequence of y y y y y y y ...
to check if all replacements are correct, now it will be possible
to preview the diff buffer that will take much less time:

diff --git a/lisp/replace.el b/lisp/replace.el
index eeac734f3bd..a5704e6966f 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -691,6 +697,28 @@ replace-string
           (use-region-noncontiguous-p))))
   (perform-replace from-string to-string nil nil delimited nil nil start end 
backward region-noncontiguous-p))
 
+(defun replace-string-as-diff (from-string to-string &optional delimited start 
end backward region-noncontiguous-p)
+  (interactive (apply (cadr (interactive-form 'replace-string))))
+  (require 'diff)
+  (let ((file-name buffer-file-name)
+        (orig-buffer (current-buffer))
+        (diff-buffer (get-buffer-create "*replace-diff*")))
+    (with-current-buffer diff-buffer
+      (buffer-disable-undo (current-buffer))
+      (let ((inhibit-read-only t))
+       (erase-buffer))
+      (diff-mode))
+    (with-temp-buffer
+      (insert-buffer-substring orig-buffer)
+      (goto-char (point-min))
+      (perform-replace from-string to-string nil nil delimited nil nil start 
end backward region-noncontiguous-p)
+      (diff-no-select orig-buffer (current-buffer) nil t diff-buffer (concat 
file-name "~") file-name))
+    (with-current-buffer diff-buffer
+      (setq-local buffer-read-only t)
+      (buffer-enable-undo (current-buffer))
+      (font-lock-ensure))
+    (pop-to-buffer diff-buffer)))
+
 (defun replace-regexp (regexp to-string &optional delimited start end backward 
region-noncontiguous-p)
   "Replace things after point matching REGEXP with TO-STRING.
 Preserve case in each match if `case-replace' and `case-fold-search'
diff --git a/lisp/vc/diff.el b/lisp/vc/diff.el
index a411d98da31..a682b88976f 100644
--- a/lisp/vc/diff.el
+++ b/lisp/vc/diff.el
@@ -149,7 +149,7 @@ diff-check-labels
                    (call-process diff-command nil t nil "--help"))
              (if (search-backward "--label" nil t) t))))))
 
-(defun diff-no-select (old new &optional switches no-async buf)
+(defun diff-no-select (old new &optional switches no-async buf label-old 
label-new)
   ;; Noninteractive helper for creating and reverting diff buffers
   "Compare the OLD and NEW file/buffer.
 If the optional SWITCHES is nil, the switches specified in the
@@ -180,11 +180,13 @@ diff-no-select
                                   (and (or old-alt new-alt)
                                       (eq diff-use-labels t)
                                       (list "--label"
-                                            (if (stringp old) old
-                                              (prin1-to-string old))
+                                             (cond ((stringp old) old)
+                                                   ((stringp label-old) 
label-old)
+                                                   ((prin1-to-string old)))
                                             "--label"
-                                            (if (stringp new) new
-                                              (prin1-to-string new))))
+                                            (cond ((stringp new) new)
+                                                   ((stringp label-new) 
label-new)
+                                                  ((prin1-to-string new)))))
                                   (list (or old-alt old)
                                         (or new-alt new)))))
                     " "))

reply via email to

[Prev in Thread] Current Thread [Next in Thread]