reddit / emacs

Does emacs have a function for getting the directory containing executing file?

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.