Emacs can be configured on a per-file, directory, or mode basis using file or directory local settings. This involves a special comment at the top or bottom of the file, or in a .dir-locals.el
file.
File local variables
These can be set in a special comments (sometimes referred to as a “prop” line, or “mode line” in vim parlance) at the top of the file:
;; -*- mode: emacs-lisp; lexical-binding: t; -*-
Or a commented block at the bottom of the file:
;; Local Variables:
;; mode: org-mode
;; indent-tabs-mode: t
;; tab-width: 4
;; eval: (flycheck-mode -1)
;; eval: (add-hook 'after-save-hook #'org-babel-execute-buffer t t)
;; End:
Rather than hand-write these, use these commands instead:
M-x add-file-local-variable
-
M-x add-file-local-variable-prop-line
andM-x copy-dir-locals-to-file-locals-prop-line
Directory or project local variables
A .dir-locals.el
file applies its settings to any Emacs buffer opened within its parent or any sub-directory. Use it to configure Emacs on a per-mode or file basis, or to apply settings to all buffers. For example:
((nil (indent-tabs-mode . t)
(tab-width . 4))
(go-mode (eval . (flycheck-mode -1)))
(org-mode (buffer-read-only . t))
("src/" (tab-width . 8))
("src/some/file.txt" (fill-column . 100))
-
((nil (indent-tabs-mode . t) (tab-width . 4))
This sets
indent-tabs-mode
tot
andtab-width
to4
in all buffers opened in this directory (or any sub-directory). -
(go-mode (eval . (flycheck-mode -1))) (org-mode (buffer-read-only . t))
This disables
flycheck-mode
in anygo-mode
buffer opened in this or any sub-directory, and setsbuffer-read-only
tot
in anyorg-mode
buffer. -
("src/" (tab-width . 8))
These settings can apply to any file in
src/
(recursive). -
("src/some/file.txt" (fill-column . 100))
And this only applies to a single file, regardless of mode.
Rather than hand-write this file, use these commands instead:
-
M-x add-dir-local-variable
(targets the.dir-locals.el
in the currect directory) -
M-x projectile-edit-dir-locals
(targets the.dir-locals.el
in the root of your current project)
Security and local variables
Emacs will prompt you before it sets any variables or evaluates any code you haven’t personally declared as “safe”, but how do you do that? Either:
-
By adding
(VAR . VAL)
tosafe-local-variables-values
whereVAR
is the name of the variable andVAL
is a safe value for it to have. e.g.(add-to-list 'safe-local-variables-values '(flycheck-disabled-checkers . (emacs-lisp-checkdoc)))
-
safe-local-eval-forms
is similar; it’s a list of lisp forms that are safe to be evaluated from local variables. e.g.(add-to-list 'safe-local-eval-forms '(add-hook 'before-save-hook #'delete-trailing-whitespace nil t))
-
Alternatively, you can declare any value for a variable as safe with:
(put 'SYMBOL 'safe-local-variable t)
Or, at least, any value that satisfies a predicate:
;; `SYMBOL' can only be set to a string value. (put 'SYMBOL 'safe-local-variable 'stringp)
There is another option, but I wouldn’t recommend it:
;; Dangerous! Allows any setting or code to be run, no questions asked!
(setq enable-local-variables :all)
If you only want to suppress the prompts and auto-ignore unsafe variables, use:
(setq enable-local-variables :safe)