Como os caminhos de arquivo são mapeados para subdiretórios no .dir-locals.el?

10

Eu gosto da ideia de .dir-locals.el. Eu tenho meu próprio .dir-locals.elarquivo no meu diretório pessoal que deve definir todas as variáveis ​​para os diretórios / arquivos que abro, a menos que exista .dir-locals.elmais perto do diretório em que abro o arquivo. No entanto, mesmo que o arquivo seja reconhecido, as variáveis ​​de diretório para subdiretórios não são aplicado aos arquivos abertos.

Este é o meu ~/.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))))

Quando abro o arquivo, ~/dev/test/test.ca variável indent-tabs-modeé definida como te c-basic-offseté 8.

(describe-variable 'c-basic-offset)nesse arquivo diz que está definido para 8from ~/.dir-locals.el.

(describe-variable 'indent-tabs-mode)nesse arquivo diz que seu valor ( t) está no estado padrão.

Posso de alguma forma alcançar o comportamento desejado? O que estou fazendo de errado? Como os caminhos de arquivo são mapeados para os subdiretórios ~/.dir-locals.el?

Editar:

Como Jonathan sugeriu , eu também tentei:

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

e até o que add-dir-local-variableacrescentou:

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

Infelizmente, nenhum deles funciona.

nert
fonte

Respostas:

7

Com base na documentação do manual , está faltando uma parte da especificação do subdiretório.

Amostra .dir-locals.el

Do manual com comentários para ênfase / esclarecimento

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

Corrigido .dir-locals.el

Isso se baseia na suposição de que você deseja que as subdirespecificações se apliquem a todos os modos. Se você só quer que eles se aplicam a c-modesubstituir nilcom c-modeno modo de especificação.

(;; 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
fonte
Entendi mal esse exemplo na documentação, obrigado por esclarecer isso. No entanto, tentei sua versão (copiar e colar) e ela ainda se comporta da mesma maneira. Mesmo com 'emacs -Q'. Sugestões para depuração também são bem-vindas.
Nert 28/05
Eu também tentei usar add-dir-local-variablee foi adicionado a ~/.dir-locals.elcom a sintaxe ainda mais curto do que eu costumava na questão: ("dev/test" (indent-tabs-mode)). Ainda não funciona, no entanto.
Nert 28/05
Acho que a minha versão foi faltando alguns parênteses, eu adicionei-los em (olhando-o em comparação com a amostra e deveria ter havido uns extras em torno das especificações Subdir("dev/test" . ((spec1 ...) (spec2 ...) ...))
Jonathan Sanguessuga-Pepin
Sim, isso funciona! O único problema agora é que as variáveis ​​de modo têm precedência sobre as do diretório, mas como estão relacionadas apenas ao modo c, posso defini-las com setq-default durante o init. Muito obrigado.
nert 29/05
11
Isso é estranho. Hoje fiz um teste usando ((org-mode . ((org-indent-mode . t))) ("subdir" . ((nil . ((org-indent-mode . nil))))e funcionou corretamente (solicitado a definir var local como nulo). Talvez tente colocar as raízes acima das especificações do subdiretório na lista, é possível que ele defina o último valor encontrado.
Jonathan Leech-Pepin