craft-0.0.0.1: src/Craft/Config/Shell.hs
module Craft.Config.Shell where
import Control.Lens hiding (noneOf, set)
import Data.Maybe (catMaybes)
import Text.Megaparsec hiding (parse)
import Craft hiding (try)
import Craft.Config
import Craft.Internal.Helpers.Parsing
newtype ShellFormat = ShellFormat { _shellfmt :: [(String, String)] }
deriving (Eq, Show)
makeLenses ''ShellFormat
instance ConfigFormat ShellFormat where
showConfig (ShellFormat cfgs) = unlines $ map showkv cfgs
where
showkv :: (String, String) -> String
showkv (k, v) = k++"="++v
parseConfig fp s =
case runParser parser (fromAbsFile fp) s of
Left err -> $craftError $ show err
Right cfgs -> return cfgs
-- | Replace an existing value if it is already set otherwise add it to the end.
set :: String -> String -> ShellFormat -> ShellFormat
set k v (ShellFormat cfgs) =
case lookup k cfgs of
Nothing -> ShellFormat $ cfgs++[(k,v)]
Just _ -> ShellFormat $ map (replace k v) cfgs
where
replace ka va (kb, vb) | ka == kb = (ka, va)
| otherwise = (kb, vb)
unset :: String -> ShellFormat -> ShellFormat
unset k (ShellFormat cfgs) = ShellFormat $ filter ((/= k) . fst) cfgs
get :: Path Abs FileP -> Craft (Maybe (Config ShellFormat))
get = Craft.Config.get
config :: Path Abs FileP -> [(String, String)] -> Config ShellFormat
config fp = Craft.Config.config fp . ShellFormat
dedup :: ShellFormat -> ShellFormat
dedup cfgs = go empty cfgs
where
go m (ShellFormat []) = m
go m (ShellFormat ((k, v):xs)) = go (set k v m) (ShellFormat xs)
empty :: ShellFormat
empty = ShellFormat []
-- TESTME
parser :: Parsec String ShellFormat
parser = do
items <- line `sepEndBy` eol
return . ShellFormat $ catMaybes items
line :: Parsec String (Maybe (String, String))
line = do
try (comment >> return Nothing)
<|> try (space >> end >> return Nothing)
<|> (Just <$> item)
comment :: Parsec String ()
comment = space >> char '#' >> manyTill anyChar end >> return ()
item :: Parsec String (String, String)
item = do
space
name <- some $ noneOf " ="
void $ char '='
-- TODO: quoted values
value <- try (someTill (noneOf " \r\n#") (lookAhead (oneOf " \r\n#")) <* manyTill anyChar end)
<|> (many (oneOf " \t") >> manyTill anyChar end >> return "")
return (name, value)