From bc1b21bb4e3594708570a1f503f69b8acc1e6814 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Fri, 25 May 2012 03:55:40 +0300 Subject: [PATCH] Use the same diff color scheme as in modern VCSes (bug#10181). * lisp/vc/diff-mode.el (diff-header, diff-file-header): Remove "green" to avoid confusion with `diff-added' that now uses green colors. (diff-removed): Use shades of red. (diff-added): Use shades of green. (diff-changed): Leave just the yellow color. (diff-use-changed-face): New variable. (diff-font-lock-keywords): Use `diff-use-changed-face' to decide how to highlight context diff changes. (diff-refine-change): Use shades of yellow. (diff-refine-removed): New face that uses shades of red. (diff-refine-added): New face that uses shades of green. (diff-refine-hunk): Use `diff-refine-change', `diff-refine-added', `diff-refine-removed' in the call to `smerge-refine-subst' depending on the value of `diff-use-changed-face'. * lisp/vc/ediff-init.el (ediff-current-diff-A, ediff-fine-diff-A): Add face condition `min-colors 88' with shades of red. (ediff-current-diff-B, ediff-fine-diff-B): Add face condition `min-colors 88' with shades of green. (ediff-current-diff-C, ediff-fine-diff-C): Add face condition `min-colors 88' with shades of yellow. * lisp/vc/smerge-mode.el (smerge-mine): Use shades of red. (smerge-other): Use shades of green. (smerge-base): Use shades of yellow. (smerge-refined-change): Empty face. (smerge-refined-removed): New face that uses shades of red. (smerge-refined-added): New face that uses shades of green. (smerge-refine-subst): Rename arg `props' to `props-c'. Add new args `props-r' and `props-a', and use them. Doc fix. (smerge-refine): Evaluate `smerge-use-changed-face' and depending on its value use different faces `smerge-refined-change', `smerge-refined-removed', `smerge-refined-added' in the call to `smerge-refine-subst'. --- etc/NEWS | 11 +++++ lisp/ChangeLog | 39 +++++++++++++++ lisp/vc/diff-mode.el | 107 +++++++++++++++++++++++++++++++---------- lisp/vc/ediff-init.el | 36 +++++++++++--- lisp/vc/smerge-mode.el | 101 ++++++++++++++++++++++++++++---------- 5 files changed, 236 insertions(+), 58 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index f6a5bcda480..b097757dab6 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -94,6 +94,17 @@ character when doing minibuffer filename prompts. * Changes in Specialized Modes and Packages in Emacs 24.2 +** Diff mode + +Faces for changes now use the same diff color scheme as in modern VCSes +where deletions are displayed in red (new faces `diff-refine-removed' +and `smerge-refined-removed' and new definition of `diff-removed'), +insertions in green (new faces `diff-refine-added' and +`smerge-refined-added' and new definition of `diff-added'). +The variable `diff-use-changed-face' defines whether to use +the face `diff-changed', or `diff-removed' and `diff-added' +to highlight changes in context diffs. + ** `sh-script' *** Pairing of parens/quotes uses electric-pair-mode instead of skeleton-pair. *** `sh-electric-here-document-mode' now controls auto-insertion of here-docs. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index be684c559f9..4cd6f324956 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,42 @@ +2012-05-25 Juri Linkov + + Use the same diff color scheme as in modern VCSes (bug#10181). + + * vc/diff-mode.el (diff-header, diff-file-header): Remove "green" + to avoid confusion with `diff-added' that now uses green colors. + (diff-removed): Use shades of red. + (diff-added): Use shades of green. + (diff-changed): Leave just the yellow color. + (diff-use-changed-face): New variable. + (diff-font-lock-keywords): Use `diff-use-changed-face' to decide + how to highlight context diff changes. + (diff-refine-change): Use shades of yellow. + (diff-refine-removed): New face that uses shades of red. + (diff-refine-added): New face that uses shades of green. + (diff-refine-hunk): Use `diff-refine-change', `diff-refine-added', + `diff-refine-removed' in the call to `smerge-refine-subst' + depending on the value of `diff-use-changed-face'. + + * vc/smerge-mode.el (smerge-mine): Use shades of red. + (smerge-other): Use shades of green. + (smerge-base): Use shades of yellow. + (smerge-refined-change): Empty face. + (smerge-refined-removed): New face that uses shades of red. + (smerge-refined-added): New face that uses shades of green. + (smerge-refine-subst): Rename arg `props' to `props-c'. Add new + args `props-r' and `props-a', and use them. Doc fix. + (smerge-refine): Evaluate `smerge-use-changed-face' and depending + on its value use different faces `smerge-refined-change', + `smerge-refined-removed', `smerge-refined-added' in the call to + `smerge-refine-subst'. + + * vc/ediff-init.el (ediff-current-diff-A, ediff-fine-diff-A): + Add face condition `min-colors 88' with shades of red. + (ediff-current-diff-B, ediff-fine-diff-B): Add face condition + `min-colors 88' with shades of green. + (ediff-current-diff-C, ediff-fine-diff-C): Add face condition + `min-colors 88' with shades of yellow. + 2012-05-24 Glenn Morris * paths.el (prune-directory-list, remote-shell-program): Move to... diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index f3f7d8ce61b..9034ffe520f 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -237,10 +237,8 @@ well." :background "grey80") (((class color) (min-colors 88) (background dark)) :background "grey45") - (((class color) (background light)) + (((class color)) :foreground "blue1" :weight bold) - (((class color) (background dark)) - :foreground "green" :weight bold) (t :weight bold)) "`diff-mode' face inherited by hunk and index header faces." :group 'diff-mode) @@ -252,9 +250,7 @@ well." :background "grey70" :weight bold) (((class color) (min-colors 88) (background dark)) :background "grey60" :weight bold) - (((class color) (background light)) - :foreground "green" :weight bold) - (((class color) (background dark)) + (((class color)) :foreground "cyan" :weight bold) (t :weight bold)) ; :height 1.3 "`diff-mode' face used to highlight file header lines." @@ -277,14 +273,28 @@ well." (defvar diff-hunk-header-face 'diff-hunk-header) (defface diff-removed - '((t :inherit diff-changed)) + '((default + :inherit diff-changed) + (((class color) (min-colors 88) (background light)) + :background "#ffdddd") + (((class color) (min-colors 88) (background dark)) + :background "#553333") + (((class color)) + :foreground "red")) "`diff-mode' face used to highlight removed lines." :group 'diff-mode) (define-obsolete-face-alias 'diff-removed-face 'diff-removed "22.1") (defvar diff-removed-face 'diff-removed) (defface diff-added - '((t :inherit diff-changed)) + '((default + :inherit diff-changed) + (((class color) (min-colors 88) (background light)) + :background "#ddffdd") + (((class color) (min-colors 88) (background dark)) + :background "#335533") + (((class color)) + :foreground "green")) "`diff-mode' face used to highlight added lines." :group 'diff-mode) (define-obsolete-face-alias 'diff-added-face 'diff-added "22.1") @@ -296,10 +306,8 @@ well." '((((class color grayscale) (min-colors 88))) ;; If the terminal lacks sufficient colors for shadowing, ;; highlight changed lines explicitly. - (((class color) (background light)) - :foreground "magenta" :weight bold :slant italic) - (((class color) (background dark)) - :foreground "yellow" :weight bold :slant italic)) + (((class color)) + :foreground "yellow")) "`diff-mode' face used to highlight changed lines." :group 'diff-mode) (define-obsolete-face-alias 'diff-changed-face 'diff-changed "22.1") @@ -374,6 +382,13 @@ well." (defconst diff-context-mid-hunk-header-re "--- \\([0-9]+\\)\\(?:,\\([0-9]+\\)\\)? ----$") +(defvar diff-use-changed-face (and (face-differs-from-default-p diff-changed-face) + (not (face-equal diff-changed-face diff-added-face)) + (not (face-equal diff-changed-face diff-removed-face))) + "If non-nil, use the face `diff-changed' for changed lines in context diffs. +Otherwise, use the face `diff-removed' for removed lines, +and the face `diff-added' for added lines.") + (defvar diff-font-lock-keywords `((,(concat "\\(" diff-hunk-header-re-unified "\\)\\(.*\\)$") (1 diff-hunk-header-face) (6 diff-function-face)) @@ -393,8 +408,25 @@ well." ("^\\([+>]\\)\\(.*\n\\)" (1 diff-indicator-added-face) (2 diff-added-face)) ("^\\(!\\)\\(.*\n\\)" - (1 diff-indicator-changed-face) (2 diff-changed-face)) - ("^Index: \\(.+\\).*\n" + (1 (if diff-use-changed-face + diff-indicator-changed-face + ;; Otherwise, search for `diff-context-mid-hunk-header-re' and + ;; if the line of context diff is above, use `diff-removed-face'; + ;; if below, use `diff-added-face'. + (save-match-data + (let ((limit (save-excursion (diff-beginning-of-hunk)))) + (if (save-excursion (re-search-backward diff-context-mid-hunk-header-re limit t)) + diff-indicator-added-face + diff-indicator-removed-face))))) + (2 (if diff-use-changed-face + diff-changed-face + ;; Otherwise, use the same method as above. + (save-match-data + (let ((limit (save-excursion (diff-beginning-of-hunk)))) + (if (save-excursion (re-search-backward diff-context-mid-hunk-header-re limit t)) + diff-added-face + diff-removed-face)))))) + ("^\\(?:Index\\|revno\\): \\(.+\\).*\n" (0 diff-header-face) (1 diff-index-face prepend)) ("^Only in .*\n" . diff-nonexistent-face) ("^\\(#\\)\\(.*\\)" @@ -1847,17 +1879,35 @@ For use in `add-log-current-defun-function'." (defface diff-refine-change '((((class color) (min-colors 88) (background light)) - :background "grey85") + :background "#ffff55") (((class color) (min-colors 88) (background dark)) - :background "grey60") - (((class color) (background light)) - :background "yellow") - (((class color) (background dark)) - :background "green") - (t :weight bold)) + :background "#aaaa22") + (t :inverse-video t)) "Face used for char-based changes shown by `diff-refine-hunk'." :group 'diff-mode) +(defface diff-refine-removed + '((default + :inherit diff-refine-change) + (((class color) (min-colors 88) (background light)) + :background "#ffaaaa") + (((class color) (min-colors 88) (background dark)) + :background "#aa2222")) + "Face used for removed characters shown by `diff-refine-hunk'." + :group 'diff-mode + :version "24.2") + +(defface diff-refine-added + '((default + :inherit diff-refine-change) + (((class color) (min-colors 88) (background light)) + :background "#aaffaa") + (((class color) (min-colors 88) (background dark)) + :background "#22aa22")) + "Face used for added characters shown by `diff-refine-hunk'." + :group 'diff-mode + :version "24.2") + (defun diff-refine-preproc () (while (re-search-forward "^[+>]" nil t) ;; Remove spurious changes due to the fact that one side of the hunk is @@ -1871,7 +1921,7 @@ For use in `add-log-current-defun-function'." ) (declare-function smerge-refine-subst "smerge-mode" - (beg1 end1 beg2 end2 props &optional preproc)) + (beg1 end1 beg2 end2 props-c &optional preproc props-r props-a)) (defun diff-refine-hunk () "Highlight changes of hunk at point at a finer granularity." @@ -1882,7 +1932,9 @@ For use in `add-log-current-defun-function'." (let* ((start (point)) (style (diff-hunk-style)) ;Skips the hunk header as well. (beg (point)) - (props '((diff-mode . fine) (face diff-refine-change))) + (props-c '((diff-mode . fine) (face diff-refine-change))) + (props-r '((diff-mode . fine) (face diff-refine-removed))) + (props-a '((diff-mode . fine) (face diff-refine-added))) ;; Be careful to go back to `start' so diff-end-of-hunk gets ;; to read the hunk header's line info. (end (progn (goto-char start) (diff-end-of-hunk) (point)))) @@ -1896,7 +1948,7 @@ For use in `add-log-current-defun-function'." end t) (smerge-refine-subst (match-beginning 0) (match-end 1) (match-end 1) (match-end 0) - props 'diff-refine-preproc))) + nil 'diff-refine-preproc props-r props-a))) (context (let* ((middle (save-excursion (re-search-forward "^---"))) (other middle)) @@ -1908,14 +1960,17 @@ For use in `add-log-current-defun-function'." (setq other (match-end 0)) (match-beginning 0)) other - props 'diff-refine-preproc)))) + (if diff-use-changed-face props-c) + 'diff-refine-preproc + (unless diff-use-changed-face props-r) + (unless diff-use-changed-face props-a))))) (t ;; Normal diffs. (let ((beg1 (1+ (point)))) (when (re-search-forward "^---.*\n" end t) ;; It's a combined add&remove, so there's something to do. (smerge-refine-subst beg1 (match-beginning 0) (match-end 0) end - props 'diff-refine-preproc)))))))) + nil 'diff-refine-preproc props-r props-a)))))))) (defun diff-undo (&optional arg) "Perform `undo', ignoring the buffer's read-only status." diff --git a/lisp/vc/ediff-init.el b/lisp/vc/ediff-init.el index 80ed9356850..674688df1c2 100644 --- a/lisp/vc/ediff-init.el +++ b/lisp/vc/ediff-init.el @@ -853,7 +853,11 @@ TYPE-OF-EMACS is either 'xemacs or 'emacs." (defface ediff-current-diff-A (if (featurep 'emacs) - '((((class color) (min-colors 16)) + '((((class color) (min-colors 88) (background light)) + :background "#ffdddd") + (((class color) (min-colors 88) (background dark)) + :background "#553333") + (((class color) (min-colors 16)) (:foreground "firebrick" :background "pale green")) (((class color)) (:foreground "blue3" :background "yellow3")) @@ -882,7 +886,11 @@ this variable represents.") (defface ediff-current-diff-B (if (featurep 'emacs) - '((((class color) (min-colors 16)) + '((((class color) (min-colors 88) (background light)) + :background "#ddffdd") + (((class color) (min-colors 88) (background dark)) + :background "#335533") + (((class color) (min-colors 16)) (:foreground "DarkOrchid" :background "Yellow")) (((class color)) (:foreground "magenta3" :background "yellow3" @@ -912,7 +920,11 @@ this variable represents.") (defface ediff-current-diff-C (if (featurep 'emacs) - '((((class color) (min-colors 16)) + '((((class color) (min-colors 88) (background light)) + :background "#ffffaa") + (((class color) (min-colors 88) (background dark)) + :background "#888833") + (((class color) (min-colors 16)) (:foreground "Navy" :background "Pink")) (((class color)) (:foreground "cyan3" :background "yellow3" :weight bold)) @@ -968,7 +980,11 @@ this variable represents.") (defface ediff-fine-diff-A (if (featurep 'emacs) - '((((class color) (min-colors 16)) + '((((class color) (min-colors 88) (background light)) + :background "#ffaaaa") + (((class color) (min-colors 88) (background dark)) + :background "#aa2222") + (((class color) (min-colors 16)) (:foreground "Navy" :background "sky blue")) (((class color)) (:foreground "white" :background "sky blue" :weight bold)) @@ -989,7 +1005,11 @@ this variable represents.") (defface ediff-fine-diff-B (if (featurep 'emacs) - '((((class color) (min-colors 16)) + '((((class color) (min-colors 88) (background light)) + :background "#aaffaa") + (((class color) (min-colors 88) (background dark)) + :background "#22aa22") + (((class color) (min-colors 16)) (:foreground "Black" :background "cyan")) (((class color)) (:foreground "magenta3" :background "cyan3")) @@ -1010,7 +1030,11 @@ this variable represents.") (defface ediff-fine-diff-C (if (featurep 'emacs) - '((((type pc)) + '((((class color) (min-colors 88) (background light)) + :background "#ffff55") + (((class color) (min-colors 88) (background dark)) + :background "#aaaa22") + (((type pc)) (:foreground "white" :background "Turquoise")) (((class color) (min-colors 16)) (:foreground "Black" :background "Turquoise")) diff --git a/lisp/vc/smerge-mode.el b/lisp/vc/smerge-mode.el index 3db1f669d63..cf1cdabc80f 100644 --- a/lisp/vc/smerge-mode.el +++ b/lisp/vc/smerge-mode.el @@ -78,36 +78,36 @@ Used in `smerge-diff-base-mine' and related functions." :type 'boolean) (defface smerge-mine - '((((min-colors 88) (background light)) - (:foreground "blue1")) - (((background light)) - (:foreground "blue")) - (((min-colors 88) (background dark)) - (:foreground "cyan1")) - (((background dark)) - (:foreground "cyan"))) + '((((class color) (min-colors 88) (background light)) + :background "#ffdddd") + (((class color) (min-colors 88) (background dark)) + :background "#553333") + (((class color)) + :foreground "red")) "Face for your code." :group 'smerge) (define-obsolete-face-alias 'smerge-mine-face 'smerge-mine "22.1") (defvar smerge-mine-face 'smerge-mine) (defface smerge-other - '((((background light)) - (:foreground "darkgreen")) - (((background dark)) - (:foreground "lightgreen"))) + '((((class color) (min-colors 88) (background light)) + :background "#ddffdd") + (((class color) (min-colors 88) (background dark)) + :background "#335533") + (((class color)) + :foreground "green")) "Face for the other code." :group 'smerge) (define-obsolete-face-alias 'smerge-other-face 'smerge-other "22.1") (defvar smerge-other-face 'smerge-other) (defface smerge-base - '((((min-colors 88) (background light)) - (:foreground "red1")) - (((background light)) - (:foreground "red")) - (((background dark)) - (:foreground "orange"))) + '((((class color) (min-colors 88) (background light)) + :background "#ffffaa") + (((class color) (min-colors 88) (background dark)) + :background "#888833") + (((class color)) + :foreground "yellow")) "Face for the base code." :group 'smerge) (define-obsolete-face-alias 'smerge-base-face 'smerge-base "22.1") @@ -124,10 +124,34 @@ Used in `smerge-diff-base-mine' and related functions." (defvar smerge-markers-face 'smerge-markers) (defface smerge-refined-change - '((t :background "yellow")) + '((t nil)) "Face used for char-based changes shown by `smerge-refine'." :group 'smerge) +(defface smerge-refined-removed + '((default + :inherit smerge-refined-change) + (((class color) (min-colors 88) (background light)) + :background "#ffaaaa") + (((class color) (min-colors 88) (background dark)) + :background "#aa2222") + (t :inverse-video t)) + "Face used for removed characters shown by `smerge-refine'." + :group 'smerge + :version "24.2") + +(defface smerge-refined-added + '((default + :inherit smerge-refined-change) + (((class color) (min-colors 88) (background light)) + :background "#aaffaa") + (((class color) (min-colors 88) (background dark)) + :background "#22aa22") + (t :inverse-video t)) + "Face used for added characters shown by `smerge-refine'." + :group 'smerge + :version "24.2") + (easy-mmode-defmap smerge-basic-map `(("n" . smerge-next) ("p" . smerge-prev) @@ -980,9 +1004,17 @@ chars to try and eliminate some spurious differences." (dolist (x props) (overlay-put ol (car x) (cdr x))) ol))))) -(defun smerge-refine-subst (beg1 end1 beg2 end2 props &optional preproc) +(defun smerge-refine-subst (beg1 end1 beg2 end2 props-c &optional preproc props-r props-a) "Show fine differences in the two regions BEG1..END1 and BEG2..END2. -PROPS is an alist of properties to put (via overlays) on the changes. +PROPS-C is an alist of properties to put (via overlays) on the changes. +PROPS-R is an alist of properties to put on removed characters. +PROPS-A is an alist of properties to put on added characters. +If PROPS-R and PROPS-A are nil, put PROPS-C on all changes. +If PROPS-C is nil, but PROPS-R and PROPS-A are non-nil, +put PROPS-A on added characters, PROPS-R on removed characters. +If PROPS-C, PROPS-R and PROPS-A are non-nil, put PROPS-C on changed characters, +PROPS-A on added characters, and PROPS-R on removed characters. + If non-nil, PREPROC is called with no argument in a buffer that contains a copy of a region, just before preparing it to for `diff'. It can be used to replace chars to try and eliminate some spurious differences." @@ -1026,10 +1058,18 @@ used to replace chars to try and eliminate some spurious differences." (m5 (match-string 5))) (when (memq op '(?d ?c)) (setq last1 - (smerge-refine-highlight-change buf beg1 m1 m2 props))) + (smerge-refine-highlight-change + buf beg1 m1 m2 + ;; Try to use props-c only for changed chars, + ;; fallback to props-r for changed/removed chars, + ;; but if props-r is nil then fallback to props-c. + (or (and (eq op '?c) props-c) props-r props-c)))) (when (memq op '(?a ?c)) (setq last2 - (smerge-refine-highlight-change buf beg2 m4 m5 props)))) + (smerge-refine-highlight-change + buf beg2 m4 m5 + ;; Same logic as for removed chars above. + (or (and (eq op '?c) props-c) props-a props-c))))) (forward-line 1) ;Skip hunk header. (and (re-search-forward "^[0-9]" nil 'move) ;Skip hunk body. (goto-char (match-beginning 0)))) @@ -1081,7 +1121,11 @@ repeating the command will highlight other two parts." ((eq (match-end 3) (match-beginning 3)) 3) (t 2))) (let ((n1 (if (eq part 1) 2 1)) - (n2 (if (eq part 3) 2 3))) + (n2 (if (eq part 3) 2 3)) + (smerge-use-changed-face + (and (face-differs-from-default-p 'smerge-refined-change) + (not (face-equal 'smerge-refined-change 'smerge-refined-added)) + (not (face-equal 'smerge-refined-change 'smerge-refined-removed))))) (smerge-ensure-match n1) (smerge-ensure-match n2) (with-silent-modifications @@ -1090,8 +1134,13 @@ repeating the command will highlight other two parts." (cons (buffer-chars-modified-tick) part))) (smerge-refine-subst (match-beginning n1) (match-end n1) (match-beginning n2) (match-end n2) - '((smerge . refine) - (face . smerge-refined-change))))) + (if smerge-use-changed-face + '((smerge . refine) (face . smerge-refined-change))) + nil + (unless smerge-use-changed-face + '((smerge . refine) (face . smerge-refined-removed))) + (unless smerge-use-changed-face + '((smerge . refine) (face . smerge-refined-added)))))) (defun smerge-diff (n1 n2) (smerge-match-conflict) -- 2.39.2