vfclists · 2022-04-12 17:10
I am setting some values in `.dir-locals.el` and I want to reference some location in some subdirectories without including the the whole path leading to the `.dir-locals.el`.
I am sure there is and I may have used it before and forgotten about it.
Will some please refresh my mind?
TheFrenchPoulp · 2022-04-12 17:28
Are you looking for `project-root`?
vfclists · 2022-04-12 17:40
I don't think it is `project-root`.
It is a reference to the file which is currently executing.
I configuring Python project directories and the `.dir-locals.el` must reference some standard directories in the project tree without my having to specify the root of the project which is where `.dir-locals.el` itself is located.
deltille · 2022-04-12 18:59
(default-directory)?
Might have to do some contortionism with (with-current-buffer) for it to work as intended, but it's the first thing that comes to mind.
Phil-Hudson · 2022-04-12 19:09
Could you explain a little more what you mean by "the executing file" and "the currently executing file" please?
podtatranec · 2022-04-12 19:40
So I did a bit of searching around and the only thing I found was `load-file-name` variable which gets only set during loading of the file.
But you could set a local "copy" of that and it might be enough? Something like:
```
(setq-local local-module-path load-file-name)
(defun print-cur-file()
(message "%s" local-module-path))
```
If you put that in say `/tmp/testlib.el` and then do:
```
(load-library "/tmp/testlib.el")
(print-cur-file)
```
It seems to do what I'd expect you wanted. But ... I feel there will be other caveats here :-)
vfclists · 2022-04-12 21:24
I am setting some project paths in a `.dir-locals.el` where the `.dir-locals.el` is located at the root of the project. So to reference paths which are under the project root's directory there should be a variable or function that can set some path variables simply by adding the directory of the `.dir-locals.el` file to the rest of the path.
That way if the whole project directory is moved around, the variables set in `dir-locals.el` automatically adjust to the new location.
Illiamen · 2022-04-13 02:30
Maybe you are interested in the function `expand-file-name` (see [File Name Expansion](https://www.gnu.org/software/emacs/manual/html_node/elisp/File-Name-Expansion.html))? You could use the function `project-root` on the current project for the directory in the expansion. Directory-local variables can be any arbitrary lisp expression using the `eval` symbol (see [Specifying File Variables](https://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-File-Variables.html)). That way, the expansion would be evaluated each time.
dcharness · 2022-04-13 06:31
Maybe `dir-locals-find-file` is what you want?
(dir-locals-find-file FILE)
Find the directory-local variables for FILE.
This searches upward in the directory tree from FILE.
It stops at the first directory that has been registered in
‘dir-locals-directory-cache’ or contains a ‘dir-locals-file’.
----8<----
This function returns either:
- nil (no directory local variables found),
- the matching entry from ‘dir-locals-directory-cache’ (a list),
- or the full path to the directory (a string) containing at
least one ‘dir-locals-file’ in the case of no valid cache
entry.
So something like the following would get you the path leading to the `.dir-locals.el` (or `nil` if not found):
(let ((found (dir-locals-find-file default-directory)))
(or (car-safe found) found))
Use inside an eval like `(eval . (setq-local dir-locals-directory ...))` in the `.dir-locals.el` itself to capture the value in a buffer-local variable.
Or calculate when needed, either evaluated in a buffer visiting something in that project (and so its `default-directory` would be set) or by substituting a filename in the project for `default-directory` in the expression.