* hydra.el (hydra-keyboard-quit): New custom var.
(defhydra): Bind `hydra-keyboard-quit' to disable an amaranth Hydra.
* hydra-test.el (hydra-amaranth-vi): Update test.
* hydra.el (defhydra): Since the transient map isn't technically going
away when a foreign key binding is pressed, don't call :post in that
case. This means that only blue heads will call :post for Hydras with
amaranth body.
Fixes#17.
* hydra.el (hydra-face-amaranth): New face.
(hydra--face): Update.
(defhydra): If the body color is amaranth, it's only possible to exit
this Hydra through a blue head. None of the other key bindings, even
"C-g" will work. There's a check in place that the current Hydra should
have at least one blue head.
Re #17.
Example:
(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"))
(global-set-key (kbd "C-z") 'hydra-vi/body)
* hydra.el (defhydra): the PLIST part of BODY argument now recognizes
:pre and :post keys. These should be single Elisp statements,
wrappable in a lambda. When you need more than one statement, use a
`progn'.
:pre will be called by `hydra-foo/body', as well as by all heads.
:post will be called by the blue heads, as well as on Hydra termination
by a command that isn't a head.
Fixes#16.
An Example:
(global-set-key
(kbd "C-z")
(defhydra hydra-vi
(:pre
(set-cursor-color "#40e0d0")
:post
(set-cursor-color "#ffffff"))
"vi"
("l" forward-char)
("h" backward-char)
("j" next-line)
("k" previous-line)
("q" nil "quit")))
* hydra.el (defhydra): First disable the transient map, then call red
head, allowing it to throw `hydra-disable' to break, then re-set
transient map.
If the called function raises an error, display this error for a
while, but still set the transient map.
* hydra-test.el: Update test.
Re #15.
* hydra-examples.el (hydra-move-splitter-left): Take ARG.
(hydra-move-splitter-right): Take ARG.
(hydra-move-splitter-up): Take ARG.
(hydra-move-splitter-down): Take ARG.
* hydra.el (hydra-base-map): Model after `universal-argument-map'; all
Hydra keymaps will inherit from this one.
(hydra-curr-map): Current Hydra keymap. This is necessary for
e.g. `hydra--digit-argument' to return to the orignial keymap.
(hydra--universal-argument): New function.
(hydra--digit-argument): New function.
(hydra--negative-argument): New function.
(hydra--hint): Fix dangling `body-color'.
(defhydra): keymap will inherit `hydra-base-map'.
`hydra-current-map' will be set by red heads. In red heads, make the
function call after `set-transient-map' so that e.g. "Beginning of
buffer" error will not exit the Hydra.
* hydra-test.el: Update tests.
Fixes#13.
* hydra.el (hydra-face-red): New face.
(hydra-face-blue): New face.
(hydra--color): Each head now has a color: red is persistent, blue is
single-use. Head color inherits body color if it's not explicitly
overridden. Body color is red unless explicitly stated.
(hydra--face): Return face that corresponds to color.
(hydra--hint): New function, moved out of `defhydra'.
(hydra-disable): New function, moved out of `defhydra'.
(hydra--doc): New function, moved out of `defhydra'.
(defhydra): Commands that will vanquish the Hydra should be colored with
`hydra-face-blue'. The ones that will make the Hydra persist should be
colored with `hydra-face-red'.
Add autoload, move some code outside, Test HEAD's second element with
`null' instead of `functionp'.
* hydra-test.el (defhydra-red-error): Rename from `defhydra'.
(hydra-blue-toggle): Add test.
* README.md: Update.
Example:
(global-set-key
(kbd "C-c C-v")
(defhydra toggle ()
"toggle"
("t" toggle-truncate-lines "truncate" :color blue)
("f" auto-fill-mode "fill" :color blue)
("a" abbrev-mode "abbrev" :color blue)
("q" nil "cancel")))
Alternatively, since heads inherit color from the body:
(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")))
* hydra.el (hydra--callablep): New function.
(hydra-create): Write down in terms of `defhydra'.
(defhydra): New macro.
`defhydra' uses more parameters than `hydra-create' and looks more like
a `defun':
(defhydra hydra-windmove (global-map "C-M-o")
"windmove"
("h" windmove-left)
("j" windmove-down)
("k" windmove-up)
("l" windmove-right)
("o"))
(defhydra hydra-zoom (global-map "<f2>")
"zoom"
("g" text-scale-increase "in")
("l" text-scale-decrease "out"))
(defhydra lispy-knight ()
"knight"
("j" lispy-knight-down)
("k" lispy-knight-up)
("z"))
Important advantages:
- Hydra body can be omitted. If you do this, you can bind the functions
that `defhydra' produced (in the example above, `lispy-knight/body')
yourself. It can be useful e.g. if you want to call these functions
conditionally.
- Each Hydra gets a nice name, like `hydra-windmove/windmove-left'
instead of the old `hydra-C-M-o-windmove-left'.
- Hydra hint (base) can now be customized.
* hydra.el (hydra-create): Update.
METHOD doesn't need to be evaled: it's either nil, a lambda, or assume
that it's a valid keymap without evaling. This will prevent eager
macroexpansion failure for this argument.
There still is a problem with eager macroexpansion failure in HEADS
argument.
Re #9
* hydra.el (hydra-create): Update.
Basically the same fix as before, only for bindings relating to a map.
Now this will work:
(hydra-create "C-y"
'(("l" forward-char)
("h" backward-char)
("j" next-line)
("k" previous-line)
("z"))
lispy-mode-map)
even though "C-y" is bound to a command in `lispy-mode-map'. The
previous binding will be undefined.
Re #4.
* hydra.el (hydra-create): Update.
Before, this would result in a disaster - all bindings of "C-x" would be
cleared:
(hydra-create "C-x" hydra-example-move-window-splitter)
Now this should be OK. Fixes#4.
* hydra.el (hydra-create): Update.
In order to bind hydras in `lispy', I need a way to split the body from
the heads. Now, this is possible:
(hydra-create "C-z"
'(("l" forward-char)
("h" backward-char)
("j" next-line)
("k" previous-line)
("z"))
lispy-mode-map)
(lispy-define-key lispy-mode-map "z" 'hydra-C-z-body)
* hydra.el (hydra-last): Store the lambda to disable the Hydra.
(hydra-create): Update.
Sometimes, I have nothing particualr on my mind to do, but I want to
stop the Hydra. I could just type "C-g", but it's possible to have
something more convenient. For instance:
(hydra-create "C-z"
'(("l" forward-char)
("h" backward-char)
("j" next-line)
("k" previous-line)
("z")))
* hydra.el (hydra-create): Expects a lists of lists for HEADS, instead
of list of cons cells. The optional thrid element of each list is the
hint.
* hydra-examples.el: Update the examples.
* README.md: Update.
Re #2
* hydra.el (hydra-create): Add a third optional argument. When it's not
supplied, the behavior should remain the same. Otherwise, it's a
lambda that's used instead of `global-set-key', with the same semantics.
* README.md: Update.
re #1