Function: vc-annotate

vc-annotate is an autoloaded, interactive and byte-compiled function defined in vc-annotate.el.gz.

Signature

(vc-annotate FILE REV &optional DISPLAY-MODE BUF MOVE-POINT-TO BACKEND)

Documentation

Display the edit history of the current FILE using colors.

This command creates a buffer that shows, for each line of the current file, when it was last edited and by whom. Additionally, colors are used to show the age of each line--blue means oldest, red means youngest, and intermediate colors indicate intermediate ages. By default, the time scale stretches back one year into the past; everything that is older than that is shown in blue.

With a prefix argument, this command asks two questions in the minibuffer. First, you may enter a revision number REV; then the buffer displays and annotates that revision instead of the working revision
(type RET in the minibuffer to leave that default unchanged). Then,
you are prompted for the time span in days which the color range should cover. For example, a time span of 20 days means that changes over the past 20 days are shown in red to blue, according to their age, and everything that is older than that is shown in blue.

If MOVE-POINT-TO is given, move the point to that line.

If BACKEND is given, use that VC backend.

Customization variables:

vc-annotate-menu-elements customizes the menu elements of the mode-specific menu. vc-annotate-color-map and vc-annotate-very-old-color define the mapping of time to colors. vc-annotate-background specifies the background color. vc-annotate-background-mode specifies whether the color map should be applied to the background or to the foreground.

View in manual

Probably introduced at or before Emacs version 23.2.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/vc/vc-annotate.el.gz
;;;###autoload
(defun vc-annotate (file rev &optional display-mode buf move-point-to backend)
  "Display the edit history of the current FILE using colors.

This command creates a buffer that shows, for each line of the current
file, when it was last edited and by whom.  Additionally, colors are
used to show the age of each line--blue means oldest, red means
youngest, and intermediate colors indicate intermediate ages.  By
default, the time scale stretches back one year into the past;
everything that is older than that is shown in blue.

With a prefix argument, this command asks two questions in the
minibuffer.  First, you may enter a revision number REV; then the buffer
displays and annotates that revision instead of the working revision
\(type RET in the minibuffer to leave that default unchanged).  Then,
you are prompted for the time span in days which the color range
should cover.  For example, a time span of 20 days means that changes
over the past 20 days are shown in red to blue, according to their
age, and everything that is older than that is shown in blue.

If MOVE-POINT-TO is given, move the point to that line.

If BACKEND is given, use that VC backend.

Customization variables:

`vc-annotate-menu-elements' customizes the menu elements of the
mode-specific menu.  `vc-annotate-color-map' and
`vc-annotate-very-old-color' define the mapping of time to colors.
`vc-annotate-background' specifies the background color.
`vc-annotate-background-mode' specifies whether the color map
should be applied to the background or to the foreground."
  (interactive
   (save-current-buffer
     (let ((name (if (length= (cadr vc-buffer-overriding-fileset) 1)
                     (caadr vc-buffer-overriding-fileset)
                   (vc-ensure-vc-buffer)
                   buffer-file-name)))
       (list name
	     (let ((def (or vc-buffer-revision
                            (funcall (if vc-annotate-use-short-revision
                                         #'vc-short-revision
                                       #'vc-working-revision)
                                     name))))
	       (if (null current-prefix-arg) def
                 (vc-read-revision
		  (format-prompt "Annotate from revision" def)
		  (list name) nil def)))
	     (if (null current-prefix-arg)
                 vc-annotate-display-mode
	       (float (string-to-number
		       (read-string (format-prompt "Annotate span days" 20)
				    nil nil "20"))))))))
  (setq vc-annotate-display-mode display-mode) ;Not sure why.  --Stef
  (let* ((backend (or backend
                      (car vc-buffer-overriding-fileset)
                      (vc-backend file)))
         (file-buffer (get-file-buffer file))
         (temp-buffer-name
          (format "*Annotate %s (rev %s)*"
                  (if file-buffer
                      (buffer-name file-buffer)
                    ;; Try to avoid ambiguity.
                    (file-relative-name file
                                        (vc-call-backend backend 'root
                                                         default-directory)))
                  rev))
         (temp-buffer-show-function 'vc-annotate-display-select)
         ;; If BUF is specified, we presume the caller maintains current line,
         ;; so we don't need to do it here.  This implementation may give
         ;; strange results occasionally in the case of REV != WORKFILE-REV.
         (current-line (or move-point-to (unless buf
					   (save-restriction
					     (widen)
					     (line-number-at-pos))))))
    (message "Annotating...")
    ;; If BUF is specified it tells in which buffer we should put the
    ;; annotations.  This is used when switching annotations to another
    ;; revision, so we should update the buffer's name.
    (when buf (with-current-buffer buf
		(rename-buffer temp-buffer-name t)
		;; In case it had to be uniquified.
		(setq temp-buffer-name (buffer-name))))
    (let ((coding-system-for-read buffer-file-coding-system))
      (with-output-to-temp-buffer temp-buffer-name
        ;; For a VC backend running on DOS/Windows, it's normal to
        ;; produce CRLF EOLs even if the original file has Unix EOLs,
        ;; which will show ^M characters in the Annotate buffer.  (One
        ;; known case in point is "svn annotate".)  Prevent that by
        ;; forcing DOS EOL decoding.
        (if (memq system-type '(windows-nt ms-dos))
            (setq coding-system-for-read
                  (coding-system-change-eol-conversion coding-system-for-read
                                                       'dos)))
        (vc-call-backend backend 'annotate-command file
                         (get-buffer temp-buffer-name) rev)
        ;; we must setup the mode first, and then set our local
        ;; variables before the show-function is called at the exit of
        ;; with-output-to-temp-buffer
        (with-current-buffer temp-buffer-name
          (unless (equal major-mode 'vc-annotate-mode)
            (vc-annotate-mode))
          (setq-local vc-annotate-backend backend)
          (setq-local vc-buffer-overriding-fileset `(,backend (,file)))
          (setq-local vc-buffer-revision rev)
          (setq-local vc-annotate-parent-display-mode display-mode)
          (kill-local-variable 'revert-buffer-function))))

    (with-current-buffer temp-buffer-name
      (vc-run-delayed
        ;; Ideally, we'd rather not move point if the user has already
        ;; moved it elsewhere, but really point here is not the position
        ;; of the user's cursor :-(
        (when current-line              ;(and (bobp))
          (goto-char (point-min))
          (forward-line (1- current-line))
          (setq vc-sentinel-movepoint (point)))
        (unless (active-minibuffer-window)
          (message "Annotating... done"))))))