More git files
[emacs.git] / .emacs.d / elisp / mo-git-blame / mo-git-blame.el
index 750eed8..fa9d0d7 100644 (file)
@@ -5,7 +5,8 @@
 
 ;; Author: Moritz Bunkus <moritz@bunkus.org>
 ;; Maintainer: Moritz Bunkus <moritz@bunkus.org>
-;; Version: 0.1.0
+;; Version: 20140409.320
+;; X-Original-Version: 0.1.0
 ;; Keywords: tools
 
 ;; mo-git-blame is free software; you can redistribute it and/or
@@ -87,7 +88,7 @@ interactive use, e.g. the file name, current revision etc.")
   "MoGitBlame menu"
   '("MoGitBlame"
     ["Re-blame for revision at point" mo-git-blame-reblame-for-revision-at t]
-    ["Re-blame for ancestor of revision at point" mo-git-blame-reblame-for-ancestor-of-revision-at-point t]
+    ["Re-blame for ancestor of revision at point" mo-git-blame-reblame-for-ancestor-of-revision-at t]
     ["Raw content for revision at point" mo-git-blame-content-for-revision-at t]
     ["Log for revision at point" mo-git-blame-log-for-revision-at t]
     ["Overwrite file with revision at point" mo-git-blame-overwrite-file-with-revision-at t]
@@ -116,6 +117,12 @@ interactive use, e.g. the file name, current revision etc.")
   :group 'mo-git-blame
   :type 'string)
 
+(defcustom mo-git-blame-git-blame-args ""
+  "Additional arguments to pass to git blame."
+  :group 'mo-git-blame
+  :type 'string)
+
+
 (defcustom mo-git-blame-incremental t
   "Runs `git blame' in the background with the --incremental
 option if this variable is non-nil."
@@ -140,6 +147,17 @@ option if this variable is non-nil."
                  (const :tag "If available" if-available)
                  (const :tag "Never" never)))
 
+(defcustom mo-git-blame-use-magit 'if-available
+  "Controls whether or not magit will be used. Possible choices:
+
+  `never'        -- do not use magit even if it is loaded
+  `if-available' -- use magit if it has been loaded before
+  `always'       -- automatically load magit and use it"
+  :group 'mo-git-blame
+  :type '(choice (const :tag "Always" always)
+                 (const :tag "If available" if-available)
+                 (const :tag "Never" never)))
+
 ;; This function was taken from magit (called 'magit-trim-line' there).
 (defun mo-git-blame-trim-line (str)
   (cond ((string= str "")
@@ -162,17 +180,14 @@ option if this variable is non-nil."
   (mo-git-blame-trim-line (mo-git-blame-git-output args)))
 
 (defun mo-git-blame-get-top-dir (cwd)
-  (let ((cwd (expand-file-name cwd))
-        git-dir)
-    (setq git-dir
-          (or (getenv "GIT_WORK_TREE")
-              (if (file-directory-p cwd)
-                  (let* ((default-directory cwd)
-                         (dir (mo-git-blame-git-string "rev-parse" "--git-dir"))
-                         (dir (concat (or (file-remote-p cwd) "") dir))
-                         (dir (if dir (file-name-directory (expand-file-name dir)) "")))
-                    (if (and dir (file-directory-p dir))
-                        (file-name-as-directory dir))))))
+  (let* ((cwd (expand-file-name cwd))
+         (git-dir (or (getenv "GIT_WORK_TREE")
+                      (if (file-directory-p cwd)
+                          (let* ((default-directory cwd)
+                                 (dir (mo-git-blame-git-string "rev-parse" "--show-toplevel"))
+                                 (dir (concat (or (file-remote-p cwd) "") dir)))
+                            (if (and dir (file-directory-p dir))
+                                (file-name-as-directory dir)))))))
     (or git-dir
         (error "No Git repository found"))))
 
@@ -352,13 +367,29 @@ git is already/still running."
   (interactive)
   (mo-git-blame-log-for-revision (plist-get mo-git-blame-vars :current-revision)))
 
+(defun mo-git-blame-show-revision--diff-mode (revision)
+  "Internal function that fills the current buffer with revision using diff-mode"
+  (erase-buffer)
+  (mo-git-blame-run "show" revision)
+  (goto-char (point-min))
+  (diff-mode))
+
+(defun mo-git-blame-show-revision--magit (revision)
+  "Internal function that fills the current buffer with revision using magit"
+  (let ((magit-commit-buffer-name (buffer-name)))
+    (magit-show-commit revision)))
+
 (defun mo-git-blame-show-revision (revision)
-  (let ((buffer (mo-git-blame-get-output-buffer)))
+  (let ((buffer (mo-git-blame-get-output-buffer))
+        (the-func (cond ((eq mo-git-blame-use-magit 'always)
+                         (require 'magit)
+                         'mo-git-blame-show-revision--magit)
+                        ((and (eq mo-git-blame-use-magit 'if-available)
+                              (functionp 'magit-show-commit))
+                         'mo-git-blame-show-revision--magit)
+                        (t 'mo-git-blame-show-revision--diff-mode))))
     (with-current-buffer buffer
-      (erase-buffer)
-      (mo-git-blame-run "show" revision)
-      (goto-char (point-min))
-      (diff-mode))
+      (funcall the-func revision))
     (display-buffer buffer)))
 
 (defun mo-git-blame-show-revision-at ()
@@ -512,6 +543,11 @@ from elisp.
         truncate-lines t)
   (use-local-map mo-git-blame-mode-map))
 
+(defun mo-git-blame--make-args (args)
+  (delete ""
+          (append (list mo-git-blame-git-blame-args)
+                  args)))
+
 (defun mo-git-blame-run-blame-normally (start-line lines-to-blame)
   (let* ((num-content-lines (mo-git-blame-number-of-content-lines))
          (num-lines-to-append (if (and start-line
@@ -527,7 +563,7 @@ from elisp.
     (if start-line
         (setq args (append (list "-L" (format "%d,+%d" start-line lines-to-blame))
                            args)))
-    (apply 'mo-git-blame-run "blame" args)
+    (apply 'mo-git-blame-run "blame" (mo-git-blame--make-args args))
 
     (if num-lines-to-append
         (dotimes (i num-lines-to-append)
@@ -544,7 +580,7 @@ from elisp.
         (setq args (append (list "-L" (format "%d,+%d" start-line lines-to-blame))
                            args)))
     (mo-git-blame-assert-not-running)
-    (apply 'mo-git-blame-run* "blame" args)))
+    (apply 'mo-git-blame-run* "blame" (mo-git-blame--make-args args))))
 
 (defun mo-git-blame-init-blame-buffer (start-line lines-to-blame)
   (if mo-git-blame-incremental
@@ -757,7 +793,15 @@ blamed."
   (interactive)
   (if (null (buffer-file-name))
       (error "The current buffer is not associated with a file."))
-  (mo-git-blame-file (buffer-file-name)))
+  (mo-git-blame-file (file-truename (buffer-file-name))))
+
+;;;###autoload
+(defun mo-git-blame-current-for-revision (revision)
+  "Calls `mo-git-blame-file' for `revision' for the current buffer."
+  (interactive "sRevision: ")
+  (if (null (buffer-file-name))
+      (error "The current buffer is not associated with a file."))
+  (mo-git-blame-file (file-truename (buffer-file-name)) revision))
 
 (provide 'mo-git-blame)