module Options.Applicative.Builder (
subparser,
strArgument,
argument,
flag,
flag',
switch,
abortOption,
infoOption,
strOption,
option,
nullOption,
short,
long,
help,
helpDoc,
value,
showDefaultWith,
showDefault,
metavar,
noArgError,
ParseError(..),
hidden,
internal,
command,
commandGroup,
completeWith,
action,
completer,
idm,
mappend,
auto,
str,
maybeReader,
eitherReader,
disabled,
readerAbort,
readerError,
InfoMod,
fullDesc,
briefDesc,
header,
headerDoc,
footer,
footerDoc,
progDesc,
progDescDoc,
failureCode,
noIntersperse,
info,
PrefsMod,
multiSuffix,
disambiguate,
showHelpOnError,
showHelpOnEmpty,
noBacktrack,
columns,
prefs,
defaultPrefs,
Mod,
ReadM,
OptionFields,
FlagFields,
ArgumentFields,
CommandFields
) where
import Control.Applicative
import Data.Semigroup hiding (option)
import Options.Applicative.Builder.Completer
import Options.Applicative.Builder.Internal
import Options.Applicative.Common
import Options.Applicative.Types
import Options.Applicative.Help.Pretty
import Options.Applicative.Help.Chunk
auto :: Read a => ReadM a
auto = eitherReader $ \arg -> case reads arg of
[(r, "")] -> return r
_ -> Left $ "cannot parse value `" ++ arg ++ "'"
str :: ReadM String
str = readerAsk
eitherReader :: (String -> Either String a) -> ReadM a
eitherReader f = readerAsk >>= either readerError return . f
maybeReader :: (String -> Maybe a) -> ReadM a
maybeReader f = eitherReader $ \arg ->
maybe (Left $ "cannot parse value `" ++ arg ++ "'") pure . f $ arg
disabled :: ReadM a
disabled = readerError "disabled option"
short :: HasName f => Char -> Mod f a
short = fieldMod . name . OptShort
long :: HasName f => String -> Mod f a
long = fieldMod . name . OptLong
value :: HasValue f => a -> Mod f a
value x = Mod id (DefaultProp (Just x) Nothing) id
showDefaultWith :: (a -> String) -> Mod f a
showDefaultWith s = Mod id (DefaultProp Nothing (Just s)) id
showDefault :: Show a => Mod f a
showDefault = showDefaultWith show
help :: String -> Mod f a
help s = optionMod $ \p -> p { propHelp = paragraph s }
helpDoc :: Maybe Doc -> Mod f a
helpDoc doc = optionMod $ \p -> p { propHelp = Chunk doc }
noArgError :: ParseError -> Mod OptionFields a
noArgError e = fieldMod $ \p -> p { optNoArgError = e }
metavar :: HasMetavar f => String -> Mod f a
metavar var = optionMod $ \p -> p { propMetaVar = var }
hidden :: Mod f a
hidden = optionMod $ \p ->
p { propVisibility = min Hidden (propVisibility p) }
command :: String -> ParserInfo a -> Mod CommandFields a
command cmd pinfo = fieldMod $ \p ->
p { cmdCommands = (cmd, pinfo) : cmdCommands p }
commandGroup :: String -> Mod CommandFields a
commandGroup g = fieldMod $ \p ->
p { cmdGroup = Just g }
completeWith :: HasCompleter f => [String] -> Mod f a
completeWith xs = completer (listCompleter xs)
action :: HasCompleter f => String -> Mod f a
action act = completer (bashCompleter act)
completer :: HasCompleter f => Completer -> Mod f a
completer f = fieldMod $ modCompleter (`mappend` f)
subparser :: Mod CommandFields a -> Parser a
subparser m = mkParser d g rdr
where
Mod _ d g = metavar "COMMAND" `mappend` m
(groupName, cmds, subs) = mkCommand m
rdr = CmdReader groupName cmds subs
argument :: ReadM a -> Mod ArgumentFields a -> Parser a
argument p (Mod f d g) = mkParser d g (ArgReader rdr)
where
ArgumentFields compl = f (ArgumentFields mempty)
rdr = CReader compl p
strArgument :: Mod ArgumentFields String -> Parser String
strArgument = argument str
flag :: a
-> a
-> Mod FlagFields a
-> Parser a
flag defv actv m = flag' actv m <|> pure defv
flag' :: a
-> Mod FlagFields a
-> Parser a
flag' actv (Mod f d g) = mkParser d g rdr
where
rdr = let fields = f (FlagFields [] actv)
in FlagReader (flagNames fields)
(flagActive fields)
switch :: Mod FlagFields Bool -> Parser Bool
switch = flag False True
abortOption :: ParseError -> Mod OptionFields (a -> a) -> Parser (a -> a)
abortOption err m = option (readerAbort err) . (`mappend` m) $ mconcat
[ noArgError err
, value id
, metavar "" ]
infoOption :: String -> Mod OptionFields (a -> a) -> Parser (a -> a)
infoOption = abortOption . InfoMsg
strOption :: Mod OptionFields String -> Parser String
strOption = option str
nullOption :: ReadM a -> Mod OptionFields a -> Parser a
nullOption = option
option :: ReadM a -> Mod OptionFields a -> Parser a
option r m = mkParser d g rdr
where
Mod f d g = metavar "ARG" `mappend` m
fields = f (OptionFields [] mempty (ErrorMsg ""))
crdr = CReader (optCompleter fields) r
rdr = OptReader (optNames fields) crdr (optNoArgError fields)
newtype InfoMod a = InfoMod
{ applyInfoMod :: ParserInfo a -> ParserInfo a }
instance Monoid (InfoMod a) where
mempty = InfoMod id
mappend = (<>)
instance Semigroup (InfoMod a) where
m1 <> m2 = InfoMod $ applyInfoMod m2 . applyInfoMod m1
fullDesc :: InfoMod a
fullDesc = InfoMod $ \i -> i { infoFullDesc = True }
briefDesc :: InfoMod a
briefDesc = InfoMod $ \i -> i { infoFullDesc = False }
header :: String -> InfoMod a
header s = InfoMod $ \i -> i { infoHeader = paragraph s }
headerDoc :: Maybe Doc -> InfoMod a
headerDoc doc = InfoMod $ \i -> i { infoHeader = Chunk doc }
footer :: String -> InfoMod a
footer s = InfoMod $ \i -> i { infoFooter = paragraph s }
footerDoc :: Maybe Doc -> InfoMod a
footerDoc doc = InfoMod $ \i -> i { infoFooter = Chunk doc }
progDesc :: String -> InfoMod a
progDesc s = InfoMod $ \i -> i { infoProgDesc = paragraph s }
progDescDoc :: Maybe Doc -> InfoMod a
progDescDoc doc = InfoMod $ \i -> i { infoProgDesc = Chunk doc }
failureCode :: Int -> InfoMod a
failureCode n = InfoMod $ \i -> i { infoFailureCode = n }
noIntersperse :: InfoMod a
noIntersperse = InfoMod $ \p -> p { infoIntersperse = False }
info :: Parser a -> InfoMod a -> ParserInfo a
info parser m = applyInfoMod m base
where
base = ParserInfo
{ infoParser = parser
, infoFullDesc = True
, infoProgDesc = mempty
, infoHeader = mempty
, infoFooter = mempty
, infoFailureCode = 1
, infoIntersperse = True }
newtype PrefsMod = PrefsMod
{ applyPrefsMod :: ParserPrefs -> ParserPrefs }
instance Monoid PrefsMod where
mempty = PrefsMod id
mappend = (<>)
instance Semigroup PrefsMod where
m1 <> m2 = PrefsMod $ applyPrefsMod m2 . applyPrefsMod m1
multiSuffix :: String -> PrefsMod
multiSuffix s = PrefsMod $ \p -> p { prefMultiSuffix = s }
disambiguate :: PrefsMod
disambiguate = PrefsMod $ \p -> p { prefDisambiguate = True }
showHelpOnError :: PrefsMod
showHelpOnError = PrefsMod $ \p -> p { prefShowHelpOnError = True }
showHelpOnEmpty :: PrefsMod
showHelpOnEmpty = PrefsMod $ \p -> p { prefShowHelpOnEmpty = True }
noBacktrack :: PrefsMod
noBacktrack = PrefsMod $ \p -> p { prefBacktrack = False }
columns :: Int -> PrefsMod
columns cols = PrefsMod $ \p -> p { prefColumns = cols }
prefs :: PrefsMod -> ParserPrefs
prefs m = applyPrefsMod m base
where
base = ParserPrefs
{ prefMultiSuffix = ""
, prefDisambiguate = False
, prefShowHelpOnError = False
, prefShowHelpOnEmpty = False
, prefBacktrack = True
, prefColumns = 80 }
idm :: Monoid m => m
idm = mempty
defaultPrefs :: ParserPrefs
defaultPrefs = prefs idm