Even though I think that learning and memorizing shortcuts is good for one's brain, a little help by the user interface is much appreciated, especially if one is working within a complex mode with many commands.

One of the best interfaces of a complex Emacs package can be seen in Magit which shows the available key options in a popup buffer. A little later Abo Abo made his Hydra package available. It allows to define nice key menus and has been a game-changer for me in my daily use of Emacs for the last two years. But the best use of it for myself I only found beginning of this year, when I had the idea about implementing a little context sensitive Hydra launcher.

This was triggered when - as happens sometimes - I went random browsing for elisp commands (using helm-apropos from helm, another of my favorite packages) and I discovered org-link-edit-forward-slurp and org-link-edit-backward-slurp and the *-barf-* equivalents which allow pulling in the surounding text of a link into the link's description text word by word. That's a real nice functionality, but it only makes sense if you have a nice shortcut to it… because remembering and typing the command is about as big an effort as performing the task just by normal editing. And I wanted not to sacrifice another of the rare free key combinations for commands I supposedly would not use that often.

So, I implemented a little launcher that would present me with all the right commands if point was on an org link, another when in a table, a source block, etc. I've been growing this over the last few months and I can say now that I've had it in constant use since day one.

This is the basic launcher code. It makes a main differentiation according to the Emacs major-mode and for org uses the org-element-context and org-element-property functions to react according to the specific context element/type.

(defun dfeich/context-hydra-launcher ()
  "A launcher for hydras based on the current context."
  (interactive)
  (cl-case major-mode
    ('org-mode (let* ((elem (org-element-context))
                      (etype (car elem))
                      (type (org-element-property :type elem)))
                 (cl-case etype
                   (src-block (hydra-babel-helper/body))
                   (link (hydra-org-link-helper/body))
                   ((table-row table-cell) (hydra-org-table-helper/body) )
                   (t (message "No specific hydra for %s/%s" etype type)
                      (hydra-org-default/body))))
               )
    ('bibtex-mode (org-ref-bibtex-hydra/body))
    ('ibuffer-mode (hydra-ibuffer-main/body))
    (t (message "No hydra for this major mode: %s" major-mode))))

(global-set-key (kbd "<f9> <f9>") 'dfeich/context-hydra-launcher)

The following image shows an example for invoking the context launcher on an org-mode link.

hydra-orglink.png

And here what is launched when the cursor is inside of a table

hydra-orgtable.png

And another one for source code blocks

hydra-orgsrcblock.png

The code is not generic enough to make a nice package of it, and I'm also using some of my custom functions which I did not yet put into MELPA packages. But I give here the link of a github gist containig my current hydra definitions.