module GitHUD.Config.Parse (
parseConfigFile
, commentParser
, itemParser
, fallThroughItemParser
, configItemsFolder
, ConfigItem(..)
, colorConfigToColor
, intensityConfigToIntensity
, stringConfigToStringList
) where
import Control.Monad (void, when)
import Text.Parsec (parse)
import Text.Parsec.Char (anyChar, char, newline, noneOf, letter, spaces, string)
import Text.Parsec.Combinator (choice, eof, many1, manyTill, optional, sepBy)
import Text.Parsec.Prim (many, try, unexpected, (<|>), (<?>))
import Text.Parsec.String (parseFromFile, Parser)
import GitHUD.Config.Types
import GitHUD.Terminal.Types
data ConfigItem = Item String String
| Comment
| ErrorLine deriving (Eq, Show)
parseConfigFile :: FilePath -> IO Config
parseConfigFile filePath = do
eitherParsed <- parseFromFile configFileParser filePath
return $ either
(const defaultConfig)
id
eitherParsed
configFileParser :: Parser Config
configFileParser = do
items <- many configItemParser
return $ foldl configItemsFolder defaultConfig items
configItemParser :: Parser ConfigItem
configItemParser = choice [
commentParser
, itemParser
, fallThroughItemParser
] <?> "config file line"
endItem :: Parser ()
endItem = choice [
void newline
, eof
] <?> "end of item"
commentParser :: Parser ConfigItem
commentParser = try $ do
char '#'
manyTill anyChar (try endItem)
return Comment
itemParser :: Parser ConfigItem
itemParser = try $ do
key <- manyTill validKeyChar (char '=')
when (key == "") $ unexpected "A key in the config file should not be empty"
value <- manyTill anyChar (try endItem)
return $ Item key value
validKeyChar :: Parser Char
validKeyChar = letter <|> (char '_')
fallThroughItemParser :: Parser ConfigItem
fallThroughItemParser = do
manyTill anyChar (try newline)
return ErrorLine
configItemsFolder :: Config -> ConfigItem -> Config
configItemsFolder conf (Item "show_part_repo_indicator" value) =
conf { confShowPartRepoIndicator = boolConfigToIntensity value }
configItemsFolder conf (Item "show_part_merge_branch_commits_diff" value) =
conf { confShowPartMergeBranchCommitsDiff = boolConfigToIntensity value }
configItemsFolder conf (Item "show_part_local_branch" value) =
conf { confShowPartLocalBranch = boolConfigToIntensity value }
configItemsFolder conf (Item "show_part_commits_to_origin" value) =
conf { confShowPartCommitsToOrigin = boolConfigToIntensity value }
configItemsFolder conf (Item "show_part_local_changes_state" value) =
conf { confShowPartLocalChangesState = boolConfigToIntensity value }
configItemsFolder conf (Item "show_part_stashes" value) =
conf { confShowPartStashes = boolConfigToIntensity value }
configItemsFolder conf (Item "git_repo_indicator" repoIndicator) = conf { confRepoIndicator = repoIndicator }
configItemsFolder conf (Item "no_tracked_upstream_text" value) =
conf { confNoTrackedUpstreamString = value }
configItemsFolder conf (Item "no_tracked_upstream_text_color" value) =
conf { confNoTrackedUpstreamStringColor = colorConfigToColor value }
configItemsFolder conf (Item "no_tracked_upstream_text_intensity" value) =
conf { confNoTrackedUpstreamStringIntensity = intensityConfigToIntensity value }
configItemsFolder conf (Item "no_tracked_upstream_indicator" value) =
conf { confNoTrackedUpstreamIndicator = value }
configItemsFolder conf (Item "no_tracked_upstream_indicator_color" value) =
conf { confNoTrackedUpstreamIndicatorColor = colorConfigToColor value }
configItemsFolder conf (Item "no_tracked_upstream_indicator_intensity" value) =
conf { confNoTrackedUpstreamIndicatorIntensity = intensityConfigToIntensity value }
configItemsFolder conf (Item "merge_branch_commits_indicator" value) =
conf { confMergeBranchCommitsIndicator = value }
configItemsFolder conf (Item "merge_branch_commits_pull_prefix" value) =
conf { confMergeBranchCommitsOnlyPull = value }
configItemsFolder conf (Item "merge_branch_commits_push_prefix" value) =
conf { confMergeBranchCommitsOnlyPush = value }
configItemsFolder conf (Item "merge_branch_commits_push_pull_infix" value) =
conf { confMergeBranchCommitsBothPullPush = value }
configItemsFolder conf (Item "merge_branch_ignore_branches" value) =
conf { confMergeBranchIgnoreBranches = stringConfigToStringList value }
configItemsFolder conf (Item "local_branch_prefix" value) =
conf { confLocalBranchNamePrefix = value }
configItemsFolder conf (Item "local_branch_suffix" value) =
conf { confLocalBranchNameSuffix = value }
configItemsFolder conf (Item "local_branch_color" value) =
conf { confLocalBranchColor = colorConfigToColor value }
configItemsFolder conf (Item "local_branch_intensity" value) =
conf { confLocalBranchIntensity = intensityConfigToIntensity value }
configItemsFolder conf (Item "local_detached_prefix" value) =
conf { confLocalDetachedPrefix = value }
configItemsFolder conf (Item "local_detached_color" value) =
conf { confLocalDetachedColor = colorConfigToColor value }
configItemsFolder conf (Item "local_detached_intensity" value) =
conf { confLocalDetachedIntensity = intensityConfigToIntensity value }
configItemsFolder conf (Item "local_commits_push_suffix" value) =
conf { confLocalCommitsPushSuffix = value }
configItemsFolder conf (Item "local_commits_push_suffix_color" value) =
conf { confLocalCommitsPushSuffixColor = colorConfigToColor value }
configItemsFolder conf (Item "local_commits_push_suffix_intensity" value) =
conf { confLocalCommitsPushSuffixIntensity = intensityConfigToIntensity value }
configItemsFolder conf (Item "local_commits_pull_suffix" value) =
conf { confLocalCommitsPullSuffix = value }
configItemsFolder conf (Item "local_commits_pull_suffix_color" value) =
conf { confLocalCommitsPullSuffixColor = colorConfigToColor value }
configItemsFolder conf (Item "local_commits_pull_suffix_intensity" value) =
conf { confLocalCommitsPullSuffixIntensity = intensityConfigToIntensity value }
configItemsFolder conf (Item "local_commits_push_pull_infix" value) =
conf { confLocalCommitsPushPullInfix = value }
configItemsFolder conf (Item "local_commits_push_pull_infix_color" value) =
conf { confLocalCommitsPushPullInfixColor = colorConfigToColor value }
configItemsFolder conf (Item "local_commits_push_pull_infix_intensity" value) =
conf { confLocalCommitsPushPullInfixIntensity = intensityConfigToIntensity value }
configItemsFolder conf (Item "change_index_add_suffix" value) =
conf { confChangeIndexAddSuffix = value }
configItemsFolder conf (Item "change_index_add_suffix_color" value) =
conf { confChangeIndexAddSuffixColor = colorConfigToColor value }
configItemsFolder conf (Item "change_index_add_suffix_intensity" value) =
conf { confChangeIndexAddSuffixIntensity = intensityConfigToIntensity value }
configItemsFolder conf (Item "change_index_mod_suffix" value) =
conf { confChangeIndexModSuffix = value }
configItemsFolder conf (Item "change_index_mod_suffix_color" value) =
conf { confChangeIndexModSuffixColor = colorConfigToColor value }
configItemsFolder conf (Item "change_index_mod_suffix_intensity" value) =
conf { confChangeIndexModSuffixIntensity = intensityConfigToIntensity value }
configItemsFolder conf (Item "change_index_del_suffix" value) =
conf { confChangeIndexDelSuffix = value }
configItemsFolder conf (Item "change_index_del_suffix_color" value) =
conf { confChangeIndexDelSuffixColor = colorConfigToColor value }
configItemsFolder conf (Item "change_index_del_suffix_intensity" value) =
conf { confChangeIndexDelSuffixIntensity = intensityConfigToIntensity value }
configItemsFolder conf (Item "change_local_add_suffix" value) =
conf { confChangeLocalAddSuffix = value }
configItemsFolder conf (Item "change_local_add_suffix_color" value) =
conf { confChangeLocalAddSuffixColor = colorConfigToColor value }
configItemsFolder conf (Item "change_local_add_suffix_intensity" value) =
conf { confChangeLocalAddSuffixIntensity = intensityConfigToIntensity value }
configItemsFolder conf (Item "change_local_mod_suffix" value) =
conf { confChangeLocalModSuffix = value }
configItemsFolder conf (Item "change_local_mod_suffix_color" value) =
conf { confChangeLocalModSuffixColor = colorConfigToColor value }
configItemsFolder conf (Item "change_local_mod_suffix_intensity" value) =
conf { confChangeLocalModSuffixIntensity = intensityConfigToIntensity value }
configItemsFolder conf (Item "change_local_del_suffix" value) =
conf { confChangeLocalDelSuffix = value }
configItemsFolder conf (Item "change_local_del_suffix_color" value) =
conf { confChangeLocalDelSuffixColor = colorConfigToColor value }
configItemsFolder conf (Item "change_local_del_suffix_intensity" value) =
conf { confChangeLocalDelSuffixIntensity = intensityConfigToIntensity value }
configItemsFolder conf (Item "change_renamed_suffix" value) =
conf { confChangeRenamedSuffix = value }
configItemsFolder conf (Item "change_renamed_suffix_color" value) =
conf { confChangeRenamedSuffixColor = colorConfigToColor value }
configItemsFolder conf (Item "change_renamed_suffix_intensity" value) =
conf { confChangeRenamedSuffixIntensity = intensityConfigToIntensity value }
configItemsFolder conf (Item "change_conflicted_suffix" value) =
conf { confChangeConflictedSuffix = value }
configItemsFolder conf (Item "change_conflicted_suffix_color" value) =
conf { confChangeConflictedSuffixColor = colorConfigToColor value }
configItemsFolder conf (Item "change_conflicted_suffix_intensity" value) =
conf { confChangeConflictedSuffixIntensity = intensityConfigToIntensity value }
configItemsFolder conf (Item "stash_suffix" value) =
conf { confStashSuffix = value }
configItemsFolder conf (Item "stash_suffix_color" value) =
conf { confStashSuffixColor = colorConfigToColor value }
configItemsFolder conf (Item "stash_suffix_intensity" value) =
conf { confStashSuffixIntensity = intensityConfigToIntensity value }
configItemsFolder conf _ = conf
colorConfigToColor :: String -> Color
colorConfigToColor str =
either
(const NoColor)
id
(parse colorParser "" str)
colorParser :: Parser Color
colorParser = choice [
string "Black" >> return Black
, string "Red" >> return Red
, string "Green" >> return Green
, string "Yellow" >> return Yellow
, string "Blue" >> return Blue
, string "Magenta" >> return Magenta
, string "Cyan" >> return Cyan
, string "White" >> return White
, string "NoColor" >> return NoColor
] <?> "color"
intensityConfigToIntensity :: String -> ColorIntensity
intensityConfigToIntensity str =
either
(const Vivid)
id
(parse intensityParser "" str)
intensityParser :: Parser ColorIntensity
intensityParser = choice [
string "Dull" >> return Dull
, string "Vivid" >> return Vivid
] <?> "intensity"
boolConfigToIntensity :: String -> Bool
boolConfigToIntensity str =
either
(const True)
id
(parse boolParser "" str)
stringConfigToStringList :: String -> [String]
stringConfigToStringList str =
either
(const [])
id
(parse stringListParser "" str)
stringListParser :: Parser [String]
stringListParser = do
branchNameList <- sepBy stripedBranchName (char ',')
return $ filter noEmptyStringFilter branchNameList
noEmptyStringFilter :: String -> Bool
noEmptyStringFilter str = not (str == "")
stripedBranchName :: Parser String
stripedBranchName = do
spaces
branchName <- many (noneOf [',', ' '])
spaces
return branchName
boolParser :: Parser Bool
boolParser = choice [
string "False" >> return False
, string "F" >> return False
, string "false" >> return False
, string "f" >> return False
, string "No" >> return False
, string "N" >> return False
, string "no" >> return False
, string "n" >> return False
, string "True" >> return True
, string "T" >> return True
, string "true" >> return True
, string "t" >> return True
, string "Yes" >> return True
, string "Y" >> return True
, string "yes" >> return True
, string "y" >> return True
] <?> "bool"