2024-10-19 substitute-command-keys

Today I have a short tip for everyone that codes Elisp (for other people or even only for themselves), inspired by something I wrote recently (and will blog about soon, too). If you want to tell the user things like “press C-c C-c to finish what you are doing”, don’t hardcode the keybindings in the message string. You may bind the command to finish whatever the user is doing to C-c C-c, true, but the user could rebind it to <f10> or even M-s s-a or whatever key they like, or even unbind it completely. Instead, use the following syntax: \[command-name] (of course, you need to double the slash if you put it in an Elisp string), and process the string with substitute-command-keys. This way, Emacs will convert your command-name to the textual representation of the actual binding of your command. If the command has more than one binding, you can set the “preferred one” by setting the :advertised-binding property of the function name using put (or preferably function-put). If that property is not set, the binding used is selected according to where-is-preferred-modifier, which see; note that the docstring of that variable is apparently wrong, since it should say where-is-internal, not where-is. Even better, the resulting string will be fontified so that the binding is in the help-key-binding face.

For example, in emacs -Q, (substitute-command-keys "\\[undo]") yields C-x u, and (substitute-command-keys "\\[describe-face]") yields M-x describe-face (since this one is not bound to any key by default).

In fact, substitute-command-keys can do a lot more – see the relevant section of the documentation in the Elisp reference.

As usual, the self-documenting nature of Emacs shows itself – the support for something as trivial as displaying the binding of a command is superb, and if you want your code to be as user-friendly as possible when showing those bindings, you only need to make use of what Emacs already gives you.

CategoryEnglish, CategoryBlog, CategoryEmacs