branch: elpa/eldoc-diffstat commit 8786bab235c7c961c275e47043a929624dddddb5 Author: Johann Klähn <joh...@jklaehn.de> Commit: Johann Klähn <joh...@jklaehn.de>
Add support for Hg repos --- eldoc-diffstat.el | 85 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 30 deletions(-) diff --git a/eldoc-diffstat.el b/eldoc-diffstat.el index ca6b599efe..0041a51aae 100644 --- a/eldoc-diffstat.el +++ b/eldoc-diffstat.el @@ -1,4 +1,4 @@ -;;; eldoc-diffstat.el --- Make git diffstat available via eldoc -*- lexical-binding: t; -*- +;;; eldoc-diffstat.el --- Make VCS diffstat available via eldoc -*- lexical-binding: t; -*- ;; Copyright (C) 2024 Johann Klähn @@ -27,39 +27,60 @@ (require 'ansi-color) (defvar eldoc-diffstat--process nil) -(defconst eldoc-diffstat--command - (list "git" "--no-pager" "show" "--color=always" - "--format=format:%an <%ae>, %aD:%n%s" "--stat=80")) +(defconst eldoc-diffstat--commands + '((Git "git" "--no-pager" "show" "--color=always" + "--format=format:%an <%ae>, %aD:%n%s" "--stat=80") + (Hg "hg" "--pager=never" "log" "--color=always" + "--template" "{author}, {date|rfc822date}:\n{desc|firstline}\n" + "--stat" "--rev"))) ;;;###autoload (defun eldoc-diffstat-setup () - "Configure eldoc buffer-locally to display diffstat for commit at point." + "Configure eldoc buffer-locally to display diffstat for revision at point." (interactive) + (unless (bound-and-true-p eldoc-mode) + (eldoc-mode)) (add-hook 'eldoc-documentation-functions #'eldoc-diffstat--docstring nil 'local)) (defun eldoc-diffstat--docstring (callback &rest _ignored) - "Display diffstat for commit at point by calling CALLBACK. + "Display diffstat for revision at point by calling CALLBACK. Intended for `eldoc-documentation-functions'." - (when-let* ((commit (or (when (fboundp 'magit-commit-at-point) - (magit-commit-at-point)) - (and (derived-mode-p 'vc-annotate-mode) - (boundp 'vc-annotate-backend) - (eq vc-annotate-backend 'Git) - (fboundp 'vc-annotate-extract-revision-at-line) - (car (vc-annotate-extract-revision-at-line))) - (and (derived-mode-p 'log-view-mode) - (boundp 'log-view-vc-backend) - (eq log-view-vc-backend 'Git) - (log-view-current-tag))))) - (if-let* (((processp eldoc-diffstat--process)) - (result (process-get eldoc-diffstat--process :result)) - ((equal commit (car result)))) - (funcall callback (cdr result)) - (eldoc-diffstat--docstring-1 commit callback)))) - -(defun eldoc-diffstat--docstring-1 (commit callback &rest _ignored) - "Display diffstat for COMMIT by calling CALLBACK." + (when-let* ((info (or (when-let (((fboundp 'magit-commit-at-point)) + (revision (magit-commit-at-point))) + (cons 'Git revision)) + (and (derived-mode-p 'vc-annotate-mode) + (boundp 'vc-annotate-backend) + (fboundp 'vc-annotate-extract-revision-at-line) + (cons vc-annotate-backend + (car (vc-annotate-extract-revision-at-line)))) + (and (derived-mode-p 'log-view-mode) + (boundp 'log-view-vc-backend) + (cons log-view-vc-backend + (log-view-current-tag))))) + (backend (car info)) + (revision (cdr info)) + (command (alist-get backend eldoc-diffstat--commands))) + (if-let ((result (eldoc--diffstat--get-cache info))) + (funcall callback result) + (eldoc-diffstat--docstring-1 (append command (list revision)) callback info)))) + +(defun eldoc--diffstat--get-cache (cache-tag) + "Retrieve cached diffstat result for CACHE-TAG if available. +CACHE-TAG is a cons cell of the form (BACKEND . REVISION) where BACKEND is +a symbol representing the version control system and REVISION is a string +identifying the specific revision. Returns the cached result if available, +nil otherwise." + (when-let* (((processp eldoc-diffstat--process)) + (cached-result (process-get eldoc-diffstat--process :cached-result)) + ((equal cache-tag (car cached-result)))) + (cdr cached-result))) + +(defun eldoc-diffstat--docstring-1 (command callback cache-tag) + "Asynchronously compute diffstat using COMMAND and pass it to CALLBACK. +This function sets up a new asynchronous process to compute the diffstat, +killing any existing process. CACHE-TAG is a unique identifier used for +caching the result, see `eldoc-diffstat--get-cache' for details." ;; Clean up old process and its buffer. (when (processp eldoc-diffstat--process) (when (process-live-p eldoc-diffstat--process) @@ -73,11 +94,10 @@ Intended for `eldoc-documentation-functions'." :name "eldoc-diffstat" :buffer (generate-new-buffer " *eldoc-diffstat*") :noquery t - :command - (append eldoc-diffstat--command (list commit)) + :command command :sentinel (apply-partially #'eldoc-diffstat--sentinel callback))) - (process-put eldoc-diffstat--process :commit commit) + (process-put eldoc-diffstat--process :cache-tag cache-tag) ;; Signal that the doc string is computed asynchronously. t) @@ -91,6 +111,10 @@ Intended for `eldoc-documentation-functions'." (put-text-property beg end 'face face)))) (ansi-color-apply-on-region (point-min) (point-max))) + ;; Delete trailing blank lines. + (goto-char (point-max)) + (delete-blank-lines) + ;; Make first line bold. (goto-char (point-min)) (put-text-property (point) @@ -110,8 +134,9 @@ Intended for `eldoc-documentation-functions'." (forward-line) (reverse-region (point) (point-max)) (let ((result (buffer-string)) - (commit (process-get eldoc-diffstat--process :commit))) - (process-put eldoc-diffstat--process :result (cons commit result)) + (cache-tag (process-get eldoc-diffstat--process :cache-tag))) + (process-put eldoc-diffstat--process :cached-result + (cons cache-tag result)) (funcall callback result))))) (provide 'eldoc-diffstat)