Created
September 23, 2017 00:34
-
-
Save dse/ba94f8724d1b8f30e5cdbb64ff553527 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Stolen from: | |
;; http://mikehucka.postach.io/post/modifying-emacss-vc-diff-for-word-oriented-diffs | |
;; | |
;; Improvements: | |
;; - Be smarter about adding --word-diff to `vc-git-diff-switches' and | |
;; not clobbering any existing settings. | |
;; - Use `defface' as the docstring for `make-face' recommends. | |
;; - Base face defaults on `diff-added' and `diff-removed'. | |
;; - Rename `vc-diff-deleted-face' to `vc-diff-removed-face' for | |
;; consistency with existing face naming conventions. | |
;; - Refactor so the advice can easily be redefined. | |
;; - Be smarter about when to invoke the advice. | |
;; | |
;; TODO: | |
;; - make this work in vc-svn as well. | |
;; - make this work universally in vc, maybe. | |
;; - make this work universally in diff, maybe. | |
;; - recognize git diff --word-diff=<mode> | |
;; (`plain' is the default for <mode>) | |
;; - recognize git diff --word-diff-regex=<regex> | |
;; - recognize git diff --color-words[=<regex>] | |
(defun dse/init/vc/git/setup-word-diffs () | |
(defun dse/init/vc/git/setup-word-diffs/eval-after-load () | |
(cond ((listp vc-git-diff-switches) | |
(add-to-list 'vc-git-diff-switches "--word-diff" 'append)) | |
((stringp vc-git-diff-switches) | |
(cond | |
((equal vc-git-diff-switches "") | |
(setq vc-git-diff-switches "--word-diff")) | |
((not (string-match "\\(\\`\\| \\)--word-diff\\(\\'\\| \\)" vc-git-diff-switches)) | |
(setq vc-git-diff-switches (concat vc-git-diff-switches " --word-diff"))))) | |
((not vc-git-diff-switches) | |
(setq vc-git-diff-switches '("--word-diff")))) | |
(defface vc-diff-added-face | |
'((default :inherit diff-added)) | |
"Face used to highlight added words.") | |
(defface vc-diff-removed-face | |
'((default :inherit diff-removed)) | |
"Face used to highlight removed words.") | |
(defun vc-git-diff-word-advice () | |
(when (and (or (and (listp vc-git-diff-switches) | |
(member "--word-diff" vc-git-diff-switches)) | |
(and (stringp vc-git-diff-switches) | |
(string-match "\\(\\`\\| \\)--word-diff\\(\\'\\| \\)" vc-git-diff-switches))) | |
(equal diff-vc-backend 'Git)) | |
(save-window-excursion | |
(with-current-buffer "*vc-diff*" | |
(let ((inhibit-read-only t)) | |
(goto-char (point-min)) | |
(while (re-search-forward "\\({\\(\\+\\)\\|\\[\\(-\\)\\)" nil t) | |
(let* ((front-start (match-beginning 0)) | |
(front-end (match-end 0)) | |
(addition-p (match-beginning 2)) | |
back-start | |
back-end) | |
(cond (addition-p | |
(re-search-forward "\\+}" nil t) | |
(setq back-start (match-beginning 0)) | |
(setq back-end (match-end 0))) | |
(t | |
(re-search-forward "\\-\\]" nil t) | |
(setq back-start (match-beginning 0)) | |
(setq back-end (match-end 0)))) | |
(if addition-p | |
(overlay-put (make-overlay front-end back-start) | |
'face 'vc-diff-added-face) | |
(overlay-put (make-overlay front-end back-start) | |
'face 'vc-diff-removed-face)) | |
;; Make sure to delete back-to-front, because the text will shift. | |
(delete-region back-start back-end) | |
(delete-region front-start front-end) | |
(goto-char front-end))) | |
(goto-char (point-min))))))) | |
(defadvice vc-diff (after vc-diff-advice last activate compile) | |
(vc-git-diff-word-advice))) | |
(eval-after-load 'vc-git #'dse/init/vc/git/setup-word-diffs/eval-after-load)) | |
(dse/init/vc/git/setup-word-diffs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment