From: Chong Yidong Date: Mon, 14 Feb 2011 01:49:24 +0000 (-0500) Subject: Add Log View toggle and log format customization for Git and Hg. X-Git-Tag: emacs-pretest-24.0.90~104^2~275^2~886 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=33f6cf7b4c003932ae6fd86597351610b037fd29;p=emacs.git Add Log View toggle and log format customization for Git and Hg. * lisp/vc/vc-git.el (vc-git-root-log-format): New option for customizing log format. (vc-git-print-log, vc-git-log-outgoing, vc-git-log-incoming) (vc-git-log-view-mode): Use it. (vc-git-expanded-log-entry): New function. (vc-git-log-view-mode): Use it. Truncate lines in root log. * lisp/vc/vc-hg.el (vc-hg-root-log-template): New option for customizing log format. (vc-hg-print-log): Use it. (vc-hg-expanded-log-entry): New function. (vc-hg-log-view-mode): Use vc-hg-root-log-template and vc-hg-expanded-log-entry. Truncate lines in root log. * lisp/vc/vc-bzr.el (vc-bzr-log-view-mode): Truncate lines in root log. * lisp/vc/log-view.el (log-view-mode-menu): Add log-view-toggle-entry-display. --- diff --git a/etc/NEWS b/etc/NEWS index c8bfffcd789..a6461b2c60e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -606,14 +606,14 @@ The vc-merge command now runs a "merge" operation, if it is supported. This merges another branch into the current one. This command prompts the user for specifics, e.g. a merge source. -**** Currently supported by Bzr, Git, and Mercurial. +**** Currently supported for Bzr, Git, and Mercurial. *** Log entries in some Log View buffers can be toggled to display a longer description by typing RET (log-view-toggle-entry-display). In the Log View buffers made by `C-x v L' (vc-print-root-log), you can use this to display the full log entry for the revision at point. -**** Currently supported by Bzr. +**** Currently supported for Bzr, Git, and Mercurial. **** Packages using Log View mode can enable this functionality by binding `log-view-expanded-log-entry-function' to a suitable function. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index ced87bb69a1..742cbfc9267 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,24 @@ +2011-02-14 Chong Yidong + + * vc/vc-git.el (vc-git-root-log-format): New option for + customizing log format. + (vc-git-print-log, vc-git-log-outgoing, vc-git-log-incoming) + (vc-git-log-view-mode): Use it. + (vc-git-expanded-log-entry): New function. + (vc-git-log-view-mode): Use it. Truncate lines in root log. + + * vc/vc-hg.el (vc-hg-root-log-template): New option for + customizing log format. + (vc-hg-print-log): Use it. + (vc-hg-expanded-log-entry): New function. + (vc-hg-log-view-mode): Use vc-hg-root-log-template and + vc-hg-expanded-log-entry. Truncate lines in root log. + + * vc/vc-bzr.el (vc-bzr-log-view-mode): Truncate lines in root log. + + * vc/log-view.el (log-view-mode-menu): Add + log-view-toggle-entry-display. + 2011-02-14 Glenn Morris * dired-x.el: Don't require man when compiling. diff --git a/lisp/vc/log-view.el b/lisp/vc/log-view.el index 3753904324b..fa731e77a6e 100644 --- a/lisp/vc/log-view.el +++ b/lisp/vc/log-view.el @@ -168,6 +168,8 @@ :help "Annotate the version at point"] ["Modify Log Comment" log-view-modify-change-comment :help "Edit the change comment displayed at point"] + ["Toggle Details at Point" log-view-toggle-entry-display + :active log-view-expanded-log-entry-function] "-----" ["Next Log Entry" log-view-msg-next :help "Go to the next count'th log message"] diff --git a/lisp/vc/vc-bzr.el b/lisp/vc/vc-bzr.el index 09a622e8fed..a36fdc60d15 100644 --- a/lisp/vc/vc-bzr.el +++ b/lisp/vc/vc-bzr.el @@ -603,6 +603,7 @@ REV non-nil gets an error." "^ *\\(?:revno: \\([0-9.]+\\)\\|merged: .+\\)")) ;; Allow expanding short log entries (when (eq vc-log-view-type 'short) + (setq truncate-lines t) (set (make-local-variable 'log-view-expanded-log-entry-function) 'vc-bzr-expanded-log-entry)) (set (make-local-variable 'log-view-font-lock-keywords) diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index de729c969ae..3b4d0e5f421 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -119,6 +119,27 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." :version "23.1" :group 'vc) +(defcustom vc-git-root-log-format + '("%d%h..: %an %ad %s" + ;; The first shy group matches the characters drawn by --graph. + ;; We use numbered groups because `log-view-message-re' wants the + ;; revision number to be group 1. + "^\\(?:[*/\\| ]+ \\)?\\(?2: ([^)]+)\\)?\\(?1:[0-9a-z]+\\)..: \ +\\(?3:.*?\\)[ \t]+\\(?4:[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\)" + ((1 'log-view-message-face) + (2 'change-log-list nil lax) + (3 'change-log-name) + (4 'change-log-date))) + "Git log format for `vc-print-root-log'. +This should be a list (FORMAT REGEXP KEYWORDS), where FORMAT is a +format string (which is passed to \"git log\" via the argument +\"--pretty=tformat:FORMAT\"), REGEXP is a regular expression +matching the resulting Git log output, and KEYWORDS is a list of +`font-lock-keywords' for highlighting the Log View buffer." + :type '(list string string (repeat sexp)) + :group 'vc + :version "24.1") + (defvar vc-git-commits-coding-system 'utf-8 "Default coding system for git commits.") @@ -666,8 +687,10 @@ for the --graph option." (append '("log" "--no-color") (when shortlog - '("--graph" "--decorate" "--date=short" - "--pretty=tformat:%d%h %ad %s" "--abbrev-commit")) + `("--graph" "--decorate" "--date=short" + ,(format "--pretty=tformat:%s" + (car vc-git-root-log-format)) + "--abbrev-commit")) (when limit (list "-n" (format "%s" limit))) (when start-revision (list start-revision)) '("--"))))))) @@ -678,7 +701,8 @@ for the --graph option." buffer 0 nil "log" "--no-color" "--graph" "--decorate" "--date=short" - "--pretty=tformat:%d%h %ad %s" "--abbrev-commit" + (format "--pretty=tformat:%s" (car vc-git-root-log-format)) + "--abbrev-commit" (concat (if (string= remote-location "") "@{upstream}" remote-location) @@ -689,9 +713,10 @@ for the --graph option." (vc-git-command nil 0 nil "fetch") (vc-git-command buffer 0 nil - "log" + "log" "--no-color" "--graph" "--decorate" "--date=short" - "--pretty=tformat:%d%h %ad %s" "--abbrev-commit" + (format "--pretty=tformat:%s" (car vc-git-root-log-format)) + "--abbrev-commit" (concat "HEAD.." (if (string= remote-location "") "@{upstream}" remote-location)))) @@ -700,6 +725,7 @@ for the --graph option." (defvar log-view-file-re) (defvar log-view-font-lock-keywords) (defvar log-view-per-file-logs) +(defvar log-view-expanded-log-entry-function) (define-derived-mode vc-git-log-view-mode log-view-mode "Git-Log-View" (require 'add-log) ;; We need the faces add-log. @@ -708,37 +734,37 @@ for the --graph option." (set (make-local-variable 'log-view-per-file-logs) nil) (set (make-local-variable 'log-view-message-re) (if (not (eq vc-log-view-type 'long)) - "^\\(?:[*/\\| ]+ \\)?\\(?: ([^)]+)\\)?\\([0-9a-z]+\\) \\([-a-z0-9]+\\) \\(.*\\)" + (cadr vc-git-root-log-format) "^commit *\\([0-9a-z]+\\)")) + ;; Allow expanding short log entries + (when (eq vc-log-view-type 'short) + (setq truncate-lines t) + (set (make-local-variable 'log-view-expanded-log-entry-function) + 'vc-git-expanded-log-entry)) (set (make-local-variable 'log-view-font-lock-keywords) (if (not (eq vc-log-view-type 'long)) - '( - ;; Same as log-view-message-re, except that we don't - ;; want the shy group for the tag name. - ("^\\(?:[*/\\| ]+ \\)?\\( ([^)]+)\\)?\\([0-9a-z]+\\) \\([-a-z0-9]+\\) \\(.*\\)" - (1 'highlight nil lax) - (2 'change-log-acknowledgement) - (3 'change-log-date))) - (append - `((,log-view-message-re (1 'change-log-acknowledgement))) - ;; Handle the case: - ;; user: foo@bar - '(("^Author:[ \t]+\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)" - (1 'change-log-email)) - ;; Handle the case: - ;; user: FirstName LastName - ("^Author:[ \t]+\\([^<(]+?\\)[ \t]*[(<]\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)[>)]" - (1 'change-log-name) - (2 'change-log-email)) - ("^ +\\(?:\\(?:[Aa]cked\\|[Ss]igned-[Oo]ff\\)-[Bb]y:\\)[ \t]+\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)" - (1 'change-log-name)) - ("^ +\\(?:\\(?:[Aa]cked\\|[Ss]igned-[Oo]ff\\)-[Bb]y:\\)[ \t]+\\([^<(]+?\\)[ \t]*[(<]\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)[>)]" - (1 'change-log-name) - (2 'change-log-email)) - ("^Merge: \\([0-9a-z]+\\) \\([0-9a-z]+\\)" - (1 'change-log-acknowledgement) - (2 'change-log-acknowledgement)) - ("^Date: \\(.+\\)" (1 'change-log-date)) + (list (cons (nth 1 vc-git-root-log-format) + (nth 2 vc-git-root-log-format))) + (append + `((,log-view-message-re (1 'change-log-acknowledgement))) + ;; Handle the case: + ;; user: foo@bar + '(("^Author:[ \t]+\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)" + (1 'change-log-email)) + ;; Handle the case: + ;; user: FirstName LastName + ("^Author:[ \t]+\\([^<(]+?\\)[ \t]*[(<]\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)[>)]" + (1 'change-log-name) + (2 'change-log-email)) + ("^ +\\(?:\\(?:[Aa]cked\\|[Ss]igned-[Oo]ff\\)-[Bb]y:\\)[ \t]+\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)" + (1 'change-log-name)) + ("^ +\\(?:\\(?:[Aa]cked\\|[Ss]igned-[Oo]ff\\)-[Bb]y:\\)[ \t]+\\([^<(]+?\\)[ \t]*[(<]\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)[>)]" + (1 'change-log-name) + (2 'change-log-email)) + ("^Merge: \\([0-9a-z]+\\) \\([0-9a-z]+\\)" + (1 'change-log-acknowledgement) + (2 'change-log-acknowledgement)) + ("^Date: \\(.+\\)" (1 'change-log-date)) ("^summary:[ \t]+\\(.+\\)" (1 'log-view-message))))))) @@ -758,6 +784,15 @@ or BRANCH^ (where \"^\" can be repeated)." (t nil)))) (beginning-of-line))) +(defun vc-git-expanded-log-entry (revision) + (with-temp-buffer + (apply 'vc-git-command t nil nil (list "log" revision "-1")) + (goto-char (point-min)) + (unless (eobp) + ;; Indent the expanded log entry. + (indent-region (point-min) (point-max) 2) + (buffer-string)))) + (defun vc-git-diff (files &optional rev1 rev2 buffer) "Get a difference report using Git between two revisions of FILES." (let (process-file-side-effects) diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index 10348544357..d283c39362a 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -138,6 +138,24 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." "Name of the Mercurial executable (excluding any arguments)." :type 'string :group 'vc) + +(defcustom vc-hg-root-log-format + '("{rev}:{tags}: {author|person} {date|shortdate} {desc|firstline}\\n" + "^\\([0-9]+\\):\\([^:]*\\): \\(.*?\\)[ \t]+\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\)" + ((1 'log-view-message-face) + (2 'change-log-list) + (3 'change-log-name) + (4 'change-log-date))) + "Mercurial log template for `vc-print-root-log'. +This should be a list (TEMPLATE REGEXP KEYWORDS), where TEMPLATE +is the \"--template\" argument string to pass to Mercurial, +REGEXP is a regular expression matching the resulting Mercurial +output, and KEYWORDS is a list of `font-lock-keywords' for +highlighting the Log View buffer." + :type '(list string string (repeat sexp)) + :group 'vc + :version "24.1") + ;;; Properties of the backend @@ -266,13 +284,14 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." (nconc (when start-revision (list (format "-r%s:" start-revision))) (when limit (list "-l" (format "%s" limit))) - (when shortlog (list "--style" "compact")) + (when shortlog (list "--template" (car vc-hg-root-log-format))) vc-hg-log-switches))))) (defvar log-view-message-re) (defvar log-view-file-re) (defvar log-view-font-lock-keywords) (defvar log-view-per-file-logs) +(defvar log-view-expanded-log-entry-function) (define-derived-mode vc-hg-log-view-mode log-view-mode "Hg-Log-View" (require 'add-log) ;; we need the add-log faces @@ -280,33 +299,34 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." (set (make-local-variable 'log-view-per-file-logs) nil) (set (make-local-variable 'log-view-message-re) (if (eq vc-log-view-type 'short) - "^\\([0-9]+\\)\\(\\[.*\\]\\)? +\\([0-9a-z]\\{12\\}\\) +\\(\\(?:[0-9]+\\)-\\(?:[0-9]+\\)-\\(?:[0-9]+\\) \\(?:[0-9]+\\):\\(?:[0-9]+\\) \\(?:[-+0-9]+\\)\\) +\\(.*\\)$" + (cadr vc-hg-root-log-format) "^changeset:[ \t]*\\([0-9]+\\):\\(.+\\)")) + ;; Allow expanding short log entries + (when (eq vc-log-view-type 'short) + (setq truncate-lines t) + (set (make-local-variable 'log-view-expanded-log-entry-function) + 'vc-hg-expanded-log-entry)) (set (make-local-variable 'log-view-font-lock-keywords) (if (eq vc-log-view-type 'short) - (append `((,log-view-message-re - (1 'log-view-message-face) - (2 'highlight nil lax) - (3 'log-view-message-face) - (4 'change-log-date) - (5 'change-log-name)))) - (append - log-view-font-lock-keywords - '( - ;; Handle the case: - ;; user: FirstName LastName - ("^user:[ \t]+\\([^<(]+?\\)[ \t]*[(<]\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)[>)]" - (1 'change-log-name) - (2 'change-log-email)) - ;; Handle the cases: - ;; user: foo@bar - ;; and - ;; user: foo - ("^user:[ \t]+\\([A-Za-z0-9_.+-]+\\(?:@[A-Za-z0-9_.-]+\\)?\\)" - (1 'change-log-email)) - ("^date: \\(.+\\)" (1 'change-log-date)) - ("^tag: +\\([^ ]+\\)$" (1 'highlight)) - ("^summary:[ \t]+\\(.+\\)" (1 'log-view-message))))))) + (list (cons (nth 1 vc-hg-root-log-format) + (nth 2 vc-hg-root-log-format))) + (append + log-view-font-lock-keywords + '( + ;; Handle the case: + ;; user: FirstName LastName + ("^user:[ \t]+\\([^<(]+?\\)[ \t]*[(<]\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)[>)]" + (1 'change-log-name) + (2 'change-log-email)) + ;; Handle the cases: + ;; user: foo@bar + ;; and + ;; user: foo + ("^user:[ \t]+\\([A-Za-z0-9_.+-]+\\(?:@[A-Za-z0-9_.-]+\\)?\\)" + (1 'change-log-email)) + ("^date: \\(.+\\)" (1 'change-log-date)) + ("^tag: +\\([^ ]+\\)$" (1 'highlight)) + ("^summary:[ \t]+\\(.+\\)" (1 'log-view-message))))))) (defun vc-hg-diff (files &optional oldvers newvers buffer) "Get a difference report using hg between two revisions of FILES." @@ -324,6 +344,16 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." (list "-r" oldvers "-r" newvers) (list "-r" oldvers))))))) +(defun vc-hg-expanded-log-entry (revision) + (with-temp-buffer + (vc-hg-command t nil nil "log" "-r" revision) + (goto-char (point-min)) + (unless (eobp) + ;; Indent the expanded log entry. + (indent-region (point-min) (point-max) 2) + (goto-char (point-max)) + (buffer-string)))) + (defun vc-hg-revision-table (files) (let ((default-directory (file-name-directory (car files)))) (with-temp-buffer