Code Monkey home page Code Monkey logo

ghelp's Introduction

ghelp

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

☞ Screencasts

Install & load

Download the files and add them to load path.

With use-package:

(use-package ghelp)

Without use-package:

(require 'ghelp)

Usage

ghelp-describeDescribe a symbol in current major mode
gehlp-describe-at-pointDescribe symbol at point (without prompt)
ghelp-resumeReopen last page
ghelp-describe-elispDescribe a Emacs symbol (like apropos)
ghelp-describe-functionDescribe a Elisp function/macro/keyboard macro
ghelp-describe-variableDescribe a Elisp variable
ghelp-describe-keyDescribe 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.

Enable backends

Each backend are loaded automatically when you enabled the corresponding package. For example, when you load helpful.el, ghelp automatically loads its helpful backend.

In ghelp buffer

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:

KeyCommand
?show help
f/bgo forward/backward in history
TABnext button
S-TABprevious button
hcollapse/expand entry
grefresh page
qclose page
ssearch/switch to a page

For more bindings, type ? in a ghelp buffer, or type M-x ghelp-describe ghelp-page-mode-map RET.

Customization

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.

Write a backend

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)

Advanced backend

Returned documentation

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.

Asynchronous backend

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)"))))

Use buttons in your 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.

Use a phony 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”.

Backend that can support undetermined major modes

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.

Screencasts

Eglot

./ghelp-eglot-800.gif

Helpful

./ghelp-helpful-800.gif

Sly

./ghelp-sly.png

ghelp's People

Contributors

casouri avatar

Stargazers

Suleyman Boyar avatar  avatar Phil Crosby avatar  avatar GotW avatar Alexey Terekhov avatar Zhengyi avatar Sergei Pashakhin avatar Kevin Brubeck Unhammer avatar Yevgnen avatar Kostas Andreadis avatar Mohammed Zeglam avatar  avatar Kyle Mitchell avatar Case Duckworth avatar  avatar Qingshui Zheng avatar Mr Unhappy avatar yqu212 avatar jdhao avatar SteamedFish avatar  avatar Fox Kiester avatar Keith Pinson avatar Yuriy Gritsenko avatar Damien Garaud avatar Alexander Barbosa avatar Alex Murray avatar Shelby Snead avatar  avatar  avatar Geekinney avatar  avatar Entroperiance.J avatar  avatar Terje Larsen avatar Xu Chunyang avatar Oleg Pykhalov avatar Clemens Radermacher avatar driftcrow avatar 我没有抓狂 avatar

Watchers

James Cloos avatar  avatar  avatar

ghelp's Issues

Byte compilation raises warnings and exits with 1

I was trying to byte-compile this, but it fails, I guess it is mainly due to the geiser-doc not being guarded (only via the main file). I think it is quite common practice to compile all the el files so it would be nice if that would work. Or should I make sure gesier exists during the byte compilation as well?

$ emacs -L . --batch -f batch-byte-compile *.el
Loading /nix/store/j7b4gj9q7frw194cpd4m7yikzyfjl2x1-emacs-git-with-packages-20201025.0/share/emacs/site-lisp/site-start.el (source)...

In end of data:
ghelp-builtin.el:435:1: Warning: the following functions are not known to be
    defined: help--symbol-completion-table,
    help-fns-function-description-header, help-fns--analyze-function,
    help-fns--key-bindings, help-fns--signature, help-fns--ensure-empty-line,
    help-fns-short-filename, cl--describe-class

In toplevel form:
ghelp-geiser.el:15:1: Error: Cannot open load file: No such file or directory, geiser-doc

In end of data:
ghelp-helpful.el:98:1: Warning: the following functions are not known to be
    defined: ghelp-get-page-data, ghelp-describe-1, ghelp-refresh

In end of data:
ghelp-test.el:56:1: Warning: the following functions are not known to be
    defined: ghelp-history--goto, ghelp-history-point, ghelp-history--find,
    ghelp-history--find-and-move, ghelp-history--forward, ghelp-history--back

In end of data:
ghelp.el:1192:1: Warning: the function ‘ghelp-geiser-backend’ is not known to
    be defined.
(1.34s) [1]

There is no ghelp buffer in list-buffers

Hi. If I run this:
M-x ghelp-describe-function RET setq
I get a *ghelp emacs-lisp-mode : setq* buffer.
If then I close this buffer with q it wanishes, it can't be found with list-buffers.

Is there a way that the *ghelp emacs-lisp-mode :...* buffer shows in list-buffers or switch-to-buffer prompt and if there isn't a way can you add it.
It would be great if for every different mode in ghelp-history-alist we got a separate ghelp buffer,
i.e. if in ghelp-history-alist there are histories for js-mode, go-mode and emacs-lisp-mode we got *ghelp js-mode...*, *ghelp go-mode...* and *ghelp emacs-lisp-mode...* buffers.

Ghelp breaks compatibility with default describe-* behaviour

For example ghelp-describe-variable/ghelp-describe-function doesn't receive any argument at all, so I can't integrate that to ivy/counsel like helpful allows me to do. Emacs default describe-key/function/variables receives an arguments as well.

(setq counsel-describe-function-function #'helpful-callable
      counsel-describe-variable-function #'helpful-variable)

I suppose that ghelp alternatives should receive an [optional] argument.

Run run-mode-hooks

ghelp should provide a ghelp-mode-hook.

This can be achieved with run-mode-hooks (docs).

My use case is that I want to turn on visual-line-mode for ghelp buffers, but not other buffers. I'm not sure if the ghelp-mode-hook is the best place for it, but it's the first place I tried, and I was surprised that there was no such hook.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.