2018-09-17 Emacs directory variables

Many people know and use Emacs file variables. I think less people know about a similar concept of directory variables.

Basically, the idea is that some variable should be specific to every single file in a directory (and its subdirectories), like it were defined (as a file-local variable) in every of its files. Alternatively, a directory variable may be specific only to files which are opened in certain major mode. Directory-local variables are defined in a file called .dir-locals.el (or .dir-locals-2.el, which see).

A caveat which I was only able to find through experimentation is that apparently, the eval “keyword” (described in the docs for file variables), while claimed by the manual to work the same way in the case of directory variables, in fact does not. While in the context of file variables it accepts a Lisp expression, its directory version needs a function (or a lambda expression). I asked about this on the mailing list. (Edit: it seems I was wrong here, see the linked thread. I wrote a follow-up about this.)

One use-case for those (apart from the obvious case of specifying some kind of behavior to all files – or all files of some mode – even the newly created, empty ones) is when for some reason you don’t want to put file-local variables in some file. For instance, that file may be under version control, and other people on your team (or some kind of broken software) do not like the Emacsy stuff you put into it. One caveat is that directory variables cannot be specified for a single file. No wonder, since this is what file variables are for – but read on.

Interestingly, there is a way of specifying directory variables without putting the .dir-locals.el file in the directory in question (this is useful if e.g. you don’t have write permissions in that directory) – see the docs for the details – but it seems that you can’t do the same thing with file-local variables. This is not a serious limitation, though, because in such a case you may always write a function which examines the name of the visited file (to be found in the buffer-file-name variable) and sets the appropriate variables and put it into find-file-hook. Such a function will even be called after processing file-local variables, so you can override (or examine) them with it. (A quick experiment showed that file-local variables are processed after the directory-local ones, so functions in find-file-hook have access to all of them.)

Be sure to at least skim the documentation on file- and directory-local variables – the details of how to specify them are a bit complicated, although there do exist some helper commands which can create them for you.

CategoryEnglish, CategoryBlog, CategoryEmacs