6

I'm not sure this is possible, but I'd like to setup some project specific key bindings by using .dir-locals.el

Of course .dir-locals.el has to contain a special list of settings, so I can't do:

(global-set-key [24 down] 'move-text-down)

Is there any way I can inject a lambda to run arbitrary code or some other way to set key bindings in .dir-locals.el?

ocodo
  • 29,401
  • 18
  • 105
  • 117
  • Your question is too general. What's the language, number of projects and number of different behaviors for each project? Give some examples. – abo-abo Nov 02 '13 at 08:30
  • 2
    @abo-abo ... sorry, but you simply don't understand the question, there's nothing general about it. – ocodo Nov 02 '13 at 09:17

1 Answers1

10

The eval pseudo-variable enables you to specify arbitrary elisp for evaluation with your local variables.

e.g. https://stackoverflow.com/a/7340962/324105

See EmacsWiki for more details.

Note that this is not a particularly useful mechanism for setting key bindings, as every buffer using the keymap in question will be affected. You would probably be better off using the dir-local config to enable a minor mode with the specific keymap for that project. Alternatively, you might adapt this approach to file-local bindings (but a minor mode would be nicer).

That being said...

A fairly minimal form is ((nil . ((eval . (progn BODY))))) with BODY being the expressions to be evaluated. Of course if BODY is only a single expression, you do not need progn.

The following therefore displays a message when you visit any file (under the directory in question):

((nil . ((eval . (message "hello")))))

The car of each list in the dir-locals form is generally a major mode symbol, or nil (as in the above example) in which case the settings apply in any major mode.

The car can also specify a sub-directory string, in which case the cdr is another dir-locals form with settings applicable to that sub-dir.

Community
  • 1
  • 1
phils
  • 71,335
  • 11
  • 153
  • 198
  • so, essentially .. a .dir-locals.el containing : `((eval . (progn BODY)))` ? (I'll give it a try) – ocodo Nov 02 '13 at 09:18
  • 1
    At minimum the format would be `((nil . ((eval . (progn BODY)))))` -- the car of each list in the form is a (major mode) symbol, or `nil` (as in this example) indicating settings which apply in *any* major mode. (The car can also specify a (sub-directory) string, and then settings applicable to that sub-dir). – phils Nov 02 '13 at 09:36
  • Thanks @phils, the emacs request to mark the `.dir-locals.el` as safe is displayed, however the code inside the `progn` body doesn't appear to execute. I added a `(message "hello")` to check in *Messages* and isn't displayed. Tried with a lambda instead, also didn't execute. Any more ideas? – ocodo Nov 02 '13 at 09:43
  • `((nil . ((eval . (progn (message "hello"))))))` works just fine for me (as does a `global-set-key`). – phils Nov 02 '13 at 12:55
  • Works fine now, I trashed the broken one, so not sure what I screwed up, but definitely a chair to keyboard interface issue. I'll paste in your working example into your answer for future reference. – ocodo Nov 02 '13 at 12:59