To get the current file’s path in Emacs Lisp, use load-file-name. This only works when a file is loaded, so running it directly in Emacs will produce an empty value, as no file is being loaded when the variable is accessed:
(message (format "load-file-name: %s" load-file-name))
load-file-name: nil
However, with the expression above saved to a file named load-file-name.el, the file name is printed to the messages buffer when it’s loaded through load-file:
(load-file "load-file-name.el")
load-file-name: /Users/jeff/notes/load-file-name.el
It also works in batch mode, when the file is loaded with the --load
flag:
emacs --batch --load load-file-name.el
load-file-name: /Users/jeff/notes/load-file-name.el
Remembering the file name for later
Trying to access the load-file-name variable later once again results in an empty value. By the time the function is called, the file is done loading, and the load-file-name variable is emptied. This means putting it in a function and calling that from outside of the file won’t work:
(defun jk/load-file-name () (format "load-file-name: %s" load-file-name))
Loading the file and then evaluating the function produces a empty value:
emacs --batch --load load-file-name-fun.el --eval "(message (jk/load-file-name))"
load-file-name: nil
Instead, bind the value to a variable name when the file loads, then use the variable instead of calling load-file-name directly:
(setq jk/load-file-name load-file-name) (defun jk/load-file-name () (format "load-file-name: %s" jk/load-file-name))
With the variable in place, loading the file and then evaluating the function returns the file’s name, as the function is simply returning the variable’s previously set value:
emacs --batch --load load-file-name-set.el --eval "(message (jk/load-file-name))"
load-file-name: /Users/jeff/notes/load-file-name-set.el