Elisp: Get Script Name at Run Time, Call by Relative Path

By Xah Lee. Date: . Last updated: .

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's the difference between load-file, load, require, autoload?.

Elisp, Writing Scritpts

  1. Run Elisp Script in Shell
  2. Get Command Line Args
  3. Read File
  4. Read File Content as List
  5. Write File
  6. Print, Output
  7. Format String
  8. Walk Dir
  9. Call Shell Command
  10. Get Script Name at Run Time
Patreon me $5 patreon

Or Buy Xah Emacs Tutorial

Or buy a nice keyboard: Best Keyboard for Emacs

If you have a question, put $5 at patreon and message me.