commit - 82289421895601458f16fa160107b9154be83342
commit + 3f25d9ffc6f214200f4e66c4d362bad00c109ca6
blob - 746bd0be40c5a89f5ec41c9a37e9b9747025ff01
blob + a248730bf65488fd35e54015185882bde0454b0e
--- vc-got.el
+++ vc-got.el
;; - update-changelog NOT IMPLEMENTED
;; * diff DONE
;; - revision-completion-table NOT IMPLEMENTED
-;; - annotate-command NOT IMPLEMENTED
-;; - annotate-time NOT IMPLEMENTED
+;; - annotate-command DONE
+;; - annotate-time DONE
;; - annotate-current-time NOT IMPLEMENTED
-;; - annotate-extract-revision-at-line NOT IMPLEMENTED
+;; - annotate-extract-revision-at-line DONE
;; - region-history NOT IMPLEMENTED
;; - region-history-mode NOT IMPLEMENTED
;; - mergebase NOT IMPLEMENTED
;; - root DONE
;; - ignore NOT IMPLEMENTED
;; - ignore-completion-table NOT IMPLEMENTED
-;; - previous-revision NOT IMPLEMENTED
-;; - next-revision NOT IMPLEMENTED
+;; - previous-revision DONE
+;; - next-revision DONE
;; - log-edit-mode NOT IMPLEMENTED
;; - check-headers NOT IMPLEMENTED
;; - delete-file NOT IMPLEMENTED
(require 'cl-seq)
(require 'seq)
(require 'vc)
+(require 'vc-annotate)
(defgroup vc-got nil
"VC GoT backend."
(dolist (file files)
(vc-got--diff file)))
(t (error "Not implemented")))))))
+
+(defun vc-got-annotate-command (file buf &optional rev)
+ "Show annotated contents of FILE in buffer BUF. If given, use revision REV."
+ (let (process-file-side-effects)
+ (with-current-buffer buf
+ ;; FIXME: vc-ensure-vc-buffer won't recognise this buffer as managed
+ ;; by got unless vc-parent-buffer points to a buffer managed by got.
+ ;; investigate why this is needed.
+ (set (make-local-variable 'vc-parent-buffer) (find-file-noselect file))
+ (apply #'vc-got--call "blame" (if rev
+ (list "-c" rev file)
+ (list file))))))
+
+(defconst vc-got--annotate-re
+ (concat "^[0-9]\\{1,\\}) " ; line number followed by )
+ "\\([a-z0-9]+\\) " ; SHA-1 of commit
+ "\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\) " ; year-mm-dd
+ "\\([^ ]\\)+ ") ; author
+ "Regexp to match annotation output lines.
+
+Provides capture groups for:
+1. revision id
+2. date of commit
+3. author of commit")
+
+(defconst vc-got--commit-re "^commit \\([a-z0-9]+\\)"
+ "Regexp to match commit lines.
+
+Provides capture group for the commit revision id.")
+
+(defun vc-got-annotate-time ()
+ "Return the time of the next line of annotation at or after point.
+Value is returned as floating point fractional number of days."
+ (save-excursion
+ (beginning-of-line)
+ (when (looking-at vc-got--annotate-re)
+ (let ((str (match-string-no-properties 2)))
+ (vc-annotate-convert-time
+ (encode-time 0 0 0
+ (string-to-number (substring str 8 10))
+ (string-to-number (substring str 5 7))
+ (string-to-number (substring str 0 4))))))))
+(defun vc-got-annotate-extract-revision-at-line ()
+ "Returns revision corresponding to the current line or nil."
+ (save-excursion
+ (beginning-of-line)
+ (when (looking-at vc-got--annotate-re)
+ (match-string-no-properties 1))))
+
+(defun vc-got-previous-revision (file rev)
+ "Return the revision number that precedes REV for FILE, or nil if no such revision exists."
+ (with-temp-buffer
+ (vc-got--log file 2 rev nil nil t)
+ (goto-char (point-min))
+ (keep-lines "^commit")
+ (when (looking-at vc-got--commit-re)
+ (match-string-no-properties 1))))
+
+(defun vc-got-next-revision (file rev)
+ "Return the revision number that follows REV for FILE, or nil
+ if no such revision exists."
+ (with-temp-buffer
+ (vc-got--log file nil nil rev)
+ (keep-lines "^commit" (point-min) (point-max))
+ (goto-char (point-max))
+ (forward-line -1) ;; return from empty line to last actual commit
+ (unless (= (point) (point-min))
+ (forward-line -1)
+ (when (looking-at vc-got--commit-re)
+ (match-string-no-properties 1)))))
+
(provide 'vc-got)
;;; vc-got.el ends here