0

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.

2
  • 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. Sep 7, 2019 at 6:38
  • Please note abbrevs expand when typing a word separator character, not just space.
    – JeanPierre
    Sep 7, 2019 at 8:08

1 Answer 1

3

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."
  (interactive)
  (if (and (equal (char-before (point)) ? )
       (not (equal (char-before (1- (point))) ? )))
      ;; try to expand abbrev
      (progn
        (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.

8
  • Instead of rebinding the SPC key, you can also use post-self-insert-hook.
    – Stefan
    Sep 7, 2019 at 17:38
  • @Stefan Interesting. So I guess you would make the hook buffer local with make-local-variable, then?
    – JeanPierre
    Sep 7, 2019 at 18:44
  • Would there be any problem/incompatibility if I rebind SPC globally?
    – Yuan Fu
    Sep 7, 2019 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, 2019 at 20:26
  • 1
    There is an edge case that you can't insert two spaces when binding this command to space. Changing (expand-abbrev) to (unless (expand-abbrev) (insert-char ?\s)) solves the problem.
    – Yuan Fu
    Sep 10, 2019 at 2:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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