butcher-1.3.3.2: Chops a command or program invocation into digestable pieces.

Safe Haskell | None
Language | Haskell2010

UI.Butcher.Monadic.Command

Contents

- Building CmdParsers - myprog -v --input PATH
- Building CmdParsers - myprog SOME_INT
- Low-level part functions

Description

Building-blocks of a CmdParser.

The simplest sensible CmdParser is just

    addCmdImpl $ putStrLn "hello, world!"

(assuming out is IO ()).

The empty CmdParser is also valid:

    return ()

But not very interesting - you won't get an `out` value from this (e.g. an IO-action to execute) when this matches (on the empty input).

    do
      addCmd "sub" $ do
        addCmdImpl $ putStrLn "sub successful"

Here, note that there is no implementation at the top-level. This means that on the empty input the resulting CommandDesc has no out-value, but on "sub" it has. Executed as a program, the user would be shown the usage on empty input, and the putStrLn would happen on "sub".

More than one subcommand? easy:

    do
      addCmd "foo" $ do {..}
      addCmd "bar" $ do {..}

Basic flag usage:

    do
      shouldVerbose <- addSimpleBoolFlag "v" ["verbose"] mzero
      addCmdImpl $ if shouldVerbose
        then putStrLn "Hello, World!!!!!"
        else putStrLn "hi."

Basic param usage:

    addCmd "echo" $ do
      addCmdHelpStr "print its parameter to output"
      str <- addRestOfInputStringParam "STRING" (paramHelpStr "the string to print")
      addCmdImpl $ putStrLn str
    addCmd "echoInt" $ do
      i <- addReadParam "INT" mempty
      addCmdImpl $ print (i::Int) -- need to disambiguate via typesig.

There are some other flag/param methods in the respective modules. Also note the example at `reorderStart`.

Synopsis

- addCmd :: Applicative f => String -> CmdParser f out () -> CmdParser f out ()
- addCmdHidden :: Applicative f => String -> CmdParser f out () -> CmdParser f out ()
- addNullCmd :: Applicative f => CmdParser f out () -> CmdParser f out ()
- addCmdImpl :: out -> CmdParser f out ()
- addCmdSynopsis :: String -> CmdParser f out ()
- addCmdHelp :: Doc -> CmdParser f out ()
- addCmdHelpStr :: String -> CmdParser f out ()
- reorderStart :: CmdParser f out ()
- reorderStop :: CmdParser f out ()
- withReorder :: CmdParser f out a -> CmdParser f out a
- peekCmdDesc :: CmdParser f out (CommandDesc ())
- peekInput :: CmdParser f out String
- module UI.Butcher.Monadic.Flag
- module UI.Butcher.Monadic.Param
- addCmdPart :: (Applicative f, Typeable p) => PartDesc -> (String -> Maybe (p, String)) -> CmdParser f out p
- addCmdPartMany :: (Applicative f, Typeable p) => ManyUpperBound -> PartDesc -> (String -> Maybe (p, String)) -> CmdParser f out [p]
- addCmdPartInp :: (Applicative f, Typeable p) => PartDesc -> (Input -> Maybe (p, Input)) -> CmdParser f out p
- addCmdPartManyInp :: (Applicative f, Typeable p) => ManyUpperBound -> PartDesc -> (Input -> Maybe (p, Input)) -> CmdParser f out [p]
- addAlternatives :: Typeable p => [(String, String -> Bool, CmdParser f out p)] -> CmdParser f out p
- data ManyUpperBound
  - = ManyUpperBound1
  - | ManyUpperBoundN
- varPartDesc :: String -> PartDesc

# Documentation

addCmd Source #

Arguments

:: Applicative f |
=> String | command name
-> CmdParser f out () | subcommand
-> CmdParser f out () |

Add a new child command in the current context.

addCmdHidden Source #

Arguments

:: Applicative f |
=> String | command name
-> CmdParser f out () | subcommand
-> CmdParser f out () |

Add a new child command in the current context, but make it hidden. It will not appear in docs/help generated by e.g. the functions in the `Pretty` module.

This feature is not well tested yet.

addNullCmd :: Applicative f => CmdParser f out () -> CmdParser f out () Source #

Add a new nameless child command in the current context. Nameless means that this command matches the empty input, i.e. will always apply. This feature is experimental and CommandDesc pretty-printing might not correctly in presense of nullCmds.

addCmdImpl :: out -> CmdParser f out () Source #

Add an implementation to the current command.

addCmdSynopsis :: String -> CmdParser f out () Source #

Add a synopsis to the command currently in scope; at top level this will be the implicit top-level command.

Adding a second synopsis will overwrite a previous synopsis; `checkCmdParser` will check that you don't (accidentally) do this however.

addCmdHelp :: Doc -> CmdParser f out () Source #

Add a help document to the command currently in scope; at top level this will be the implicit top-level command.

Adding a second document will overwrite a previous document; `checkCmdParser` will check that you don't (accidentally) do this however.

addCmdHelpStr :: String -> CmdParser f out () Source #

Like ``addCmdHelp` . PP.text`

reorderStart :: CmdParser f out () Source #

Best explained via example:

    do
      reorderStart
      bright <- addSimpleBoolFlag "" ["bright"] mempty
      yellow <- addSimpleBoolFlag "" ["yellow"] mempty
      reorderStop
      ..

will accept any inputs "" "--bright" "--yellow" "--bright --yellow" "--yellow --bright".

This works for any flags/params, but bear in mind that the results might be unexpected because params may match on any input.

Note that start/stop must occur in pairs, and it will be a runtime error if you mess this up. Use `checkCmdParser` if you want to check all parts of your `CmdParser` without providing inputs that provide 100% coverage.

reorderStop :: CmdParser f out () Source #

See `reorderStart`

withReorder :: CmdParser f out a -> CmdParser f out a Source #

Safe wrapper around `reorderStart`/`reorderStop` for cases where reducing to a single binding is possible/preferable.

peekCmdDesc :: CmdParser f out (CommandDesc ()) Source #

Semi-hacky way of accessing the output CommandDesc from inside of a `CmdParser`. This is not implemented via knot-tying, i.e. the CommandDesc you get is _not_ equivalent to the CommandDesc returned by `runCmdParser`. Also see `runCmdParserWithHelpDesc` which does knot-tying.

For best results, use this "below" any `addCmd` invocations in the current context, e.g. directly before the `addCmdImpl` invocation.

peekInput :: CmdParser f out String Source #

Semi-hacky way of accessing the current input that is not yet processed. This must not be used to do any parsing. The purpose of this function is to provide a String to be used for output to the user, as feedback about what command was executed. For example we may think of an interactive program reacting to commandline input such as "run --delay 60 fire-rockets" which shows a 60 second delay on the "fire-rockets" command. The latter string could have been obtained via `peekInput` after having parsed "run --delay 60" already.

# Building CmdParsers - myprog -v --input PATH

module UI.Butcher.Monadic.Flag

# Building CmdParsers - myprog SOME_INT

module UI.Butcher.Monadic.Param

# Low-level part functions

addCmdPart :: (Applicative f, Typeable p) => PartDesc -> (String -> Maybe (p, String)) -> CmdParser f out p Source #

Add part that is expected to occur exactly once in the input. May succeed on empty input (e.g. by having a default).

addCmdPartMany :: (Applicative f, Typeable p) => ManyUpperBound -> PartDesc -> (String -> Maybe (p, String)) -> CmdParser f out [p] Source #

Add part that is not required to occur, and can occur as often as indicated by `ManyUpperBound`. Must not succeed on empty input.

addCmdPartInp :: (Applicative f, Typeable p) => PartDesc -> (Input -> Maybe (p, Input)) -> CmdParser f out p Source #

Add part that is expected to occur exactly once in the input. May succeed on empty input (e.g. by having a default).

Only difference to `addCmdPart` is that it accepts `Input`, i.e. can behave differently for `String` and `[String]` input.

addCmdPartManyInp :: (Applicative f, Typeable p) => ManyUpperBound -> PartDesc -> (Input -> Maybe (p, Input)) -> CmdParser f out [p] Source #

Add part that is not required to occur, and can occur as often as indicated by `ManyUpperBound`. Must not succeed on empty input.

Only difference to `addCmdPart` is that it accepts `Input`, i.e. can behave differently for `String` and `[String]` input.

addAlternatives :: Typeable p => [(String, String -> Bool, CmdParser f out p)] -> CmdParser f out p Source #

Add a list of sub-parsers one of which will be selected and used based on the provided predicate function. The input elements consist of: a) a name used for the command description of the output, b) a predicate function; the first True predicate determines which element to apply c) a CmdParser.

data ManyUpperBound Source #

Specifies whether we accept 0-1 or 0-n for `CmdParserPart`s.

Constructors

ManyUpperBound1 |
ManyUpperBoundN |

varPartDesc :: String -> PartDesc Source #

Create a simple PartDesc from a string.