Fix & improve doom/help-package{s,-config}

The help buffer for Doom packages now display:

- locations of (and links to) where a package is configured in Doom
- limited documentation for site packages (like elisp-mode)
This commit is contained in:
Henrik Lissner 2019-05-08 02:08:08 -04:00
parent b9729380c4
commit ed562212eb
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395

View file

@ -320,7 +320,7 @@ current file is in, or d) the module associated with the current major mode (see
;; ;;
;;; `doom/help-packages' ;;; `doom/help-packages'
(defun doom--describe-package-insert-button (label path &optional regexp) (defun doom--help-package-insert-button (label path &optional regexp)
(declare (indent defun)) (declare (indent defun))
(insert-text-button (insert-text-button
(string-trim label) (string-trim label)
@ -340,43 +340,20 @@ current file is in, or d) the module associated with the current major mode (see
(recenter) (recenter)
(message "Couldn't find the config block")))))))) (message "Couldn't find the config block"))))))))
(defun doom--completing-package (&optional prompt refresh) (defun doom--help-packages-list (&optional refresh)
(let* (guess (or (unless refresh
(sym (symbol-at-point)) (doom-cache-get 'help-packages))
(package-list (or (unless refresh (doom-cache-get 'help-packages))
(doom-cache-set 'help-packages (doom-package-list 'all)))) (doom-cache-set 'help-packages (doom-package-list 'all))))
(pkg-alist (seq-group-by #'car package-list))
(packages (defun doom--help-package-configs (package)
;; TODO Refactor me ;; TODO Add git checks, in case ~/.emacs.d isn't a git repo
(cl-loop for (pkg . descs) in (cl-sort pkg-alist #'string-lessp :key #'car) (let ((default-directory doom-emacs-dir))
for str = (split-string
(format "%-40s %s" (shell-command-to-string
pkg (format "git grep --no-break --no-heading --line-number '%s %s\\($\\| \\)'"
(cl-loop for (desc . plist) in descs "\\(^;;;###package\\|(after!\\|(def-package!\\)"
for module = (car (plist-get plist :modules)) package))
collect "\n" t)))
(format "%s%s"
(car module)
(if (cdr module) (format " %s" (cdr module)) ""))
into modules
finally return
(propertize (string-join modules ", ")
'face 'font-lock-comment-face)))
collect str
and do
(when (eq pkg sym)
(setq guess str)))))
(intern
(car (split-string
(completing-read
(or prompt
(if guess
(format "Describe package (default %s): "
(car (split-string guess " ")))
"Describe package: "))
packages nil t nil nil
(if guess guess))
" ")))))
;;;###autoload ;;;###autoload
(defun doom/help-packages (package) (defun doom/help-packages (package)
@ -387,61 +364,118 @@ defined and configured.
If prefix arg is present, refresh the cache." If prefix arg is present, refresh the cache."
(interactive (interactive
(list (doom--completing-package nil current-prefix-arg))) (let* ((guess (or (function-called-at-point)
(symbol-at-point))))
(require 'finder-inf nil t)
(unless package--initialized
(package-initialize t))
(let* ((doom--packages (doom--help-packages-list))
(packages (cl-delete-duplicates
(append (mapcar 'car package-alist)
(mapcar 'car package--builtins)
(mapcar 'car doom--packages)
nil))))
(unless (memq guess packages)
(setq guess nil))
(list (intern (completing-read (if guess
(format "Select package to search for (default %s): "
guess)
"Describe package: ")
packages nil t nil nil
(if guess (symbol-name guess))))))))
(if (or (package-desc-p package) (if (or (package-desc-p package)
(and (symbolp package) (and (symbolp package)
(or (assq package package-alist) (or (assq package package-alist)
(assq package package-archive-contents) (assq package package-archive-contents)
(assq package package--builtins)))) (assq package package--builtins))))
(describe-package package) (describe-package package)
(doom--describe-package package)) (help-setup-xref (list #'doom/help-packages package)
(called-interactively-p 'interactive))
(with-help-window (help-buffer)
(with-current-buffer standard-output
(prin1 package)
(princ " is a site package.\n\n"))))
(save-excursion (save-excursion
(with-current-buffer (help-buffer) (with-current-buffer (help-buffer)
(let ((inhibit-read-only t)) (let ((doom-packages (doom--help-packages-list))
(inhibit-read-only t)
(indent (make-string 13 ? )))
(goto-char (point-min)) (goto-char (point-min))
(when (and (doom-package-installed-p package) (if (re-search-forward "^ *Status: " nil t)
(re-search-forward "^ *Status: " nil t)) (progn
(end-of-line) (end-of-line)
(let ((indent (make-string (length (match-string 0)) ? ))) (insert "\n"))
(insert "\n" indent "Installed by the following Doom modules:\n") (re-search-forward "\n\n" nil t))
(package--print-help-section "Source")
(insert
(pcase (ignore-errors (doom-package-backend package))
(`elpa "[M]ELPA")
(`quelpa (format "QUELPA %s" (prin1-to-string (doom-package-prop package :recipe))))
(`emacs "Built-in")
(_ (symbol-file package)))
"\n")
(when (assq package doom-packages)
(package--print-help-section "Modules")
(insert "Declared by the following Doom modules:\n")
(dolist (m (doom-package-prop package :modules)) (dolist (m (doom-package-prop package :modules))
(insert indent) (insert indent)
(doom--describe-package-insert-button (doom--help-package-insert-button
(format "%s %s" (car m) (or (cdr m) "")) (format "%s %s" (car m) (or (cdr m) ""))
(pcase (car 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")) (insert "\n")))
(package--print-help-section "Source")
(pcase (doom-package-backend package)
(`elpa (insert "[M]ELPA"))
(`quelpa (insert (format "QUELPA %s" (prin1-to-string (doom-package-prop package :recipe)))))
(`emacs (insert "Built-in")))
(insert "\n")
(package--print-help-section "Configs") (package--print-help-section "Configs")
(insert "This package is configured in the following locations:")
(dolist (location (doom--help-package-configs package))
(insert "\n" indent)
(insert-text-button (insert-text-button
"See where this package is configured" location
'face 'link 'face 'link
'follow-link t 'follow-link t
'action 'action
`(lambda (_) (doom/help-package-config ',package))))))))) `(lambda (_)
;;;###autoload
(defun doom/help-package-config (package)
"Jump to any `def-package!', `after!' or ;;;###package block for PACKAGE."
(interactive
(list (doom--completing-package "Select package to search for: " current-prefix-arg)))
(let* ((default-directory doom-emacs-dir)
(results (shell-command-to-string
(format "git grep --no-break --no-heading --line-number '%s %s\\($\\| \\)'"
"\\(^;;;###package\\|(after!\\|(def-package!\\)"
package)))
(select (completing-read "Jump to config: " (split-string results "\n" t))))
(cl-destructuring-bind (file line _match) (cl-destructuring-bind (file line _match)
(split-string select ":") ,(split-string location ":")
(find-file (expand-file-name file doom-emacs-dir)) (find-file (expand-file-name file doom-emacs-dir))
(goto-line (string-to-number line)) (goto-line (string-to-number line))
(recenter)))) (recenter)))))))))
;;;###autoload
(defun doom/help-package-config (package &optional arg)
"Jump to any `def-package!', `after!' or ;;;###package block for PACKAGE.
This only searches `doom-emacs-dir' (typically ~/.emacs.d) and does not include
config blocks in your private config."
(interactive
(let* ((guess (or (function-called-at-point)
(symbol-at-point))))
(require 'finder-inf nil t)
(unless package--initialized
(package-initialize t))
(let ((packages (cl-delete-duplicates
(append (mapcar 'car package-alist)
(mapcar 'car package--builtins)
nil))))
(unless (memq guess packages)
(setq guess nil))
(list (intern (completing-read (if guess
(format "Select package to search for (default %s): "
guess)
"Describe package: ")
packages nil t nil nil
(if guess (symbol-name guess))))))))
(cl-destructuring-bind (file line _match)
(split-string
(completing-read
"Jump to config: "
(or (doom--help-package-configs package)
(user-error "This package isn't configured by you or Doom")))
":")
(find-file (expand-file-name file doom-emacs-dir))
(goto-line (string-to-number line))
(recenter)))