]> git.eshelyaron.com Git - emacs.git/commitdiff
Support displaying refactor edits as diff
authorEshel Yaron <me@eshelyaron.com>
Wed, 10 Apr 2024 19:31:56 +0000 (21:31 +0200)
committerEshel Yaron <me@eshelyaron.com>
Wed, 10 Apr 2024 19:31:56 +0000 (21:31 +0200)
lisp/progmodes/refactor.el
lisp/vc/diff.el

index 889789b348369a7dc1f0a4e85363d0179462d8a3..6ab2a9916096963326b8b753b6054f6a617cb8ca 100644 (file)
@@ -38,8 +38,8 @@
   "Function to use for applying edits during refactoring."
   :type '(choice (const :tag "Apply edits at once" refactor-apply-edits-at-once)
                  ;; TODO:
-                 ;; (const :tag "Display edits as diff" refactor-display-edits-as-diff)
                  ;; (const :tag "Query about each edit" refactor-query-apply-edits)
+                 (const :tag "Display edits as diff" refactor-display-edits-as-diff)
                  (function :tag "Custom function")))
 
 (defcustom refactor-read-operation-function
@@ -189,6 +189,18 @@ associated with this edit.  Depending on the value of
 `refactor-apply-edits-function', `refactor-rename' may display ANN when
 applying the relevant edit.")
 
+(defun refactor--apply-edits (edits)
+  (pcase-dolist (`(,beg ,end ,str . ,_) (sort edits :key #'cadr :reverse t))
+    (let ((source (current-buffer)))
+      (with-temp-buffer
+        (insert str)
+        (let ((temp (current-buffer)))
+          (with-current-buffer source
+            (save-excursion
+              (save-restriction
+                (narrow-to-region beg end)
+                (replace-buffer-contents temp)))))))))
+
 (defun refactor-apply-edits-at-once (edits)
   "Apply EDITS at once, without confirmation."
   (dolist (edit edits)
@@ -199,22 +211,35 @@ applying the relevant edit.")
     (with-current-buffer (car buffer-changes)
       (atomic-change-group
         (let* ((change-group (prepare-change-group)))
-          (dolist (change (sort (cdr buffer-changes) :key #'cadr :reverse t))
-            (pcase change
-              (`(,beg ,end ,str . ,_)
-               (let ((source (current-buffer)))
-                 (with-temp-buffer
-                   (insert str)
-                   (let ((temp (current-buffer)))
-                     (with-current-buffer source
-                       (save-excursion
-                         (save-restriction
-                           (narrow-to-region beg end)
-                           (replace-buffer-contents temp)))))))
-               ;; TODO - temporarly highlight replacement text.
-               )))
+          (refactor--apply-edits (cdr buffer-changes))
           (undo-amalgamate-change-group change-group))))))
 
+(defun refactor-display-edits-as-diff (edits)
+  "Display EDITS as a diff."
+  (dolist (edit edits)
+    (let ((file-or-buffer (car edit)))
+      (when (bufferp file-or-buffer)
+        (setcar edit (buffer-file-name file-or-buffer)))))
+  (with-current-buffer (get-buffer-create "*Refactor Diff*")
+    (buffer-disable-undo (current-buffer))
+    (setq buffer-read-only t)
+    (diff-mode)
+    (let ((inhibit-read-only t)
+          (target (current-buffer)))
+      (erase-buffer)
+      (pcase-dolist (`(,file . ,changes) edits)
+        (with-temp-buffer
+          (let* ((diff (current-buffer)))
+            (with-temp-buffer
+              (insert-file-contents file)
+              (refactor--apply-edits changes)
+              (diff-no-select file (current-buffer) nil t diff))
+            (with-current-buffer target (insert-buffer-substring diff))))))
+    (buffer-enable-undo (current-buffer))
+    (goto-char (point-min))
+    (pop-to-buffer (current-buffer))
+    (font-lock-ensure)))
+
 (defun refactor-apply-edits (edits)
   "Apply EDITS.
 
index a64fbc478539db44d0687e13228dfd92bd6604d1..3c64f8313a6ff656c6a274dd035661c6a99bc093 100644 (file)
@@ -149,6 +149,7 @@ Possible values are:
                    (call-process diff-command nil t nil "--help"))
              (if (search-backward "--label" nil t) t))))))
 
+;;;###autoload
 (defun diff-no-select (old new &optional switches no-async buf)
   ;; Noninteractive helper for creating and reverting diff buffers
   "Compare the OLD and NEW file/buffer.