Emacs .dir-locals.el - setting key bindings
Asked Answered
Z

1

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?

Zimmer answered 2/11, 2013 at 2:2 Comment(2)
Your question is too general. What's the language, number of projects and number of different behaviors for each project? Give some examples.Geronto
@Geronto ... sorry, but you simply don't understand the question, there's nothing general about it.Zimmer
P
10

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

e.g. https://mcmap.net/q/1278438/-how-can-i-move-php-mode-settings-from-emacs-to-dir-locals-el

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.

Pigskin answered 2/11, 2013 at 9:14 Comment(5)
so, essentially .. a .dir-locals.el containing : ((eval . (progn BODY))) ? (I'll give it a try)Zimmer
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).Pigskin
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?Zimmer
((nil . ((eval . (progn (message "hello")))))) works just fine for me (as does a global-set-key).Pigskin
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.Zimmer

© 2022 - 2024 — McMap. All rights reserved.