2017-06-08 11:47:56 +02:00
|
|
|
;;; core/autoload/help.el -*- lexical-binding: t; -*-
|
2017-05-27 14:31:08 +02:00
|
|
|
|
2019-04-23 20:46:58 -04:00
|
|
|
(defvar doom--help-major-mode-module-alist
|
2019-02-24 21:00:19 -05:00
|
|
|
'((dockerfile-mode :tools docker)
|
2019-04-23 20:46:58 -04:00
|
|
|
(agda2-mode :lang agda)
|
2019-02-24 21:00:19 -05:00
|
|
|
(haxor-mode :lang assembly)
|
|
|
|
(mips-mode :lang assembly)
|
|
|
|
(nasm-mode :lang assembly)
|
|
|
|
(c-mode :lang cc)
|
|
|
|
(c++-mode :lang cc)
|
|
|
|
(objc++-mode :lang cc)
|
|
|
|
(crystal-mode :lang crystal)
|
|
|
|
(lisp-mode :lang common-lisp)
|
|
|
|
(csharp-mode :lang csharp)
|
|
|
|
(clojure-mode :lang clojure)
|
|
|
|
(graphql-mode :lang data)
|
|
|
|
(toml-mode :lang data)
|
|
|
|
(json-mode :lang data)
|
|
|
|
(yaml-mode :lang data)
|
|
|
|
(csv-mode :lang data)
|
|
|
|
(dhall-mode :lang data)
|
|
|
|
(erlang-mode :lang erlang)
|
|
|
|
(elixir-mode :lang elixir)
|
|
|
|
(elm-mode :lang elm)
|
2018-02-19 20:27:18 -05:00
|
|
|
(emacs-lisp-mode :lang emacs-lisp)
|
2019-02-24 21:00:19 -05:00
|
|
|
(ess-r-mode :lang ess)
|
|
|
|
(ess-julia-mode :lang ess)
|
|
|
|
(go-mode :lang go)
|
|
|
|
(haskell-mode :lang haskell)
|
|
|
|
(hy-mode :lang hy)
|
2019-04-23 20:46:58 -04:00
|
|
|
(idris-mode :lang idris)
|
2019-02-24 21:00:19 -05:00
|
|
|
(java-mode :lang java)
|
|
|
|
(js2-mode :lang javascript)
|
|
|
|
(rjsx-mode :lang javascript)
|
|
|
|
(typescript-mode :lang javascript)
|
|
|
|
(coffee-mode :lang javascript)
|
|
|
|
(julia-mode :lang julia)
|
2019-04-23 20:46:58 -04:00
|
|
|
(kotlin-mode :lang kotlin)
|
2019-02-24 21:00:19 -05:00
|
|
|
(latex-mode :lang latex)
|
|
|
|
(LaTeX-mode :lang latex)
|
|
|
|
(ledger-mode :lang ledger)
|
|
|
|
(lua-mode :lang lua)
|
|
|
|
(markdown-mode :lang markdown)
|
|
|
|
(gfm-mode :lang markdown)
|
|
|
|
(nim-mode :lang nim)
|
|
|
|
(nix-mode :lang nix)
|
|
|
|
(taureg-mode :lang ocaml)
|
|
|
|
(org-mode :lang org)
|
|
|
|
(perl-mode :lang perl)
|
|
|
|
(php-mode :lang php)
|
|
|
|
(hack-mode :lang php)
|
|
|
|
(plantuml-mode :lang plantuml)
|
2018-02-19 20:27:18 -05:00
|
|
|
(purescript-mode :lang purescript)
|
2019-02-24 21:00:19 -05:00
|
|
|
(python-mode :lang python)
|
2018-02-19 20:27:18 -05:00
|
|
|
(restclient-mode :lang rest)
|
2019-02-24 21:00:19 -05:00
|
|
|
(ruby-mode :lang ruby)
|
|
|
|
(enh-ruby-mode :lang ruby)
|
|
|
|
(rust-mode :lang rust)
|
|
|
|
(scala-mode :lang scala)
|
|
|
|
(sh-mode :lang sh)
|
|
|
|
(swift-mode :lang swift)
|
|
|
|
(web-mode :lang web)
|
|
|
|
(css-mode :lang web)
|
|
|
|
(scss-mode :lang web)
|
|
|
|
(sass-mode :lang web)
|
|
|
|
(less-css-mode :lang web)
|
2019-04-23 20:46:58 -04:00
|
|
|
(stylus-mode :lang web)
|
|
|
|
(terra-mode :lang terra)
|
|
|
|
(vala-mode :lang vala))
|
2019-05-01 19:12:52 -04:00
|
|
|
"An alist mapping major modes to Doom modules.
|
|
|
|
|
|
|
|
This is used by `doom/help-modules' to auto-select the module corresponding to
|
|
|
|
the current major-modea.")
|
2018-02-19 20:27:18 -05:00
|
|
|
|
2018-05-20 12:13:05 +02:00
|
|
|
|
|
|
|
;;
|
2019-04-23 20:46:58 -04:00
|
|
|
;;; Helpers
|
2018-05-20 12:13:05 +02:00
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom-active-minor-modes ()
|
|
|
|
"Return a list of active minor-mode symbols."
|
|
|
|
(cl-loop for mode in minor-mode-list
|
|
|
|
if (and (boundp mode) (symbol-value mode))
|
|
|
|
collect mode))
|
|
|
|
|
|
|
|
|
|
|
|
;;
|
2019-04-23 20:46:58 -04:00
|
|
|
;;; Custom describe commands
|
|
|
|
|
|
|
|
;;;###autoload (defalias 'doom/describe-autodefs #'doom/help-autodefs)
|
|
|
|
;;;###autoload (defalias 'doom/describe-module #'doom/help-modules)
|
|
|
|
;;;###autoload (defalias 'doom/describe-package #'doom/help-packages)
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom/describe-active-minor-mode (mode)
|
|
|
|
"Get information on an active minor mode. Use `describe-minor-mode' for a
|
|
|
|
selection of all minor-modes, active or not."
|
|
|
|
(interactive
|
|
|
|
(list (completing-read "Minor mode: " (doom-active-minor-modes))))
|
|
|
|
(describe-minor-mode-from-symbol
|
|
|
|
(cond ((stringp mode) (intern mode))
|
|
|
|
((symbolp mode) mode)
|
|
|
|
((error "Expected a symbol/string, got a %s" (type-of mode))))))
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom/describe-symbol (symbol)
|
|
|
|
"Show help for SYMBOL, a variable, function or macro."
|
|
|
|
(interactive
|
|
|
|
(list (helpful--read-symbol "Symbol: " #'helpful--bound-p)))
|
|
|
|
(let* ((sym (intern-soft symbol))
|
|
|
|
(bound (boundp sym))
|
|
|
|
(fbound (fboundp sym)))
|
|
|
|
(cond ((and sym bound (not fbound))
|
|
|
|
(helpful-variable sym))
|
|
|
|
((and sym fbound (not bound))
|
|
|
|
(helpful-callable sym))
|
|
|
|
((apropos (format "^%s\$" symbol)))
|
|
|
|
((apropos (format "%s" symbol))))))
|
|
|
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
;;; Documentation commands
|
|
|
|
|
2019-05-18 21:29:47 -04:00
|
|
|
(defun doom--org-headings (files &optional depth include-files)
|
|
|
|
"TODO"
|
2019-05-08 00:56:16 -04:00
|
|
|
(require 'org)
|
2019-05-15 20:51:52 -04:00
|
|
|
(let* ((default-directory doom-docs-dir)
|
|
|
|
(org-agenda-files (mapcar #'expand-file-name (doom-enlist files)))
|
|
|
|
(depth (if (integerp depth) depth)))
|
2019-04-23 20:46:58 -04:00
|
|
|
(unwind-protect
|
|
|
|
(delq nil
|
|
|
|
(org-map-entries
|
|
|
|
(lambda ()
|
2019-05-15 20:51:52 -04:00
|
|
|
(cl-destructuring-bind (level _reduced-level _todo _priority text tags)
|
|
|
|
(org-heading-components)
|
|
|
|
(let ((path (org-get-outline-path)))
|
|
|
|
(when (and (or (null depth)
|
|
|
|
(<= level depth))
|
|
|
|
(or (null tags)
|
|
|
|
(not (string-match-p ":TOC" tags))))
|
2019-05-18 21:29:47 -04:00
|
|
|
(propertize
|
2019-05-15 20:51:52 -04:00
|
|
|
(mapconcat
|
|
|
|
'identity
|
|
|
|
(list (mapconcat #'identity
|
|
|
|
(append (when include-files
|
|
|
|
(list (or (+org-get-property "TITLE")
|
|
|
|
(file-relative-name buffer-file-name))))
|
|
|
|
path
|
2019-05-19 19:15:29 -04:00
|
|
|
(list (replace-regexp-in-string org-any-link-re "\\4" text)))
|
2019-05-15 20:51:52 -04:00
|
|
|
" > ")
|
|
|
|
tags)
|
|
|
|
" ")
|
2019-05-18 21:29:47 -04:00
|
|
|
'location (cons buffer-file-name (point)))))))
|
2019-05-15 20:51:52 -04:00
|
|
|
t 'agenda))
|
2019-04-23 20:46:58 -04:00
|
|
|
(mapc #'kill-buffer org-agenda-new-buffers)
|
|
|
|
(setq org-agenda-new-buffers nil))))
|
|
|
|
|
2019-05-18 21:29:47 -04:00
|
|
|
;;;###autoload
|
|
|
|
(defun doom-completing-read-org-headings (prompt files &optional depth include-files initial-input)
|
|
|
|
"TODO"
|
2019-05-19 19:15:29 -04:00
|
|
|
(let (ivy-sort-functions-alist)
|
|
|
|
(if-let* ((result (completing-read
|
|
|
|
prompt
|
|
|
|
(doom--org-headings files depth include-files)
|
|
|
|
nil nil initial-input)))
|
|
|
|
(cl-destructuring-bind (file . location)
|
|
|
|
(get-text-property 0 'location result)
|
|
|
|
(find-file file)
|
|
|
|
(goto-char location))
|
|
|
|
(user-error "Aborted"))))
|
2019-05-18 21:29:47 -04:00
|
|
|
|
2019-04-23 20:46:58 -04:00
|
|
|
;;;###autoload
|
|
|
|
(defun doom/help ()
|
|
|
|
"Open Doom's user manual."
|
|
|
|
(interactive)
|
|
|
|
(find-file (expand-file-name "index.org" doom-docs-dir)))
|
|
|
|
|
|
|
|
;;;###autoload
|
2019-05-18 21:29:47 -04:00
|
|
|
(defun doom/help-search (&optional initial-input)
|
2019-04-23 20:46:58 -04:00
|
|
|
"Search Doom's documentation and jump to a headline."
|
|
|
|
(interactive)
|
2019-05-19 19:15:29 -04:00
|
|
|
(doom-completing-read-org-headings
|
|
|
|
"Find in Doom help: "
|
|
|
|
(list "getting_started.org"
|
|
|
|
"contributing.org"
|
|
|
|
"troubleshooting.org"
|
|
|
|
"tutorials.org"
|
|
|
|
"faq.org"
|
|
|
|
"../modules/README.org")
|
|
|
|
2 t initial-input))
|
2019-04-23 20:46:58 -04:00
|
|
|
|
2019-05-19 19:02:17 -04:00
|
|
|
;;;###autoload
|
|
|
|
(defun doom/help-news-search (&optional initial-input)
|
|
|
|
"Search headlines in Doom's newsletters."
|
|
|
|
(interactive)
|
|
|
|
(doom-completing-read-org-headings
|
2019-06-16 15:27:49 +02:00
|
|
|
"Find in News: "
|
|
|
|
(nreverse (doom-files-in (expand-file-name "news" doom-docs-dir)
|
|
|
|
:match "/[0-9]"
|
|
|
|
:relative-to doom-docs-dir
|
|
|
|
:sort t))
|
2019-05-19 19:02:17 -04:00
|
|
|
nil t initial-input))
|
|
|
|
|
2019-04-23 20:46:58 -04:00
|
|
|
;;;###autoload
|
2019-05-18 21:29:47 -04:00
|
|
|
(defun doom/help-faq (&optional initial-input)
|
2019-04-23 20:46:58 -04:00
|
|
|
"Search Doom's FAQ and jump to a question."
|
|
|
|
(interactive)
|
2019-05-18 21:29:47 -04:00
|
|
|
(doom-completing-read-org-headings
|
|
|
|
"Find in FAQ: " (list "faq.org")
|
|
|
|
nil nil initial-input))
|
2018-05-20 12:13:05 +02:00
|
|
|
|
|
|
|
;;;###autoload
|
2019-04-23 20:46:58 -04:00
|
|
|
(defun doom/help-news ()
|
|
|
|
"Open a Doom newsletter.
|
|
|
|
The latest newsletter will be selected by default."
|
|
|
|
(interactive)
|
|
|
|
(let* ((default-directory (expand-file-name "news/" doom-docs-dir))
|
|
|
|
(news-files (doom-files-in default-directory)))
|
|
|
|
(find-file
|
|
|
|
(read-file-name (format "Open Doom newsletter (current: v%s): "
|
|
|
|
doom-version)
|
|
|
|
default-directory
|
|
|
|
(if (member doom-version news-files)
|
|
|
|
doom-version
|
|
|
|
(concat (mapconcat #'number-to-string
|
|
|
|
(nbutlast (version-to-list doom-version) 1)
|
|
|
|
".")
|
|
|
|
".x"))
|
|
|
|
t doom-version))))
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom/help-autodefs (autodef)
|
2019-05-01 19:12:52 -04:00
|
|
|
"Open documentation for an autodef.
|
2018-05-20 12:13:05 +02:00
|
|
|
|
2019-04-23 20:46:58 -04:00
|
|
|
An autodef is a Doom concept. It is a function or macro that is always defined,
|
|
|
|
whether or not its containing module is disabled (in which case it will safely
|
2019-05-01 19:12:52 -04:00
|
|
|
no-op without evaluating its arguments). This syntactic sugar lets you use them
|
|
|
|
without needing to check if they are available."
|
2018-05-20 12:13:05 +02:00
|
|
|
(interactive
|
2018-06-15 15:47:29 +02:00
|
|
|
(let* ((settings
|
|
|
|
(cl-loop with case-fold-search = nil
|
|
|
|
for sym being the symbols of obarray
|
|
|
|
for sym-name = (symbol-name sym)
|
|
|
|
if (and (or (functionp sym)
|
|
|
|
(macrop sym))
|
|
|
|
(string-match-p "[a-z]!$" sym-name))
|
|
|
|
collect sym))
|
|
|
|
(sym (symbol-at-point))
|
2019-03-05 01:54:39 -05:00
|
|
|
(autodef
|
2018-06-15 15:47:29 +02:00
|
|
|
(completing-read
|
2018-06-16 12:26:58 +02:00
|
|
|
"Describe setter: "
|
2018-06-15 15:47:29 +02:00
|
|
|
;; TODO Could be cleaner (refactor me!)
|
|
|
|
(cl-loop with maxwidth = (apply #'max (mapcar #'length (mapcar #'symbol-name settings)))
|
|
|
|
for def in (sort settings #'string-lessp)
|
2019-02-24 20:40:16 -05:00
|
|
|
if (get def 'doom-module)
|
2018-06-15 15:47:29 +02:00
|
|
|
collect
|
|
|
|
(format (format "%%-%ds%%s" (+ maxwidth 4))
|
|
|
|
def (propertize (format "%s %s" (car it) (cdr it))
|
|
|
|
'face 'font-lock-comment-face))
|
2019-02-24 20:40:16 -05:00
|
|
|
else if (and (string-match-p "^set-.+!$" (symbol-name def))
|
|
|
|
(symbol-file def)
|
|
|
|
(file-in-directory-p (symbol-file def) doom-core-dir))
|
2018-06-15 15:47:29 +02:00
|
|
|
collect
|
|
|
|
(format (format "%%-%ds%%s" (+ maxwidth 4))
|
2019-02-24 20:40:16 -05:00
|
|
|
def (propertize (format "core/%s.el" (file-name-sans-extension (file-relative-name (symbol-file def) doom-core-dir)))
|
|
|
|
'face 'font-lock-comment-face)))
|
2018-06-15 15:47:29 +02:00
|
|
|
nil t
|
|
|
|
(when (and (symbolp sym)
|
|
|
|
(string-match-p "!$" (symbol-name sym)))
|
|
|
|
(symbol-name sym)))))
|
2019-03-05 01:54:39 -05:00
|
|
|
(list (and autodef (car (split-string autodef " "))))))
|
|
|
|
(or (stringp autodef)
|
|
|
|
(functionp autodef)
|
|
|
|
(signal 'wrong-type-argument (list '(stringp functionp) autodef)))
|
|
|
|
(let ((fn (if (functionp autodef)
|
|
|
|
autodef
|
|
|
|
(intern-soft autodef))))
|
2018-06-02 16:23:50 +02:00
|
|
|
(or (fboundp fn)
|
2019-03-05 01:54:39 -05:00
|
|
|
(error "'%s' is not a valid DOOM autodef" autodef))
|
2018-06-15 15:47:29 +02:00
|
|
|
(if (fboundp 'helpful-callable)
|
|
|
|
(helpful-callable fn)
|
|
|
|
(describe-function fn))))
|
2018-05-20 12:13:05 +02:00
|
|
|
|
2019-03-05 01:53:52 -05:00
|
|
|
;;;###autoload
|
2019-04-23 20:46:58 -04:00
|
|
|
(defun doom/help-modules (category module)
|
|
|
|
"Open the documentation for a Doom module.
|
2018-01-28 03:00:25 -05:00
|
|
|
|
2019-04-21 19:59:44 -04:00
|
|
|
CATEGORY is a keyword and MODULE is a symbol. e.g. :editor and 'evil.
|
2018-06-15 15:51:05 +02:00
|
|
|
|
|
|
|
Automatically selects a) the module at point (in private init files), b) the
|
|
|
|
module derived from a `featurep!' or `require!' call, c) the module that the
|
|
|
|
current file is in, or d) the module associated with the current major mode (see
|
2019-04-23 20:46:58 -04:00
|
|
|
`doom--help-major-mode-module-alist')."
|
2017-05-27 14:31:08 +02:00
|
|
|
(interactive
|
2018-06-15 15:51:05 +02:00
|
|
|
(let* ((module
|
|
|
|
(cond ((and buffer-file-name
|
|
|
|
(eq major-mode 'emacs-lisp-mode)
|
|
|
|
(file-in-directory-p buffer-file-name doom-private-dir)
|
|
|
|
(save-excursion (goto-char (point-min))
|
|
|
|
(re-search-forward "^\\s-*(doom! " nil t))
|
|
|
|
(thing-at-point 'sexp t)))
|
|
|
|
((save-excursion
|
|
|
|
(require 'smartparens)
|
|
|
|
(ignore-errors
|
|
|
|
(sp-beginning-of-sexp)
|
|
|
|
(unless (eq (char-after) ?\()
|
|
|
|
(backward-char))
|
|
|
|
(let ((sexp (sexp-at-point)))
|
|
|
|
(when (memq (car-safe sexp) '(featurep! require!))
|
|
|
|
(format "%s %s" (nth 1 sexp) (nth 2 sexp)))))))
|
|
|
|
((and buffer-file-name
|
2019-06-25 21:38:16 +02:00
|
|
|
(when-let (mod (doom-module-from-path buffer-file-name))
|
2018-06-15 15:51:05 +02:00
|
|
|
(format "%s %s" (car mod) (cdr mod)))))
|
2019-06-25 21:38:16 +02:00
|
|
|
((when-let (mod (cdr (assq major-mode doom--help-major-mode-module-alist)))
|
2018-06-15 15:51:05 +02:00
|
|
|
(format "%s %s"
|
|
|
|
(symbol-name (car mod))
|
|
|
|
(symbol-name (cadr mod)))))))
|
|
|
|
(module-string
|
|
|
|
(completing-read
|
|
|
|
"Describe module: "
|
|
|
|
(cl-loop for path in (doom-module-load-path 'all)
|
|
|
|
for (cat . mod) = (doom-module-from-path path)
|
|
|
|
for format = (format "%s %s" cat mod)
|
|
|
|
if (doom-module-p cat mod)
|
|
|
|
collect format
|
2019-04-23 20:46:58 -04:00
|
|
|
else if (and cat mod)
|
2018-06-15 15:51:05 +02:00
|
|
|
collect (propertize format 'face 'font-lock-comment-face))
|
|
|
|
nil t nil nil module))
|
|
|
|
(key (split-string module-string " ")))
|
|
|
|
(list (intern (car key))
|
|
|
|
(intern (cadr key)))))
|
|
|
|
(cl-check-type category symbol)
|
|
|
|
(cl-check-type module symbol)
|
2019-04-17 16:38:44 -04:00
|
|
|
(let ((path (doom-module-locate-path category module)))
|
|
|
|
(unless (file-readable-p path)
|
|
|
|
(error "'%s %s' isn't a valid module; it doesn't exist" category module))
|
|
|
|
(if-let* ((readme-path (doom-module-locate-path category module "README.org")))
|
|
|
|
(find-file readme-path)
|
|
|
|
(if (y-or-n-p (format "The '%s %s' module has no README file. Explore its directory?"
|
|
|
|
category module))
|
|
|
|
(doom-project-browse path)
|
|
|
|
(user-error "Aborted module lookup")))))
|
2018-03-12 12:51:05 -04:00
|
|
|
|
2019-04-23 20:46:58 -04:00
|
|
|
|
|
|
|
;;
|
|
|
|
;;; `doom/help-packages'
|
|
|
|
|
2019-05-08 02:08:08 -04:00
|
|
|
(defun doom--help-package-insert-button (label path &optional regexp)
|
2019-03-05 01:53:52 -05:00
|
|
|
(declare (indent defun))
|
|
|
|
(insert-text-button
|
|
|
|
(string-trim label)
|
|
|
|
'face 'link
|
|
|
|
'follow-link t
|
|
|
|
'action
|
|
|
|
`(lambda (_)
|
|
|
|
(unless (file-exists-p ,path)
|
|
|
|
(user-error "Module doesn't exist"))
|
|
|
|
(when (window-dedicated-p)
|
|
|
|
(other-window 1))
|
|
|
|
(let ((buffer (find-file ,path)))
|
|
|
|
(when ,(stringp regexp)
|
|
|
|
(with-current-buffer buffer
|
|
|
|
(goto-char (point-min))
|
|
|
|
(if (re-search-forward ,regexp nil t)
|
|
|
|
(recenter)
|
|
|
|
(message "Couldn't find the config block"))))))))
|
2018-05-20 12:13:05 +02:00
|
|
|
|
2019-05-08 02:08:08 -04:00
|
|
|
(defun doom--help-packages-list (&optional refresh)
|
|
|
|
(or (unless refresh
|
|
|
|
(doom-cache-get 'help-packages))
|
|
|
|
(doom-cache-set 'help-packages (doom-package-list 'all))))
|
|
|
|
|
|
|
|
(defun doom--help-package-configs (package)
|
|
|
|
;; TODO Add git checks, in case ~/.emacs.d isn't a git repo
|
|
|
|
(let ((default-directory doom-emacs-dir))
|
|
|
|
(split-string
|
|
|
|
(shell-command-to-string
|
|
|
|
(format "git grep --no-break --no-heading --line-number '%s %s\\($\\| \\)'"
|
|
|
|
"\\(^;;;###package\\|(after!\\|(def-package!\\)"
|
|
|
|
package))
|
|
|
|
"\n" t)))
|
2019-03-05 01:53:52 -05:00
|
|
|
|
2019-03-04 19:49:27 -05:00
|
|
|
;;;###autoload
|
2019-04-23 20:46:58 -04:00
|
|
|
(defun doom/help-packages (package)
|
|
|
|
"Like `describe-package', but for packages installed by Doom modules.
|
2019-03-04 19:49:27 -05:00
|
|
|
|
2019-03-05 01:53:52 -05:00
|
|
|
Only shows installed packages. Includes information about where packages are
|
|
|
|
defined and configured.
|
2019-03-04 19:49:27 -05:00
|
|
|
|
2019-04-23 20:46:58 -04:00
|
|
|
If prefix arg is present, refresh the cache."
|
2019-03-04 19:49:27 -05:00
|
|
|
(interactive
|
2019-05-08 02:08:08 -04:00
|
|
|
(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))))))))
|
2019-04-23 20:46:58 -04:00
|
|
|
(if (or (package-desc-p package)
|
|
|
|
(and (symbolp package)
|
|
|
|
(or (assq package package-alist)
|
|
|
|
(assq package package-archive-contents)
|
|
|
|
(assq package package--builtins))))
|
|
|
|
(describe-package package)
|
2019-05-08 02:08:08 -04:00
|
|
|
(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"))))
|
2019-03-05 01:53:52 -05:00
|
|
|
(save-excursion
|
|
|
|
(with-current-buffer (help-buffer)
|
2019-05-08 02:08:08 -04:00
|
|
|
(let ((doom-packages (doom--help-packages-list))
|
|
|
|
(inhibit-read-only t)
|
|
|
|
(indent (make-string 13 ? )))
|
2019-03-05 01:53:52 -05:00
|
|
|
(goto-char (point-min))
|
2019-05-08 02:08:08 -04:00
|
|
|
(if (re-search-forward "^ *Status: " nil t)
|
|
|
|
(progn
|
|
|
|
(end-of-line)
|
2019-03-05 01:53:52 -05:00
|
|
|
(insert "\n"))
|
2019-05-08 02:08:08 -04:00
|
|
|
(re-search-forward "\n\n" nil t))
|
|
|
|
|
|
|
|
(package--print-help-section "Source")
|
2019-05-30 13:59:39 -04:00
|
|
|
(insert (or (pcase (ignore-errors (doom-package-backend package))
|
|
|
|
(`elpa (concat "[M]ELPA " (doom--package-url package)))
|
|
|
|
(`quelpa (format "QUELPA %s" (prin1-to-string (doom-package-prop package :recipe))))
|
|
|
|
(`emacs "Built-in")
|
|
|
|
(_ (symbol-file package)))
|
|
|
|
"unknown")
|
2019-05-19 20:30:09 -04:00
|
|
|
"\n")
|
2019-05-08 02:08:08 -04:00
|
|
|
|
|
|
|
(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))
|
|
|
|
(insert indent)
|
|
|
|
(doom--help-package-insert-button
|
|
|
|
(format "%s %s" (car m) (or (cdr m) ""))
|
|
|
|
(pcase (car m)
|
|
|
|
(:core doom-core-dir)
|
|
|
|
(:private doom-private-dir)
|
|
|
|
(category (doom-module-path category (cdr m)))))
|
|
|
|
(insert "\n")))
|
|
|
|
|
|
|
|
(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
|
|
|
|
location
|
|
|
|
'face 'link
|
|
|
|
'follow-link t
|
|
|
|
'action
|
|
|
|
`(lambda (_)
|
|
|
|
(cl-destructuring-bind (file line _match)
|
|
|
|
,(split-string location ":")
|
|
|
|
(find-file (expand-file-name file doom-emacs-dir))
|
2019-05-15 20:53:11 -04:00
|
|
|
(goto-char (point-min))
|
|
|
|
(forward-line (1- line))
|
2019-05-08 02:08:08 -04:00
|
|
|
(recenter)))))))))
|
2019-03-04 19:49:27 -05:00
|
|
|
|
2019-05-19 20:29:51 -04:00
|
|
|
(defvar doom--package-cache nil)
|
|
|
|
(defun doom--package-list ()
|
|
|
|
(let* ((guess (or (function-called-at-point)
|
|
|
|
(symbol-at-point))))
|
|
|
|
(require 'finder-inf nil t)
|
|
|
|
(unless package--initialized
|
|
|
|
(package-initialize t))
|
|
|
|
(let ((packages (or doom--package-cache
|
|
|
|
(progn
|
|
|
|
(message "Reading packages...")
|
|
|
|
(cl-delete-duplicates
|
|
|
|
(append (mapcar 'car package-alist)
|
|
|
|
(mapcar 'car package--builtins)
|
|
|
|
(mapcar 'car package-archive-contents)))))))
|
|
|
|
(setq doom--package-cache packages)
|
|
|
|
(unless (memq guess packages)
|
|
|
|
(setq guess nil))
|
|
|
|
(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)))))))
|
|
|
|
|
|
|
|
(defun doom--package-url (package)
|
|
|
|
(cond ((assq package package--builtins)
|
|
|
|
(user-error "Package is built into Emacs and cannot be looked up"))
|
2019-06-25 21:38:16 +02:00
|
|
|
((when-let (location (locate-library (symbol-name package)))
|
2019-05-19 20:29:51 -04:00
|
|
|
(with-temp-buffer
|
|
|
|
(insert-file-contents (concat (file-name-sans-extension location) ".el")
|
|
|
|
nil 0 4096)
|
|
|
|
(let ((case-fold-search t))
|
|
|
|
(when (re-search-forward " \\(?:URL\\|homepage\\|Website\\): \\(http[^\n]+\\)\n" nil t)
|
|
|
|
(match-string-no-properties 1))))))
|
|
|
|
((and (ignore-errors (eq (doom-package-backend package) 'quelpa))
|
|
|
|
(let* ((plist (cdr (doom-package-prop package :recipe)))
|
|
|
|
(fetcher (plist-get plist :fetcher)))
|
|
|
|
(pcase fetcher
|
|
|
|
(`git (plist-get plist :url))
|
|
|
|
(`github (format "https://github.com/%s.git" (plist-get plist :repo)))
|
|
|
|
(`gitlab (format "https://gitlab.com/%s.git" (plist-get plist :repo)))
|
|
|
|
(`bitbucket (format "https://bitbucket.com/%s" (plist-get plist :repo)))
|
|
|
|
(`wiki (format "https://www.emacswiki.org/emacs/download/%s"
|
|
|
|
(or (car-safe (doom-enlist (plist-get plist :files)))
|
|
|
|
(format "%s.el" package))))
|
|
|
|
(_ (plist-get plist :url))))))
|
|
|
|
((and (require 'package nil t)
|
|
|
|
(or package-archive-contents (doom-refresh-packages-maybe))
|
|
|
|
(pcase (package-desc-archive (cadr (assq package package-archive-contents)))
|
|
|
|
("org" "https://orgmode.org")
|
|
|
|
((or "melpa" "melpa-mirror")
|
|
|
|
(format "https://melpa.org/#/%s" package))
|
|
|
|
("elpa"
|
|
|
|
(format "https://elpa.gnu.org/packages/%s.html" package))
|
|
|
|
(archive
|
|
|
|
(user-error "%S isn't installed through any known source (%s)"
|
|
|
|
package archive)))))
|
|
|
|
((user-error "Cannot find the homepage for %S" package))))
|
|
|
|
|
2019-03-12 14:21:41 +10:00
|
|
|
;;;###autoload
|
2019-05-15 20:53:11 -04:00
|
|
|
(defun doom/help-package-config (package)
|
2019-05-08 02:08:08 -04:00
|
|
|
"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."
|
2019-05-19 20:29:51 -04:00
|
|
|
(interactive (list (doom--package-list)))
|
2019-05-08 02:08:08 -04:00
|
|
|
(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))
|
2019-05-15 20:53:11 -04:00
|
|
|
(goto-char (point-min))
|
|
|
|
(forward-line (1- line))
|
2019-05-08 02:08:08 -04:00
|
|
|
(recenter)))
|
2019-05-19 20:29:51 -04:00
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom/help-package-homepage (package)
|
|
|
|
"Open PACKAGE's repo or homepage in your browser."
|
|
|
|
(interactive (list (doom--package-list)))
|
|
|
|
(browse-url (doom--package-url package)))
|