(This README is best viewed on Codeberg).
Inspired by str, this library offers modern and consistent filepath manipulation for Common Lisp.
It addresses three main issues found with the status quo, namely:
- Centrality: Functionality is spread across the standard library and
uiop
. - Completeness: A number of common operations found in newer languages are missing entirely.
- Clarity: Function names are often unintuitive.
The filepaths
library solves these issues by offering functions commonly found
elsewhere while naming them what you’d generally expect them to be. For
instance:
(filepaths:join "/home/you/code" "common-lisp" "hello.lisp")
#P"/home/you/code/common-lisp/hello.lisp"
There are many more functions available.
Note that this library is currently Unix only and doesn’t offer functions for communicating with the filesystem to test if files exist, etc.
Compiler | **.json | Verbatum .. | Unicode Paths |
---|---|---|---|
SBCL | Yes | Yes | Yes |
ECL | No | Yes | Yes |
ABCL | Yes | No | Yes |
CCL | Yes | No | Yes |
Clasp | No | Yes | Yes (2.7) |
Allegro | Yes | No | Yes |
This library is available on Ultralisp. It uses only standard library functions and has no external dependencies.
It is recommended that you import this library with the nickname path
or p
,
although the usage examples further down all use the full name, filepaths
.
(:local-nicknames (:p :filepaths))
Note that nearly every function here can be passed either a pathname
or a
string
.
Is the given PATH the root directory?
(filepaths:rootp #p"/")
T
Is the given PATH an empty string?
(filepaths:emptyp #p"")
T
Yields T when the given PATH is a full, absolute path.
(filepaths:absolutep "/home/colin/foo.txt")
T
Yields T when the given PATH is a relative one.
(filepaths:relativep #p"bar/foo.txt")
T
Are the initial components of a PATH some BASE?
(filepaths:starts-with-p #p"/foo/bar/baz/zing.json" "/foo/bar")
T
Are the final components of a PATH some given CHILD?
(filepaths:ends-with-p #p"/foo/bar/baz/zing.json" "baz/zing.json")
T
Yields T if the PATH represents a directory. It only tests for structure; the filesystem isn’t probed.
(filepaths:directoryp #p"/foo/bar/")
T
(filepaths:directoryp #p"/foo/bar/baz.txt")
NIL
Combine two or more components together.
(filepaths:join "/foo" "bar" "baz" "test.json")
#P"/foo/bar/baz/test.json"
(filepaths:join #p"/bar/baz/" #p"foo.json")
#P"/bar/baz/foo.json"
The non-extension, non-directory portion of the filename of a PATH.
(filepaths:base #p"/foo/bar/baz.txt")
baz
Swap the base portion of a PATH with a NEW one. Yields a new path object.
(filepaths:with-base #p"/foo/bar/baz.txt" "jack")
#P"/foo/bar/jack.txt"
The filename of a PATH with no other directory components.
(filepaths:name #p"/foo/bar/baz.txt")
baz.txt
Swap the filename portion of a PATH with a NEW one. Yields a new path object.
(filepaths:with-name #p"/foo/bar/baz.txt" "jack.json")
#P"/foo/bar/jack.json"
Yield PATH without its final component, if there is one.
(filepaths:parent #p"/foo/bar/baz.txt")
#P"/foo/bar/"
Swap the parent portion of a PATH.
(filepaths:with-parent #p"/foo/bar/baz.json" #p"/zing")
#P"/zing/baz.json"
The extension of a given PATH.
(filepaths:extension #p"/foo/bar.json")
json
Swap the entire extension of a given PATH. Yields a new path object.
(filepaths:with-extension #p"/foo/bar/baz.txt" "json")
#P"/foo/bar/baz.json"
Add an extension to the given path, even if it already has one.
(filepaths:add-extension #p"/foo/bar/baz.txt" "zip")
#P"/foo/bar/baz.txt.zip"
Remove an extension from a PATH.
(filepaths:drop-extension #p"/foo/bar/baz.json")
#P"/foo/bar/baz"
(filepaths:drop-extension #p"/foo/bar/baz.json.zip")
#P"/foo/bar/baz.json"
Every component of a PATH broken up as a list.
(filepaths:components #p"/foo/bar/baz.json")
("/" "foo" "bar" "baz.json")
Given a LIST of path components, construct a proper pathname object.
(filepaths:from-list '("foo" "bar" "baz"))
#P"foo/bar/baz"
(filepaths:from-list (filepaths:components "/foo/bar/baz/file.txt"))
#P"/foo/bar/baz/file.txt"
If a given PATH doesn’t end in a path separator, add one.
(filepaths:ensure-directory #p"/foo/bar/baz")
#P"/foo/bar/baz/"
A PATH is definitely a string after this.
(type-of (filepaths:ensure-string #p"/foo/bar"))
(SIMPLE-BASE-STRING 8)
A PATH is definitely a pathname after this.
(type-of (filepaths:ensure-path "/foo/bar"))
PATHNAME
Convert a PATH object into string.
(filepaths:to-string #p"/foo/bar/baz.txt")
/foo/bar/baz.txt
Convert a string into a proper filepath object.
(filepaths:from-string "/foo/bar/baz.txt")
#P"/foo/bar/baz.txt"
For certain functions in this library, it is not appropriate to return nil
in
case of an error. The following conditions are thus triggered under certain
circumstances:
no-filename
empty-path
root-no-parent
- Windows support