From 9d9e48d9041bf039d873b23484301acca52972e9 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Fri, 9 Nov 2012 01:31:53 +0800 Subject: [PATCH] Rewrite and rename diff-delete-trailing-whitespace. * 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 | 3 ++ doc/emacs/files.texi | 27 ++++++++------- etc/NEWS | 2 +- lisp/ChangeLog | 5 +++ lisp/vc/diff-mode.el | 96 ++++++++++++++++++++++++++++++++++++---------------- 5 files changed, 90 insertions(+), 43 deletions(-) diff --git a/doc/emacs/ChangeLog b/doc/emacs/ChangeLog index 14ed58fb5c1..2a58735535f 100644 --- a/doc/emacs/ChangeLog +++ b/doc/emacs/ChangeLog @@ -1,5 +1,8 @@ 2012-11-08 Chong Yidong + * files.texi (Diff Mode): Doc fixes for + diff-delete-trailing-whitespace (Bug#12831). + * trouble.texi (Crashing): Copyedits. 2012-11-08 Glenn Morris diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index e2a85c6d138..8b609891caf 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi @@ -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 diff --git a/etc/NEWS b/etc/NEWS index d909cd2bfc7..e241bdba3cb 100644 --- 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 diff --git a/lisp/ChangeLog b/lisp/ChangeLog index b17f3d9a59e..d9facb94cf8 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2012-11-08 Chong Yidong + + * vc/diff-mode.el (diff-delete-trailing-whitespace): Rewrite, and + rename from diff-remove-trailing-whitespace (Bug#12831). + 2012-11-08 Stefan Monnier * emacs-lisp/advice.el: Require `cl-lib' at run-time to fix diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index daf43c5c167..26c64ce2ad3 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -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) -- 2.11.4.GIT