0

Just when is it appropriate to put the asterisk * into the interactive spec of a command function? The elisp manual says the effect is to cause an error if the command is attempted in a read only buffer, so clearly this should be done when, in some sense, the command modifies the current buffer.

But this is not precise enough; is the mere possibility of a modification sufficient grounds? What about a command like untabify which could potentially modify my buffer but in fact it never does because I never use physical tab characters?

On the other hand, pretty much any command can be made a no-op by a zero prefix argument, so I guess if I wanted to be sure a modification would in fact occur I'd never use the asterisk.

I just wish the manual were more explicit about this. What is your interpretation?

3

First, this is untrue, assuming I understand what you mean:

On the other hand, pretty much any command can be made a no-op by a zero prefix argument

Beyond that, the answer, IMO, is that you do what you like when defining commands. The point of the * and its doc is to let you know what it does. How/when you decide to use it is up to you.

It's you who answers the question, "Do I want invocation of this command to raise an error if the buffer is read-only?" That's all - there's nothing more to it.

Some particular command, or some particular command author, might well want the error to be raised only if the command would be sure to modify the buffer. But that's not what * does. I raises an error systematically, anytime the command is invoked in a read-only buffer.


You can see for yourself what * would do for untabify in a read-only buffer with no TAB chars:

(defun my-untabify ()
  (interactive "*")
  (untabify (region-beginning) (region-end)))

You ask, in a comment, whether there is some convention regarding the use of * in interactive. My answer is no, not as far as I know. I don't believe there's anything in Coding Conventions, for example.

And I've tried to give a reason why: The behavior of * is just to raise an error whenever the command is invoked interactively in a read-only buffer. What convention could there possibly be about that? If you use * then it'll do just that.

Whether you want it to raise an error in such a context depends on you and what you expect your users will expect in the particular context. How could there be any general guideline about that? That's a judgment call based on the context; it can't be something context-independent.

I suppose you could imagine trying to categorize situations that combine a read-only buffer with various kinds of commands, and come up with some general rules for which kinds of commands in which read-only contexts might be better candidates for raising such an error.

I don't expect that exercise would be worthwhile, but I could be wrong. In any case, I don't think such a classification has been done - I know of no such guideline.

2
  • Thanks for answering. There are places in elisp where a pleasant user experience depends on the programmer following a convention. Keybindings, which of them are "reserved for the user", are one such - and sure enough, quite often I try to use some package, even a popular one, only to see it mess up my keybindings. I do not want my code to be like that. So I was interested if there was a coding convention associated with this particular mechanism. Your answer sounds like "No", am I reading you right? – q.undertow Jul 4 '20 at 23:23
  • Yes, you're reading me right. But perhaps someone else will point to some such convention... The Elisp manual has these entries for convention, among others, which you might want to study: buffer display conventions, coding conventions in Emacs Lisp, major mode conventions, minor mode conventions, programming conventions. – Drew Jul 5 '20 at 0:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.