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 [] = ([],[])