如何在emacs目录变量文件中访问当前目录的路径?

Chr*_*s R 20 emacs elisp

根据Emacs文档,目录变量适用于包含文件的目录下的所有.dir-locals.el文件.

如何在该文件中将变量设置为包含该文件的完整路径?例如:

((nil . ((indent-tabs-mode . t)
          (my-project-path **THIS_DIRECTORY**))))
Run Code Online (Sandbox Code Playgroud)

nbe*_*rth 11

我问自己同样的问题,并没有在网上找到解决方案,所以我认为这个答案可能有所帮助.实际上,事实证明我们可以重dir-locals-find-file用来获取包含该.dir-locals.el文件的目录.所以这就是我找到的,例如,设置一个专用于整个目录的aspell个人字典:

((nil . ((eval . (setq ispell-personal-dictionary
                       (expand-file-name
                        ".aspell_words"
                        (file-name-directory
                         (let ((d (dir-locals-find-file ".")))
                           (if (stringp d) d (car d))))))))))
Run Code Online (Sandbox Code Playgroud)

此外,似乎条目按照指定的顺序进行评估,因此以下代码应该起作用:

((nil . ((eval . (set (make-local-variable 'my-project-path)
                      (file-name-directory
                       (let ((d (dir-locals-find-file ".")))
                         (if (stringp d) d (car d))))))
         (eval . (message "Project directory set to `%s'." my-project-path)))))
Run Code Online (Sandbox Code Playgroud)

Emacs会抱怨不安全的局部变量(由于eval构造),但仍然可以永久地标记它是安全的.

  • 我的缺点:我的快速测试有偏差,因为“.dir-locals.el”都是相同的。因此,确实,“dir-locals-find-file”总是返回 Emacs 遇到的第一个“.dir-locals.el”(最接近访问的文件)。我承认这个限制。 (2认同)
  • 好吧,我现在实际上“查看”了代码,结果发现在任何情况下,只有一个“.dir-locals.el”会被查询到任何特定的缓冲区。所以我认为手册需要澄清这一点...... (2认同)
  • 换句话说:**我的批评是基于对 `.dir-locals.el` 工作原理的误解**。 (2认同)

slu*_*slu 6

我认为(file-name-directory (or load-file-name buffer-file-name))应该给你目录路径.

请参见http://xahlee.org/emacs/elisp_idioms_batch.html

编辑:除非它不会,因为任何eval表达式都是在其变量被黑客攻击的缓冲区的上下文中计算的.

  • 是的,但是......据我所知,emacs实际上并没有评估.dir-locals中的表单; 相反,它只是读取它们,并将值分配给命名变量......并且值必须是常量.我希望我错了,但我怀疑我没办法. (2认同)

paj*_*to0 2

如果对OP或其他人来说仍然很重要,我建议您创建一个函数来生成文件.dir-locals.el。然后我们可以写这样的东西:

(let ((path default-directory)
      file)
  (setq file (format "%s/.dir-locals.el" path))
  (with-temp-buffer
    (insert (format "((nil . ((indent-tabs-mode . t)
          (my-project-path \"%s\"))))" path))
    (when (file-writable-p file)
      (write-region (point-min)
                    (point-max)
                    file))))
Run Code Online (Sandbox Code Playgroud)

在项目主目录中执行。