module Options.Applicative.Builder (
subparser,
argument,
arguments,
arguments1,
flag,
flag',
switch,
nullOption,
abortOption,
infoOption,
strOption,
option,
short,
long,
help,
helpDoc,
value,
showDefaultWith,
showDefault,
metavar,
reader,
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, (<|>), many, some)
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 :: Monad m => Read a => String -> m a
auto arg = case reads arg of
[(r, "")] -> return r
_ -> fail $ "cannot parse value `" ++ arg ++ "'"
str :: Monad m => String -> m String
str = return
disabled :: Monad m => String -> m a
disabled = const . fail $ "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 }
reader :: (String -> ReadM a) -> Mod OptionFields a
reader f = fieldMod $ \p -> p { optReader = f }
eitherReader :: (String -> Either String a) -> Mod OptionFields a
eitherReader f = reader (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 :: (String -> Maybe 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
arguments :: (String -> Maybe a) -> Mod ArgumentFields a -> Parser [a]
arguments r m = many (argument r m)
arguments1 :: (String -> Maybe a) -> Mod ArgumentFields a -> Parser [a]
arguments1 r m = some (argument r m)
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
nullOption :: Mod OptionFields a -> Parser a
nullOption m = mkParser d g rdr
where
Mod f d g = metavar "ARG" `mappend` m
fields = f (OptionFields [] mempty disabled (ErrorMsg ""))
crdr = CReader (optCompleter fields) (optReader fields)
rdr = OptReader (optNames fields) crdr (optNoArgError fields)
abortOption :: ParseError -> Mod OptionFields (a -> a) -> Parser (a -> a)
abortOption err m = nullOption . (`mappend` m) $ mconcat
[ reader (const (ReadM (Left err)))
, noArgError err
, value id
, metavar ""
, hidden ]
infoOption :: String -> Mod OptionFields (a -> a) -> Parser (a -> a)
infoOption = abortOption . InfoMsg
strOption :: Mod OptionFields String -> Parser String
strOption m = nullOption $ reader str `mappend` m
option :: Read a => Mod OptionFields a -> Parser a
option m = nullOption $ reader auto `mappend` m
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
(&) :: Monoid m => m -> m -> m
(&) = mappend