rw-r--r--

chown -R toon blog/ && chmod -R u=rw,go=r $_

Emacs package: use-package-hydra

posted on 2018-12-27

I totally forgot about this, but a few months ago I wrote my first Emacs package. Before I tell you about the package itself, some background.

use-package

I’m a huge fan of use-package. It’s a great package to bundle all configuration of installed packages together.

You can see how I’m using it in my personal emacs configuration, and below is one example use case:

(use-package whitespace
  :ensure t
  :hook ((prog-mode text-mode) . whitespace-mode)
  :custom-face (whitespace-line ((t (:background "gray90"))))
  :custom (whitespace-line-column 80)
          (whitespace-style '(face tabs empty trailing lines-tail)))

So the body of the (use-package) macro accepts various keywords like:

:ensure
To ensure the package is installed.
:hook
Hook a function to be called by any existing hook, like mode hooks.
:custom
Customize variables defined by the package.

hydra

Hydra is a package that got me intrigued. It’s a very sophisticated package that allows you to configure series of key bindings. It more or less allows you to activate a temporary key map. But let me explain with the simplest example from their README:

(defhydra hydra-zoom (global-map "<f2>")
  "zoom"
  ("g" text-scale-increase "in")
  ("l" text-scale-decrease "out"))

By pressing f2 you activate the hydra and then the keys g and l can be used to zoom in or out. You can keep tapping those two keys, until you tap any other key and the hydra gets deactivated.

I wanted to use this package, but I was a bit annoyed (use-package) didn’t have a :hydra keyword.

use-package-hydra

So I wrote use-package-hydra. It’s pretty simple, under 100 lines, and it just expands the :hydra keyword to a call to (defhydra).

This is an example from the README:

(use-package yasnippet
  :after hydra
  :bind (:map yas-minor-mode-map ("<f2>" . hydra-yas/body))
  :hydra (hydra-yas (:color blue :hint nil)
          "
              ^YASnippets^
--------------------------------------------
  Modes:    Load/Visit:    Actions:

 _g_lobal  _d_irectory    _i_nsert
 _m_inor   _f_ile         _t_ryout
 _e_xtra   _l_ist         _n_ew
 ^ ^       _a_ll
"
          ("d" yas-load-directory)
          ("e" yas-activate-extra-mode)
          ("i" yas-insert-snippet)
          ("f" yas-visit-snippet-file :color blue)
          ("n" yas-new-snippet)
          ("t" yas-tryout-snippet)
          ("l" yas-describe-tables)
          ("g" yas/global-mode)
          ("m" yas/minor-mode)
          ("a" yas-reload-all)))

It defines a hydra named hydra-yas. Just like the (defhydra) macro, this will define the function hydra-yas/body. Inside the (use-package) body that function is bound to f2. So pressing f2 i will trigger yas-insert-snippet.

Future

Like I said, I forgot about the package. That is probably because I didn’t get much attention when I announced it on the emacs-devel mailing list. I was hoping for reaction on how to improve the code or hear people being excited about it, but there wasn’t much action.

Also the issue where this package was suggested didn’t get much traction.

Now, honestly, I’m not even using it myself…

I really would like to improve the package, so it’s more DRY1. Like I want to avoid putting in hydra-yas and hydra-yas/body, and have those auto-defined with the user knowing.


Comments are welcome on Reddit.

Footnotes:

1

Don’t Repeat Yourself