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?.

If you have a question, put $5 at patreon and message me on xah discord.
Or support me by Buy Xah Emacs Tutorial

Emacs Tutorial

Emacs Init

Emacs Keys

ELisp

ELisp Examples

ELisp Write Major Mode


ELisp

Basics

Basic Functions

Writing Command

Writing Script

Lisp Data Structure

Lisp Symbol

Elisp Misc