Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Emacs Lisp and non-deterministic regexes

Tags:

regex

emacs

elisp

I've been spending too much time lately trying to debug some auto-complete-mode functionality in Emacs, this function appears to be non-deterministic and has left me utterly confused.

 (re-search-backward "\\(\\sw\\|\\s_\\|\\s\\.\\|\\s\\\\|[#@|]\\)\\=")

The command is called in a while loop, searching backwards from the current point to find the full "word" that should be autocompleted. For reference, the actual code.

A bit of background and my investigations

I have been trying to setup autocompletion for Javascript, using slime to connect to a Node.js backend.

Autocomplete inside a Slime REPL connected to a Node.js backend is perfect,

enter image description here

Autocomplete inside a js2-mode buffer, connected to Slime, is failing to look up completions from slime. In this image you can see it falling back to the words already in the buffer.

enter image description here

I've tracked this down to Slime's slime-beginning-of-symbol function.

Assume that I'm trying to complete fs.ch where fs has been required and is in scope already, the point is located on after the h character.

In the slime repl buffer the beginning function moves the point all of the way back until it hits whitespace and matches fs.ch.

In the js2-mode buffer the beginning function moves the point only to the dot character and matches only ch.

Reproducing the problem

I've been testing this by evaling (re-search-backward "\\(\\sw\\|\\s_\\|\\s\\.\\|\\s\\\\|[#@|]\\)\\=") repeatedly in various buffers. For all examples, the point starts at the end of the line and moves backwards until the search fails.

  • In the scratch buffer fs.ch the point ends on the c.
  • In the slime repl fs.ch the point ends on the f.
  • In the js2-mode buffer fs.ch the point ends on the c.
  • In an emacs-lisp-mode buffer fs.ch the point ends on the f.

I have no idea why this is happening

I'm going to assume that there's something in these modes that either sets or unsets a global regex var that then has this effect, but so far I've been unable to find or implicate anything.

I even tracked this down to the emacs c code, but at that point realised that I was in completely over my head and decided to ask for help.

Help?

like image 679
Dan Midwood Avatar asked Nov 11 '22 14:11

Dan Midwood


1 Answers

You should replace \\s\\. with \\s. in your regexp.

like image 86
Stefan Avatar answered Nov 15 '22 11:11

Stefan