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