]> git.bundesbrandschatzamt.de Git - emacsconfig.git/commitdiff
update git-timemachine
authorAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Sun, 22 Dec 2024 12:01:10 +0000 (13:01 +0100)
committerAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Sun, 22 Dec 2024 12:34:25 +0000 (13:34 +0100)
Signed-off-by: Andreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
elpa/git-timemachine-20230630.1214/git-timemachine-autoloads.el [deleted file]
elpa/git-timemachine-20230630.1214/git-timemachine-pkg.el [deleted file]
elpa/git-timemachine-20230630.1214/git-timemachine.el [deleted file]
elpa/git-timemachine-20241125.750/git-timemachine-autoloads.el [new file with mode: 0644]
elpa/git-timemachine-20241125.750/git-timemachine-pkg.el [new file with mode: 0644]
elpa/git-timemachine-20241125.750/git-timemachine.el [new file with mode: 0755]

diff --git a/elpa/git-timemachine-20230630.1214/git-timemachine-autoloads.el b/elpa/git-timemachine-20230630.1214/git-timemachine-autoloads.el
deleted file mode 100644 (file)
index d196f94..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-;;; git-timemachine-autoloads.el --- automatically extracted autoloads  -*- lexical-binding: t -*-
-;;
-;;; Code:
-
-(add-to-list 'load-path (directory-file-name
-                         (or (file-name-directory #$) (car load-path))))
-
-\f
-;;;### (autoloads nil "git-timemachine" "git-timemachine.el" (0 0
-;;;;;;  0 0))
-;;; Generated autoloads from git-timemachine.el
-
-(autoload 'git-timemachine-toggle "git-timemachine" "\
-Toggle git timemachine mode." t nil)
-
-(autoload 'git-timemachine "git-timemachine" "\
-Enable git timemachine for file of current buffer." t nil)
-
-(autoload 'git-timemachine-switch-branch "git-timemachine" "\
-Enable git timemachine for current buffer, switching to GIT-BRANCH.
-
-\(fn GIT-BRANCH)" t nil)
-
-(register-definition-prefixes "git-timemachine" '("git-timemachine-"))
-
-;;;***
-\f
-;;;### (autoloads nil nil ("git-timemachine-pkg.el") (0 0 0 0))
-
-;;;***
-\f
-;; 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-20230630.1214/git-timemachine-pkg.el b/elpa/git-timemachine-20230630.1214/git-timemachine-pkg.el
deleted file mode 100644 (file)
index 03da232..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-(define-package "git-timemachine" "20230630.1214" "Walk through git revisions of a file"
-  '((emacs "24.3")
-    (transient "0.1.0"))
-  :commit "ac933e5cd29583c131401f3bd991d98129c316df" :authors
-  '(("Peter Stiernström" . "peterNOSPAMstiernstrom.se"))
-  :maintainers
-  '(("Peter Stiernström" . "peterNOSPAMstiernstrom.se"))
-  :maintainer
-  '("Peter Stiernström" . "peterNOSPAMstiernstrom.se")
-  :keywords
-  '("vc")
-  :url "https://gitlab.com/pidu/git-timemachine")
-;; Local Variables:
-;; no-byte-compile: t
-;; End:
diff --git a/elpa/git-timemachine-20230630.1214/git-timemachine.el b/elpa/git-timemachine-20230630.1214/git-timemachine.el
deleted file mode 100755 (executable)
index 65bba0b..0000000
+++ /dev/null
@@ -1,438 +0,0 @@
-;;; git-timemachine.el --- Walk through git revisions of a file
-
-;; Copyright (C) 2014 Peter Stiernström
-
-;; Author: Peter Stiernström <peterNOSPAMstiernstrom.se>
-;; Version: 4.13
-;; URL: https://gitlab.com/pidu/git-timemachine
-;; Keywords: vc
-;; Package-Requires: ((emacs "24.3") (transient "0.1.0"))
-
-;; This file is not part of GNU Emacs
-
-;; This program is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Use git-timemachine to browse historic versions of a file with p
-;;; (previous) and n (next).
-
-;;; Code:
-
-(require 'vc-git)
-(require 'cl-lib)
-(require 'transient)
-
-(defgroup git-timemachine nil
-  "Walk through git revisions of a file."
-  :link '(url-link "https://codeberg.org/pidu/git-timemachine")
-  :group 'tools)
-
-(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
-  '((default :weight bold))
-  "Face for git timemachine commit sha."
-  :group 'git-timemachine)
-
-(defface git-timemachine-minibuffer-detail-face
-  '((((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
-  '((((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
-  "What to display when `git-timemachine-show-minibuffer-details` is t.
-Available values are:
-`commit` : The SHA hash of the commit
-`subject`: The subject of the commit message"
-  :type '(radio (const :tag "Commit SHA" commit) (const :tag "Commit Subject" subject))
-  :group 'git-timemachine)
-
-(defcustom git-timemachine-show-author
-  t
-  "Prepend author to minibuffer details."
-  :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)
-
-(defcustom git-timemachine-quit-to-invoking-buffer
-  t
-  "Switch to invoking buffer on `git-timemachine-quit`."
-  :type 'boolean
-  :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--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.
-
-When passed a GIT-BRANCH, lists revisions from that branch."
-  (if git-timemachine--revisions-cache
-    git-timemachine--revisions-cache
-    (setq git-timemachine--revisions-cache
-      (prog2
-             (message "Fetching Revisions...")
-             (let ((default-directory git-timemachine-directory)
-               (file git-timemachine-file))
-          (with-temp-buffer
-
-            (unless (zerop (if git-branch
-                             (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))
-            (let ((lines)
-                   (commit-number (/ (1+ (count-lines (point-min) (point-max))) 3)))
-              (while (not (eobp))
-                (let ((line (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
-                  (string-match "\\([^\0]*\\)\0\\([^\0]*\\)\0\\([^\0]*\\)\0\\(.*\\)\0\\(.*\\)" line)
-                  (let ((commit (match-string 1 line))
-                         (date-relative (match-string 2 line))
-                         (date-full (match-string 3 line))
-                         (subject (match-string 4 line))
-                         (author (match-string 5 line)))
-                    (forward-line 1)
-                    (let ((file-name (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
-                      (push (list commit file-name commit-number date-relative date-full subject author) lines))))
-                (setq commit-number (1- commit-number))
-                (forward-line 2))
-              (nreverse lines))))
-        (message "Fetching Revisions...done")))))
-
-(defun git-timemachine-show-current-revision ()
-  "Show last (current) revision of file."
-  (interactive)
-  (git-timemachine-show-revision (car (git-timemachine--revisions))))
-
-(defun git-timemachine-show-latest-revision-in-branch (git-branch)
-  "Show last (current) revision of file in GIT-BRANCH."
-  (interactive "MGit branch: ")
-  (git-timemachine-show-revision (car (git-timemachine--revisions git-branch))))
-
-(defun git-timemachine--next-revision (revisions)
-  "Return the revision following the current revision in REVISIONS."
-  (or (cadr (cl-member (car git-timemachine-revision) revisions :key #'car :test #'string=))
-    (car (reverse revisions))))
-
-(defun git-timemachine-show-previous-revision ()
-  "Show previous revision of file."
-  (interactive)
-  (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)
-  (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 #'completing-read "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)))
-          (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."
-  (when revision
-    (let ((current-position (point))
-           (commit (car revision))
-           (revision-file-name (nth 1 revision))
-           (commit-index (nth 2 revision))
-           (date-relative (nth 3 revision))
-           (date-full (nth 4 revision))
-           (subject (nth 5 revision)))
-      (setq buffer-read-only nil)
-      (erase-buffer)
-      (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))
-              (n-of-m (format "(%d/%d %s)" commit-index (length revisions) date-relative)))
-        (setq mode-line-buffer-identification
-          (list (propertized-buffer-identification "%12b") "@"
-            (propertize (git-timemachine-abbreviate commit) 'face 'git-timemachine-commit) " name:" revision-file-name" " n-of-m)))
-      (setq git-timemachine-revision revision)
-      (goto-char current-position)
-      (when git-timemachine-show-minibuffer-details
-        (git-timemachine--show-minibuffer-details revision))
-      (git-timemachine--erm-workaround))))
-
-(declare-function erm-reset-buffer "ext:enh-ruby-mode")
-
-(defun git-timemachine--erm-workaround ()
-  "Workaround for enhanced ruby mode not detecting revision change."
-  (when (eq major-mode 'enh-ruby-mode)
-    (ignore-errors (erm-reset-buffer))))
-
-(defun git-timemachine--show-minibuffer-details (revision)
-  "Show details for REVISION in minibuffer."
-  (let* ((date-relative (nth 3 revision))
-          (date-full (nth 4 revision))
-          (author (if git-timemachine-show-author (concat (nth 6 revision) ": ") ""))
-          (sha-or-subject (if (eq git-timemachine-minibuffer-detail 'commit) (car revision) (nth 5 revision))))
-    (message "%s%s [%s (%s)]"
-      (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.
-
-Given CURR-REVISION and NEW-REVISION determine if we need to
-updated CURRENT-LINE."
-  (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))
-
-(defun git-timemachine-quit ()
-  "Exit the timemachine."
-  (interactive)
-  (let ((parent-buffer-name buffer-file-name))
-    (kill-buffer)
-    (let ((parent-buffer (find-buffer-visiting parent-buffer-name)))
-      (when (and parent-buffer git-timemachine-quit-to-invoking-buffer)
-        (switch-to-buffer parent-buffer nil t)))))
-
-(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 revision's full commit hash."
-  (interactive)
-  (let ((revision (car git-timemachine-revision)))
-    (message revision)
-    (kill-new revision)))
-
-(defun git-timemachine-kill-abbreviated-revision ()
-  "Kill the current revision's abbreviated commit hash."
-  (interactive)
-  (let ((revision (git-timemachine-abbreviate (car git-timemachine-revision))))
-    (message revision)
-    (kill-new revision)))
-
-(defun git-timemachine-show-commit ()
-  "Show commit for current revision."
-  (interactive)
-  (let ((rev (car git-timemachine-revision)))
-    (if (fboundp 'magit-show-commit)
-      (magit-show-commit rev)
-      (message "You need to install magit to show commit"))))
-
-(transient-define-prefix git-timemachine-help ()
-  "Show online help."
-  ["Navigate"
-    [("p" "show previous revision" git-timemachine-show-previous-revision)
-      ("n" "show next revision" git-timemachine-show-next-revision)
-      ("g" "show nth revision" git-timemachine-show-nth-revision)
-      ("t" "show fuzzy revision" git-timemachine-show-revision-fuzzy)]]
-  ["Kill current revision"
-    [("w" "kill abbreviated revision" git-timemachine-kill-abbreviated-revision)
-      ("W" "kill revision" git-timemachine-kill-revision)]]
-  ["Misc"
-    [("b" "blame current revision" git-timemachine-blame)
-      ("c" "show commit" git-timemachine-show-commit)
-      ("?" "show help" git-timemachine-help)
-      ("q" "quit" git-timemachine-quit)]])
-
-(define-minor-mode git-timemachine-mode
-  "Git Timemachine, feel the wings of history."
-  :init-value nil
-  :lighter " Timemachine"
-  :keymap
-  '(("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)
-     ("b" . git-timemachine-blame)
-     ("c" . git-timemachine-show-commit)
-     ("?" . git-timemachine-help))
-  :group 'git-timemachine)
-
-(defun git-timemachine-validate (file)
-  "Validate that there is a FILE and that it belongs to a git repository.
-Call with the value of 'buffer-file-name."
-  (unless file
-    (error "This buffer is not visiting a file"))
-  (unless (vc-git-registered file)
-    (error "This file is not git tracked")))
-
-(defun git-timemachine--start (get-revision-fn)
-  "Setup a timemachine buffer and populate it from the result of GET-REVISION-FN."
-  (setq git-timemachine--revisions-cache nil)
-  (git-timemachine-validate (buffer-file-name))
-  (let ((git-directory (expand-file-name (vc-git-root (buffer-file-name))))
-         (file-name (buffer-file-name))
-         (timemachine-buffer (format "timemachine:%s" (buffer-name)))
-         (cur-line (line-number-at-pos))
-         (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)
-      (delay-mode-hooks (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 (- new-line 1))
-      (git-timemachine--set-cursor-position cursor-position)
-      (git-timemachine-mode))))
-
-;;;###autoload
-(defun git-timemachine-toggle ()
-  "Toggle git timemachine mode."
-  (interactive)
-  (if (bound-and-true-p git-timemachine-mode)
-    (git-timemachine-quit)
-    (git-timemachine)))
-
-;;;###autoload
-(defun git-timemachine ()
-  "Enable git timemachine for file of current buffer."
-  (interactive)
-  (git-timemachine--start #'git-timemachine-show-current-revision))
-
-;;;###autoload
-(defun git-timemachine-switch-branch (git-branch)
-  "Enable git timemachine for current buffer, switching to GIT-BRANCH."
-  (interactive (list (completing-read "Branch to switch to: "(vc-git-branches))))
-  (git-timemachine--start (lambda () (git-timemachine-show-latest-revision-in-branch git-branch))))
-
-(provide 'git-timemachine)
-
-;;; git-timemachine.el ends here
diff --git a/elpa/git-timemachine-20241125.750/git-timemachine-autoloads.el b/elpa/git-timemachine-20241125.750/git-timemachine-autoloads.el
new file mode 100644 (file)
index 0000000..11db8b1
--- /dev/null
@@ -0,0 +1,36 @@
+;;; git-timemachine-autoloads.el --- automatically extracted autoloads (do not edit)   -*- lexical-binding: t -*-
+;; Generated by the `loaddefs-generate' function.
+
+;; This file is part of GNU Emacs.
+
+;;; Code:
+
+(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
+
+
+\f
+;;; Generated autoloads from git-timemachine.el
+
+(autoload 'git-timemachine-toggle "git-timemachine" "\
+Toggle git timemachine mode." t)
+(autoload 'git-timemachine "git-timemachine" "\
+Enable git timemachine for file of current buffer." t)
+(autoload 'git-timemachine-switch-branch "git-timemachine" "\
+Enable git timemachine for current buffer, switching to GIT-BRANCH.
+
+(fn GIT-BRANCH)" t)
+(register-definition-prefixes "git-timemachine" '("git-timemachine-"))
+\f
+;;; End of scraped data
+
+(provide 'git-timemachine-autoloads)
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; no-native-compile: t
+;; coding: utf-8-emacs-unix
+;; End:
+
+;;; git-timemachine-autoloads.el ends here
diff --git a/elpa/git-timemachine-20241125.750/git-timemachine-pkg.el b/elpa/git-timemachine-20241125.750/git-timemachine-pkg.el
new file mode 100644 (file)
index 0000000..fa271a2
--- /dev/null
@@ -0,0 +1,11 @@
+;; -*- no-byte-compile: t; lexical-binding: nil -*-
+(define-package "git-timemachine" "20241125.750"
+  "Walk through git revisions of a file."
+  '((emacs     "24.3")
+    (transient "0.1.0"))
+  :url "https://codeberg.org/pidu/git-timemachine"
+  :commit "62ebb0c6588d848b1b7b90bf1a3aa4c04e873822"
+  :revdesc "62ebb0c6588d"
+  :keywords '("vc")
+  :authors '(("Peter Stiernström" . "peterNOSPAMstiernstrom.se"))
+  :maintainers '(("Peter Stiernström" . "peterNOSPAMstiernstrom.se")))
diff --git a/elpa/git-timemachine-20241125.750/git-timemachine.el b/elpa/git-timemachine-20241125.750/git-timemachine.el
new file mode 100755 (executable)
index 0000000..30e23e2
--- /dev/null
@@ -0,0 +1,496 @@
+;;; git-timemachine.el --- Walk through git revisions of a file
+
+;; Copyright (C) 2014 Peter Stiernström
+
+;; Author: Peter Stiernström <peterNOSPAMstiernstrom.se>
+;; Package-Version: 20241125.750
+;; Package-Revision: 62ebb0c6588d
+;; URL: https://codeberg.org/pidu/git-timemachine
+;; Keywords: vc
+;; Package-Requires: ((emacs "24.3") (transient "0.1.0"))
+
+;; This file is not part of GNU Emacs
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Use git-timemachine to browse historic versions of a file with p
+;;; (previous) and n (next).
+
+;;; Code:
+
+(require 'vc-git)
+(require 'cl-lib)
+(require 'transient)
+
+(defgroup git-timemachine nil
+  "Walk through git revisions of a file."
+  :link '(url-link "https://codeberg.org/pidu/git-timemachine")
+  :group 'tools)
+
+(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
+  '((default :weight bold))
+  "Face for git timemachine commit sha."
+  :group 'git-timemachine)
+
+(defface git-timemachine-minibuffer-detail-face
+  '((((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
+  '((((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
+  "What to display when `git-timemachine-show-minibuffer-details` is t.
+Available values are:
+`commit` : The SHA hash of the commit
+`subject`: The subject of the commit message"
+  :type '(radio (const :tag "Commit SHA" commit) (const :tag "Commit Subject" subject))
+  :group 'git-timemachine)
+
+(defcustom git-timemachine-show-author
+  t
+  "Prepend author to minibuffer details."
+  :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)
+
+(defcustom git-timemachine-quit-to-invoking-buffer
+  t
+  "Switch to invoking buffer on `git-timemachine-quit`."
+  :type 'boolean
+  :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--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.
+
+When passed a GIT-BRANCH, lists revisions from that branch."
+  (if git-timemachine--revisions-cache
+    git-timemachine--revisions-cache
+    (setq git-timemachine--revisions-cache
+      (prog2
+             (message "Fetching Revisions...")
+             (let ((default-directory git-timemachine-directory)
+               (file git-timemachine-file))
+          (with-temp-buffer
+
+            (unless (zerop (if git-branch
+                             (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))
+            (let ((lines)
+                   (commit-number (/ (1+ (count-lines (point-min) (point-max))) 3)))
+              (while (not (eobp))
+                (let ((line (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
+                  (string-match "\\([^\0]*\\)\0\\([^\0]*\\)\0\\([^\0]*\\)\0\\(.*\\)\0\\(.*\\)" line)
+                  (let ((commit (match-string 1 line))
+                         (date-relative (match-string 2 line))
+                         (date-full (match-string 3 line))
+                         (subject (match-string 4 line))
+                         (author (match-string 5 line)))
+                    (forward-line 1)
+                    (let ((file-name (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
+                      (push (list commit file-name commit-number date-relative date-full subject author) lines))))
+                (setq commit-number (1- commit-number))
+                (forward-line 2))
+              (nreverse lines))))
+        (message "Fetching Revisions...done")))))
+
+(defun git-timemachine-show-current-revision ()
+  "Show last (current) revision of file."
+  (interactive)
+  (git-timemachine-show-revision (car (git-timemachine--revisions))))
+
+(defun git-timemachine-show-latest-revision-in-branch (git-branch)
+  "Show last (current) revision of file in GIT-BRANCH."
+  (interactive "MGit branch: ")
+  (git-timemachine-show-revision (car (git-timemachine--revisions git-branch))))
+
+(defun git-timemachine--next-revision (revisions)
+  "Return the revision following the current revision in REVISIONS."
+  (or (cadr (cl-member (car git-timemachine-revision) revisions :key #'car :test #'string=))
+    (car (reverse revisions))))
+
+(defun git-timemachine-show-previous-revision ()
+  "Show previous revision of file."
+  (interactive)
+  (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)
+  (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 #'completing-read "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)))
+          (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-nearest-revision (&optional relative-hash)
+ "Show last revision of the current file nearest to RELATIVE-HASH."
+ (interactive "sEnter commit hash: ")
+ (let* ((abs-file-name (buffer-file-name (current-buffer)))
+        (root-directory
+         (expand-file-name
+          (vc-call-backend
+           (vc-responsible-backend abs-file-name)
+           'root abs-file-name)))
+        (default-directory root-directory)
+        (file-name (string-remove-prefix root-directory abs-file-name))
+       (line
+        (with-temp-buffer
+         (process-file vc-git-program nil t nil "log" "--max-count" "1" relative-hash "--pretty=format:%H%x00%ar%x00%ad%x00%s%x00%an" "--" file-name)
+         (buffer-substring-no-properties (point-min) (point-max))))
+       (line-list (unless (string-prefix-p "fatal" line t) (string-split line "\0")))
+       (hash (nth 0 line-list))
+       (date-relative (nth 1 line-list))
+       (date-full  (nth 2 line-list))
+       (subject (nth 3 line-list))
+       (author (nth 4 line-list))
+       (revision (list hash file-name -1 date-relative date-full subject author)))
+  (if line-list
+   (git-timemachine-show-revision revision)
+   (message "No such commit %s" relative-hash))))
+
+(defun git-timemachine-show-revision (revision)
+ "Show a REVISION (commit hash) of the current file."
+ (when revision
+  (let ((current-position (point))
+        (commit (car revision))
+        (revision-file-name (nth 1 revision))
+        (commit-index (nth 2 revision))
+        (date-relative (nth 3 revision))
+        (date-full (nth 4 revision))
+        (subject (nth 5 revision)))
+   (when (bound-and-true-p magit-blame-mode) (magit-blame-quit))
+   (setq buffer-read-only nil)
+   (erase-buffer)
+   (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))
+          (n-of-m (format "(%d/%d %s)" commit-index (length revisions) date-relative)))
+    (setq mode-line-buffer-identification
+     (list (propertized-buffer-identification "%12b") "@"
+      (propertize (git-timemachine-abbreviate commit) 'face 'git-timemachine-commit) " name:" revision-file-name" " n-of-m)))
+   (setq git-timemachine-revision revision)
+   (goto-char current-position)
+   (when git-timemachine-show-minibuffer-details
+    (git-timemachine--show-minibuffer-details revision))
+   (git-timemachine--erm-workaround))))
+
+(declare-function erm-reset-buffer "ext:enh-ruby-mode")
+
+(defun git-timemachine--erm-workaround ()
+  "Workaround for enhanced ruby mode not detecting revision change."
+  (when (eq major-mode 'enh-ruby-mode)
+    (ignore-errors (erm-reset-buffer))))
+
+(defun git-timemachine--show-minibuffer-details (revision)
+  "Show details for REVISION in minibuffer."
+  (let* ((date-relative (nth 3 revision))
+          (date-full (nth 4 revision))
+          (author (if git-timemachine-show-author (concat (nth 6 revision) ": ") ""))
+          (sha-or-subject (if (eq git-timemachine-minibuffer-detail 'commit) (car revision) (nth 5 revision))))
+    (message "%s%s [%s (%s)]"
+      (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.
+
+Given CURR-REVISION and NEW-REVISION determine if we need to
+updated CURRENT-LINE."
+  (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))
+
+(defun git-timemachine-quit ()
+  "Exit the timemachine."
+  (interactive)
+  (let ((parent-buffer-name buffer-file-name))
+    (kill-buffer)
+    (let ((parent-buffer (find-buffer-visiting parent-buffer-name)))
+      (when (and parent-buffer git-timemachine-quit-to-invoking-buffer)
+        (switch-to-buffer parent-buffer nil t)))))
+
+(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 revision's full commit hash."
+  (interactive)
+  (let ((revision (car git-timemachine-revision)))
+    (message revision)
+    (kill-new revision)))
+
+(defun git-timemachine-kill-abbreviated-revision ()
+  "Kill the current revision's abbreviated commit hash."
+  (interactive)
+  (let ((revision (git-timemachine-abbreviate (car git-timemachine-revision))))
+    (message revision)
+    (kill-new revision)))
+
+(defun git-timemachine-show-commit ()
+ "Show commit for current revision."
+ (interactive)
+ (let ((rev (car git-timemachine-revision)))
+  (if (fboundp 'magit-show-commit)
+   (magit-show-commit rev)
+   (message "You need to install magit to show commit"))))
+
+(defun git-timemachine-show-revision-introducing (text)
+ "Show the revision introducing TEXT to the file."
+ (interactive "sShow revision introducing text: ")
+ (let ((has-text? (lambda ()
+                   (save-excursion
+                    (goto-char (point-min))
+                    (search-forward text nil t))))
+       (buffer-name (format "timemachine:%s" (buffer-name)))
+       (at-revision nil))
+  (if (not (funcall has-text?))
+   (message "Buffer does not contain: %s" text)
+   (progn
+    (setq at-revision (car git-timemachine-revision))
+    (while (funcall has-text?)
+     (git-timemachine-show-previous-revision)
+     (when (string= at-revision (car git-timemachine-revision))
+      (throw :not-found text))
+     (setq at-revision (car git-timemachine-revision)))
+    (git-timemachine-show-next-revision)))))
+
+(transient-define-prefix git-timemachine-help ()
+ "Show online help."
+ ["Navigate"
+  [("p" "show previous revision" git-timemachine-show-previous-revision)
+   ("n" "show next revision" git-timemachine-show-next-revision)
+   ("g" "show nth revision" git-timemachine-show-nth-revision)
+   ("h" "show nearest revision" git-timemachine-show-nearest-revision)
+   ("t" "show fuzzy revision" git-timemachine-show-revision-fuzzy)
+   ("i" "show revision introducing" git-timemachine-show-revision-introducing)]]
+ ["Kill current revision"
+  [("w" "kill abbreviated revision" git-timemachine-kill-abbreviated-revision)
+   ("W" "kill revision" git-timemachine-kill-revision)]]
+ ["Misc"
+  [("b" "blame current revision" git-timemachine-blame)
+   ("c" "show commit" git-timemachine-show-commit)
+   ("?" "show help" git-timemachine-help)
+   ("q" "quit" git-timemachine-quit)]])
+
+(define-minor-mode git-timemachine-mode
+ "Git Timemachine, feel the wings of history."
+ :init-value nil
+ :lighter " Timemachine"
+ :keymap
+ '(("p" . git-timemachine-show-previous-revision)
+   ("n" . git-timemachine-show-next-revision)
+   ("g" . git-timemachine-show-nth-revision)
+   ("h" . git-timemachine-show-nearest-revision)
+   ("t" . git-timemachine-show-revision-fuzzy)
+   ("i" . git-timemachine-show-revision-introducing)
+   ("q" . git-timemachine-quit)
+   ("w" . git-timemachine-kill-abbreviated-revision)
+   ("W" . git-timemachine-kill-revision)
+   ("b" . git-timemachine-blame)
+   ("c" . git-timemachine-show-commit)
+   ("?" . git-timemachine-help))
+ :group 'git-timemachine)
+
+(defun git-timemachine-validate (file)
+  "Validate that there is a FILE and that it belongs to a git repository.
+Call with the value of 'buffer-file-name."
+  (unless file
+    (error "This buffer is not visiting a file"))
+  (unless (vc-git-registered file)
+    (error "This file is not git tracked")))
+
+(defun git-timemachine--start (get-revision-fn)
+ "Setup a timemachine buffer and populate it from the result of GET-REVISION-FN."
+ (setq git-timemachine--revisions-cache nil)
+ (git-timemachine-validate (buffer-file-name))
+ (let ((git-directory (expand-file-name (vc-git-root (buffer-file-name))))
+       (file-name (buffer-file-name))
+       (timemachine-buffer (format "timemachine:%s" (buffer-name)))
+       (cur-line (line-number-at-pos))
+       (cursor-position (git-timemachine--get-cursor-position))
+       (new-line nil)
+       (mode major-mode)
+       (coding-system buffer-file-coding-system)
+       (font-lock-mode-enabled (bound-and-true-p font-lock-mode)))
+  (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)
+   (delay-mode-hooks (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 (- new-line 1))
+   (git-timemachine--set-cursor-position cursor-position)
+   (git-timemachine-mode)
+   (when font-lock-mode-enabled
+    (if (fboundp 'font-lock-update)
+     (font-lock-update)
+     (with-no-warnings
+      (font-lock-fontify-buffer)))))))
+
+;;;###autoload
+(defun git-timemachine-toggle ()
+  "Toggle git timemachine mode."
+  (interactive)
+  (if (bound-and-true-p git-timemachine-mode)
+    (git-timemachine-quit)
+    (git-timemachine)))
+
+;;;###autoload
+(defun git-timemachine ()
+  "Enable git timemachine for file of current buffer."
+  (interactive)
+  (git-timemachine--start #'git-timemachine-show-current-revision))
+
+;;;###autoload
+(defun git-timemachine-switch-branch (git-branch)
+  "Enable git timemachine for current buffer, switching to GIT-BRANCH."
+  (interactive (list (completing-read "Branch to switch to: "(vc-git-branches))))
+  (git-timemachine--start (lambda () (git-timemachine-show-latest-revision-in-branch git-branch))))
+
+(provide 'git-timemachine)
+
+;;; git-timemachine.el ends here