Next: , Previous: Relative File Names, Up: File Names


25.8.4 Functions that Expand Filenames

Expansion of 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 name as well as the file name to be expanded. Expansion also simplifies file names by eliminating redundancies such as ./ 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. (The value of directory should itself be an absolute directory 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"
          (expand-file-name "$HOME/foo")
               => "/xcssun/users/rms/lewis/$HOME/foo"
     

Filenames containing ‘.’ or ‘..’ are simplified to their canonical form:

          (expand-file-name "bar/../foo")
               => "/xcssun/users/rms/lewis/foo"
     

Note that expand-file-name does not expand environment variables; only substitute-in-file-name does that.

— Function: file-relative-name filename &optional directory

This function does the inverse of expansion—it tries to return a relative name that is equivalent to filename when interpreted relative to directory. If directory is omitted or nil, it defaults to the current buffer's default directory.

On some operating systems, an absolute file name begins with a device name. On such systems, filename has no relative equivalent based on directory if they start with two different device names. In this case, file-relative-name returns filename in absolute form.

          (file-relative-name "/foo/bar" "/foo/")
               => "bar"
          (file-relative-name "/foo/bar" "/hack/")
               => "../foo/bar"
     
— 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.

Aside from VMS, 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 variables references in filename with the environment variable values. Following standard Unix shell syntax, ‘$’ is the prefix to substitute an environment variable value.

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 ‘}’.

Here we assume that the environment variable HOME, which holds the user's home directory name, has value ‘/xcssun/users/rms’.

          (substitute-in-file-name "$HOME/foo")
               => "/xcssun/users/rms/foo"
     

After substitution, if a ‘~’ or a ‘/’ appears following a ‘/’, everything before the following ‘/’ is discarded:

          (substitute-in-file-name "bar/~/foo")
               => "~/foo"
          (substitute-in-file-name "/usr/local/$HOME/foo")
               => "/xcssun/users/rms/foo"
               ;; /usr/local/ has been discarded.
     

On VMS, ‘$’ substitution is not done, so this function does nothing on VMS except discard superfluous initial components as shown above.