From: Eshel Yaron Date: Wed, 10 Apr 2024 19:31:56 +0000 (+0200) Subject: Support displaying refactor edits as diff X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=f85e77e7a212efb7d09be920e2dadaa1fc2ebfa6;p=emacs.git Support displaying refactor edits as diff --- diff --git a/lisp/progmodes/refactor.el b/lisp/progmodes/refactor.el index 889789b3483..6ab2a991609 100644 --- a/lisp/progmodes/refactor.el +++ b/lisp/progmodes/refactor.el @@ -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. diff --git a/lisp/vc/diff.el b/lisp/vc/diff.el index a64fbc47853..3c64f8313a6 100644 --- a/lisp/vc/diff.el +++ b/lisp/vc/diff.el @@ -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.