@@ -7,7 +7,9 @@ module Data.Text.FixWhitespace
7
7
, LineError (.. )
8
8
, displayLineError
9
9
, transform
10
+ , transformWithLog
10
11
, TabSize
12
+ , Verbose
11
13
, defaultTabSize
12
14
)
13
15
where
@@ -23,12 +25,13 @@ import qualified Data.Text.IO as Text {- Strict IO -}
23
25
24
26
import System.IO ( IOMode (ReadMode ), hSetEncoding , utf8 , withFile )
25
27
26
- import Data.List.Extra.Drop ( dropWhileEnd1 )
28
+ import Data.List.Extra.Drop ( dropWhileEnd1 , dropWhile1 )
27
29
30
+ type Verbose = Bool
28
31
type TabSize = Int
29
32
30
33
-- | Default tab size.
31
-
34
+ --
32
35
defaultTabSize :: TabSize
33
36
defaultTabSize = 8
34
37
@@ -51,27 +54,42 @@ data LineError = LineError Int Text
51
54
-- | Check a file against the whitespace policy,
52
55
-- returning a fix if violations occurred.
53
56
--
54
- checkFile :: TabSize -> FilePath -> IO CheckResult
55
- checkFile tabSize f =
57
+ checkFile :: TabSize -> Verbose -> FilePath -> IO CheckResult
58
+ checkFile tabSize verbose f =
56
59
handle (\ (e :: IOException ) -> return $ CheckIOError e) $
57
60
withFile f ReadMode $ \ h -> do
58
61
hSetEncoding h utf8
59
62
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, [] )
61
66
return $ if s' == s then CheckOK else CheckViolation s' lvs
62
67
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
+
63
81
-- | 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.
65
83
--
66
84
type TransformM = Writer [LineError ]
67
85
68
86
-- | Transforms the contents of a file.
69
87
--
70
- transform
88
+ transformWithLog
71
89
:: TabSize -- ^ Expand tab characters to so many spaces. Keep tabs if @<= 0@.
72
90
-> Text -- ^ Text before transformation.
73
91
-> (Text , [LineError ]) -- ^ Text after transformation and violating lines if any.
74
- transform tabSize =
92
+ transformWithLog tabSize =
75
93
runWriter .
76
94
fmap Text. unlines .
77
95
fixAllViolations .
@@ -82,7 +100,7 @@ transform tabSize =
82
100
fixAllViolations =
83
101
removeFinalEmptyLinesExceptOne
84
102
<=<
85
- mapM (fixLineWith $ removeTrailingWhitespace . convertTabs)
103
+ mapM (fixLineWith $ removeTrailingWhitespace . convertTabs tabSize )
86
104
87
105
removeFinalEmptyLinesExceptOne :: [Text ] -> TransformM [Text ]
88
106
removeFinalEmptyLinesExceptOne ls
@@ -96,9 +114,6 @@ transform tabSize =
96
114
lenLs' = length ls'
97
115
els = replicate (lenLs - lenLs') " "
98
116
99
- removeTrailingWhitespace =
100
- Text. dropWhileEnd $ \ c -> generalCategory c `elem` [Space ,Format ] || c == ' \t '
101
-
102
117
fixLineWith :: (Text -> Text ) -> (Int , Text ) -> TransformM Text
103
118
fixLineWith fixer (i, l)
104
119
| l == l' = pure l
@@ -108,16 +123,22 @@ transform tabSize =
108
123
where
109
124
l' = fixer l
110
125
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 '
113
129
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 )
118
139
119
- addSpaces :: Int -> String -> String
120
- addSpaces n = (replicate n ' ' ++ )
140
+ addSpaces :: Int -> String -> String
141
+ addSpaces n = (replicate n ' ' ++ )
121
142
122
143
-- | Print a erroneous line with 'visibleSpaces'.
123
144
--
0 commit comments