I'm trying to expand abbreviations with some additional characters, so I'm using the regexp option on an abbrev-table to try and add these characters. The expression I used was found on this tutorial http://ergoemacs.org/emacs/elisp_abbrev.html and is "\\([_-*0-9A-Za-z]+\\)"
when using this expression I can only use expands that match a single character. I've tried several different variations on the regexp and can't get anything to work. Any suggestions of what is going on would be great?
-
Are you sure that in your code the regular expression has double backslashes? (In your post you have single backslashes).– wvxvwCommented Jun 14, 2017 at 12:22
-
@wvxvw Yes, they have double backslashes (copy and pasting the tutorial entirely doesn't work). Sorry about the missing backslashes they'd been escaped here, and I didn't notice.– James SnookCommented Jun 14, 2017 at 12:24
3 Answers
The regexp used in the tutorial will match one or more characters, and its stopping when it matches one. You need to force it to match back to the previous word break. That's what the \\<
pattern does. So either of the following should work:
(abbrev-table-put xem-abbrev-table :regexp "\\<\\([_-*0-9A-Za-z]+\\)")
(abbrev-table-put xem-abbrev-table :regexp "\\<\\([_[:word:]]+\\)")
Your version, \\<\\(\\w+\\)\\W*
will ignore non-word characters between point and the previous text (that's what the terminal \\W*
is doing); my versions will only match when point is at the end of the abbrev (ie, no spaces after). If that's what you intend, you need to add that to the regexps here as well.
Ironically, the original code works as expected without defining a regexp at all, because by default the abbrev table will use the preceding word.
What's going on inside the abbrev code is that it uses looking-back
to look at what's before point in the buffer. It stops when it gets a match, which you originally observed as matching a single letter. It's possible to tell looking-back
to be greedy to get a longer match, but the abbrev code doesn't call it that way.
So the problem is not the regexps, but how they are used inside the abbrev code. The suggestion @Tyler gives is one way to do it. If what you're trying to do is set up abbrev tables for a mode as in the original example, if you are just matching words for abbrevs you can just skip specifying a regexp at all.
-
i think the tutorial used the regexp to add the _ and - symbols to the list of characters you can use in your abbrevs– TylerCommented Dec 13, 2018 at 10:54
-
Good point. Unfortunately, if that's important, the abbrev code is still getting in the way of making it work.– WinCommented Dec 14, 2018 at 16:47
From what I can tell the website where I got the regular expression from is wrong (at least for the version of emacs that I'm using (gnu emacs 25.2)). The regular expression instead has to be something like this: \\<\\(\\w+\\)\\W*
(I believe that this statement would replicate the behaviour of abbrevs when no regexp expression has been given).
From what I can tell \w
doesn't play well within []
which makes adding characters to be expanded harder than it would otherwise be.
-
4Inside
[]
,[:word:]
is like\w
, see (elisp) Char Classes.– npostavsCommented Jun 19, 2017 at 12:00