Some Personal Hydras for GNU Emacs

Today I want to share with you some of my personal hydras, i.e. groups of key-bindings for use with the Hydra package for GNU Emacs. Along the way I’ll also be referencing a variety of useful packages.

Note: Throughout this article you will see examples of use-package, a terrific package to help organize and control the loading and configuration of third-party packages.

Zooming

This first hydra is a modification of one from the Hydra wiki, where you can find a variety of great user-submitted hydras. This particular hydra is for adjusting the scale of text in a buffer, i.e. zooming in and out. Here is the example from the wiki:

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

I have some entirely subjective problems with this hydra:

  1. It does not contain a command to reset the scale to its default value.

  2. The keys do not match the default Emacs bindings for zooming, e.g. C-x C-+.

  3. The hydra hijacks <f2>, which I use for something already. Admittedly this is trivial to change.

Here is my personal version:

(defhydra hydra-zoom ()
  "zoom"
  ("+" text-scale-increase "in")
  ("-" text-scale-decrease "out")
  ("0" (text-scale-adjust 0) "reset")
  ("q" nil "quit" :color blue))

The benefits to my version, which again are entirely subjective:

  1. The keys to increase and decrease the scale are consistent with the default C-x C-+ and C-x C-- bindings, respectively.

  2. There is a key to reset the scale to its default, mirroring the default C-x C-0 which performs that same task.

  3. There is an explicit key to exit the hydra. You can always just use C-g, but I have grown to like having a q in hydras for ending them.

I like to use Key-Chord Mode for a lot of bindings. One nice thing about defhydra is that it returns a function you can bind to a key in order to invoke the hydra, so my actual configuration looks like this:

(key-chord-define-global "QZ"
 (defhydra hydra-zoom ()
   ;; ...
   ))

That allows me to press QZ to quickly modify the zoom in a buffer.

Org Mode Navigation

I use Org Mode constantly, and so here is a hydra I use to navigate such files:

(defhydra hydra-org (:color red :columns 3)
  "Org Mode Movements"
  ("n" outline-next-visible-heading "next heading")
  ("p" outline-previous-visible-heading "prev heading")
  ("N" org-forward-heading-same-level "next heading at same level")
  ("P" org-backward-heading-same-level "prev heading at same level")
  ("u" outline-up-heading "up heading")
  ("g" org-goto "goto" :exit t))

This demonstrates the :columns feature of Hydra, which is a nice and quick way to neatly format the display of hydras in the minibuffer without resorting to the amazing things you can do with fancy formatting strings.

Page Breaks

I recently wrote about using page breaks and how I use helm-pages to help navigation. But in that article I did not show you the hydra I use to further improve said navigation:

(use-package helm-pages
  :config
  (defhydra hydra-page-breaks (global-map "C-x")
    "pages"
    ("[" backward-page "backward")
    ("]" forward-page "forward")
    ("M-p" helm-pages "helm" :color blue)
    ("RET" nil "quit")))

This example shows off the power of global-map in hydras. The default bindings for backward-page and forward-page are C-x [ and C-x ], respectively. By using global-map "C-x" I tell Hydra to hijack those bindings so that they invoke my hydra. And then there is M-p there to invoke helm-pages if I want, i.e. C-x M-p.

Flycheck

Flycheck is an amazing syntax-checking package for Emacs, and I’m a fan of helm-flycheck for navigation. Here’s the hydra I use for quickly navigating between warnings and errors which Flycheck reports, with quick access to helm-flycheck:

(use-package helm-flycheck
  :config
  (define-key flycheck-mode-map (kbd "C-c ! h") 'helm-flycheck)
  (key-chord-define-global "QF"
   (defhydra flycheck-hydra ()
     "errors"
     ("n" flycheck-next-error "next")
     ("p" flycheck-previous-error "previous")
     ("h" helm-flycheck "helm" :color blue)
     ("q" nil "quit"))))

You’ll notice I also bind helm-flycheck to the keys C-c ! h, using the C-c !prefix whick is predominate in Flycheck.

Desktops

I find desktops to be a convenient way of managing ‘sessions’ in Emacs, i.e. collections of related buffers. This is the hydra I use for them:

(defhydra hydra-desktop (:color blue)
  "desktop"
  ("c" desktop-clear "clear")
  ("s" desktop-save "save")
  ("r" desktop-revert "revert")
  ("d" desktop-change-dir "dir"))

Avy

Avy is a damned fast way to jump to characters, (sub-)words, and lines. In this hydra I combine it with link-hint, a package based on Avy used to jump-to and open URLs:

(use-package avy
  :config
  (use-package link-hint)
  (global-set-key (kbd "M-g g") #'avy-goto-line)
  (defhydra hydra-avy (global-map "M-g" :color blue)
    "avy-goto"
    ("c" avy-goto-char "char")
    ("C" avy-goto-char-2 "char-2")
    ("w" avy-goto-word-1 "word")
    ("s" avy-goto-subword-1 "subword")
    ("u" link-hint-open-link "open-URI")
    ("U" link-hint-copy-link "copy-URI")))

Corral

Finally there is Corral, a useful package for wrapping text in various delimiters, which I find quite useful in computer programming. Simply chcek out the example of the project’s home page to see it in action. Here is my hydra for Corral:

(use-package corral
  :config
  (defhydra hydra-corral (:columns 4)
    "Corral"
    ("(" corral-parentheses-backward "Back")
    (")" corral-parentheses-forward "Forward")
    ("[" corral-brackets-backward "Back")
    ("]" corral-brackets-forward "Forward")
    ("{" corral-braces-backward "Back")
    ("}" corral-braces-forward "Forward")
    ("." hydra-repeat "Repeat"))
  (global-set-key (kbd "C-c c") #'hydra-corral/body))

This hydra demonstrates hydra-repeat, which will repeatedly invoke the last ‘head’ of the current hydra. So for example, after pressing C-c a ( I can continue to press . to repeat the ( head of the hydra. If I then were to press ] then . would repeat that head. My choice to use . for this purpose does not in any way represent an influence from Vim.

…Cough…

Conclusion

So there are some relatively simple hydras which I find useful on a daily basis. I hope you find some of them helpful. And if you have any cool ones please share them in the comments here and/or on the Hydra wiki.

Advertisements

5 thoughts on “Some Personal Hydras for GNU Emacs

  1. […] of hydras, as we did yesterday, Eric James Michael Ritz has a nice post on some of the hydras he uses. If you're looking to see some good ways of using the hydra package, Ritz's post is a worth taking […]

  2. Good stuff, thanks for sharing! On zooming: The built-in behavior is already very hydra-like, I’ve found. After an initial C-x C-+ (or – or 0) you can let go of any modifiers and just keep hitting = (+) , -, and 0 to zoom in, out, and reset.

    1. Yeah, the default zooming commands are pretty hydra-esque already. Honestly the biggest personal benefit I get out of using the hydra is the fact I can bind it to a key-chord, which is just more convenient for me than C-x C-+ to start zooming in or out.

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