@@ -7,7 +7,9 @@ module Data.Text.FixWhitespace
77 , LineError (.. )
88 , displayLineError
99 , transform
10+ , transformWithLog
1011 , TabSize
12+ , Verbose
1113 , defaultTabSize
1214 )
1315 where
@@ -23,12 +25,13 @@ import qualified Data.Text.IO as Text {- Strict IO -}
2325
2426import System.IO ( IOMode (ReadMode ), hSetEncoding , utf8 , withFile )
2527
26- import Data.List.Extra.Drop ( dropWhileEnd1 )
28+ import Data.List.Extra.Drop ( dropWhileEnd1 , dropWhile1 )
2729
30+ type Verbose = Bool
2831type TabSize = Int
2932
3033-- | Default tab size.
31-
34+ --
3235defaultTabSize :: TabSize
3336defaultTabSize = 8
3437
@@ -51,27 +54,42 @@ data LineError = LineError Int Text
5154-- | Check a file against the whitespace policy,
5255-- returning a fix if violations occurred.
5356--
54- checkFile :: TabSize -> FilePath -> IO CheckResult
55- checkFile tabSize f =
57+ checkFile :: TabSize -> Verbose -> FilePath -> IO CheckResult
58+ checkFile tabSize verbose f =
5659 handle (\ (e :: IOException ) -> return $ CheckIOError e) $
5760 withFile f ReadMode $ \ h -> do
5861 hSetEncoding h utf8
5962 s <- Text. hGetContents h
60- let (s', lvs) = transform tabSize s
63+ let (s', lvs)
64+ | verbose = transformWithLog tabSize s
65+ | otherwise = (transform tabSize s, [] )
6166 return $ if s' == s then CheckOK else CheckViolation s' lvs
6267
68+ transform
69+ :: TabSize -- ^ Expand tab characters to so many spaces. Keep tabs if @<= 0@.
70+ -> Text -- ^ Text before transformation.
71+ -> Text -- ^ Text after transformation.
72+ transform tabSize =
73+ Text. unlines .
74+ removeFinalEmptyLinesExceptOne .
75+ map (removeTrailingWhitespace . convertTabs tabSize) .
76+ Text. lines
77+ where
78+ removeFinalEmptyLinesExceptOne =
79+ reverse . dropWhile1 Text. null . reverse
80+
6381-- | The transformation monad: maintains info about lines that
64- -- violate the rules.
82+ -- violate the rules. Used in the verbose mode to build a log.
6583--
6684type TransformM = Writer [LineError ]
6785
6886-- | Transforms the contents of a file.
6987--
70- transform
88+ transformWithLog
7189 :: TabSize -- ^ Expand tab characters to so many spaces. Keep tabs if @<= 0@.
7290 -> Text -- ^ Text before transformation.
7391 -> (Text , [LineError ]) -- ^ Text after transformation and violating lines if any.
74- transform tabSize =
92+ transformWithLog tabSize =
7593 runWriter .
7694 fmap Text. unlines .
7795 fixAllViolations .
@@ -82,7 +100,7 @@ transform tabSize =
82100 fixAllViolations =
83101 removeFinalEmptyLinesExceptOne
84102 <=<
85- mapM (fixLineWith $ removeTrailingWhitespace . convertTabs)
103+ mapM (fixLineWith $ removeTrailingWhitespace . convertTabs tabSize )
86104
87105 removeFinalEmptyLinesExceptOne :: [Text ] -> TransformM [Text ]
88106 removeFinalEmptyLinesExceptOne ls
@@ -96,9 +114,6 @@ transform tabSize =
96114 lenLs' = length ls'
97115 els = replicate (lenLs - lenLs') " "
98116
99- removeTrailingWhitespace =
100- Text. dropWhileEnd $ \ c -> generalCategory c `elem` [Space ,Format ] || c == ' \t '
101-
102117 fixLineWith :: (Text -> Text ) -> (Int , Text ) -> TransformM Text
103118 fixLineWith fixer (i, l)
104119 | l == l' = pure l
@@ -108,16 +123,22 @@ transform tabSize =
108123 where
109124 l' = fixer l
110125
111- convertTabs = if tabSize <= 0 then id else
112- Text. pack . reverse . fst . foldl convertOne ([] , 0 ) . Text. unpack
126+ removeTrailingWhitespace :: Text -> Text
127+ removeTrailingWhitespace =
128+ Text. dropWhileEnd $ \ c -> generalCategory c `elem` [Space ,Format ] || c == ' \t '
113129
114- convertOne (a, p) ' \t ' = (addSpaces n a, p + n)
115- where
116- n = tabSize - p `mod` tabSize -- Here, tabSize > 0 is guaranteed
117- convertOne (a, p) c = (c: a, p+ 1 )
130+ convertTabs :: TabSize -> Text -> Text
131+ convertTabs tabSize = if tabSize <= 0 then id else
132+ Text. pack . reverse . fst . foldl (convertOne tabSize) ([] , 0 ) . Text. unpack
133+
134+ convertOne :: TabSize -> (String , Int ) -> Char -> (String , Int )
135+ convertOne tabSize (a, p) ' \t ' = (addSpaces n a, p + n)
136+ where
137+ n = tabSize - p `mod` tabSize -- Here, tabSize > 0 is guaranteed
138+ convertOne _tabSize (a, p) c = (c: a, p+ 1 )
118139
119- addSpaces :: Int -> String -> String
120- addSpaces n = (replicate n ' ' ++ )
140+ addSpaces :: Int -> String -> String
141+ addSpaces n = (replicate n ' ' ++ )
121142
122143-- | Print a erroneous line with 'visibleSpaces'.
123144--
0 commit comments