How can I configure a hook with a lambda? (Saving parameters to use in lambdas)

Viewed 317

I am currently trying to set up a C++ hook for setting shortcuts to compile different projects and I have the following code:

(defun configure-proj (proj key)
    (add-hook 'c++-mode-hook
              (function (lambda ()
                          (local-set-key (kbd (concatenate 'string key " u")) (lambda () (compile-unit-tests proj)))
                          (local-set-key (kbd (concatenate 'string key " d")) (lambda () (compile-debug proj)))
                          (local-set-key (kbd (concatenate 'string key " r")) (lambda () (compile-balanced proj)))
                          (local-set-key (kbd (concatenate 'string key " i")) (lambda () (compile-func-interactive proj "balanced" "11")))
                          (local-set-key (kbd (concatenate 'string key " c")) 'clean-all)))))

(configure-proj "Proj name" "<f4>")

The error states that there is a File mode specification error: (void-variable key). I know that the error in my code is that the key parameter from configure-proj is not being copied when the hook is being created, but I don't know how to fix it. Can anyone help?

Edit: Forgot to show how I run configure-proj.

2 Answers

As explained by coredump, the problem is that your config file is not using lexical scoping. So add -*- lexical-binding:t -*- somewhere on the first line of the file.

If you don't wish to enable lexical-binding for the whole library, then you could alternatively use a workaround like:

(defun configure-proj (proj key)
  (add-hook 'c++-mode-hook
            `(lambda ()
               (local-set-key ,(kbd (concatenate 'string key " u")) (lambda () (interactive) (compile-unit-tests proj)))
               (local-set-key ,(kbd (concatenate 'string key " d")) (lambda () (interactive) (compile-debug proj)))
               (local-set-key ,(kbd (concatenate 'string key " r")) (lambda () (interactive) (compile-balanced proj)))
               (local-set-key ,(kbd (concatenate 'string key " i")) (lambda () (interactive) (compile-func-interactive proj "balanced" "11")))
               (local-set-key ,(kbd (concatenate 'string key " c")) 'clean-all))))
Related