I have a list with the pattern (list (cons key-binding1 file-name1) (cons key-binding2 file-name2)...)

(setq hot-list
       (cons "H-g" "~/Documents/goals")
       (cons "H-h" "~/Documents/things")
       (cons "H-1" "~/Files/C/abc.c")
       (cons "H-2" "~/Files/C/abc2.c")
       (cons "H-3" "~/Files/C/abc3.c")
       (cons "H-e" "~/.emacs") ))

Now I want to bind each key-binding to the respective file. But I don't want to do write a (global-set-key) form for each file. Instead I use (dolist) :

(dolist (i hot-list)
  (global-set-key (kbd (car i))
          (list `lambda (list i)
            `(find-file (cdr ,i)))))

When I try "H-1", it gives an error: " Invalid function: (lambda (("H-1" . "~/Files/C/abc.c")) (interactive) (find-file (cdr ("H-1" . "~/Files/C/abc.c")))) "

Although I don't find anything wrong with my code. (global-set-key) accept a command. And the test: (commandp (lambda (("H-1" . "~/Files/C/abc.c")) (interactive) (find-file (cdr ("H-1" . "~/Files/C/abc.c"))))) returns t

How should I do this?


2 Answers 2


It's usually easier to construct code to evaluate this way using backquote. A backquoted list is like a quoted list, except that forms preceded by a comma are evaluated and the result interpolated into the list. So, for your example, you might do this:

(dolist (i hot-list)
  (global-set-key (kbd (car i))
                 `(lambda ()
                    (find-file ,(cdr i)))))

In defining the functions, the only thing that needs to be evaluated is the (cdr i). In practice, I find that the easiest way to write something like this is to write the lambda (or other expression) that you want, then figure out which small parts need to be evaluated to get the result.


You may be interested in Emacs' built-in register feature with which you can bind a letter to a file location (among other things):

(cl-loop for (key file-name) in '((?g "~/Documents/goals")
                                  (?h "~/Documents/things")
                                  (?1 "~/Documents/C/abc.c")
                                  (?2 "~/Documents/C/abc2.c")
                                  (?3 "~/Documents/C/abc3.c")
                                  (?e "~/.emacs"))
         do (set-register key `(file . ,file-name)))

Then jump to your .emacs file with C-x r j e.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.