]> code.delx.au - gnu-emacs-elpa/blob - diff-hl-margin.el
New global mode: diff-hl-margin
[gnu-emacs-elpa] / diff-hl-margin.el
1 ;;; diff-hl-margin.el --- Highlight buffer changes on margins -*- lexical-binding: t -*-
2
3 ;; This file is not part of GNU Emacs.
4
5 ;; This file is free software: you can redistribute it and/or modify
6 ;; it under the terms of the GNU General Public License as published by
7 ;; the Free Software Foundation, either version 3 of the License, or
8 ;; (at your option) any later version.
9
10 ;; This file is distributed in the hope that it will be useful,
11 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ;; GNU General Public License for more details.
14
15 ;; You should have received a copy of the GNU General Public License
16 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
17
18 ;;; Commentary:
19
20 ;; This is a global mode, it modified `diff-hl-mode' to use the margin
21 ;; instead of the fringe. To toggle, type `M-x diff-hl-margin-mode'.
22 ;;
23 ;; Compared to the default behavior, this makes `diff-hl-mode'
24 ;; indicators show up even when Emacs is running in a terminal.
25 ;;
26 ;; On the flip side, the indicators look simpler, and they are
27 ;; incompatible with `linum-mode' or any other mode that uses the
28 ;; margin.
29 ;;
30 ;; You might want to enable it conditionally in your init file
31 ;; depending on whether Emacs is running in graphical mode:
32 ;;
33 ;; (unless (window-system) (diff-hl-margin-mode))
34
35 (require 'diff-hl)
36 (require 'diff-hl-dired)
37
38 (defvar diff-hl-margin-old-highlight-function nil)
39
40 ;;;###autoload
41 (define-minor-mode diff-hl-margin-mode
42 "Toggle displaying `diff-hl-mode' highlights on the margin."
43 :lighter "" :global t
44 (if diff-hl-margin-mode
45 (progn
46 (setq diff-hl-margin-old-highlight-function diff-hl-highlight-function
47 diff-hl-highlight-function 'diff-hl-highlight-on-margin)
48 (setq-default left-margin-width 1)
49 (dolist (buffer (buffer-list))
50 (with-current-buffer buffer
51 (cond
52 (diff-hl-mode
53 (diff-hl-update))
54 (diff-hl-dired-mode
55 (diff-hl-dired-update))))))
56 (setq diff-hl-highlight-function diff-hl-margin-old-highlight-function
57 diff-hl-margin-old-highlight-function nil)
58 (setq-default left-margin-width 0)
59 (dolist (buffer (buffer-list))
60 (with-current-buffer buffer
61 (cond
62 (diff-hl-mode
63 (diff-hl-update))
64 (diff-hl-dired-mode
65 (diff-hl-dired-update))))))
66 (walk-windows (lambda (win) (set-window-buffer win (window-buffer win)))))
67
68 (defvar diff-hl-margin-spec-cache
69 (loop for (type . char) in '((insert . "+") (delete . "-")
70 (change . "|") (unknown . "?"))
71 collect (cons type
72 (propertize
73 " " 'display
74 `((margin left-margin)
75 ,(propertize char 'face
76 (intern (format "diff-hl-%s" type))))))))
77
78 (defun diff-hl-highlight-on-margin (ovl type _shape)
79 (let ((spec (cdr (assoc type diff-hl-margin-spec-cache))))
80 (overlay-put ovl 'before-string spec)))
81
82 (provide 'diff-hl-margin)
83
84 ;;; diff-hl-margin.el ends here