From 91ade3effdbf19b7d8793020a1c31a4ff791a58d Mon Sep 17 00:00:00 2001
From: Paul Nelson <ultrono@gmail.com>
Date: Wed, 4 Sep 2024 09:24:25 +0200
Subject: [PATCH] Add Ediff feature for copying all differences

* lisp/vc/ediff-util.el (ediff-diff-to-diff): With universal
prefix, copy all differences.

* doc/misc/ediff.texi (Quick Help Commands):
* etc/NEWS: (Lisp Changes in Emacs 31.1): Document the new
feature.
---
 doc/misc/ediff.texi   | 26 ++++++++++++++------------
 etc/NEWS              | 16 ++++++++++++++++
 lisp/vc/ediff-util.el | 29 +++++++++++++++++------------
 3 files changed, 47 insertions(+), 24 deletions(-)

diff --git a/doc/misc/ediff.texi b/doc/misc/ediff.texi
index 749025c870b..6afb38e3fae 100644
--- a/doc/misc/ediff.texi
+++ b/doc/misc/ediff.texi
@@ -489,15 +489,16 @@ Quick Help Commands
 @item a
 @kindex a
 @emph{In comparison sessions:}
-Copies the current difference region (or the region specified as the prefix
-to this command) from buffer A to buffer B@.
-Ediff saves the old contents of buffer B's region; it can
-be restored via the command @kbd{rb}, which see.
+Copies the current difference region (or the region specified as the
+prefix to this command, or @emph{all} regions with @kbd{C-u} prefix)
+from buffer A to buffer B@.  Ediff saves the old contents of buffer B's
+region; it can be restored via the command @kbd{rb}, which see.
 
 @emph{In merge sessions:}
-Copies the current difference region (or the region specified as the prefix
-to this command) from buffer A to the merge buffer.  The old contents of
-this region in buffer C can be restored via the command @kbd{r}.
+Copies the current difference region (or the region specified as the
+prefix to this command, or @emph{all} regions with @kbd{C-u} prefix)
+from buffer A to the merge buffer.  The old contents of this region in
+buffer C can be restored via the command @kbd{r}.
 
 @item b
 @kindex b
@@ -511,11 +512,12 @@ Quick Help Commands
 
 @item ab
 @kindex ab
-Copies the current difference region (or the region specified as the prefix
-to this command) from buffer A to buffer B@.  This (and the next five)
-command is enabled only in sessions that compare three files
-simultaneously.  The old region in buffer B is saved and can be restored
-via the command @kbd{rb}.
+Copies the current difference region (or the region specified as the
+prefix to this command, or @emph{all} regions with @kbd{C-u} prefix)
+from buffer A to buffer B@.  This (and the next five) command is enabled
+only in sessions that compare three files simultaneously.  The old
+region in buffer B is saved and can be restored via the command
+@kbd{rb}.
 @item ac
 @kindex ac
 Copies the difference region from buffer A to buffer C@.
diff --git a/etc/NEWS b/etc/NEWS
index f10f9ae4d65..a6db0c96288 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -121,6 +121,22 @@ A new ':authorizable t' parameter has been added to 'dbus-call-method'
 and 'dbus-call-method-asynchronously' to allow the user to interactively
 authorize the invoked D-Bus method (e.g., via polkit).
 
++++
+** Ediff's copy commands now apply to all changes with 'C-u' prefix.
+The Ediff copy commands, bound to 'a', 'b', 'ab', etc., now copy all
+changes when supplied with a universal prefix argument via 'C-u':
+
+- 'C-u a' copies all changes from buffer A to buffer B (in 2-way diff)
+  or to buffer C (in 3-way diff or merge).
+- 'C-u b' copies all changes from buffer B to buffer A (in 2-way diff)
+  or to buffer C (in 3-way diff or merge).
+- 'C-u a b' copies all changes from buffer A to buffer B.
+- 'C-u b a' copies all changes from buffer B to buffer A.
+- 'C-u a c' copies all changes from buffer A to buffer C.
+- 'C-u b c' copies all changes from buffer B to buffer C.
+- 'C-u c a' copies all changes from buffer C to buffer A.
+- 'C-u c b' copies all changes from buffer C to buffer B.
+
 
 * Changes in Emacs 31.1 on Non-Free Operating Systems
 
diff --git a/lisp/vc/ediff-util.el b/lisp/vc/ediff-util.el
index 597d8a5e643..c2cdf7d4e5e 100644
--- a/lisp/vc/ediff-util.el
+++ b/lisp/vc/ediff-util.el
@@ -1891,7 +1891,7 @@ ediff-diff-at-point
 (defun ediff-diff-to-diff (arg &optional keys)
   "Copy buffer-X'th difference region to buffer Y (X,Y are A, B, or C).
 With numerical prefix argument ARG, copy the difference specified
-in the arg.
+in the arg.  With prefix `C-u', copy all differences.
 Otherwise, copy the difference given by `ediff-current-difference'.
 This command assumes it is bound to a 2-character key sequence, `ab', `ba',
 `ac', etc., which is used to determine the types of buffers to be used for
@@ -1904,17 +1904,22 @@ ediff-diff-to-diff
   (interactive "P")
   (ediff-barf-if-not-control-buffer)
   (or keys (setq keys (this-command-keys)))
-  (if (eq arg '-) (setq arg -1)) ; translate neg arg to -1
-  (if (numberp arg) (ediff-jump-to-difference arg))
-
-  (let* ((char1 (aref keys 0))
-	 (char2 (aref keys 1))
-	 ediff-verbose-p)
-    (ediff-copy-diff ediff-current-difference
-		     (ediff-char-to-buftype char1)
-		     (ediff-char-to-buftype char2))
-    ;; recenter with rehighlighting, but no messages
-    (ediff-recenter)))
+  (if (equal arg '(4))
+      ;; copy all differences with `C-u' prefix
+      (let ((n 0))
+        (while (ediff-valid-difference-p n)
+          (ediff-diff-to-diff (1+ n) keys)
+          (setq n (1+ n))))
+    (if (eq arg '-) (setq arg -1))      ; translate neg arg to -1
+    (if (numberp arg) (ediff-jump-to-difference arg))
+    (let* ((char1 (aref keys 0))
+	   (char2 (aref keys 1))
+	   ediff-verbose-p)
+      (ediff-copy-diff ediff-current-difference
+		       (ediff-char-to-buftype char1)
+		       (ediff-char-to-buftype char2))
+      ;; recenter with rehighlighting, but no messages
+      (ediff-recenter))))
 
 (defun ediff-copy-A-to-B (arg)
   "Copy ARGth difference region from buffer A to B.
-- 
2.39.3 (Apple Git-145)

