console-program-0.3.2.0: src/System/Console/ConfigFile.hs
module System.Console.ConfigFile
(
readFromFile
) where
import System.Console.Command
import System.Console.Internal (name)
import Control.Applicative ((<$>))
import Control.Exception (tryJust)
import Control.Monad (guard)
import Control.Monad.IO.Class (MonadIO,liftIO)
import Data.List (isPrefixOf,concat)
import Data.List.Split (Splitter,split,whenElt,keepDelimsR)
import qualified Data.Map as Map
import Data.Map (Map)
import Data.Maybe (isJust)
import qualified Data.Tree as Tree
import qualified Fez.Data.Conf as Fez
import System.Directory (getAppUserDataDirectory)
import System.IO.Error (isDoesNotExistError)
type UserCommand = [String]
readFromFile :: (MonadIO m) => Commands m -> UserCommand -> m [String]
readFromFile commands command = liftIO $ do
dataDir <- getAppUserDataDirectory $ name (Tree.rootLabel commands)
let configFile = dataDir ++ "/" ++ "config"
fileContents <- either (const "") id <$> tryJust (guard . isDoesNotExistError) (readFile configFile)
return $ Fez.parseToArgs . unlines $ filterSections command fileContents
filterSections :: UserCommand -> String -> [String]
filterSections c = concat . map snd . filter (flip isPrefixOf c . fst) . map parseSection . s . lines
where
s :: [String] -> [[String]]
s = split $ keepDelimsR $ whenElt (isJust . header)
header :: String -> Maybe [String]
header ('[' : xs) = Just . words . takeWhile (/= ']') $ xs
header _ = Nothing
parseSection :: [String] -> ([String],[String])
parseSection (h : rest) = case header h of
Just c -> (c,rest)
Nothing -> ([],h : rest)
parseSection [] = ([],[])