0

I'm new to Emacs and Common Lisp. I'm wanting to use abbrev-mode to replace standard Common Lisp function names with aliases that I have created. So for example, I would like to replace the following standard functions with my aliases:

  1. equalp
  2. alpha-char-p
  3. char<
  4. char/=

Following the example here, I defined my abbrev table in the global-abbrev-table definition in the abbrev_defs.el file in the folder ~\emacs.d\.

However, I discovered that it does not replace connected multi-words or words that contains non-alphanumeric characters (all except the first in my examples). Reading various answers to questions here like this, things I need to do to fix this are:

  1. Create a regexp that will define abbrev boundaries. I want the regex to match any sequences of characters except white spaces, parentheses and quotes, so I came up with this regexp \\([^\n\t '()\"]*\\), which I tested using M-x re-builder inside Emacs.
  2. Modify the syntax table with the new regexp by adding the function abbrev-table-put. I came up with this: (abbrev-table-put global-abbrev-table :regexp "\\([^\n\t '()\"]*\\)" )

After adding that sexp at the end of my init file, abbrev-mode is now broken. It no longer replaces any word, but the default abbrev-mode behavior comes back if I comment out that sexp. Adding the sexp to either file abbrev_defs.el or the end of file abbrev.el doesn't work.

Question: What's the right fix here? Is my regex wrong? Where should I put that sexp? Any other errors I'm doing?

1

For part 1, you need to test your regexp when searching backward, and there you'll see that Emacs will always end up matching just the empty string (which is the nearest match). So you probably want a regexp like

"\\(?:^\\|[\t '()\"]\\)\\([^\n\t '()\"]*\\)"

so as to force Emacs to look further back all the way to the first char which is not part of the abbrev (even "\\(?:^\\|[\t '()\"]\\)\\(.*\\)" might work).

Nitpick for point 2: you're not "adding the function abbrev-table-put", which would mean defining that function. Instead you're adding a call to that function.

  • Thank you. I tested your answer and it works on most cases, except for "char<" and "char/=". – Noble_Bright_Life Mar 1 '18 at 8:22
  • I also tried "\(?:^\\|[\t '()\"]\)\([^\n\t '()\"]*\)\(?:$\\|[\t '()\"]\)" but did not work. Also, how do I test a regexp when searching backward, or forward inside emacs? – Noble_Bright_Life Mar 1 '18 at 17:57
  • You can do M-: (re-search-backward "\\(?:^\\|[\t '()\"]\\)\\([^\n\t '()\"]*\\)") RET. Maybe for char< you're hitting a problem in Emacs. If so, this is the wrong place to discuss it, better report it as a bug. – Stefan Mar 1 '18 at 20:55
  • Thanks, I will accept your answer, as it could probably be a bug. Cheers. – Noble_Bright_Life Mar 2 '18 at 3:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.