Subject: 28.0.50; PATCH: added new (diff-refresh-hunk) function

From: Dima Kogan <[email-masked]>
Date: Thu, 29 Oct 2020 12:56:50 -0700

Hi. Here's a patch to add a new function to diff-mode:
(diff-refresh-hunk). I'm binding it to "C-c C-l" because it "refreshes"
the hunk like C-l refreshes the screen. This is useful to me to throw
out no-op pieces of a hunk, which I often get after editing the
*vc-diff* buffer.

For instance, I might end up with this hunk:

@@ -298,12 +312,12 @@
         stuff
-        f(x);
+           f(x);
 
         more stuff

-        g(x);
+        g(x);

         stuff

I'd like to clean it up by throwing out the g(x) pieces, since they're
the same, but keeping the f(x) pieces since they differ. C-c C-w would
throw out both since it ignores whitespace differences, but the new C-c
C-l does what I want.

Thanks

>From ef3900e44b7d9e8771278de843887998cfddd48f Mon Sep 17 00:00:00 2001
From: Dima Kogan <[email-masked]>
Date: Thu, 29 Oct 2020 12:49:50 -0700
Subject: [PATCH] Added new (diff-refresh-hunk) function

Just like the existing (diff-ignore-whitespace-hunk) function, it invokes the
external "diff" tool to recompute the hunk, but it keeps the whitespace.
Useful for throwing out no-op pieces of hunks.

* lisp/vc/diff-mode.el (diff-refresh-hunk): New function
---
 lisp/vc/diff-mode.el | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index 7c9ad25eb31..eded9dcb704 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -208,6 +208,8 @@ diff-mode-map
     ;; `d' because it duplicates the context :-(  --Stef
     ("\C-c\C-d" . diff-unified->context)
     ("\C-c\C-w" . diff-ignore-whitespace-hunk)
+    ;; `l' because it "refreshes" the hunk like C-l refreshes the screen
+    ("\C-c\C-l" . diff-refresh-hunk)
     ("\C-c\C-b" . diff-refine-hunk)  ;No reason for `b' :-(
     ("\C-c\C-f" . next-error-follow-minor-mode))
   "Keymap for `diff-mode'.  See also `diff-mode-shared-map'.")
@@ -244,6 +246,8 @@ diff-mode-menu
      :help "Split the current (unified diff) hunk at point into two hunks"]
     ["Ignore whitespace changes" diff-ignore-whitespace-hunk
      :help "Re-diff the current hunk, ignoring whitespace differences"]
+    ["Recompute the hunk" diff-refresh-hunk
+     :help "Re-diff the current hunk, keeping the whitespace differences"]
     ["Highlight fine changes"	diff-refine-hunk
      :help "Highlight changes of hunk at point at a finer granularity"]
     ["Kill current hunk"	diff-hunk-kill
@@ -2045,8 +2049,13 @@ diff-current-defun
 (defun diff-ignore-whitespace-hunk ()
   "Re-diff the current hunk, ignoring whitespace differences."
   (interactive)
+  (diff-refresh-hunk t))
+
+(defun diff-refresh-hunk (&optional ignore-whitespace)
+  "Re-diff the current hunk."
+  (interactive)
   (let* ((char-offset (- (point) (diff-beginning-of-hunk t)))
-	 (opts (pcase (char-after) (?@ "-bu") (?* "-bc") (_ "-b")))
+	 (opt_type (pcase (char-after) (?@ "-u") (?* "-c")))
 	 (line-nb (and (or (looking-at "[^0-9]+\\([0-9]+\\)")
 			   (error "Can't find line number"))
 		       (string-to-number (match-string 1))))
@@ -2057,7 +2066,12 @@ diff-ignore-whitespace-hunk
 	 (file1 (make-temp-file "diff1"))
 	 (file2 (make-temp-file "diff2"))
 	 (coding-system-for-read buffer-file-coding-system)
-	 old new)
+	 opts old new)
+    (when ignore-whitespace
+      (setq opts '("-b")))
+    (when opt_type
+      (setq opts (cons opt_type opts)))
+
     (unwind-protect
 	(save-excursion
 	  (setq old (diff-hunk-text hunk nil char-offset))
@@ -2066,8 +2080,9 @@ diff-ignore-whitespace-hunk
 	  (write-region (concat lead (car new)) nil file2 nil 'nomessage)
 	  (with-temp-buffer
 	    (let ((status
-		   (call-process diff-command nil t nil
-				 opts file1 file2)))
+		   (apply 'call-process
+			  `(,diff-command nil t nil
+			                 ,@opts ,file1 ,file2))))
 	      (pcase status
 		(0 nil)                 ;Nothing to reformat.
 		(1 (goto-char (point-min))
-- 
2.28.0.rc0