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.
And here what is launched when the cursor is inside of a table
And another one for source code blocks
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.