(defun diff-kill-trailing-blanks () "Inspect the current diff and remove trailing whitespace (spaces, tabs). That is, it removes trailing whitespaces from the lines modified or introduced by this diff. Shows a message with the name of the altered buffers, which are unsaved. If a file referenced on the diff has no buffer and needs to be fixed, a buffer visiting that file is created." (interactive) (save-excursion ;; We assume that the diff header has no trailing whitespace. (let (modified-buffers white-positions) (goto-char (point-min)) (while (re-search-forward "^[+!>].*?[ \t]+$" (point-max) t) (save-excursion (destructuring-bind (buf line-offset pos src dst &optional switched) (diff-find-source-location t t) (when line-offset (save-excursion (set-buffer buf) (goto-char (+ (car pos) (cdr src))) (beginning-of-line) (when (re-search-forward "\\([ \t]+\\)$" (line-end-position) t) (unless (member buf modified-buffers) (push buf modified-buffers)) (push buf white-positions) (push (match-beginning 0) white-positions) (push (match-end 0) white-positions))))))) (setq white-positions (nreverse white-positions)) (while white-positions (save-excursion (set-buffer (pop white-positions)) (delete-region (pop white-positions) (pop white-positions)))) (if modified-buffers (message "Deleted trailing whitespace from: %s" (mapconcat #'(lambda (buf) (format "`%s'" (buffer-name buf))) modified-buffers " ")) (message "No fixes needed."))))) (defun diff-show-trailing-blanks () "Show trailing blanks in modified lines for diff-mode." (interactive) (let ((whitespace-style '(trailing)) (whitespace-trailing-regexp "^[+!>].*?\\([\t ]+\\)$")) (whitespace-mode 1))) ; display trailing blanks in diff buffer