-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Toolkit for quickly whipping up config files and command-line interfaces. -- -- A simple toolkit for quickly whipping up REPLs, input validation and -- sets of commands included. @package repl-toolkit @version 1.1.0.0 -- | Types used by other modules in the package. -- -- The module contains the following exception hierarchy: -- -- module System.REPL.Types -- | An error message indicating that a value wasn't able to be parsed. type TypeError = SomeException -- | An error message indicating that a value failed a predicate. type PredicateError = SomeException -- | A prompt. type PromptMsg = Text -- | A predicate which a value has to fulfil. type Predicate m a b = a -> m (Either PredicateError b) -- | A predicate which does not change the type of its input. type Predicate' m a = Predicate m a a -- | A parser which either returns a parsed value or an error message. type Parser a = Text -> Either TypeError a -- | The description of an 'ask for user input'-action. The type parameters -- are the used monad (typically IO or ExceptT), the type -- of the read value and the type of the error that is thrown in case of -- failures. -- -- The components are a prompt, a parser, and a predicate that the parsed -- value must fulfil. The predicate -- -- data Asker m a b Asker :: Text -> Parser a -> Predicate m a b -> Asker m a b -- | The prompt to be displayed to the user. [askerPrompt] :: Asker m a b -> Text -- | The parser for the input value. [askerParser] :: Asker m a b -> Parser a -- | The predicate which the input, once read, must fulfill. The Left side -- is an error message. [askerPredicate] :: Asker m a b -> Predicate m a b -- | An Asker which does not convert its argument into a different type -- after parsing. type Asker' m a = Asker m a a -- | Root of the exception hierarchy. data SomeREPLError SomeREPLError :: e -> SomeREPLError replErrorUpcast :: (Exception a) => a -> SomeException replErrorDowncast :: (Exception a) => SomeException -> Maybe a -- | Generic error related to Askers. Either the input was incorrect -- in some way, or the process was aborted by the user. data SomeAskerError SomeAskerError :: e -> SomeAskerError askerErrorUpcast :: (Exception a) => a -> SomeException askerErrorDowncast :: (Exception a) => SomeException -> Maybe a -- | The input could not be parsed. data AskerTypeError AskerTypeError :: SomeException -> AskerTypeError -- | The parsed value failed a predicate. data AskerPredicateError AskerPredicateError :: SomeException -> AskerPredicateError -- | The input for an Asker was aborted by the user. data AskerInputAbortedError AskerInputAbortedError :: AskerInputAbortedError -- | A generic type failure for use with Askers. data GenericTypeError GenericTypeError :: Text -> GenericTypeError -- | Constructor for GenericTypeError which wraps the value into a -- SomeException. genericTypeError :: Text -> SomeException -- | A generic predicate failure for use with Askers. data GenericPredicateError GenericPredicateError :: Text -> GenericPredicateError -- | Constructor for GenericTypeError which wraps the value into a -- SomeException. genericPredicateError :: Text -> SomeException -- | A verbatim Text whose Read instance simply returns the read string, -- as-is. This is useful for askers which ask for strings without quotes. newtype Verbatim Verbatim :: Text -> Verbatim [fromVerbatim] :: Verbatim -> Text -- | Read-instance for Verbatim. Wraps the given value into quotes -- and reads it a a Text. -- | Indicates whether the target of a path exists and what form it has. data PathExistenceType IsDirectory :: PathExistenceType IsFile :: PathExistenceType DoesNotExist :: PathExistenceType -- | Indicates that no part of a path exists. data PathRootDoesNotExist PathRootDoesNotExist :: FilePath -> PathRootDoesNotExist -- | Indicates that the last existing portion of a path is not writable. data PathIsNotWritable PathIsNotWritable :: FilePath -> PathIsNotWritable -- | Generic error related to command execution. data SomeCommandError SomeCommandError :: e -> SomeCommandError commandErrorUpcast :: (Exception a) => a -> SomeException commandErrorDowncast :: (Exception a) => SomeException -> Maybe a -- | The input of a command was malformed and could not be interpreted. -- I.e. the input contained inadmissible characters, or quotes were -- mismatched. The Text argument contains the parser error. data MalformedParamsError MalformedParamsError :: Text -> MalformedParamsError -- | Too many parameters were given to a command. The first value is the -- maximum, the second the actual number. data TooManyParamsError TooManyParamsError :: Int -> Int -> TooManyParamsError -- | Too few parameters were given to a command. The first value is the -- minium, the second the actual number. data TooFewParamsError TooFewParamsError :: Int -> Int -> TooFewParamsError -- | A REPL command, possibly with parameters. data Command m i a Command :: Text -> (i -> Bool) -> Text -> ([i] -> m (a, [i])) -> Command m i a -- | The short name of the command. Purely informative. [commandName] :: Command m i a -> Text -- | Returns whether the first part of an input (the command name) matches -- a the command. defCommandTest is appropriate for most cases. [commandTest] :: Command m i a -> i -> Bool -- | A description of the command. [commandDesc] :: Command m i a -> Text -- | Runs the command with the input text as parameter, returning the -- unconsumed input. [runPartialCommand] :: Command m i a -> [i] -> m (a, [i]) -- | Indicates that some string was not able to be parsed. data NoConfigFileParseError NoConfigFileParseError :: Text -> NoConfigFileParseError instance GHC.Read.Read System.REPL.Types.NoConfigFileParseError instance GHC.Classes.Eq System.REPL.Types.NoConfigFileParseError instance GHC.Show.Show System.REPL.Types.NoConfigFileParseError instance GHC.Classes.Ord System.REPL.Types.TooFewParamsError instance GHC.Classes.Eq System.REPL.Types.TooFewParamsError instance GHC.Show.Show System.REPL.Types.TooFewParamsError instance GHC.Classes.Ord System.REPL.Types.TooManyParamsError instance GHC.Classes.Eq System.REPL.Types.TooManyParamsError instance GHC.Show.Show System.REPL.Types.TooManyParamsError instance GHC.Classes.Ord System.REPL.Types.MalformedParamsError instance GHC.Classes.Eq System.REPL.Types.MalformedParamsError instance GHC.Show.Show System.REPL.Types.MalformedParamsError instance GHC.Show.Show System.REPL.Types.PathIsNotWritable instance GHC.Classes.Eq System.REPL.Types.PathIsNotWritable instance GHC.Show.Show System.REPL.Types.PathRootDoesNotExist instance GHC.Classes.Eq System.REPL.Types.PathRootDoesNotExist instance GHC.Enum.Bounded System.REPL.Types.PathExistenceType instance GHC.Enum.Enum System.REPL.Types.PathExistenceType instance GHC.Read.Read System.REPL.Types.PathExistenceType instance GHC.Classes.Ord System.REPL.Types.PathExistenceType instance GHC.Show.Show System.REPL.Types.PathExistenceType instance GHC.Classes.Eq System.REPL.Types.PathExistenceType instance GHC.Classes.Eq System.REPL.Types.GenericPredicateError instance GHC.Show.Show System.REPL.Types.GenericPredicateError instance GHC.Classes.Eq System.REPL.Types.GenericTypeError instance GHC.Show.Show System.REPL.Types.GenericTypeError instance GHC.Show.Show System.REPL.Types.AskerInputAbortedError instance GHC.Show.Show System.REPL.Types.AskerPredicateError instance GHC.Show.Show System.REPL.Types.AskerTypeError instance GHC.Show.Show System.REPL.Types.SomeREPLError instance GHC.Exception.Exception System.REPL.Types.SomeREPLError instance GHC.Show.Show System.REPL.Types.SomeAskerError instance GHC.Exception.Exception System.REPL.Types.SomeAskerError instance GHC.Exception.Exception System.REPL.Types.AskerTypeError instance GHC.Exception.Exception System.REPL.Types.AskerPredicateError instance GHC.Exception.Exception System.REPL.Types.AskerInputAbortedError instance GHC.Exception.Exception System.REPL.Types.GenericTypeError instance GHC.Exception.Exception System.REPL.Types.GenericPredicateError instance GHC.Read.Read System.REPL.Types.Verbatim instance GHC.Exception.Exception System.REPL.Types.PathRootDoesNotExist instance GHC.Exception.Exception System.REPL.Types.PathIsNotWritable instance GHC.Show.Show System.REPL.Types.SomeCommandError instance GHC.Exception.Exception System.REPL.Types.SomeCommandError instance GHC.Exception.Exception System.REPL.Types.MalformedParamsError instance GHC.Exception.Exception System.REPL.Types.TooManyParamsError instance GHC.Exception.Exception System.REPL.Types.TooFewParamsError instance GHC.Base.Functor m => GHC.Base.Functor (System.REPL.Types.Command m i) instance GHC.Base.Monad m => Data.Functor.Bind.Class.Apply (System.REPL.Types.Command m i) instance GHC.Base.Monad m => Data.Functor.Bind.Class.Bind (System.REPL.Types.Command m i) instance GHC.Exception.Exception System.REPL.Types.NoConfigFileParseError -- | Helper functions relating to State. module System.REPL.State -- | Extracts a result from the current state. Defined as get1 f = -- liftM f get. get1 :: Monad m => (s -> a) -> StateT s m a -- | Extracts two results from the current state. get2 :: Monad m => (s -> a) -> (s -> b) -> StateT s m (a, b) -- | Extracts three results from the current state. get3 :: Monad m => (s -> a) -> (s -> b) -> (s -> c) -> StateT s m (a, b, c) -- | Extracts four results from the current state. get4 :: Monad m => (s -> a) -> (s -> b) -> (s -> c) -> (s -> d) -> StateT s m (a, b, c, d) -- | Extracts five results from the current state. get5 :: Monad m => (s -> a) -> (s -> b) -> (s -> c) -> (s -> d) -> (s -> e) -> StateT s m (a, b, c, d, e) -- | Extracts six results from the current state. get6 :: Monad m => (s -> a) -> (s -> b) -> (s -> c) -> (s -> d) -> (s -> e) -> (s -> f) -> StateT s m (a, b, c, d, e, f) -- | Extracts seven results from the current state. get7 :: Monad m => (s -> a) -> (s -> b) -> (s -> c) -> (s -> d) -> (s -> e) -> (s -> f) -> (s -> g) -> StateT s m (a, b, c, d, e, f, g) -- | Extracts eight results from the current state. get8 :: Monad m => (s -> a) -> (s -> b) -> (s -> c) -> (s -> d) -> (s -> e) -> (s -> f) -> (s -> g) -> (s -> h) -> StateT s m (a, b, c, d, e, f, g, h) -- | Little helper functions for getting and putting lines. -- -- This module re-exports part of Data.ListLike.IO, which contains -- names that clash with Prelude. module System.REPL.Prompt -- | Prints a string to stderr. putErr :: ListLikeIO full item => full -> IO () -- | Prints a string, followed by a newline character, to stderr. putErrLn :: ListLikeIO full item => full -> IO () -- | Prints > and asks the user to input a line. prompt :: (MonadIO m, ListLikeIO full item) => m full -- | Prints its first argument and, in the same line, asks the user to -- input a line. prompt' :: (MonadIO m, ListLikeIO full item, ListLikeIO full' item') => full -> m full' -- | The same as prompt, but aborts as soon as the user presses a given key -- (commonly '\ESC'). This function temporarily tries to set the -- buffering mode to NoBuffering via hSetBuffering, which may not -- be supported. See the documentation of hSetBuffering for -- details. promptAbort :: (MonadIO m, ListLikeIO full item, ListLikeIO full' Char, MonadCatch m) => Char -> full -> m full' -- | Contains logic for reading configuration files. module System.REPL.Config -- | Tries to read a configuration from file. If the file is missing, a -- default instance is written to file and returned. The following -- exceptions may be thrown: -- -- readConfigFile :: forall e m a. (MonadThrow m, Functor m, MonadIO m, Default a, Exception e) => FilePath -> (ByteString -> Either e a) -> (a -> ByteString) -> m a -- | Variant of readConfigFile that uses JSON for (de)serialization. -- -- If the file's content's can't be parsed, a NoParseError will -- be thrown. readConfigJSON :: forall m a. (MonadThrow m, Functor m, MonadIO m, Default a, ToJSON a, FromJSON a) => FilePath -> m a -- | Variant of readConfigFile that uses Show and Read -- for (de)serialization. -- -- If the file's content's can't be parsed, a NoParseError will -- be thrown. readConfigShow :: forall m a. (MonadThrow m, Functor m, MonadIO m, Default a, Show a, Read a) => FilePath -> m a -- | Indicates that some string was not able to be parsed. data NoConfigFileParseError NoConfigFileParseError :: Text -> NoConfigFileParseError -- | Asking the user for input on the console. -- -- The main type is Asker, which takes care of parsing and -- verifying user input. module System.REPL.Ask -- | A prompt. type PromptMsg = Text -- | An error message indicating that a value wasn't able to be parsed. type TypeError = SomeException -- | An error message indicating that a value failed a predicate. type PredicateError = SomeException -- | A predicate which a value has to fulfil. type Predicate m a b = a -> m (Either PredicateError b) -- | A predicate which does not change the type of its input. type Predicate' m a = Predicate m a a -- | A parser which either returns a parsed value or an error message. type Parser a = Text -> Either TypeError a -- | The description of an 'ask for user input'-action. The type parameters -- are the used monad (typically IO or ExceptT), the type -- of the read value and the type of the error that is thrown in case of -- failures. -- -- The components are a prompt, a parser, and a predicate that the parsed -- value must fulfil. The predicate -- -- data Asker m a b Asker :: Text -> Parser a -> Predicate m a b -> Asker m a b -- | The prompt to be displayed to the user. [askerPrompt] :: Asker m a b -> Text -- | The parser for the input value. [askerParser] :: Asker m a b -> Parser a -- | The predicate which the input, once read, must fulfill. The Left side -- is an error message. [askerPredicate] :: Asker m a b -> Predicate m a b -- | An Asker which does not convert its argument into a different type -- after parsing. type Asker' m a = Asker m a a -- | Root of the exception hierarchy. data SomeREPLError SomeREPLError :: e -> SomeREPLError -- | Generic error related to Askers. Either the input was incorrect -- in some way, or the process was aborted by the user. data SomeAskerError SomeAskerError :: e -> SomeAskerError -- | The input could not be parsed. data AskerTypeError AskerTypeError :: SomeException -> AskerTypeError -- | The parsed value failed a predicate. data AskerPredicateError AskerPredicateError :: SomeException -> AskerPredicateError -- | A generic type failure for use with Askers. data GenericTypeError GenericTypeError :: Text -> GenericTypeError -- | A generic predicate failure for use with Askers. data GenericPredicateError GenericPredicateError :: Text -> GenericPredicateError -- | Constructor for GenericTypeError which wraps the value into a -- SomeException. genericTypeError :: Text -> SomeException -- | Constructor for GenericTypeError which wraps the value into a -- SomeException. genericPredicateError :: Text -> SomeException -- | Creates an Asker which only cares about the type of the input. typeAskerP :: Applicative m => PromptMsg -> Parser a -> Asker' m a -- | An asker which asks for an optional value. If only whitespace is -- entered (according to isSpace), it returns Nothing -- without further parsing or checking; otherwise, it behaves identically -- to asker. maybeAskerP :: Applicative m => PromptMsg -> Parser a -> Predicate m a b -> Asker m (Maybe a) (Maybe b) -- | A verbatim Text whose Read instance simply returns the read string, -- as-is. This is useful for askers which ask for strings without quotes. newtype Verbatim Verbatim :: Text -> Verbatim [fromVerbatim] :: Verbatim -> Text -- | A parser based on readMaybe. This suffices for the parsing of -- most data types. readParser :: Read a => (Text -> TypeError) -> Parser a -- | Creates a general Asker with readMaybe as its parser. -- Using readMaybe is perfectly fine for most values, keep in mind -- that the input Text has to be unpacked into a string. This can be -- costly on very large inputs. -- -- NOTE: Instances of String/Text have to be surrounded with -- quotes ("). You practically never want this when asking for input. If -- you want to get the user input as-is, restrict the return type to -- Asker m Verbatim or use 'predAsker'/'lineAsker'. asker :: (Functor m, Read a) => PromptMsg -> (Text -> TypeError) -> Predicate' m a -> Asker' m a -- | A wrapper around getLine. Prints no prompt and returns the user -- input as-is. lineAsker :: Applicative m => Asker' m Text -- | Creates an Asker based on Read which just cares about the type -- of the input. typeAsker :: (Applicative m, Read a) => PromptMsg -> (Text -> TypeError) -> Asker' m a -- | Creates an Asker which takes its input verbatim as -- Text. Quotes around the input are not required. The input -- thus only has to pass a predicate, not any parsing. predAsker :: (Functor m) => PromptMsg -> Predicate m Text b -> Asker m Text b -- | An asker based on Read which asks for an optional value. maybeAsker :: (Applicative m, Read a) => PromptMsg -> (Text -> TypeError) -> Predicate' m a -> Asker' m (Maybe a) -- | Executes an Asker. A SomeAskerError is thrown if the inpout -- can't be parsing into a value of the correct type, if the input fails -- the Asker's predicate, or if the escape key is pressed. ask :: (MonadIO m, MonadCatch m) => Asker m a b -> Maybe Text -> m b -- | See ask. Always reads the input from stdin. -- --
--   ask' a = ask a Nothing
--   
ask' :: (MonadIO m, MonadCatch m) => Asker m a b -> m b -- | Executes an Asker. If the Text argument is Nothing, the user is -- asked to enter a line on stdin. If it is Just x, x -- is taken to be input. -- -- Pressing the escape key returns a AskerInputAborterError (if -- supported). askEither :: (MonadIO m, MonadCatch m) => Asker m a b -> Maybe Text -> m (Either SomeAskerError b) -- | Repeatedly executes an ask action until the user enters a valid value. -- Error messages are printed each time. untilValid :: forall m a. (MonadIO m, MonadCatch m, Read a) => m a -> m a -- | Creates a predicate from a boolean function and an error message. boolPredicate :: Functor m => (a -> m Bool) -> (a -> PredicateError) -> Predicate' m a -- | Indicates that no part of a path exists. data PathRootDoesNotExist PathRootDoesNotExist :: FilePath -> PathRootDoesNotExist -- | Indicates that the last existing portion of a path is not writable. data PathIsNotWritable PathIsNotWritable :: FilePath -> PathIsNotWritable -- | Indicates whether the target of a path exists and what form it has. data PathExistenceType IsDirectory :: PathExistenceType IsFile :: PathExistenceType DoesNotExist :: PathExistenceType -- | Asks the user for a file or a directory. -- -- Parsing checks for basic validity via isValid. Invalid paths -- are rejected. -- -- After that, the asker determines whether the target exists and what -- type it has. You can run a predicate on that information. filepathAsker :: MonadIO m => PromptMsg -> (FilePath -> TypeError) -> Predicate m (PathExistenceType, FilePath) b -> Asker m FilePath b -- | See filepathAsker. This Asker also ensures that the -- given path is writeable in the following sense: -- -- -- -- PathRootDoesNotExist and PathIsNotWritable exceptions -- are thrown if the first or second of these conditions is violated. -- -- For relative paths, we only check that the current directory is -- writable. -- -- Handled exceptions: -- -- writableFilepathAsker :: MonadIO m => PromptMsg -> (FilePath -> TypeError) -> Predicate m (PathExistenceType, FilePath) b -> Asker m FilePath b -- | Provides Commands for REPLs. Commands are there to provide high-level -- handling of user input and to offer functionality in a standard, -- composable way. -- -- Whereas an Asker is good for getting a single value, a -- Command can get multiple inputs and be composed with other -- commands. -- -- Use cases: -- --
    --
  1. Getting specific numbers of arguments or optional arguments from -- the user. E.g.
  2. --
-- --
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import Data.Text (unpack)
--   
--   asker :: Asker' IO String
--   asker = Asker "Enter argument: " (Right . unpack) (return . Right)
--   
--   cmd = makeCommand3 "command" ("command"==) "description" True [asker,asker,asker] (t x y z -> putStrLn "yay!")
--   
--   
-- -- This is a command with 3 arguments. The user can enter the arguments -- in the same line or give them one by one: -- --
--   >>> command arg1 arg2 arg3
--   yay!
--   
-- --
--   >>> command
--   Enter argument:
--   
--   >>> arg1
--   Enter  argument:
--   
--   >>> arg2
--   Enter argument:
--   
--   >>> arg3
--   yay!
--   
-- -- Had we set the bool above to False, only the first form would -- have been allowed. -- -- Arguments can contain whitespace if they are surrounded with quotes: -- --
--   >>> command "arg1 with spaces" arg2 arg3
--   yay!
--   
-- -- Optional arguments are also possible: -- --
--   cmd = makeCommandN "command" ("command"==) "description" True [asker] [optAsker]
--                      (t (x:xs) -> do putStrLn ("Required argument: " ++ x)
--                                       if null xs then putStrLn "No optional argument."
--                                       else putStrLn ("Optional argument: " ++ head xs))
--   
--   
-- --
--   >>> command arg1
--   Required argument: arg1
--   
-- --
--   >>> command arg1 arg2
--   Required argument: arg1
--   Optional argument: arg2
--   
-- --
    --
  1. Creating command hierarchies, e.g.
  2. --
-- --
--   commit = makeCommand 1 "commit" ...
--   sendEmail = makeCommand "send-email"
--   sendTweet = makeCommand "send-tweet"
--   
--   commit' = subcommand commit [sendEmail, sendTweet]
--   
--   main = makeREPLSimple [commit']
--   
--   
-- --
--   >>> myVersionControl commit "my first commit" send-email
--   
-- -- Here, commit is the root command and sendEmail, -- sendTweet its two possible sub-commands. The sub-commands get -- executed after their root command. -- --
    --
  1. Making a REPL out of some commands.
  2. --
-- -- As above, one can use makeREPL or makeREPLSimple to -- create a REPL out of a list of commands and use it as the -- main function instead of going through the chore of writing a -- loop it by hand. module System.REPL.Command -- | A REPL command, possibly with parameters. data Command m i a Command :: Text -> (i -> Bool) -> Text -> ([i] -> m (a, [i])) -> Command m i a -- | The short name of the command. Purely informative. [commandName] :: Command m i a -> Text -- | Returns whether the first part of an input (the command name) matches -- a the command. defCommandTest is appropriate for most cases. [commandTest] :: Command m i a -> i -> Bool -- | A description of the command. [commandDesc] :: Command m i a -> Text -- | Runs the command with the input text as parameter, returning the -- unconsumed input. [runPartialCommand] :: Command m i a -> [i] -> m (a, [i]) -- | Takes a list xs and executes the first command in a list -- whose commandTest matches the input. -- -- Note that the resultant command cs -- runPartialCommand should only be executed with an input -- t if 'commandTest c t' == True', where t' is either -- head (readArgs t) or mempty if t is empty. -- Otherwise, the result is undefined. oneOf :: Monoid i => Text -> Text -> [Command m i a] -> Command m i a -- | Adds a list of possible subcommands after a command (that should leave -- some input unconsumed). Ignoring all the required parameters for a -- moment, -- --
--   subcommand x xs = x >>- oneOf xs
--   
subcommand :: (Monad m, Monoid i) => Command m i a -> [a -> Command m i b] -> Command m i b -- | Runs the command with the input text as parameter, discarding any -- left-over input. The command test is disregarded. -- -- Can throw: -- -- runCommand :: (MonadThrow m) => Command m Text a -> Text -> m a -- | Runs the command with the input text as parameter. The command test is -- disregarded. -- -- Can throw: -- -- -- -- Note: TooManyParamsError will only be thrown after the -- command's execution is attempted. This is because of the subcommand -- mechanism, which prevents the static determination of the number of -- required arguments. runSingleCommand :: (MonadThrow m) => Command m Text a -> Text -> m a -- | Runs the command with the input text as parameter. -- -- The first parameter (or the empty string, if no input was given) is -- passed to the command test. If it fails the test, Nothing is -- returned. -- -- Can throw: -- -- runSingleCommandIf :: MonadThrow m => Command m Text a -> Text -> m (Maybe a) -- | Runs a REPL based on a set of commands. For a line of input, the -- commands are tried in following order: -- -- makeREPL :: (MonadIO m, MonadCatch m) => [Command m Text a] -> Command m Text b -> Command m Text c -> m Text -> [Handler m ()] -> m () -- | A variant of makeREPL with some default settings: -- -- makeREPLSimple :: (MonadIO m, MonadCatch m) => [Command m Text a] -> m () -- | Root of the exception hierarchy. data SomeREPLError SomeREPLError :: e -> SomeREPLError -- | Generic error related to command execution. data SomeCommandError SomeCommandError :: e -> SomeCommandError -- | The input of a command was malformed and could not be interpreted. -- I.e. the input contained inadmissible characters, or quotes were -- mismatched. The Text argument contains the parser error. data MalformedParamsError MalformedParamsError :: Text -> MalformedParamsError -- | Too few parameters were given to a command. The first value is the -- minium, the second the actual number. data TooFewParamsError TooFewParamsError :: Int -> Int -> TooFewParamsError -- | Too many parameters were given to a command. The first value is the -- maximum, the second the actual number. data TooManyParamsError TooManyParamsError :: Int -> Int -> TooManyParamsError -- | Splits and trims the input of a command. If the input cannot be -- parsed, a MalformedParamsError exception is thrown. -- --

Format

-- -- 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). -- -- Arguments are parsed using parsec's stringLiteral -- (haskell-style), meaning that escape sequences and unicode characters -- are handled automatically. readArgs :: MonadThrow m => Text -> m [Text] -- | Gets the first part of a command string. Returns Nothing if the string -- is empty or if readArgs throws a MalformedParamsError. getName :: Text -> Maybe Text -- | The "default" command test for making commands. This function uses -- getName to extract the first part of the user input, stripping -- whitespace and also checking whether the entire input is well-formed. defCommandTest :: [Text] -> Text -> Bool -- | 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 is empty or contains -- whitespace. quoteArg :: Text -> Text -- | Prints out a list of command names, with their descriptions. summarizeCommands :: MonadIO m => [Command m2 i z] -> m () -- | Creates a command without parameters. makeCommand :: (MonadIO m, MonadCatch m, Monoid i) => Text -> (i -> Bool) -> Text -> (i -> m z) -> Command m i z -- | Creates a command with one parameter. makeCommand1 :: (MonadIO m, MonadCatch m) => Text -> (Text -> Bool) -> Text -> Bool -> Asker m a0 a -> (Text -> a -> m z) -> Command m Text z -- | Creates a command with two parameters. makeCommand2 :: (MonadIO m, MonadCatch m) => Text -> (Text -> Bool) -> Text -> Bool -> Asker m a0 a -> Asker m b0 b -> (Text -> a -> b -> m z) -> Command m Text z -- | Creates a command with three parameters. makeCommand3 :: (MonadIO m, MonadCatch m) => Text -> (Text -> Bool) -> Text -> Bool -> Asker m a0 a -> Asker m b0 b -> Asker m c0 c -> (Text -> a -> b -> c -> m z) -> Command m Text z -- | Creates a command with four parameters. makeCommand4 :: (MonadIO m, MonadCatch m) => Text -> (Text -> Bool) -> Text -> Bool -> Asker m a0 a -> Asker m b0 b -> Asker m c0 c -> Asker m d0 d -> (Text -> a -> b -> c -> d -> m z) -> Command m Text z -- | Creates a command with five parameters. makeCommand5 :: (MonadIO m, MonadCatch m) => Text -> (Text -> Bool) -> Text -> Bool -> Asker m a0 a -> Asker m b0 b -> Asker m c0 c -> Asker m d0 d -> Asker m e0 e -> (Text -> a -> b -> c -> d -> e -> m z) -> Command m Text z -- | Creates a command with six parameters. makeCommand6 :: (MonadIO m, MonadCatch m) => Text -> (Text -> Bool) -> Text -> Bool -> Asker m a0 a -> Asker m b0 b -> Asker m c0 c -> Asker m d0 d -> Asker m e0 e -> Asker m f0 f -> (Text -> a -> b -> c -> d -> e -> f -> m z) -> Command m Text z -- | Creates a command with seven parameters. makeCommand7 :: (MonadIO m, MonadCatch m) => Text -> (Text -> Bool) -> Text -> Bool -> Asker m a0 a -> Asker m b0 b -> Asker m c0 c -> Asker m d0 d -> Asker m e0 e -> Asker m f0 f -> Asker m g0 g -> (Text -> a -> b -> c -> d -> e -> f -> g -> m z) -> Command m Text z -- | Creates a command with eight parameters. makeCommand8 :: (MonadIO m, MonadCatch m) => Text -> (Text -> Bool) -> Text -> Bool -> Asker m a0 a -> Asker m b0 b -> Asker m c0 c -> Asker m d0 d -> Asker m e0 e -> Asker m f0 f -> Asker m g0 g -> Asker m h0 h -> (Text -> a -> b -> c -> d -> e -> f -> g -> h -> m z) -> Command m Text 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. makeCommandN :: (MonadIO m, MonadCatch m) => Text -> (Text -> Bool) -> Text -> Bool -> [Asker m a0 a] -> [Asker m b0 a] -> (Text -> [a] -> m z) -> Command m Text z -- | A command that takes no arguments and does nothing. noOpCmd :: (MonadIO m, MonadCatch m) => Text -> [Text] -> Command m Text () -- | A command with the name ":exit" and the description "Exits the -- program." Otherwise, it does nothing. -- -- You can use this as the exit-command for makeREPL, if no -- special clean-up is needed upon quitting. defExitCmd :: (MonadIO m, MonadCatch m) => Command m Text () -- | A help-command with the name ":help" and the description "Prints this -- help text." -- -- It goes through the given list of commands and prints the name and -- description of each one. defHelpCmd :: (MonadIO m, MonadCatch m, Foldable f) => f (Command m0 a b) -> Command m Text () -- | A default error handler that catches SomeREPLError and prints -- it to stdout. -- -- For the following errors, we print a user-friendly error message: -- -- -- -- For every other subtype of SomeREPLError, we just print the -- Show-instance. -- -- Useful in combination with makeREPL. defErrorHandler :: MonadIO m => [Handler m ()] -- | Contents: -- -- -- -- With commands, making a full-fledged CLI is as simple as writing: -- --
--   main :: IO ()
--   main = makeREPLSimple [cmd1, cmd2, cmd3]
--   
--   
-- -- module System.REPL