]> code.delx.au - gnu-emacs-elpa/blob - packages/hydra/README.md
Merge commit '0cda39255827f283e7578cd469ae42daad9556a2' from js2-mode
[gnu-emacs-elpa] / packages / hydra / README.md
1 [![Build Status](https://travis-ci.org/abo-abo/hydra.svg?branch=master)](https://travis-ci.org/abo-abo/hydra)
2
3 This is a package for GNU Emacs that can be used to tie related commands into a family of short
4 bindings with a common prefix - a Hydra.
5
6 ![hydra](http://oremacs.com/download/Hydra.jpg)
7
8 ## Description for Poets
9
10 Once you summon the Hydra through the prefixed binding (the body + any one head), all heads can be
11 called in succession with only a short extension.
12
13 The Hydra is vanquished once Hercules, any binding that isn't the Hydra's head, arrives. Note that
14 Hercules, besides vanquishing the Hydra, will still serve his original purpose, calling his proper
15 command. This makes the Hydra very seamless, it's like a minor mode that disables itself
16 auto-magically.
17
18 ## Description for Pragmatics
19
20 Imagine that you have bound <kbd>C-c j</kbd> and <kbd>C-c k</kbd> in your
21 config. You want to call <kbd>C-c j</kbd> and <kbd>C-c k</kbd> in some
22 (arbitrary) sequence. Hydra allows you to:
23
24 - Bind your functions in a way that pressing <kbd>C-c jjkk3j5k</kbd> is
25 equivalent to pressing <kbd>C-c j C-c j C-c k C-c k M-3 C-c j M-5 C-c
26 k</kbd>. Any key other than <kbd>j</kbd> or <kbd>k</kbd> exits this state.
27
28 - Assign a custom hint to this group of functions, so that you know immediately
29 after pressing <kbd>C-c</kbd> that you can follow up with <kbd>j</kbd> or
30 <kbd>k</kbd>.
31
32 If you want to quickly understand the concept, see [the video demo](https://www.youtube.com/watch?v=_qZliI1BKzI).
33
34 <!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc/generate-toc again -->
35 **Table of Contents**
36
37 - [Sample Hydras](#sample-hydras)
38 - [The one with the least amount of code](#the-one-with-the-least-amount-of-code)
39 - [The impressive-looking one](#the-impressive-looking-one)
40 - [Community wiki](#community-wiki)
41 - [The Rules of Hydra-tics](#the-rules-of-hydra-tics)
42 - [`hydra-awesome`](#hydra-awesome)
43 - [`awesome-map` and `awesome-binding`](#awesome-map-and-awesome-binding)
44 - [`awesome-plist`](#awesome-plist)
45 - [`:pre` and `:post`](#pre-and-post)
46 - [`:exit`](#exit)
47 - [`:foreign-keys`](#foreign-keys)
48 - [`:color`](#color)
49 - [`:timeout`](#timeout)
50 - [`:hint`](#hint)
51 - [`:bind`](#bind)
52 - [`awesome-docstring`](#awesome-docstring)
53 - [`awesome-head-1`](#awesome-head-1)
54 - [`head-binding`](#head-binding)
55 - [`head-command`](#head-command)
56 - [`head-hint`](#head-hint)
57 - [`head-plist`](#head-plist)
58
59 <!-- markdown-toc end -->
60
61 # Sample Hydras
62
63 ## The one with the least amount of code
64
65 ```cl
66 (defhydra hydra-zoom (global-map "<f2>")
67 "zoom"
68 ("g" text-scale-increase "in")
69 ("l" text-scale-decrease "out"))
70 ```
71
72 With this simple code, you can:
73
74 - Start zooming in with <kbd>&lt;f2&gt; g</kbd>.
75 - Continue to zoom in with <kbd>g</kbd>.
76 - Or zoom out with <kbd>l</kbd>.
77 - Zoom in five times at once with <kbd>5g</kbd>.
78 - Stop zooming with *any* key that isn't <kbd>g</kbd> or <kbd>l</kbd>.
79
80 For any Hydra:
81
82 - `digit-argument` can be called with <kbd>0</kbd>-<kbd>9</kbd>.
83 - `negative-argument` can be called with <kbd>-</kbd>.
84 - `universal-argument` can be called with <kbd>C-u</kbd>.
85
86 ## The impressive-looking one
87
88 Here's the result of pressing <kbd>.</kbd> in the good-old Buffer menu:
89
90 ![hydra-buffer-menu](http://oremacs.com/download/hydra-buffer-menu.png)
91
92 The code is large but very simple:
93
94 ```cl
95 (defhydra hydra-buffer-menu (:color pink
96 :hint nil)
97 "
98 ^Mark^ ^Unmark^ ^Actions^ ^Search
99 ^^^^^^^^-----------------------------------------------------------------
100 _m_: mark _u_: unmark _x_: execute _R_: re-isearch
101 _s_: save _U_: unmark up _b_: bury _I_: isearch
102 _d_: delete ^ ^ _g_: refresh _O_: multi-occur
103 _D_: delete up ^ ^ _T_: files only: % -28`Buffer-menu-files-only
104 _~_: modified
105 "
106 ("m" Buffer-menu-mark)
107 ("u" Buffer-menu-unmark)
108 ("U" Buffer-menu-backup-unmark)
109 ("d" Buffer-menu-delete)
110 ("D" Buffer-menu-delete-backwards)
111 ("s" Buffer-menu-save)
112 ("~" Buffer-menu-not-modified)
113 ("x" Buffer-menu-execute)
114 ("b" Buffer-menu-bury)
115 ("g" revert-buffer)
116 ("T" Buffer-menu-toggle-files-only)
117 ("O" Buffer-menu-multi-occur :color blue)
118 ("I" Buffer-menu-isearch-buffers :color blue)
119 ("R" Buffer-menu-isearch-buffers-regexp :color blue)
120 ("c" nil "cancel")
121 ("v" Buffer-menu-select "select" :color blue)
122 ("o" Buffer-menu-other-window "other-window" :color blue)
123 ("q" quit-window "quit" :color blue))
124
125 (define-key Buffer-menu-mode-map "." 'hydra-buffer-menu/body)
126 ```
127
128 Looking at the code, you can see `hydra-buffer-menu` as sort of a namespace construct that wraps
129 each function that it's given in code that shows that hint and makes it easy to call the related
130 functions. One additional function is created and returned as the result of `defhydra` -
131 `hydra-buffer-menu/body`. This function does nothing except setting up the hint and the keymap, and
132 is usually the entry point to complex hydras.
133
134 To write your own hydras, you can:
135
136 - Either modify an existing hydra to do what you want to do.
137 - Or read [the rules](#the-rules-of-hydra-tics),
138 [the examples](https://github.com/abo-abo/hydra/blob/master/hydra-examples.el),
139 the docstrings and comments in the source.
140
141 # Community wiki
142
143 You can find some user created hydras and more documentation in the project's
144 [community wiki](https://github.com/abo-abo/hydra/wiki/). Feel free to add your
145 own or edit the existing ones.
146
147 # The Rules of Hydra-tics
148
149 Each hydra (take `awesome` as a prefix to make it more specific) looks like this:
150
151 ```
152 (defhydra hydra-awesome (awesome-map awesome-binding awesome-plist)
153 awesome-docstring
154 awesome-head-1
155 awesome-head-2
156 awesome-head-3
157 ...)
158 ```
159
160 ## `hydra-awesome`
161
162 Each hydra needs a name, and this one is named `hydra-awesome`. You can name your hydras as you wish,
163 but I prefer to start each one with `hydra-`, because it acts as an additional namespace layer, for example:
164 `hydra-zoom`, `hydra-helm`, `hydra-apropos` etc.
165
166 If you name your hydra `hydra-awesome`, the return result of `defhydra` will be `hydra-awesome/body`.
167
168 Here's what `hydra-zoom/body` looks like, if you're interested:
169
170 ```cl
171 (defun hydra-zoom/body nil
172 "Create a hydra with a \"<f2>\" body and the heads:
173
174 \"g\": `text-scale-increase',
175 \"l\": `text-scale-decrease'
176
177 The body can be accessed via `hydra-zoom/body'."
178 (interactive)
179 (hydra-default-pre)
180 (when hydra-is-helpful
181 (if hydra-lv
182 (lv-message
183 (eval hydra-zoom/hint))
184 (message
185 (eval hydra-zoom/hint))))
186 (hydra-set-transient-map
187 hydra-zoom/keymap
188 (lambda nil
189 (hydra-keyboard-quit)
190 nil)
191 nil)
192 (setq prefix-arg
193 current-prefix-arg))
194 ```
195
196 ## `awesome-map` and `awesome-binding`
197
198 This can be any keymap, for instance, `global-map` or `isearch-mode-map`.
199
200 For this example:
201
202 ```cl
203 (defhydra hydra-zoom (global-map "<f2>")
204 "zoom"
205 ("g" text-scale-increase "in")
206 ("l" text-scale-decrease "out"))
207 ```
208
209 - `awesome-map` is `global-map`
210 - `awesome-binding` is `"<f2>"`
211
212 And here's the relevant generated code:
213
214 ```cl
215 (unless (keymapp (lookup-key global-map (kbd "<f2>")))
216 (define-key global-map (kbd "<f2>") nil))
217 (define-key global-map [f2 103]
218 (function hydra-zoom/text-scale-increase))
219 (define-key global-map [f2 108]
220 (function hydra-zoom/text-scale-decrease))
221 ```
222
223 As you see, `"<f2>"` is used as a prefix for <kbd>g</kbd> (char value 103) and <kbd>l</kbd>
224 (char value 108).
225
226 If you don't want to use a map right now, you can skip it like this:
227
228 ```cl
229 (defhydra hydra-zoom (nil nil)
230 "zoom"
231 ("g" text-scale-increase "in")
232 ("l" text-scale-decrease "out"))
233 ```
234
235 Or even simpler:
236
237 ```cl
238 (defhydra hydra-zoom ()
239 "zoom"
240 ("g" text-scale-increase "in")
241 ("l" text-scale-decrease "out"))
242 ```
243
244 But then you would have to bind `hydra-zoom/text-scale-increase` and
245 `hydra-zoom/text-scale-decrease` yourself.
246
247 ## `awesome-plist`
248
249 You can read up on what a plist is in
250 [the Elisp manual](https://www.gnu.org/software/emacs/manual/html_node/elisp/Property-Lists.html).
251
252 You can use `awesome-plist` to modify the behavior of each head in some way.
253 Below is a list of each key.
254
255 ### `:pre` and `:post`
256
257 You can specify code that will be called before each head, and after the body. For example:
258
259 ```cl
260 (defhydra hydra-vi (:pre (set-cursor-color "#40e0d0")
261 :post (progn
262 (set-cursor-color "#ffffff")
263 (message
264 "Thank you, come again.")))
265 "vi"
266 ("l" forward-char)
267 ("h" backward-char)
268 ("j" next-line)
269 ("k" previous-line)
270 ("q" nil "quit"))
271 ```
272
273 Thanks to `:pre`, each time any head is called, the cursor color is changed.
274 And when the hydra quits, the cursor color will be made black again with `:post`.
275
276 ### `:exit`
277
278 The `:exit` key is inherited by every head (they can override it) and influences what will happen
279 after executing head's command:
280
281 - `:exit nil` (the default) means that the hydra state will continue - you'll still see the hint and be able to use short bindings.
282 - `:exit t` means that the hydra state will stop.
283
284 ### `:foreign-keys`
285
286 The `:foreign-keys` key belongs to the body and decides what to do when a key is pressed that doesn't
287 belong to any head:
288
289 - `:foreign-keys nil` (the default) means that the hydra state will stop and the foreign key will
290 do whatever it was supposed to do if there was no hydra state.
291 - `:foreign-keys warn` will not stop the hydra state, but instead will issue a warning without
292 running the foreign key.
293 - `:foreign-keys run` will not stop the hydra state, and try to run the foreign key.
294
295 ### `:color`
296
297 The `:color` key is a shortcut. It aggregates `:exit` and `:foreign-keys` key in the following way:
298
299 | color | toggle |
300 |----------+----------------------------|
301 | red | |
302 | blue | :exit t |
303 | amaranth | :foreign-keys warn |
304 | teal | :foreign-keys warn :exit t |
305 | pink | :foreign-keys run |
306
307 It's also a trick to make you instantly aware of the current hydra keys that you're about to press:
308 the keys will be highlighted with the appropriate color.
309
310 ### `:timeout`
311
312 The `:timeout` key starts a timer for the corresponding amount of seconds that disables the hydra.
313 Calling any head will refresh the timer.
314
315 ### `:hint`
316
317 The `:hint` key will be inherited by each head. Each head is allowed to override it, of course.
318 One value that makes sense is `:hint nil`. See below for an explanation of head hint.
319
320 ### `:bind`
321
322 The `:bind` key provides a lambda to be used to bind each head. This is quite advanced and rarely
323 used, you're not likely to need it. But if you would like to bind your heads with e.g. `bind-key`
324 instead of `define-key` you can use this option.
325
326 The `:bind` key can be overridden by each head. This is useful if you want to have a few heads that
327 are not bound outside the hydra.
328
329 ## `awesome-docstring`
330
331 This can be a simple string used to build the final hydra hint. However, if you start it with a
332 newline, the key-highlighting and Ruby-style string interpolation becomes enabled, as you can see in
333 `hydra-buffer-menu` above.
334
335 To highlight a key, just wrap it in underscores. Note that the key must belong to one of the heads.
336 The key will be highlighted with the color that is appropriate to the behavior of the key, i.e. if
337 the key will make the hydra exit, the color will be blue.
338
339 To insert an empty character, use `^`. The only use of this is to have your code aligned as
340 nicely as the result.
341
342 To insert a dynamic Elisp variable, use `%`&#96; followed by the variable. Each time the variable
343 changes due to a head, the docstring will be updated. `format`-style width specifiers can be used.
344
345 To insert a dynamic Elisp expression, use e.g. `%(length (dired-get-marked-files))`. If a head will
346 change the amount of marked files, for example, it will be appropriately updated.
347
348 If the result of the Elisp expression is a string and you don't want to quote it, use this form:
349 `%s(shell-command-to-string "du -hs")`.
350
351 ## `awesome-head-1`
352
353 Each head looks like this:
354
355 ```cl
356 (head-binding head-command head-hint head-plist)
357 ```
358
359 For the head `("g" text-scale-increase "in")`:
360
361 - `head-binding` is `"g"`.
362 - `head-command` is `text-scale-increase`.
363 - `head-hint` is `"in"`.
364 - `head-plist` is `nil`.
365
366 ### `head-binding`
367
368 The `head-binding` is a string that can be passed to `kbd`.
369
370 ### `head-command`
371
372 The `head-command` can be:
373
374 - command name, like `text-scale-increase`.
375 - a lambda, like
376
377 ("g" (lambda ()
378 (interactive)
379 (let ((current-prefix-arg 4))
380 (call-interactively #'magit-status)))
381 "git")
382
383 - nil, which exits the hydra.
384 - a single sexp, which will be wrapped in an interactive lambda.
385
386 Here's an example of the last option:
387
388 ```cl
389 (defhydra hydra-launcher (:color blue)
390 "Launch"
391 ("h" man "man")
392 ("r" (browse-url "http://www.reddit.com/r/emacs/") "reddit")
393 ("w" (browse-url "http://www.emacswiki.org/") "emacswiki")
394 ("s" shell "shell")
395 ("q" nil "cancel"))
396 (global-set-key (kbd "C-c r") 'hydra-launcher/body)
397 ```
398
399 ### `head-hint`
400
401 In case of a large body docstring, you usually don't want the head hint to show up, since
402 you've already documented it the the body docstring.
403 You can set the head hint to `nil` to do this.
404
405 Example:
406
407 ```cl
408 (defhydra hydra-zoom (global-map "<f2>")
409 "
410 Press _g_ to zoom in.
411 "
412 ("g" text-scale-increase nil)
413 ("l" text-scale-decrease "out"))
414 ```
415
416 ### `head-plist`
417
418 Here's a list of body keys that can be overridden in each head:
419
420 - `:exit`
421 - `:color`
422 - `:bind`