Emacs Lisp: File Path Functions

By Xah Lee. Date: . Last updated: .

Here's the most useful functions on file path.

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 "~/xyz.txt")
;; "~/"
file-name-nondirectory
return the file name part san dir.
(file-name-nondirectory "~/xyz.txt")
;; "xyz.txt"
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.
;; 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

Emacs Lisp File/Buffer