Organizing Key-Bindings in GNU Emacs Using Hydra

Today I want to give you a brief introduce to Hydra. It is a great package for managing groups of key-bindings. The author is Oleh Krehel, known as ‘abo-abo’ in the Emacs community. Don’t be surprised if the name sounds familiar, as he is a prolific Emacs Lisp programmer.

Why Use Hydra?

I like to create groups of key-bindings with a common prefix. For example, all of my keys to change major-modes begin with C-c m. All of my text-mode related commands begin with C-c t. And so on. I find this to be an efficient system, and Hydra exists for people like me, as its documentation says:

This is a package for GNU Emacs that can be used to tie related commands into a family of short bindings with a common prefix – a Hydra.

So if you have similar preferences then I think you’ll like what you’re about to see.

My Example Hydras

Creating a ‘hydra’, a group of bindings, begins with the defhydra macro. Here is an example from my own Emacs configuration:

(defhydra hydra-major (:color blue)
  "major-mode"
  ("t" text-mode "text")
  ("d" diff-mode "diff")
  ("l" lua-mode "lua")
  ("p" php-mode "php")
  ("m" markdown-mode "markdown"))

(global-set-key (kbd "C-c m") 'hydra-major/body)

Now when I press C-c m I see this in the minibuffer. It’s probably not too hard to work backwards from the result to understand the syntax of defhydra. The first argument, hydra-major, is the name of the key-binding group. The macro uses that name when defining some other functions, like the hydra-major/body function that I bind to my prefix of choice in order to evoke the hydra.

Next are any options. I’ll return to explain :color blue momentarily.

Then comes text to display for the hydra. I use a simple string but you can get pretty fancy.

And finally are the heads of the hydra: the single letter keys which invoke a given major mode. The basic format is (key mode hint-text), but again the package supports more complex definitions if you need or want them.

Now back to :color blue. Notice in my example that the letters for each mode choice are in blue. This is not purely aesthetic; the color indicates what the hydra will do after the choice. Blue options end the hydra choices. In otherwords, once I select a blue option my choices are over and the hydra vanishes from the minibuffer. The default behavior, however, is for the hydra to remain active and allow you to select other heads. This can be useful for toggling multiple minor-modes and/or invoking a series of commands. For example, this is also from my personal configuration:

(defhydra hydra-text ()
  "text"
  ("f" auto-fill-mode "fill")
  ("a" align-regexp "align" :color blue)
  ("i" ispell-buffer "ispell" :color blue)
  ("l" visual-line-mode "line")
  ("t" typo-mode "typo"))

(global-set-key (kbd "C-c t") 'hydra-text/body)

Here only two commands are explicitly marked as blue. The rest default to red, which means I can invoke them multiple times without cutting off the hydra. For example, after pressing C-c t I can press f to toggle auto-fill-mode, then t to toggle typo-mode, then f again if I changed my mind about using auto-fill-mode, and finally i to spell-check the entire buffer, which would close the hydra since that’s one of the blue commands. Or C-g if I were done with the red commands and didn’t want to use a blue one.

Further Reading

That should give you a nice taste of what’s possible with defhydra. But I have only scratched the surface. At this point you should check out the official project page along with the author’s blog for his articles about how he uses Hydra. I hope you find it as useful as I have for organizing key-bindings.

Advertisements

One thought on “Organizing Key-Bindings in GNU Emacs Using Hydra

  1. […] is about or would like to see if it's something you can use, Eric James Michael Ritz has a nice introduction to Hydra and how he uses it. It's short and easy to digest. After reading it, you should have a good idea of […]

Add Your Thoughts

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s