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

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

[elpa] externals/marginalia 5e646cc3f6: Add marginalia-annotate-library


From: ELPA Syncer
Subject: [elpa] externals/marginalia 5e646cc3f6: Add marginalia-annotate-library (#127)
Date: Thu, 13 Jan 2022 10:57:38 -0500 (EST)

branch: externals/marginalia
commit 5e646cc3f6e9a295069c2ce3e545a21c27eca19d
Author: Daniel Mendler <mail@daniel-mendler.de>
Commit: GitHub <noreply@github.com>

    Add marginalia-annotate-library (#127)
    
    * Add marginalia-annotate-library
    
    Needs a lot of work to make this acceptably fast. But I increasingly miss
    library annotations.
    
    * marginalia-annotate-library: Add "Loaded" indicator
    
    Other minor improvements
    
    * marginalia-annotate-library: Handle more library headers
---
 marginalia.el | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/marginalia.el b/marginalia.el
index 1791efa115..5146119aca 100644
--- a/marginalia.el
+++ b/marginalia.el
@@ -102,6 +102,7 @@ a relative age."
      (file marginalia-annotate-file)
      (project-file marginalia-annotate-project-file)
      (buffer marginalia-annotate-buffer)
+     (library marginalia-annotate-library)
      (multi-category marginalia-annotate-multi-category)))
   "Annotator function registry.
 Associates completion categories with annotation functions.
@@ -952,6 +953,82 @@ These annotations are skipped for remote paths."
   (when-let (root (marginalia--project-root))
     (marginalia-annotate-file (expand-file-name cand root))))
 
+(defvar-local marginalia--library-cache nil)
+(defun marginalia--library-cache ()
+  "Return library cache hash table."
+  (with-current-buffer
+      (if-let (win (active-minibuffer-window))
+          (window-buffer win)
+        (current-buffer))
+    ;; `locate-file' and `locate-library' are bottlenecks for the
+    ;; annotator. Therefore we compute all the library paths first.
+    (unless marginalia--library-cache
+      (setq marginalia--library-cache (make-hash-table :test #'equal))
+      ;; Search in reverse because of shadowing
+      (dolist (dir (reverse load-path))
+        (dolist (file (ignore-errors
+                        (directory-files dir 'full
+                                         "\\.el\\(?:\\.gz\\)?\\'")))
+          (puthash (marginalia--library-name file)
+                   file marginalia--library-cache))))
+    marginalia--library-cache))
+
+(defun marginalia--library-name (file)
+  "Get name of library FILE."
+  (string-remove-suffix
+   ".el" (string-remove-suffix
+          ".gz" (file-name-nondirectory file))))
+
+(defun marginalia--library-kill ()
+  "Kill temporary buffer."
+  (kill-buffer " *marginalia library*"))
+
+(defun marginalia--library-doc (file)
+  "Return library documentation string for FILE."
+  (let ((doc (get-text-property 0 'marginalia--library-doc file)))
+    (unless doc
+      ;; Extract documentation string. We cannot use `lm-summary' here,
+      ;; since it decompresses the whole file, which is slower.
+      (let ((str (with-current-buffer
+                     (or (get-buffer " *marginalia library*")
+                         (progn
+                           (add-hook 'minibuffer-exit-hook 
#'marginalia--library-kill)
+                           (get-buffer-create " *marginalia library*")))
+                   (erase-buffer)
+                   (let ((inhibit-message t) (message-log-max nil))
+                     (insert-file-contents file nil 0 200))
+                   (buffer-substring (point-min) (line-end-position)))))
+        (cond
+         ((string-match "\\`(define-package\\s-+\"\\([^\"]+\\)\"" str)
+          (setq doc (format "Generated package description from %s.el"
+                            (match-string 1 str))))
+         ((string-match "\\`;+\\s-*" str)
+          (setq doc (substring str (match-end 0)))
+          (when (string-match "\\`[^ \t]+\\s-+-+\\s-+" doc)
+            (setq doc (substring doc (match-end 0))))
+          (when (string-match "\\s-*-\\*-" doc)
+            (setq doc (substring doc 0 (match-beginning 0)))))
+         (t (setq doc "")))
+        ;; Add the documentation string to the cache
+        (put-text-property 0 1 'marginalia--library-doc doc file)))
+    doc))
+
+(defun marginalia-annotate-library (cand)
+  "Annotate library CAND with documentation and path."
+  (setq cand (marginalia--library-name cand))
+  (when-let (file (gethash cand (marginalia--library-cache)))
+    (marginalia--fields
+     ;; Display if the corresponding feature is loaded.
+     ;; feature/=library file, but better than nothing.
+     ((when-let (sym (intern-soft cand))
+        (when (memq sym features)
+          (propertize "Loaded" 'face 'marginalia-on)))
+      :width 8)
+     ((marginalia--library-doc file)
+      :truncate 1.0 :face 'marginalia-documentation)
+     ((abbreviate-file-name (file-name-directory file))
+      :truncate -0.5 :face 'marginalia-file-name))))
+
 (defun marginalia-classify-by-command-name ()
   "Lookup category for current command."
   (and marginalia--command



reply via email to

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