On the fly key sequence insertion

If you’ve ever saw Irreal or Xah Lee‘s blog, you’ve certainly saw the very interesting thing they do to show Emacs’ key. By shamelessly stealing their method, I can now write keys like this: C-c+a.

I’m currently writing a little tutorial for some coworkers and this stroke me as being the ideal way to show how to enter some commands.

Writing mostly in Org-mode, my chosen method is Irreal’s org-mode macro:

#+MACRO: key @<span class="key">$1@</span>

This way, every time I write { {{key(C-something)}}} (without the whitespace), it will export to HTML and give this: C-something. Nice eh?

Irreal later posted about how he didn’t like the macro method and made an elisp function to replace some text in the buffer. The function is really interesting, but I didn’t like the part where you have to t.y.p.e the command. Most of these commands are now muscle memory. If I write them by hand, without doing them, I have to stop and think about it. Bleh.

I needed another solution, one that could flow in my work. I wanted to be able to make a tutorial by actually doing the commands.

The solution is very simple… so of course I’ve wasted hours before finally solving it.

How can we input a sequence of keys, but at the same time make sure it isn’t executed? There’s a function I use everyday that does exactly that: describe-key (C-h+k). The source code shows that the secret recipe is the interactive function, with the code letter “K”. Marvelous! Let’s try a little test function:

(defun test-fn (arg)
  (interactive "KKey sequence: ")
  (print arg))

Unfortunately, C-c+a shows up as “^Ca”. Ugly. Useless.

The magic function we need to add is single-key-description. This will turn characters into the pretty “C-c a” we all know and love. The function now looks like this:

(defun test-fn (arg)
  (interactive "KKey sequence: ")
  (print (mapcar 'single-key-description arg)))

And it returns (“C-c” “a”). Great, now we just need to add the “{{{” sugar around it:

(defun insert-key-for-org-macro (arg)
  "Insert the key-sequence for org-macro."
  (interactive "KKey sequence: ")
  (insert "{{{key\(")
  (insert (mapconcat 'single-key-description 
		     arg
		     "\)}}}+{{{key\("))
  (insert "\)}}}"))

Tada! Bind this to a key (say <f5>) and you will be able to enter key sequences faster than you ever hoped!


2 responses to “On the fly key sequence insertion

Leave a Reply

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

%d bloggers like this: