reddit / emacs
How can I make abbreviations expand instantly?
AwkwardNumber7584 · 2022-12-27 18:32
Hi,
Is there a way to make certain abbreviations straightforward, without the use of extra keys? Here's an approximation:
```
(defun abbrev-or-insert ()
(interactive)
(self-insert-command 1)
(expand-abbrev))
(define-abbrev-table 'global-abbrev-table
'(
("HH" "---~" nil :case-fixed t :count 0)
("LL" "\\ldots{}" nil :case-fixed t :count 0)
("ДД" "\\ldots{}" nil :case-fixed t :count 0)
))
(global-set-key (kbd "Д") 'abbrev-or-insert)
(global-set-key (kbd "H") 'abbrev-or-insert)
(global-set-key (kbd "L") 'abbrev-or-insert)
```
It works as desired; well, almost:
```
\ldots{}\ldots{}арпДД \ldots{}\ldots{}
\ldots{}abaLL \ldots{}\ldots{}booLL
```
Somehow, any input after the expansion of the abbreviation is disruptive. It takes a space to make it work again. Is there a way to get rid of that space?
ieure · 2022-12-27 20:26
I guess by "instantly," you mean you want ex. "fyi" to expand to "for your information" rather than "fyi " ("fyi" followed by a space).
Try adding `expand-abbrev` to `post-command-hooks`.
timmymayes · 2022-12-27 20:37
I think abbrev-mode and define a new abbrev with C-x a i g
akirakom · 2022-12-27 21:44
`post-self-insert-hook` would be even better than `post-command-hook`.
ieure · 2022-12-27 21:53
You're right!
AwkwardNumber7584 · 2022-12-27 23:37
I'm sorry, I've got no experience with the hooks. I just added this globally:
```
(add-hook 'post-self-insert-hook #'expand-abbrev)
```
No errors, no change in behavior.
AccurateRendering · 2022-12-28 01:22
I'd learn about yasnippet before writing my own snippet expander.
AwkwardNumber7584 · 2022-12-28 06:18
How exactly would you write the suggested hook?
akirakom · 2022-12-28 06:30
It works for me. I have no idea why it doesn't for you. Could you check the value of `post-self-insert-hook` in the buffer? It can have a local value, so try the following one:
(add-hook 'post-self-insert-hook #'expand-abbrev nil t)
akirakom · 2022-12-28 06:39
Actually, `abbrev` is quite useful even if you use another snippet framework. It can be combined with other "auto-typing" frameworks such as skeleton and tempo. With abbrev, you can bind an interactive function to a string, so the backend can be anything. However, yasnippet has an advantage of its great template syntax, so I don't object of your idea of learning it too. For trivial use cases, abbrev + skeleton/tempo is capable enough.
AwkwardNumber7584 · 2022-12-28 07:34
It doesn't help, unfortunately. I use Doom Emacs, BTW. It shouldn't make any difference in my case, probably.
AwkwardNumber7584 · 2022-12-28 07:35
What do you mean by checking?
akirakom · 2022-12-28 08:08
1. `M-x describe-variable RET post-self-insert-hook` in the buffer you are typing into.
2. See the value ("Its value is ...") and check if it contains `expand-abbrev`.
AwkwardNumber7584 · 2022-12-28 09:06
(1) It says `[match required]`
Anyway,
```
Its value is
(sp--post-self-insert-hook-handler electric-indent-post-self-insert-function blink-paren-post-self-insert-function)
```
Apparently, no `post-self-insert-hook` here.
Out of my code:
```
(add-hook 'post-self-insert-hook #'expand-abbrev nil t)
```
Emacs server restarted, more than once.
akirakom · 2022-12-28 11:23
> Apparently, no
> post-self-insert-hook
> here.
Perhaps some of your minor modes have made `post-self-insert-hook` variable local to buffers. You can add the function globally before you turn on the problematic minor mode in `init.el`. Otherwise, you have to add `expand-abbrev` to `post-self-insert-hook` in each buffer where you need it.
akirakom · 2022-12-28 11:25
> (1) It says
> [match required]
`RET` was required, sorry.
AwkwardNumber7584 · 2022-12-28 12:03
I tried `add-hook` as the first statement in my `init.el`. Won't work. I checked the list of minor modes: there's dozens of them. Concerning buffers: I really need these abbreviations in `*.tex` files only. Can I automate this?
AwkwardNumber7584 · 2022-12-28 14:13
But, but... What is `sp--post-self-insert-hook-handler`? Tried research, found nothing.
akirakom · 2022-12-28 14:44
> sp--post-self-insert-hook-handler
It's from smartparens.el: https://github.com/search?q=sp--post-self-insert-hook-handler+language%3Aemacs-lisp&type=code
yurikhan · 2022-12-28 16:25
I suspect the thing that throws you off is that by default Emacs extracts the abbrev name as the last word before point. You seem to want them to expand even if written immediately adjacent to other word characters, so you need to help Emacs determine where your abbrev names start.
(define-abbrev-table 'global-abbrev-table
'(
("HH" "---~" nil :case-fixed t :count 0)
("LL" "\\ldots{}" nil :case-fixed t :count 0)
("ДД" "\\ldots{}" nil :case-fixed t :count 0)
)
:regexp (regexp-opt '("HH" "LL" "ДД") t))
Additionally, as said in other comments, you need to trigger `(expand-abbrev)` in your `post-self-insert-hook`.
AwkwardNumber7584 · 2022-12-28 18:35
Thank you very much! Looks like everything is just fine. Unless there's still something I haven't yet noticed :)
AwkwardNumber7584 · 2022-12-29 03:23
Still, neither absence nor presence of
```
(add-hook 'post-self-insert-hook #'expand-abbrev nil t)
```
makes any difference. It just works with your `:regexp`.