W jaki sposób ścieżki plików są mapowane do podkatalogów w .dir-locals.el?

10

Podoba mi się pomysł .dir-locals.el. Mam własny .dir-locals.elplik w katalogu domowym, który powinien ustawić wszystkie zmienne dla katalogów / plików, które otwieram, chyba że znajduje się .dir-locals.elbliżej katalogu, w którym otwieram plik. Jednak pomimo rozpoznania pliku zmienne katalogów dla podkatalogów nie są stosowane do otwartych plików.

To jest moje ~/.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))))

Kiedy otwieram plik, ~/dev/test/test.czmienna indent-tabs-modejest ustawiona na ti c-basic-offsetma wartość 8.

(describe-variable 'c-basic-offset)w pliku mówi mi, że jest on ustawiony na 8od ~/.dir-locals.el.

(describe-variable 'indent-tabs-mode)w tym pliku mówi, że jego wartość ( t) jest właśnie w stanie domyślnym.

Czy mogę w jakiś sposób osiągnąć pożądane zachowanie? Co ja robię źle? W jaki sposób ścieżki plików są mapowane do podkatalogów ~/.dir-locals.el?

Edytować:

Jak zasugerował Jonathan , próbowałem też:

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

a nawet co add-dir-local-variabledodał:

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

Niestety, żadna z nich też nie działa.

nert
źródło

Odpowiedzi:

7

W oparciu o dokumentację w podręczniku brakuje części specyfikacji podkatalogu.

Przykładowy plik .dir-locals.el

Z podręcznika z komentarzami do podkreślenia / wyjaśnienia

(;; 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"))))))

Poprawiony plik .dir-locals.el

Jest to oparte na założeniu, że subdirspecyfikacje mają dotyczyć wszystkich trybów. Jeśli tylko chcesz je zastosować do c-modezastąpienia nilze c-modew trybie specyfikacją.

(;; 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))))
Jonathan Leech-Pepin
źródło
Źle zrozumiałem ten przykład w dokumencie, dziękuję za wyjaśnienie. Jednak wypróbowałem twoją wersję (kopiuj-wklej) i nadal działa w ten sam sposób. Nawet z „emacs -Q”. Mile widziane są również sugestie dotyczące debugowania.
nert
Próbowałem również za pomocą add-dir-local-variablei dodano ~/.dir-locals.eljeszcze krótszym składni niż kiedyś w pytaniu: ("dev/test" (indent-tabs-mode)). Nadal jednak nie działa.
nert
Myślę, że w mojej wersji brakuje niektórych parenów, dodałem je (przeglądając je w porównaniu do próbki i powinny być dodatkowe w pobliżu specyfikacji subdir("dev/test" . ((spec1 ...) (spec2 ...) ...))
Jonathan Leech-Pepin
Tak, to działa! Jedynym problemem jest teraz to, że zmienne trybu mają pierwszeństwo przed zmiennymi katalogowymi, ale ponieważ są one powiązane tylko z trybem c, mogę ustawić je za pomocą setq-default podczas inicjalizacji. Dziękuję Ci bardzo.
nert
1
To jest dziwne. Zrobiłem dzisiaj test przy użyciu ((org-mode . ((org-indent-mode . t))) ("subdir" . ((nil . ((org-indent-mode . nil))))i działało poprawnie (monit o ustawienie lokalnego var na zero). Może spróbuj umieścić te root nad specyfikacjami sub-dir na liście, możliwe, że ustawi je na ostatnią znalezioną wartość.
Jonathan Leech-Pepin