Subject: bug#58516: 28.1; add option/key to rerun current diff without whitespace changes

From: Robert Pluim <[email-masked]>
Date: Mon, 17 Oct 2022 14:27:42 +0200

>>>>> On Fri, 14 Oct 2022 18:51:42 +0200, Daniel Martín via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <[email-masked]> said:

    Daniel> Robert Pluim <[email-masked]> writes:
    >> 
    >> Something like this, perhaps. I stuck it on a separate key, but we
    >> could put it on "C-u C-c C-w" instead.
    >> 

    Daniel> Looks good.  I agree that using a prefix argument is a better idea to
    Daniel> save some key bindings.

Hey, there are *loads* of bindings available. "C-c C-ｗ" anyone? 😺

Comments welcome

Robert
-- 
>From 8192b0ac043ce2f79189ec5473ad390fe0371dd8 Mon Sep 17 00:00:00 2001
From: Robert Pluim <[email-masked]>
Date: Mon, 17 Oct 2022 14:18:23 +0200
Subject: [PATCH] Teach 'diff-ignore-whitespace-hunk' how to regenerate all
 hunks
To: [email-masked]

This implements the request from Bug#58516.

* lisp/vc/diff-mode.el (diff-ignore-whitespace-hunk): Regenerate all
the hunks when called with a prefix arg.
(diff--iterate-hunks): Add optional arg for start of iteration.
(diff--ignore-whitespace-all-hunks): Iterate over all hunks, regenerate
ignoring whitespace.

* doc/emacs/files.texi (Diff Mode): Describe change in behaviour.
* etc/NEWS: Announce the change.
---
 doc/emacs/files.texi |  3 ++-
 etc/NEWS             |  6 ++++++
 lisp/vc/diff-mode.el | 21 ++++++++++++++++-----
 3 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi
index 1717c5c25b..7f8a30e9d9 100644
--- a/doc/emacs/files.texi
+++ b/doc/emacs/files.texi
@@ -1728,7 +1728,8 @@ Diff Mode
 
 @item C-c C-w
 @findex diff-ignore-whitespace-hunk
-Re-generate the current hunk, disregarding changes in whitespace
+Re-generate the current hunk, disregarding changes in whitespace.
+With a non-@code{nil} prefix arg, re-generate all the hunks
 (@code{diff-ignore-whitespace-hunk}).
 
 @item C-x 4 A
diff --git a/etc/NEWS b/etc/NEWS
index ca857056fd..8d8f1e3b7b 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1507,6 +1507,12 @@ Sets the value of the buffer-local variable 'whitespace-style' in
 'diff-mode' buffers.  By default, this variable is '(face trailing)',
 which preserves behavior from previous Emacs versions.
 
++++
+*** 'diff-ignore-whitespace-hunk' can now be applied to all hunks.
+When called with a non-nil prefix argument
+'diff-ignore-whitespace-hunk' now iterates over all the hunks in the
+current diff, regenerating them without whitespace changes.
+
 +++
 *** New user option 'diff-add-log-use-relative-names'.
 If non-nil insert file names in ChangeLog skeletons relative to the
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index a9591c9d82..5a8d25800c 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -2102,10 +2102,13 @@ diff-current-defun
               (goto-char (+ (car pos) (cdr src)))
               (add-log-current-defun)))))))
 
-(defun diff-ignore-whitespace-hunk ()
-  "Re-diff the current hunk, ignoring whitespace differences."
-  (interactive)
-  (diff-refresh-hunk t))
+(defun diff-ignore-whitespace-hunk (whole-buffer)
+  "Re-diff the current hunk, ignoring whitespace differences.
+With non-nil prefix arg, re-diff all the hunks."
+  (interactive "P")
+  (if whole-buffer
+      (diff--ignore-whitespace-all-hunks)
+    (diff-refresh-hunk t)))
 
 (defun diff-refresh-hunk (&optional ignore-whitespace)
   "Re-diff the current hunk."
@@ -2275,10 +2278,12 @@ diff--refine-hunk
                                   (match-end 0) end
                                   nil #'diff-refine-preproc props-r props-a)))))))
 
-(defun diff--iterate-hunks (max fun)
+(defun diff--iterate-hunks (max fun &optional min)
   "Iterate over all hunks between point and MAX.
 Call FUN with two args (BEG and END) for each hunk."
   (save-excursion
+      (when min
+      (goto-char min))
     (catch 'malformed
       (let* ((beg (or (ignore-errors (diff-beginning-of-hunk))
                       (ignore-errors (diff-hunk-next) (point))
@@ -2298,6 +2303,12 @@ diff--iterate-hunks
                         (or (ignore-errors (diff-hunk-next) (point))
                             max)))))))))
 
+(defun diff--ignore-whitespace-all-hunks ()
+  "Re-diff all the hunks, ignoring whitespace-differences."
+  (diff--iterate-hunks (point-max) (lambda (_ _)
+                                     (diff-refresh-hunk t))
+                       (point-min)))
+
 (defun diff--font-lock-refined (max)
   "Apply hunk refinement from font-lock."
   (when (eq diff-refine 'font-lock)
-- 
2.37.1.116.g9dd64cb4d3