reddit / emacs
Please tell me about the different approaches to text expansion you can find in emacs.
deltille · 2022-05-18 04:48
After seeing [today's thread](https://old.reddit.com/r/emacs/comments/urmnjj/text_expansion_with_hippie_expand/) on Mastering Emacs' article on
hippie-expand, and seeing in its comments many of the same things that
have confused me for several months now, I thought it would be a good
time to get this straightened out in my config once and for all.
I know there are a lot of options for text expansion, and they each
seem to have slightly different preconcepts, encouraging slightly
different use.
Emacs' built in 'skeleton' system has its own 'microsyntax'(?) and is
clearly geared to popping in medium- or large-sized structures defined
ahead of time, usually where certain fields have to be filled. (I also
recall bemoaning how poorly-documented skeletons were, especially
online...)
I know 'yasnippet' is based on the way TextMate did it. I didn't use
TextMate, so I'm not sure what this means in practice.
I know 'tempo', 'abbrev', 'dabbrev'/'dynamic abbrev' and 'hippie
expand' exist, but I know little about any of them, other than that
some (maybe all?) come with emacs these days, and may or may not
need to be explicitly required.
I also know of another *kind* of text expansion -- text 'prediction',
text completion?-- that tries to *complete* text for you,
intelligently or otherwise, sometimes in the main buffer, sometimes in
the minibuffer. I know this tends to be handled by another kind of
package entirely. I also know that in the last major update, emacs
received several new kinds of minibuffer completion.
*But*, I noticed that this capacity seems to, sometimes, overlap with
text expansion packages. This is one of those 'preconcepts'-- ideas
about what 'text expansion' *could* mean-- that I was talking about,
implicit in a given package. To me, 'expansion' implies I know exactly
what it is something will unpack into, rather than being unsure and
needing an interface to decide. But I can certainly see how the two
ideas could be fruitfully blended, for example in M-/ (which seems
to be bound to `dabbrev-expand` by default).
So, I wonder if someone who feels strongly about text expansion might
want to clear this up-- and perhaps try to sell me on one or the other
:) In the process, helping to straighten out the next person confused
about this ecosystem-within-an-ecosystem. I've already shallowly gone
over a few of them, 'skeleton' primarily, but there's so many options
that would take so much time to deep-dive that it makes much more
sense to ask someone already familiar.
Horrih · 2022-05-18 04:53
Thank you for posting this, am really interested as well, this post might help many people
deltille · 2022-05-18 04:56
I hope so. Honestly, some of the things people have patiently explained to me on this subreddit have made me want to start a blog -- as someone who doesn't particularly enjoy blogging. It feels like a shame to let that knowledge drop off into 'too long ago to easily search or index' purgatory.
dirtycimments · 2022-05-18 05:33
Or a wiki, if blogging feels like a slog for you 👍
mickeyp · 2022-05-18 06:07
Abbrev is the simplest of them all. It looks at the word before point, checks its abbrev tables (mode-specific or global) and replaces the word at point if it finds a replacement.
Abbrev is designed for unoptrusive replacement of text. I downloaded a list of Wikipedia's most common typos and misspellings and converted it to abbrev. Now my Emacs will fix thousands of common errors without me even really knowing it's doing it.
Dynamic abbrev expands text at point when you ask it to, based on other words in your buffer(s). Hippie is like that, too, but more advanced.
Skeleton and Tempo let you define complex expansion patterns using a simple s-expression-like language. They're very powerful. Yasnippet does much of the same, but it's beginner friendly, opting for a simpler syntax. I use the latter, but used to use the former. I'd go back to the former, as it was what I first used when I started using Emacs, but I can't be bothered converting stuff.
Completion at point is Emacs's builtin completion tool. Which is what Company generally uses for its backends. Said backends offer up completions for the word or symbol at point. This is usually tied to 'intelligent completion' like LSP or other sources of facts -- but it doesn't have to be. Emacs is flexible, so you can plug dynamic abbrev into it if you want. Or, with a bit of work, the other way around.
Emacs intentionally overlaps things, because your needs are different depending on what you want to do. Completion at point (builtin, or using Company) is usually contextual even if the word itself isn't. Think completing ``MyStruct.Foo`` to ``MyStruct.FooBar``. The choice is only available when you want to complete a struct, because LSP says it's only available at that point.
Dynanic, Hippie, etc. take the more holistic and naive approach of just shoving matches at you, provided the pattern(s) match. It'll therefore work in your README file, source code comments, or anywhere really.
deltille · 2022-05-18 06:13
You are the author of the post I linked, right? Thank you, I wasn't expecting that :) It's exactly the breakdown I wanted.
Did I miss any of the major packages for this in my searching? I listed the ones I knew about but did not imagine it to be an exhaustive list.
deltille · 2022-05-18 06:22
That niche seems pretty filled by emacs-wiki... but you remind me that there are blog/wiki hybrids about and that idea does seem a lot more palatable to me. Thanks for the thought.
pragmat1c1 · 2022-05-18 08:04
Excellent overview and summary. Thank you! - Love your book („Mastering Emacs“) by the way. Wondefully written.
mickeyp · 2022-05-18 08:36
Thank you :)
TabCompletion · 2022-05-18 08:38
IDK, I've been using hippie expand and it serves what I want.
TabCompletion · 2022-05-18 08:42
Yeah I love how you can get expanding to work on any buffer
chmouelb · 2022-05-18 12:25
> Abbrev is designed for unoptrusive replacement of text. I downloaded a list of Wikipedia’s most common typos and misspellings and converted it to abbrev. Now my Emacs will fix thousands of common errors without me even really knowing it’s doing it
Very cool, would you have that abbrev list available somewhere by any chance ? Thanks
[deleted] · 2022-05-18 15:02
[deleted]
00-11 · 2022-05-18 17:20
Little-known but longstanding library `completion.el`, which is part of Emacs since ~forever. The doc is the code Commentary. Builds a persistable "database" (cache) of expansions on the fly. You can use that to expand text as you type. Also has a dabbrev behavior.
Needs some love, to make it into the 21st century. But quite useful even as is.
whompyjaw · 2022-05-18 23:02
Very much agree. I just bought it yesterday and got to chapter 4! Loving it.
shryzr · 2022-05-19 00:00
You could use the Emacswiki itself to write about Emacs and underlying oddmuse wiki framework for your own wiki. Check out https://alexschroeder.ch/wiki/Diary
[deleted] · 2022-05-19 03:33
[deleted]
azfrak · 2022-05-19 03:56
I found this on the emacs wiki [https://www.emacswiki.org/emacs/autocorrection\_abbrev\_defs](https://www.emacswiki.org/emacs/autocorrection_abbrev_defs)
bhrgunatha · 2022-05-19 08:48
Thanks for posting that link.
Having not used `abbrev-mode` before, I now have a comprehensive and universal ~~spelling~~ mis-typing correcter.
Added bonus: all those corrections are also available to `hippe-expand` too since the default `hippie-expand-try-functions-list` includes `try-expand-all-abbrevs`.
I put [the snippet you linked](https://www.emacswiki.org/emacs/autocorrection_abbrev_defs) into a file - I chose `~/emacs.d/.saves/abbrevs`
In my config, I added these 3 lines:
(setq abbrev-file-name (expand-file-name ".saves/abbrevs" user-emacs-directory)
(setq-default abbrev-mode t) ; abbrev-mode in all buffers
(use-package hippie-exp
:bind (([remap dabbrev-expand] . hippie-expand)))
azfrak · 2022-05-19 12:05
thanks for sharing this, I have never used abbrev or hippie expand before (didnt even know they existed), but is definitely something I am going to try out now :)
karthink · 2022-05-19 12:20
> Emacs intentionally overlaps things, because your needs are different depending on what you want to do.
That's imputing foresight or design to a process that isn't there. I doubt that the overlap is intentional. I think the principle that writing fresh code is more enjoyable than updating or modifying old code is at play here. Users just write libraries to suit their exact needs, leading to a lot of unintentional overlap with existing features. A few of these libraries end up in Emacs core. The fact that the completion code spans three decades (skeleteon was written in 1993) and generations of users doesn't help.
Some wide-spanning efforts like native comp or the ongoing treesitter integration don't fit this model, but all completion code except the CAPF API certainly seems to.
JDRiverRun · 2022-05-20 01:24
I tend to think of two categories of completion/expansion:
1. **I know exactly what I want, but it's such a chore to type out.** A good example might be org-mode src blocks. Here I reach for a template-style *abbrev*/*snippet package*. Small plug for [tempel](https://github.com/minad/tempel), which reimagines tempo. Some modern lsp servers even include smart template expansion with "fields" you can hop around between (ya-snippet is good at this). There are lots of "libraries" of useful expansion templates for various modes for many of these tools.
2. **I kind-of-sort-of know what I'm typing, but I'd like to see a list to confirm.** Was that `doFunction` or `do_function`? Here you want a *completion system*, which can be in-buffer, in the mini-buffer or in a special buffer. The sources of completion candidates are... up to you. Fancy things like completion candidates from know-it-all LSP servers, simple things like filenames, useful things like the emacs internal symbol list, etc. I favor emacs-standard "completion-at-point-functions" (aka CAPFs) since they cover most everything, and recommend trying [corfu](https://github.com/minad/corfu) as a replacement for the default UI.
There's no bright line between these two. You can mix and match tools endlessly. Some present you with a list of choices. Others just insert "the next match" and let you keep cycling through. I actually tend to "launch" my template-expansion *from completion*. Just one fewer thing to remember, plus it's hard to remember all those template names. I even stuff dabbrev results into the completion list in some modes. One stop shopping.
I will say it would be better if there were a single standard for template expansion, rather than... *many.* That's part of the reason I think using CAPFs for completion makes sense.
deltille · 2022-05-20 06:48
Thanks for the thoughtful reply. This really takes apart the vague 'overlap' I got a sense for but couldn't put my finger on.
You got my attention re: yasnippet with tooling for fields and jumping around them. Do other packages have something like this that you know of (and if so is it as well-implemented?)
Also thanks for mentioning "CAPF" as an abbreviation-- this seems to be a useful keyword to search. (like when I figured out what "DWIM" meant...)
JDRiverRun · 2022-05-20 15:07
I know Tempo/Tempel also have fields you can hop with M-}, but ya-snippet seems to reign there and have lots of flexibility, like out of order field navigation. Tempel exposes a Standard CAPF so you can trivially access it via your favorite completion system. And it’s an 8x smaller package, which I value (similar with corfu vs. company).