I want to expand abbrev when I type two spaces instead of one. Is there any way to do it? Simply adding a space to the abbrev pattern doesn't work -- the abbrev is still expanded on the first space.

  • Assume it's possible to write a function triggered by idle-timer, which looks back for two spaces, jumps back with save-excursion and tries to expand. – Andreas Röhler Sep 7 '19 at 6:38
  • Please note abbrevs expand when typing a word separator character, not just space. – JeanPierre Sep 7 '19 at 8:08

First, note that abbrevs expand when typing a word separator character, not just space. Looking at the doc for self-insert-command suggests that's no way to easily change the behavior of abbrev-mode.

self-insert-command is an interactive built-in function in ‘src/cmds.c’.

(self-insert-command N)

Insert the character you type. Whichever character you type to run this command is inserted. The numeric prefix argument N says how many times to repeat the insertion. Before insertion, ‘expand-abbrev’ is executed if the inserted character does not have word syntax and the previous character in the buffer does.

However, what can be done is to not use abbrev-mode and rather bind the space key to a command that calls expand-abbrev "on second space" and falls back to inserting a space if no abbrev is found. The following code does that.

(defun insert-space-or-expand-abbrev-on-second-space ()
  "Insert a space or expand abbrev before current space."
  (if (and (equal (char-before (point)) ? )
       (not (equal (char-before (1- (point))) ? )))
      ;; try to expand abbrev
        (backward-char 1)
        ;; if no expansion occurs, fall back to inserting space
        (unless (expand-abbrev) (insert-char ? ))
        (forward-char 1))
     ;; just insert space
     (insert-char ? )))

(local-set-key  " " 'insert-space-or-expand-abbrev-on-second-space)

If an abbrev in indeed expanded, the second space is not inserted, but you can insert one by typing the space key one more time, since no abbrev would be found this time.

One could define something like a two-spaces-abbrev-mode based on this code.

As mentionned by @Stefan, a different approach would be to use post-self-insert-hook.

  • Instead of rebinding the SPC key, you can also use post-self-insert-hook. – Stefan Sep 7 '19 at 17:38
  • @Stefan Interesting. So I guess you would make the hook buffer local with make-local-variable, then? – JeanPierre Sep 7 '19 at 18:44
  • Would there be any problem/incompatibility if I rebind SPC globally? – Yuan Fu Sep 7 '19 at 19:48
  • No, hooks are not variables: you just use the local arg of add-hook to indicate that the function should only be added to the hook in the current buffer. – Stefan Sep 7 '19 at 20:26
  • @YuanFu: Not really, no, but when you rebind the key, other code can't know whether the new binding does "essentially the same" as the old one or not, so it can result in less smooth interaction with other packages that also tweak the behavior of SPC. – Stefan Sep 7 '19 at 20:29

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.