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-lineandM-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-modetotandtab-widthto4in 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-modein anygo-modebuffer opened in this or any sub-directory, and setsbuffer-read-onlytotin anyorg-modebuffer. -
("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.elin the currect directory) -
M-x projectile-edit-dir-locals(targets the.dir-locals.elin 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-valueswhereVARis the name of the variable andVALis 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-formsis 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)