The problem is that Emacs Lisp variable bindings are dynamic by default. That is, when a function is evaluated, bound variables are looked up not in the environment where the function was defined, but in the environment where the function was called.
Emacs 24 or later supports lexical binding (that is, the function sees the variables that were bound around the function definition) natively, but since it alters the semantics of existing code you need to enable it explicitly. Usually this is done by adding a file local variable setting to the first line of the .el
file:
;; -*- lexical-binding: t; -*-
Another alternative is to use lexical-let
from the cl
library. This works in earlier Emacs versions as well. Note that in this way you explicitly specify which variables should have lexical binding, so code such as (lexical-let ((foo foo)) ...)
is not uncommon — foo
is an existing variable which needs to be "carried over" into the function.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…