Rewrite and rename diff-delete-trailing-whitespace.
authorChong Yidong <cyd@gnu.org>
Thu, 8 Nov 2012 17:31:53 +0000 (01:31 +0800)
committerChong Yidong <cyd@gnu.org>
Thu, 8 Nov 2012 17:31:53 +0000 (01:31 +0800)
* lisp/vc/diff-mode.el (diff-delete-trailing-whitespace): Rewrite, and
rename from diff-remove-trailing-whitespace (Bug#12831).

* files.texi (Diff Mode): Doc fixes for
diff-delete-trailing-whitespace.

doc/emacs/ChangeLog
doc/emacs/files.texi
etc/NEWS
lisp/ChangeLog
lisp/vc/diff-mode.el

index 14ed58f..2a58735 100644 (file)
@@ -1,5 +1,8 @@
 2012-11-08  Chong Yidong  <cyd@gnu.org>
 
+       * files.texi (Diff Mode): Doc fixes for
+       diff-delete-trailing-whitespace (Bug#12831).
+
        * trouble.texi (Crashing): Copyedits.
 
 2012-11-08  Glenn Morris  <rgm@gnu.org>
index e2a85c6..8b60989 100644 (file)
@@ -1341,7 +1341,7 @@ contents of the hunk.
   You can edit a Diff mode buffer like any other buffer.  (If it is
 read-only, you need to make it writable first.  @xref{Misc Buffer}.)
 Whenever you change a hunk, Diff mode attempts to automatically
-correct the line numbers in the hunk headers, to ensure that the diff
+correct the line numbers in the hunk headers, to ensure that the patch
 remains ``correct''.  To disable automatic line number correction,
 change the variable @code{diff-update-on-the-fly} to @code{nil}.
 
@@ -1472,17 +1472,20 @@ functions that are deleted by the patch.
 
 @c Trailing whitespace is NOT shown by default.
 @c Emacs's dir-locals file enables this (for some reason).
-@cindex trailing whitespace, in diffs
-@findex diff-remove-trailing-whitespace
-  Diff mode has various features for dealing with trailing whitespace
-on modified lines, since this is often an unintentional and unwanted
-change.  If you enable Whitespace mode in a Diff buffer, trailing
-whitespace is highlighted (@pxref{Useless Whitespace}).  The command
-@kbd{M-x diff-remove-trailing-whitespace} searches for trailing
-whitespace in the lines modified or added by a diff.  If it finds any,
-it tries to visit the associated file(s) and remove it.  It does not
-save the modifications, rather it lists any buffers that were modified
-so you can decide for yourself what to do.
+@cindex trailing whitespace, in patches
+@findex diff-delete-trailing-whitespace
+  Patches sometimes include trailing whitespace on modified lines, as
+an unintentional and undesired change.  There are two ways to deal
+with this problem.  Firstly, if you enable Whitespace mode in a Diff
+buffer (@pxref{Useless Whitespace}), it automatically highlights
+trailing whitespace in modified lines.  Secondly, you can use the
+command @kbd{M-x diff-delete-trailing-whitespace}, which searches for
+trailing whitespace in the lines modified by the patch, and removes
+that whitespace in both the patch and the patched source file(s).
+This command does not save the modifications that it makes, so you can
+decide whether to save the changes (the list of modified files is
+displayed in the echo area).  With a prefix argument, it tries to
+modify the original source files rather than the patched source files.
 
 @node Misc File Ops
 @section Miscellaneous File Operations
index d909cd2..e241bdb 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -406,7 +406,7 @@ face `diff-changed', or `diff-removed' and `diff-added' to highlight
 changes in context diffs.
 
 +++
-*** The new command `diff-remove-trailing-whitespace' removes trailing
+*** The new command `diff-delete-trailing-whitespace' removes trailing
 whitespace introduced by a diff.
 
 ** Dired
index b17f3d9..d9facb9 100644 (file)
@@ -1,3 +1,8 @@
+2012-11-08  Chong Yidong  <cyd@gnu.org>
+
+       * vc/diff-mode.el (diff-delete-trailing-whitespace): Rewrite, and
+       rename from diff-remove-trailing-whitespace (Bug#12831).
+
 2012-11-08  Stefan Monnier  <monnier@iro.umontreal.ca>
 
        * emacs-lisp/advice.el: Require `cl-lib' at run-time to fix
index daf43c5..26c64ce 100644 (file)
@@ -178,7 +178,7 @@ when editing big diffs)."
     ["Unified -> Context"      diff-unified->context
      :help "Convert unified diffs to context diffs"]
     ;;["Fixup Headers"         diff-fixup-modifs       (not buffer-read-only)]
-    ["Remove trailing whitespace" diff-remove-trailing-whitespace
+    ["Remove trailing whitespace" diff-delete-trailing-whitespace
      :help "Remove trailing whitespace problems introduced by the diff"]
     ["Show trailing whitespace" whitespace-mode
      :style toggle :selected (bound-and-true-p whitespace-mode)
@@ -2048,35 +2048,71 @@ I.e. like `add-change-log-entry-other-window' but applied to all hunks."
       ;; When there's no more hunks, diff-hunk-next signals an error.
       (error nil))))
 
-(defun diff-remove-trailing-whitespace ()
-  "Remove trailing whitespace from the lines modified/added by a diff.
-Called from a buffer containing a diff, this searches for trailing
-whitespace (spaces, tabs) in the modified/added lines.  If the
-file that such a line refers to can be found, it visits it and
-removes the associated whitespace, if it is present.  It does not
-save any changed buffers, it just gives a message naming them."
-  (interactive)
-  ;; We assume that the diff header has no trailing whitespace.
-  (let ((modified-buffers nil))
-    (save-excursion
-      (goto-char (point-min))
-      (while (re-search-forward "^[+!>].*[ \t]+$" (point-max) t)
-        (pcase-let ((`(,buf ,line-offset ,pos ,src ,_dst ,_switched)
-                     (diff-find-source-location t t)))
-          (when line-offset
-            (with-current-buffer buf
-              (save-excursion
-                (goto-char (+ (car pos) (cdr src)))
-                (beginning-of-line)
-                (when (re-search-forward "\\([ \t]+\\)$" (line-end-position) t)
-                  (unless (memq buf modified-buffers)
-                    (push buf modified-buffers))
-                  (replace-match ""))))))))
-    (if modified-buffers
-        (message "Deleted new trailing whitespace from: %s"
-                 (mapconcat (lambda (buf) (concat "`" (buffer-name buf) "'"))
-                            modified-buffers " "))
-      (message "No trailing whitespace fixes needed."))))
+(defun diff-delete-trailing-whitespace (&optional other-file)
+  "Remove trailing whitespace from lines modified in this diff.
+This edits both the current Diff mode buffer and the patched
+source file(s).  If `diff-jump-to-old-file' is non-nil, edit the
+original (unpatched) source file instead.  With a prefix argument
+OTHER-FILE, flip the choice of which source file to edit.
+
+If a file referenced in the diff has no buffer and needs to be
+fixed, visit it in a buffer."
+  (interactive "P")
+  (save-excursion
+    (goto-char (point-min))
+    (let* ((other (diff-xor other-file diff-jump-to-old-file))
+          (modified-buffers nil)
+          (style (save-excursion
+                   (when (re-search-forward diff-hunk-header-re nil t)
+                     (goto-char (match-beginning 0))
+                     (diff-hunk-style))))
+          (regexp (concat "^[" (if other "-<" "+>") "!]"
+                          (if (eq style 'context) " " "")
+                          ".*?\\([ \t]+\\)$"))
+          (inhibit-read-only t)
+          (end-marker (make-marker))
+          hunk-end)
+      ;; Move to the first hunk.
+      (re-search-forward diff-hunk-header-re nil 1)
+      (while (progn (save-excursion
+                     (re-search-forward diff-hunk-header-re nil 1)
+                     (setq hunk-end (point)))
+                   (< (point) hunk-end))
+       ;; For context diffs, search only in the appropriate half of
+       ;; the hunk.  For other diffs, search within the entire hunk.
+       (if (not (eq style 'context))
+           (set-marker end-marker hunk-end)
+         (let ((mid-hunk
+                (save-excursion
+                  (re-search-forward diff-context-mid-hunk-header-re hunk-end)
+                  (point))))
+           (if other
+               (set-marker end-marker mid-hunk)
+             (goto-char mid-hunk)
+             (set-marker end-marker hunk-end))))
+       (while (re-search-forward regexp end-marker t)
+         (let ((match-data (match-data)))
+           (pcase-let ((`(,buf ,line-offset ,pos ,src ,_dst ,_switched)
+                        (diff-find-source-location other-file)))
+             (when line-offset
+               ;; Remove the whitespace in the Diff mode buffer.
+               (set-match-data match-data)
+               (replace-match "" t t nil 1)
+               ;; Remove the whitespace in the source buffer.
+               (with-current-buffer buf
+                 (save-excursion
+                   (goto-char (+ (car pos) (cdr src)))
+                   (beginning-of-line)
+                   (when (re-search-forward "\\([ \t]+\\)$" (line-end-position) t)
+                     (unless (memq buf modified-buffers)
+                       (push buf modified-buffers))
+                     (replace-match ""))))))))
+       (goto-char hunk-end))
+      (if modified-buffers
+         (message "Deleted trailing whitespace from %s."
+                  (mapconcat (lambda (buf) (concat "`" (buffer-name buf) "'"))
+                             modified-buffers ", "))
+       (message "No trailing whitespace to delete.")))))
 
 ;; provide the package
 (provide 'diff-mode)