2021-03-27 The interactive clause and modes

I was reading up on the interactive clause recently, and I noticed something I’m quite sure there wasn’t there before. (Indeed, I checked it and it’s really new – it was added in February to the master branch, so expect some time before it hits the distributions. This is a bit embarrassing, but I’m not really sure how the release cycle works for Emacs – I just compile it from master every now and then - but it looks like it should be present in the newest version, that is, v27.2.)

So, If you have a command which should only be available in some mode, you can say something like

(defun special-command ()
  "This command is only available in special mode."
  (interactive "" special-mode)
  (message "This is a special command."))

and then this command is marked as “tied” to special-mode. This has two effects (at least, two that I’m aware of). One is that you can say

(setq read-extended-command-predicate

in your init.el file, and then M-x won’t offer special-command for completion unless you are in special-mode (or any mode derived from it). For some reason, this is not on by default – I didn’t notice any performance issues with that, so it’s probably a question of backwards compatibility (in fact, setting that might improve performance when using some sophisticated completion engine, but this is just me theorizing, I didn’t perform any proper experiments).

There is, however, a much cooler effect of using this form of interactive: even without any particular setting, C-h m in special-mode will now list special-command below the list of keybindings, under the “Other commands for this mode, not bound to any keys” title. This has a drawback – running C-h m in an Emacs session where lots of commands are defined will take a few seconds – but I can live with that, especially that it can drastically improve discoverability. Now, even if some mode does not bind its less often used commands to any keys, describe-mode lists them – and so is closer to being a “manual” for the mode, i.e., the default place you can go to actually learn to use the mode.

Let me also add that you can put multiple modes in this new form of the interactive clause, and you can put there minor modes, too! Also, remember that you need the arg-descriptor argument to interactive to use this feature, so if your command takes no arguments, you may e.g. use an empty string there.

I have to say that this is a great addition to Emacs (even if I have to wait a few moments for the effects of describe-mode, and even though apparently I can’t turn that off). It does have a few rough edges – like the performance penalty or the fact that the “describe” feature only works for major modes. But those are just minor quirks (and they may be resolved in the future).

Believe it or not, but Emacs is even more self-documenting now!

CategoryEnglish, CategoryBlog, CategoryEmacs