9
9
;; Keywords: git, version control, release management
11
;; Compatibility: Emacs21
11
;; Compatibility: Emacs21, Emacs22 and EmacsCVS
14
14
;; This file is *NOT* part of GNU Emacs.
15
15
;; This file is distributed under the same terms as GNU Emacs.
64
;; It requires GNU Emacs 21. If you'are using Emacs 20, try
64
;; It requires GNU Emacs 21 or later and Git 1.5.0 and up
66
;; If you'are using Emacs 20, try changing this:
67
68
;; (overlay-put ovl 'face (list :background
68
69
;; (cdr (assq 'color (cddddr info)))))
80
(require 'cl) ; to use `push', `pop'
82
(defun color-scale (l)
91
(push (concat "#" (car r) (car g) (car b)) colors)
81
(eval-when-compile (require 'cl)) ; to use `push', `pop'
84
(defun git-blame-color-scale (&rest elements)
85
"Given a list, returns a list of triples formed with each
88
a b => bbb bba bab baa abb aba aaa aab"
93
(setq result (cons (format "#%s%s%s" a b c) result)))))
96
;; (git-blame-color-scale "0c" "04" "24" "1c" "2c" "34" "14" "3c") =>
97
;; ("#3c3c3c" "#3c3c14" "#3c3c34" "#3c3c2c" "#3c3c1c" "#3c3c24"
98
;; "#3c3c04" "#3c3c0c" "#3c143c" "#3c1414" "#3c1434" "#3c142c" ...)
100
(defmacro git-blame-random-pop (l)
101
"Select a random element from L and returns it. Also remove
102
selected element from l."
103
;; only works on lists with unique elements
104
`(let ((e (elt ,l (random (length ,l)))))
105
(setq ,l (remove e ,l))
97
108
(defvar git-blame-dark-colors
98
(color-scale '("0c" "04" "24" "1c" "2c" "34" "14" "3c")))
109
(git-blame-color-scale "0c" "04" "24" "1c" "2c" "34" "14" "3c")
110
"*List of colors (format #RGB) to use in a dark environment.
112
To check out the list, evaluate (list-colors-display git-blame-dark-colors).")
100
114
(defvar git-blame-light-colors
101
(color-scale '("c4" "d4" "cc" "dc" "f4" "e4" "fc" "ec")))
103
(defvar git-blame-ancient-color "dark green")
115
(git-blame-color-scale "c4" "d4" "cc" "dc" "f4" "e4" "fc" "ec")
116
"*List of colors (format #RGB) to use in a light environment.
118
To check out the list, evaluate (list-colors-display git-blame-light-colors).")
120
(defvar git-blame-colors '()
121
"Colors used by git-blame. The list is built once when activating git-blame
124
(defvar git-blame-ancient-color "dark green"
125
"*Color to be used for ancient commit.")
105
127
(defvar git-blame-autoupdate t
106
128
"*Automatically update the blame display while editing")
125
147
"A queue of update requests")
126
148
(make-variable-buffer-local 'git-blame-update-queue)
151
(defvar git-blame-file nil)
152
(defvar git-blame-current nil)
128
154
(defvar git-blame-mode nil)
129
155
(make-variable-buffer-local 'git-blame-mode)
130
(unless (assq 'git-blame-mode minor-mode-alist)
131
(setq minor-mode-alist
132
(cons (list 'git-blame-mode " blame")
157
(defvar git-blame-mode-line-string " blame"
158
"String to display on the mode line when git-blame is active.")
160
(or (assq 'git-blame-mode minor-mode-alist)
161
(setq minor-mode-alist
162
(cons '(git-blame-mode git-blame-mode-line-string) minor-mode-alist)))
136
165
(defun git-blame-mode (&optional arg)
137
"Minor mode for displaying Git blame"
166
"Toggle minor mode for displaying Git blame
168
With prefix ARG, turn the mode on if ARG is positive."
138
169
(interactive "P")
140
(setq git-blame-mode (eq arg 1))
141
(setq git-blame-mode (not git-blame-mode)))
172
(if git-blame-mode (git-blame-mode-off) (git-blame-mode-on)))
173
((> (prefix-numeric-value arg) 0) (git-blame-mode-on))
174
(t (git-blame-mode-off))))
176
(defun git-blame-mode-on ()
177
"Turn on git-blame mode.
179
See also function `git-blame-mode'."
142
180
(make-local-variable 'git-blame-colors)
143
181
(if git-blame-autoupdate
144
182
(add-hook 'after-change-functions 'git-blame-after-change nil t)
145
183
(remove-hook 'after-change-functions 'git-blame-after-change t))
146
184
(git-blame-cleanup)
149
(let ((bgmode (cdr (assoc 'background-mode (frame-parameters)))))
150
(if (eq bgmode 'dark)
151
(setq git-blame-colors git-blame-dark-colors)
152
(setq git-blame-colors git-blame-light-colors)))
153
(setq git-blame-cache (make-hash-table :test 'equal))
155
(cancel-timer git-blame-idle-timer)))
185
(let ((bgmode (cdr (assoc 'background-mode (frame-parameters)))))
186
(if (eq bgmode 'dark)
187
(setq git-blame-colors git-blame-dark-colors)
188
(setq git-blame-colors git-blame-light-colors)))
189
(setq git-blame-cache (make-hash-table :test 'equal))
190
(setq git-blame-mode t)
193
(defun git-blame-mode-off ()
194
"Turn off git-blame mode.
196
See also function `git-blame-mode'."
198
(if git-blame-idle-timer (cancel-timer git-blame-idle-timer))
199
(setq git-blame-mode nil))
158
202
(defun git-reblame ()
159
203
"Recalculate all blame information in the current buffer"
160
205
(unless git-blame-mode
161
(error "git-blame is not active"))
206
(error "Git-blame is not active"))
163
208
(git-blame-cleanup)
283
327
(inhibit-point-motion-hooks t)
284
328
(inhibit-modification-hooks t))
286
(let ((color (pop git-blame-colors)))
288
(setq color git-blame-ancient-color))
330
;; Assign a random color to each new commit info
331
;; Take care not to select the same color multiple times
332
(let ((color (if git-blame-colors
333
(git-blame-random-pop git-blame-colors)
334
git-blame-ancient-color)))
289
335
(setq info (list hash src-line res-line num-lines
290
336
(git-describe-commit hash)
291
337
(cons 'color color))))