Endless Parentheses

Ramblings on productivity and technical subjects.

profile for Malabarba on Stack Exchange

A quick guide to directory-local (or project-specific) variables

One of the questions we get most often about CIDER is “can I configure X on a per-project basis?”. Occasionally, you find someone suggesting (or even implementing) some sophisticated configurable variable trying to account for multiple simultaneous use-cases. Fortunately that’s one effort we don’t need to make. Emacs already has that built-in in the form of directory-local variables (dir-local for short).

As the name implies, dir-local variable values (can) apply to all files inside a given directory (also applying recursively to its sub-directories), though you can also restrict them by major-mode or by subdirectory. To configure it:

  1. Invoke M-x add-dir-local-variable.
  2. This will prompt you for a major-mode, then a variable name, and finally a variable value.
  3. Finally, it will drop you in a (newly-created) file called .dir-locals.el in the current directory. Just save this file and you’re done!

By doing this, you have configured the given variable to always have the provided value anywhere inside the current directory, so make sure you’re at the root of your project when you call the command. If you use Projectile, there’s the projectile-edit-dir-locals command for doing just that.

Also worth noting:

  • If you type nil for the major-mode, it applies to all major-modes.
  • There is (of course) tab-completion in the variable-name prompt.
  • If you answer eval for the variable name, it will prompt you for a lisp expression, instead of a value. This expression will be saved and will be evaluated every time a file is visited.
  • After doing this, call revert-buffer on any previously-open files to apply the new value.

Update 21 Jul 2016

It’s worth mentioning that Joel McCracken posted a similar quick guide a few years ago. Some of the information is the same, but some is complementary, so you might want to have a look.

comments powered by Disqus