From 8b86268b69acdb63697dbcb9def2582fa1be517f Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Wed, 5 Nov 2014 14:59:31 -0500 Subject: [PATCH] * lisp/vc/vc.el (vc-region-history): New command. (vc-print-log-internal): Use cl-some. * lisp/vc/vc-git.el (vc-git-region-history): New function. (vc-git-region-history-mode-map) (vc-git--log-view-long-font-lock-keywords) (vc-git-region-history-font-lock-keywords): New vars. (vc-git-region-history-font-lock): New function. (vc-git-region-history-mode): New major mode. --- etc/NEWS | 2 ++ lisp/ChangeLog | 18 ++++++++++++--- lisp/vc/vc-git.el | 48 ++++++++++++++++++++++++++++++++++++++- lisp/vc/vc.el | 57 ++++++++++++++++++++++++++++++++++------------- 4 files changed, 106 insertions(+), 19 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 6dcf64bede3..68ad5c00c8f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -125,6 +125,8 @@ Unicode standards. * Changes in Specialized Modes and Packages in Emacs 25.1 +** VC +*** The new command vc-region-history shows the log+diff of the active region. ** Calc +++ *** If `quick-calc' is called with a prefix argument, insert the diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 9b8cf9793cd..a0108305ac3 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,15 @@ +2014-11-05 Stefan Monnier + + * vc/vc.el (vc-region-history): New command. + (vc-print-log-internal): Use cl-some. + + * vc/vc-git.el (vc-git-region-history): New function. + (vc-git-region-history-mode-map) + (vc-git--log-view-long-font-lock-keywords) + (vc-git-region-history-font-lock-keywords): New vars. + (vc-git-region-history-font-lock): New function. + (vc-git-region-history-mode): New major mode. + 2014-11-05 Tassilo Horn * net/eww.el (subr-x): Require subr-x at compile-time because eww @@ -23,9 +35,9 @@ 2014-11-05 Michael Albinus - * net/tramp-sh.el (tramp-do-copy-or-rename-file-via-buffer): Don't use - a local copy; setting `inhibit-file-name-handlers' proper might be - more performant. (Bug#18751) + * net/tramp-sh.el (tramp-do-copy-or-rename-file-via-buffer): Don't use + a local copy; setting `inhibit-file-name-handlers' proper might be + more performant. (Bug#18751) 2014-11-05 Glenn Morris diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index afcfd666082..5d7c0ef5c7b 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -869,6 +869,52 @@ If LIMIT is non-nil, show no more than this many entries." "@{upstream}" remote-location)))) +(defun vc-git-region-history (file buffer lfrom lto) + (vc-git-command buffer 'async nil "log" "-p" ;"--follow" ;FIXME: not supported? + (format "-L%d,%d:%s" lfrom lto (file-relative-name file)))) + +(require 'diff-mode) + +(defvar vc-git-region-history-mode-map + (let ((map (make-composed-keymap + nil (make-composed-keymap + (list diff-mode-map vc-git-log-view-mode-map))))) + map)) + +(defvar vc-git--log-view-long-font-lock-keywords nil) +(defvar font-lock-keywords) +(defvar vc-git-region-history-font-lock-keywords + `((vc-git-region-history-font-lock))) + +(defun vc-git-region-history-font-lock (limit) + (let ((in-diff (save-excursion + (beginning-of-line) + (or (looking-at "^\\(?:diff\\|commit\\)\\>") + (re-search-backward "^\\(?:diff\\|commit\\)\\>" nil t)) + (eq ?d (char-after (match-beginning 0)))))) + (while + (let ((end (save-excursion + (if (re-search-forward "\n\\(diff\\|commit\\)\\>" + limit t) + (match-beginning 1) + limit)))) + (let ((font-lock-keywords (if in-diff diff-font-lock-keywords + vc-git--log-view-long-font-lock-keywords))) + (font-lock-fontify-keywords-region (point) end)) + (goto-char end) + (prog1 (< (point) limit) + (setq in-diff (eq ?d (char-after)))))) + nil)) + +(define-derived-mode vc-git-region-history-mode + vc-git-log-view-mode "Git-Region-History" + "Major mode to browse Git's \"log -p\" output." + (setq-local vc-git--log-view-long-font-lock-keywords + log-view-font-lock-keywords) + (setq-local font-lock-defaults + (cons 'vc-git-region-history-font-lock-keywords + (cdr font-lock-defaults)))) + (defvar log-view-message-re) (defvar log-view-file-re) (defvar log-view-font-lock-keywords) @@ -884,7 +930,7 @@ If LIMIT is non-nil, show no more than this many entries." (if (not (eq vc-log-view-type 'long)) (cadr vc-git-root-log-format) "^commit *\\([0-9a-z]+\\)")) - ;; Allow expanding short log entries + ;; 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) diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 5491d67e700..b2cb4470da1 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -1,4 +1,4 @@ -;;; vc.el --- drive a version-control system from within Emacs -*- lexical-binding: t -*- +;;; vc.el --- drive a version-control system from within Emacs -*- lexical-binding:t -*- ;; Copyright (C) 1992-1998, 2000-2014 Free Software Foundation, Inc. @@ -458,6 +458,15 @@ ;; If the backend supports annotating through copies and renames, ;; and displays a file name and a revision, then return a cons ;; (REVISION . FILENAME). +;; +;; - region-history (FILE BUFFER LFROM LTO) +;; +;; Insert into BUFFER the history (log comments and diffs) of the content of +;; FILE between lines LFROM and LTO. This is typically done asynchronously. +;; +;; - region-history-mode () +;; +;; Major mode to use for the output of `region-history'. ;; TAG SYSTEM ;; @@ -673,6 +682,7 @@ (require 'vc-hooks) (require 'vc-dispatcher) +(require 'cl-lib) (declare-function diff-setup-whitespace "diff-mode" ()) @@ -2227,19 +2237,11 @@ earlier revisions. Show up to LIMIT entries (non-nil means unlimited)." ;; Don't switch to the output buffer before running the command, ;; so that any buffer-local settings in the vc-controlled ;; buffer can be accessed by the command. - (let ((dir-present nil) - (vc-short-log nil) + (let* ((dir-present (cl-some #'file-directory-p files)) + (shortlog (not (null (memq (if dir-present 'directory 'file) + vc-log-short-style)))) (buffer-name "*vc-change-log*") - type) - (dolist (file files) - (when (file-directory-p file) - (setq dir-present t))) - (setq vc-short-log - (not (null (if dir-present - (memq 'directory vc-log-short-style) - (memq 'file vc-log-short-style))))) - (setq type (if vc-short-log 'short 'long)) - (let ((shortlog vc-short-log)) + (type (if shortlog 'short 'long))) (vc-log-internal-common backend buffer-name files type (lambda (bk buf _type-arg files-arg) @@ -2252,7 +2254,7 @@ earlier revisions. Show up to LIMIT entries (non-nil means unlimited)." (vc-call-backend bk 'show-log-entry working-revision)) (lambda (_ignore-auto _noconfirm) (vc-print-log-internal backend files working-revision - is-start-revision limit)))))) + is-start-revision limit))))) (defvar vc-log-view-type nil "Set this to differentiate the different types of logs.") @@ -2271,7 +2273,6 @@ earlier revisions. Show up to LIMIT entries (non-nil means unlimited)." (with-current-buffer (get-buffer-create buffer-name) (set (make-local-variable 'vc-log-view-type) type)) (setq retval (funcall backend-func backend buffer-name type files)) - (pop-to-buffer buffer-name) (let ((inhibit-read-only t)) ;; log-view-mode used to be called with inhibit-read-only bound ;; to t, so let's keep doing it, just in case. @@ -2280,6 +2281,9 @@ earlier revisions. Show up to LIMIT entries (non-nil means unlimited)." (set (make-local-variable 'log-view-vc-fileset) files) (set (make-local-variable 'revert-buffer-function) rev-buff-func)) + ;; Display after setting up major-mode, so display-buffer-alist can know + ;; the major-mode. + (pop-to-buffer buffer-name) (vc-run-delayed (let ((inhibit-read-only t)) (funcall setup-buttons-func backend files retval) @@ -2386,6 +2390,29 @@ When called interactively with a prefix argument, prompt for REMOTE-LOCATION." (vc-incoming-outgoing-internal backend remote-location "*vc-outgoing*" 'log-outgoing))) +;;;###autoload +(defun vc-region-history (from to) + "Show the history of the region FROM..TO." + (interactive "r") + (let* ((lfrom (line-number-at-pos from)) + (lto (line-number-at-pos to)) + (file buffer-file-name) + (backend (vc-backend file)) + (buf (get-buffer-create "*VC-history*"))) + (with-current-buffer buf + (setq-local vc-log-view-type 'long)) + (vc-call region-history file buf lfrom lto) + (with-current-buffer buf + (vc-call-backend backend 'region-history-mode) + (set (make-local-variable 'log-view-vc-backend) backend) + (set (make-local-variable 'log-view-vc-fileset) file) + (set (make-local-variable 'revert-buffer-function) + (lambda (_ignore-auto _noconfirm) + (with-current-buffer buf + (let ((inhibit-read-only t)) (erase-buffer))) + (vc-call region-history file buf lfrom lto)))) + (display-buffer buf))) + ;;;###autoload (defun vc-revert () "Revert working copies of the selected fileset to their repository contents. -- 2.39.5