module Options.Applicative.Builder (
subparser,
strArgument,
argument,
flag,
flag',
switch,
abortOption,
infoOption,
strOption,
option,
nullOption,
short,
long,
help,
helpDoc,
value,
showDefaultWith,
showDefault,
metavar,
eitherReader,
noArgError,
ParseError(..),
hidden,
internal,
command,
completeWith,
action,
completer,
idm,
#if __GLASGOW_HASKELL__ > 702
(<>),
#endif
mappend,
auto,
str,
disabled,
readerAbort,
readerError,
InfoMod,
fullDesc,
briefDesc,
header,
headerDoc,
footer,
footerDoc,
progDesc,
progDescDoc,
failureCode,
noIntersperse,
info,
PrefsMod,
multiSuffix,
disambiguate,
showHelpOnError,
noBacktrack,
columns,
prefs,
Mod,
ReadM,
OptionFields,
FlagFields,
ArgumentFields,
CommandFields
) where
import Control.Applicative (pure, (<|>))
import Data.Monoid (Monoid (..)
#if __GLASGOW_HASKELL__ > 702
, (<>)
#endif
)
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
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 }
eitherReader :: (String -> Either String a) -> ReadM a
eitherReader f = readerAsk >>= either readerError return . f
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 }
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
rdr = uncurry CmdReader (mkCommand m)
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 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 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 }
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
, prefBacktrack = True
, prefColumns = 80 }
idm :: Monoid m => m
idm = mempty