This package provides a generic help system similar to Emacs Help. Unlike Emacs Help, ghelp works for more major-modes and is extensible with backends.
Features
- Unified entry command
- Unified UI
- Documentation history, you can search in history, go back/forward.
Currently supported backends
Download the files and add them to load path.
With use-package
:
(use-package ghelp)
Without use-package
:
(require 'ghelp)
ghelp-describe | Describe a symbol in current major mode |
gehlp-describe-at-point | Describe symbol at point (without prompt) |
ghelp-resume | Reopen last page |
ghelp-describe-elisp | Describe a Emacs symbol (like apropos) |
ghelp-describe-function | Describe a Elisp function/macro/keyboard macro |
ghelp-describe-variable | Describe a Elisp variable |
ghelp-describe-key | Describe a key sequence |
Normally ghelp-describe
shows documentation of the symbol at point, If you want to query for a symbol (e.g., with completion), type C-u
then ghelp-describe
.
Each backend are loaded automatically when you enabled the corresponding package. For example, when you load helpful.el
, ghelp automatically loads its helpful backend.
A ghelp buffer is called a page. Each page is made of several entries. Each entry is a self-contained documentation. (For example, you could have a entry for a symbol as a function and another one for it as a variable.)
Commands you can use:
Key | Command |
---|---|
? | show help |
f/b | go forward/backward in history |
TAB | next button |
S-TAB | previous button |
h | collapse/expand entry |
g | refresh page |
q | close page |
s | search/switch to a page |
For more bindings, type ?
in a ghelp buffer, or type M-x ghelp-describe ghelp-page-mode-map RET
.
If you want several major modes to share the same set of history and backends (like lisp-interaction-mode
and emacs-lisp-mode
), add an entry (mode1 . mode2)
to ghelp-mode-share-alist
, and mode1
will share everything of mode2
.
You can customize faces: ghelp-entry
, ghelp-folded-entry
, and ghelp-entry-title
.
Normally if you call ghelp-describe-function
it selects the backends to use by the current major-mode. If you want to look up some symbol with a specific backend, try (ghelp-describe-with-mode ’prompt 'mode)
. For example, you can bind
(define-key (kbd "C-h C-e") (lambda () (interactive) (ghelp-describe-with-mode ’force-prompt ’emacs-lisp-mode)))
to look up Emacs Lisp symbols regardless of which major mode you are currently in.
A backend is a function that takes two arguments COMMAND
and DATA
.
If COMMAND
is symbol
, return a string representing the symbol that the user wants documentation for.
If COMMAND
is doc
, return the documentation for SYMBOL
, where SYMBOL
is from DATA
:
(:symbol-name SYMBOL :marker MARKER)
And MARKER
is the marker at the point where user invoked ghelp-describe
. Returned documentation should be a string ending with a newline. Return nil if no documentation is found.
Below is an example backend that gets the symbol and then the documentation and returns them. It only recognizes “woome”, “veemo”, “love” and “tank”.
(defun ghelp-dummy-backend (command data)
(pcase command
('symbol (completing-read "Symbol: "
'("woome" "veemo" "love" "tank")))
('doc (pcase (plist-get data :symbol-name)
("woome" "Woome!!\n")
("veemo" "Veemo!!\n")
("love" "Peace!!\n")
("tank" "TANK! THE! BEST!\n")))))
You can try this out by typing M-x ghelp-dummy RET
.
Once you have a backend, register it by
(ghelp-register-backend 'major-mode #'your-backend-function)
Besides a string, the returned documentation could carry more information.
First, it can be a list of form (TITLE BODY)
where TITLE
is the title for your documentation, and BODY
is the body of your documentation. This way you can use a title other than the symbol name.
Second, you can return multiple documentations by returning a list ((TITLE BODY)...)
, where each element is a (TITLE BODY)
form.
Ghelp also supports asynchronous backends. Instead of returning the documentation immediately, a backend can return a callback function. This function should have a signature like (display-fn &rest _)
. display-fn
is a function that takes a single argument doc
. &rest _
allows ghelp to extend this interface in the future.
An example:
(lambda (display-fn)
(backend-async-call
(lambda (doc)
(funcall display-fn "(documentation)"))))
You can use buttons in your documentation as long they are text buttons made by text properties, rather than overlay buttons. After all your are returning a string, which doesn’t carry overlays.
However, one problem might arise if the command invoked by your button needs some information, like the symbol that this documentation page is describing. You can get that by (ghelp-get-page-data)
, which returns a plist of form
(:symbol-name SYMBOL :mode MODE :marker MARKER)
SYMBOL
and MARKER
are the same as before, MODE
is the major mode.
Normally each backend is tied to an actual major mode. But if you want to write a backend that doesn’t associate with any major mode, like a dictionary, you can use ghelp-describe-with-mode
, and use dictionary
as your “major mode”.
Backends like eglot can support a wide range of major modes that can’t be determined ahead of time. For this kinds of backends, use t
for the MODE
argument when registering them:
(ghelp-register-backend t #'your-backend-function)
Your backend function should support the available-p
command, in addition to the symbol
and doc
command. It should return t/nil indication the backend’s availability in the current buffer.
Eglot
Helpful
Sly