Skip to content

Commit 37ce6b1

Browse files
committed
Merge branch 'dk/blame-el'
* dk/blame-el: git-blame.el: Change how blame information is shown.
2 parents d9499c8 + c5022f5 commit 37ce6b1

File tree

1 file changed

+102
-54
lines changed

1 file changed

+102
-54
lines changed

contrib/emacs/git-blame.el

Lines changed: 102 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,57 @@
8080

8181
(eval-when-compile (require 'cl)) ; to use `push', `pop'
8282

83+
(defface git-blame-prefix-face
84+
'((((background dark)) (:foreground "gray"
85+
:background "black"))
86+
(((background light)) (:foreground "gray"
87+
:background "white"))
88+
(t (:weight bold)))
89+
"The face used for the hash prefix."
90+
:group 'git-blame)
91+
92+
(defgroup git-blame nil
93+
"A minor mode showing Git blame information."
94+
:group 'git
95+
:link '(function-link git-blame-mode))
96+
97+
98+
(defcustom git-blame-use-colors t
99+
"Use colors to indicate commits in `git-blame-mode'."
100+
:type 'boolean
101+
:group 'git-blame)
102+
103+
(defcustom git-blame-prefix-format
104+
"%h %20A:"
105+
"The format of the prefix added to each line in `git-blame'
106+
mode. The format is passed to `format-spec' with the following format keys:
107+
108+
%h - the abbreviated hash
109+
%H - the full hash
110+
%a - the author name
111+
%A - the author email
112+
%c - the committer name
113+
%C - the committer email
114+
%s - the commit summary
115+
"
116+
:group 'git-blame)
117+
118+
(defcustom git-blame-mouseover-format
119+
"%h %a %A: %s"
120+
"The format of the description shown when pointing at a line in
121+
`git-blame' mode. The format string is passed to `format-spec'
122+
with the following format keys:
123+
124+
%h - the abbreviated hash
125+
%H - the full hash
126+
%a - the author name
127+
%A - the author email
128+
%c - the committer name
129+
%C - the committer email
130+
%s - the commit summary
131+
"
132+
:group 'git-blame)
133+
83134

84135
(defun git-blame-color-scale (&rest elements)
85136
"Given a list, returns a list of triples formed with each
@@ -302,72 +353,69 @@ See also function `git-blame-mode'."
302353
(src-line (string-to-number (match-string 2)))
303354
(res-line (string-to-number (match-string 3)))
304355
(num-lines (string-to-number (match-string 4))))
305-
(setq git-blame-current
306-
(if (string= hash "0000000000000000000000000000000000000000")
307-
nil
308-
(git-blame-new-commit
309-
hash src-line res-line num-lines))))
310-
(delete-region (point) (match-end 0))
311-
t)
312-
((looking-at "filename \\(.+\\)\n")
313-
(let ((filename (match-string 1)))
314-
(git-blame-add-info "filename" filename))
315-
(delete-region (point) (match-end 0))
356+
(delete-region (point) (match-end 0))
357+
(setq git-blame-current (list (git-blame-new-commit hash)
358+
src-line res-line num-lines)))
316359
t)
317360
((looking-at "\\([a-z-]+\\) \\(.+\\)\n")
318361
(let ((key (match-string 1))
319362
(value (match-string 2)))
320-
(git-blame-add-info key value))
321-
(delete-region (point) (match-end 0))
322-
t)
323-
((looking-at "boundary\n")
324-
(setq git-blame-current nil)
325-
(delete-region (point) (match-end 0))
363+
(delete-region (point) (match-end 0))
364+
(git-blame-add-info (car git-blame-current) key value)
365+
(when (string= key "filename")
366+
(git-blame-create-overlay (car git-blame-current)
367+
(caddr git-blame-current)
368+
(cadddr git-blame-current))
369+
(setq git-blame-current nil)))
326370
t)
327371
(t
328372
nil)))
329373

330-
(defun git-blame-new-commit (hash src-line res-line num-lines)
374+
(defun git-blame-new-commit (hash)
375+
(with-current-buffer git-blame-file
376+
(or (gethash hash git-blame-cache)
377+
;; Assign a random color to each new commit info
378+
;; Take care not to select the same color multiple times
379+
(let* ((color (if git-blame-colors
380+
(git-blame-random-pop git-blame-colors)
381+
git-blame-ancient-color))
382+
(info `(,hash (color . ,color))))
383+
(puthash hash info git-blame-cache)
384+
info))))
385+
386+
(defun git-blame-create-overlay (info start-line num-lines)
331387
(save-excursion
332388
(set-buffer git-blame-file)
333-
(let ((info (gethash hash git-blame-cache))
334-
(inhibit-point-motion-hooks t)
389+
(let ((inhibit-point-motion-hooks t)
335390
(inhibit-modification-hooks t))
336-
(when (not info)
337-
;; Assign a random color to each new commit info
338-
;; Take care not to select the same color multiple times
339-
(let ((color (if git-blame-colors
340-
(git-blame-random-pop git-blame-colors)
341-
git-blame-ancient-color)))
342-
(setq info (list hash src-line res-line num-lines
343-
(git-describe-commit hash)
344-
(cons 'color color))))
345-
(puthash hash info git-blame-cache))
346-
(goto-line res-line)
347-
(while (> num-lines 0)
348-
(if (get-text-property (point) 'git-blame)
349-
(forward-line)
350-
(let* ((start (point))
351-
(end (progn (forward-line 1) (point)))
352-
(ovl (make-overlay start end)))
353-
(push ovl git-blame-overlays)
354-
(overlay-put ovl 'git-blame info)
355-
(overlay-put ovl 'help-echo hash)
391+
(goto-line start-line)
392+
(let* ((start (point))
393+
(end (progn (forward-line num-lines) (point)))
394+
(ovl (make-overlay start end))
395+
(hash (car info))
396+
(spec `((?h . ,(substring hash 0 6))
397+
(?H . ,hash)
398+
(?a . ,(git-blame-get-info info 'author))
399+
(?A . ,(git-blame-get-info info 'author-mail))
400+
(?c . ,(git-blame-get-info info 'committer))
401+
(?C . ,(git-blame-get-info info 'committer-mail))
402+
(?s . ,(git-blame-get-info info 'summary)))))
403+
(push ovl git-blame-overlays)
404+
(overlay-put ovl 'git-blame info)
405+
(overlay-put ovl 'help-echo
406+
(format-spec git-blame-mouseover-format spec))
407+
(if git-blame-use-colors
356408
(overlay-put ovl 'face (list :background
357-
(cdr (assq 'color (nthcdr 5 info)))))
358-
;; the point-entered property doesn't seem to work in overlays
359-
;;(overlay-put ovl 'point-entered
360-
;; `(lambda (x y) (git-blame-identify ,hash)))
361-
(let ((modified (buffer-modified-p)))
362-
(put-text-property (if (= start 1) start (1- start)) (1- end)
363-
'point-entered
364-
`(lambda (x y) (git-blame-identify ,hash)))
365-
(set-buffer-modified-p modified))))
366-
(setq num-lines (1- num-lines))))))
367-
368-
(defun git-blame-add-info (key value)
369-
(if git-blame-current
370-
(nconc git-blame-current (list (cons (intern key) value)))))
409+
(cdr (assq 'color (cdr info))))))
410+
(overlay-put ovl 'line-prefix
411+
(propertize (format-spec git-blame-prefix-format spec)
412+
'face 'git-blame-prefix-face))))))
413+
414+
(defun git-blame-add-info (info key value)
415+
(nconc info (list (cons (intern key) value))))
416+
417+
(defun git-blame-get-info (info key)
418+
(cdr (assq key (cdr info))))
371419

372420
(defun git-blame-current-commit ()
373421
(let ((info (get-char-property (point) 'git-blame)))

0 commit comments

Comments
 (0)