;; internal buffer-local variables
(defvar vc-annotate-backend nil)
-(defvar vc-annotate-parent-file nil)
-(defvar vc-annotate-parent-rev nil)
(defvar vc-annotate-parent-display-mode nil)
(defconst vc-annotate-font-lock-keywords
(defvar vc-sentinel-movepoint)
;;;###autoload
-(defun vc-annotate (file rev &optional display-mode buf move-point-to vc-bk)
+(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
If MOVE-POINT-TO is given, move the point to that line.
-If VC-BK is given used that VC backend.
+If BACKEND is given, use that VC backend.
Customization variables:
should be applied to the background or to the foreground."
(interactive
(save-current-buffer
- (vc-ensure-vc-buffer)
- (list buffer-file-name
- (let ((def (funcall (if vc-annotate-use-short-revision
- #'vc-short-revision
- #'vc-working-revision)
- buffer-file-name)))
- (if (null current-prefix-arg) def
- (vc-read-revision
- (format-prompt "Annotate from revision" def)
- (list buffer-file-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")))))))
- (vc-ensure-vc-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* ((temp-buffer-name (format "*Annotate %s (rev %s)*" (buffer-name) rev))
(temp-buffer-show-function 'vc-annotate-display-select)
(rename-buffer temp-buffer-name t)
;; In case it had to be uniquified.
(setq temp-buffer-name (buffer-name))))
- (with-output-to-temp-buffer temp-buffer-name
- (let ((backend (or vc-bk (vc-backend file)))
- (coding-system-for-read buffer-file-coding-system))
- ;; 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-annotate-parent-file file)
- (setq-local vc-annotate-parent-rev rev)
- (setq-local vc-annotate-parent-display-mode display-mode)
- (kill-local-variable 'revert-buffer-function))))
+ (let ((backend (or backend
+ (car vc-buffer-overriding-fileset)
+ (vc-backend file)))
+ (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
(interactive)
(if (not (equal major-mode 'vc-annotate-mode))
(message "Cannot be invoked outside of a vc annotate buffer")
- (let ((warp-rev (vc-working-revision vc-annotate-parent-file)))
- (if (equal warp-rev vc-annotate-parent-rev)
+ (let ((warp-rev (vc-working-revision (cadr vc-buffer-overriding-fileset))))
+ (if (equal warp-rev vc-buffer-revision)
(message "Already at revision %s" warp-rev)
(vc-annotate-warp-revision warp-rev)))))
'annotate-extract-revision-at-line)))
(if (or (null rev) (consp rev))
rev
- (cons rev vc-annotate-parent-file))))
+ (cons rev (cadr vc-buffer-overriding-fileset)))))
(defun vc-annotate-revision-at-line ()
"Visit the annotation of the revision identified in the current line."
(let ((rev-at-line (vc-annotate-extract-revision-at-line)))
(if (not rev-at-line)
(message "Cannot extract revision number from the current line")
- (if (and (equal (car rev-at-line) vc-annotate-parent-rev)
- (string= (cdr rev-at-line) vc-annotate-parent-file))
+ (if (and (equal (car rev-at-line) vc-buffer-revision)
+ (string= (cdr rev-at-line) (cadr vc-buffer-overriding-fileset)))
(message "Already at revision %s" rev-at-line)
(vc-annotate-warp-revision (car rev-at-line) (cdr rev-at-line)))))))
(newrev nil))
(cond
((and (integerp revspec) (> revspec 0))
- (setq newrev vc-annotate-parent-rev)
+ (setq newrev vc-buffer-revision)
(while (and (> revspec 0) newrev)
(setq newrev (vc-call-backend vc-annotate-backend 'next-revision
- (or file vc-annotate-parent-file) newrev))
+ (or file
+ (cadr vc-buffer-overriding-fileset))
+ newrev))
(setq revspec (1- revspec)))
(unless newrev
(message "Cannot increment %d revisions from revision %s"
- revspeccopy vc-annotate-parent-rev)))
+ revspeccopy vc-buffer-revision)))
((and (integerp revspec) (< revspec 0))
- (setq newrev vc-annotate-parent-rev)
+ (setq newrev vc-buffer-revision)
(while (and (< revspec 0) newrev)
(setq newrev (vc-call-backend vc-annotate-backend 'previous-revision
- (or file vc-annotate-parent-file) newrev))
+ (or file
+ (cadr vc-buffer-overriding-fileset))
+ newrev))
(setq revspec (1+ revspec)))
(unless newrev
(message "Cannot decrement %d revisions from revision %s"
- (- 0 revspeccopy) vc-annotate-parent-rev)))
+ (- 0 revspeccopy) vc-buffer-revision)))
((stringp revspec) (setq newrev revspec))
(t (error "Invalid argument to vc-annotate-warp-revision")))
(when newrev
- (vc-annotate (or file vc-annotate-parent-file) newrev
+ (vc-annotate (or file
+ (cadr vc-buffer-overriding-fileset))
+ newrev
vc-annotate-parent-display-mode
buf
;; Pass the current line so that vc-annotate will
(let ((line (save-restriction
(widen)
(line-number-at-pos)))
- (rev vc-annotate-parent-rev))
+ (rev vc-buffer-revision)
+ (file (cadr vc-buffer-overriding-fileset)))
(pop-to-buffer
(or (and (buffer-live-p vc-parent-buffer)
vc-parent-buffer)
- (and (file-exists-p vc-annotate-parent-file)
- (find-file-noselect vc-annotate-parent-file))
- (error "File not found: %s" vc-annotate-parent-file)))
+ (and (file-exists-p file) (find-file-noselect file))
+ (error "File not found: %s" file)))
(save-restriction
(widen)
(goto-char (point-min))
(declare-function vc-dir-deduce-fileset "vc-dir" (&optional state-model-only-files))
(declare-function dired-vc-deduce-fileset "dired-aux" (&optional state-model-only-files not-state-changing))
+(defvar-local vc-buffer-overriding-fileset nil
+ "Specialized, static value for `vc-deduce-fileset' for this buffer.
+If non-nil, this should be a list of length 2 or 5.
+See `vc-deduce-fileset' regarding these possible forms.
+If this list is of length 2, it will be used only when the
+STATE-MODEL-ONLY-FILES argument to `vc-deduce-fileset' is nil.")
+
+(defvar-local vc-buffer-revision nil
+ "VCS revision to which this buffer's contents corresponds.
+Lisp code which sets this should also set `vc-buffer-overriding-fileset'
+such that the buffer's local variables also specify a VC backend,
+rendering the value of this variable unambiguous.")
+
(defun vc-deduce-fileset (&optional not-state-changing
allow-unregistered
state-model-only-files)
(set-buffer (buffer-base-buffer)))
(let (backend)
(cond
+ ((and vc-buffer-overriding-fileset
+ (not (or (length= vc-buffer-overriding-fileset 2)
+ (length= vc-buffer-overriding-fileset 5))))
+ (error "Invalid value for `vc-buffer-overriding-fileset' %S"
+ vc-buffer-overriding-fileset))
+ ((and (or (not state-model-only-files)
+ (length= vc-buffer-overriding-fileset 5))
+ vc-buffer-overriding-fileset))
((derived-mode-p 'vc-dir-mode)
(vc-dir-deduce-fileset state-model-only-files))
((derived-mode-p 'dired-mode)
(list buffer-file-name))))
(t (error "File is not under version control")))))
+;; This function should possibly honor `vc-buffer-overriding-fileset'
+;; when the fileset consists of a single file, but only if that file is
+;; part of the current working revision, i.e., actually on disk now.
(defun vc-ensure-vc-buffer ()
"Make sure that the current buffer visits a version-controlled file."
(cond
Saves the buffer to the file."
(let ((automatic-backup (vc-version-backup-file-name file revision))
(filebuf (or (get-file-buffer file) (current-buffer)))
- (filename (vc-version-backup-file-name file revision 'manual)))
+ (filename (vc-version-backup-file-name file revision 'manual))
+ (backend (or backend (vc-backend file))))
(unless (file-exists-p filename)
(if (file-exists-p automatic-backup)
(rename-file automatic-backup filename nil)
;; Change buffer to get local value of
;; vc-checkout-switches.
(with-current-buffer filebuf
- (if backend
- (vc-call-backend backend 'find-revision file revision outbuf)
- (vc-call find-revision file revision outbuf)))))
+ (vc-call-backend backend 'find-revision
+ file revision outbuf))))
(setq failed nil))
(when (and failed (file-exists-p filename))
(delete-file filename))))
(vc-mode-line file))
(message "Checking out %s...done" filename)))
- (let ((result-buf (find-file-noselect filename)))
+ (let ((result-buf (find-file-noselect filename))
+ (file (expand-file-name file))) ; ensure it's absolute
(with-current-buffer result-buf
- ;; Set the parent buffer so that things like
- ;; C-x v g, C-x v l, ... etc work.
- (setq-local vc-parent-buffer filebuf))
+ (setq-local vc-parent-buffer filebuf
+ vc-buffer-overriding-fileset `(,backend (,file))
+ vc-buffer-revision revision))
result-buf)))
(defun vc-find-revision-no-save (file revision &optional backend buffer)
`buffer-file-name' to the name constructed from the file name and the
revision number.
Unlike `vc-find-revision-save', doesn't save the buffer to the file."
- (let* ((buffer (when (buffer-live-p buffer) buffer))
+ (let* ((buffer (and (buffer-live-p buffer) buffer))
(filebuf (or buffer (get-file-buffer file) (current-buffer)))
- (filename (unless buffer (vc-version-backup-file-name file revision 'manual))))
+ (filename (and (not buffer)
+ (vc-version-backup-file-name file revision 'manual)))
+ (backend (or backend (vc-backend file))))
(unless (and (not buffer)
(or (get-file-buffer filename)
(file-exists-p filename)))
(unless buffer (setq buffer-file-name filename))
(let ((outbuf (current-buffer)))
(with-current-buffer filebuf
- (if backend
- (vc-call-backend backend 'find-revision file revision outbuf)
- (vc-call find-revision file revision outbuf))))
+ (vc-call-backend backend 'find-revision file revision outbuf)))
(decode-coding-inserted-region (point-min) (point-max) file)
(after-insert-file-set-coding (- (point-max) (point-min)))
(goto-char (point-min))
(kill-buffer (get-file-buffer filename)))))))
(let ((result-buf (or buffer
(get-file-buffer filename)
- (find-file-noselect filename))))
+ (find-file-noselect filename)))
+ (file (expand-file-name file))) ; ensure it's absolute
(with-current-buffer result-buf
- (setq-local vc-parent-buffer filebuf))
+ (setq-local vc-parent-buffer filebuf
+ vc-buffer-overriding-fileset `(,backend (,file))
+ vc-buffer-revision revision))
result-buf)))
;; Header-insertion code
(let* ((vc-fileset (vc-deduce-fileset t)) ;FIXME: Why t? --Stef
(backend (car vc-fileset))
(files (cadr vc-fileset))
-;; (working-revision (or working-revision (vc-working-revision (car files))))
- )
+ (working-revision (or working-revision vc-buffer-revision)))
(vc-print-log-internal backend files working-revision nil limit)))
;;;###autoload