├── LICENSE
├── bin
└── time-magit-status
├── README.md
└── magit-delta.el
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Dan Davison
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/bin/time-magit-status:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | :;exec emacs --quick --load "$0" "$@"
3 | (defun -install-package (package)
4 | (unless (package-installed-p package)
5 | (package-refresh-contents)
6 | (package-install package)))
7 |
8 | (setq package-archives '(("melpa" . "http://melpa.org/packages/")))
9 | (package-initialize)
10 | (-install-package 'magit)
11 | (-install-package 'magit-delta)
12 |
13 | (setq use-magit-delta (let ((val (getenv "USE_MAGIT_DELTA")))
14 | (and val
15 | (not (string-equal val ""))
16 | (not (string-equal val "0")))))
17 |
18 | (princ (format "magit-delta %s\n" (if use-magit-delta "on" "off"))
19 | #'external-debugging-output)
20 |
21 | (defun time-magit-status ()
22 | (interactive)
23 | (let ((start-time (time-to-seconds (current-time))))
24 | (magit-status)
25 | (princ (format "magit-status took %.1f seconds\n"
26 | (- (time-to-seconds (current-time)) start-time))
27 | #'external-debugging-output)))
28 |
29 | (when use-magit-delta
30 | (add-hook 'magit-mode-hook (lambda () (magit-delta-mode +1))))
31 | (time-magit-status)
32 | (kill-emacs)
33 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This Emacs package provides a minor mode which configures [Magit](https://github.com/magit/magit) to use [delta](https://github.com/dandavison/delta) when displaying diffs.
2 |
3 | 1. Install [delta](https://github.com/dandavison/delta).
4 | 2. Install magit-delta from [MELPA](https://melpa.org/#/getting-started).
5 | 3. Use `M-x magit-delta-mode` to toggle between using delta, and normal magit behavior.
6 | To activate it automatically:
7 | ```emacs-lisp
8 | (add-hook 'magit-mode-hook (lambda () (magit-delta-mode +1)))
9 | ```
10 |
11 | Or with `use-package`
12 | ```emacs-lisp
13 | (use-package magit-delta
14 | :hook (magit-mode . magit-delta-mode))
15 | ```
16 |
17 |
18 |
19 |
20 |
21 | |
22 |
23 | If you run emacs as a terminal application (`emacs -nw`) and colors are not being rendered correctly, then follow the instructions here: https://www.gnu.org/software/emacs/manual/html_node/efaq/Colors-on-a-TTY.html.
24 |
25 |
26 | ### Credit
27 | - [magit](https://github.com/magit/magit)
28 | - [xterm-color](https://github.com/atomontage/xterm-color)
29 |
--------------------------------------------------------------------------------
/magit-delta.el:
--------------------------------------------------------------------------------
1 | ;;; magit-delta.el --- Use Delta when displaying diffs in Magit -*- lexical-binding: t; -*-
2 |
3 | ;; Author: Dan Davison
4 | ;; URL: https://github.com/dandavison/magit-delta
5 | ;; Version: 0.1
6 | ;; Package-Requires: ((emacs "25.1") (magit "20200426") (xterm-color "2.0"))
7 |
8 | ;; SPDX-License-Identifier: MIT
9 |
10 | ;;; Commentary:
11 |
12 | ;; This package integrates Delta (https://github.com/dandavison/delta) with
13 | ;; Magit (https://github.com/magit), so that diffs in Magit are displayed with
14 | ;; color highlighting provided by Delta.
15 | ;;
16 | ;; Use M-x magit-delta-mode to toggle between using Delta, and normal Magit
17 | ;; behavior.
18 |
19 | ;;; Code:
20 | (require 'magit)
21 | (require 'xterm-color)
22 | (require 'dash)
23 |
24 | (defgroup magit-delta nil
25 | "Magit delta customizations."
26 | :group 'magit-diff
27 | :group 'magit-modes)
28 |
29 | (defcustom magit-delta-delta-executable "delta"
30 | "The delta executable on your system to be used by Magit."
31 | :type 'string
32 | :group 'magit-delta)
33 |
34 | (defcustom magit-delta-default-light-theme "GitHub"
35 | "The default color theme when Emacs has a light background."
36 | :type 'string
37 | :group 'magit-delta)
38 |
39 | (defcustom magit-delta-default-dark-theme "Monokai Extended"
40 | "The default color theme when Emacs has a dark background."
41 | :type 'string
42 | :group 'magit-delta)
43 |
44 | (defcustom magit-delta-delta-args
45 | `("--max-line-distance" "0.6"
46 | "--true-color" ,(if xterm-color--support-truecolor "always" "never")
47 | "--color-only")
48 | "Delta command line arguments as a list of strings.
49 |
50 | If the color theme is not specified using --theme, then it will
51 | be chosen automatically according to whether the current Emacs
52 | frame has a light or dark background. See `magit-delta-default-light-theme' and
53 | `magit-delta-default-dark-theme'.
54 |
55 | --color-only is required in order to use delta with magit; it
56 | will be added if not present."
57 | :type '(repeat string)
58 | :group 'magit-delta)
59 |
60 | (defcustom magit-delta-hide-plus-minus-markers t
61 | "Whether to hide the +/- markers at the beginning of diff lines."
62 | :type '(choice (const :tag "Hide" t)
63 | (const :tag "Show" nil))
64 | :group 'magit-delta)
65 |
66 | (defun magit-delta--make-delta-args ()
67 | "Make final list of delta command-line arguments."
68 | (let ((args magit-delta-delta-args))
69 | (unless (-intersection '("--syntax-theme" "--light" "--dark") args)
70 | (setq args (nconc
71 | (list "--syntax-theme"
72 | (if (eq (frame-parameter nil 'background-mode) 'dark)
73 | magit-delta-default-dark-theme
74 | magit-delta-default-light-theme))
75 | args)))
76 | (unless (member "--color-only" args)
77 | (setq args (cons "--color-only" args)))
78 | args))
79 |
80 | (defvar magit-delta--magit-diff-refine-hunk--orig-value nil)
81 |
82 |
83 | ;;;###autoload
84 | (define-minor-mode magit-delta-mode
85 | "Use Delta when displaying diffs in Magit.
86 |
87 | https://github.com/dandavison/delta"
88 | :lighter " Δ"
89 | (let ((magit-faces-to-override
90 | '(magit-diff-context-highlight
91 | magit-diff-added
92 | magit-diff-added-highlight
93 | magit-diff-removed
94 | magit-diff-removed-highlight)))
95 | (cond
96 | (magit-delta-mode
97 | (add-hook 'magit-diff-wash-diffs-hook #'magit-delta-call-delta-and-convert-ansi-escape-sequences)
98 | (setq magit-delta--magit-diff-refine-hunk--orig-value
99 | magit-diff-refine-hunk
100 |
101 | magit-diff-refine-hunk
102 | nil
103 |
104 | face-remapping-alist
105 | (nconc
106 | (--remove (member (car it) magit-faces-to-override)
107 | face-remapping-alist)
108 | (--map (cons it 'default) magit-faces-to-override))))
109 | ('deactivate
110 | (remove-hook 'magit-diff-wash-diffs-hook #'magit-delta-call-delta-and-convert-ansi-escape-sequences)
111 | (setq magit-diff-refine-hunk
112 | magit-delta--magit-diff-refine-hunk--orig-value
113 |
114 | face-remapping-alist
115 | (--remove (member (car it) magit-faces-to-override)
116 | face-remapping-alist))))))
117 |
118 | (defun magit-delta-call-delta-and-convert-ansi-escape-sequences ()
119 | "Call delta on buffer contents and convert ANSI escape sequences to overlays.
120 |
121 | The input buffer contents are expected to be raw git output."
122 | (apply #'call-process-region
123 | (point-min) (point-max)
124 | magit-delta-delta-executable t t nil (magit-delta--make-delta-args))
125 | (let ((buffer-read-only nil))
126 | (xterm-color-colorize-buffer 'use-overlays)
127 | (if magit-delta-hide-plus-minus-markers
128 | (magit-delta-hide-plus-minus-markers))))
129 |
130 | (defun magit-delta-hide-plus-minus-markers ()
131 | "Apply text properties to hide the +/- markers at the beginning of lines."
132 | (save-excursion
133 | (goto-char (point-min))
134 | ;; Within hunks, hide - or + at the start of a line.
135 | (let ((in-hunk nil))
136 | (while (re-search-forward "^\\(diff\\|@@\\|+\\|-\\)" nil t)
137 | (cond
138 | ((string-equal (match-string 0) "diff")
139 | (setq in-hunk nil))
140 | ((string-equal (match-string 0) "@@")
141 | (setq in-hunk t))
142 | (in-hunk
143 | (add-text-properties (match-beginning 0) (match-end 0)
144 | '(display " "))))))))
145 |
146 | (provide 'magit-delta)
147 |
148 | ;;; magit-delta.el ends here
149 |
--------------------------------------------------------------------------------