"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
`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)
(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.