4

Q: how does one approximate the functionality of the non-existent pre-self-insert-hook?

This question is inspired by the curiosity that is the combination of abbrev-mode and self-insert-command. The docstring for the latter:

Insert the character you type.

Whichever character you type to run this command is inserted. Before insertion, expand-abbrev is executed if the inserted character does not have word syntax and the previous character in the buffer does. After insertion, the value of auto-fill-function is called if the auto-fill-chars table has a non-nil value for the inserted character. At the end, it runs post-self-insert-hook.

It looks to be the case that the call to expand-abbrev is baked directly into self-insert-command -- I assume for efficiency reasons, because it is ancient, or both (feel free to comment if you happen to know why). Ordinarily, I would have expected such a function to run via a hook. However, although there is a post-self-insert-hook, there is no pre-self-insert-hook.

In the absence of such a hook, how does one approximate that functionality, and, more importantly, do so with a minimum of fuss?

None of the options I can think of are ideal:

  • advice: self-insert-command is a primitive defined in C and therefore ignores advice
  • pre-command-hook: simple, but it's overkill because it runs before every command, and not just self-insert-command, and one may only want to run the command as part of self-insert-command
  • define a wrapper around self-insert-command: this appears to be what org-mode and smartparens do (with org-self-insert-command and sp--self-insert-command), but seems complicated by the fact that a) you'd need to rebind an awful lot of keys to use it, b) if one uses multiple major or minor modes that use their own wrapper functions, one needs to keep track of fallback functions so that one does not lose the functionality of other wrappers when rebinding keys (at least I think so; I'm not so sure I understand this part).
  • Actually, it's not so ancient. It was apparently added in Emacs 23. Dunno why. Seems like self-insert-command should only, well, self-insert... You might want to ask emacs-devel@gnu.org your question (and why self-insert-command does expand-abbrev). – Drew Apr 5 '15 at 0:40
  • Well, you used to be able to advise primitives defined in C. (On n'arrete pas le progres.) You can still, however, advise expand-abbrev - does that help? – Drew Apr 5 '15 at 0:41
  • Define a new input method? I mean, you could define an input method to use your function before self-inserting command, so that would be equivalent to having a before- hook. – wvxvw Apr 5 '15 at 5:05
  • You can advise functions defined in C, but the advice won't apply if it's called from C. – npostavs Apr 5 '15 at 18:57
  • @dan (thinking out loud) What about an input-method? – PythonNut Apr 6 '15 at 5:26
4

You can advise self-insert-command just fine. In older Emacsen, it was sometimes (often) called directly from C, but since Emacs-24 (IIRC) it's never called directly from C, so the advice should work reliably.

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.