Skip to content

Commit

Permalink
Merge branch 'post1.5.1/blame.el'
Browse files Browse the repository at this point in the history
* post1.5.1/blame.el:
  git-blame.el: pick a set of random colors for each git-blame turn
  git-blame.el: separate git-blame-mode to ease maintenance
  • Loading branch information
Junio C Hamano committed Apr 4, 2007
2 parents 80b6e39 + 3cc5ca3 commit 1f71372
Showing 1 changed file with 92 additions and 46 deletions.
138 changes: 92 additions & 46 deletions contrib/emacs/git-blame.el
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
;; License: GPL
;; Keywords: git, version control, release management
;;
;; Compatibility: Emacs21

;; Compatibility: Emacs21, Emacs22 and EmacsCVS
;; Git 1.5 and up

;; This file is *NOT* part of GNU Emacs.
;; This file is distributed under the same terms as GNU Emacs.
Expand Down Expand Up @@ -61,8 +61,9 @@

;;; Compatibility:
;;
;; It requires GNU Emacs 21. If you'are using Emacs 20, try
;; changing this:
;; It requires GNU Emacs 21 or later and Git 1.5.0 and up
;;
;; If you'are using Emacs 20, try changing this:
;;
;; (overlay-put ovl 'face (list :background
;; (cdr (assq 'color (cddddr info)))))
Expand All @@ -77,30 +78,51 @@
;;
;;; Code:

(require 'cl) ; to use `push', `pop'

(defun color-scale (l)
(let* ((colors ())
r g b)
(setq r l)
(while r
(setq g l)
(while g
(setq b l)
(while b
(push (concat "#" (car r) (car g) (car b)) colors)
(pop b))
(pop g))
(pop r))
colors))
(eval-when-compile (require 'cl)) ; to use `push', `pop'


(defun git-blame-color-scale (&rest elements)
"Given a list, returns a list of triples formed with each
elements of the list.
a b => bbb bba bab baa abb aba aaa aab"
(let (result)
(dolist (a elements)
(dolist (b elements)
(dolist (c elements)
(setq result (cons (format "#%s%s%s" a b c) result)))))
result))

;; (git-blame-color-scale "0c" "04" "24" "1c" "2c" "34" "14" "3c") =>
;; ("#3c3c3c" "#3c3c14" "#3c3c34" "#3c3c2c" "#3c3c1c" "#3c3c24"
;; "#3c3c04" "#3c3c0c" "#3c143c" "#3c1414" "#3c1434" "#3c142c" ...)

(defmacro git-blame-random-pop (l)
"Select a random element from L and returns it. Also remove
selected element from l."
;; only works on lists with unique elements
`(let ((e (elt ,l (random (length ,l)))))
(setq ,l (remove e ,l))
e))

(defvar git-blame-dark-colors
(color-scale '("0c" "04" "24" "1c" "2c" "34" "14" "3c")))
(git-blame-color-scale "0c" "04" "24" "1c" "2c" "34" "14" "3c")
"*List of colors (format #RGB) to use in a dark environment.
To check out the list, evaluate (list-colors-display git-blame-dark-colors).")

(defvar git-blame-light-colors
(color-scale '("c4" "d4" "cc" "dc" "f4" "e4" "fc" "ec")))
(git-blame-color-scale "c4" "d4" "cc" "dc" "f4" "e4" "fc" "ec")
"*List of colors (format #RGB) to use in a light environment.
To check out the list, evaluate (list-colors-display git-blame-light-colors).")

(defvar git-blame-ancient-color "dark green")
(defvar git-blame-colors '()
"Colors used by git-blame. The list is built once when activating git-blame
minor mode.")

(defvar git-blame-ancient-color "dark green"
"*Color to be used for ancient commit.")

(defvar git-blame-autoupdate t
"*Automatically update the blame display while editing")
Expand All @@ -125,41 +147,64 @@
"A queue of update requests")
(make-variable-buffer-local 'git-blame-update-queue)

;; FIXME: docstrings
(defvar git-blame-file nil)
(defvar git-blame-current nil)

(defvar git-blame-mode nil)
(make-variable-buffer-local 'git-blame-mode)
(unless (assq 'git-blame-mode minor-mode-alist)
(setq minor-mode-alist
(cons (list 'git-blame-mode " blame")
minor-mode-alist)))

(defvar git-blame-mode-line-string " blame"
"String to display on the mode line when git-blame is active.")

(or (assq 'git-blame-mode minor-mode-alist)
(setq minor-mode-alist
(cons '(git-blame-mode git-blame-mode-line-string) minor-mode-alist)))

;;;###autoload
(defun git-blame-mode (&optional arg)
"Minor mode for displaying Git blame"
"Toggle minor mode for displaying Git blame
With prefix ARG, turn the mode on if ARG is positive."
(interactive "P")
(if arg
(setq git-blame-mode (eq arg 1))
(setq git-blame-mode (not git-blame-mode)))
(cond
((null arg)
(if git-blame-mode (git-blame-mode-off) (git-blame-mode-on)))
((> (prefix-numeric-value arg) 0) (git-blame-mode-on))
(t (git-blame-mode-off))))

(defun git-blame-mode-on ()
"Turn on git-blame mode.
See also function `git-blame-mode'."
(make-local-variable 'git-blame-colors)
(if git-blame-autoupdate
(add-hook 'after-change-functions 'git-blame-after-change nil t)
(remove-hook 'after-change-functions 'git-blame-after-change t))
(git-blame-cleanup)
(if git-blame-mode
(progn
(let ((bgmode (cdr (assoc 'background-mode (frame-parameters)))))
(if (eq bgmode 'dark)
(setq git-blame-colors git-blame-dark-colors)
(setq git-blame-colors git-blame-light-colors)))
(setq git-blame-cache (make-hash-table :test 'equal))
(git-blame-run))
(cancel-timer git-blame-idle-timer)))
(let ((bgmode (cdr (assoc 'background-mode (frame-parameters)))))
(if (eq bgmode 'dark)
(setq git-blame-colors git-blame-dark-colors)
(setq git-blame-colors git-blame-light-colors)))
(setq git-blame-cache (make-hash-table :test 'equal))
(setq git-blame-mode t)
(git-blame-run))

(defun git-blame-mode-off ()
"Turn off git-blame mode.
See also function `git-blame-mode'."
(git-blame-cleanup)
(if git-blame-idle-timer (cancel-timer git-blame-idle-timer))
(setq git-blame-mode nil))

;;;###autoload
(defun git-reblame ()
"Recalculate all blame information in the current buffer"
(unless git-blame-mode
(error "git-blame is not active"))
(interactive)
(unless git-blame-mode
(error "Git-blame is not active"))

(git-blame-cleanup)
(git-blame-run))

Expand Down Expand Up @@ -275,17 +320,18 @@
(t
nil)))


(defun git-blame-new-commit (hash src-line res-line num-lines)
(save-excursion
(set-buffer git-blame-file)
(let ((info (gethash hash git-blame-cache))
(inhibit-point-motion-hooks t)
(inhibit-modification-hooks t))
(when (not info)
(let ((color (pop git-blame-colors)))
(unless color
(setq color git-blame-ancient-color))
;; Assign a random color to each new commit info
;; Take care not to select the same color multiple times
(let ((color (if git-blame-colors
(git-blame-random-pop git-blame-colors)
git-blame-ancient-color)))
(setq info (list hash src-line res-line num-lines
(git-describe-commit hash)
(cons 'color color))))
Expand Down

0 comments on commit 1f71372

Please sign in to comment.