25.9.4 Functions that Expand Filenames
Expanding a file name means converting a relative file name to an absolute one. Since this is done relative to a default directory, you must specify the default directory as well as the file name to be expanded. It also involves expanding abbreviations like ~/
(see abbreviate-file-name), and eliminating redundancies like ./
and name/../
.
function
expand-file-name filename \&optional directoryβ
This function converts filename
to an absolute file name. If directory
is supplied, it is the default directory to start with if filename
is relative and does not start with β~
β. (The value of directory
should itself be an absolute directory name or directory file name; it may start with β~
β.) Otherwise, the current bufferβs value of default-directory
is used. For example:
(expand-file-name "foo")
β "/xcssun/users/rms/lewis/foo"
(expand-file-name "../foo")
β "/xcssun/users/rms/foo"
(expand-file-name "foo" "/usr/spool/")
β "/usr/spool/foo"
If the part of filename
before the first slash is β~
β, it expands to your home directory, which is typically specified by the value of the HOME
environment variable (see General Variables in The GNU Emacs Manual). If the part before the first slash is β~user
β and if user
is a valid login name, it expands to user
βs home directory. If you do not want this expansion for a relative filename
that might begin with a literal β~
β, you can use (concat (file-name-as-directory directory) filename)
instead of (expand-file-name filename directory)
.
Filenames containing β.
β or β..
β are simplified to their canonical form:
(expand-file-name "bar/../foo")
β "/xcssun/users/rms/lewis/foo"
In some cases, a leading β..
β component can remain in the output:
(expand-file-name "../home" "/")
β "/../home"
This is for the sake of filesystems that have the concept of a superroot above the root directory /
. On other filesystems, /../
is interpreted exactly the same as /
.
Expanding .
or the empty string returns the default directory:
(expand-file-name "." "/usr/spool/")
β "/usr/spool"
(expand-file-name "" "/usr/spool/")
β "/usr/spool"
Note that expand-file-name
does not expand environment variables; only substitute-in-file-name
does that:
(expand-file-name "$HOME/foo")
β "/xcssun/users/rms/lewis/$HOME/foo"
Note also that expand-file-name
does not follow symbolic links at any level. This results in a difference between the way file-truename
and expand-file-name
treat β..
β. Assuming that β/tmp/bar
β is a symbolic link to the directory β/tmp/foo/bar
β we get:
(file-truename "/tmp/bar/../myfile")
β "/tmp/foo/myfile"
(expand-file-name "/tmp/bar/../myfile")
β "/tmp/myfile"
If you may need to follow symbolic links preceding β..
β, you should make sure to call file-truename
without prior direct or indirect calls to expand-file-name
. See Truenames.
variable
default-directoryβ
The value of this buffer-local variable is the default directory for the current buffer. It should be an absolute directory name; it may start with β~
β. This variable is buffer-local in every buffer.
expand-file-name
uses the default directory when its second argument is nil
.
The value is always a string ending with a slash.
default-directory
β "/user/lewis/manual/"
function
substitute-in-file-name filenameβ
This function replaces environment variable references in filename
with the environment variable values. Following standard Unix shell syntax, β$
β is the prefix to substitute an environment variable value. If the input contains β$$
β, that is converted to β$
β; this gives the user a way to quote a β$
β.
The environment variable name is the series of alphanumeric characters (including underscores) that follow the β$
β. If the character following the β$
β is a β{
β, then the variable name is everything up to the matching β}
β.
Calling substitute-in-file-name
on output produced by substitute-in-file-name
tends to give incorrect results. For instance, use of β$$
β to quote a single β$
β wonβt work properly, and β$
β in an environment variableβs value could lead to repeated substitution. Therefore, programs that call this function and put the output where it will be passed to this function need to double all β$
β characters to prevent subsequent incorrect results.
Here we assume that the environment variable HOME
, which holds the userβs home directory, has value β/xcssun/users/rms
β.
(substitute-in-file-name "$HOME/foo")
β "/xcssun/users/rms/foo"
After substitution, if a β~
β or a β/
β appears immediately after another β/
β, the function discards everything before it (up through the immediately preceding β/
β).
(substitute-in-file-name "bar/~/foo")
β "~/foo"
(substitute-in-file-name "/usr/local/$HOME/foo")
β "/xcssun/users/rms/foo"
;; /usr/local/ has been discarded.
Sometimes, it is not desired to expand file names. In such cases, the file name can be quoted to suppress the expansion, and to handle the file name literally. Quoting happens by prefixing the file name with β/:
β.
macro
file-name-quote nameβ
This macro adds the quotation prefix β/:
β to the file name
. For a local file name
, it prefixes name
with β/:
β. If name
is a remote file name, the local part of name
(see Magic File Names) is quoted. If name
is already a quoted file name, name
is returned unchanged.
(substitute-in-file-name (file-name-quote "bar/~/foo"))
β "/:bar/~/foo"
(substitute-in-file-name (file-name-quote "/ssh:host:bar/~/foo"))
β "/ssh:host:/:bar/~/foo"
The macro cannot be used to suppress file name handlers from magic file names (see Magic File Names).
macro
file-name-unquote nameβ
This macro removes the quotation prefix β/:
β from the file name
, if any. If name
is a remote file name, the local part of name
is unquoted.
macro
file-name-quoted-p nameβ
This macro returns non-nil
, when name
is quoted with the prefix β/:
β. If name
is a remote file name, the local part of name
is checked.