Xah Lee has an interesting post that taught me something I already knew. The problem that Lee deals with is how to write an Emacs command (that is, a function callable by, say, 【Meta+x】 and the function name) that is also callable directly from elisp code. In general, that’s not hard because interactive functions are always callable from elisp. In Lee’s case, the problem was that the function was called differently in the two cases: when called interactively, the function was passed the beginning and end of a region to work on; when called directly, it was passed a string. Lee has a nice solution and if you write Emacs Lisp you should take a look at how he solved it.
What I want to talk about is the interactive
declaration. If you’ve written any Emacs Lisp you know that it specifies how arguments are to be passed to the function when it’s called interactively. Normally this is specified by code letters in a string that makes up the argument to interactive
. For example,
(interactive "nEnter a number: ")
says that the function will be passed a number that Emacs will prompt the user for with Enter a number:
. Similarly,
(interactive "p")
passes the function the prefix argument. All the prefix codes are in the built in documentation as well as the Emacs Lisp Manual.
You can also pass interactive
an expression instead of a string and have the expression return a list of the arguments to pass to the command. That’s the part that I learned but already knew. I already knew it because I read it every time I look up interactive
in the built in documentation to check the code letters. Somehow, though, it just never sunk in. Maybe because it’s hard to imagine a realistic use case. Fortunately, Lee has more imagination that I do and came up with a very good use case. Again, you should look at his post to see a nice example of passing interactive
an expression instead of a string.
The full story on interactive
is in the Section 21.2.1 of the Emacs Lisp Manual. There’s a lot of useful information in there that’s worth reading about.