hindent-6.1.0: src/HIndent/Config.hs
{-# LANGUAGE OverloadedStrings #-}
-- | Things related to HIndent configuration.
module HIndent.Config
( Config(..)
, defaultConfig
, getConfig
) where
import Control.Applicative
import Data.Int
import Data.Maybe
import Data.Yaml
import qualified Data.Yaml as Y
import HIndent.LanguageExtension.Conversion
import HIndent.LanguageExtension.Types
import qualified HIndent.Path.Find as Path
import Path
import qualified Path.IO as Path
-- | Configurations shared among the different styles. Styles may pay
-- attention to or completely disregard this configuration.
data Config = Config
{ configMaxColumns :: !Int64 -- ^ Maximum columns to fit code into ideally.
, configIndentSpaces :: !Int64 -- ^ How many spaces to indent?
, configTrailingNewline :: !Bool -- ^ End with a newline.
, configSortImports :: !Bool -- ^ Sort imports in groups.
, configLineBreaks :: [String] -- ^ Break line when meets these operators.
, configExtensions :: [Extension]
-- ^ Extra language extensions enabled by default.
}
instance FromJSON Config where
parseJSON (Y.Object v) =
Config
<$> fmap
(fromMaybe (configMaxColumns defaultConfig))
(v Y..:? "line-length")
<*> fmap
(fromMaybe (configIndentSpaces defaultConfig))
(v Y..:? "indent-size" <|> v Y..:? "tab-size")
<*> fmap
(fromMaybe (configTrailingNewline defaultConfig))
(v Y..:? "force-trailing-newline")
<*> fmap
(fromMaybe (configSortImports defaultConfig))
(v Y..:? "sort-imports")
<*> fmap
(fromMaybe (configLineBreaks defaultConfig))
(v Y..:? "line-breaks")
<*> (traverse convertExt . fromMaybe [] =<< v Y..:? "extensions")
where
convertExt x =
case strToExt x of
Just x' -> pure x'
Nothing -> error $ "Unknow extension: " ++ show x
parseJSON _ = fail "Expected Object for Config value"
-- | Default style configuration.
defaultConfig :: Config
defaultConfig =
Config
{ configMaxColumns = 80
, configIndentSpaces = 2
, configTrailingNewline = True
, configSortImports = True
, configLineBreaks = []
, configExtensions = []
}
-- | Read config from a config file, or return 'defaultConfig'.
getConfig :: IO Config
getConfig = do
cur <- Path.getCurrentDir
homeDir <- Path.getHomeDir
mfile <-
Path.findFileUp
cur
((== ".hindent.yaml") . toFilePath . filename)
(Just homeDir)
case mfile of
Nothing -> return defaultConfig
Just file -> do
result <- Y.decodeFileEither (toFilePath file)
case result of
Left e -> error (show e)
Right config -> return config