Как я могу получить доступ к пути к текущему каталогу в файле переменных каталога emacs?
Согласно документации Emacs, Переменные каталога применяются ко всем файлам ниже каталога, содержащего файл .dir-locals.el
.
Как я могу в этом файле установить переменную в полный путь, содержащий файл? Например:
((nil . ((indent-tabs-mode . t)
(my-project-path **THIS_DIRECTORY**))))
Ответы
Ответ 1
Я задал себе тот же вопрос и не нашел решения в Интернете, поэтому я думаю, что этот ответ может помочь. На самом деле, оказывается, мы можем повторно использовать 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)))))
Emacs будет жаловаться на небезопасные локальные переменные (из-за конструкции eval
), но все же можно постоянно помечать его безопасно.
Ответ 2
Я думаю, (file-name-directory (or load-file-name buffer-file-name))
должен указать путь к каталогу.
См. http://xahlee.org/emacs/elisp_idioms_batch.html
Изменить: кроме этого не будет, потому что любые выражения eval
оцениваются в контексте буфера, чьи переменные взломаются.
Ответ 3
В случае, если это все еще имеет значение, для 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))))
для выполнения в домашнем каталоге проекта.
Ответ 4
hack-local-variables
является основной функцией обработки всех локальных переменных и вызывает hack-dir-local-variables
для работы с файлом .dir-locals.el
(или локальной переменной класса dir, если вы не используете этот файл).
Код для создания каталога не изолирован в своей собственной функции, поэтому нам придется скопировать его в новую функцию (это из 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))
Ответ 5
Если вы работаете над * nix, вы можете получить рабочий каталог с помощью следующего кода elisp,
(defun get-working-directory ()
(getenv "PWD))
Btw, я должен упомянуть, что (shell-command "pwd")
приведет к каталогу, где файл (который соответствует тому, который вы сейчас редактируете).
Ответ 6
В моем случае я хотел найти файл, который был относительно моего текущего рабочего каталога для моего репозитория, и файл .dir-locals.el был проверен в корне, поэтому файл "local" в .dir -locals.el также был файлом "local" для корня проекта.
pajato0 ответ выше работал в некоторых случаях, но он также нарушал другие режимы (например, magit). Я обошел проблему, используя функцию projectile
package projectile-project-root
, чтобы найти мой базовый путь для меня:
((nil . ((eval . (setq cmake-ide-build-dir
(concat (projectile-project-root) "/build-make"))
))))