optparse-applicative-0.12.0.0/0000755000000000000000000000000012601215511014244 5ustar0000000000000000optparse-applicative-0.12.0.0/CHANGELOG.md0000644000000000000000000002026212601215511016057 0ustar0000000000000000## Version 0.12.0.0 (17 Sep 2015) - Add "missing" error condition descriptions when required flags and arguments are not provided. - Allow multiple short flags to be concatenated together behind a single hyphen, e.g. "-xcf". - Updated dependency bounds on `process` and `ansi-wl-pprint`. - Add `Show` and `Eq` instances to some types for easier debugging. - Add defaultPrefs, a default preferences value - Docs. ## Version 0.11.0.2 (17 Feb 2015) - Updated dependency bounds. ## Version 0.11.0.1 (5 Oct 2014) - Updated documentation. ## Version 0.11.0 (4 Oct 2014) - Added Alternative instances for `Chunk` and `ReadM`. - The `ReadM` monad is now a `ReaderT` for the argument being parsed. User defined readers do not need to handle their argument explicitly, but can always access it using `readerAsk`. - Argument builders now take a `ReadM` parameter, just like options. - Fixed bugs * \#106 - argument should perhaps use `ReadM` ## Version 0.10.0 (1 Sep 2014) - Parser execution and help text generation are now more modular, and allow for greater customisation. - More consistent API for `option` and `argument` builders: now `option` takes a reader as argument, and `nullOption` is deprecated in favour of `option`. The `reader` modifier is gone. Quick migration guide: * `option` (without a `reader` modifier) => `option auto` * `nullOption` (without a `reader` modifier) => `option disabled` * `option`/`nullOption` (with a `reader r` modifier) => `option r`. - Added convenience builder `strArgument`, equivalent to `argument str`. - Removed functions deprecated from at least version 0.8.0. - Switched test infrastructure to `tasty`. - Fixed bugs * \#63 - Inconsistency between 'argument' and 'strOption' types ## Version 0.9.1.1 (31 Jul 2014) - Fixed bugs * \#97 - Version 0.9.1 fails test suite ## Version 0.9.1 (30 Jul 2014) - Documentation tweaks. - Added low-level function to handle parse results (pull request \#94). - `ParserResult` now has a `Show` instance (see issue \#95). - Fixed bugs * \#93 - Formatting problem for several sub-parsers ## Version 0.9.0 (23 May 2014) - The option returned by `abortOption` is now visible by default. ## Version 0.8.1 (5 May 2014) - Fixed bugs * \#74 - Missing newline ## Version 0.8.0.1 (19 Mar 2014) - Fixed bugs * \#73 - Release 0.8.0 is broken ## Version 0.8.0 (16 Mar 2014) - Help page formatting. Added `columns` preference modifier, which can be used to specify the number of columns in the output terminal. - Deprecated `arguments` and `arguments1` builders. Using `many` and `some` on a parser built using `argument` now returns a multiple argument parsers that behaves correctly with respect to `--`. - Fixed bugs * \#60 - runParser can't be called * \#64 - --help behaviour ## Version 0.7.0.2 (18 Oct 2013) - Fixed bugs * \#51 - Build fails with ghc 6.12.3 and ghc 7.0.4 ## Version 0.7.0.1 (18 Oct 2013) - Minor docs fixes ## Version 0.7.0 (17 Oct 2013) - Added builders for options that always fail. This makes it easier to create options that just print an error message or display some brief information and then exit (like `--version`). - Added `execParserMaybe` and `customExecParserMaybe` functions (pull request #49). - Fixed bugs * \#47 - Current master prints help text instead of error * \#48 - Can we have an eitherReader convenience function? * \#50 - In order parsing problems. * \#22 - Strict (no-intersperse) arguments ## Version 0.6.0 (11 Oct 2013) - Arguments are now always parsed in order. - Fixed bugs * \#40 - Add context information to error messages * \#41 - Readme uses old reader API * \#38 - Internal types leaking into public API * \#44 - Can the build input restriction process == 1.1.* be relaxed? * \#28 - Help for subcommands ## Version 0.5.2.1 (24 Dic 2012) - Minor docs fixes. ## Version 0.5.2 (23 Dic 2012) - Fixed compatibility with GHC 7.2. ## Version 0.5.1 (23 Dic 2012) - There is a new parser preference `noBacktrack`, that controls whether how a failure in a subparser is propagated. By default, an unknown option in a subparser causes the option to be looked up in parent parsers. When `noBacktrack` is used, this behavior is disabled. This is useful to implement subcommands that have no relations with their parent commands. - Fixed bugs * \#35 - Artifacts of "hidden" * \#31 - Backtracking on commands * \#25 - Allow for using Maybe in options types to specify optional arguments * \#34 - No simple/obvious way to add a --version switch * \#29 - Document Mod * \#26 - Improve docs for the `Arrow` interface ## Version 0.5.0 (22 Dic 2012) - Fewer GHC extensions required. - Improved error handling: unrecognized options now result in an error message. - By default, the full help text is not displayed on parse errors anymore. This behavior can be controlled with the `prefShowHelpOnError` field of `ParserPrefs`. - The `(&)` operator is now deprecated. Modifiers can still be combined using `(<>)` or `mappend`. - Fixed bugs * \#37 - Use (\<\>) instead of (&) in documentation ## Version 0.4.3 (09 Dic 2012) - Updated dependency bounds. ## Version 0.4.2 (26 Nov 2012) - Fixed bugs * \#27 - Please include the test source files in the cabal sdist tarball ## Version 0.4.1 (04 Sep 2012) - Fixed bugs * \#19 - Regression ## Version 0.4.0 (05 Aug 2012) - Brief help text for nested commands now shows the full command line. - Fixed inefficiency in the `arguments` parsers for long argument lists. - Added automatic [bash completion](https://github.com/pcapriotti/optparse-applicative/wiki/Bash-Completion). - Added `disambiguate` modifier for `prefs`, which enabled automatic disambiguation of option abbreviations. With disambiguation on, a command line like: foo --out will match an option called `--output`, as long as its the only one starting with the string `out`. - Added `briefDesc` modifier. - Fixed bugs * \#8 - Long options not disambiguated * \#10 - Shell completions * \#16 - Possible memory leak? ## Version 0.3.2 (31 Jul 2012) - Fixed bug where both branches of an alternative could be matched. - Improved brief help text for alternatives. ## Version 0.3.1 (30 Jul 2012) - Added new `showDefault` and `showDefaultWith` modifiers, which will result in the default value (if present) to be displayed in the help text. - Fixed bugs * \#12 - Optionally display default values in help ## Version 0.3.0 (30 Jul 2012) - Option modifiers are now instances of `Monoid` instead of `Category`. - Dropped dependencies on data-default and data-lens. - Fixed bugs * \#14 - "arguments" can no longer take a list as a default ## Version 0.2.0 (23 Jul 2012) - Parser is now an instance of Alternative. This makes it possible to build certain complex parsers that were not definable before. See `tests/Examples/Alternatives.hs` for a simple example. - Removed `multi` modifier. You can now use the `many` or `some` methods from `Alternative`, instead, to create parsers for options that can appear more than once. - Added new `flag'` builder that returns a flag without a default value. Although flags without default values were not useful before, with the addition of `Alternative` combinators, they do have valid use cases. - Added new `internal` modifier for options. An internal option is completely invisible in the help text. - Added a new `customExecParser` function, which takes an additional `ParserPrefs` parameter. At the moment, `ParserPrefs` can only be used to control how many-valued option metavars are displayed in the help text. Setting its `multiSuffix` field to e.g. `...` will result in an `arguments` parser description like `[METAVAR]...`. - Fixed bugs * \#6 - "arguments" swallows options * \#5 - Help formatting for "arguments" misleading ## Version 0.1.1 (21 Jul 2012) - New arrow interface - Fixed bugs * \#7 - "arguments" reads positional arguments in reverse ## Version 0.1.0 (07 Jul 2012) - Improved error reporting internals - Removed template-haskell dependency - Fixed bugs: * \#3 - No help for subparsers * \#4 - Extra empty lines around command list ## Version 0.0.1 (09 Jun 2012) - Initial release. optparse-applicative-0.12.0.0/LICENSE0000644000000000000000000000277012601215511015257 0ustar0000000000000000Copyright (c) 2012, Paolo Capriotti All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Paolo Capriotti nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. optparse-applicative-0.12.0.0/optparse-applicative.cabal0000644000000000000000000001065212601215511021370 0ustar0000000000000000name: optparse-applicative version: 0.12.0.0 synopsis: Utilities and combinators for parsing command line options description: Here is a simple example of an applicative option parser: . @ data Sample = Sample { hello :: String , quiet :: Bool } . sample :: Parser Sample sample = Sample \<$\> strOption ( long \"hello\" \<\> metavar \"TARGET\" \<\> help \"Target for the greeting\" ) \<*\> switch ( long \"quiet\" \<\> help \"Whether to be quiet\" ) @ . The parser is built using applicative style starting from a set of basic combinators. In this example, @hello@ is defined as an 'option' with a @String@ argument, while @quiet@ is a boolean 'flag' (called 'switch'). . A parser can be used like this: . @ greet :: Sample -> IO () greet (Sample h False) = putStrLn $ \"Hello, \" ++ h greet _ = return () . main :: IO () main = execParser opts \>\>= greet where opts = info (helper \<*\> sample) ( fullDesc \<\> progDesc \"Print a greeting for TARGET\" \<\> header \"hello - a test for optparse-applicative\" ) @ . The @greet@ function is the entry point of the program, while @opts@ is a complete description of the program, used when generating a help text. The 'helper' combinator takes any parser, and adds a @help@ option to it (which always fails). . The @hello@ option in this example is mandatory (since it doesn't have a default value), so running the program without any argument will display a help text: . >hello - a test for optparse-applicative > >Usage: hello --hello TARGET [--quiet] > Print a greeting for TARGET > >Available options: > -h,--help Show this help text > --hello TARGET Target for the greeting > --quiet Whether to be quiet . containing a short usage summary, and a detailed list of options with descriptions. license: BSD3 license-file: LICENSE author: Paolo Capriotti maintainer: paolo@capriotti.io copyright: (c) 2012-2014 Paolo Capriotti category: System build-type: Simple cabal-version: >= 1.8 extra-source-files: CHANGELOG.md README.md tests/Examples/Alternatives.hs tests/Examples/Cabal.hs tests/Examples/Commands.hs tests/Examples/Hello.hs tests/Examples/Formatting.hs tests/alt.err.txt tests/cabal.err.txt tests/commands.err.txt tests/commands_header.err.txt tests/commands_header_full.err.txt tests/hello.err.txt tests/formatting.err.txt tests/nested.err.txt tests/subparsers.err.txt homepage: https://github.com/pcapriotti/optparse-applicative bug-reports: https://github.com/pcapriotti/optparse-applicative/issues source-repository head type: git location: https://github.com/pcapriotti/optparse-applicative.git library exposed-modules: Options.Applicative, Options.Applicative.Arrows, Options.Applicative.BashCompletion, Options.Applicative.Builder, Options.Applicative.Builder.Completer, Options.Applicative.Builder.Internal, Options.Applicative.Common, Options.Applicative.Extra, Options.Applicative.Help, Options.Applicative.Help.Pretty, Options.Applicative.Help.Chunk, Options.Applicative.Help.Core, Options.Applicative.Help.Types, Options.Applicative.Types, Options.Applicative.Internal ghc-options: -Wall build-depends: base == 4.*, transformers >= 0.2 && < 0.5, transformers-compat >= 0.3 && < 0.5, process >= 1.0 && < 1.4, ansi-wl-pprint >= 0.6.6 && < 0.7 optparse-applicative-0.12.0.0/README.md0000644000000000000000000002632312601215511015531 0ustar0000000000000000# Applicative option parser This package contains utilities and combinators to define command line option parsers. [![Continuous Integration status][status-png]][status] [![Hackage page (downloads and API reference)][hackage-png]][hackage] **Table of Contents** - [Getting started](#getting-started) - [Supported options](#supported-options) - [Regular options](#regular-options) - [Flags](#flags) - [Arguments](#arguments) - [Commands](#commands) - [Option builders](#option-builders) - [Advanced features](#advanced-features) - [How it works](#how-it-works) ## Getting started Install with ```sh cabal install optparse-applicative ``` Here is a simple example of an applicative option parser: ```haskell import Options.Applicative data Sample = Sample { hello :: String , quiet :: Bool } sample :: Parser Sample sample = Sample <$> strOption ( long "hello" <> metavar "TARGET" <> help "Target for the greeting" ) <*> switch ( long "quiet" <> help "Whether to be quiet" ) ``` The parser is built using [applicative style][applicative] starting from a set of basic combinators. In this example, `hello` is defined as an option with a `String` argument, while `quiet` is a boolean flag (called `switch`). A parser can be used like this: ```haskell greet :: Sample -> IO () greet (Sample h False) = putStrLn $ "Hello, " ++ h greet _ = return () main :: IO () main = execParser opts >>= greet where opts = info (helper <*> sample) ( fullDesc <> progDesc "Print a greeting for TARGET" <> header "hello - a test for optparse-applicative" ) ``` The `greet` function is the entry point of the program, while `opts` is a complete description of the program, used when generating a help text. The `helper` combinator takes any parser, and adds a `help` option to it. The `hello` option in this example is mandatory (since it doesn't have a default value), so running the program without any argument will display a short option summary: Usage: hello --hello TARGET [--quiet] Running the program with the `--help` option will display the full help text: hello - a test for optparse-applicative Usage: hello --hello TARGET [--quiet] Print a greeting for TARGET Available options: -h,--help Show this help text --hello TARGET Target for the greeting --quiet Whether to be quiet containing a detailed list of options with descriptions. The specified metavars are used as placeholders for the option arguments, and can be referred to in the program description. This makes it possible to explicitly describe the connection between the options and the behaviour of the program. Parsers are instances of both `Applicative` and `Alternative`, and work with any generic combinator, like `many` and `some`. For example, to make a option return `Nothing` instead of failing when it's not supplied, you can use the `optional` combinator in `Control.Applicative`: ```haskell optional $ strOption ( long "output" <> metavar "DIRECTORY" ) ``` [applicative]: http://www.soi.city.ac.uk/~ross/papers/Applicative.html ## Supported options `optparse-applicative` supports four kinds of options: regular options, flags, arguments and commands. ### Regular options A **regular option** is an option which takes a single argument, parses it, and returns a value. A regular option can have a default value, which is used as the result if the option is not found in the command line. An option without a default value is considered mandatory, and produces an error when not found. Regular options can have **long** names, or **short** (one-character) names, which determine when the option matches and how the argument is extracted. An option with a long name (say "output") is specified on the command line as --output filename.txt or --output=filename.txt while a short name option (say "o") can be specified with -o filename.txt or -ofilename.txt Options can have more than one name, usually one long and one short, although you are free to create options with an arbitrary combination of long and short names. Regular options returning strings are the most common, and they can be created using the `strOption` builder. For example, ```haskell strOption ( long "output" <> short 'o' <> metavar "FILE" <> help "Write output to FILE" ) ``` creates a regular option with a string argument (which can be referred to as `FILE` in the help text and documentation), a long name "output" and a short name "o". See below for more information on the builder syntax and modifiers. A regular option can return an object of any type, and takes a *reader* parameter which specifies how the argument should be parsed. A common reader is `auto`, which assumes a `Read` instance for the return type and uses it to parse its argument. For example: ```haskell lineCount :: Parser Int lineCount = option auto ( long "lines" <> short 'n' <> metavar "K" <> help "Output the last K lines" ) ``` specifies a regular option with an `Int` argument. We added an explicit type annotation here, since without it the parser would have been polymorphic in the output type. There's usually no need to add type annotations, however, because the type will be normally inferred from the context in which the parser is used. You can also create a custom reader that doesn't use the `Read` typeclass, and use it to parse option arguments. A custom reader is a value in the `ReadM` monad. ```haskell data FluxCapacitor = ... parseFluxCapacitor :: Monad m => String -> m FluxCapacitor option (str >>= parseFluxCapacitor) ( long "flux-capacitor" ) ``` Use `readerAbort` or `readerError` within the `ReadM` monad to exit with an error message. ### Flags A **flag** is just like a regular option, but it doesn't take any arguments: it is either present in the command line or not. A flag has a default value and an **active value**. If the flag is found on the command line, the active value is returned, otherwise the default value is used. For example: ```haskell data Verbosity = Normal | Verbose flag Normal Verbose ( long "verbose" <> short 'v' <> help "Enable verbose mode" ) ``` is a flag parser returning a `Verbosity` value. Simple boolean flags can be specified using the `switch` builder, like so: ```haskell switch ( long "keep-tmp-files" <> help "Retain all intermediate temporary files" ) ``` There is also a `flag'` builder, which has no default value. For example, to add a `--version` switch to a program, you could write: ```haskell flag' Nothing (long "version" <> hidden) <|> (Just <$> normal_options) ``` ### Arguments An **argument** parser specifies a positional command line argument. The `argument` builder takes a reader parameter, and creates a parser which will return the parsed value every time it is passed a command line argument for which the reader succeeds. For example ```haskell argument str (metavar "FILE") ``` creates an argument accepting any string. To accept an arbitrary number of arguments, combine the `argument` builder with either the `many` or `some` combinator: ```haskell some (argument str (metavar "FILES...")) ``` Arguments are only displayed in the brief help text, so there's no need to attach a description to them. They should be manually documented in the program description. Note that arguments starting with `-` are considered options by default, and will not be considered by an `argument` parser. However, parsers always accept a special argument: `--`. When a `--` is found on the command line, all the following words are considered by `argument` parsers, regardless of whether they start with `-` or not. ### Commands A **command** can be used to specify a sub-parser to be used when a certain string is encountered in the command line. Commands are useful to implement command line programs with multiple functions, each with its own set of options, and possibly some global options that apply to all of them. Typical examples are version control systems like `git`, or build tools like `cabal`. A command can be created using the `subparser` builder, and commands can be added with the `command` modifier. For example ```haskell subparser ( command "add" (info addOptions ( progDesc "Add a file to the repository" )) <> command "commit" (info commitOptions ( progDesc "Record changes to the repository" )) ) ``` Each command takes a full `ParserInfo` structure, which will be used to extract a description for this command when generating a help text. Note that all the parsers appearing in a command need to have the same type. For this reason, it is often best to use a sum type which has the same structure as the command itself. For example, for the parser above, you would define a type like: ```haskell data Options = Options { optGlobalOpt :: String , optGlobalFlag :: Bool ... , optCommand :: Command } data Command = Add AddOptions | Commit CommitOptions ... ``` Alternatively, you can directly return an `IO` action from a parser, and execute it using `join` from `Control.Monad`. ```haskell start :: String -> IO () stop :: IO () opts :: Parser (IO ()) opts = subparser ( command "start" (info (start <$> argument str idm) idm) <> command "stop" (info (pure stop) idm) ) main :: IO () main = join $ execParser (info opts idm) ``` ## Option builders Builders allow you to define parsers using a convenient combinator-based syntax. Each builder takes a **modifier** as parameter, and returns a parser. A modifier is a composition of functions which act on the option, setting values for properties or adding features, and is used to build the option from scratch and finally lift it to a single-option parser, which can then be combined with other parsers using normal `Applicative` combinators. Modifiers are instances of the `Monoid` typeclass, so they can be combined using the composition function `mappend` (or simply `(<>)`). See the [haddock documentation][builder-documentation] for `Options.Applicative.Builder` for a full list of builders and modifiers. ## Advanced features * [Bash completion] * [Arrow interface] * [Disambiguation] [Bash completion]: https://github.com/pcapriotti/optparse-applicative/wiki/Bash-Completion [Arrow interface]: https://github.com/pcapriotti/optparse-applicative/wiki/Arrows [Disambiguation]: https://github.com/pcapriotti/optparse-applicative/wiki/Disambiguation ## How it works A `Parser a` is essentially a heterogeneous list of `Option`s, implemented with existential types. All options are therefore known statically (i.e. before parsing, not necessarily before runtime), and can, for example, be traversed to generate a help text. See [this blog post][blog] for a more detailed explanation based on a simplified implementation. [status-png]: https://api.travis-ci.org/pcapriotti/optparse-applicative.svg [status]: http://travis-ci.org/pcapriotti/optparse-applicative?branch=master [blog]: http://paolocapriotti.com/blog/2012/04/27/applicative-option-parser/ [builder-documentation]: http://hackage.haskell.org/package/optparse-applicative/docs/Options-Applicative-Builder.html [hackage-png]: http://img.shields.io/hackage/v/optparse-applicative.svg [hackage]: http://hackage.haskell.org/package/optparse-applicative optparse-applicative-0.12.0.0/Setup.hs0000644000000000000000000000005612601215511015701 0ustar0000000000000000import Distribution.Simple main = defaultMain optparse-applicative-0.12.0.0/Options/0000755000000000000000000000000012601215511015677 5ustar0000000000000000optparse-applicative-0.12.0.0/Options/Applicative.hs0000644000000000000000000000225112601215511020474 0ustar0000000000000000module Options.Applicative ( -- * Applicative option parsers -- -- | This is an empty module which simply re-exports all the public definitions -- of this package. -- -- See for a tutorial, -- and a general introduction to applicative option parsers. -- -- See the documentation of individual modules for more details. -- * Exported modules -- -- | The standard @Applicative@ module is re-exported here for convenience. module Control.Applicative, -- | Parser type and low-level parsing functionality. module Options.Applicative.Common, -- | Utilities to build parsers out of basic primitives. module Options.Applicative.Builder, -- | Common completion functions. module Options.Applicative.Builder.Completer, -- | Utilities to run parsers and display a help text. module Options.Applicative.Extra, ) where -- reexport Applicative here for convenience import Control.Applicative import Options.Applicative.Common import Options.Applicative.Builder import Options.Applicative.Builder.Completer import Options.Applicative.Extra {-# ANN module "HLint: ignore Use import/export shortcut" #-} optparse-applicative-0.12.0.0/Options/Applicative/0000755000000000000000000000000012601215511020140 5ustar0000000000000000optparse-applicative-0.12.0.0/Options/Applicative/Arrows.hs0000644000000000000000000000462512601215511021760 0ustar0000000000000000-- | This module contains an arrow interface for option parsers, which allows -- to define and combine parsers using the arrow notation and arrow -- combinators. -- -- The arrow syntax is particularly useful to create parsers of nested -- structures, or records where the order of fields is different from the order -- in which the parsers should be applied. -- -- For example, an 'Options.Applicative.Builder.arguments` parser often needs -- to be applied last, and that makes it inconvenient to use it for a field -- which is not the last one in a record. -- -- Using the arrow syntax and the functions in this module, one can write, e.g.: -- -- > data Options = Options -- > { optArgs :: [String] -- > , optVerbose :: Bool } -- > -- > opts :: Parser Options -- > opts = runA $ proc () -> do -- > verbose <- asA (switch (short 'v')) -< () -- > args <- asA (arguments str idm) -< () -- > returnA -< Options args verbose -- -- Parser arrows, created out of regular 'Parser' values using the 'asA' -- function, are arrows taking @()@ as argument and returning the parsed value. module Options.Applicative.Arrows ( module Control.Arrow, A(..), asA, runA, ParserA, ) where import Control.Arrow import Control.Category (Category(..)) import Options.Applicative import Prelude hiding ((.), id) -- | For any 'Applicative' functor @f@, @A f@ is the 'Arrow' instance -- associated to @f@. -- -- The 'A' constructor can be used to convert a value of type @f (a -> b)@ into -- an arrow. newtype A f a b = A { unA :: f (a -> b) } -- | Convert a value of type @f a@ into an arrow taking @()@ as argument. -- -- Applied to a value of type 'Parser', it turns it into an arrow that can be -- used inside an arrow command, or passed to arrow combinators. asA :: Applicative f => f a -> A f () a asA x = A $ const <$> x -- | Convert an arrow back to an applicative value. -- -- This function can be used to return a result of type 'Parser' from an arrow -- command. runA :: Applicative f => A f () a -> f a runA a = unA a <*> pure () instance Applicative f => Category (A f) where id = A $ pure id -- use reverse composition, because we want effects to run from -- top to bottom in the arrow syntax (A f) . (A g) = A $ flip (.) <$> g <*> f instance Applicative f => Arrow (A f) where arr = A . pure first (A f) = A $ first <$> f -- | The type of arrows associated to the applicative 'Parser' functor. type ParserA = A Parser optparse-applicative-0.12.0.0/Options/Applicative/BashCompletion.hs0000644000000000000000000000564412601215511023414 0ustar0000000000000000-- | You don't need to import this module to enable bash completion. -- -- See -- -- for more information on bash completion. module Options.Applicative.BashCompletion ( bashCompletionParser ) where import Control.Applicative ((<$>), (<*>), many) import Data.Foldable (asum) import Data.List (isPrefixOf) import Data.Maybe (fromMaybe, listToMaybe) import Options.Applicative.Builder import Options.Applicative.Common import Options.Applicative.Internal import Options.Applicative.Types bashCompletionParser :: ParserInfo a -> ParserPrefs -> Parser CompletionResult bashCompletionParser pinfo pprefs = complParser where failure opts = CompletionResult { execCompletion = \progn -> unlines <$> opts progn } complParser = asum [ failure <$> ( bashCompletionQuery pinfo pprefs <$> (many . strOption) (long "bash-completion-word" `mappend` internal) <*> option auto (long "bash-completion-index" `mappend` internal) ) , failure <$> (bashCompletionScript <$> strOption (long "bash-completion-script" `mappend` internal)) ] bashCompletionQuery :: ParserInfo a -> ParserPrefs -> [String] -> Int -> String -> IO [String] bashCompletionQuery pinfo pprefs ws i _ = case runCompletion compl pprefs of Just (Left (SomeParser p)) -> list_options p Just (Right c) -> run_completer c _ -> return [] where list_options = fmap concat . sequence . mapParser (const opt_completions) opt_completions opt = case optMain opt of OptReader ns _ _ -> return $ show_names ns FlagReader ns _ -> return $ show_names ns ArgReader rdr -> run_completer (crCompleter rdr) CmdReader ns _ -> return $ filter_names ns show_name :: OptName -> String show_name (OptShort c) = '-':[c] show_name (OptLong name) = "--" ++ name show_names :: [OptName] -> [String] show_names = filter_names . map show_name filter_names :: [String] -> [String] filter_names = filter is_completion run_completer :: Completer -> IO [String] run_completer c = runCompleter c (fromMaybe "" (listToMaybe ws'')) (ws', ws'') = splitAt i ws is_completion :: String -> Bool is_completion = case ws'' of w:_ -> isPrefixOf w _ -> const True compl = runParserInfo pinfo (drop 1 ws') bashCompletionScript :: String -> String -> IO [String] bashCompletionScript prog progn = return [ "_" ++ progn ++ "()" , "{" , " local cmdline" , " CMDLINE=(--bash-completion-index $COMP_CWORD)" , "" , " for arg in ${COMP_WORDS[@]}; do" , " CMDLINE=(${CMDLINE[@]} --bash-completion-word $arg)" , " done" , "" , " COMPREPLY=( $(" ++ prog ++ " \"${CMDLINE[@]}\") )" , "}" , "" , "complete -o filenames -F _" ++ progn ++ " " ++ progn ] optparse-applicative-0.12.0.0/Options/Applicative/Builder.hs0000644000000000000000000002661612601215511022075 0ustar0000000000000000{-# LANGUAGE CPP #-} module Options.Applicative.Builder ( -- * Parser builders -- -- | This module contains utility functions and combinators to create parsers -- for individual options. -- -- Each parser builder takes an option modifier. A modifier can be created by -- composing the basic modifiers provided by this module using the 'Monoid' -- operations 'mempty' and 'mappend', or their aliases 'idm' and '<>'. -- -- For example: -- -- > out = strOption -- > ( long "output" -- > <> short 'o' -- > <> metavar "FILENAME" ) -- -- creates a parser for an option called \"output\". subparser, strArgument, argument, flag, flag', switch, abortOption, infoOption, strOption, option, nullOption, -- * Modifiers short, long, help, helpDoc, value, showDefaultWith, showDefault, metavar, eitherReader, noArgError, ParseError(..), hidden, internal, command, completeWith, action, completer, idm, #if __GLASGOW_HASKELL__ > 702 (<>), #endif mappend, -- * Readers -- -- | A collection of basic 'Option' readers. auto, str, disabled, readerAbort, readerError, -- * Builder for 'ParserInfo' InfoMod, fullDesc, briefDesc, header, headerDoc, footer, footerDoc, progDesc, progDescDoc, failureCode, noIntersperse, info, -- * Builder for 'ParserPrefs' PrefsMod, multiSuffix, disambiguate, showHelpOnError, noBacktrack, columns, prefs, defaultPrefs, -- * Types 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 -- readers -- -- | 'Option' reader based on the 'Read' type class. auto :: Read a => ReadM a auto = eitherReader $ \arg -> case reads arg of [(r, "")] -> return r _ -> Left $ "cannot parse value `" ++ arg ++ "'" -- | String 'Option' reader. str :: ReadM String str = readerAsk -- | Null 'Option' reader. All arguments will fail validation. disabled :: ReadM a disabled = readerError "disabled option" -- modifiers -- -- | Specify a short name for an option. short :: HasName f => Char -> Mod f a short = fieldMod . name . OptShort -- | Specify a long name for an option. long :: HasName f => String -> Mod f a long = fieldMod . name . OptLong -- | Specify a default value for an option. -- -- /Note/: Because this modifier means the parser will never fail, -- do not use it with combinators such as 'some' or 'many', as -- these combinators continue until a failure occurs. -- Careless use will thus result in a hang. value :: HasValue f => a -> Mod f a value x = Mod id (DefaultProp (Just x) Nothing) id -- | Specify a function to show the default value for an option. showDefaultWith :: (a -> String) -> Mod f a showDefaultWith s = Mod id (DefaultProp Nothing (Just s)) id -- | Show the default value for this option using its 'Show' instance. showDefault :: Show a => Mod f a showDefault = showDefaultWith show -- | Specify the help text for an option. help :: String -> Mod f a help s = optionMod $ \p -> p { propHelp = paragraph s } -- | Specify the help text for an option as a 'Text.PrettyPrint.ANSI.Leijen.Doc' -- value. helpDoc :: Maybe Doc -> Mod f a helpDoc doc = optionMod $ \p -> p { propHelp = Chunk doc } -- | Convert a function in the 'Either' monad to a reader. eitherReader :: (String -> Either String a) -> ReadM a eitherReader f = readerAsk >>= either readerError return . f -- | Specify the error to display when no argument is provided to this option. noArgError :: ParseError -> Mod OptionFields a noArgError e = fieldMod $ \p -> p { optNoArgError = e } -- | Specify a metavariable for the argument. -- -- Metavariables have no effect on the actual parser, and only serve to specify -- the symbolic name for an argument to be displayed in the help text. metavar :: HasMetavar f => String -> Mod f a metavar var = optionMod $ \p -> p { propMetaVar = var } -- | Hide this option from the brief description. hidden :: Mod f a hidden = optionMod $ \p -> p { propVisibility = min Hidden (propVisibility p) } -- | Add a command to a subparser option. command :: String -> ParserInfo a -> Mod CommandFields a command cmd pinfo = fieldMod $ \p -> p { cmdCommands = (cmd, pinfo) : cmdCommands p } -- | Add a list of possible completion values. completeWith :: HasCompleter f => [String] -> Mod f a completeWith xs = completer (listCompleter xs) -- | Add a bash completion action. Common actions include @file@ and -- @directory@. See -- -- for a complete list. action :: HasCompleter f => String -> Mod f a action act = completer (bashCompleter act) -- | Add a completer to an argument. -- -- A completer is a function String -> IO String which, given a partial -- argument, returns all possible completions for that argument. completer :: HasCompleter f => Completer -> Mod f a completer f = fieldMod $ modCompleter (`mappend` f) -- parsers -- -- | Builder for a command parser. The 'command' modifier can be used to -- specify individual commands. 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) -- | Builder for an argument parser. 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 -- | Builder for a 'String' argument. strArgument :: Mod ArgumentFields String -> Parser String strArgument = argument str -- | Builder for a flag parser. -- -- A flag that switches from a \"default value\" to an \"active value\" when -- encountered. For a simple boolean value, use `switch` instead. flag :: a -- ^ default value -> a -- ^ active value -> Mod FlagFields a -- ^ option modifier -> Parser a flag defv actv m = flag' actv m <|> pure defv -- | Builder for a flag parser without a default value. -- -- Same as 'flag', but with no default value. In particular, this flag will -- never parse successfully by itself. -- -- It still makes sense to use it as part of a composite parser. For example -- -- > length <$> many (flag' () (short 't')) -- -- is a parser that counts the number of "-t" arguments on the command line. flag' :: a -- ^ active value -> Mod FlagFields a -- ^ option modifier -> 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) -- | Builder for a boolean flag. -- -- > switch = flag False True switch :: Mod FlagFields Bool -> Parser Bool switch = flag False True -- | An option that always fails. -- -- When this option is encountered, the option parser immediately aborts with -- the given parse error. If you simply want to output a message, use -- 'infoOption' instead. abortOption :: ParseError -> Mod OptionFields (a -> a) -> Parser (a -> a) abortOption err m = option (readerAbort err) . (`mappend` m) $ mconcat [ noArgError err , value id , metavar "" ] -- | An option that always fails and displays a message. infoOption :: String -> Mod OptionFields (a -> a) -> Parser (a -> a) infoOption = abortOption . InfoMsg -- | Builder for an option taking a 'String' argument. strOption :: Mod OptionFields String -> Parser String strOption = option str -- | Same as 'option'. {-# DEPRECATED nullOption "Use 'option' instead" #-} nullOption :: ReadM a -> Mod OptionFields a -> Parser a nullOption = option -- | Builder for an option using the given reader. 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) -- | Modifier for 'ParserInfo'. 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 -- | Show a full description in the help text of this parser. fullDesc :: InfoMod a fullDesc = InfoMod $ \i -> i { infoFullDesc = True } -- | Only show a brief description in the help text of this parser. briefDesc :: InfoMod a briefDesc = InfoMod $ \i -> i { infoFullDesc = False } -- | Specify a header for this parser. header :: String -> InfoMod a header s = InfoMod $ \i -> i { infoHeader = paragraph s } -- | Specify a header for this parser as a 'Text.PrettyPrint.ANSI.Leijen.Doc' -- value. headerDoc :: Maybe Doc -> InfoMod a headerDoc doc = InfoMod $ \i -> i { infoHeader = Chunk doc } -- | Specify a footer for this parser. footer :: String -> InfoMod a footer s = InfoMod $ \i -> i { infoFooter = paragraph s } -- | Specify a footer for this parser as a 'Text.PrettyPrint.ANSI.Leijen.Doc' -- value. footerDoc :: Maybe Doc -> InfoMod a footerDoc doc = InfoMod $ \i -> i { infoFooter = Chunk doc } -- | Specify a short program description. progDesc :: String -> InfoMod a progDesc s = InfoMod $ \i -> i { infoProgDesc = paragraph s } -- | Specify a short program description as a 'Text.PrettyPrint.ANSI.Leijen.Doc' -- value. progDescDoc :: Maybe Doc -> InfoMod a progDescDoc doc = InfoMod $ \i -> i { infoProgDesc = Chunk doc } -- | Specify an exit code if a parse error occurs. failureCode :: Int -> InfoMod a failureCode n = InfoMod $ \i -> i { infoFailureCode = n } -- | Disable parsing of regular options after arguments noIntersperse :: InfoMod a noIntersperse = InfoMod $ \p -> p { infoIntersperse = False } -- | Create a 'ParserInfo' given a 'Parser' and a modifier. 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 } -- convenience shortcuts -- | Trivial option modifier. idm :: Monoid m => m idm = mempty -- | Default preferences. defaultPrefs :: ParserPrefs defaultPrefs = prefs idm optparse-applicative-0.12.0.0/Options/Applicative/Common.hs0000644000000000000000000003005512601215511021727 0ustar0000000000000000{-# LANGUAGE Rank2Types #-} module Options.Applicative.Common ( -- * Option parsers -- -- | A 'Parser' is composed of a list of options. Several kinds of options -- are supported: -- -- * Flags: simple no-argument options. When a flag is encountered on the -- command line, its value is returned. -- -- * Options: options with an argument. An option can define a /reader/, -- which converts its argument from String to the desired value, or throws a -- parse error if the argument does not validate correctly. -- -- * Arguments: positional arguments, validated in the same way as option -- arguments. -- -- * Commands. A command defines a completely independent sub-parser. When a -- command is encountered, the whole command line is passed to the -- corresponding parser. -- Parser, liftOpt, showOption, -- * Program descriptions -- -- A 'ParserInfo' describes a command line program, used to generate a help -- screen. Two help modes are supported: brief and full. In brief mode, only -- an option and argument summary is displayed, while in full mode each -- available option and command, including hidden ones, is described. -- -- A basic 'ParserInfo' with default values for fields can be created using -- the 'info' function. -- -- A 'ParserPrefs' contains general preferences for all command-line -- options, and can be built with the 'prefs' function. ParserInfo(..), ParserPrefs(..), -- * Running parsers runParserInfo, runParserFully, runParser, evalParser, -- * Low-level utilities mapParser, treeMapParser, optionNames, optDesc, OptDescStyle (..) ) where import Control.Applicative (pure, (<*>), (<$>), (<|>), (<$)) import Control.Arrow (left) import Control.Monad (guard, mzero, msum, when, liftM) import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.State (StateT(..), get, put, runStateT) import Data.List (isPrefixOf, sort, intersperse) import Data.Maybe (maybeToList) import Data.Monoid (Monoid(..)) import Options.Applicative.Internal import Options.Applicative.Types import Options.Applicative.Help.Pretty import Options.Applicative.Help.Chunk showOption :: OptName -> String showOption (OptLong n) = "--" ++ n showOption (OptShort n) = '-' : [n] optionNames :: OptReader a -> [OptName] optionNames (OptReader names _ _) = names optionNames (FlagReader names _) = names optionNames _ = [] isOptionPrefix :: OptName -> OptName -> Bool isOptionPrefix (OptShort x) (OptShort y) = x == y isOptionPrefix (OptLong x) (OptLong y) = x `isPrefixOf` y isOptionPrefix _ _ = False -- | Create a parser composed of a single option. liftOpt :: Option a -> Parser a liftOpt = OptP data MatchResult = NoMatch | Match (Maybe String) instance Monoid MatchResult where mempty = NoMatch mappend m@(Match _) _ = m mappend _ m = m argMatches :: MonadP m => OptReader a -> String -> Maybe (StateT Args m a) argMatches opt arg = case opt of ArgReader rdr -> Just $ do result <- lift $ runReadM (crReader rdr) arg return result CmdReader _ f -> flip fmap (f arg) $ \subp -> StateT $ \args -> do setContext (Just arg) subp prefs <- getPrefs let runSubparser | prefBacktrack prefs = \i a -> runParser (getPolicy i) (infoParser i) a | otherwise = \i a -> (,) <$> runParserInfo i a <*> pure [] runSubparser subp args _ -> Nothing optMatches :: MonadP m => Bool -> OptReader a -> OptWord -> Maybe (StateT Args m a) optMatches disambiguate opt (OptWord arg1 val) = case opt of OptReader names rdr no_arg_err -> do guard $ has_name arg1 names Just $ do args <- get let mb_args = uncons $ maybeToList val ++ args let missing_arg = lift $ missingArgP no_arg_err (crCompleter rdr) (arg', args') <- maybe missing_arg return mb_args put args' lift $ runReadM (withReadM (errorFor arg1) (crReader rdr)) arg' FlagReader names x -> do guard $ has_name arg1 names Just $ do args <- get let val' = (\s -> '-' : s) <$> val put $ maybeToList val' ++ args return x _ -> Nothing where errorFor name msg = "option " ++ showOption name ++ ": " ++ msg has_name a | disambiguate = any (isOptionPrefix a) | otherwise = elem a isArg :: OptReader a -> Bool isArg (ArgReader _) = True isArg _ = False data OptWord = OptWord OptName (Maybe String) parseWord :: String -> Maybe OptWord parseWord ('-' : '-' : w) = Just $ let (opt, arg) = case span (/= '=') w of (_, "") -> (w, Nothing) (w', _ : rest) -> (w', Just rest) in OptWord (OptLong opt) arg parseWord ('-' : w) = case w of [] -> Nothing (a : rest) -> Just $ let arg = rest <$ guard (not (null rest)) in OptWord (OptShort a) arg parseWord _ = Nothing searchParser :: Monad m => ParserPrefs -> (forall r . Option r -> NondetT m r) -> Parser a -> NondetT m (Parser a) searchParser _ _ (NilP _) = mzero searchParser _ f (OptP opt) = liftM pure (f opt) searchParser pprefs f (MultP p1 p2) = foldr1 () [ do p1' <- searchParser pprefs f p1 return (p1' <*> p2) , do p2' <- searchParser pprefs f p2 return (p1 <*> p2') ] searchParser pprefs f (AltP p1 p2) = msum [ searchParser pprefs f p1 , searchParser pprefs f p2 ] searchParser pprefs f (BindP p k) = do p' <- searchParser pprefs f p case (evalParser False False (optDesc pprefs missingStyle) p') of Left _ -> mzero Right aa -> pure $ k aa searchOpt :: MonadP m => ParserPrefs -> OptWord -> Parser a -> NondetT (StateT Args m) (Parser a) searchOpt pprefs w = searchParser pprefs $ \opt -> do let disambiguate = prefDisambiguate pprefs && optVisibility opt > Internal case optMatches disambiguate (optMain opt) w of Just matcher -> lift matcher Nothing -> mzero searchArg :: MonadP m => ParserPrefs -> String -> Parser a -> NondetT (StateT Args m) (Parser a) searchArg pprefs arg = searchParser pprefs $ \opt -> do when (isArg (optMain opt)) cut case argMatches (optMain opt) arg of Just matcher -> lift matcher Nothing -> mzero stepParser :: MonadP m => ParserPrefs -> ArgPolicy -> String -> Parser a -> NondetT (StateT Args m) (Parser a) stepParser pprefs SkipOpts arg p = case parseWord arg of Just w -> searchOpt pprefs w p Nothing -> searchArg pprefs arg p stepParser pprefs AllowOpts arg p = msum [ searchArg pprefs arg p , do w <- hoistMaybe (parseWord arg) searchOpt pprefs w p ] -- | Apply a 'Parser' to a command line, and return a result and leftover -- arguments. This function returns an error if any parsing error occurs, or -- if any options are missing and don't have a default value. runParser :: MonadP m => ArgPolicy -> Parser a -> Args -> m (a, Args) runParser SkipOpts p ("--" : argt) = runParser AllowOpts p argt runParser policy p args = case args of [] -> do prefs <- getPrefs exitP p $ MissingError `left` result prefs (arg : argt) -> do prefs <- getPrefs (mp', args') <- do_step prefs arg argt case mp' of Nothing -> hoistEither (MissingError `left` (result prefs)) <|> parseError arg Just p' -> runParser policy p' args' where result (prefs') = (,) <$> evalParser False False (optDesc prefs' missingStyle) p <*> pure args do_step prefs arg argt = (`runStateT` argt) . disamb (not (prefDisambiguate prefs)) $ stepParser prefs policy arg p parseError :: MonadP m => String -> m a parseError arg = errorP . ErrorMsg $ msg where msg = case arg of ('-':_) -> "Invalid option `" ++ arg ++ "'" _ -> "Invalid argument `" ++ arg ++ "'" getPolicy :: ParserInfo a -> ArgPolicy getPolicy i = if infoIntersperse i then SkipOpts else AllowOpts runParserInfo :: MonadP m => ParserInfo a -> Args -> m a runParserInfo i = runParserFully (getPolicy i) (infoParser i) runParserFully :: MonadP m => ArgPolicy -> Parser a -> Args -> m a runParserFully policy p args = do (r, args') <- runParser policy p args guard $ null args' return r -- | The default value of a 'Parser'. This function returns an error if any of -- the options don't have a default value. evalParser :: Bool -> Bool -> (forall x . OptHelpInfo -> Option x -> b) -> Parser a -> Either (OptTree b) a evalParser _ _ _ (NilP r) = maybeToEither (MultNode []) r evalParser m d f (OptP opt) | optVisibility opt > Internal = Left $ Leaf (f (OptHelpInfo m d) opt) | otherwise = Left $ MultNode [] evalParser m d f (MultP p1 p2) = case evalParser m d f p1 <*> evalParser m d f p2 of Right a -> Right a Left _ -> case (evalParser m d f p1, evalParser m d f p2) of (Left a', Left b') -> Left $ MultNode [a', b'] (Left a', _) -> Left $ MultNode [a'] (_, Left b') -> Left $ MultNode [b'] _ -> Left $ MultNode [] evalParser m d f (AltP p1 p2) = case (evalParser m d f p1, evalParser m d f p2) of (Right a', _) -> Right a' (_, Right b') -> Right b' (Left a', Left b') -> Left $ AltNode [a', b'] evalParser _ d f (BindP p k) = evalParser True d f p >>= (evalParser True d f) . k -- | Map a polymorphic function over all the options of a parser, and collect -- the results in a list. mapParser :: (forall x. OptHelpInfo -> Option x -> b) -> Parser a -> [b] mapParser f = flatten . treeMapParser f where flatten (Leaf x) = [x] flatten (MultNode xs) = xs >>= flatten flatten (AltNode xs) = xs >>= flatten -- | Like 'mapParser', but collect the results in a tree structure. treeMapParser :: (forall x . OptHelpInfo -> Option x -> b) -> Parser a -> OptTree b treeMapParser g = simplify . go False False g where has_default :: Parser a -> Bool has_default p = either (const False) (const True) (evalParser False False g p) go :: Bool -> Bool -> (forall x . OptHelpInfo -> Option x -> b) -> Parser a -> OptTree b go _ _ _ (NilP _) = MultNode [] go m d f (OptP opt) | optVisibility opt > Internal = Leaf (f (OptHelpInfo m d) opt) | otherwise = MultNode [] go m d f (MultP p1 p2) = MultNode [go m d f p1, go m d f p2] go m d f (AltP p1 p2) = AltNode [go m d' f p1, go m d' f p2] where d' = d || has_default p1 || has_default p2 go _ d f (BindP p _) = go True d f p simplify :: OptTree a -> OptTree a simplify (Leaf x) = Leaf x simplify (MultNode xs) = case concatMap (remove_mult . simplify) xs of [x] -> x xs' -> MultNode xs' where remove_mult (MultNode ts) = ts remove_mult t = [t] simplify (AltNode xs) = case concatMap (remove_alt . simplify) xs of [] -> MultNode [] [x] -> x xs' -> AltNode xs' where remove_alt (AltNode ts) = ts remove_alt (MultNode []) = [] remove_alt t = [t] -- | Style for rendering an option. data OptDescStyle = OptDescStyle { descSep :: Doc , descHidden :: Bool , descSurround :: Bool } -- | Generate description for a single option. optDesc :: ParserPrefs -> OptDescStyle -> OptHelpInfo -> Option a -> Chunk Doc optDesc pprefs style info opt = let ns = optionNames $ optMain opt mv = stringChunk $ optMetaVar opt descs = map (string . showOption) (sort ns) desc' = listToChunk (intersperse (descSep style) descs) <<+>> mv show_opt | optVisibility opt == Hidden = descHidden style | otherwise = optVisibility opt == Visible suffix | hinfoMulti info = stringChunk . prefMultiSuffix $ pprefs | otherwise = mempty render chunk | not show_opt = mempty | isEmpty chunk || not (descSurround style) = mappend chunk suffix | hinfoDefault info = mappend (fmap brackets chunk) suffix | null (drop 1 descs) = mappend chunk suffix | otherwise = mappend (fmap parens chunk) suffix in render desc' missingStyle :: OptDescStyle missingStyle = OptDescStyle { descSep = string "|" , descHidden = False , descSurround = True } maybeToEither :: b -> Maybe a -> Either b a maybeToEither = flip maybe Right . Left optparse-applicative-0.12.0.0/Options/Applicative/Extra.hs0000644000000000000000000001471012601215511021562 0ustar0000000000000000{-# LANGUAGE RankNTypes #-} module Options.Applicative.Extra ( -- * Extra parser utilities -- -- | This module contains high-level functions to run parsers. helper, hsubparser, execParser, execParserMaybe, customExecParser, customExecParserMaybe, execParserPure, getParseResult, handleParseResult, parserFailure, renderFailure, ParserFailure(..), overFailure, ParserResult(..), ParserPrefs(..), CompletionResult(..), ) where import Control.Applicative (pure, (<$>), (<|>), (<**>)) import Data.Monoid (mempty, mconcat) import System.Environment (getArgs, getProgName) import System.Exit (exitSuccess, exitWith, ExitCode(..)) import System.IO (hPutStrLn, stderr) import Options.Applicative.BashCompletion import Options.Applicative.Builder hiding (briefDesc) import Options.Applicative.Builder.Internal import Options.Applicative.Common import Options.Applicative.Help import Options.Applicative.Internal import Options.Applicative.Types -- | A hidden \"helper\" option which always fails. helper :: Parser (a -> a) helper = abortOption ShowHelpText $ mconcat [ long "help" , short 'h' , help "Show this help text" , hidden ] hsubparser :: Mod CommandFields a -> Parser a hsubparser m = mkParser d g rdr where Mod _ d g = m `mappend` metavar "COMMAND" (cmds, subs) = mkCommand m rdr = CmdReader cmds (fmap add_helper . subs) add_helper pinfo = pinfo { infoParser = infoParser pinfo <**> helper } -- | Run a program description. -- -- Parse command line arguments. Display help text and exit if any parse error -- occurs. execParser :: ParserInfo a -> IO a execParser = customExecParser defaultPrefs -- | Run a program description with custom preferences. customExecParser :: ParserPrefs -> ParserInfo a -> IO a customExecParser pprefs pinfo = execParserPure pprefs pinfo <$> getArgs >>= handleParseResult -- | Handle `ParserResult`. handleParseResult :: ParserResult a -> IO a handleParseResult (Success a) = return a handleParseResult (Failure failure) = do progn <- getProgName let (msg, exit) = renderFailure failure progn case exit of ExitSuccess -> putStrLn msg _ -> hPutStrLn stderr msg exitWith exit handleParseResult (CompletionInvoked compl) = do progn <- getProgName msg <- execCompletion compl progn putStr msg exitSuccess -- | Extract the actual result from a `ParserResult` value. -- -- This function returns 'Nothing' in case of errors. Possible error messages -- or completion actions are simply discarded. -- -- If you want to display error messages and invoke completion actions -- appropriately, use 'handleParseResult' instead. getParseResult :: ParserResult a -> Maybe a getParseResult (Success a) = Just a getParseResult _ = Nothing -- | Run a program description in pure code. -- -- This function behaves like 'execParser', but can be called from pure code. -- Note that, in case of errors, no message is displayed, and this function -- simply returns 'Nothing'. -- -- If you need to keep track of error messages, use 'execParserPure' instead. {-# DEPRECATED execParserMaybe "Use execParserPure together with getParseResult instead" #-} execParserMaybe :: ParserInfo a -> [String] -> Maybe a execParserMaybe = customExecParserMaybe defaultPrefs -- | Run a program description with custom preferences in pure code. -- -- See 'execParserMaybe' for details. {-# DEPRECATED customExecParserMaybe "Use execParserPure together with getParseResult instead" #-} customExecParserMaybe :: ParserPrefs -> ParserInfo a -> [String] -> Maybe a customExecParserMaybe pprefs pinfo args = getParseResult $ execParserPure pprefs pinfo args -- | The most general way to run a program description in pure code. execParserPure :: ParserPrefs -- ^ Global preferences for this parser -> ParserInfo a -- ^ Description of the program to run -> [String] -- ^ Program arguments -> ParserResult a execParserPure pprefs pinfo args = case runP p pprefs of (Right (Right r), _) -> Success r (Right (Left c), _) -> CompletionInvoked c (Left err, ctx) -> Failure $ parserFailure pprefs pinfo err ctx where pinfo' = pinfo { infoParser = (Left <$> bashCompletionParser pinfo pprefs) <|> (Right <$> infoParser pinfo) } p = runParserInfo pinfo' args -- | Generate a `ParserFailure` from a `ParseError` in a given `Context`. -- -- This function can be used, for example, to show the help text for a parser: -- -- @handleParseResult . Failure $ parserFailure pprefs pinfo ShowHelpText mempty@ parserFailure :: ParserPrefs -> ParserInfo a -> ParseError -> Context -> ParserFailure ParserHelp parserFailure pprefs pinfo msg ctx = ParserFailure $ \progn -> let h = with_context ctx pinfo $ \names pinfo' -> mconcat [ base_help pinfo' , usage_help progn names pinfo' , error_help ] in (h, exit_code, prefColumns pprefs) where exit_code = case msg of ErrorMsg _ -> ExitFailure (infoFailureCode pinfo) UnknownError -> ExitFailure (infoFailureCode pinfo) MissingError _ -> ExitFailure (infoFailureCode pinfo) ShowHelpText -> ExitSuccess InfoMsg _ -> ExitSuccess with_context :: Context -> ParserInfo a -> (forall b . [String] -> ParserInfo b -> c) -> c with_context NullContext i f = f [] i with_context (Context n i) _ f = f n i usage_help progn names i = case msg of InfoMsg _ -> mempty _ -> usageHelp $ vcatChunks [ pure . parserUsage pprefs (infoParser i) . unwords $ progn : names , fmap (indent 2) . infoProgDesc $ i ] error_help = errorHelp $ case msg of ShowHelpText -> mempty ErrorMsg m -> stringChunk m InfoMsg m -> stringChunk m MissingError x -> stringChunk "Missing:" <<+>> fold_tree x UnknownError -> mempty base_help :: ParserInfo a -> ParserHelp base_help i | show_full_help = mconcat [h, f, parserHelp pprefs (infoParser i)] | otherwise = mempty where h = headerHelp (infoHeader i) f = footerHelp (infoFooter i) show_full_help = case msg of ShowHelpText -> True _ -> prefShowHelpOnError pprefs renderFailure :: ParserFailure ParserHelp -> String -> (String, ExitCode) renderFailure failure progn = let (h, exit, cols) = execFailure failure progn in (renderHelp cols h, exit) optparse-applicative-0.12.0.0/Options/Applicative/Help.hs0000644000000000000000000000034412601215511021365 0ustar0000000000000000module Options.Applicative.Help ( module X ) where import Options.Applicative.Help.Pretty as X import Options.Applicative.Help.Chunk as X import Options.Applicative.Help.Types as X import Options.Applicative.Help.Core as X optparse-applicative-0.12.0.0/Options/Applicative/Internal.hs0000644000000000000000000001644712601215511022264 0ustar0000000000000000{-# LANGUAGE ExistentialQuantification #-} module Options.Applicative.Internal ( P , Context(..) , MonadP(..) , ParseError(..) , uncons , hoistMaybe , hoistEither , runReadM , withReadM , runP , Completion , runCompletion , SomeParser(..) , ComplError(..) , ListT , takeListT , runListT , NondetT , cut , () , disamb ) where import Control.Applicative (Applicative(..), Alternative(..), (<$>)) import Control.Monad (MonadPlus(..), liftM, ap, guard) import Control.Monad.Trans.Class (MonadTrans, lift) import Control.Monad.Trans.Except (runExcept, runExceptT, withExcept, ExceptT(..), throwE, catchE) import Control.Monad.Trans.Reader (mapReaderT, runReader, runReaderT, Reader, ReaderT, ask) import Control.Monad.Trans.Writer (runWriterT, WriterT, tell) import Control.Monad.Trans.State (StateT, get, put, evalStateT) import Data.Maybe (maybeToList) import Data.Monoid (Monoid(..)) import Options.Applicative.Types class (Alternative m, MonadPlus m) => MonadP m where setContext :: Maybe String -> ParserInfo a -> m () getPrefs :: m ParserPrefs missingArgP :: ParseError -> Completer -> m a tryP :: m a -> m (Either ParseError a) errorP :: ParseError -> m a exitP :: Parser b -> Either ParseError a -> m a newtype P a = P (ExceptT ParseError (WriterT Context (Reader ParserPrefs)) a) instance Functor P where fmap f (P m) = P $ fmap f m instance Applicative P where pure a = P $ pure a P f <*> P a = P $ f <*> a instance Alternative P where empty = P empty P x <|> P y = P $ x <|> y instance Monad P where return a = P $ return a P x >>= k = P $ x >>= \a -> case k a of P y -> y instance MonadPlus P where mzero = P mzero mplus (P x) (P y) = P $ mplus x y data Context = forall a . Context [String] (ParserInfo a) | NullContext contextNames :: Context -> [String] contextNames (Context ns _) = ns contextNames NullContext = [] instance Monoid Context where mempty = NullContext mappend c (Context ns i) = Context (contextNames c ++ ns) i mappend c _ = c instance MonadP P where setContext name = P . lift . tell . Context (maybeToList name) getPrefs = P . lift . lift $ ask missingArgP e _ = errorP e tryP (P p) = P $ lift $ runExceptT p exitP _ = P . (either throwE return) errorP = P . throwE hoistMaybe :: MonadPlus m => Maybe a -> m a hoistMaybe = maybe mzero return hoistEither :: MonadP m => Either ParseError a -> m a hoistEither = either errorP return runP :: P a -> ParserPrefs -> (Either ParseError a, Context) runP (P p) = runReader . runWriterT . runExceptT $ p uncons :: [a] -> Maybe (a, [a]) uncons [] = Nothing uncons (x : xs) = Just (x, xs) runReadM :: MonadP m => ReadM a -> String -> m a runReadM (ReadM r) s = hoistEither . runExcept $ runReaderT r s withReadM :: (String -> String) -> ReadM a -> ReadM a withReadM f = ReadM . mapReaderT (withExcept f') . unReadM where f' (ErrorMsg err) = ErrorMsg (f err) f' e = e data SomeParser = forall a . SomeParser (Parser a) data ComplError = ComplParseError String | ComplExit data ComplResult a = ComplParser SomeParser | ComplOption Completer | ComplResult a instance Functor ComplResult where fmap = liftM instance Applicative ComplResult where pure = ComplResult (<*>) = ap instance Monad ComplResult where return = pure m >>= f = case m of ComplResult r -> f r ComplParser p -> ComplParser p ComplOption c -> ComplOption c newtype Completion a = Completion (ExceptT ParseError (ReaderT ParserPrefs ComplResult) a) instance Functor Completion where fmap f (Completion m) = Completion $ fmap f m instance Applicative Completion where pure a = Completion $ pure a Completion f <*> Completion a = Completion $ f <*> a instance Alternative Completion where empty = Completion empty Completion x <|> Completion y = Completion $ x <|> y instance Monad Completion where return a = Completion $ return a Completion x >>= k = Completion $ x >>= \a -> case k a of Completion y -> y instance MonadPlus Completion where mzero = Completion mzero mplus (Completion x) (Completion y) = Completion $ mplus x y instance MonadP Completion where setContext _ _ = return () getPrefs = Completion $ lift ask missingArgP _ = Completion . lift . lift . ComplOption tryP (Completion p) = Completion $ catchE (Right <$> p) (return . Left) exitP p _ = Completion . lift . lift . ComplParser $ SomeParser p errorP = Completion . throwE runCompletion :: Completion r -> ParserPrefs -> Maybe (Either SomeParser Completer) runCompletion (Completion c) prefs = case runReaderT (runExceptT c) prefs of ComplResult _ -> Nothing ComplParser p' -> Just $ Left p' ComplOption compl -> Just $ Right compl -- A "ListT done right" implementation newtype ListT m a = ListT { stepListT :: m (TStep a (ListT m a)) } data TStep a x = TNil | TCons a x bimapTStep :: (a -> b) -> (x -> y) -> TStep a x -> TStep b y bimapTStep _ _ TNil = TNil bimapTStep f g (TCons a x) = TCons (f a) (g x) hoistList :: Monad m => [a] -> ListT m a hoistList = foldr (\x xt -> ListT (return (TCons x xt))) mzero takeListT :: Monad m => Int -> ListT m a -> ListT m a takeListT 0 = const mzero takeListT n = ListT . liftM (bimapTStep id (takeListT (n - 1))) . stepListT runListT :: Monad m => ListT m a -> m [a] runListT xs = do s <- stepListT xs case s of TNil -> return [] TCons x xt -> liftM (x :) (runListT xt) instance Monad m => Functor (ListT m) where fmap f = ListT . liftM (bimapTStep f (fmap f)) . stepListT instance Monad m => Applicative (ListT m) where pure = hoistList . pure (<*>) = ap instance Monad m => Monad (ListT m) where return = pure xs >>= f = ListT $ do s <- stepListT xs case s of TNil -> return TNil TCons x xt -> stepListT $ f x `mplus` (xt >>= f) instance Monad m => Alternative (ListT m) where empty = mzero (<|>) = mplus instance MonadTrans ListT where lift = ListT . liftM (`TCons` mzero) instance Monad m => MonadPlus (ListT m) where mzero = ListT (return TNil) mplus xs ys = ListT $ do s <- stepListT xs case s of TNil -> stepListT ys TCons x xt -> return $ TCons x (xt `mplus` ys) -- nondeterminism monad with cut operator newtype NondetT m a = NondetT { runNondetT :: ListT (StateT Bool m) a } instance Monad m => Functor (NondetT m) where fmap f = NondetT . fmap f . runNondetT instance Monad m => Applicative (NondetT m) where pure = NondetT . pure NondetT m1 <*> NondetT m2 = NondetT (m1 <*> m2) instance Monad m => Monad (NondetT m) where return = pure NondetT m1 >>= f = NondetT $ m1 >>= runNondetT . f instance Monad m => MonadPlus (NondetT m) where mzero = NondetT mzero NondetT m1 `mplus` NondetT m2 = NondetT (m1 `mplus` m2) instance Monad m => Alternative (NondetT m) where empty = mzero (<|>) = mplus instance MonadTrans NondetT where lift = NondetT . lift . lift () :: Monad m => NondetT m a -> NondetT m a -> NondetT m a () m1 m2 = NondetT . mplus (runNondetT m1) $ do s <- lift get guard (not s) runNondetT m2 cut :: Monad m => NondetT m () cut = NondetT $ lift (put True) disamb :: Monad m => Bool -> NondetT m a -> m (Maybe a) disamb allow_amb xs = do xs' <- (`evalStateT` False) . runListT . takeListT (if allow_amb then 1 else 2) . runNondetT $ xs return $ case xs' of [x] -> Just x _ -> Nothing optparse-applicative-0.12.0.0/Options/Applicative/Types.hs0000644000000000000000000002250612601215511021605 0ustar0000000000000000{-# LANGUAGE Rank2Types, ExistentialQuantification #-} module Options.Applicative.Types ( ParseError(..), ParserInfo(..), ParserPrefs(..), Option(..), OptName(..), OptReader(..), OptProperties(..), OptVisibility(..), ReadM(..), readerAsk, readerAbort, readerError, CReader(..), Parser(..), ParserM(..), Completer(..), mkCompleter, CompletionResult(..), ParserFailure(..), ParserResult(..), overFailure, Args, ArgPolicy(..), OptHelpInfo(..), OptTree(..), ParserHelp(..), fromM, oneM, manyM, someM, optVisibility, optMetaVar, optHelp, optShowDefault ) where import Control.Applicative (Applicative(..), Alternative(..), (<$>), optional) import Control.Monad (ap, liftM, MonadPlus, mzero, mplus) import Control.Monad.Trans.Except (Except, throwE) import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Reader (ReaderT, ask) import Data.Monoid (Monoid(..)) import System.Exit (ExitCode(..)) import Options.Applicative.Help.Types import Options.Applicative.Help.Pretty import Options.Applicative.Help.Chunk data ParseError = ErrorMsg String | InfoMsg String | ShowHelpText | UnknownError | MissingError (OptTree (Chunk Doc)) deriving Show instance Monoid ParseError where mempty = UnknownError mappend m UnknownError = m mappend _ m = m -- | A full description for a runnable 'Parser' for a program. data ParserInfo a = ParserInfo { infoParser :: Parser a -- ^ the option parser for the program , infoFullDesc :: Bool -- ^ whether the help text should contain full -- documentation , infoProgDesc :: Chunk Doc -- ^ brief parser description , infoHeader :: Chunk Doc -- ^ header of the full parser description , infoFooter :: Chunk Doc -- ^ footer of the full parser description , infoFailureCode :: Int -- ^ exit code for a parser failure , infoIntersperse :: Bool -- ^ allow regular options and flags to occur -- after arguments (default: True) } instance Functor ParserInfo where fmap f i = i { infoParser = fmap f (infoParser i) } -- | Global preferences for a top-level 'Parser'. data ParserPrefs = ParserPrefs { prefMultiSuffix :: String -- ^ metavar suffix for multiple options , prefDisambiguate :: Bool -- ^ automatically disambiguate abbreviations -- (default: False) , prefShowHelpOnError :: Bool -- ^ always show help text on parse errors -- (default: False) , prefBacktrack :: Bool -- ^ backtrack to parent parser when a -- subcommand fails (default: True) , prefColumns :: Int -- ^ number of columns in the terminal, used to -- format the help page (default: 80) } deriving (Eq, Show) data OptName = OptShort !Char | OptLong !String deriving (Eq, Ord, Show) -- | Visibility of an option in the help text. data OptVisibility = Internal -- ^ does not appear in the help text at all | Hidden -- ^ only visible in the full description | Visible -- ^ visible both in the full and brief descriptions deriving (Eq, Ord, Show) -- | Specification for an individual parser option. data OptProperties = OptProperties { propVisibility :: OptVisibility -- ^ whether this flag is shown is the brief description , propHelp :: Chunk Doc -- ^ help text for this option , propMetaVar :: String -- ^ metavariable for this option , propShowDefault :: Maybe String -- ^ what to show in the help text as the default } deriving Show -- | A single option of a parser. data Option a = Option { optMain :: OptReader a -- ^ reader for this option , optProps :: OptProperties -- ^ properties of this option } instance Show (Option a) where show opt = "Option {optProps = " ++ show (optProps opt) ++ "}" instance Functor Option where fmap f (Option m p) = Option (fmap f m) p -- | A newtype over 'ReaderT String Except', used by option readers. newtype ReadM a = ReadM { unReadM :: ReaderT String (Except ParseError) a } instance Functor ReadM where fmap f (ReadM r) = ReadM (fmap f r) instance Applicative ReadM where pure = ReadM . pure ReadM x <*> ReadM y = ReadM $ x <*> y instance Alternative ReadM where empty = mzero (<|>) = mplus instance Monad ReadM where return = pure ReadM r >>= f = ReadM $ r >>= unReadM . f fail = readerError instance MonadPlus ReadM where mzero = ReadM mzero mplus (ReadM x) (ReadM y) = ReadM $ mplus x y -- | Return the value being read. readerAsk :: ReadM String readerAsk = ReadM ask -- | Abort option reader by exiting with a 'ParseError'. readerAbort :: ParseError -> ReadM a readerAbort = ReadM . lift . throwE -- | Abort option reader by exiting with an error message. readerError :: String -> ReadM a readerError = readerAbort . ErrorMsg data CReader a = CReader { crCompleter :: Completer , crReader :: ReadM a } instance Functor CReader where fmap f (CReader c r) = CReader c (fmap f r) -- | An 'OptReader' defines whether an option matches an command line argument. data OptReader a = OptReader [OptName] (CReader a) ParseError -- ^ option reader | FlagReader [OptName] !a -- ^ flag reader | ArgReader (CReader a) -- ^ argument reader | CmdReader [String] (String -> Maybe (ParserInfo a)) -- ^ command reader instance Functor OptReader where fmap f (OptReader ns cr e) = OptReader ns (fmap f cr) e fmap f (FlagReader ns x) = FlagReader ns (f x) fmap f (ArgReader cr) = ArgReader (fmap f cr) fmap f (CmdReader cs g) = CmdReader cs ((fmap . fmap) f . g) -- | A @Parser a@ is an option parser returning a value of type 'a'. data Parser a = NilP (Maybe a) | OptP (Option a) | forall x . MultP (Parser (x -> a)) (Parser x) | AltP (Parser a) (Parser a) | forall x . BindP (Parser x) (x -> Parser a) instance Functor Parser where fmap f (NilP x) = NilP (fmap f x) fmap f (OptP opt) = OptP (fmap f opt) fmap f (MultP p1 p2) = MultP (fmap (f.) p1) p2 fmap f (AltP p1 p2) = AltP (fmap f p1) (fmap f p2) fmap f (BindP p k) = BindP p (fmap f . k) instance Applicative Parser where pure = NilP . Just (<*>) = MultP newtype ParserM r = ParserM { runParserM :: forall x . (r -> Parser x) -> Parser x } instance Monad ParserM where return x = ParserM $ \k -> k x ParserM f >>= g = ParserM $ \k -> f (\x -> runParserM (g x) k) instance Functor ParserM where fmap = liftM instance Applicative ParserM where pure = return (<*>) = ap fromM :: ParserM a -> Parser a fromM (ParserM f) = f pure oneM :: Parser a -> ParserM a oneM p = ParserM (BindP p) manyM :: Parser a -> ParserM [a] manyM p = do mx <- oneM (optional p) case mx of Nothing -> return [] Just x -> (x:) <$> manyM p someM :: Parser a -> ParserM [a] someM p = (:) <$> oneM p <*> manyM p instance Alternative Parser where empty = NilP Nothing (<|>) = AltP many p = fromM $ manyM p some p = fromM $ (:) <$> oneM p <*> manyM p newtype Completer = Completer { runCompleter :: String -> IO [String] } mkCompleter :: (String -> IO [String]) -> Completer mkCompleter = Completer instance Monoid Completer where mempty = Completer $ \_ -> return [] mappend (Completer c1) (Completer c2) = Completer $ \s -> (++) <$> c1 s <*> c2 s newtype CompletionResult = CompletionResult { execCompletion :: String -> IO String } instance Show CompletionResult where showsPrec p _ = showParen (p > 10) $ showString "CompletionResult _" newtype ParserFailure h = ParserFailure { execFailure :: String -> (h, ExitCode, Int) } instance Show h => Show (ParserFailure h) where showsPrec p (ParserFailure f) = showParen (p > 10) $ showString "ParserFailure " . showsPrec 11 (f "") instance Functor ParserFailure where fmap f (ParserFailure err) = ParserFailure $ \progn -> let (h, exit, cols) = err progn in (f h, exit, cols) -- | Result of 'execParserPure'. data ParserResult a = Success a | Failure (ParserFailure ParserHelp) | CompletionInvoked CompletionResult deriving Show instance Functor ParserResult where fmap f (Success a) = Success (f a) fmap _ (Failure f) = Failure f fmap _ (CompletionInvoked c) = CompletionInvoked c overFailure :: (ParserHelp -> ParserHelp) -> ParserResult a -> ParserResult a overFailure f (Failure failure) = Failure $ fmap f failure overFailure _ r = r instance Applicative ParserResult where pure = Success Success f <*> r = fmap f r Failure f <*> _ = Failure f CompletionInvoked c <*> _ = CompletionInvoked c instance Monad ParserResult where return = pure Success x >>= f = f x Failure f >>= _ = Failure f CompletionInvoked c >>= _ = CompletionInvoked c type Args = [String] data ArgPolicy = SkipOpts | AllowOpts deriving (Eq, Show) data OptHelpInfo = OptHelpInfo { hinfoMulti :: Bool , hinfoDefault :: Bool } deriving (Eq, Show) data OptTree a = Leaf a | MultNode [OptTree a] | AltNode [OptTree a] deriving Show optVisibility :: Option a -> OptVisibility optVisibility = propVisibility . optProps optHelp :: Option a -> Chunk Doc optHelp = propHelp . optProps optMetaVar :: Option a -> String optMetaVar = propMetaVar . optProps optShowDefault :: Option a -> Maybe String optShowDefault = propShowDefault . optProps optparse-applicative-0.12.0.0/Options/Applicative/Builder/0000755000000000000000000000000012601215511021526 5ustar0000000000000000optparse-applicative-0.12.0.0/Options/Applicative/Builder/Completer.hs0000644000000000000000000000146712601215511024024 0ustar0000000000000000module Options.Applicative.Builder.Completer ( Completer , mkCompleter , listIOCompleter , listCompleter , bashCompleter ) where import Control.Applicative ((<$>), pure) import Control.Exception (IOException, try) import Data.List (isPrefixOf) import System.Process (readProcess) import Options.Applicative.Types listIOCompleter :: IO [String] -> Completer listIOCompleter ss = Completer $ \s -> filter (isPrefixOf s) <$> ss listCompleter :: [String] -> Completer listCompleter = listIOCompleter . pure bashCompleter :: String -> Completer bashCompleter action = Completer $ \word -> do let cmd = unwords ["compgen", "-A", action, "--", word] result <- tryIO $ readProcess "bash" ["-c", cmd] "" return . lines . either (const []) id $ result tryIO :: IO a -> IO (Either IOException a) tryIO = try optparse-applicative-0.12.0.0/Options/Applicative/Builder/Internal.hs0000644000000000000000000001121212601215511023633 0ustar0000000000000000module Options.Applicative.Builder.Internal ( -- * Internals Mod(..), HasName(..), HasCompleter(..), HasValue, HasMetavar, OptionFields(..), FlagFields(..), CommandFields(..), ArgumentFields(..), DefaultProp(..), optionMod, fieldMod, baseProps, mkCommand, mkParser, mkOption, mkProps, internal ) where import Control.Applicative (pure, (<*>), empty, (<|>)) import Control.Monad (mplus) import Data.Monoid (Monoid(..)) import Options.Applicative.Common import Options.Applicative.Types data OptionFields a = OptionFields { optNames :: [OptName] , optCompleter :: Completer , optNoArgError :: ParseError } data FlagFields a = FlagFields { flagNames :: [OptName] , flagActive :: a } data CommandFields a = CommandFields { cmdCommands :: [(String, ParserInfo a)] } data ArgumentFields a = ArgumentFields { argCompleter :: Completer } class HasName f where name :: OptName -> f a -> f a instance HasName OptionFields where name n fields = fields { optNames = n : optNames fields } instance HasName FlagFields where name n fields = fields { flagNames = n : flagNames fields } class HasCompleter f where modCompleter :: (Completer -> Completer) -> f a -> f a instance HasCompleter OptionFields where modCompleter f p = p { optCompleter = f (optCompleter p) } instance HasCompleter ArgumentFields where modCompleter f p = p { argCompleter = f (argCompleter p) } class HasValue f where -- this is just so that it is not necessary to specify the kind of f hasValueDummy :: f a -> () instance HasValue OptionFields where hasValueDummy _ = () instance HasValue ArgumentFields where hasValueDummy _ = () class HasMetavar f where hasMetavarDummy :: f a -> () instance HasMetavar OptionFields where hasMetavarDummy _ = () instance HasMetavar ArgumentFields where hasMetavarDummy _ = () instance HasMetavar CommandFields where hasMetavarDummy _ = () -- mod -- data DefaultProp a = DefaultProp (Maybe a) (Maybe (a -> String)) instance Monoid (DefaultProp a) where mempty = DefaultProp Nothing Nothing mappend (DefaultProp d1 s1) (DefaultProp d2 s2) = DefaultProp (d1 `mplus` d2) (s1 `mplus` s2) -- | An option modifier. -- -- Option modifiers are values that represent a modification of the properties -- of an option. -- -- The type parameter @a@ is the return type of the option, while @f@ is a -- record containing its properties (e.g. 'OptionFields' for regular options, -- 'FlagFields' for flags, etc...). -- -- An option modifier consists of 3 elements: -- -- - A field modifier, of the form @f a -> f a@. These are essentially -- (compositions of) setters for some of the properties supported by @f@. -- -- - An optional default value and function to display it. -- -- - A property modifier, of the form @OptProperties -> OptProperties@. This -- is just like the field modifier, but for properties applicable to any -- option. -- -- Modifiers are instances of 'Monoid', and can be composed as such. -- -- You rarely need to deal with modifiers directly, as most of the times it is -- sufficient to pass them to builders (such as 'strOption' or 'flag') to -- create options (see 'Options.Applicative.Builder'). data Mod f a = Mod (f a -> f a) (DefaultProp a) (OptProperties -> OptProperties) optionMod :: (OptProperties -> OptProperties) -> Mod f a optionMod = Mod id mempty fieldMod :: (f a -> f a) -> Mod f a fieldMod f = Mod f mempty id instance Monoid (Mod f a) where mempty = Mod id mempty id Mod f1 d1 g1 `mappend` Mod f2 d2 g2 = Mod (f2 . f1) (d2 `mappend` d1) (g2 . g1) -- | Base default properties. baseProps :: OptProperties baseProps = OptProperties { propMetaVar = "" , propVisibility = Visible , propHelp = mempty , propShowDefault = Nothing } mkCommand :: Mod CommandFields a -> ([String], String -> Maybe (ParserInfo a)) mkCommand m = (map fst cmds, (`lookup` cmds)) where Mod f _ _ = m CommandFields cmds = f (CommandFields []) mkParser :: DefaultProp a -> (OptProperties -> OptProperties) -> OptReader a -> Parser a mkParser d@(DefaultProp def _) g rdr = liftOpt opt <|> maybe empty pure def where opt = mkOption d g rdr mkOption :: DefaultProp a -> (OptProperties -> OptProperties) -> OptReader a -> Option a mkOption d g rdr = Option rdr (mkProps d g) mkProps :: DefaultProp a -> (OptProperties -> OptProperties) -> OptProperties mkProps (DefaultProp def sdef) g = props where props = (g baseProps) { propShowDefault = sdef <*> def } -- | Hide this option from the help text internal :: Mod f a internal = optionMod $ \p -> p { propVisibility = Internal } optparse-applicative-0.12.0.0/Options/Applicative/Help/0000755000000000000000000000000012601215511021030 5ustar0000000000000000optparse-applicative-0.12.0.0/Options/Applicative/Help/Chunk.hs0000644000000000000000000000771512601215511022446 0ustar0000000000000000{-# LANGUAGE CPP #-} module Options.Applicative.Help.Chunk ( mappendWith , Chunk(..) , chunked , listToChunk , (<<+>>) , (<>) , vcatChunks , vsepChunks , isEmpty , stringChunk , paragraph , extractChunk , tabulate ) where import Control.Applicative import Control.Monad import Data.Maybe import Data.Monoid import Options.Applicative.Help.Pretty mappendWith :: Monoid a => a -> a -> a -> a mappendWith s x y = mconcat [x, s, y] -- | The free monoid on a semigroup 'a'. newtype Chunk a = Chunk { unChunk :: Maybe a } deriving (Eq, Show) instance Functor Chunk where fmap f = Chunk . fmap f . unChunk instance Applicative Chunk where pure = Chunk . pure Chunk f <*> Chunk x = Chunk (f <*> x) instance Alternative Chunk where empty = Chunk Control.Applicative.empty a <|> b = Chunk $ unChunk a <|> unChunk b instance Monad Chunk where return = pure m >>= f = Chunk $ unChunk m >>= unChunk . f instance MonadPlus Chunk where mzero = Chunk mzero mplus m1 m2 = Chunk $ mplus (unChunk m1) (unChunk m2) -- | Given a semigroup structure on 'a', return a monoid structure on 'Chunk a'. -- -- Note that this is /not/ the same as 'liftA2'. chunked :: (a -> a -> a) -> Chunk a -> Chunk a -> Chunk a chunked _ (Chunk Nothing) y = y chunked _ x (Chunk Nothing) = x chunked f (Chunk (Just x)) (Chunk (Just y)) = Chunk (Just (f x y)) -- | Concatenate a list into a Chunk. 'listToChunk' satisfies: -- -- > isEmpty . listToChunk = null -- > listToChunk = mconcat . fmap pure listToChunk :: Monoid a => [a] -> Chunk a listToChunk [] = mempty listToChunk xs = pure (mconcat xs) instance Monoid a => Monoid (Chunk a) where mempty = Chunk Nothing mappend = chunked mappend -- | Part of a constrained comonad instance. -- -- This is the counit of the adjunction between 'Chunk' and the forgetful -- functor from monoids to semigroups. It satisfies: -- -- > extractChunk . pure = id -- > extractChunk . fmap pure = id extractChunk :: Monoid a => Chunk a -> a extractChunk = fromMaybe mempty . unChunk -- we could also define: -- duplicate :: Monoid a => Chunk a -> Chunk (Chunk a) -- duplicate = fmap pure -- | Concatenate two 'Chunk's with a space in between. If one is empty, this -- just returns the other one. -- -- Unlike '<+>' for 'Doc', this operation has a unit element, namely the empty -- 'Chunk'. (<<+>>) :: Chunk Doc -> Chunk Doc -> Chunk Doc (<<+>>) = chunked (<+>) -- | Concatenate two 'Chunk's with a softline in between. This is exactly like -- '<<+>>', but uses a softline instead of a space. (<>) :: Chunk Doc -> Chunk Doc -> Chunk Doc (<>) = chunked () -- | Concatenate 'Chunk's vertically. vcatChunks :: [Chunk Doc] -> Chunk Doc vcatChunks = foldr (chunked (.$.)) mempty -- | Concatenate 'Chunk's vertically separated by empty lines. vsepChunks :: [Chunk Doc] -> Chunk Doc vsepChunks = foldr (chunked (\x y -> x .$. mempty .$. y)) mempty -- | Whether a 'Chunk' is empty. Note that something like 'pure mempty' is not -- considered an empty chunk, even though the underlying 'Doc' is empty. isEmpty :: Chunk a -> Bool isEmpty = isNothing . unChunk -- | Convert a 'String' into a 'Chunk'. This satisfies: -- -- > isEmpty . stringChunk = null -- > extractChunk . stringChunk = string stringChunk :: String -> Chunk Doc stringChunk "" = mempty stringChunk s = pure (string s) -- | Convert a paragraph into a 'Chunk'. The resulting chunk is composed by the -- words of the original paragraph separated by softlines, so it will be -- automatically word-wrapped when rendering the underlying document. -- -- This satisfies: -- -- > isEmpty . paragraph = null . words paragraph :: String -> Chunk Doc paragraph = foldr (chunked () . stringChunk) mempty . words tabulate' :: Int -> [(Doc, Doc)] -> Chunk Doc tabulate' _ [] = mempty tabulate' size table = pure $ vcat [ indent 2 (fillBreak size key <+> value) | (key, value) <- table ] -- | Display pairs of strings in a table. tabulate :: [(Doc, Doc)] -> Chunk Doc tabulate = tabulate' 24 optparse-applicative-0.12.0.0/Options/Applicative/Help/Core.hs0000644000000000000000000000636012601215511022261 0ustar0000000000000000module Options.Applicative.Help.Core ( cmdDesc, briefDesc, fold_tree, fullDesc, ParserHelp(..), errorHelp, headerHelp, usageHelp, bodyHelp, footerHelp, parserHelp, parserUsage, ) where import Control.Monad (guard) import Data.Maybe (maybeToList, catMaybes) import Data.Monoid (mempty) import Options.Applicative.Common import Options.Applicative.Types import Options.Applicative.Help.Pretty import Options.Applicative.Help.Chunk -- | Generate descriptions for commands. cmdDesc :: Parser a -> Chunk Doc cmdDesc = vcatChunks . mapParser desc where desc _ opt = case optMain opt of CmdReader cmds p -> tabulate [(string cmd, align (extractChunk d)) | cmd <- reverse cmds , d <- maybeToList . fmap infoProgDesc $ p cmd ] _ -> mempty -- | Generate a brief help text for a parser. briefDesc :: ParserPrefs -> Parser a -> Chunk Doc briefDesc pprefs = fold_tree . treeMapParser (optDesc pprefs style) where style = OptDescStyle { descSep = string "|" , descHidden = False , descSurround = True } fold_tree :: OptTree (Chunk Doc) -> Chunk Doc fold_tree (Leaf x) = x fold_tree (MultNode xs) = foldr ((<>) . fold_tree) mempty xs fold_tree (AltNode xs) = alt_node . filter (not . isEmpty) . map fold_tree $ xs where alt_node :: [Chunk Doc] -> Chunk Doc alt_node [n] = n alt_node ns = fmap parens . foldr (chunked (\x y -> x char '|' y)) mempty $ ns -- | Generate a full help text for a parser. fullDesc :: ParserPrefs -> Parser a -> Chunk Doc fullDesc pprefs = tabulate . catMaybes . mapParser doc where doc info opt = do guard . not . isEmpty $ n guard . not . isEmpty $ h return (extractChunk n, align . extractChunk $ h <<+>> hdef) where n = optDesc pprefs style info opt h = optHelp opt hdef = Chunk . fmap show_def . optShowDefault $ opt show_def s = parens (string "default:" <+> string s) style = OptDescStyle { descSep = string "," , descHidden = True , descSurround = False } errorHelp :: Chunk Doc -> ParserHelp errorHelp chunk = ParserHelp chunk mempty mempty mempty mempty headerHelp :: Chunk Doc -> ParserHelp headerHelp chunk = ParserHelp mempty chunk mempty mempty mempty usageHelp :: Chunk Doc -> ParserHelp usageHelp chunk = ParserHelp mempty mempty chunk mempty mempty bodyHelp :: Chunk Doc -> ParserHelp bodyHelp chunk = ParserHelp mempty mempty mempty chunk mempty footerHelp :: Chunk Doc -> ParserHelp footerHelp chunk = ParserHelp mempty mempty mempty mempty chunk -- | Generate the help text for a program. parserHelp :: ParserPrefs -> Parser a -> ParserHelp parserHelp pprefs p = bodyHelp . vsepChunks $ [ with_title "Available options:" (fullDesc pprefs p) , with_title "Available commands:" (cmdDesc p) ] where with_title :: String -> Chunk Doc -> Chunk Doc with_title title = fmap (string title .$.) -- | Generate option summary. parserUsage :: ParserPrefs -> Parser a -> String -> Doc parserUsage pprefs p progn = hsep [ string "Usage:" , string progn , align (extractChunk (briefDesc pprefs p)) ] {-# ANN footerHelp "HLint: ignore Eta reduce" #-} optparse-applicative-0.12.0.0/Options/Applicative/Help/Pretty.hs0000644000000000000000000000040712601215511022654 0ustar0000000000000000module Options.Applicative.Help.Pretty ( module Text.PrettyPrint.ANSI.Leijen , (.$.) ) where import Text.PrettyPrint.ANSI.Leijen hiding ((<$>), (<>), columns) import qualified Text.PrettyPrint.ANSI.Leijen as PP (.$.) :: Doc -> Doc -> Doc (.$.) = (PP.<$>) optparse-applicative-0.12.0.0/Options/Applicative/Help/Types.hs0000644000000000000000000000172312601215511022473 0ustar0000000000000000module Options.Applicative.Help.Types ( ParserHelp(..), renderHelp ) where import Data.Monoid import Options.Applicative.Help.Chunk import Options.Applicative.Help.Pretty data ParserHelp = ParserHelp { helpError :: Chunk Doc , helpHeader :: Chunk Doc , helpUsage :: Chunk Doc , helpBody :: Chunk Doc , helpFooter :: Chunk Doc } instance Show ParserHelp where showsPrec _ h = showString (renderHelp 80 h) instance Monoid ParserHelp where mempty = ParserHelp mempty mempty mempty mempty mempty mappend (ParserHelp e1 h1 u1 b1 f1) (ParserHelp e2 h2 u2 b2 f2) = ParserHelp (mappend e1 e2) (mappend h1 h2) (mappend u1 u2) (mappend b1 b2) (mappend f1 f2) helpText :: ParserHelp -> Doc helpText (ParserHelp e h u b f) = extractChunk . vsepChunks $ [e, h, u, b, f] -- | Convert a help text to 'String'. renderHelp :: Int -> ParserHelp -> String renderHelp cols = (`displayS` "") . renderPretty 1.0 cols . helpText optparse-applicative-0.12.0.0/tests/0000755000000000000000000000000012601215511015406 5ustar0000000000000000optparse-applicative-0.12.0.0/tests/alt.err.txt0000644000000000000000000000034412601215511017517 0ustar0000000000000000Usage: alt (--virtual-machine VM | --cloud-service CS | --dry-run) Available options: --virtual-machine VM Virtual machine name --cloud-service CS Cloud service name -h,--help Show this help text optparse-applicative-0.12.0.0/tests/cabal.err.txt0000644000000000000000000000041312601215511017776 0ustar0000000000000000Usage: cabal configure [--enable-tests] [-f|--flags FLAGS] Prepare to build the package Available options: --enable-tests Enable compilation of test suites -f,--flags FLAGS Enable the given flag -h,--help Show this help text optparse-applicative-0.12.0.0/tests/commands.err.txt0000644000000000000000000000030112601215511020531 0ustar0000000000000000Usage: commands COMMAND Available options: -h,--help Show this help text Available commands: hello Print greeting goodbye Say goodbye optparse-applicative-0.12.0.0/tests/commands_header.err.txt0000644000000000000000000000006612601215511022051 0ustar0000000000000000Invalid option `-zzz' Usage: commands_header COMMAND optparse-applicative-0.12.0.0/tests/commands_header_full.err.txt0000644000000000000000000000035112601215511023070 0ustar0000000000000000Invalid option `-zzz' foo Usage: commands_header_full COMMAND Available options: -h,--help Show this help text Available commands: hello Print greeting goodbye Say goodbye optparse-applicative-0.12.0.0/tests/formatting.err.txt0000644000000000000000000000107712601215511021115 0ustar0000000000000000Usage: formatting [-t|--test FOO_BAR_BAZ_LONG_METAVARIABLE] This is a very long program description. This text should be automatically wrapped to fit the size of the terminal Available options: -t,--test FOO_BAR_BAZ_LONG_METAVARIABLE This is an options with a very very long description. Hopefully, this will be nicely formatted by the help text generator. -h,--help Show this help text optparse-applicative-0.12.0.0/tests/hello.err.txt0000644000000000000000000000042212601215511020037 0ustar0000000000000000hello - a test for optparse-applicative Usage: hello --hello TARGET [--quiet] Print a greeting for TARGET Available options: --hello TARGET Target for the greeting --quiet Whether to be quiet -h,--help Show this help text optparse-applicative-0.12.0.0/tests/nested.err.txt0000644000000000000000000000004612601215511020220 0ustar0000000000000000Missing: -a A Usage: nested c b -a A optparse-applicative-0.12.0.0/tests/subparsers.err.txt0000644000000000000000000000035612601215511021133 0ustar0000000000000000Usage: subparsers COMMAND COMMAND Available options: -h,--help Show this help text Available commands: add Add a file to the repository commit Record changes to the repository optparse-applicative-0.12.0.0/tests/Examples/0000755000000000000000000000000012601215511017164 5ustar0000000000000000optparse-applicative-0.12.0.0/tests/Examples/Alternatives.hs0000644000000000000000000000044412601215511022163 0ustar0000000000000000module Examples.Alternatives where import Options.Applicative data Value = A | B deriving (Eq, Show) values :: Parser [Value] values = many $ a <|> b a :: Parser Value a = flag' A (short 'a') b :: Parser Value b = flag' B (short 'b') opts :: ParserInfo [Value] opts = info values idm optparse-applicative-0.12.0.0/tests/Examples/Cabal.hs0000644000000000000000000000633612601215511020532 0ustar0000000000000000{-# LANGUAGE Arrows, CPP #-} module Examples.Cabal where import Options.Applicative import Options.Applicative.Arrows #if __GLASGOW_HASKELL__ <= 702 import Data.Monoid (<>) :: Monoid a => a -> a -> a (<>) = mappend #endif data Args = Args CommonOpts Command deriving Show data CommonOpts = CommonOpts { optVerbosity :: Int } deriving Show data Command = Install ConfigureOpts InstallOpts | Update | Configure ConfigureOpts | Build BuildOpts deriving Show data InstallOpts = InstallOpts { instReinstall :: Bool , instForce :: Bool } deriving Show data ConfigureOpts = ConfigureOpts { configTests :: Bool , configFlags :: [String] } deriving Show data BuildOpts = BuildOpts { buildDir :: FilePath } deriving Show version :: Parser (a -> a) version = infoOption "0.0.0" ( long "version" <> help "Print version information" ) parser :: Parser Args parser = runA $ proc () -> do opts <- asA commonOpts -< () cmds <- (asA . hsubparser) ( command "install" (info installParser (progDesc "Installs a list of packages")) <> command "update" (info updateParser (progDesc "Updates list of known packages")) <> command "configure" (info configureParser (progDesc "Prepare to build the package")) <> command "build" (info buildParser (progDesc "Make this package ready for installation")) ) -< () A version >>> A helper -< Args opts cmds commonOpts :: Parser CommonOpts commonOpts = CommonOpts <$> option auto ( short 'v' <> long "verbose" <> metavar "LEVEL" <> help "Set verbosity to LEVEL" <> value 0 ) installParser :: Parser Command installParser = runA $ proc () -> do config <- asA configureOpts -< () inst <- asA installOpts -< () returnA -< Install config inst installOpts :: Parser InstallOpts installOpts = runA $ proc () -> do reinst <- asA (switch (long "reinstall")) -< () force <- asA (switch (long "force-reinstall")) -< () returnA -< InstallOpts { instReinstall = reinst , instForce = force } updateParser :: Parser Command updateParser = pure Update configureParser :: Parser Command configureParser = runA $ proc () -> do config <- asA configureOpts -< () returnA -< Configure config configureOpts :: Parser ConfigureOpts configureOpts = runA $ proc () -> do tests <- (asA . switch) ( long "enable-tests" <> help "Enable compilation of test suites" ) -< () flags <- (asA . many . strOption) ( short 'f' <> long "flags" <> metavar "FLAGS" <> help "Enable the given flag" ) -< () returnA -< ConfigureOpts tests flags buildParser :: Parser Command buildParser = runA $ proc () -> do opts <- asA buildOpts -< () returnA -< Build opts buildOpts :: Parser BuildOpts buildOpts = runA $ proc () -> do bdir <- (asA . strOption) ( long "builddir" <> metavar "DIR" <> value "dist" ) -< () returnA -< BuildOpts bdir pinfo :: ParserInfo Args pinfo = info parser ( progDesc "An example modelled on cabal" ) main :: IO () main = do r <- execParser pinfo print r optparse-applicative-0.12.0.0/tests/Examples/Commands.hs0000644000000000000000000000150112601215511021256 0ustar0000000000000000{-# LANGUAGE CPP #-} module Examples.Commands where import Data.List import Options.Applicative #if __GLASGOW_HASKELL__ <= 702 import Data.Monoid (<>) :: Monoid a => a -> a -> a (<>) = mappend #endif data Sample = Hello [String] | Goodbye deriving Show hello :: Parser Sample hello = Hello <$> many (argument str (metavar "TARGET...")) sample :: Parser Sample sample = subparser ( command "hello" (info hello (progDesc "Print greeting")) <> command "goodbye" (info (pure Goodbye) (progDesc "Say goodbye")) ) run :: Sample -> IO () run (Hello targets) = putStrLn $ "Hello, " ++ intercalate ", " targets ++ "!" run Goodbye = putStrLn "Goodbye." opts :: ParserInfo Sample opts = info (sample <**> helper) idm main :: IO () main = execParser opts >>= run optparse-applicative-0.12.0.0/tests/Examples/Formatting.hs0000644000000000000000000000054012601215511021631 0ustar0000000000000000module Examples.Formatting where import Data.Monoid import Options.Applicative opts :: Parser Int opts = option auto $ mconcat [ long "test" , short 't' , value 0 , metavar "FOO_BAR_BAZ_LONG_METAVARIABLE" , help "This is an options with a very very long description. Hopefully, this will be nicely formatted by the help text generator." ] optparse-applicative-0.12.0.0/tests/Examples/Hello.hs0000644000000000000000000000145412601215511020567 0ustar0000000000000000{-# LANGUAGE CPP #-} module Examples.Hello where import Options.Applicative #if __GLASGOW_HASKELL__ <= 702 import Data.Monoid (<>) :: Monoid a => a -> a -> a (<>) = mappend #endif data Sample = Sample { hello :: String , quiet :: Bool } deriving Show sample :: Parser Sample sample = Sample <$> strOption ( long "hello" <> metavar "TARGET" <> help "Target for the greeting" ) <*> switch ( long "quiet" <> help "Whether to be quiet" ) greet :: Sample -> IO () greet (Sample h False) = putStrLn $ "Hello, " ++ h greet _ = return () main :: IO () main = execParser opts >>= greet opts :: ParserInfo Sample opts = info (sample <**> helper) ( fullDesc <> progDesc "Print a greeting for TARGET" <> header "hello - a test for optparse-applicative" )