Easily arrange hydra into a matrix

The new :columns option

Today I'll introduce a pretty cool new option that you can use to quickly create hydra docstrings arranged in a matrix. This, of course, was already possible before, but you had to format the matrix by-hand like this (I cite just bit instead of the full code, it was cut to fit into the Jekyll code column restriction):

( defhydra hydra-projectile ( :color teal :hint nil ) " PROJECTILE: Find File Search/Tags ----------------------------------------- _s-f_: file _a_: ag _ff_: file dwim _g_: update gtags _fd_: file curr dir _o_: multi-occur " ( "s-f" projectile-find-file ) ( "a" projectile-ag ) ( "ff" projectile-find-file-dwim ) ( "fd" projectile-find-file-in-directory ) ( "g" ggtags-update-tags ) ( "o" projectile-multi-occur ) ( "q" nil "cancel" ))

The syntax above is still very useful if you want to arrange every detail perfectly or need Ruby-style quoting. But here's the new syntax that allows to get almost the same docstring much easier:

( defhydra hydra-projectile ( :color blue :columns 4 ) "Projectile" ( "a" projectile-ag "ag" ) ( "b" projectile-switch-to-buffer "switch to buffer" ) ( "c" projectile-invalidate-cache "cache clear" ) ( "d" projectile-find-dir "dir" ) ( "s-f" projectile-find-file "file" ) ( "ff" projectile-find-file-dwim "file dwim" ) ( "fd" projectile-find-file-in-directory "file curr dir" ) ( "g" ggtags-update-tags "update gtags" ) ( "i" projectile-ibuffer "Ibuffer" ) ( "K" projectile-kill-buffers "Kill all buffers" ) ( "o" projectile-multi-occur "multi-occur" ) ( "p" projectile-switch-project "switch" ) ( "r" projectile-recentf "recent file" ) ( "x" projectile-remove-known-project "remove known" ) ( "X" projectile-cleanup-known-projects "cleanup non-existing" ) ( "z" projectile-cache-current-file "cache current" ) ( "q" nil "cancel" ))

It still looks pretty good, in my opinion:

Note how all redundant information has been removed. Another advantage is the you can easily:

Add/remove heads.

Update head hints.

Change the number of columns.

A bit of customization

After each change, just re-eval the defhydra and you're done - no need to manually re-arrange the docstring. Since there already is an interface that allows you to customize the docstring very precisely, I tried to make the new interface as automatic as possible: just specify the number of columns and you're done. But if you want just a little bit more customization, look at this code:

( defvar hydra-key-doc-function 'hydra-key-doc-function-default "The function for formatting key-doc pairs." ) ( defun hydra-key-doc-function-default ( key key-width doc doc-width ) ( format ( format "%%%ds: %%%ds" key-width ( - -1 doc-width )) key doc ))

So if you want to add a little space here and there, or e.g. wrap key bindings in brackets, just clone hydra-key-doc-function-default , customize it a bit and set hydra-key-doc-function to the new function.

Outro

If you've been using just the plain style before and felt that you can't fit your docstring on one line, try the new style: it's just one line of change with respect to your old code. And if you've been building the docstring by-hand, see if it's possible to transform it to the new style: adding and removing new heads will become easier. Thanks to @Fuco1 for the suggestion in #140.