I would like to set the major mode for a file as you would using file-local variables
Local Variables:
mode: text
End:
but in .dir-locals.el
in order not to “pollute” the file in question. Is this possible?
Emacs Stack Exchange is a question and answer site for those using, extending or developing Emacs. It only takes a minute to sign up.
Sign up to join this communityIt's possible to specify a string instead of a mode, but this only works for subdirectories. So I'll use nil
instead to match all modes, then the eval
key to change the major mode conditionally:
((nil
(eval
(lambda ()
(when (string= (file-name-nondirectory buffer-file-name)
"file-name.extension")
(my-mode))))))
A downside of this approach is that the eval
key is unsafe, so you'll need to confirm the variable permanently for this to have an effect.
(error "Lisp nesting exceeds ‘max-lisp-eval-depth’")
because it keeps trying to apply the mode in a loop.
The following .dir-locals.el
works just fine for me to set the major mode of all files in a directory to shell-script-mode
:
((nil . ((mode . shell-script))))
The obvious downside is that you can't specify the major mode for only a given subset of files in the directory.
Addendum: Amusingly, it also has the side effect of setting the major mode of .dir-locals.el
itself to shell-script-mode
.
Addendum 2: Rather more amusingly, it also has the side effect of setting the major mode of Dired buffers to shell-script-mode
, making it impossible to open any (as an error is thrown during the initialization).
For me accepted answer give error:
(error "Lisp nesting exceeds ‘max-lisp-eval-depth’")
Because it tried to apply the mode recursively, when it open a file it executed a mode and if the mode was changed it executed the eval again recursively:
For me this works:
((nil (eval
(lambda ()
(when (and (string-match-p "\\.js\\'" buffer-file-name)
(not (string= (major-mode) "rjsx-mode")))
(rjsx-mode))))))
For rjsx-mode that I wanted to apply for all js file in project directory.
eval
pseudo-variable is the only way to handle it in a.dir-locals.el
file. For custom elisp, you might just look at usingauto-mode-alist
to match the filename regexp (you can useregexp-quote
to create patterns for verbatim string values, if necessary).