10

I like the idea of .dir-locals.el. I have my own .dir-locals.el file in my home directory that should set all the variables for directories/files that I open unless there is .dir-locals.el closer to the directory I open the file in. However, even though the file is recognized, directory variables for subdirectories are not applied to opened files.

This is my ~/.dir-locals.el:

(("dev/school" .
  ((indent-tabs-mode . nil)
   (c-basic-offset . 4)))
 ("dev/test" .
  ((indent-tabs-mode . nil)
   (c-basic-offset . 4)))
 (c-mode .
  ((c-file-style . "linux")
   (c-basic-offset . 8))))

When I open file ~/dev/test/test.c the variable indent-tabs-mode is set to t and c-basic-offset is 8.

(describe-variable 'c-basic-offset) in that file tells me it is set to 8 from ~/.dir-locals.el.

(describe-variable 'indent-tabs-mode) in that file says it's value (t) is just in its default state.

Can I somehow achieve the desired behaviour? What am I doing wrong? How are file paths mapped to subdirectories in ~/.dir-locals.el?

Edit:

As Jonathan suggested, I also tried:

(;; dev/school subdir
 ("dev/school" .
  ;; dev/school specification for all modes
  (nil . ((indent-tabs-mode . nil)
          (c-basic-offset . 4)))))

and even what add-dir-local-variable added:

(("dev/school"
  (indent-tabs-mode)
  (c-basic-offset . 4)))

Unfortunately, none of those work either.

7

Based on the documentation in the manual, you are missing a portion of the subdir specification.

Sample .dir-locals.el

From the manual with comments for emphasis/clarification

(;; Dir settings
 (nil . ((indent-tabs-mode . t)
         (fill-column . 80)))
 (c-mode . ((c-file-style . "BSD")
            (subdirs . nil)))
 ;; Subdir specification
 ("src/imported" .
  ;; Subdir settings
  ((nil . ((change-log-default-name
            . "ChangeLog.local"))))))

Corrected .dir-locals.el

This is based on the assumption that you want the subdir specifications to apply to all modes. If you only want them to apply to c-mode replace nil with c-mode in the mode-specification.

(;; dev/school subdir
 ("dev/school" .
  ;; dev/school specification for all modes
  ((nil . ((indent-tabs-mode . nil)
           (c-basic-offset . 4)))))
 ;; dev/test subdir
 ("dev/test" .
  ;; dev/test specification for all modes
  ((nil . ((indent-tabs-mode . nil)
           (c-basic-offset . 4)))))
 ;; c-mode specification for dir + subdirs
 (c-mode .
  ((c-file-style . "linux")
   (c-basic-offset . 8))))
  • I misunderstood that example in the documentaiton, thank you for clarifying that. However, I tried your version (copy-paste) and it still behaves the same way. Even with 'emacs -Q'. Suggestions for debugging are welcomed, too. – nert May 28 '15 at 20:22
  • I also tried using add-dir-local-variable and it was added to ~/.dir-locals.el with even shorter syntax than I used in the question: ("dev/test" (indent-tabs-mode)). Still doesn't work, though. – nert May 28 '15 at 20:36
  • I think my version was missing some parens, I've added them in (looking it over compared to the sample and there should have been extra ones around the subdir specs ("dev/test" . ((spec1 ...) (spec2 ...) ...)) – Jonathan Leech-Pepin May 29 '15 at 13:33
  • Yes, that works! The only problem now is that the mode variables take precedence over the directory ones, but since they are only related to c-mode I can set them with setq-default during init. Thank you very much. – nert May 29 '15 at 14:24
  • 1
    That's strange. I did a test today using ((org-mode . ((org-indent-mode . t))) ("subdir" . ((nil . ((org-indent-mode . nil)))) and it worked properly (prompted to set local var to nil). Maybe try putting the root ones above the sub-dir specifications within the list, it's possible it sets it to the last value found. – Jonathan Leech-Pepin May 29 '15 at 14:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.