module Todos.ReadConfig
(readConfig)
where
import Prelude hiding (putStrLn,readFile,getContents,print)
import Todos.IO
import System.Environment
import System.FilePath
import System.Directory (doesFileExist)
import Text.ParserCombinators.Parsec
import Todos.Unicode
word ∷ Parser String
word = choice $ map try [quotedOption, simpleOption, quoted, simpleWord]
simpleWord = many1 $ noneOf " \t\r\n=\"'"
quotedOption = (try quotedLongOption) <|> quotedShortOption
quotedLongOption ∷ Parser String
quotedLongOption = do
string "--"
o ← simpleWord
char '='
v ← quoted
return ("--" ⧺ o ⧺ "=" ⧺ v)
quotedShortOption ∷ Parser String
quotedShortOption = do
string "-"
o ← simpleWord
v ← quoted
return ("-" ⧺ o ⧺ v)
simpleOption = do
o ← simpleWord
optional $ char '='
v ← simpleWord
return (o ⧺ "=" ⧺ v)
quoted = quoted1 <|> quoted2
quoted1 = do
char '\''
s ← many1 $ noneOf "'"
char '\''
return s
quoted2 = do
char '"'
s ← many1 $ noneOf "\""
char '"'
return s
pConfig ∷ Parser [String]
pConfig = word `sepBy` space
parseConfig ∷ String → [String]
parseConfig str =
case parse pConfig "config file" str of
Right lst → lst
Left err → error $ show err
readFile' ∷ FilePath → IO [String]
readFile' path =
do b ← doesFileExist path
if not b
then return []
else do
str ← readFile path
return $ parseConfig (unwords $ lines str)
readConfig ∷ IO [String]
readConfig = do
home ← getEnv "HOME"
let homepath = home </> ".config" </> "todos" </> "todos.conf"
homecfg ← readFile' homepath
localcfg ← readFile' ".todos.conf"
return $ homecfg ⧺ localcfg