Saving match data in-between Elisp evals22 Feb 2015
This is a new feature I've added recently to lispy that's useful when debugging regex-related code.
The gist of it is that the match data is a single global object in Emacs.
So if you call
string-match with your C-x C-e, there's no
guarantee that e.g.
match-beginning will return the proper thing with another C-x C-e,
since any package running in your Emacs could mess with the match data (packages that use timers
or post-command hooks etc.).
After getting annoyed by this a few times, I've finally added a
fail-safe to e (
lispy-eval) and p
lispy-eval-other-window). Here's how it looks like:
(defvar lispy-eval-match-data nil) (defun lispy--eval-elisp-form (form lexical) "Eval FORM and return its value. If LEXICAL is t, evaluate using lexical scoping. Restore and save `lispy-eval-match-data' appropriately, so that no other packages disturb the match data." (let (val) (fset '\, #'identity) (set-match-data lispy-eval-match-data) (setq val (eval form lexical)) (setq lispy-eval-match-data (match-data)) (fset '\, nil) val))
There's also a little dance of ignoring comma operators in the rare
case when I want to eval inside a backquoted list. The two
functions that you can take away from this exercise are
set-match-data which appropriately return and store a list of
integers. Keeping the string separate from the regex match is a neat
way to improve performance.