scratch/undo-apply d8aeff97494 2/3: Improve undo-in-region support for diff-unified->context
Helmut Eller <[email protected]> Sun, 26 Jul 2026 12:56:32 -0400 (EDT)
| Newsgroups | gmane.emacs.diffs |
|---|---|
| Message-ID | <[email protected]> |
branch: scratch/undo-apply commit d8aeff97494d80ebdaf48a2ca4a83bb1fbd705ad Author: Helmut Eller <[email protected]> Commit: Helmut Eller <[email protected]> Improve undo-in-region support for diff-unified->context * lisp/vc/diff-mode.el (diff-unified->context, diff-context->unified): Use the new 'apply variant for buffer-undo-list entries. --- lisp/vc/diff-mode.el | 10 ++-- test/lisp/vc/diff-mode-tests.el | 115 +++++++++++++++++++++++++++++++++++----- 2 files changed, 109 insertions(+), 16 deletions(-) diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index c27abda1af9..6db3d4bb803 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -1399,8 +1399,9 @@ else cover the whole buffer." ;; a single entry that uses diff-context->unified to do ;; the work. (setq buffer-undo-list - (cons (list 'apply (- old-end end) start (point-max) - 'diff-context->unified start (point-max)) + (cons (list 'apply (- old-end end) + (cons start (point-max)) + 'diff-context->unified) old-undo))))))))))) (defun diff-context->unified (start end &optional to-context) @@ -1497,8 +1498,9 @@ With a prefix argument, convert unified format to context format." ;; of undo elements with just a single special one. (unless (or (not reversible) (eq buffer-undo-list t)) (setq buffer-undo-list - (cons (list 'apply (- old-end end) pt1 (point) - 'diff-unified->context pt1 (point)) + (cons (list 'apply (- old-end end) + (cons pt1 (point)) + 'diff-unified->context) old-undo))) ))))))))) diff --git a/test/lisp/vc/diff-mode-tests.el b/test/lisp/vc/diff-mode-tests.el index 875f5cf8bfe..13cb81eaa10 100644 --- a/test/lisp/vc/diff-mode-tests.el +++ b/test/lisp/vc/diff-mode-tests.el @@ -846,20 +846,111 @@ index 0000000..3456789 ") (ert-deftest diff-mode-tests-undo-unified->context () + (let* ((unified diff-mode-tests--unified-patch) + (context diff-mode-tests--context-patch)) + (pcase-dolist (`(,convert ,v1 ,v2) + `((,#'diff-unified->context ,unified ,context) + (,#'diff-context->unified ,context ,unified))) + (let ((b (generate-new-buffer "test.diff"))) + (unwind-protect + (with-current-buffer b + (insert v1) + (diff-mode) + (undo-boundary) + (funcall convert (point-min) (point-max)) + (should (equal (buffer-string) v2)) + (undo-boundary) + (undo) + (should (equal (buffer-string) v1))) + (kill-buffer b)))))) + +(defvar diff-mode-tests--selective-undo-patch-1 + "--- /tmp/a.el 2026-07-14 08:27:52.751202012 +0200 ++++ /tmp/b.el 2026-07-14 08:28:01.087191220 +0200 +@@ -2,7 +2,7 @@ (defun foo () + x + y + z +- a) ++ b) + ;; + ;; + ;; +*************** (defun bar () +*** 19,22 **** + x + y + z +! aa) +--- 19,22 ---- + x + y + z +! bb) +") + +(defvar diff-mode-tests--selective-undo-patch-2 + "*** /tmp/a.el 2026-07-14 08:27:52.751202012 +0200 +--- /tmp/b.el 2026-07-14 08:28:01.087191220 +0200 +*************** (defun foo () +*** 2,8 **** + x + y + z +! a) + ;; + ;; + ;; +--- 2,8 ---- + x + y + z +! b) + ;; + ;; + ;; +@@ -19,4 +19,4 @@ (defun bar () + x + y + z +- aa) ++ bb) +") + +(defun diff-mode-tests--mark-region (beg end) + (transient-mark-mode 1) + (goto-char beg) + (push-mark (point) t t) + (setq mark-active t) + (goto-char end)) + +(ert-deftest diff-mode-tests-selective-undo () (let* ((unified diff-mode-tests--unified-patch) (context diff-mode-tests--context-patch) - (b (generate-new-buffer "test.diff"))) - (unwind-protect - (with-current-buffer b - (insert unified) - (diff-mode) - (undo-boundary) - (diff-unified->context (point-min) (point-max)) - (should (equal (buffer-string) context)) - (undo-boundary) - (undo) - (should (equal (buffer-string) unified))) - (kill-buffer b)))) + (mixed-1 diff-mode-tests--selective-undo-patch-1) + (mixed-2 diff-mode-tests--selective-undo-patch-2)) + (pcase-dolist (`(,convert ,v1 ,v2 ,v3) + `((,#'diff-unified->context ,unified ,context ,mixed-1) + (,#'diff-context->unified ,context ,unified ,mixed-2))) + (let ((b (generate-new-buffer "test.diff"))) + (unwind-protect + (with-current-buffer b + (insert v1) + (diff-mode) + (undo-boundary) + (funcall convert (point-min) (point-max)) + (should (equal (buffer-string) v2)) + (goto-char (point-min)) + (re-search-forward "(defun foo ()") + (replace-match "(defun baz ()") + (goto-char (point-min)) + (should (not (re-search-forward "(defun foo ()" nil t))) + (re-search-forward (regexp-quote "(defun bar ()")) + (diff-mode-tests--mark-region (point-min) (point)) + (undo-boundary) + (undo) + (should (equal (buffer-string) v3))) + (kill-buffer b)))))) (provide 'diff-mode-tests) ;;; diff-mode-tests.el ends here