Mar 22
I have search *kind of* fixed.
I’m using the FileManip from Hackage to do my Regex matching, it’s basically what I was doing already, but a LOT faster. It’s functionality for finding matching directory/file names is blazing fast compared to my own functions. I also have the within files searching fixed, but that adds a big delay to getting the results. Here’s some code!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | checkFile :: String -- ^ The expression to be searched for. -> FilePath -- ^ The path to the file to be checked. -> IO Bool -- ^ Whether or not the pattern is found. checkFile pattern file = withFile file ReadMode ( \h -> do conts <- hGetContents h return $!( any ( ~~ pattern ) ( words conts ) ) ) searchDirectoryFiles :: FilePath -> GlobPattern -> IO [FilePath] searchDirectoryFiles dir pattern = find ( always ) ( fileName ~~? pattern ) dir >>= (\d -> recurseSearchFiles dir pattern >>= (\c -> return ( d ++ c) ) ) recurseSearchFiles :: FilePath -> String -> IO [FilePath] recurseSearchFiles dir pattern = do conts <- ( getDirectoryContents dir `Er.catch` (\_ -> return ([]) ) ) >>= (\c -> filterLinks ( map (\p -> dir ++ "/" ++ p) ( filter ( not . isPrefixOf "." ) ( filter ( not . isSuffixOf "~" ) c ) ) ) ) dirs <- filterM doesDirectoryExist conts files <- filterM doesFileExist conts matches <- filterM ( checkFile pattern ) files subR <- forM dirs $ \d -> recurseSearchFiles d pattern return ( matches ++ ( concat subR ) ) |
Basically now how its done is:
- Using the FileManip functions, get all matching file & directory names below the supplied directory.
- Then, get the contents of a directory and filter the trash out of it. Split it into directories & files. Use checkFile to filter out the files containing a String matching the pattern. Recurse into the subdirectories, and carry out these steps on those too.
- Concat all these results together, and return them.
M