summaryrefslogtreecommitdiff
path: root/Utility
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2011-09-19 01:37:04 -0400
committerGravatar Joey Hess <joey@kitenet.net>2011-09-19 01:38:01 -0400
commitdcded89129c4647bc71b474aac6d3e334b4321c1 (patch)
treeb0ad55d41caf7a3fdee9839b4c0f848f75249819 /Utility
parent6e80f195148ca689d85c6c8ed7f1a4f9720397a7 (diff)
reorg
Diffstat (limited to 'Utility')
-rw-r--r--Utility/Path.hs27
1 files changed, 27 insertions, 0 deletions
diff --git a/Utility/Path.hs b/Utility/Path.hs
index 9b8041dad..fe474ee82 100644
--- a/Utility/Path.hs
+++ b/Utility/Path.hs
@@ -90,3 +90,30 @@ prop_relPathDirToFile_basics from to
| otherwise = not (null r)
where
r = relPathDirToFile from to
+
+{- Given an original list of files, and an expanded list derived from it,
+ - ensures that the original list's ordering is preserved.
+ -
+ - The input list may contain a directory, like "dir" or "dir/". Any
+ - items in the expanded list that are contained in that directory will
+ - appear at the same position as it did in the input list.
+ -}
+preserveOrder :: [FilePath] -> [FilePath] -> [FilePath]
+-- optimisation, only one item in original list, so no reordering needed
+preserveOrder [_] new = new
+preserveOrder orig new = collect orig new
+ where
+ collect [] n = n
+ collect [_] n = n -- optimisation
+ collect (l:ls) n = found ++ collect ls rest
+ where (found, rest)=partition (l `dirContains`) n
+
+{- Runs an action that takes a list of FilePaths, and ensures that
+ - its return list preserves order.
+ -
+ - This assumes that it's cheaper to call preserveOrder on the result,
+ - than it would be to run the action separately with each param. In the case
+ - of git file list commands, that assumption tends to hold.
+ -}
+runPreserveOrder :: ([FilePath] -> IO [FilePath]) -> [FilePath] -> IO [FilePath]
+runPreserveOrder a files = preserveOrder files <$> a files