I am having a problem working with closures. I hope I can explain this clearly. When I try to start a compilation I typically do it like this:
(let ((dir (get-dir)) (model-root root) (default-directory dir) (compilation-environment env) (compilation-buffer-name-function (lambda (mode) (format "*%s %s %s*" (f-filename model-root) (downcase mode) (f-filename dir))))) (compilation-start "some command" 'foo-mode))
But, I want to use a custom function instead of
compilation-start. This custom function will add commands to a queue instead of running them right away. However that means I need to capture the dynamically scoped variables from the
let binding. This works fine except for when I get the value of
compilation-buffer-name-function, it evaluates to a closure like this.
(closure ((model-root . "/root/path/") (dir . "/some/directory/") t) (mode) (format "%s %s %s" (f-filename model-root) (downcase mode) (f-filename dir)))
The problem is, that form is not a valid form for evaluation. It gives me the error
let: Symbol’s function definition is void: closure. I am aware the
closure is not a real function and that is merely an implementation detail that is exposed to the user.
Here is my code to call
compilation-start when the command is ready (this is the code that is giving the error).
(cl-loop for command in compilation-queued-commands with bindings = (car command) with args = (cdr command) do (eval `(let ,bindings (apply 'compilation-start ',(-flatten args)))))
This is the code I am using to capture the dynamic variables
(defvar compilation-dynamic-closures '(compilation-buffer-name-function compilation-environment default-directory)) (add-to-list 'compilation-queued-commands (list (mapcar (lambda (var) (list var (symbol-value var))) compilation-dynamic-closures) compilation-args))
So my question is, how can I capture and replay this closure later?