From 73165957aaf944d2c74c0d8d1aeba3be0f1282ac Mon Sep 17 00:00:00 2001 From: Andreas Gerler Date: Tue, 13 Nov 2018 12:14:43 +0100 Subject: [PATCH] update git-timemachine. Signed-off-by: Andreas Gerler --- .../git-timemachine-pkg.el | 1 - .../git-timemachine-autoloads.el | 12 +- .../git-timemachine-pkg.el | 2 + .../git-timemachine.el | 167 +++++++++++++++--- 4 files changed, 151 insertions(+), 31 deletions(-) delete mode 100644 elpa/git-timemachine-20160120.416/git-timemachine-pkg.el rename elpa/{git-timemachine-20160120.416 => git-timemachine-20180607.820}/git-timemachine-autoloads.el (66%) create mode 100644 elpa/git-timemachine-20180607.820/git-timemachine-pkg.el rename elpa/{git-timemachine-20160120.416 => git-timemachine-20180607.820}/git-timemachine.el (58%) diff --git a/elpa/git-timemachine-20160120.416/git-timemachine-pkg.el b/elpa/git-timemachine-20160120.416/git-timemachine-pkg.el deleted file mode 100644 index f388f2ae..00000000 --- a/elpa/git-timemachine-20160120.416/git-timemachine-pkg.el +++ /dev/null @@ -1 +0,0 @@ -(define-package "git-timemachine" "20160120.416" "Walk through git revisions of a file" 'nil :url "https://github.com/pidu/git-timemachine" :keywords '("git")) diff --git a/elpa/git-timemachine-20160120.416/git-timemachine-autoloads.el b/elpa/git-timemachine-20180607.820/git-timemachine-autoloads.el similarity index 66% rename from elpa/git-timemachine-20160120.416/git-timemachine-autoloads.el rename to elpa/git-timemachine-20180607.820/git-timemachine-autoloads.el index ace999b3..0dce9972 100644 --- a/elpa/git-timemachine-20160120.416/git-timemachine-autoloads.el +++ b/elpa/git-timemachine-20180607.820/git-timemachine-autoloads.el @@ -1,10 +1,13 @@ ;;; git-timemachine-autoloads.el --- automatically extracted autoloads ;; ;;; Code: -(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + -;;;### (autoloads nil "git-timemachine" "git-timemachine.el" (22215 -;;;;;; 7686 0 0)) +;;;### (autoloads nil "git-timemachine" "git-timemachine.el" (0 0 +;;;;;; 0 0)) ;;; Generated autoloads from git-timemachine.el (autoload 'git-timemachine-toggle "git-timemachine" "\ @@ -22,11 +25,14 @@ Enable git timemachine for current buffer, switching to GIT-BRANCH. \(fn GIT-BRANCH)" t nil) +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "git-timemachine" '("git-timemachine-"))) + ;;;*** ;; Local Variables: ;; version-control: never ;; no-byte-compile: t ;; no-update-autoloads: t +;; coding: utf-8 ;; End: ;;; git-timemachine-autoloads.el ends here diff --git a/elpa/git-timemachine-20180607.820/git-timemachine-pkg.el b/elpa/git-timemachine-20180607.820/git-timemachine-pkg.el new file mode 100644 index 00000000..2ea9376f --- /dev/null +++ b/elpa/git-timemachine-20180607.820/git-timemachine-pkg.el @@ -0,0 +1,2 @@ +;;; -*- no-byte-compile: t -*- +(define-package "git-timemachine" "20180607.820" "Walk through git revisions of a file" '((emacs "24.3")) :commit "90a980578249c102da3e904fccdc9a2a5a0e7bcc" :keywords '("git") :authors '(("Peter Stiernström" . "peter@stiernstrom.se")) :maintainer '("Peter Stiernström" . "peter@stiernstrom.se") :url "https://github.com/pidu/git-timemachine") diff --git a/elpa/git-timemachine-20160120.416/git-timemachine.el b/elpa/git-timemachine-20180607.820/git-timemachine.el similarity index 58% rename from elpa/git-timemachine-20160120.416/git-timemachine.el rename to elpa/git-timemachine-20180607.820/git-timemachine.el index 4281b3ea..1e01e278 100644 --- a/elpa/git-timemachine-20160120.416/git-timemachine.el +++ b/elpa/git-timemachine-20180607.820/git-timemachine.el @@ -3,10 +3,11 @@ ;; Copyright (C) 2014 Peter Stiernström ;; Author: Peter Stiernström -;; Version: 3.0 -;; Package-Version: 20160120.416 +;; Version: 4.6 +;; Package-Version: 20180607.820 ;; URL: https://github.com/pidu/git-timemachine ;; Keywords: git +;; Package-Requires: ((emacs "24.3")) ;; This file is not part of GNU Emacs @@ -35,11 +36,13 @@ (defcustom git-timemachine-abbreviation-length 12 "Number of chars from the full sha1 hash to use for abbreviation." + :type 'integer :group 'git-timemachine) (defcustom git-timemachine-show-minibuffer-details t "Non-nil means that details of the commit (its hash and date) will be shown in the minibuffer while navigating commits." + :type 'boolean :group 'git-timemachine) (defface git-timemachine-commit @@ -48,14 +51,20 @@ will be shown in the minibuffer while navigating commits." :group 'git-timemachine) (defface git-timemachine-minibuffer-detail-face - '((t (:foreground "yellow"))) - "How to display the minibuffer detail" - :group 'git-timemachine) + '((((class color) (background dark)) + :foreground "yellow") + (((class color) (background light)) + :foreground "yellow4")) + "How to display the minibuffer detail" + :group 'git-timemachine) (defface git-timemachine-minibuffer-author-face - '((t (:foreground "orange"))) - "How to display the author in minibuffer" - :group 'git-timemachine) + '((((class color) (background dark)) + :foreground "orange") + (((class color) (background light)) + :foreground "DarkOrange4")) + "How to display the author in minibuffer" + :group 'git-timemachine) (defcustom git-timemachine-minibuffer-detail 'subject @@ -72,17 +81,27 @@ Available values are: :type 'boolean :group 'git-timemachine) +(defcustom git-timemachine-global-git-arguments + '("-c" "log.showSignature=false" "--no-pager") + "Common arguments for all git commands." + :type 'list + :group 'git-timemachine) + (defvar-local git-timemachine-directory nil) (defvar-local git-timemachine-revision nil) (defvar-local git-timemachine-file nil) (defvar-local git-timemachine--revisions-cache nil) (defun git-timemachine-completing-read-fn (&rest args) - "Apply ARGS to `ido-completing-read' if available and fall back to `completing-read'." - (if (fboundp 'ido-completing-read) - (apply 'ido-completing-read args) - (apply 'completing-read args) - )) + "Apply ARGS to `ido-completing-read' if available and fall back to `completing-read'." + (cond + ((fboundp 'ivy-read) (apply 'ivy-read args)) + ((fboundp 'ido-completing-read) (apply 'ido-completing-read args)) + (t (apply 'completing-read args)))) + +(defun git-timemachine--process-file (&rest args) + "Run ‘process-file’ with ARGS and ‘git-timemachine-global-git-arguments’ applied." + (apply #'process-file vc-git-program nil t nil (append git-timemachine-global-git-arguments args))) (defun git-timemachine--revisions (&optional git-branch) "List git revisions of current buffers file. @@ -98,8 +117,8 @@ When passed a GIT-BRANCH, lists revisions from that branch." (with-temp-buffer (unless (zerop (if git-branch - (process-file vc-git-program nil t nil "--no-pager" "log" git-branch "--name-only" "--follow" "--pretty=format:%H%x00%ar%x00%ad%x00%s%x00%an" "--" file) - (process-file vc-git-program nil t nil "--no-pager" "log" "--name-only" "--follow" "--pretty=format:%H%x00%ar%x00%ad%x00%s%x00%an" "--" file))) + (git-timemachine--process-file "log" git-branch "--name-only" "--follow" "--pretty=format:%H%x00%ar%x00%ad%x00%s%x00%an" "--" file) + (git-timemachine--process-file "log" "--name-only" "--follow" "--pretty=format:%H%x00%ar%x00%ad%x00%s%x00%an" "--" file))) (error "Git log command exited with non-zero exit status for file: %s" file)) (goto-char (point-min)) @@ -139,21 +158,54 @@ When passed a GIT-BRANCH, lists revisions from that branch." (defun git-timemachine-show-previous-revision () "Show previous revision of file." (interactive) - (git-timemachine-show-revision (git-timemachine--next-revision (git-timemachine--revisions)))) + (let ((new-line nil) + (curr-revision git-timemachine-revision) + (new-revision (git-timemachine--next-revision (git-timemachine--revisions))) + (cursor-win-pos (git-timemachine--get-cursor-position))) + (setq new-line (git-timemachine--find-new-current-line curr-revision new-revision (line-number-at-pos))) + (git-timemachine-show-revision new-revision) + (forward-line (- new-line (line-number-at-pos))) + (git-timemachine--set-cursor-position cursor-win-pos))) (defun git-timemachine-show-next-revision () "Show next revision of file." (interactive) - (git-timemachine-show-revision (git-timemachine--next-revision (reverse (git-timemachine--revisions))))) + (let ((new-line nil) + (curr-revision git-timemachine-revision) + (new-revision (git-timemachine--next-revision (reverse (git-timemachine--revisions)))) + (cursor-win-pos (git-timemachine--get-cursor-position))) + (setq new-line (git-timemachine--find-new-current-line curr-revision new-revision (line-number-at-pos))) + (git-timemachine-show-revision new-revision) + (forward-line (- new-line (line-number-at-pos))) + (git-timemachine--set-cursor-position cursor-win-pos))) + +(defun git-timemachine-show-revision-fuzzy () + "Show the revision with the chosen commit message." + (interactive) + (let* ((revisions (git-timemachine--revisions)) + (wanted + (funcall #'git-timemachine-completing-read-fn "Commit message: " + (mapcar (apply-partially #'nth 5) revisions)))) + (git-timemachine-show-revision + (cl-find wanted revisions + :key (apply-partially #'nth 5) + :test #'equal)))) (defun git-timemachine-show-nth-revision (rev-number) "Show the REV-NUMBER revision." (interactive "nEnter revision number: ") (let* ((revisions (reverse (git-timemachine--revisions))) - (revision (nth (1- rev-number) revisions)) - (num-revisions (length revisions))) - (if revision (git-timemachine-show-revision revision) - (message "Only %d revisions exist." num-revisions)))) + (num-revisions (length revisions)) + (curr-revision git-timemachine-revision) + (new-revision (nth (1- rev-number) revisions)) + (new-line nil) + (cursor-win-pos (git-timemachine--get-cursor-position))) + (if (not new-revision) + (message "Only %d revisions exist." num-revisions) + (setq new-line (git-timemachine--find-new-current-line curr-revision new-revision (line-number-at-pos))) + (git-timemachine-show-revision new-revision) + (forward-line (- new-line (line-number-at-pos))) + (git-timemachine--set-cursor-position cursor-win-pos)))) (defun git-timemachine-show-revision (revision) "Show a REVISION (commit hash) of the current file." @@ -167,9 +219,9 @@ When passed a GIT-BRANCH, lists revisions from that branch." (subject (nth 5 revision))) (setq buffer-read-only nil) (erase-buffer) - (let ((default-directory git-timemachine-directory)) - (process-file vc-git-program nil t nil "--no-pager" "show" - (concat commit ":" revision-file-name))) + (let ((default-directory git-timemachine-directory) + (process-coding-system-alist (list (cons "" (cons buffer-file-coding-system default-process-coding-system))))) + (git-timemachine--process-file "show" (concat commit ":" revision-file-name))) (setq buffer-read-only t) (set-buffer-modified-p nil) (let* ((revisions (git-timemachine--revisions)) @@ -192,6 +244,51 @@ When passed a GIT-BRANCH, lists revisions from that branch." (propertize author 'face 'git-timemachine-minibuffer-author-face) (propertize sha-or-subject 'face 'git-timemachine-minibuffer-detail-face) date-full date-relative))) +(defun git-timemachine--find-new-current-line (curr-revision new-revision current-line) + "Return the new current line after a revision jump." + (let* ((revisions (reverse (git-timemachine--revisions))) + (current-commit (car curr-revision)) + (curr-rev-number (+ (or (cl-position curr-revision revisions) 0) 1)) + (new-commit (car new-revision)) + (new-rev-number (+ (or (cl-position new-revision revisions) 0) 1)) + (new-line nil) + (file git-timemachine-file) + (reverse (< curr-rev-number new-rev-number))) + ;; If no commit change, do nothing + (if (= curr-rev-number new-rev-number) + current-line + ;; Get new current line number using `git-blame` + (with-temp-buffer + (if reverse + (git-timemachine--process-file "blame" "--reverse" "-n" (format "-L %s,%s" current-line current-line) file (format "%s..%s" current-commit new-commit)) + (git-timemachine--process-file "blame" "-n" (format "-L %s,%s" current-line current-line) file (format "%s..%s" new-commit current-commit))) + (goto-char (point-min)) + ;; If end-of-buffer problem + (when (search-forward-regexp "^fatal: file .+ has only .+ lines" nil t) + (setq current-line (- current-line 1)) + (erase-buffer) + (if reverse + (git-timemachine--process-file "blame" "--reverse" "-n" (format "-L %s,%s" current-line current-line) file (format "%s..%s" current-commit new-commit)) + (git-timemachine--process-file "blame" "-n" (format "-L %s,%s" current-line current-line) file (format "%s..%s" new-commit current-commit)))) + (goto-char (point-min)) + (search-forward-regexp "^[^ ]+ \\([^ ]+\\)") + (setq new-line (string-to-number (match-string 1))) + ;; In case git blame doesn't give what we expect + (when (= new-line 0) (setq new-line current-line)) + new-line)))) + +(defun git-timemachine--get-cursor-position () + "Return the cursor visual line number with respect to the +current window first line" + (let* ((win-point-min (save-excursion (move-to-window-line 0) (point))) + (cur-pos (count-screen-lines win-point-min (point)))) + cur-pos)) + +(defun git-timemachine--set-cursor-position (POS) + "Set the cursor position to the POS visual line with +respect to the window first line" + (recenter POS)) + (defun git-timemachine-abbreviate (revision) "Return REVISION abbreviated to `git-timemachine-abbreviation-length' chars." (substring revision 0 git-timemachine-abbreviation-length)) @@ -201,6 +298,14 @@ When passed a GIT-BRANCH, lists revisions from that branch." (interactive) (kill-buffer)) +(defun git-timemachine-blame () + "Call magit-blame on current revision." + (interactive) + (if (fboundp 'magit-blame) + (let ((magit-buffer-revision (car git-timemachine-revision))) + (magit-blame)) + (message "You need to install magit for blame capabilities"))) + (defun git-timemachine-kill-revision () "Kill the current revisions abbreviated commit hash." (interactive) @@ -223,9 +328,11 @@ When passed a GIT-BRANCH, lists revisions from that branch." '(("p" . git-timemachine-show-previous-revision) ("n" . git-timemachine-show-next-revision) ("g" . git-timemachine-show-nth-revision) + ("t" . git-timemachine-show-revision-fuzzy) ("q" . git-timemachine-quit) ("w" . git-timemachine-kill-abbreviated-revision) - ("W" . git-timemachine-kill-revision)) + ("W" . git-timemachine-kill-revision) + ("b" . git-timemachine-blame)) :group 'git-timemachine) (defun git-timemachine-validate (file) @@ -244,17 +351,23 @@ Call with the value of 'buffer-file-name." (file-name (buffer-file-name)) (timemachine-buffer (format "timemachine:%s" (buffer-name))) (cur-line (line-number-at-pos)) - (mode major-mode)) + (cursor-position (git-timemachine--get-cursor-position)) + (new-line nil) + (mode major-mode) + (coding-system buffer-file-coding-system)) (with-current-buffer (get-buffer-create timemachine-buffer) (switch-to-buffer timemachine-buffer) (setq buffer-file-name file-name) + (setq buffer-file-coding-system coding-system) (funcall mode) (setq git-timemachine-directory git-directory git-timemachine-file (file-relative-name file-name git-directory) git-timemachine-revision nil) (funcall get-revision-fn) + (setq new-line (git-timemachine--find-new-current-line git-timemachine-revision (list "HEAD" "" 0 "" "" "" "") cur-line)) ;; Allow to stay on the same line (goto-char (point-min)) - (forward-line (1- cur-line)) + (forward-line (- new-line 1)) + (git-timemachine--set-cursor-position cursor-position) (git-timemachine-mode)))) ;;;###autoload -- 2.47.3