You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

309 lines
9.2 KiB

[![Build Status](https://travis-ci.org/abo-abo/hydra.svg?branch=master)](https://travis-ci.org/abo-abo/hydra)
This is a package for GNU Emacs that can be used to tie related
commands into a family of short bindings with a common prefix - a
Hydra.
![hydra](http://oremacs.com/download/Hydra.png)
Once you summon the Hydra through the prefixed binding (the body + any
one head), all heads can be called in succession with only a short
extension.
The Hydra is vanquished once Hercules, any binding that isn't the
Hydra's head, arrives. Note that Hercules, besides vanquishing the
Hydra, will still serve his orignal purpose, calling his proper
command. This makes the Hydra very seamless, it's like a minor mode
that disables itself auto-magically.
## Sample global Hydras
### Zoom
```cl
(defhydra hydra-zoom (global-map "<f2>")
"zoom"
("g" text-scale-increase "in")
("l" text-scale-decrease "out"))
```
### Goto-error
```cl
(defhydra hydra-error (global-map "M-g")
"goto-error"
("h" first-error "first")
("j" next-error "next")
("k" previous-error "prev")
("v" recenter-top-bottom "recenter")
("q" nil "quit"))
```
### Splitter
```cl
(require 'hydra-examples)
(defhydra hydra-splitter (global-map "C-M-s")
"splitter"
("h" hydra-move-splitter-left)
("j" hydra-move-splitter-down)
("k" hydra-move-splitter-up)
("l" hydra-move-splitter-right))
```
### Community wiki
A few useful hydras are aggregated in projects [community wiki](https://github.com/abo-abo/hydra/wiki/Hydras%20by%20Topic). Feel free to add your own or edit existing ones.
## Using the functions generated by `defhydra`
With the example above, you can e.g.:
```cl
(key-chord-define-global "tt" 'hydra-zoom/body)
```
In fact, since `defhydra` returns the body symbol, you can even write
it like this:
```cl
(key-chord-define-global
"tt"
(defhydra hydra-zoom (global-map "<f2>")
"zoom"
("g" text-scale-increase "in")
("l" text-scale-decrease "out")))
```
If you like key chords so much that you don't want to touch the global
map at all, you can e.g.:
```
(key-chord-define-global
"hh"
(defhydra hydra-error ()
"goto-error"
("h" first-error "first")
("j" next-error "next")
("k" previous-error "prev")))
```
You can also substitute `global-map` with any other keymap, like
`c++-mode-map` or `yas-minor-mode-map`.
See the [introductory blog post](http://oremacs.com/2015/01/20/introducing-hydra/) for more information.
## Using Hydra for major-mode or minor-mode bindings
Here's an example:
```cl
(defhydra lispy-vi (lispy-mode-map "C-z")
"vi"
("l" forward-char)
("h" backward-char)
("j" next-line)
("k" previous-line))
```
## Can Hydras can be helpful?
They can, if
```cl
(setq hydra-is-helpful t)
```
This is the default setting. In this case, you'll get a hint in the
echo area consisting of current Hydra's base comment and heads. You
can even add comments to the heads like this:
```
(defhydra hydra-zoom (global-map "<f2>")
"zoom"
("g" text-scale-increase "in")
("l" text-scale-decrease "out"))
```
With this, you'll see `zoom: [g]: in, [l]: out.` in your echo area,
once the zoom Hydra becomes active.
## Colorful Hydras
Since version `0.5.0`, Hydra's heads all have a color associated with them:
- *red* (default) means the calling this head will not vanquish the Hydra
- *blue* means that the Hydra will be vanquished after calling this head
In all the older examples, all heads are red by default. You can specify blue heads like this:
```cl
(global-set-key
(kbd "C-c C-v")
(defhydra toggle ()
"toggle"
("a" abbrev-mode "abbrev" :color blue)
("d" toggle-debug-on-error "debug" :color blue)
("f" auto-fill-mode "fill" :color blue)
("t" toggle-truncate-lines "truncate" :color blue)
("w" whitespace-mode "whitespace" :color blue)
("q" nil "cancel")))
```
Or, since the heads can inherit the color from the body, the following is equivalent:
```cl
(global-set-key
(kbd "C-c C-v")
(defhydra toggle (:color blue)
"toggle"
("a" abbrev-mode "abbrev")
("d" toggle-debug-on-error "debug")
("f" auto-fill-mode "fill")
("t" toggle-truncate-lines "truncate")
("w" whitespace-mode "whitespace")
("q" nil "cancel")))
```
The above Hydra is very similar to this code:
```cl
(global-set-key (kbd "C-c C-v t") 'toggle-truncate-lines)
(global-set-key (kbd "C-c C-v f") 'auto-fill-mode)
(global-set-key (kbd "C-c C-v a") 'abbrev-mode)
```
However, there are two important differences:
- you get a hint like this right after <kbd>C-c C-v</kbd>:
toggle: [t]: truncate, [f]: fill, [a]: abbrev, [q]: cancel.
- you can cancel <kbd>C-c C-v</kbd> with a command while executing that command, instead of e.g.
getting an error `C-c C-v C-n is undefined` for <kbd>C-c C-v C-n</kbd>.
## Hydras and numeric arguments
Since version `0.6.0`, for any Hydra:
- `digit-argment` can be called with <kbd>0</kbd>-<kbd>9</kbd>.
- `negative-argument` can be called with <kbd>-</kbd>
- `universal-argument` can be called with <kbd>C-u</kbd>
## Hydras can have `:pre` and `:post` statements
Since version `0.7.0`, you can specify code that will be called before each head, and
after the body. For example:
```cl
(global-set-key
(kbd "C-z")
(defhydra hydra-vi
(:pre
(set-cursor-color "#40e0d0")
:post
(progn
(set-cursor-color "#ffffff")
(message
"Thank you, come again.")))
"vi"
("l" forward-char)
("h" backward-char)
("j" next-line)
("k" previous-line)
("q" nil "quit")))
```
## New Hydra color: amaranth
Since version `0.8.0`, a new color - amaranth, in addition to the previous red and blue, is
available for the Hydra body.
According to [Wikipedia](http://en.wikipedia.org/wiki/Amaranth):
> The word amaranth comes from the Greek word amaranton, meaning "unwilting" (from the
> verb marainesthai, meaning "wilt"). The word was applied to amaranth because it did not
> soon fade and so symbolized immortality.
Hydras with amaranth body are impossible to quit with any binding *except* a blue head.
A check for at least one blue head exists in `defhydra`, so that you don't get stuck by accident.
Here's an example of an amaranth Hydra:
```cl
(global-set-key
(kbd "C-z")
(defhydra hydra-vi
(:pre
(set-cursor-color "#40e0d0")
:post
(set-cursor-color "#ffffff")
:color amaranth)
"vi"
("l" forward-char)
("h" backward-char)
("j" next-line)
("k" previous-line)
("q" nil "quit")))
```
The only way to exit it, is to press <kbd>q</kbd>. No other methods will work. You can
use an amaranth Hydra instead of a red one, if for you the cost of being able to exit only
though certain bindings is less than the cost of accidentally exiting a red Hydra by
pressing the wrong prefix.
Note that it does not make sense to define a single amaranth head, so this color can only
be assigned to the body. An amaranth body will always have some amaranth heads and some
blue heads (otherwise, it's impossible to exit), no reds.
## Generate simple lambdas in-place:
Since version `0.9.0` it's possible to pass a single sexp instead of a function name or a lambda
to a head. This sexp will be wrapped in an interactive lambda. Here's an example:
```cl
(defhydra hydra-launcher (:color blue)
"Launch"
("h" man "man")
("r" (browse-url "http://www.reddit.com/r/emacs/") "reddit")
("w" (browse-url "http://www.emacswiki.org/") "emacswiki")
("s" shell "shell")
("q" nil "cancel"))
(global-set-key (kbd "C-c r") 'hydra-launcher/body)
```
## Define Hydra heads that don't show up in the hint at all
This can be done by setting the head's hint explicitly to `nil`, instead of the usual string.
## Use a dedicated window for Hydra hints
Since version `0.10.0`, setting `hydra-lv` to `t` (the default setting) will make it use a dedicated
window right above the Echo Area for hints. This has the advantage that you can immediately see
any `message` output from the functions that you call, since Hydra no longer uses `message` to display
the hint. You can still have the old behavior by setting `hydra-lv` to `nil`.
## Color table
| Body Color | Head Inherited | Executing NON-HEADS | Executing HEADS |
|------------+----------------+-----------------------+-----------------|
| amaranth | red | Disallow and Continue | Continue |
| teal | blue | Disallow and Continue | Quit |
| pink | red | Allow and Continue | Continue |
| red | red | Allow and Quit | Continue |
| blue | blue | Allow and Quit | Quit |
## Color to toggle correspondence
By popular demand, an alternative syntax has been implemented that translates to colors without
using them in the syntax. `:exit` can be used both in body (heads will inherit) and in heads
(possible to override body). `:exit` is nil by default, corresponding to `red` head; you don't need
to set it explicitly to nil. `:nonheads` can be used only in body and can be either nil (default),
`warn` or `run`.
| color | toggle |
|----------+------------------------|
| red | |
| blue | :exit t |
| amaranth | :nonheads warn |
| teal | :nonheads warn :exit t |
| pink | :nonheads run |