Merge branch 'post1.5.1/blame.el'

* 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
This commit is contained in:
Junio C Hamano 2007-04-04 00:10:03 -07:00
commit 1f71372711

View file

@ -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.
@ -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)))))
@ -77,30 +78,51 @@
;;
;;; Code:
(require 'cl) ; to use `push', `pop'
(eval-when-compile (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))
(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.
(defvar git-blame-ancient-color "dark green")
To check out the list, evaluate (list-colors-display git-blame-light-colors).")
(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")
@ -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))
@ -275,7 +320,6 @@
(t
nil)))
(defun git-blame-new-commit (hash src-line res-line num-lines)
(save-excursion
(set-buffer git-blame-file)
@ -283,9 +327,11 @@
(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))))