Improve doom/help-packages

+ Cache package list
+ Show "generating package list" message the first time (better ux)
+ Display location of package files in package information
+ Turn links/file paths into buttons
+ Add link to module readmes (if any)

Mentioned in #4406
This commit is contained in:
Henrik Lissner 2020-12-11 01:42:21 -05:00
parent 55e90f064f
commit a3b8be52a8
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395

View file

@ -381,25 +381,33 @@ current file is in, or d) the module associated with the current major mode (see
;; ;;
;;; `doom/help-packages' ;;; `doom/help-packages'
(defun doom--help-package-insert-button (label path &optional regexp) (defun doom--help-insert-button (label &optional path)
(declare (indent defun)) (cl-destructuring-bind (uri . qs)
(let ((parts (split-string label "::" t)))
(cons (string-trim (car parts))
(string-join (cdr parts) "::")))
(let ((path (or path label)))
(insert-text-button (insert-text-button
(string-trim label) uri
'face 'link 'face 'link
'follow-link t 'follow-link t
'action 'action
`(lambda (_) (lambda (_)
(unless (file-exists-p ,path)
(user-error "Module doesn't exist"))
(when (window-dedicated-p) (when (window-dedicated-p)
(other-window 1)) (other-window 1))
(let ((buffer (find-file ,path))) (pcase (cond ((string-match-p "^https?://" qs) 'url)
(when ,(stringp regexp) ('file))
((or `file `nil)
(unless (file-exists-p path)
(user-error "Path does not exist: %S" path))
(let ((buffer (or (get-file-buffer path)
(find-file path))))
(when qs
(with-current-buffer buffer (with-current-buffer buffer
(goto-char (point-min)) (goto-char (point-min))
(if (re-search-forward ,regexp nil t) (re-search-forward qs)
(recenter) (recenter)))))
(message "Couldn't find the config block")))))))) (`url (browse-url uri))))))))
(defun doom--help-package-configs (package) (defun doom--help-package-configs (package)
(let ((default-directory doom-emacs-dir)) (let ((default-directory doom-emacs-dir))
@ -413,6 +421,7 @@ current file is in, or d) the module associated with the current major mode (see
":(exclude)*.org")) ":(exclude)*.org"))
"\n" t))) "\n" t)))
(defvar doom--help-packages-list nil)
;;;###autoload ;;;###autoload
(defun doom/help-packages (package) (defun doom/help-packages (package)
"Like `describe-package', but for packages installed by Doom modules. "Like `describe-package', but for packages installed by Doom modules.
@ -427,12 +436,18 @@ If prefix arg is present, refresh the cache."
(require 'finder-inf nil t) (require 'finder-inf nil t)
(require 'package) (require 'package)
(require 'straight) (require 'straight)
(let ((packages (delete-dups (let ((packages
(if (and doom--help-packages-list (null current-prefix-arg))
doom--help-packages-list
(message "Generating packages list for the first time...")
(sit-for 0.1)
(setq doom--help-packages-list
(delete-dups
(append (mapcar #'car package-alist) (append (mapcar #'car package-alist)
(mapcar #'car package--builtins) (mapcar #'car package--builtins)
(mapcar #'intern (hash-table-keys straight--build-cache)) (mapcar #'intern (hash-table-keys straight--build-cache))
(mapcar #'car (doom-package-list 'all)) (mapcar #'car (doom-package-list 'all))
nil)))) nil))))))
(unless (memq guess packages) (unless (memq guess packages)
(setq guess nil)) (setq guess nil))
(list (list
@ -440,9 +455,10 @@ If prefix arg is present, refresh the cache."
(completing-read (if guess (completing-read (if guess
(format "Select Doom package to search for (default %s): " (format "Select Doom package to search for (default %s): "
guess) guess)
"Describe Doom package: ") (format "Describe Doom package (%d): " (length packages)))
packages nil t nil nil packages nil t nil nil
(if guess (symbol-name guess)))))))) (if guess (symbol-name guess))))))))
;; TODO Refactor me.
(require 'core-packages) (require 'core-packages)
(doom-initialize-packages) (doom-initialize-packages)
(if (or (package-desc-p package) (if (or (package-desc-p package)
@ -477,20 +493,39 @@ If prefix arg is present, refresh the cache."
"unpinned") "unpinned")
"\n") "\n")
(package--print-help-section "Build") (package--print-help-section "Build")
(insert (let ((default-directory (straight--repos-dir (symbol-name package)))) (let ((default-directory (straight--repos-dir (symbol-name package))))
(cdr (insert (cdr (doom-call-process "git" "log" "-1" "--format=%D %h %ci"))
(doom-call-process "git" "log" "-1" "--format=%D %h %ci"))) "\n" indent))
"\n") (package--print-help-section "Build location")
(let ((build-dir (straight--build-dir (symbol-name package))))
(if (file-exists-p build-dir)
(doom--help-insert-button (abbreviate-file-name build-dir))
(insert "n/a")))
(insert "\n" indent)
(package--print-help-section "Repo location")
(let ((repo-dir (straight--repos-dir (symbol-name package))))
(if (file-exists-p repo-dir)
(doom--help-insert-button (abbreviate-file-name repo-dir))
(insert "n/a"))
(insert "\n"))
(let ((recipe (doom-package-build-recipe package))) (let ((recipe (doom-package-build-recipe package)))
(insert (format! "%s\n" (package--print-help-section "Recipe")
(indent 13 (insert (format "%s\n" (string-trim (pp-to-string recipe))))
(string-trim (pp-to-string recipe)))))
(package--print-help-section "Homepage") (package--print-help-section "Homepage")
(insert (doom--package-url package)))) (doom--help-insert-button (doom--package-url package)))
(`elpa (insert "[M]ELPA " (doom--package-url package))) (insert "\n" indent))
(`builtin (insert "Built-in")) (`elpa (insert "[M]ELPA ")
(`other (insert (doom--help-insert-button (doom--package-url package))
(package--print-help-section "Location")
(doom--help-insert-button
(abbreviate-file-name
(file-name-directory (locate-library (symbol-name package))))))
(`builtin (insert "Built-in\n")
(package--print-help-section "Location")
(doom--help-insert-button
(abbreviate-file-name
(file-name-directory (locate-library (symbol-name package))))))
(`other (doom--help-insert-button
(abbreviate-file-name (abbreviate-file-name
(or (symbol-file package) (or (symbol-file package)
(locate-library (symbol-name package)))))) (locate-library (symbol-name package))))))
@ -506,14 +541,24 @@ If prefix arg is present, refresh the cache."
(package--print-help-section "Modules") (package--print-help-section "Modules")
(insert "Declared by the following Doom modules:\n") (insert "Declared by the following Doom modules:\n")
(dolist (m modules) (dolist (m modules)
(insert indent) (let* ((module-path (pcase (car m)
(doom--help-package-insert-button
(format "%s %s" (car m) (or (cdr m) ""))
(pcase (car m)
(:core doom-core-dir) (:core doom-core-dir)
(:private doom-private-dir) (:private doom-private-dir)
(category (doom-module-path category (cdr m))))) (category (doom-module-path category (cdr m)))))
(insert "\n"))) (readme-path (expand-file-name "README.org" module-path)))
(insert indent)
(doom--help-insert-button
(format "%s %s" (car m) (or (cdr m) ""))
module-path)
(insert " (")
(if (file-exists-p readme-path)
(doom--help-insert-button
"readme"
(expand-file-name
"README.org"
readme-path))
(insert "no readme"))
(insert ")\n"))))
(package--print-help-section "Configs") (package--print-help-section "Configs")
(insert "This package is configured in the following locations:") (insert "This package is configured in the following locations:")
@ -582,7 +627,9 @@ If prefix arg is present, refresh the cache."
(format "%s.el" package)))) (format "%s.el" package))))
(_ (plist-get plist :url)))))) (_ (plist-get plist :url))))))
((and (require 'package nil t) ((and (require 'package nil t)
(or package-archive-contents (doom-refresh-packages-maybe)) (or package-archive-contents
(progn (package-refresh-contents)
package-archive-contents))
(pcase (package-desc-archive (cadr (assq package package-archive-contents))) (pcase (package-desc-archive (cadr (assq package package-archive-contents)))
("org" "https://orgmode.org") ("org" "https://orgmode.org")
((or "melpa" "melpa-mirror") ((or "melpa" "melpa-mirror")