* lv.el (lv-wnd): New variable.
(lv-window): New defun to get a window similar in properties to Echo Area.
(lv-message): New defun, a replacement for `message', that writes to `lv-window'.
* hydra.el (hydra-lv): New defcustom. If nil, use the Echo Area,
otherwise, use LV.
(hydra-disable): Add optional arg KILL-LV.
(hydra--message): New defun to dispatch on `hydra-lv'.
(hydra--make-defun): Prematurely disable with LV only for blue heads,
since regenerating LV window would cause screen tearing. No need for
timeouts between `message' when using LV. HINT argument is now a
function symbol that returns a string, instead of a plain string.
(defhydra): Generate a new defun with name `NAME/hint'.
* Makefile: Load lv.
* hydra-test.el: Update all tests.
* README.md: Update.
* hydra.el (defhydra): With amaranth body, all heads that aren't blue
become amaranth. Specifying red explicitly does nothing. Add a check and
warn when this happens.
re #29
* hydra.el (hydra--hint): If the HINT part of HEAD is explicitely nil,
omit it from the compound hint.
Example:
(global-set-key
(kbd "C-M-o")
(defhydra hydra-window (:color amaranth)
"window"
("h" windmove-left nil)
("j" windmove-down nil)
("k" windmove-up nil)
("l" windmove-right nil)
("v" (lambda ()
(interactive)
(split-window-right)
(windmove-right))
"vert")
("x" (lambda ()
(interactive)
(split-window-below)
(windmove-down))
"horz")
("q" nil "cancel")))
Here, "h", "j", "k", "l" will not be in the echo area.
* hydra.el (hydra--make-callable): New function.
(defhydra): Use `hydra--make-callable'. Now, head's CMD is either:
command name, nil, a sexp. In case of a sexp, it will be wrapped
unevaluated in an interactive lambda. You can use a `progn' to have many
statements in the sexp.
Fixes#25.
Example:
(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)
* hydra.el (hydra--head-property): Clean up doc.
(hydra--make-defun): Clean up doc.
(defhydra): Improve doc.
Both body and heads recognize :bind property in their plist.
It can be either nil or a lambda of `global-set-key' format.
Example:
(defhydra hydra-goto (global-map "M-g"
:bind
(lambda (key cmd)
(bind-key key cmd)))
("g" goto-line "goto-line" :bind global-set-key)
("c" goto-char "goto-char"))
Here, `global-set-key' will be used to bind `goto-line' to "M-g g".
And `bind-key' will be used to bind `goto-char' to "M-g c".
Note that since `bind-key' is a macro, it was necessary to wrap it
in a lambda.
Since this commit, it's not possible to pass a lambda instead of
the whole BODY arg, as was advertised before. Just put it on
:bind now.
* hydra.el (hydra--make-defun): Take an additional arg to paste as the
last statement.
(defhydra): Set `hydra-foo/body' last statement to
`(setq prefix-arg current-prefix-arg)'.
* hydra-test.el: Update tests.
Example:
(global-set-key
(kbd "C-z")
(defhydra hydra-vi ()
"vi"
("l" forward-char)
("q" nil "quit")))
Now, "C-u C-z l" will result in (forward-char 4). All the other "l" will
normally call (forward-char 1), unless an additional prefix is given.
The previous behavior allowed only for "C-z C-u l" to get
(forward-char 4).
Fixes#21.
* hydra.el (hydra--make-defun): `(catch 'hydra-disable ...)' should
extend thoughout the whole defun. The scope was reduced by mistake
earlier, now restoring.
* hydra-test.el: Update tests.
* hydra.el (hydra--head-property): Accept an optional DEFAULT arg.
(defhydra): A head will not be bound in the body map when it has `:bind
nil' in its plist.
Example:
(defhydra hydra-next-error (c++-mode-map "C-x")
"next-error"
("`" next-error "next")
("j" next-error "next" :bind nil)
("k" previous-error "previous" :bind nil))
Here, only "C-x `" will be bound in `c++-mode-map', "C-x j" and "C-x k"
will not be bound. However, e.g. "C-x `jjk" will be possible.
* 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