elisp: Directory Names

 
 24.8.3 Directory Names
 ----------------------
 
 A “directory name” is the name of a directory.  A directory is actually
 a kind of file, so it has a file name (called the “directory file name”,
 which is related to the directory name but not identical to it.  (This
 is not quite the same as the usual Unix terminology.)  These two
 different names for the same entity are related by a syntactic
 transformation.  On GNU and Unix systems, this is simple: a directory
 name ends in a slash, whereas the directory file name lacks that slash.
 On MS-DOS the relationship is more complicated.
 
    The difference between directory name and directory file name is
 subtle but crucial.  When an Emacs variable or function argument is
 described as being a directory name, a directory file name is not
 acceptable.  When ‘file-name-directory’ returns a string, that is always
 a directory name.
 
    The following two functions convert between directory names and
 directory file names.  They do nothing special with environment variable
 substitutions such as ‘$HOME’, and the constructs ‘~’, ‘.’ and ‘..’.
 
  -- Function: file-name-as-directory filename
      This function returns a string representing FILENAME in a form that
      the operating system will interpret as the name of a directory (a
      directory name).  On most systems, this means appending a slash to
      the string (if it does not already end in one).
 
           (file-name-as-directory "~rms/lewis")
                ⇒ "~rms/lewis/"
 
  -- Function: directory-name-p filename
      This function returns non-‘nil’ if FILENAME ends with a directory
      separator character.  This is the forward slash ‘/’ on Unix and GNU
      systems; MS-Windows and MS-DOS recognize both the forward slash and
      the backslash ‘\’ as directory separators.
 
  -- Function: directory-file-name dirname
      This function returns a string representing DIRNAME in a form that
      the operating system will interpret as the name of a file (a
      directory file name).  On most systems, this means removing the
      final slash (or backslash) from the string.
 
           (directory-file-name "~lewis/")
                ⇒ "~lewis"
 
    Given a directory name, you can combine it with a relative file name
 using ‘concat’:
 
      (concat DIRNAME RELFILE)
 
 Be sure to verify that the file name is relative before doing that.  If
 you use an absolute file name, the results could be syntactically
 invalid or refer to the wrong file.
 
    If you want to use a directory file name in making such a
 combination, you must first convert it to a directory name using
 ‘file-name-as-directory’:
 
      (concat (file-name-as-directory DIRFILE) RELFILE)
 
 Don’t try concatenating a slash by hand, as in
 
      ;;; Wrong!
      (concat DIRFILE "/" RELFILE)
 
 because this is not portable.  Always use ‘file-name-as-directory’.
 
    To avoid the issues mentioned above, or if the DIRNAME value might be
 nil (for example, from an element of ‘load-path’), use:
 
      (expand-file-name RELFILE DIRNAME)
 
    To convert a directory name to its abbreviation, use this function:
 
  -- Function: abbreviate-file-name filename
      This function returns an abbreviated form of FILENAME.  It applies
      the abbreviations specified in ‘directory-abbrev-alist’ (SeeFile
      Aliases (emacs)File Aliases.), then substitutes ‘~’ for the user’s
      home directory if the argument names a file in the home directory
      or one of its subdirectories.  If the home directory is a root
      directory, it is not replaced with ‘~’, because this does not make
      the result shorter on many systems.
 
      You can use this function for directory names and for file names,
      because it recognizes abbreviations even as part of the name.