How can I expand oe
to ö
immediately after hitting the e
without hitting any extra key like space
for expansion?
Why? For better ergonomics I've remapped some keys like ö, ü
and thus must write them with oe
and ue
.
How can I expand oe
to ö
immediately after hitting the e
without hitting any extra key like space
for expansion?
Why? For better ergonomics I've remapped some keys like ö, ü
and thus must write them with oe
and ue
.
Out of the box it is not possible with the abbrev system since self-insert-command
calls expand-abbrev
only when a non-word character is to be inserted. Citation from the doc string of expand-abbrev
:
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 to put a before-advice on self-insert-command
that also calls some kind of expand-abbrev
on characters with word syntax.
We should keep that mechanism as local as possible to avoid an errornous abbrev system.
abbrev-in-word-regexp
. Only text that matches this regexp is expanded mid-word.expand-abbrev
directly to self-insert-command
but add a hook pre-self-insert-command-hook
. We can add our stuff there buffer-locally.(defvar-local abbrev-in-word-regexp nil
"Run `expand-abbrev' if text before point matches this regexp.")
(defun run-pre-self-insert-hook (&rest args)
(run-hooks 'pre-self-insert-hook))
(advice-add 'self-insert-command :before #'run-pre-self-insert-hook)
(defun my-in-word-expand-abbrev ()
"Run `expand-abbrev' when text before point matches `abbrev-in-word-regexp'."
(when (looking-back abbrev-in-word-regexp (line-beginning-position))
(expand-abbrev)))
(defun my-text-mode-setup ()
"Work to be done in `text-mode-hook'."
(setq abbrev-in-word-regexp "\\([aou]e\\)")
(add-hook 'pre-self-insert-hook #'my-in-word-expand-abbrev nil t))
(add-hook 'text-mode-hook #'my-text-mode-setup)
You could try something like this: add additional behavior to "e" itself. Make it insert by default, but try to expand otherwise
(defun e-insert-or-expand ()
"Insert 'e', and if it is part of an abbrev, expand the abbrev"
(interactive)
(insert "e")
(expand-abbrev))
(global-set-key "e" 'e-insert-or-expand)
If you want to refine this to only happening when you are behind a valid expansion prefix (o
or u
) you could do something like
(defvar e-expansion-prefixes '("o" "u"))
(defun e-insert-or-expand ()
"Insert 'e', and if it is part of an abbrev, expand the abbrev"
(interactive)
(insert "e")
(when (save-excursion
(backward-char)
(looking-back (regexp-opt e-expansion-prefixes) 1))
(expand-abbrev)))