├── 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 | image 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 | --------------------------------------------------------------------------------