repl-toolkit-0.2.0.0: Toolkit for quickly whipping up command-line interfaces.

Safe HaskellNone
LanguageHaskell2010

System.REPL.Command

Contents

Description

Provides Commands for REPLs. Commands take care of input and parameter-handling, and allow parameters to be supplied in the same line as the command's name (e.g. ":cmd param1 param2" on stdin). Provided parameters can be parsed and checked (say, against databases) before they are passed to the actual command function. They are relatively large units of abstraction, but they allow the easy creation of relatively sophisticated command loops, and have the advantage that one doesn't need to fiddle around with input handling in the middle of the actual command code.

Synopsis

Command dispatch

Using the Command class is not necessary, but it makes dealing with user input considerably easier. When a command is run with a line of input, it automatically segments it by whitespace, tries to interpret each part as one of its arguments and passes them to the actual command function. If any arguments haven't been supplies, it asks for them on stdin. If too many arguments have been supplied, or if any argument' parsing returns an error, the command is aborted.

Example:

cd = makeCommand1 ...
>>> :cd ../
Directory changed!
>>> :cd
Enter new directory:
>>> ../
Directory changed!

data Command m a Source

A REPL command, possibly with parameters.

Constructors

Command 

Fields

commandName :: Text

The short name of the command. Purely informative.

commandTest :: Text -> Bool

Returns whether a string matches a command name. The simplest form is s== for some string s, but more liberal matchings are possible.

commandDesc :: Text

A description of the command.

numParameters :: Maybe Int

The number of parameters, if fixed.

runCommand :: Text -> m a

Runs the command with the input text as parameter.

Instances

commandInfo :: MonadIO m => Command m a -> m () Source

Prints information (the command name, description and, if given, the number of parameters) about a command to the console.

runOnce :: MonadIO m => Text -> Command m a -> m (Maybe a) Source

Takes a line of text and a command. If the text matches the given command's commandTest, the command is run with it. If not, Nothing is returned.

commandDispatch Source

Arguments

:: (MonadIO m, MonadError SomeException m, Functor m) 
=> Text

The user's input.

-> [Command m z]

The command library.

-> m z 

Takes an input and tries to run it against a list of commands, trying the out in sequence. The first command whose commandTest returns True is executed. If none of the commands match, NothingFoundFailure is thrown.

summarizeCommands :: MonadIO m => [Command m2 z] -> m () Source

Prints out a list of command names, with their descriptions.

readArgs :: Text -> Either Text [Text] Source

Splits and trims the input of a command. Any non-whitespace sequence of characters is interpreted as one argument, unless double quotes (") are used, in which case they demarcate an argument. Each argument is parsed as a haskell string literal (quote-less arguments have quotes inserted around them). If the number of quotes in the input is not even, the operating will fail.

Arguments are parsed using parsec's stringLiteral (haskell-style), meaning that escape sequences and unicode characters are handled automatically.

quoteArg :: Text -> Text Source

Surrounds an argument in quote marks, if necessary. This is useful when arguments were extracted via readArgs, which deletes quote marks. Quotes are placed around the input iff it doesn't begin with a quote mark ("). readArgs and quoteArg are inverse up to suitable isomorphism, i.e. if 'readArgs orig = (Right res)', then it holds that readArgs orig = readArgs $ intercalate " " $ map quoteArg res

Making commands.

makeCommand Source

Arguments

:: (MonadIO m, MonadError SomeException m, Functor m) 
=> Text

Command name.

-> (Text -> Bool)

Command test.

-> Text

Command description.

-> (Text -> m a)

The actual command.

-> Command m a 

Creates a command without parameters.

makeCommand1 Source

Arguments

:: (MonadIO m, MonadError SomeException m, Functor m, Read a) 
=> Text

Command name.

-> (Text -> Bool)

Command test.

-> Text

Command description

-> Asker m a

Asker for the first parameter.

-> (Text -> a -> m z) 
-> Command m z 

Creates a command with one parameter.

makeCommand2 Source

Arguments

:: (MonadIO m, MonadError SomeException m, Functor m, Read a, Read b) 
=> Text

Command name.

-> (Text -> Bool)

Command test.

-> Text

Command description

-> Asker m a

Asker for the first parameter.

-> Asker m b

Asker for the second perameter.

-> (Text -> a -> b -> m z) 
-> Command m z 

Creates a command with two parameters.

makeCommand3 Source

Arguments

:: (MonadIO m, MonadError SomeException m, Functor m, Read a, Read b, Read c) 
=> Text

Command name.

-> (Text -> Bool)

Command test.

-> Text

Command description

-> Asker m a

Asker for the first parameter.

-> Asker m b

Asker for the second perameter.

-> Asker m c

Asker for the third parameter.

-> (Text -> a -> b -> c -> m z) 
-> Command m z 

Creates a command with three parameters.

makeCommand4 Source

Arguments

:: (MonadIO m, MonadError SomeException m, Functor m, Read a, Read b, Read c, Read d) 
=> Text

Command name.

-> (Text -> Bool)

Command test.

-> Text

Command description

-> Asker m a

Asker for the first parameter.

-> Asker m b

Asker for the second perameter.

-> Asker m c

Asker for the third parameter.

-> Asker m d

Asker for the fourth parameter.

-> (Text -> a -> b -> c -> d -> m z) 
-> Command m z 

Creates a command with four parameters.

makeCommand5 Source

Arguments

:: (MonadIO m, MonadError SomeException m, Functor m, Read a, Read b, Read c, Read d, Read e) 
=> Text

Command name.

-> (Text -> Bool)

Command test.

-> Text

Command description

-> Asker m a

Asker for the first parameter.

-> Asker m b

Asker for the second perameter.

-> Asker m c

Asker for the third parameter.

-> Asker m d

Asker for the fourth parameter.

-> Asker m e

Asker for the fifth parameter.

-> (Text -> a -> b -> c -> d -> e -> m z) 
-> Command m z 

Creates a command with five parameters.

makeCommand6 Source

Arguments

:: (MonadIO m, MonadError SomeException m, Functor m, Read a, Read b, Read c, Read d, Read e, Read f) 
=> Text

Command name.

-> (Text -> Bool)

Command test.

-> Text

Command description

-> Asker m a

Asker for the first parameter.

-> Asker m b

Asker for the second perameter.

-> Asker m c

Asker for the third parameter.

-> Asker m d

Asker for the fourth parameter.

-> Asker m e

Asker for the fifth parameter.

-> Asker m f

Asker for the sixth parameter.

-> (Text -> a -> b -> c -> d -> e -> f -> m z) 
-> Command m z 

Creates a command with four parameters.

makeCommandN Source

Arguments

:: (MonadIO m, MonadError SomeException m, Functor m, Read a) 
=> Text

Command name.

-> (Text -> Bool)

Command test.

-> Text

Command description

-> [Asker m a]

Askers for the necessary parameters.

-> [Asker m a]

Askers for the optional parameters.

-> (Text -> [a] -> m z) 
-> Command m z 

Creates a command with a list of parameters. The first list necc of Askers indicates the necessary parameters; the user must at least provide this many. The second list opt contains Askers for additional, optional parameters, and may be infinite. If the number of passed parameters exceeds length necc + length opt, or if any Asker fails, the command returns an AskFailure.