Emacs Lisp: Get Script Name at Run Time, Call by Relative Path
Get Current Script's Name Programmatically
;; get the current elisp script's name at run time (or load-file-name buffer-file-name)
Explanation: If user ran your script by
eval-buffer
, then
load-file-name's value would be nil. So, using both {load-file-name,
buffer-file-name
} is a good way to get the script name regardless whether the script is executed by load or eval buffer.
If you want the directory, call file-name-directory
on the result.
Get Full Path from Relative Path at Run Time
If you have file A, that calls load
to load a file at B, and B calls load
on file C using a relative path, then Emacs will complain about unable to find C. Because, emacs does not switch current directory with load
.
The following function solves this problem.
(defun xah-get-fullpath (@file-relative-path) "Return the full path of *file-relative-path, relative to caller's file location. Example: If you have this line (xah-get-fullpath \"../xyz.el\") in the file at /home/joe/emacs/emacs_lib.el then the return value is /home/joe/xyz.el Regardless how or where emacs_lib.el is called. This function solves 2 problems. ① If you have file A, that calls the `load' on a file at B, and B calls `load' on file C using a relative path, then Emacs will complain about unable to find C. Because, emacs does not switch current directory with `load'. To solve this problem, when your code only knows the relative path of another file C, you can use the variable `load-file-name' to get the current file's full path, then use that with the relative path to get a full path of the file you are interested. ② To know the current file's full path, emacs has 2 ways: `load-file-name' and `buffer-file-name'. If the file is loaded by `load', then `load-file-name' works but `buffer-file-name' doesn't. If the file is called by `eval-buffer', then `load-file-name' is nil. You want to be able to get the current file's full path regardless the file is run by `load' or interactively by `eval-buffer'." (concat (file-name-directory (or load-file-name buffer-file-name)) @file-relative-path) )
See also: What is the difference between load-file, load, require, autoload?.