elisp: File Name Expansion

 
 24.8.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 name 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.  (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 the combined file name before the first slash is
      ‘~’, it expands to the value of the ‘HOME’ environment variable
      (usually your home directory).  If the part before the first slash
      is ‘~USER’ and if USER is a valid login name, it expands to USER’s
      home 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 ‘/’.
 
      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’.  SeeTruenames.
 
  -- 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 name, 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.