Подтвердить что ты не робот

Как я могу получить доступ к пути к текущему каталогу в файле переменных каталога emacs?

Согласно документации Emacs, Переменные каталога применяются ко всем файлам ниже каталога, содержащего файл .dir-locals.el.

Как я могу в этом файле установить переменную в полный путь, содержащий файл? Например:

((nil . ((indent-tabs-mode . t)
          (my-project-path **THIS_DIRECTORY**))))
4b9b3361

Ответ 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"))
         ))))