-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Add function stripFilePath
#75
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -85,6 +85,7 @@ module System.FilePath.MODULE_NAME | |
takeDirectory, replaceDirectory, | ||
combine, (</>), | ||
splitPath, joinPath, splitDirectories, | ||
stripFilePath, | ||
|
||
-- * Drive functions | ||
splitDrive, joinDrive, | ||
|
@@ -827,6 +828,49 @@ makeRelative root path | |
takeAbs x | hasLeadingPathSeparator x && not (hasDrive x) = [pathSeparator] | ||
takeAbs x = map (\y -> if isPathSeparator y then pathSeparator else toLower y) $ takeDrive x | ||
|
||
-- | Strip the given directory from the filepath if and only if | ||
-- the given directory is a prefix of the filepath. | ||
-- | ||
-- >>> stripFilePath "app" "app/File.hs" | ||
-- Just "File.hs" | ||
-- | ||
-- >>> stripFilePath "src" "app/File.hs" | ||
-- Nothing | ||
-- | ||
-- >>> stripFilePath "src" "src-dir/File.hs" | ||
-- Nothing | ||
-- | ||
-- >>> stripFilePath "." "src/File.hs" | ||
-- Just "src/File.hs" | ||
-- | ||
-- >>> stripFilePath "app/" "./app/Lib/File.hs" | ||
-- Just "Lib/File.hs" | ||
-- | ||
-- >>> stripFilePath "/app/" "./app/Lib/File.hs" | ||
-- Nothing -- Nothing since '/app/' is absolute | ||
-- | ||
-- >>> stripFilePath "/app" "/app/Lib/File.hs" | ||
-- Just "Lib/File.hs" | ||
stripFilePath :: FilePath -> FilePath -> Maybe FilePath | ||
stripFilePath "." fp | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about:
I can't figure out what semantics a user would expect here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could take rust as a precedent?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, so do we want There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's in general a possible idea, for the whole API to have those for the case of errors. |
||
| isRelative fp = Just fp | ||
| otherwise = Nothing | ||
stripFilePath dir' fp' | ||
| Just relativeFpParts <- splitDir `stripPrefix` splitFp = Just (joinPath relativeFpParts) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the |
||
| otherwise = Nothing | ||
where | ||
dir = normalise dir' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm a friend of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the whole implementation is a bit trash atm, so no reason other than trying to be as simple as possible |
||
fp = normalise fp' | ||
|
||
splitFp = splitPath fp | ||
splitDir = splitPath dir | ||
|
||
stripFilePath' (x:xs) (y:ys) | ||
| x `equalFilePath` y = stripFilePath' xs ys | ||
| otherwise = Nothing | ||
stripFilePath' [] ys = Just ys | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm not sure whether we should allow this or not (most of the filepath API allows empty paths), but it at least warrants its own doctest line, because for some it might be unexpected. This also means this function does not guarantee a valid filepath. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point! BTW, rust has the same:
|
||
stripFilePath' _ [] = Nothing | ||
|
||
-- | Normalise a file | ||
-- | ||
-- * \/\/ outside of the drive can be made blank | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this behave with windows file namespaces, such as
\\?\
,\\.\
and\??\
. See e.g.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My apologies, my implementation is very naive since I have never needed anything like that (I personally don't even know what windows file namespaces are)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure... I've implemented a filepath AST and parser here: #99
That would be more strict wrt special windows filepaths. I haven't decided yet how to use this AST yet... it's pretty annoying to pattern match on it. Using just lexemes on the other hand throws away some information. If you have ideas, let me know.