diff --git a/core/io/pathnames/pathnames-docs.factor b/core/io/pathnames/pathnames-docs.factor index db8a0d46ec..cc65d5da5d 100644 --- a/core/io/pathnames/pathnames-docs.factor +++ b/core/io/pathnames/pathnames-docs.factor @@ -1,5 +1,5 @@ USING: help.markup help.syntax io.backend io.files io.directories strings -sequences ; +sequences io.pathnames.private ; IN: io.pathnames HELP: path-separator? @@ -7,7 +7,7 @@ HELP: path-separator? { $description "Tests if the code point is a platform-specific path separator." } { $examples "On Unix:" - { $example "USING: io.pathnames prettyprint ;" "CHAR: / path-separator? ." "t" } + { $example "USING: io.pathnames.private prettyprint ;" "CHAR: / path-separator? ." "t" } } ; HELP: parent-directory @@ -46,12 +46,24 @@ HELP: path-components { $description "Splits a pathname on the " { $link path-separator } " into its its component strings." } ; HELP: append-path -{ $values { "str1" "a string" } { "str2" "a string" } { "str" "a string" } } -{ $description "Appends " { $snippet "str1" } " and " { $snippet "str2" } " to form a pathname." } ; +{ $values { "path1" "a pathname string" } { "path2" "a pathname string" } { "path" "a pathname string" } } +{ $description "Appends " { $snippet "path1" } " and " { $snippet "path2" } " to form a pathname." } +{ $examples + { $unchecked-example """USING: io.pathnames prettyprint ; +"first" "second.txt" append-path .""" +"first/second.txt" + } +} ; HELP: prepend-path -{ $values { "str1" "a string" } { "str2" "a string" } { "str" "a string" } } -{ $description "Appends " { $snippet "str2" } " and " { $snippet "str1" } " to form a pathname." } ; +{ $values { "path1" "a pathname string" } { "path2" "a pathname string" } { "path" "a pathname string" } } +{ $description "Appends " { $snippet "path2" } " and " { $snippet "path1" } " to form a pathname." } +{ $examples + { $unchecked-example """USING: io.pathnames prettyprint ; +"second.txt" "first" prepend-path .""" +"first/second.txt" + } +} ; { append-path prepend-path } related-words @@ -77,7 +89,7 @@ HELP: pathname { $class-description "Class of path name objects. Path name objects can be created by calling " { $link } "." } ; HELP: normalize-path -{ $values { "str" "a pathname string" } { "newstr" "a new pathname string" } } +{ $values { "string" "a pathname string" } { "string'" "a new pathname string" } } { $description "Prepends the " { $link current-directory } " to the pathname, resolves a " { $snippet "resource:" } " prefix, if present, and performs any platform-specific pathname normalization." } { $notes "High-level words, such as " { $link } " and " { $link delete-file } " call this word for you. It only needs to be called directly when passing pathnames to C functions or external processes. This is because Factor does not use the operating system's notion of a current directory, and instead maintains its own dynamically-scoped " { $link current-directory } " variable." } { $examples @@ -90,7 +102,8 @@ HELP: normalize-path HELP: canonicalize-path { $values { "path" "a pathname string" } { "path'" "a new pathname string" } } -{ $description "Returns an canonical name for a path. The canonical name is an absolute path containing no symlinks." } ; +{ $description "Outputs a path where none of the path components are symlinks. This word is useful for determining the actual path on disk where a file is stored; the root of this absolute path is a mount point in the file-system." } +{ $notes "Most code should not need to call this word except in very special circumstances. One use case is finding the actual file-system on which a file is stored." } ; HELP: { $values { "string" "a pathname string" } { "pathname" pathname } } @@ -98,20 +111,28 @@ HELP: HELP: home { $values { "dir" string } } -{ $description "Outputs the user's home directory." } ; +{ $description "Outputs the user's home directory." } +{ $examples + { $unchecked-example "USING: io.pathnames prettyprint ;" + "home ." + "/home/factor-user" + } +} ; -ARTICLE: "io.pathnames" "Pathname manipulation" -"Pathname manipulation:" +ARTICLE: "io.pathnames" "Pathnames" +"Pathnames are objects that contain a string representing the path to a file on disk. Pathnames are cross-platform; Windows accepts both forward and backward slashes as directory separators and new separators are added as a forward slash on all platforms. Clicking a pathname object in the UI brings up the file in one of the supported editors, but otherwise, pathnames and strings are interchangeable. See " { $link "editor" } " for more details." $nl +"Pathname introspection:" { $subsections parent-directory file-name file-stem file-extension - last-path-separator path-components +} +"Appending pathnames:" +{ $subsections prepend-path append-path - canonicalize-path } "Pathname presentations:" { $subsections @@ -120,7 +141,11 @@ ARTICLE: "io.pathnames" "Pathname manipulation" } "Literal pathnames:" { $subsections POSTPONE: P" } -"Low-level word:" -{ $subsections normalize-path } ; +"Low-level words:" +{ $subsections + normalize-path + (normalize-path) + canonicalize-path +} ; ABOUT: "io.pathnames" diff --git a/core/io/pathnames/pathnames-tests.factor b/core/io/pathnames/pathnames-tests.factor index c3e419e60d..7a98a47f42 100644 --- a/core/io/pathnames/pathnames-tests.factor +++ b/core/io/pathnames/pathnames-tests.factor @@ -1,6 +1,6 @@ USING: io.pathnames io.files.temp io.directories continuations math io.files.private kernel -namespaces tools.test ; +namespaces tools.test io.pathnames.private ; IN: io.pathnames.tests [ "passwd" ] [ "/etc/passwd" file-name ] unit-test diff --git a/core/io/pathnames/pathnames.factor b/core/io/pathnames/pathnames.factor index 6a49ed5797..4a38d2e4aa 100644 --- a/core/io/pathnames/pathnames.factor +++ b/core/io/pathnames/pathnames.factor @@ -6,14 +6,16 @@ IN: io.pathnames SYMBOL: current-directory + + ERROR: no-parent-directory path ; : parent-directory ( path -- parent ) @@ -61,8 +65,6 @@ ERROR: no-parent-directory path ; [ nip ] } cond ; -PRIVATE> - : windows-absolute-path? ( path -- path ? ) { { [ dup "\\\\?\\" head? ] [ t ] } @@ -87,7 +89,9 @@ PRIVATE> [ f ] } cond nip ; -: append-path ( str1 str2 -- str ) +PRIVATE> + +: append-path ( path1 path2 -- path ) { { [ over empty? ] [ append-path-empty ] } { [ dup empty? ] [ drop ] } @@ -107,7 +111,7 @@ PRIVATE> ] } cond ; -: prepend-path ( str1 str2 -- str ) +: prepend-path ( path1 path2 -- path ) swap append-path ; inline : file-name ( path -- string ) diff --git a/core/syntax/syntax-docs.factor b/core/syntax/syntax-docs.factor index 854db7a0ce..df78083f30 100644 --- a/core/syntax/syntax-docs.factor +++ b/core/syntax/syntax-docs.factor @@ -574,7 +574,7 @@ HELP: SBUF" HELP: P" { $syntax "P\" pathname\"" } { $values { "pathname" "a pathname string" } } -{ $description "Reads from the input string until the next occurrence of " { $link POSTPONE: " } ", creates a new " { $link pathname } ", and appends it to the parse tree." } +{ $description "Reads from the input string until the next occurrence of " { $link POSTPONE: " } ", creates a new " { $link pathname } ", and appends it to the parse tree. Pathnames presented in the UI are clickable, which opens them in a text editor configured with " { $link "editor" } "." } { $examples { $example "USING: accessors io io.files ;" "P\" foo.txt\" string>> print" "foo.txt" } } ; HELP: (