emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/eldoc-diffstat a15690a8a7 05/10: Minor refactoring


From: ELPA Syncer
Subject: [nongnu] elpa/eldoc-diffstat a15690a8a7 05/10: Minor refactoring
Date: Fri, 13 Dec 2024 16:01:50 -0500 (EST)

branch: elpa/eldoc-diffstat
commit a15690a8a79ca05d64aefb263b396844a2c0fb60
Author: Johann Klähn <johann@jklaehn.de>
Commit: Johann Klähn <johann@jklaehn.de>

    Minor refactoring
---
 eldoc-diffstat.el | 155 ++++++++++++++++++++++++++++++++----------------------
 1 file changed, 93 insertions(+), 62 deletions(-)

diff --git a/eldoc-diffstat.el b/eldoc-diffstat.el
index 0041a51aae..83b90b5c76 100644
--- a/eldoc-diffstat.el
+++ b/eldoc-diffstat.el
@@ -4,6 +4,8 @@
 
 ;; Author: Johann Klähn <johann@jklaehn.de>
 ;; Keywords: vc, docs
+;; Version: 0.1
+;; Package-Requires: ((emacs "29.1"))
 
 ;; 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
@@ -20,66 +22,89 @@
 
 ;;; Commentary:
 
-;; Adapted from 
https://www.tsdh.org/posts/2022-07-20-using-eldoc-with-magit-async.html
+;; This package provides a way to display VCS diffstat information via eldoc.
+;; It supports Git and Mercurial repositories.
+;;
+;; To use, call `eldoc-diffstat-setup' in the desired buffer or mode hook.
+;; You might also want to add the following to your config:
+;;
+;;   (eldoc-add-command
+;;    'magit-next-line 'magit-previous-line
+;;    'magit-section-forward 'magit-section-backward
+;;    'magit-section-forward-sibling 'magit-section-backward-sibling)
+;;
+;; Adapted from Tassilo Horn's blog post:
+;; https://www.tsdh.org/posts/2022-07-20-using-eldoc-with-magit-async.html
 
 ;;; Code:
 
 (require 'ansi-color)
 
-(defvar eldoc-diffstat--process nil)
+(defvar eldoc-diffstat--process nil
+  "The latest async process used for fetching diffstat information.
+Only one active process at a time; new requests terminate previous ones.
+After completion, a cached version of the diffstat output is attached as
+a property to the process object.")
+
 (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")))
+        "--stat" "--rev"))
+  "Alist mapping VCS backend to the command to use for computing the 
diffstat.")
 
 ;;;###autoload
 (defun eldoc-diffstat-setup ()
   "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))
+            #'eldoc-diffstat--docstring nil 'local)
+  (unless (bound-and-true-p eldoc-mode)
+    (eldoc-mode)))
 
 (defun eldoc-diffstat--docstring (callback &rest _ignored)
   "Display diffstat for revision at point by calling CALLBACK.
 Intended for `eldoc-documentation-functions'."
-  (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)))))
+  (when-let* ((info (eldoc-diffstat--get-revision-info))
               (backend (car info))
               (revision (cdr info))
               (command (alist-get backend eldoc-diffstat--commands)))
-    (if-let ((result (eldoc--diffstat--get-cache info)))
+    (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))))
+(defun eldoc-diffstat--get-revision-info ()
+  "Get revision info for the current buffer context.
+The returned record should be 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."
+  (cond
+   ((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)))))
+
+(defun eldoc-diffstat--get-cache (revision-info)
+  "Retrieve cached diffstat result for REVISION-INFO if available."
+  (when-let* ((proc eldoc-diffstat--process)
+              ((processp proc))
+              (cached-result (process-get proc :cached-result))
+              ((equal revision-info (car cached-result))))
     (cdr cached-result)))
 
-(defun eldoc-diffstat--docstring-1 (command callback cache-tag)
+(defun eldoc-diffstat--docstring-1 (command callback revision-info)
   "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
+killing any existing process.  REVISION-INFO 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)
@@ -96,48 +121,54 @@ caching the result, see `eldoc-diffstat--get-cache' for 
details."
     :noquery t
     :command command
     :sentinel
-    (apply-partially #'eldoc-diffstat--sentinel callback)))
-  (process-put eldoc-diffstat--process :cache-tag cache-tag)
+    (lambda (&rest args)
+      (apply #'eldoc-diffstat--sentinel callback args))))
+  (process-put eldoc-diffstat--process :revision-info revision-info)
 
   ;; Signal that the doc string is computed asynchronously.
   t)
 
-(defun eldoc-diffstat--sentinel (callback proc event)
+(defun eldoc-diffstat--sentinel (callback proc _event)
   "Display output of PROC by calling CALLBACK if EVENT indicates success."
   (when (eq (process-status proc) 'exit)
     (with-current-buffer (process-buffer proc)
-      (let ((ansi-color-apply-face-function
-             (lambda (beg end face)
-               (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)
-                         (line-end-position)
-                         'face 'bold)
-
-      ;; Join second line.
-      (forward-line)
-      (join-line)
-
-      ;; Move summary to the top and make it italic.
-      (forward-line)
-      (reverse-region (point) (point-max))
-      (put-text-property (point)
-                         (line-end-position)
-                         'face 'italic)
-      (forward-line)
-      (reverse-region (point) (point-max))
+      (eldoc-diffstat--format-output-buffer)
       (let ((result (buffer-string))
-            (cache-tag (process-get eldoc-diffstat--process :cache-tag)))
+            (revision-info (process-get eldoc-diffstat--process 
:revision-info)))
         (process-put eldoc-diffstat--process :cached-result
-                     (cons cache-tag result))
+                     (cons revision-info result))
         (funcall callback result)))))
 
+(defun eldoc-diffstat--format-output-buffer ()
+  "Format the diffstat output."
+  ;; Translate color control sequences into text properties.
+  (let ((ansi-color-apply-face-function
+         (lambda (beg end face)
+           (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)
+                     (line-end-position)
+                     'face 'bold)
+
+  ;; Join second line.
+  (forward-line)
+  (join-line)
+
+  ;; Move summary to the top and make it italic.
+  (forward-line)
+  (reverse-region (point) (point-max))
+  (put-text-property (point)
+                     (line-end-position)
+                     'face 'italic)
+  (forward-line)
+  (reverse-region (point) (point-max)))
+
 (provide 'eldoc-diffstat)
 ;;; eldoc-diffstat.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]