From 85df4f6674ee49d51e8e6a7a2265daefcb3cb7d2 Mon Sep 17 00:00:00 2001 From: "Richard M. Stallman" Date: Mon, 19 Aug 2002 18:43:18 +0000 Subject: [PATCH] Move the node Relative Files before Directory Names. Show what file-name-nondirectory returns when given a directory name. Explain that abbreviate-file-name works on file names too. Explain how to combine a directory name with a relative file name with concat, and the pitfalls. Update some details. --- lispref/files.texi | 167 ++++++++++++++++++++++++++++----------------- 1 file changed, 104 insertions(+), 63 deletions(-) diff --git a/lispref/files.texi b/lispref/files.texi index eb008544f4a..35955f14b40 100644 --- a/lispref/files.texi +++ b/lispref/files.texi @@ -1384,9 +1384,9 @@ and work properly on all systems without change. @menu * File Name Components:: The directory part of a file name, and the rest. +* Relative File Names:: Some file names are relative to a current directory. * Directory Names:: A directory's name as a directory is different from its name as a file. -* Relative File Names:: Some file names are relative to a current directory. * File Name Expansion:: Converting relative file names to absolute ones. * Unique File Names:: Generating names for temporary files. * File Name Completion:: Finding the completions for a given file name. @@ -1420,10 +1420,13 @@ in Emacs omits the version number, so that version numbers in Emacs are found mostly in directory lists. @defun file-name-directory filename -This function returns the directory part of @var{filename} (or -@code{nil} if @var{filename} does not include a directory part). On -most systems, the function returns a string ending in a slash. On VMS, -it returns a string ending in one of the three characters @samp{:}, +This function returns the directory part of @var{filename}, as a +directory name (@pxref{Directory Names}), or @code{nil} if +@var{filename} does not include a directory part. + +On GNU and Unix systems, a string returned by this function always +ends in a slash. On MSDOS it can also end in a colon. On VMS, it +returns a string ending in one of the three characters @samp{:}, @samp{]}, or @samp{>}. @example @@ -1455,6 +1458,10 @@ This function returns the nondirectory part of @var{filename}. @result{} "foo" @end group @group +(file-name-nondirectory "lewis/") + @result{} "" +@end group +@group ;; @r{The following example is accurate only on VMS.} (file-name-nondirectory "[X]FOO.TMP") @result{} "FOO.TMP" @@ -1462,6 +1469,18 @@ This function returns the nondirectory part of @var{filename}. @end example @end defun +@defun file-name-extension filename &optional period +This function returns @var{filename}'s final ``extension,'' if any, +after applying @code{file-name-sans-versions} to remove any +version/backup part. It returns @code{nil} for extensionless file +names such as @file{foo}. If @var{period} is non-nil, then the +returned value includes the period that delimits the extension, and if +@var{filename} has no extension, the value is @code{""}. If the last +component of a file name begins with a @samp{.}, that @samp{.} doesn't +count as the beginning of an extension, so, for example, +@file{.emacs}'s ``extension'' is @code{nil}, not @samp{.emacs}. +@end defun + @defun file-name-sans-versions filename &optional keep-backup-version This function returns @var{filename} with any file version numbers, backup version numbers, or trailing tildes discarded. @@ -1525,16 +1544,41 @@ value of @code{?/}. @end defvar @end ignore -@defun file-name-extension filename &optional period -This function returns @var{filename}'s final ``extension,'' if any, -after applying @code{file-name-sans-versions} to remove any -version/backup part. It returns @code{nil} for extensionless file -names such as @file{foo}. If @var{period} is non-nil, then the -returned value includes the period that delimits the extension, and if -@var{filename} has no extension, the value is @code{""}. If the last -component of a file name begins with a @samp{.}, that @samp{.} doesn't -count as the beginning of an extension, so, for example, -@file{.emacs}'s ``extension'' is @code{nil}, not @samp{.emacs}. +@node Relative File Names +@subsection Absolute and Relative File Names +@cindex absolute file name +@cindex relative file name + + All the directories in the file system form a tree starting at the +root directory. A file name can specify all the directory names +starting from the root of the tree; then it is called an @dfn{absolute} +file name. Or it can specify the position of the file in the tree +relative to a default directory; then it is called a @dfn{relative} file +name. On Unix and GNU/Linux, an absolute file name starts with a slash +or a tilde (@samp{~}), and a relative one does not. On MS-DOS and +MS-Windows, an absolute file name starts with a slash or a backslash, or +with a drive specification @samp{@var{x}:/}, where @var{x} is the +@dfn{drive letter}. The rules on VMS are complicated. + +@defun file-name-absolute-p filename +This function returns @code{t} if file @var{filename} is an absolute +file name, @code{nil} otherwise. On VMS, this function understands both +Unix syntax and VMS syntax. + +@example +@group +(file-name-absolute-p "~rms/foo") + @result{} t +@end group +@group +(file-name-absolute-p "rms/foo") + @result{} nil +@end group +@group +(file-name-absolute-p "/user/rms/foo") + @result{} t +@end group +@end example @end defun @node Directory Names @@ -1543,19 +1587,20 @@ count as the beginning of an extension, so, for example, @cindex directory name @cindex file name of directory - A @dfn{directory name} is the name of a directory. A directory is a -kind of file, and it has a 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 most systems, this is simple: -a directory name ends in a slash (or backslash), whereas the directory's -name as a file lacks that slash. On VMS, the relationship is more -complicated. + A @dfn{directory name} is the name of a directory. A directory is +actually a kind of file, so it has a 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 (or +backslash), whereas the directory's name as a file lacks that slash. +On MSDOS and VMS, the relationship is more complicated. The difference between a directory name and its name as a file is subtle but crucial. When an Emacs variable or function argument is described as being a directory name, a file name of a directory is not -acceptable. +acceptable. When @code{file-name-directory} returns a string, that is +always a directory name. The following two functions convert between directory names and file names. They do nothing special with environment variable substitutions @@ -1591,6 +1636,38 @@ to @file{[X]Y.DIR.1}. @end example @end defun + Given a directory name, you can combine it with a relative file name +using @code{concat}: + +@example +(concat @var{dirname} @var{relfile}) +@end example + +@noindent +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 +@code{file-name-as-directory}: + +@example +(concat (file-name-as-directory @var{dirfile}) @var{relfile}) +@end example + +@noindent +Don't try concatenating a slash by hand, as in + +@example +;;; @r{Wrong!} +(concat @var{dirfile} "/" @var{relfile}) +@end example + +@noindent +because this is not portable. Always use +@code{file-name-as-directory}. + @cindex directory name abbreviation Directory name abbreviations are useful for directories that are normally accessed through symbolic links. Sometimes the users recognize @@ -1624,47 +1701,11 @@ and so on. To convert a directory name to its abbreviation, use this function: -@defun abbreviate-file-name dirname +@defun abbreviate-file-name filename This function applies abbreviations from @code{directory-abbrev-alist} to its argument, and substitutes @samp{~} for the user's home -directory. -@end defun - -@node Relative File Names -@subsection Absolute and Relative File Names -@cindex absolute file name -@cindex relative file name - - All the directories in the file system form a tree starting at the -root directory. A file name can specify all the directory names -starting from the root of the tree; then it is called an @dfn{absolute} -file name. Or it can specify the position of the file in the tree -relative to a default directory; then it is called a @dfn{relative} file -name. On Unix and GNU/Linux, an absolute file name starts with a slash -or a tilde (@samp{~}), and a relative one does not. On MS-DOS and -MS-Windows, an absolute file name starts with a slash or a backslash, or -with a drive specification @samp{@var{x}:/}, where @var{x} is the -@dfn{drive letter}. The rules on VMS are complicated. - -@defun file-name-absolute-p filename -This function returns @code{t} if file @var{filename} is an absolute -file name, @code{nil} otherwise. On VMS, this function understands both -Unix syntax and VMS syntax. - -@example -@group -(file-name-absolute-p "~rms/foo") - @result{} t -@end group -@group -(file-name-absolute-p "rms/foo") - @result{} nil -@end group -@group -(file-name-absolute-p "/user/rms/foo") - @result{} t -@end group -@end example +directory. You can use it for directory names and for file names, +because it recognizes abbreviations even as part of the name. @end defun @node File Name Expansion -- 2.39.5