.dir-locals.el
文件的目录下的所有文件。在该文件中,如何将变量设置为包含文件的完整路径?例如:
((nil . ((indent-tabs-mode . t)
(my-project-path **THIS_DIRECTORY**))))
.dir-locals.el
文件的目录下的所有文件。((nil . ((indent-tabs-mode . t)
(my-project-path **THIS_DIRECTORY**))))
我曾经问过自己同样的问题,但在网上没有找到解决方案,所以我认为这个答案可能会有所帮助。实际上,我们可以重复使用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))))))))))
此外,似乎输入项按照指定的顺序进行评估,因此以下代码应该可行:
((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)))))
使用eval
构造会导致Emacs抱怨不安全的本地变量,但仍然可以永久标记为安全。
更新:自 Emacs ≥ 26.3(也可能适用于早期版本),似乎需要使用 (dir-locals-find-file "./")
而不是 (dir-locals-find-file ".")
。
.dir-locals.el
都是相同的。所以确实,dir-locals-find-file
总是返回Emacs遇到的第一个.dir-locals.el
(最接近访问的文件)。我承认这种限制。 - nberth.dir-locals.el
会被查询关于任何特定缓冲区。所以我认为手册需要澄清这一点... - SamB.dir-locals.el
的工作方式的误解。 - SamBispell-personal-dictionary
的示例,将其也设置为make-local-variable
是否有意义呢?因为默认情况下它不是缓冲区本地的,所以现在的示例会改变全局绑定,影响到dir-locals目录之外的地方。 - undefined((nil . ((eval . (setq cmake-ide-build-dir
(concat (projectile-project-root) "/build-make"))
))))
我认为(file-name-directory (or load-file-name buffer-file-name))
应该给出目录路径。
参见链接
编辑:但它不会,因为任何eval
表达式都是在被篡改变量的缓冲区的上下文中评估的。
((nil . ((did-it-work (file-name-directory (or load-file-name buffer-file-name))))))
不过,我得到了一个"unsafe-variable"警告。 - offby1我发现Emacs自带的locate-dominating-file
程序很有用,可以检索已知文件的当前目录。下面的示例将guix-directory
变量设置为包含.dir-locals.el
文件的项目的最顶层目录。
((nil . ((eval . (setq guix-directory
(locate-dominating-file default-directory
".dir-locals.el"))))))
虽然该设置依赖于eval
,不是一个安全的safe.dir-locals.el设置,但它可以完成任务。
.dir-locals.el
文件,那么这将给出错误的答案,对吗?因此,即使代码在哪个文件中,如果/a/.dir-locals.el
和/a/b/.dir-locals.el
都存在,则guix-directory
将为/a
。 - Troy Daniels如果仍然有影响,我建议您创建一个函数来生成.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))))
应在项目主目录下执行。
hack-local-variables
是处理所有本地变量的主要函数,并调用 hack-dir-local-variables
处理 .dir-locals.el
文件(如果您没有使用该文件,则为目录本地类变量)。
建立目录的代码不是在其自己的函数中隔离的,因此我们将不得不将其复制到一个新函数中(这是从 GNU Emacs 24.0.95.1 中获取的):
(defun my-dir-locals-dir ()
"Return the directory local variables directory.
Code taken from `hack-dir-local-variables'."
(let ((variables-file (dir-locals-find-file (or (buffer-file-name) default-directory)))
(dir-name nil))
(cond
((stringp variables-file)
(setq dir-name (file-name-directory variables-file)))
((consp variables-file)
(setq dir-name (nth 0 variables-file))))
dir-name))
.dir-locals.el
文件中... - SamB(defun get-working-directory ()
(getenv "PWD))
(shell-command "pwd")
将会返回当前正在编辑的缓冲区所对应的文件所在的目录。