branch: master
commit 622c798a7efd52ed873c60d80b97c1b5e0366885
Author: Oleh Krehel <ohwoeo...@gmail.com>
Commit: Oleh Krehel <ohwoeo...@gmail.com>

    README.md: move some stuff to wiki, add more stuff
---
 README.md |  349 +++++++++++++++++++++++++++----------------------------------
 1 files changed, 155 insertions(+), 194 deletions(-)

diff --git a/README.md b/README.md
index e0441a0..47ed9cc 100644
--- a/README.md
+++ b/README.md
@@ -32,6 +32,12 @@ With this simple code, you can:
 - Zoom in five times at once with <kbd>5g</kbd>.
 - Stop zooming with *any* key that isn't <kbd>g</kbd> or <kbd>l</kbd>.
 
+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>.
+
 ### The impressive-looking one
 
 Here's the result of pressing <kbd>.</kbd> in the good-old Buffer menu:
@@ -45,12 +51,12 @@ The code is large but very simple:
                              :hint nil)
   "
 ^Mark^             ^Unmark^           ^Actions^          ^Search
-^^^^^^^^-----------------------------------------------------------------      
                  (__)
-_m_: mark          _u_: unmark        _x_: execute       _R_: re-isearch       
                  (oo)
-_s_: save          _U_: unmark up     _b_: bury          _I_: isearch          
            /------\\/
-_d_: delete        ^ ^                _g_: refresh       _O_: multi-occur      
           / |    ||
-_D_: delete up     ^ ^                _T_: files only: % 
-28`Buffer-menu-files-only^^    *  /\\---/\\
-_~_: modified      ^ ^                ^ ^                ^^                    
             ~~   ~~
+^^^^^^^^-----------------------------------------------------------------
+_m_: mark          _u_: unmark        _x_: execute       _R_: re-isearch
+_s_: save          _U_: unmark up     _b_: bury          _I_: isearch
+_d_: delete        ^ ^                _g_: refresh       _O_: multi-occur
+_D_: delete up     ^ ^                _T_: files only: % 
-28`Buffer-menu-files-only
+_~_: modified
 "
   ("m" Buffer-menu-mark)
   ("u" Buffer-menu-unmark)
@@ -74,8 +80,8 @@ _~_: modified      ^ ^                ^ ^                ^^
 (define-key Buffer-menu-mode-map "." 'hydra-buffer-menu/body)
 ```
 
-Looking at the code you can see `hydra-buffer-menu` as sort of a namespace 
construct that wraps each
-function that it's given in code that shows that hint and makes it easy to 
call the related
+Looking at the code, you can see `hydra-buffer-menu` as sort of a namespace 
construct that wraps
+each function that it's given in code that shows that hint and makes it easy 
to call the related
 functions. One additional function is created and returned as the result of 
`defhydra` -
 `hydra-buffer-menu/body`.  This function does nothing except setting up the 
hint and the keymap, and
 is usually the entry point to complex hydras.
@@ -91,211 +97,187 @@ A good amount of 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 the existing ones.
 
-## Using the functions generated by `defhydra`
+## The Rules Hydra-tics
 
-With the example above, you can e.g.:
+Each hydra (take `awesome` as a prefix to make it more specific) looks like 
this:
 
-```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")))
+(defhydra hydra-awesome (awesome-map awesome-binding awesome-plist)
+  awesome-docstring
+  awesome-head-1
+  awesome-head-2
+  awesome-head-3
+  ...)
 ```
 
-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")))
-```
+### `hydra-awesome`
 
-You can also substitute `global-map` with any other keymap, like
-`c++-mode-map` or `yas-minor-mode-map`.
+Each hydra needs a name, and this one is named `hydra-awesome`. You can name 
your hydras as you wish,
+but I prefer to start each one with `hydra-`, because it acts as an additional 
namespace layer, for example:
+`hydra-zoom`, `hydra-helm`, `hydra-apropos` etc.
 
-See the [introductory blog 
post](http://oremacs.com/2015/01/20/introducing-hydra/) for more information.
+If you name your hydra `hydra-awesome`, the return result of `defhydra` will 
be `hydra-awesome/body`.
 
-## Using Hydra for major-mode or minor-mode bindings
-
-Here's an example:
+Here's what `hydra-zoom/body` looks like, if you're interested:
 
 ```cl
-(defhydra lispy-vi (lispy-mode-map "C-z")
-  "vi"
-  ("l" forward-char)
-  ("h" backward-char)
-  ("j" next-line)
-  ("k" previous-line))
+(defun hydra-zoom/body nil
+  "Create a hydra with a \"<f2>\" body and the heads:
+
+\"g\":    `text-scale-increase',
+\"l\":    `text-scale-decrease'
+
+The body can be accessed via `hydra-zoom/body'."
+  (interactive)
+  (hydra-disable)
+  (catch (quote hydra-disable)
+    (when hydra-is-helpful (hydra-zoom/hint))
+    (setq hydra-last
+          (hydra-set-transient-map
+           (setq hydra-curr-map
+                 (quote
+                  (keymap (7 . hydra-keyboard-quit)
+                          (108 . hydra-zoom/text-scale-decrease)
+                          (103 . hydra-zoom/text-scale-increase)
+                          (kp-subtract . hydra--negative-argument)
+                          (kp-9 . hydra--digit-argument)
+                          (kp-8 . hydra--digit-argument)
+                          (kp-7 . hydra--digit-argument)
+                          (kp-6 . hydra--digit-argument)
+                          (kp-5 . hydra--digit-argument)
+                          (kp-4 . hydra--digit-argument)
+                          (kp-3 . hydra--digit-argument)
+                          (kp-2 . hydra--digit-argument)
+                          (kp-1 . hydra--digit-argument)
+                          (kp-0 . hydra--digit-argument)
+                          (57 . hydra--digit-argument)
+                          (56 . hydra--digit-argument)
+                          (55 . hydra--digit-argument)
+                          (54 . hydra--digit-argument)
+                          (53 . hydra--digit-argument)
+                          (52 . hydra--digit-argument)
+                          (51 . hydra--digit-argument)
+                          (50 . hydra--digit-argument)
+                          (49 . hydra--digit-argument)
+                          (48 . hydra--digit-argument)
+                          (45 . hydra--negative-argument)
+                          (21 . hydra--universal-argument))))
+           t (lambda nil (hydra-cleanup))))
+    (setq prefix-arg current-prefix-arg)))
 ```
 
-## Can Hydras can be helpful?
+### `awesome-map` and `awesome-binding`
 
-They can, if
+This can be any keymap, for instance, `global-map` or `isearch-mode-map`.
 
-```cl
-(setq hydra-is-helpful t)
-```
+For this example:
 
-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:
-
-```
+```cl
 (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.
+- `awesome-map` is `global-map`
+- `awesome-binding` is `"<f2>"`
 
-## 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:
+And here's the relevant generated code:
 
 ```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")))
+(unless (keymapp (lookup-key global-map (kbd "<f2>")))
+  (define-key global-map (kbd "<f2>") nil))
+(define-key global-map [f2 103]
+  (function hydra-zoom/text-scale-increase))
+(define-key global-map [f2 108]
+  (function hydra-zoom/text-scale-decrease))
 ```
 
-Or, since the heads can inherit the color from the body, the following is 
equivalent:
+As you see, `"<f2>"` is used as a prefix for <kbd>g</kbd> (char value 103) and 
<kbd>l</kbd>
+(char value 108).
+
+If you don't want to use a map right now, you can skip it like this:
 
 ```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")))
+(defhydra hydra-zoom (nil nil)
+  "zoom"
+  ("g" text-scale-increase "in")
+  ("l" text-scale-decrease "out"))
 ```
 
-The above Hydra is very similar to this code:
+Or even simpler:
 
 ```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)
+(defhydra hydra-zoom ()
+  "zoom"
+  ("g" text-scale-increase "in")
+  ("l" text-scale-decrease "out"))
 ```
 
-However, there are two important differences:
-
-- you get a hint like this right after <kbd>C-c C-v</kbd>:
+But then you would have to bind `hydra-zoom/text-scale-increase` and
+`hydra-zoom/text-scale-decrease` yourself.
 
-        toggle: [t]: truncate, [f]: fill, [a]: abbrev, [q]: cancel.
+### `awesome-plist`
 
-- 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>.
+You can read up on what a plist is in
+[the Elisp 
manual](https://www.gnu.org/software/emacs/manual/html_node/elisp/Property-Lists.html).
 
-## 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>
+You can use `awesome-plist` to modify the behavior of each head in some way.
+Below is a list of each key.
 
-## Hydras can have `:pre` and `:post` statements
+#### `:pre` and `:post`
 
-Since version `0.7.0`, you can specify code that will be called before each 
head, and
-after the body. For example:
+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")))
+(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
+Thanks to `:pre`, each time any head is called, the cursor color is changed.
+And when the hydra quits, the cursor color will be made black again with 
`:post`.
 
-Since version `0.8.0`, a new color - amaranth, in addition to the previous red 
and blue, is
-available for the Hydra body.
+### `awesome-head-1`
 
-According to [Wikipedia](http://en.wikipedia.org/wiki/Amaranth):
+Each head looks like this:
 
-> 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.
+```cl
+(head-binding head-command head-hint head-plist)
+```
 
-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.
+For a head `("g" text-scale-increase "in")`:
 
-Here's an example of an amaranth Hydra:
+- `head-binding` is `"g"`.
+- `head-command` is `text-scale-increase`.
+- `head-hint` is `"in"`.
+- `head-plist` is `nil`.
 
-```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")))
-```
+#### `head-command`
+
+The `head-command` can be:
 
-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.
+- command name, like `text-scale-increase`.
+- a lambda, like
 
-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.
+        ("g" (lambda ()
+               (interactive)
+               (let ((current-prefix-arg 4))
+                 (call-interactively #'magit-status)))
+             "git")
 
-## Generate simple lambdas in-place:
+- nil, which exits the hydra.
+- a single sexp, which will be wrapped in an interactive lambda.
 
-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:
+Here's an example of the last option:
 
 ```cl
 (defhydra hydra-launcher (:color blue)
@@ -308,40 +290,19 @@ to a head. This sexp will be wrapped in an interactive 
lambda. Here's an example
 (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
-
+#### `head-hint`
 
-    | 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            |
+In case of a large body docstring, you usually don't want the head hint to 
show up, since
+you've already documented it the the body docstring.
+You can set the head hint to `nil` to do this.
 
-## Color to toggle correspondence
+Example:
 
-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.  `:foreign-keys` can be used only in body and can 
be either nil (default),
-`warn` or `run`.
-
-    | color    | toggle                     |
-    |----------+----------------------------|
-    | red      |                            |
-    | blue     | :exit t                    |
-    | amaranth | :foreign-keys warn         |
-    | teal     | :foreign-keys warn :exit t |
-    | pink     | :foreign-keys run          |
+```cl
+(defhydra hydra-zoom (global-map "<f2>")
+  "
+Press _g_ to zoom in.
+"
+  ("g" text-scale-increase nil)
+  ("l" text-scale-decrease "out"))
+```

Reply via email to