Elisp: File Path Functions

By Xah Lee. Date: . Last updated: .

Get Current Dir

default-directory

A Buffer Local Variable. Value is typically the dir path of the current buffer.

💡 TIP: You should not modify this variable.

Get File Path Parts

file-name-directory

return the dir part.

(file-name-directory "a/b/c")
"a/b/"

(file-name-directory "a/b/c/")
"a/b/c/"
file-name-nondirectory

return the file name part san dir.

(file-name-nondirectory "a/b/c")
;; "c"

(file-name-nondirectory "a/b/c/")
;; ""

(file-name-nondirectory "abc")
;; "abc"
file-name-extension

(file-name-extension FILENAME &optional PERIOD)

return the file name extension.

(file-name-extension "~/cat.jpg")
;; "jpg"
file-name-sans-extension

remove the file name extension.

(file-name-sans-extension "~/cat.tar.gz")
;; "~/cat.tar"

Relative Path, Full Path

file-relative-name

(file-relative-name FILENAME &optional DIRECTORY)

return relative path, with respect to default-directory or DIRECTORY

(file-relative-name "~/b/cat.jpg" "~/")
;; "b/cat.jpg"
expand-file-name

(expand-file-name NAME &optional DEFAULT-DIRECTORY)

return the full path, from relative path.

(expand-file-name "test.el")
;; sample output
;; "c:/Users/xah/.emacs.d/temp/test.el"
file-truename

(file-truename FILENAME)

Return the true name, by chasing symbolic links, also some canonize the name. Result is full path.

  • Relative path is resolved to full path.
  • Symbolic links are chased.
  • On Microsoft Windows, it'll also lowercase the drive letter.
  • Backslash is changed to slash.
;; file-truename examples

;; on windows, capital driver letter is lowercased
(file-truename "C:/Users/a/b.txt")
;; "c:/Users/a/b.txt"

;; file existance is not changed

;; on windows, backslash becomes slash
(file-truename "C:\\Users\\a\\b.txt")
;; "c:/Users/a/b.txt"

;; relative path are expanded with respect to value of default-directory
(file-truename "b.txt")
;; "c:/Users/xah/.emacs.d/temp/c.txt"

Join File Paths

file-name-with-extension

(file-name-with-extension FILENAME EXTENSION)

join a file name with extension.

(file-name-with-extension "ff" "jpg")
;; "ff.jpg"

(file-name-with-extension "ff" ".jpg")
;; "ff.jpg"
file-name-concat

(file-name-concat DIRECTORY &rest COMPONENTS)

join file paths, and making sure there is one and only one slash between parts.

(file-name-concat "~/a")
;; "~/a"

(file-name-concat "~/a" "b")
;; "~/a/b"

(file-name-concat "~/a/" "b")
;; "~/a/b"

;; the second arg should not start with slash
(file-name-concat "~/a/" "/b")
;; "~/a//b"

Directory Path

directory-name-p

return true if it ends in a slash.

(directory-name-p "test.el")
file-name-as-directory

basically add a slash to the end, if none already. In emacs lisp, dir path should end in a slash.

(file-name-as-directory "~/.emacs.d/temp")
;; "~/.emacs.d/temp/"

Misc

substitute-in-file-name

Substitute environment variables, such as $HOME

Others

Reference

Elisp, File, Buffer