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
309 lines
9.2 KiB
[](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. |
|
|
|
 |
|
|
|
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 |
|
|
|