|
Packit |
3fa651 |
module Options.Applicative.Builder (
|
|
Packit |
3fa651 |
-- * Parser builders
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- | This module contains utility functions and combinators to create parsers
|
|
Packit |
3fa651 |
-- for individual options.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- Each parser builder takes an option modifier. A modifier can be created by
|
|
Packit |
3fa651 |
-- composing the basic modifiers provided by this module using the 'Monoid'
|
|
Packit |
3fa651 |
-- operations 'mempty' and 'mappend', or their aliases 'idm' and '<>'.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- For example:
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- > out = strOption
|
|
Packit |
3fa651 |
-- > ( long "output"
|
|
Packit |
3fa651 |
-- > <> short 'o'
|
|
Packit |
3fa651 |
-- > <> metavar "FILENAME" )
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- creates a parser for an option called \"output\".
|
|
Packit |
3fa651 |
subparser,
|
|
Packit |
3fa651 |
strArgument,
|
|
Packit |
3fa651 |
argument,
|
|
Packit |
3fa651 |
flag,
|
|
Packit |
3fa651 |
flag',
|
|
Packit |
3fa651 |
switch,
|
|
Packit |
3fa651 |
abortOption,
|
|
Packit |
3fa651 |
infoOption,
|
|
Packit |
3fa651 |
strOption,
|
|
Packit |
3fa651 |
option,
|
|
Packit |
3fa651 |
nullOption,
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- * Modifiers
|
|
Packit |
3fa651 |
short,
|
|
Packit |
3fa651 |
long,
|
|
Packit |
3fa651 |
help,
|
|
Packit |
3fa651 |
helpDoc,
|
|
Packit |
3fa651 |
value,
|
|
Packit |
3fa651 |
showDefaultWith,
|
|
Packit |
3fa651 |
showDefault,
|
|
Packit |
3fa651 |
metavar,
|
|
Packit |
3fa651 |
noArgError,
|
|
Packit |
3fa651 |
ParseError(..),
|
|
Packit |
3fa651 |
hidden,
|
|
Packit |
3fa651 |
internal,
|
|
Packit |
3fa651 |
style,
|
|
Packit |
3fa651 |
command,
|
|
Packit |
3fa651 |
commandGroup,
|
|
Packit |
3fa651 |
completeWith,
|
|
Packit |
3fa651 |
action,
|
|
Packit |
3fa651 |
completer,
|
|
Packit |
3fa651 |
idm,
|
|
Packit |
3fa651 |
mappend,
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- * Readers
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- | A collection of basic 'Option' readers.
|
|
Packit |
3fa651 |
auto,
|
|
Packit |
3fa651 |
str,
|
|
Packit |
3fa651 |
maybeReader,
|
|
Packit |
3fa651 |
eitherReader,
|
|
Packit |
3fa651 |
disabled,
|
|
Packit |
3fa651 |
readerAbort,
|
|
Packit |
3fa651 |
readerError,
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- * Builder for 'ParserInfo'
|
|
Packit |
3fa651 |
InfoMod,
|
|
Packit |
3fa651 |
fullDesc,
|
|
Packit |
3fa651 |
briefDesc,
|
|
Packit |
3fa651 |
header,
|
|
Packit |
3fa651 |
headerDoc,
|
|
Packit |
3fa651 |
footer,
|
|
Packit |
3fa651 |
footerDoc,
|
|
Packit |
3fa651 |
progDesc,
|
|
Packit |
3fa651 |
progDescDoc,
|
|
Packit |
3fa651 |
failureCode,
|
|
Packit |
3fa651 |
noIntersperse,
|
|
Packit |
3fa651 |
forwardOptions,
|
|
Packit |
3fa651 |
info,
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- * Builder for 'ParserPrefs'
|
|
Packit |
3fa651 |
PrefsMod,
|
|
Packit |
3fa651 |
multiSuffix,
|
|
Packit |
3fa651 |
disambiguate,
|
|
Packit |
3fa651 |
showHelpOnError,
|
|
Packit |
3fa651 |
showHelpOnEmpty,
|
|
Packit |
3fa651 |
noBacktrack,
|
|
Packit |
3fa651 |
columns,
|
|
Packit |
3fa651 |
prefs,
|
|
Packit |
3fa651 |
defaultPrefs,
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- * Types
|
|
Packit |
3fa651 |
Mod,
|
|
Packit |
3fa651 |
ReadM,
|
|
Packit |
3fa651 |
OptionFields,
|
|
Packit |
3fa651 |
FlagFields,
|
|
Packit |
3fa651 |
ArgumentFields,
|
|
Packit |
3fa651 |
CommandFields
|
|
Packit |
3fa651 |
) where
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
import Control.Applicative
|
|
Packit |
3fa651 |
import Data.Semigroup hiding (option)
|
|
Packit |
3fa651 |
import Data.String (fromString, IsString)
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
import Options.Applicative.Builder.Completer
|
|
Packit |
3fa651 |
import Options.Applicative.Builder.Internal
|
|
Packit |
3fa651 |
import Options.Applicative.Common
|
|
Packit |
3fa651 |
import Options.Applicative.Types
|
|
Packit |
3fa651 |
import Options.Applicative.Help.Pretty
|
|
Packit |
3fa651 |
import Options.Applicative.Help.Chunk
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- Readers --
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | 'Option' reader based on the 'Read' type class.
|
|
Packit |
3fa651 |
auto :: Read a => ReadM a
|
|
Packit |
3fa651 |
auto = eitherReader $ \arg -> case reads arg of
|
|
Packit |
3fa651 |
[(r, "")] -> return r
|
|
Packit |
3fa651 |
_ -> Left $ "cannot parse value `" ++ arg ++ "'"
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | String 'Option' reader.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- Polymorphic over the `IsString` type class since 0.14.
|
|
Packit |
3fa651 |
str :: IsString s => ReadM s
|
|
Packit |
3fa651 |
str = fromString <$> readerAsk
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Convert a function producing an 'Either' into a reader.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- As an example, one can create a ReadM from an attoparsec Parser
|
|
Packit |
3fa651 |
-- easily with
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- > import qualified Data.Attoparsec.Text as A
|
|
Packit |
3fa651 |
-- > import qualified Data.Text as T
|
|
Packit |
3fa651 |
-- > attoparsecReader :: A.Parser a => ReadM a
|
|
Packit |
3fa651 |
-- > attoparsecReader p = eitherReader (A.parseOnly p . T.pack)
|
|
Packit |
3fa651 |
eitherReader :: (String -> Either String a) -> ReadM a
|
|
Packit |
3fa651 |
eitherReader f = readerAsk >>= either readerError return . f
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Convert a function producing a 'Maybe' into a reader.
|
|
Packit |
3fa651 |
maybeReader :: (String -> Maybe a) -> ReadM a
|
|
Packit |
3fa651 |
maybeReader f = do
|
|
Packit |
3fa651 |
arg <- readerAsk
|
|
Packit |
3fa651 |
maybe (readerError $ "cannot parse value `" ++ arg ++ "'") return . f $ arg
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Null 'Option' reader. All arguments will fail validation.
|
|
Packit |
3fa651 |
disabled :: ReadM a
|
|
Packit |
3fa651 |
disabled = readerError "disabled option"
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- modifiers --
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Specify a short name for an option.
|
|
Packit |
3fa651 |
short :: HasName f => Char -> Mod f a
|
|
Packit |
3fa651 |
short = fieldMod . name . OptShort
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Specify a long name for an option.
|
|
Packit |
3fa651 |
long :: HasName f => String -> Mod f a
|
|
Packit |
3fa651 |
long = fieldMod . name . OptLong
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Specify a default value for an option.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- /Note/: Because this modifier means the parser will never fail,
|
|
Packit |
3fa651 |
-- do not use it with combinators such as 'some' or 'many', as
|
|
Packit |
3fa651 |
-- these combinators continue until a failure occurs.
|
|
Packit |
3fa651 |
-- Careless use will thus result in a hang.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- To display the default value, combine with showDefault or
|
|
Packit |
3fa651 |
-- showDefaultWith.
|
|
Packit |
3fa651 |
value :: HasValue f => a -> Mod f a
|
|
Packit |
3fa651 |
value x = Mod id (DefaultProp (Just x) Nothing) id
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Specify a function to show the default value for an option.
|
|
Packit |
3fa651 |
showDefaultWith :: (a -> String) -> Mod f a
|
|
Packit |
3fa651 |
showDefaultWith s = Mod id (DefaultProp Nothing (Just s)) id
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Show the default value for this option using its 'Show' instance.
|
|
Packit |
3fa651 |
showDefault :: Show a => Mod f a
|
|
Packit |
3fa651 |
showDefault = showDefaultWith show
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Specify the help text for an option.
|
|
Packit |
3fa651 |
help :: String -> Mod f a
|
|
Packit |
3fa651 |
help s = optionMod $ \p -> p { propHelp = paragraph s }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Specify the help text for an option as a 'Text.PrettyPrint.ANSI.Leijen.Doc'
|
|
Packit |
3fa651 |
-- value.
|
|
Packit |
3fa651 |
helpDoc :: Maybe Doc -> Mod f a
|
|
Packit |
3fa651 |
helpDoc doc = optionMod $ \p -> p { propHelp = Chunk doc }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Specify the error to display when no argument is provided to this option.
|
|
Packit |
3fa651 |
noArgError :: ParseError -> Mod OptionFields a
|
|
Packit |
3fa651 |
noArgError e = fieldMod $ \p -> p { optNoArgError = const e }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Specify a metavariable for the argument.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- Metavariables have no effect on the actual parser, and only serve to specify
|
|
Packit |
3fa651 |
-- the symbolic name for an argument to be displayed in the help text.
|
|
Packit |
3fa651 |
metavar :: HasMetavar f => String -> Mod f a
|
|
Packit |
3fa651 |
metavar var = optionMod $ \p -> p { propMetaVar = var }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Hide this option from the brief description.
|
|
Packit |
3fa651 |
hidden :: Mod f a
|
|
Packit |
3fa651 |
hidden = optionMod $ \p ->
|
|
Packit |
3fa651 |
p { propVisibility = min Hidden (propVisibility p) }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Apply a function to the option description in the usage text.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- > import Options.Applicative.Help
|
|
Packit |
3fa651 |
-- > flag' () (short 't' <> style bold)
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- /NOTE/: This builder is more flexible than its name and example
|
|
Packit |
3fa651 |
-- allude. One of the motivating examples for its addition was to
|
|
Packit |
3fa651 |
-- used `const` to completely replace the usage text of an option.
|
|
Packit |
3fa651 |
style :: ( Doc -> Doc ) -> Mod f a
|
|
Packit |
3fa651 |
style x = optionMod $ \p ->
|
|
Packit |
3fa651 |
p { propDescMod = Just x }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Add a command to a subparser option.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- Suggested usage for multiple commands is to add them to a single subparser. e.g.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- @
|
|
Packit |
3fa651 |
-- sample :: Parser Sample
|
|
Packit |
3fa651 |
-- sample = subparser
|
|
Packit |
3fa651 |
-- ( command "hello"
|
|
Packit |
3fa651 |
-- (info hello (progDesc "Print greeting"))
|
|
Packit |
3fa651 |
-- <> command "goodbye"
|
|
Packit |
3fa651 |
-- (info goodbye (progDesc "Say goodbye"))
|
|
Packit |
3fa651 |
-- )
|
|
Packit |
3fa651 |
-- @
|
|
Packit |
3fa651 |
command :: String -> ParserInfo a -> Mod CommandFields a
|
|
Packit |
3fa651 |
command cmd pinfo = fieldMod $ \p ->
|
|
Packit |
3fa651 |
p { cmdCommands = (cmd, pinfo) : cmdCommands p }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Add a description to a group of commands.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- Advanced feature for separating logical groups of commands on the parse line.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- If using the same `metavar` for each group of commands, it may yield a more
|
|
Packit |
3fa651 |
-- attractive usage text combined with `hidden` for some groups.
|
|
Packit |
3fa651 |
commandGroup :: String -> Mod CommandFields a
|
|
Packit |
3fa651 |
commandGroup g = fieldMod $ \p ->
|
|
Packit |
3fa651 |
p { cmdGroup = Just g }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Add a list of possible completion values.
|
|
Packit |
3fa651 |
completeWith :: HasCompleter f => [String] -> Mod f a
|
|
Packit |
3fa651 |
completeWith = completer . listCompleter
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Add a bash completion action. Common actions include @file@ and
|
|
Packit |
3fa651 |
-- @directory@. See
|
|
Packit |
3fa651 |
-- <http://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html#Programmable-Completion-Builtins>
|
|
Packit |
3fa651 |
-- for a complete list.
|
|
Packit |
3fa651 |
action :: HasCompleter f => String -> Mod f a
|
|
Packit |
3fa651 |
action = completer . bashCompleter
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Add a completer to an argument.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- A completer is a function String -> IO String which, given a partial
|
|
Packit |
3fa651 |
-- argument, returns all possible completions for that argument.
|
|
Packit |
3fa651 |
completer :: HasCompleter f => Completer -> Mod f a
|
|
Packit |
3fa651 |
completer f = fieldMod $ modCompleter (`mappend` f)
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- parsers --
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Builder for a command parser. The 'command' modifier can be used to
|
|
Packit |
3fa651 |
-- specify individual commands.
|
|
Packit |
3fa651 |
subparser :: Mod CommandFields a -> Parser a
|
|
Packit |
3fa651 |
subparser m = mkParser d g rdr
|
|
Packit |
3fa651 |
where
|
|
Packit |
3fa651 |
Mod _ d g = metavar "COMMAND" `mappend` m
|
|
Packit |
3fa651 |
(groupName, cmds, subs) = mkCommand m
|
|
Packit |
3fa651 |
rdr = CmdReader groupName cmds subs
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Builder for an argument parser.
|
|
Packit |
3fa651 |
argument :: ReadM a -> Mod ArgumentFields a -> Parser a
|
|
Packit |
3fa651 |
argument p (Mod f d g) = mkParser d g (ArgReader rdr)
|
|
Packit |
3fa651 |
where
|
|
Packit |
3fa651 |
ArgumentFields compl = f (ArgumentFields mempty)
|
|
Packit |
3fa651 |
rdr = CReader compl p
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Builder for a 'String' argument.
|
|
Packit |
3fa651 |
strArgument :: IsString s => Mod ArgumentFields s -> Parser s
|
|
Packit |
3fa651 |
strArgument = argument str
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Builder for a flag parser.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- A flag that switches from a \"default value\" to an \"active value\" when
|
|
Packit |
3fa651 |
-- encountered. For a simple boolean value, use `switch` instead.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- /Note/: Because this parser will never fail, it can not be used with
|
|
Packit |
3fa651 |
-- combinators such as 'some' or 'many', as these combinators continue until
|
|
Packit |
3fa651 |
-- a failure occurs. See @flag'@.
|
|
Packit |
3fa651 |
flag :: a -- ^ default value
|
|
Packit |
3fa651 |
-> a -- ^ active value
|
|
Packit |
3fa651 |
-> Mod FlagFields a -- ^ option modifier
|
|
Packit |
3fa651 |
-> Parser a
|
|
Packit |
3fa651 |
flag defv actv m = flag' actv m <|> pure defv
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Builder for a flag parser without a default value.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- Same as 'flag', but with no default value. In particular, this flag will
|
|
Packit |
3fa651 |
-- never parse successfully by itself.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- It still makes sense to use it as part of a composite parser. For example
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- > length <$> many (flag' () (short 't'))
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- is a parser that counts the number of "-t" arguments on the command line,
|
|
Packit |
3fa651 |
-- alternatively
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- > flag' True (long "on") <|> flag' False (long "off")
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- will require the user to enter '--on' or '--off' on the command line.
|
|
Packit |
3fa651 |
flag' :: a -- ^ active value
|
|
Packit |
3fa651 |
-> Mod FlagFields a -- ^ option modifier
|
|
Packit |
3fa651 |
-> Parser a
|
|
Packit |
3fa651 |
flag' actv (Mod f d g) = mkParser d g rdr
|
|
Packit |
3fa651 |
where
|
|
Packit |
3fa651 |
rdr = let fields = f (FlagFields [] actv)
|
|
Packit |
3fa651 |
in FlagReader (flagNames fields)
|
|
Packit |
3fa651 |
(flagActive fields)
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Builder for a boolean flag.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- /Note/: Because this parser will never fail, it can not be used with
|
|
Packit |
3fa651 |
-- combinators such as 'some' or 'many', as these combinators continue until
|
|
Packit |
3fa651 |
-- a failure occurs. See @flag'@.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- > switch = flag False True
|
|
Packit |
3fa651 |
switch :: Mod FlagFields Bool -> Parser Bool
|
|
Packit |
3fa651 |
switch = flag False True
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | An option that always fails.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- When this option is encountered, the option parser immediately aborts with
|
|
Packit |
3fa651 |
-- the given parse error. If you simply want to output a message, use
|
|
Packit |
3fa651 |
-- 'infoOption' instead.
|
|
Packit |
3fa651 |
abortOption :: ParseError -> Mod OptionFields (a -> a) -> Parser (a -> a)
|
|
Packit |
3fa651 |
abortOption err m = option (readerAbort err) . (`mappend` m) $ mconcat
|
|
Packit |
3fa651 |
[ noArgError err
|
|
Packit |
3fa651 |
, value id
|
|
Packit |
3fa651 |
, metavar "" ]
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | An option that always fails and displays a message.
|
|
Packit |
3fa651 |
infoOption :: String -> Mod OptionFields (a -> a) -> Parser (a -> a)
|
|
Packit |
3fa651 |
infoOption = abortOption . InfoMsg
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Builder for an option taking a 'String' argument.
|
|
Packit |
3fa651 |
strOption :: IsString s => Mod OptionFields s -> Parser s
|
|
Packit |
3fa651 |
strOption = option str
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Same as 'option'.
|
|
Packit |
3fa651 |
{-# DEPRECATED nullOption "Use 'option' instead" #-}
|
|
Packit |
3fa651 |
nullOption :: ReadM a -> Mod OptionFields a -> Parser a
|
|
Packit |
3fa651 |
nullOption = option
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Builder for an option using the given reader.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- This is a regular option, and should always have either a @long@ or
|
|
Packit |
3fa651 |
-- @short@ name specified in the modifiers (or both).
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- > nameParser = option str ( long "name" <> short 'n' )
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
option :: ReadM a -> Mod OptionFields a -> Parser a
|
|
Packit |
3fa651 |
option r m = mkParser d g rdr
|
|
Packit |
3fa651 |
where
|
|
Packit |
3fa651 |
Mod f d g = metavar "ARG" `mappend` m
|
|
Packit |
3fa651 |
fields = f (OptionFields [] mempty ExpectsArgError)
|
|
Packit |
3fa651 |
crdr = CReader (optCompleter fields) r
|
|
Packit |
3fa651 |
rdr = OptReader (optNames fields) crdr (optNoArgError fields)
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Modifier for 'ParserInfo'.
|
|
Packit |
3fa651 |
newtype InfoMod a = InfoMod
|
|
Packit |
3fa651 |
{ applyInfoMod :: ParserInfo a -> ParserInfo a }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
instance Monoid (InfoMod a) where
|
|
Packit |
3fa651 |
mempty = InfoMod id
|
|
Packit |
3fa651 |
mappend = (<>)
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
instance Semigroup (InfoMod a) where
|
|
Packit |
3fa651 |
m1 <> m2 = InfoMod $ applyInfoMod m2 . applyInfoMod m1
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Show a full description in the help text of this parser.
|
|
Packit |
3fa651 |
fullDesc :: InfoMod a
|
|
Packit |
3fa651 |
fullDesc = InfoMod $ \i -> i { infoFullDesc = True }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Only show a brief description in the help text of this parser.
|
|
Packit |
3fa651 |
briefDesc :: InfoMod a
|
|
Packit |
3fa651 |
briefDesc = InfoMod $ \i -> i { infoFullDesc = False }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Specify a header for this parser.
|
|
Packit |
3fa651 |
header :: String -> InfoMod a
|
|
Packit |
3fa651 |
header s = InfoMod $ \i -> i { infoHeader = paragraph s }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Specify a header for this parser as a 'Text.PrettyPrint.ANSI.Leijen.Doc'
|
|
Packit |
3fa651 |
-- value.
|
|
Packit |
3fa651 |
headerDoc :: Maybe Doc -> InfoMod a
|
|
Packit |
3fa651 |
headerDoc doc = InfoMod $ \i -> i { infoHeader = Chunk doc }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Specify a footer for this parser.
|
|
Packit |
3fa651 |
footer :: String -> InfoMod a
|
|
Packit |
3fa651 |
footer s = InfoMod $ \i -> i { infoFooter = paragraph s }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Specify a footer for this parser as a 'Text.PrettyPrint.ANSI.Leijen.Doc'
|
|
Packit |
3fa651 |
-- value.
|
|
Packit |
3fa651 |
footerDoc :: Maybe Doc -> InfoMod a
|
|
Packit |
3fa651 |
footerDoc doc = InfoMod $ \i -> i { infoFooter = Chunk doc }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Specify a short program description.
|
|
Packit |
3fa651 |
progDesc :: String -> InfoMod a
|
|
Packit |
3fa651 |
progDesc s = InfoMod $ \i -> i { infoProgDesc = paragraph s }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Specify a short program description as a 'Text.PrettyPrint.ANSI.Leijen.Doc'
|
|
Packit |
3fa651 |
-- value.
|
|
Packit |
3fa651 |
progDescDoc :: Maybe Doc -> InfoMod a
|
|
Packit |
3fa651 |
progDescDoc doc = InfoMod $ \i -> i { infoProgDesc = Chunk doc }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Specify an exit code if a parse error occurs.
|
|
Packit |
3fa651 |
failureCode :: Int -> InfoMod a
|
|
Packit |
3fa651 |
failureCode n = InfoMod $ \i -> i { infoFailureCode = n }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Disable parsing of regular options after arguments. After a positional
|
|
Packit |
3fa651 |
-- argument is parsed, all remaining options and arguments will be treated
|
|
Packit |
3fa651 |
-- as a positional arguments. Not recommended in general as users often
|
|
Packit |
3fa651 |
-- expect to be able to freely intersperse regular options and flags within
|
|
Packit |
3fa651 |
-- command line options.
|
|
Packit |
3fa651 |
noIntersperse :: InfoMod a
|
|
Packit |
3fa651 |
noIntersperse = InfoMod $ \p -> p { infoPolicy = NoIntersperse }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Intersperse matched options and arguments normally, but allow unmatched
|
|
Packit |
3fa651 |
-- options to be treated as positional arguments.
|
|
Packit |
3fa651 |
-- This is sometimes useful if one is wrapping a third party cli tool and
|
|
Packit |
3fa651 |
-- needs to pass options through, while also providing a handful of their
|
|
Packit |
3fa651 |
-- own options. Not recommended in general as typos by the user may not
|
|
Packit |
3fa651 |
-- yield a parse error and cause confusion.
|
|
Packit |
3fa651 |
forwardOptions :: InfoMod a
|
|
Packit |
3fa651 |
forwardOptions = InfoMod $ \p -> p { infoPolicy = ForwardOptions }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Create a 'ParserInfo' given a 'Parser' and a modifier.
|
|
Packit |
3fa651 |
info :: Parser a -> InfoMod a -> ParserInfo a
|
|
Packit |
3fa651 |
info parser m = applyInfoMod m base
|
|
Packit |
3fa651 |
where
|
|
Packit |
3fa651 |
base = ParserInfo
|
|
Packit |
3fa651 |
{ infoParser = parser
|
|
Packit |
3fa651 |
, infoFullDesc = True
|
|
Packit |
3fa651 |
, infoProgDesc = mempty
|
|
Packit |
3fa651 |
, infoHeader = mempty
|
|
Packit |
3fa651 |
, infoFooter = mempty
|
|
Packit |
3fa651 |
, infoFailureCode = 1
|
|
Packit |
3fa651 |
, infoPolicy = Intersperse }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
newtype PrefsMod = PrefsMod
|
|
Packit |
3fa651 |
{ applyPrefsMod :: ParserPrefs -> ParserPrefs }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
instance Monoid PrefsMod where
|
|
Packit |
3fa651 |
mempty = PrefsMod id
|
|
Packit |
3fa651 |
mappend = (<>)
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
instance Semigroup PrefsMod where
|
|
Packit |
3fa651 |
m1 <> m2 = PrefsMod $ applyPrefsMod m2 . applyPrefsMod m1
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Include a suffix to attach to the metavar when multiple values
|
|
Packit |
3fa651 |
-- can be entered.
|
|
Packit |
3fa651 |
multiSuffix :: String -> PrefsMod
|
|
Packit |
3fa651 |
multiSuffix s = PrefsMod $ \p -> p { prefMultiSuffix = s }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Turn on disambiguation.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- See
|
|
Packit |
3fa651 |
-- https://github.com/pcapriotti/optparse-applicative#disambiguation
|
|
Packit |
3fa651 |
disambiguate :: PrefsMod
|
|
Packit |
3fa651 |
disambiguate = PrefsMod $ \p -> p { prefDisambiguate = True }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Show full help text on any error.
|
|
Packit |
3fa651 |
showHelpOnError :: PrefsMod
|
|
Packit |
3fa651 |
showHelpOnError = PrefsMod $ \p -> p { prefShowHelpOnError = True }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Show the help text if the user enters only the program name or
|
|
Packit |
3fa651 |
-- subcommand.
|
|
Packit |
3fa651 |
--
|
|
Packit |
3fa651 |
-- This will suppress a "Missing:" error and show the full usage
|
|
Packit |
3fa651 |
-- instead if a user just types the name of the program.
|
|
Packit |
3fa651 |
showHelpOnEmpty :: PrefsMod
|
|
Packit |
3fa651 |
showHelpOnEmpty = PrefsMod $ \p -> p { prefShowHelpOnEmpty = True }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Turn off backtracking after subcommand is parsed.
|
|
Packit |
3fa651 |
noBacktrack :: PrefsMod
|
|
Packit |
3fa651 |
noBacktrack = PrefsMod $ \p -> p { prefBacktrack = False }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Set the maximum width of the generated help text.
|
|
Packit |
3fa651 |
columns :: Int -> PrefsMod
|
|
Packit |
3fa651 |
columns cols = PrefsMod $ \p -> p { prefColumns = cols }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Create a `ParserPrefs` given a modifier
|
|
Packit |
3fa651 |
prefs :: PrefsMod -> ParserPrefs
|
|
Packit |
3fa651 |
prefs m = applyPrefsMod m base
|
|
Packit |
3fa651 |
where
|
|
Packit |
3fa651 |
base = ParserPrefs
|
|
Packit |
3fa651 |
{ prefMultiSuffix = ""
|
|
Packit |
3fa651 |
, prefDisambiguate = False
|
|
Packit |
3fa651 |
, prefShowHelpOnError = False
|
|
Packit |
3fa651 |
, prefShowHelpOnEmpty = False
|
|
Packit |
3fa651 |
, prefBacktrack = True
|
|
Packit |
3fa651 |
, prefColumns = 80 }
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- Convenience shortcuts
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Trivial option modifier.
|
|
Packit |
3fa651 |
idm :: Monoid m => m
|
|
Packit |
3fa651 |
idm = mempty
|
|
Packit |
3fa651 |
|
|
Packit |
3fa651 |
-- | Default preferences.
|
|
Packit |
3fa651 |
defaultPrefs :: ParserPrefs
|
|
Packit |
3fa651 |
defaultPrefs = prefs idm
|