(abbrev-table-get global-abbrev-table :regexp) is nil the abbreviation before point is determined by
forward-word (see doc of
But in most major modes the underscore
_ will not have word syntax.
First, we need to accept symbols as abbreviations. Abbrev-tables have a regular expression that matches abbreviations with
(abbrev-table-put global-abbrev-table :regexp "\\_<\\(\\(?:\\sw\\|\\s_\\)+\\)")
expand-abbrev is run in
Relevant part of the doc of
Before insertion, ‘expand-abbrev’ is executed if the inserted character does
not have word syntax and the previous character in the buffer does.
So we have still the problem that after typing
else__ the char before point does not have word syntax. There are two ways of solving it:
- You change your abbrev to something like
else_a (the last
a standing for abbrev). The last character before point is word consistent and the expansion will work after hitting space or newline.
else__ as abbreviation and use a similar solution as in another answer about abbrev:
(defvar pre-self-insert-hook nil
"Normal hook run before `self-insert-command'.")
(defun run-pre-self-insert-hook (&rest args)
(advice-add 'self-insert-command :before #'run-pre-self-insert-hook)
(defun my-symbols-expand-abbrev ()
"Also expand if the preceeding char has symbol syntax."
(when (and (eq (char-syntax (aref (this-command-keys-vector) 0)) ?\s)
(char-before) ;; avoid error at beginning of buffer
(eq (char-syntax (char-before)) ?_))
(add-hook 'pre-self-insert-hook #'my-symbols-expand-abbrev)
- Consider to expand
else__ only in those major modes where it makes sense.
- Consider using the library
skeleton.el instead of
abbrev.el. You can define skeletons with
define-skeleton and use them with
skeleton-insert. Skeletons allow you to place point easily between
end. Furthermore it allows you to indent and format the source code automagically.