Update/improve sy-git-log, sy-git-blame.
authorSteve Youngs <steve@sxemacs.org>
Thu, 19 Oct 2017 11:46:55 +0000 (21:46 +1000)
committerSteve Youngs <steve@sxemacs.org>
Thu, 19 Oct 2017 11:46:55 +0000 (21:46 +1000)
With this change, viewing the log looks much nicer with a little
font-locking.  You can also pass on custom git log options via a 2nd
prefix arg.

* sy-git.el (sy-git-log): Allow setting custom git log options via
a 2nd prefix arg. Add some font-locking. Don't use electric-help.
(sy-git-log-font-lock-keywords): New.
(sy-git-blame): Don't use electric-help, shrink the window if the
buffer is smaller.

Signed-off-by: Steve Youngs <steve@sxemacs.org>
sy-git.el

index 962c641..7c8b63e 100644 (file)
--- a/sy-git.el
+++ b/sy-git.el
@@ -5,7 +5,7 @@
 ;; Author:     Steve Youngs <steve@sxemacs.org>
 ;; Maintainer: Steve Youngs <steve@sxemacs.org>
 ;; Created:    <2015-07-05>
-;; Time-stamp: <Monday Oct 16, 2017 09:05:17 steve>
+;; Time-stamp: <Thursday Oct 19, 2017 21:43:53 steve>
 ;; Homepage:   http://git.sxemacs.org/slh
 ;; Keywords:   git, tools, convenience
 
 (require 'ediff)
 (require 'diff-mode)
 
-;; diff
+
+(defun sy-git-check-hook (hook)
+  "Return non-nil when HOOK script exists and is usable.
+
+By \"usable\" we mean for `sy-git-add-log-entry'."
+  (let ((hookname (file-basename hook)))
+    (when (file-exists-p hook)
+      (with-temp-buffer
+       (insert-file-contents-literally hook)
+       (goto-char (point-min))
+       (cond
+        ((equal hookname "commit-msg")
+         (re-search-forward (regexp-quote "sed -i '/^#/d'") nil t))
+        ((equal hookname "post-commit")
+         (re-search-forward (regexp-quote "rm -f ${LOG}") nil t))
+        (t nil))))))
+
+;;; diff
+;; FIXME: might be nice to be able to diff against other revisions
+;; aside from HEAD.
 (defun sy-git-diff ()
   "Show a diff of the current file against HEAD."
   (interactive)
       (vc-version-other-window "HEAD")
       (ediff-buffers bufferA bufferB))))
 
-;; blame
+;;; blame
 (defun sy-git-blame ()
   "Display git blame for the current file.
 
@@ -89,6 +108,9 @@ If the region is active the output will be for just the lines of the
 file within the region."
   (interactive)
   (let ((gitcmd "git blame ")
+       (cb (current-buffer))
+       (gb (format "*GIT Blame::%s*"
+                   (file-basename (buffer-file-name))))
        beg end)
     (when (region-active-p)
       (setq beg (line-number (region-beginning))
@@ -96,50 +118,85 @@ file within the region."
     (and beg end
         (setq gitcmd (concat gitcmd (format "-L%d,%d " beg end))))
     (setq gitcmd (concat gitcmd (file-basename (buffer-file-name))))
-    (with-electric-help
-     #'(lambda ()
-        (setq truncate-lines t)
-        (insert
-         (with-temp-buffer
-           (insert (shell-command-to-string gitcmd))
-           (buffer-string (current-buffer)))))
-     "*GIT Blame*")))
-
-;; log
-(defun sy-git-log (all)
-  "Display git log of current file.
+    (push-window-configuration)
+    (with-current-buffer (get-buffer-create gb)
+      (erase-buffer)
+      (setq truncate-lines t)
+      (insert (shell-command-to-string gitcmd))
+      (goto-char (point-min))
+      (view-mode cb #'(lambda (gb)
+                     (kill-buffer gb)
+                     (pop-window-configuration))))
+    (pop-to-buffer gb)
+    (shrink-window-if-larger-than-buffer)))
 
-With prefix arg, ALL, display the log for the entire repo."
-  (interactive "p")
-  (let ((gitcmd "git log --format=fuller"))
-    (unless current-prefix-arg
-      (setq gitcmd
-           (concat gitcmd
-                   (format " %s" (file-basename (buffer-file-name))))))
-    (with-electric-help
-     #'(lambda ()
-        (insert
-         (with-temp-buffer
-           (insert (shell-command-to-string gitcmd))
-           (buffer-string (current-buffer)))))
-     "*GIT Log*")))
+;;; log
+(defvar sy-git-log-font-lock-keywords
+  '(;;
+    ;; Headers
+    ("^commit .*$"
+     (0 font-lock-warning-face))
+    (#r"^\(Author\(Date\)?:\|Commit\(Date\)?:\|Date:\|Merge:\)"
+       (1 gnus-header-content))
+    ;; date
+    (#r"Date:\(.*$\)"
+       (1 change-log-date-face))
+    ;; name/email
+    (#r":\s-+\(.*\)\s-+<\(.*\)>"
+       (1 change-log-name-face)
+       (2 change-log-email-face))
+    ;; file name
+    (#r"^\s-+\* \([^ ,:(]+\)"
+       (1 change-log-file-face))
+    ;; Function or variable names.
+    ("(\\([^) ,:\n]+\\)"
+     (1 change-log-list-face)
+     ("\\=, *\\([^) ,:\n]+\\)" nil nil
+      (1 change-log-list-face)))
+    ;; Signed-off
+    (#r"\(Signed-off\|Reviewed\|Reported\|Acked\)-by:\|Cc:"
+       (0 gnus-header-content))))
 
-(defun sy-git-check-hook (hook)
-  "Return non-nil when HOOK script exists and is usable.
+(defun sy-git-log (opts)
+  "Display git log of current file.
 
-By \"usable\" we mean for `sy-git-add-log-entry'."
-  (let ((hookname (file-basename hook)))
-    (when (file-exists-p hook)
-      (with-temp-buffer
-       (insert-file-contents-literally hook)
-       (goto-char (point-min))
-       (cond
-        ((equal hookname "commit-msg")
-         (re-search-forward (regexp-quote "sed -i '/^#/d'") nil t))
-        ((equal hookname "post-commit")
-         (re-search-forward (regexp-quote "rm -f ${LOG}") nil t))
-        (t nil))))))
+With one prefix arg, OPTS, display the log for the entire repo.
+With two prefix args, prompt for options to pass to git-log.
+
+The default options used are: `--shortstat', except when two prefix
+args are used and then the only options used are those the user
+supplies."
+  (interactive "P")
+  (let ((cb (current-buffer))
+       (gb "*GIT Log::%s*")
+       (gitcmd "git log"))
+    (case (car opts)
+      ;; 1 prefix arg, log for whole repo
+      (4 (setq gitcmd (concat gitcmd " --shortstat")
+              gb (format gb "Whole Repo")))
+      ;; 2 prefix args, prompt for options
+      (16 (setq gitcmd (concat gitcmd " "
+                              (read-string "Git Log options: "))
+               gb (format gb "Custom")))
+      ;; default, show log of current file
+      (otherwise (setq gitcmd (concat gitcmd
+                                     " --shortstat "
+                                     (file-basename (buffer-file-name)))
+                      gb (format gb (file-basename (buffer-file-name))))))
+    (push-window-configuration)
+    (with-current-buffer (get-buffer-create gb)
+      (erase-buffer)
+      (set (make-local-variable 'font-lock-defaults)
+          '(sy-git-log-font-lock-keywords t t))
+      (insert (shell-command-to-string gitcmd))
+      (goto-char (point-min))
+      (view-mode cb #'(lambda (gb)
+                      (kill-buffer gb)
+                      (pop-window-configuration))))
+    (pop-to-buffer gb)
+    (shrink-window-if-larger-than-buffer)))
 
+;;; add-log
 (defun sy-git-add-log-entry (&optional newlog)
   "*A wrapper for `add-change-log-entry'.