I would like to set the major mode for a file as you would using file-local variables
Local Variables: mode: text End:
.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 community
It'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.
.dir-locals.el works just fine for me to set the major mode of all files in a directory to
((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
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.