@@ -1,46 +1,69 @@
1−{-# LANGUAGE OverloadedStrings #-}
1+{-# LANGUAGE DeriveAnyClass, DeriveGeneric, LambdaCase, NoImplicitPrelude, OverloadedStrings #-}
2−{-# LANGUAGE NoImplicitPrelude #-}
3−{-# LANGUAGE TypeApplications #-}
4−{-# LANGUAGE DeriveGeneric #-}
5−{-# LANGUAGE DeriveAnyClass #-}
6−{-# LANGUAGE RecordWildCards #-}
2+{-# LANGUAGE RecordWildCards, ScopedTypeVariables, TypeApplications #-}
8module Control.Hext.Processor
4module Control.Hext.Processor
9− ( processFiles
5+ ( processFiles,
9+import Control.Hext.Config
10+import Data.Haskell.Parser
11+import Data.List hiding (head, unlines)
12+import qualified Data.Text as T
12import Relude
13import Relude
14−import Data.List hiding (unlines)
15import System.Directory.Tree
14import System.Directory.Tree
16−import Data.Haskell.Parser
18getFiles :: FilePath -> IO [FilePath]
16getFiles :: FilePath -> IO [FilePath]
19getFiles dir = do
17getFiles dir = do
20− (_ :/ tree) <- readDirectoryWith return dir
18+ (_ :/ tree) <- readDirectoryWith return dir
21− return . (>>= getHs) . unwrapDir $ tree
19+ return . (>>= getHs) . unwrapDir $ tree
23− unwrapDir :: DirTree a -> [DirTree a]
21+ unwrapDir :: DirTree a -> [DirTree a]
24− unwrapDir (Dir _ paths) = paths
22+ unwrapDir (Dir _ paths) = paths
25− unwrapDir _ = []
23+ unwrapDir _ = []
24+ getHs :: DirTree FilePath -> [FilePath]
25+ getHs (File _ path) | ".hs" `isSuffixOf` path = pure path
26+ getHs (Dir name paths) | not $ "." `isPrefixOf` name = paths >>= getHs
27− getHs :: DirTree FilePath -> [FilePath]
28− getHs (File _ path) | ".hs" `isSuffixOf` path = pure path
29− getHs (Dir name paths) | not $ "." `isPrefixOf` name = paths >>= getHs
32−processFile :: [Text] -> Text -> Text
29+processFile :: Text -> Text -> Text
33processFile extensions file =
30processFile extensions file =
34− (unlines . fmap wrapExtension) extensions
31+ extensions
36 <> withoutExtensions file
33 <> withoutExtensions file
38− wrapExtension :: Text -> Text
39− wrapExtension e = "{-# LANGUAGE " <> e <> " #-}"
35+wrapExtension :: Text -> Text
36+wrapExtension ee = "{-# LANGUAGE " <> ee <> " #-}"
39+baseLength = T.length $ wrapExtension ""
41−processFiles :: [Text] -> FilePath -> IO ()
41+processFiles :: Maybe LineLimit -> [Text] -> FilePath -> IO ()
42−processFiles extensions dir = do
42+processFiles limit allExtensions dir = do
43− files <- getFiles dir
43+ files <- getFiles dir
44− forM_ files $ \file -> do
44+ forM_ files $ \file -> do
45− contents <- readFileText file
45+ contents <- readFileText file
46− writeFileText file . processFile extensions $ contents
46+ writeFileText file . processFile (wrapExtensions allExtensions) $ contents
48+ wrapExtensions :: [Text] -> Text
49+ wrapExtensions [] = ""
50+ wrapExtensions extensions@(e : ee) = case limit of
51+ Nothing -> unlines . fmap wrapExtension $ extensions
52+ Just Unlimited -> unlines . pure . wrapExtension . mconcat . intersperse ", " $ extensions
54+ let emptyExtra = ([], ee, baseLength + T.length e)
59+ (Just current@(_, [], _)) -> Just (current, Nothing)
60+ (Just current@(soFar, ne : next, l)) ->
61+ let thing = (ne : soFar, next, l + T.length ne + 2)
62+ in Just (current, Just thing)
65+ (extraExtensions, eLeft, _) =
66+ fromMaybe emptyExtra . viaNonEmpty head . reverse . filter (\(_, _, n') -> n' <= n) $ ee'
67+ in (wrapExtension . mconcat . intersperse ", " $ e : reverse extraExtensions)
69+ <> wrapExtensions eLeft