Behold The Mighty Hydra!
20 Jan 2015I managed to spike a lot of interest for sticky key bindings in my earlier post, Zoom in/out with style. So now, I've refactored this method into a convenient library hydra.el.
The Concept
This package can be used to tie related functions 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.
An Example
This code will accomplish the task of the previous post:
(require 'hydra)
(hydra-create "<f2>"
'(("g" text-scale-increase)
("l" text-scale-decrease)))
Now, <f2> is the Hydra's body: you need to press it only once, together with one of the heads (g or l), to summon the Hydra.
Afterwards, you can call the heads in succession without the body prefix, i.e. <f2> g g g l will work. To vanquish the Hydra, just call up Hercules: any key binding that's not g or l, e.g. C-f or whatever you wanted to do.
Note that you can still assign an unrelated binding to e.g. <f2> f: the Hydra does not take over <f2>, only over <f2> l and <f2> g.
The Infrastructure
hydra-create
will create new interactive functions for you with the proper docstrings:
hydra-<f2>-text-scale-increase is an interactive Lisp function.
It is bound to <f2> g.
(hydra-<f2>-text-scale-increase)
Create a hydra with a "<f2>" body and the heads:
"g":
"l":text-scale-increase
,text-scale-decrease
.Call the head:
text-scale-increase
.
An exciting new Hydra: move window splitter
Zooming is old news, Hydra bundles a new application:
(require 'hydra-examples)
(hydra-create "C-M-o" hydra-example-move-window-splitter)
or in the expanded form (equivalent):
(hydra-create "C-M-o"
'(("h" hydra-move-splitter-left)
("j" hydra-move-splitter-down)
("k" hydra-move-splitter-up)
("l" hydra-move-splitter-right)))
This will allow you to move the window splitter, after you issue C-x 2 or C-x 3 one or more times, with e.g. C-M-o h h j k j l k l h. You can, of course, customize both the body and the heads of this Hydra to your preferences.
The docstrings for this Hydra look more impressive, too:
hydra-C-M-o-move-splitter-up is an interactive Lisp function.
It is bound to C-M-o k.
(hydra-C-M-o-move-splitter-up)
Create a hydra with a "C-M-o" body and the heads:
"h":
"j":hydra-move-splitter-left
,hydra-move-splitter-down
, "k":hydra-move-splitter-up
, "l":hydra-move-splitter-right
.Call the head:
hydra-move-splitter-up
.
Outro
I hope that you enjoy the new library and let me know when you invent some novel and efficient Hydras. Happy hacking!