    -- | Parameters are arguments of your current command that are not prefixed
    -- by some flag. Typical commandline interface is something like
    -- "PROGRAM [FLAGS] INPUT". Here, FLAGS are Flags in butcher, and INPUT is
    -- a Param, in this case a String representing a path, for example.
    module UI.Butcher.Monadic.Param
      ( Param(..)
      , paramHelp
      , paramHelpStr
      , paramDefault
      , paramSuggestions
      , paramFile
      , paramDirectory
      , addParamRead
      , addParamReadOpt
      , addParamString
      , addParamStringOpt
      , addParamStrings
      , addParamNoFlagString
      , addParamNoFlagStringOpt
      , addParamNoFlagStrings
      , addParamRestOfInput
      , addParamRestOfInputRaw
      , -- * Deprecated for more consistent naming
        addReadParam
      , addReadParamOpt
      , addStringParam
      , addStringParamOpt
      , addStringParams
      , addRestOfInputStringParam
      )
    where

    #include "prelude.inc"
    import           Control.Monad.Free
    import qualified Control.Monad.Trans.MultiRWS.Strict as MultiRWSS
    import qualified Control.Monad.Trans.MultiState.Strict as MultiStateS

    import qualified Text.PrettyPrint as PP

    import           Data.HList.ContainsType

    import           UI.Butcher.Monadic.Internal.Types
    import           UI.Butcher.Monadic.Internal.Core

    -- | param-description monoid. You probably won't need to use the constructor;
    -- mzero or any (<>) of param(Help|Default|Suggestion) works well.
    data Param p = Param
      { Param p -> Maybe p
    _param_default :: Maybe p
      , Param p -> Maybe Doc
    _param_help :: Maybe PP.Doc
      , Param p -> Maybe [CompletionItem]
    _param_suggestions :: Maybe [CompletionItem]
      }

    appendParam :: Param p -> Param p -> Param p
    appendParam :: Param p -> Param p -> Param p
    appendParam (Param a1 :: Maybe p
    a1 b1 :: Maybe Doc
    b1 c1 :: Maybe [CompletionItem]
    c1) (Param a2 :: Maybe p
    a2 b2 :: Maybe Doc
    b2 c2 :: Maybe [CompletionItem]
    c2) = Maybe p -> Maybe Doc -> Maybe [CompletionItem] -> Param p
    forall p. Maybe p -> Maybe Doc -> Maybe [CompletionItem] -> Param p
    Param (Maybe p
    a1 Maybe p -> Maybe p -> Maybe p
    forall a. Maybe a -> Maybe a -> Maybe a
    `f` Maybe p
    a2)
                                                          (Maybe Doc
    b1 Maybe Doc -> Maybe Doc -> Maybe Doc
    forall a. Semigroup a => a -> a -> a
    <> Maybe Doc
    b2)
                                                          (Maybe [CompletionItem]
    c1 Maybe [CompletionItem]
    -> Maybe [CompletionItem] -> Maybe [CompletionItem]
    forall a. Semigroup a => a -> a -> a
    <> Maybe [CompletionItem]
    c2)
     where
      f :: Maybe a -> Maybe a -> Maybe a
    f Nothing x :: Maybe a
    x = Maybe a
    x
      f x :: Maybe a
    x       _ = Maybe a
    x

    instance Semigroup (Param p) where
      <> :: Param p -> Param p -> Param p
    (<>) = Param p -> Param p -> Param p
    forall p. Param p -> Param p -> Param p
    appendParam

    instance Monoid (Param p) where
      mempty :: Param p
    mempty = Maybe p -> Maybe Doc -> Maybe [CompletionItem] -> Param p
    forall p. Maybe p -> Maybe Doc -> Maybe [CompletionItem] -> Param p
    Param Maybe p
    forall a. Maybe a
    Nothing Maybe Doc
    forall a. Maybe a
    Nothing Maybe [CompletionItem]
    forall a. Maybe a
    Nothing
      mappend :: Param p -> Param p -> Param p
    mappend = Param p -> Param p -> Param p
    forall a. Semigroup a => a -> a -> a
    (<>)

    -- | Create a 'Param' with just a help text.
    paramHelpStr :: String -> Param p
    paramHelpStr :: String -> Param p
    paramHelpStr s :: String
    s = Param p
    forall a. Monoid a => a
    mempty { _param_help :: Maybe Doc
    _param_help = Doc -> Maybe Doc
    forall a. a -> Maybe a
    Just (Doc -> Maybe Doc) -> Doc -> Maybe Doc
    forall a b. (a -> b) -> a -> b
    $ String -> Doc
    PP.text String
    s }

    -- | Create a 'Param' with just a help text.
    paramHelp :: PP.Doc -> Param p
    paramHelp :: Doc -> Param p
    paramHelp h :: Doc
    h = Param p
    forall a. Monoid a => a
    mempty { _param_help :: Maybe Doc
    _param_help = Doc -> Maybe Doc
    forall a. a -> Maybe a
    Just Doc
    h }

    -- | Create a 'Param' with just a default value.
    paramDefault :: p -> Param p
    paramDefault :: p -> Param p
    paramDefault d :: p
    d = Param Any
    forall a. Monoid a => a
    mempty { _param_default :: Maybe p
    _param_default = p -> Maybe p
    forall a. a -> Maybe a
    Just p
    d }

    -- | Create a 'Param' with just a list of suggestion values.
    paramSuggestions :: [String] -> Param p
    paramSuggestions :: [String] -> Param p
    paramSuggestions ss :: [String]
    ss =
      Param p
    forall a. Monoid a => a
    mempty { _param_suggestions :: Maybe [CompletionItem]
    _param_suggestions = [CompletionItem] -> Maybe [CompletionItem]
    forall a. a -> Maybe a
    Just ([CompletionItem] -> Maybe [CompletionItem])
    -> [CompletionItem] -> Maybe [CompletionItem]
    forall a b. (a -> b) -> a -> b
    $ String -> CompletionItem
    CompletionString (String -> CompletionItem) -> [String] -> [CompletionItem]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [String]
    ss }

    -- | Create a 'Param' that is a file path.
    paramFile :: Param p
    paramFile :: Param p
    paramFile = Param p
    forall a. Monoid a => a
    mempty { _param_suggestions :: Maybe [CompletionItem]
    _param_suggestions = [CompletionItem] -> Maybe [CompletionItem]
    forall a. a -> Maybe a
    Just [CompletionItem
    CompletionFile] }

    -- | Create a 'Param' that is a directory path.
    paramDirectory :: Param p
    paramDirectory :: Param p
    paramDirectory = Param p
    forall a. Monoid a => a
    mempty { _param_suggestions :: Maybe [CompletionItem]
    _param_suggestions = [CompletionItem] -> Maybe [CompletionItem]
    forall a. a -> Maybe a
    Just [CompletionItem
    CompletionDirectory] }

    -- | Add a parameter to the 'CmdParser' by making use of a 'Text.Read.Read'
    -- instance. Take care not to use this to return Strings unless you really
    -- want that, because it will require the quotation marks and escaping as
    -- is normal for the Show/Read instances for String.
    addParamRead :: forall f out a
                  . (Applicative f, Typeable a, Show a, Text.Read.Read a)
                 => String -- ^ paramater name, for use in usage/help texts
                 -> Param a -- ^ properties
                 -> CmdParser f out a
    addParamRead :: String -> Param a -> CmdParser f out a
    addParamRead = String -> Param a -> CmdParser f out a
    forall (f :: * -> *) out a.
    (Applicative f, Typeable a, Show a, Read a) =>
    String -> Param a -> CmdParser f out a
    addReadParam
    {-# DEPRECATED addReadParam "use 'addParamRead'" #-}
    addReadParam :: forall f out a
                  . (Applicative f, Typeable a, Show a, Text.Read.Read a)
                 => String -- ^ paramater name, for use in usage/help texts
                 -> Param a -- ^ properties
                 -> CmdParser f out a
    addReadParam :: String -> Param a -> CmdParser f out a
    addReadParam name :: String
    name par :: Param a
    par = PartDesc -> (String -> Maybe (a, String)) -> CmdParser f out a
    forall (f :: * -> *) p out.
    (Applicative f, Typeable p) =>
    PartDesc -> (String -> Maybe (p, String)) -> CmdParser f out p
    addCmdPart PartDesc
    desc String -> Maybe (a, String)
    parseF
      where
        desc :: PartDesc
        desc :: PartDesc
    desc = Maybe [CompletionItem] -> PartDesc -> PartDesc
    addSuggestion (Param a -> Maybe [CompletionItem]
    forall p. Param p -> Maybe [CompletionItem]
    _param_suggestions Param a
    par)
             (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ ((PartDesc -> PartDesc)
    -> (Doc -> PartDesc -> PartDesc)
    -> Maybe Doc
    -> PartDesc
    -> PartDesc
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe PartDesc -> PartDesc
    forall a. a -> a
    id Doc -> PartDesc -> PartDesc
    PartWithHelp (Maybe Doc -> PartDesc -> PartDesc)
    -> Maybe Doc -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ Param a -> Maybe Doc
    forall p. Param p -> Maybe Doc
    _param_help Param a
    par)
             (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ ((PartDesc -> PartDesc)
    -> (a -> PartDesc -> PartDesc) -> Maybe a -> PartDesc -> PartDesc
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe PartDesc -> PartDesc
    forall a. a -> a
    id (String -> PartDesc -> PartDesc
    PartDefault (String -> PartDesc -> PartDesc)
    -> (a -> String) -> a -> PartDesc -> PartDesc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> String
    forall a. Show a => a -> String
    show) (Maybe a -> PartDesc -> PartDesc)
    -> Maybe a -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ Param a -> Maybe a
    forall p. Param p -> Maybe p
    _param_default Param a
    par)
             (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ String -> PartDesc
    PartVariable String
    name
        parseF :: String -> Maybe (a, String)
        parseF :: String -> Maybe (a, String)
    parseF s :: String
    s = case ReadS a
    forall a. Read a => ReadS a
    Text.Read.reads String
    s of
          ((x :: a
    x, ' ':r :: String
    r):_) -> (a, String) -> Maybe (a, String)
    forall a. a -> Maybe a
    Just (a
    x, (Char -> Bool) -> String -> String
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile Char -> Bool
    Char.isSpace String
    r)
          ((x :: a
    x, []):_)    -> (a, String) -> Maybe (a, String)
    forall a. a -> Maybe a
    Just (a
    x, [])
          _ -> Param a -> Maybe a
    forall p. Param p -> Maybe p
    _param_default Param a
    par Maybe a -> (a -> (a, String)) -> Maybe (a, String)
    forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
    <&> \x :: a
    x -> (a
    x, String
    s)

    -- | Like addReadParam, but optional. I.e. if reading fails, returns Nothing.
    addParamReadOpt :: forall f out a
                     . (Applicative f, Typeable a, Text.Read.Read a)
                    => String -- ^ paramater name, for use in usage/help texts
                    -> Param a -- ^ properties
                    -> CmdParser f out (Maybe a)
    addParamReadOpt :: String -> Param a -> CmdParser f out (Maybe a)
    addParamReadOpt = String -> Param a -> CmdParser f out (Maybe a)
    forall (f :: * -> *) out a.
    (Applicative f, Typeable a, Read a) =>
    String -> Param a -> CmdParser f out (Maybe a)
    addReadParamOpt
    {-# DEPRECATED addReadParamOpt "use 'addParamReadOpt'" #-}
    addReadParamOpt :: forall f out a
                     . (Applicative f, Typeable a, Text.Read.Read a)
                    => String -- ^ paramater name, for use in usage/help texts
                    -> Param a -- ^ properties
                    -> CmdParser f out (Maybe a)
    addReadParamOpt :: String -> Param a -> CmdParser f out (Maybe a)
    addReadParamOpt name :: String
    name par :: Param a
    par = PartDesc
    -> (String -> Maybe (Maybe a, String)) -> CmdParser f out (Maybe a)
    forall (f :: * -> *) p out.
    (Applicative f, Typeable p) =>
    PartDesc -> (String -> Maybe (p, String)) -> CmdParser f out p
    addCmdPart PartDesc
    desc String -> Maybe (Maybe a, String)
    parseF
      where
        desc :: PartDesc
        desc :: PartDesc
    desc = Maybe [CompletionItem] -> PartDesc -> PartDesc
    addSuggestion (Param a -> Maybe [CompletionItem]
    forall p. Param p -> Maybe [CompletionItem]
    _param_suggestions Param a
    par)
             (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ PartDesc -> PartDesc
    PartOptional
             (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ ((PartDesc -> PartDesc)
    -> (Doc -> PartDesc -> PartDesc)
    -> Maybe Doc
    -> PartDesc
    -> PartDesc
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe PartDesc -> PartDesc
    forall a. a -> a
    id Doc -> PartDesc -> PartDesc
    PartWithHelp (Maybe Doc -> PartDesc -> PartDesc)
    -> Maybe Doc -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ Param a -> Maybe Doc
    forall p. Param p -> Maybe Doc
    _param_help Param a
    par)
             (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ String -> PartDesc
    PartVariable String
    name
        parseF :: String -> Maybe (Maybe a, String)
        parseF :: String -> Maybe (Maybe a, String)
    parseF s :: String
    s = case ReadS a
    forall a. Read a => ReadS a
    Text.Read.reads String
    s of
          ((x :: a
    x, ' ':r :: String
    r):_) -> (Maybe a, String) -> Maybe (Maybe a, String)
    forall a. a -> Maybe a
    Just (a -> Maybe a
    forall a. a -> Maybe a
    Just a
    x, (Char -> Bool) -> String -> String
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile Char -> Bool
    Char.isSpace String
    r)
          ((x :: a
    x, []):_)    -> (Maybe a, String) -> Maybe (Maybe a, String)
    forall a. a -> Maybe a
    Just (a -> Maybe a
    forall a. a -> Maybe a
    Just a
    x, [])
          _ -> (Maybe a, String) -> Maybe (Maybe a, String)
    forall a. a -> Maybe a
    Just (Maybe a
    forall a. Maybe a
    Nothing, String
    s) -- TODO: we could warn about a default..

    -- | Add a parameter that matches any string of non-space characters if
    -- input==String, or one full argument if input==[String]. See the 'Input' doc
    -- for this distinction.
    addParamString
      :: forall f out . (Applicative f)
      => String
      -> Param String
      -> CmdParser f out String
    addParamString :: String -> Param String -> CmdParser f out String
    addParamString = String -> Param String -> CmdParser f out String
    forall (f :: * -> *) out.
    Applicative f =>
    String -> Param String -> CmdParser f out String
    addStringParam
    {-# DEPRECATED addStringParam "use 'addParamString'" #-}
    addStringParam
      :: forall f out . (Applicative f)
      => String
      -> Param String
      -> CmdParser f out String
    addStringParam :: String -> Param String -> CmdParser f out String
    addStringParam name :: String
    name par :: Param String
    par = PartDesc
    -> (Input -> Maybe (String, Input)) -> CmdParser f out String
    forall (f :: * -> *) p out.
    (Applicative f, Typeable p) =>
    PartDesc -> (Input -> Maybe (p, Input)) -> CmdParser f out p
    addCmdPartInp PartDesc
    desc Input -> Maybe (String, Input)
    parseF
      where
        desc :: PartDesc
        desc :: PartDesc
    desc = Maybe [CompletionItem] -> PartDesc -> PartDesc
    addSuggestion (Param String -> Maybe [CompletionItem]
    forall p. Param p -> Maybe [CompletionItem]
    _param_suggestions Param String
    par)
             (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ ((PartDesc -> PartDesc)
    -> (Doc -> PartDesc -> PartDesc)
    -> Maybe Doc
    -> PartDesc
    -> PartDesc
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe PartDesc -> PartDesc
    forall a. a -> a
    id Doc -> PartDesc -> PartDesc
    PartWithHelp (Maybe Doc -> PartDesc -> PartDesc)
    -> Maybe Doc -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ Param String -> Maybe Doc
    forall p. Param p -> Maybe Doc
    _param_help Param String
    par)
             (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ String -> PartDesc
    PartVariable String
    name
        parseF :: Input -> Maybe (String, Input)
        parseF :: Input -> Maybe (String, Input)
    parseF (InputString str :: String
    str)
          = case (Char -> Bool) -> String -> (String, String)
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break Char -> Bool
    Char.isSpace (String -> (String, String)) -> String -> (String, String)
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> String -> String
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile Char -> Bool
    Char.isSpace String
    str of
              ("", rest :: String
    rest) -> Param String -> Maybe String
    forall p. Param p -> Maybe p
    _param_default Param String
    par Maybe String
    -> (String -> (String, Input)) -> Maybe (String, Input)
    forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
    <&> \x :: String
    x -> (String
    x, String -> Input
    InputString String
    rest)
              (x :: String
    x, rest :: String
    rest) -> (String, Input) -> Maybe (String, Input)
    forall a. a -> Maybe a
    Just (String
    x, String -> Input
    InputString String
    rest)
        parseF (InputArgs args :: [String]
    args) = case [String]
    args of
          (s1 :: String
    s1:sR :: [String]
    sR) -> (String, Input) -> Maybe (String, Input)
    forall a. a -> Maybe a
    Just (String
    s1, [String] -> Input
    InputArgs [String]
    sR)
          []      -> Param String -> Maybe String
    forall p. Param p -> Maybe p
    _param_default Param String
    par Maybe String
    -> (String -> (String, Input)) -> Maybe (String, Input)
    forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
    <&> \x :: String
    x -> (String
    x, [String] -> Input
    InputArgs [String]
    args)

    -- | Like 'addParamString', but optional, I.e. succeeding with Nothing if
    -- there is no remaining input.
    addParamStringOpt
      :: forall f out . (Applicative f)
      => String
      -> Param Void
      -> CmdParser f out (Maybe String)
    addParamStringOpt :: String -> Param Void -> CmdParser f out (Maybe String)
    addParamStringOpt = String -> Param Void -> CmdParser f out (Maybe String)
    forall (f :: * -> *) out.
    Applicative f =>
    String -> Param Void -> CmdParser f out (Maybe String)
    addStringParamOpt
    {-# DEPRECATED addStringParamOpt "use 'addParamStringOpt'" #-}
    addStringParamOpt
      :: forall f out . (Applicative f)
      => String
      -> Param Void
      -> CmdParser f out (Maybe String)
    addStringParamOpt :: String -> Param Void -> CmdParser f out (Maybe String)
    addStringParamOpt name :: String
    name par :: Param Void
    par = PartDesc
    -> (Input -> Maybe (Maybe String, Input))
    -> CmdParser f out (Maybe String)
    forall (f :: * -> *) p out.
    (Applicative f, Typeable p) =>
    PartDesc -> (Input -> Maybe (p, Input)) -> CmdParser f out p
    addCmdPartInp PartDesc
    desc Input -> Maybe (Maybe String, Input)
    parseF
      where
        desc :: PartDesc
        desc :: PartDesc
    desc = Maybe [CompletionItem] -> PartDesc -> PartDesc
    addSuggestion (Param Void -> Maybe [CompletionItem]
    forall p. Param p -> Maybe [CompletionItem]
    _param_suggestions Param Void
    par)
             (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ PartDesc -> PartDesc
    PartOptional
             (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ ((PartDesc -> PartDesc)
    -> (Doc -> PartDesc -> PartDesc)
    -> Maybe Doc
    -> PartDesc
    -> PartDesc
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe PartDesc -> PartDesc
    forall a. a -> a
    id Doc -> PartDesc -> PartDesc
    PartWithHelp (Maybe Doc -> PartDesc -> PartDesc)
    -> Maybe Doc -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ Param Void -> Maybe Doc
    forall p. Param p -> Maybe Doc
    _param_help Param Void
    par)
             (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ String -> PartDesc
    PartVariable String
    name
        parseF :: Input -> Maybe (Maybe String, Input)
        parseF :: Input -> Maybe (Maybe String, Input)
    parseF (InputString str :: String
    str)
          = case (Char -> Bool) -> String -> (String, String)
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break Char -> Bool
    Char.isSpace (String -> (String, String)) -> String -> (String, String)
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> String -> String
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile Char -> Bool
    Char.isSpace String
    str of
              ("", rest :: String
    rest) -> (Maybe String, Input) -> Maybe (Maybe String, Input)
    forall a. a -> Maybe a
    Just (Maybe String
    forall a. Maybe a
    Nothing, String -> Input
    InputString String
    rest)
              (x :: String
    x, rest :: String
    rest) -> (Maybe String, Input) -> Maybe (Maybe String, Input)
    forall a. a -> Maybe a
    Just (String -> Maybe String
    forall a. a -> Maybe a
    Just String
    x, String -> Input
    InputString String
    rest)
        parseF (InputArgs args :: [String]
    args) = case [String]
    args of
          (s1 :: String
    s1:sR :: [String]
    sR) -> (Maybe String, Input) -> Maybe (Maybe String, Input)
    forall a. a -> Maybe a
    Just (String -> Maybe String
    forall a. a -> Maybe a
    Just String
    s1, [String] -> Input
    InputArgs [String]
    sR)
          []      -> (Maybe String, Input) -> Maybe (Maybe String, Input)
    forall a. a -> Maybe a
    Just (Maybe String
    forall a. Maybe a
    Nothing, [String] -> Input
    InputArgs [])

    -- | Add a parameter that matches any string of non-space characters if
    -- input==String, or one full argument if input==[String]. See the 'Input' doc
    -- for this distinction.
    addParamStrings
      :: forall f out
       . (Applicative f)
      => String
      -> Param Void
      -> CmdParser f out [String]
    addParamStrings :: String -> Param Void -> CmdParser f out [String]
    addParamStrings = String -> Param Void -> CmdParser f out [String]
    forall (f :: * -> *) out.
    Applicative f =>
    String -> Param Void -> CmdParser f out [String]
    addStringParams
    {-# DEPRECATED addStringParams "use 'addParamStrings'" #-}
    addStringParams
      :: forall f out
       . (Applicative f)
      => String
      -> Param Void
      -> CmdParser f out [String]
    addStringParams :: String -> Param Void -> CmdParser f out [String]
    addStringParams name :: String
    name par :: Param Void
    par = ManyUpperBound
    -> PartDesc
    -> (Input -> Maybe (String, Input))
    -> CmdParser f out [String]
    forall (f :: * -> *) p out.
    (Applicative f, Typeable p) =>
    ManyUpperBound
    -> PartDesc -> (Input -> Maybe (p, Input)) -> CmdParser f out [p]
    addCmdPartManyInp ManyUpperBound
    ManyUpperBoundN PartDesc
    desc Input -> Maybe (String, Input)
    parseF
     where
      desc :: PartDesc
      desc :: PartDesc
    desc =
        Maybe [CompletionItem] -> PartDesc -> PartDesc
    addSuggestion (Param Void -> Maybe [CompletionItem]
    forall p. Param p -> Maybe [CompletionItem]
    _param_suggestions Param Void
    par)
          (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ ((PartDesc -> PartDesc)
    -> (Doc -> PartDesc -> PartDesc)
    -> Maybe Doc
    -> PartDesc
    -> PartDesc
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe PartDesc -> PartDesc
    forall a. a -> a
    id Doc -> PartDesc -> PartDesc
    PartWithHelp (Maybe Doc -> PartDesc -> PartDesc)
    -> Maybe Doc -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ Param Void -> Maybe Doc
    forall p. Param p -> Maybe Doc
    _param_help Param Void
    par)
          (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ String -> PartDesc
    PartVariable String
    name
      parseF :: Input -> Maybe (String, Input)
      parseF :: Input -> Maybe (String, Input)
    parseF (InputString str :: String
    str) =
        case (Char -> Bool) -> String -> (String, String)
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break Char -> Bool
    Char.isSpace (String -> (String, String)) -> String -> (String, String)
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> String -> String
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile Char -> Bool
    Char.isSpace String
    str of
          ("", _   ) -> Maybe (String, Input)
    forall a. Maybe a
    Nothing
          (x :: String
    x , rest :: String
    rest) -> (String, Input) -> Maybe (String, Input)
    forall a. a -> Maybe a
    Just (String
    x, String -> Input
    InputString String
    rest)
      parseF (InputArgs args :: [String]
    args) = case [String]
    args of
        (s1 :: String
    s1:sR :: [String]
    sR) -> (String, Input) -> Maybe (String, Input)
    forall a. a -> Maybe a
    Just (String
    s1, [String] -> Input
    InputArgs [String]
    sR)
        []      -> Maybe (String, Input)
    forall a. Maybe a
    Nothing

    -- | Like 'addParamString' but does not match strings starting with a dash.
    -- This prevents misinterpretation of flags as params.
    addParamNoFlagString
      :: forall f out . (Applicative f)
      => String
      -> Param String
      -> CmdParser f out String
    addParamNoFlagString :: String -> Param String -> CmdParser f out String
    addParamNoFlagString name :: String
    name par :: Param String
    par = PartDesc
    -> (Input -> Maybe (String, Input)) -> CmdParser f out String
    forall (f :: * -> *) p out.
    (Applicative f, Typeable p) =>
    PartDesc -> (Input -> Maybe (p, Input)) -> CmdParser f out p
    addCmdPartInp PartDesc
    desc Input -> Maybe (String, Input)
    parseF
     where
      desc :: PartDesc
      desc :: PartDesc
    desc =
        Maybe [CompletionItem] -> PartDesc -> PartDesc
    addSuggestion (Param String -> Maybe [CompletionItem]
    forall p. Param p -> Maybe [CompletionItem]
    _param_suggestions Param String
    par)
          (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ ((PartDesc -> PartDesc)
    -> (Doc -> PartDesc -> PartDesc)
    -> Maybe Doc
    -> PartDesc
    -> PartDesc
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe PartDesc -> PartDesc
    forall a. a -> a
    id Doc -> PartDesc -> PartDesc
    PartWithHelp (Maybe Doc -> PartDesc -> PartDesc)
    -> Maybe Doc -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ Param String -> Maybe Doc
    forall p. Param p -> Maybe Doc
    _param_help Param String
    par)
          (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ String -> PartDesc
    PartVariable String
    name
      parseF :: Input -> Maybe (String, Input)
      parseF :: Input -> Maybe (String, Input)
    parseF (InputString str :: String
    str) =
        case (Char -> Bool) -> String -> (String, String)
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break Char -> Bool
    Char.isSpace (String -> (String, String)) -> String -> (String, String)
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> String -> String
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile Char -> Bool
    Char.isSpace String
    str of
          (""   , rest :: String
    rest) -> Param String -> Maybe String
    forall p. Param p -> Maybe p
    _param_default Param String
    par Maybe String
    -> (String -> (String, Input)) -> Maybe (String, Input)
    forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
    <&> \x :: String
    x -> (String
    x, String -> Input
    InputString String
    rest)
          ('-':_, _   ) -> Param String -> Maybe String
    forall p. Param p -> Maybe p
    _param_default Param String
    par Maybe String
    -> (String -> (String, Input)) -> Maybe (String, Input)
    forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
    <&> \x :: String
    x -> (String
    x, String -> Input
    InputString String
    str)
          (x :: String
    x    , rest :: String
    rest) -> (String, Input) -> Maybe (String, Input)
    forall a. a -> Maybe a
    Just (String
    x, String -> Input
    InputString String
    rest)
      parseF (InputArgs args :: [String]
    args) = case [String]
    args of
        []           -> Param String -> Maybe String
    forall p. Param p -> Maybe p
    _param_default Param String
    par Maybe String
    -> (String -> (String, Input)) -> Maybe (String, Input)
    forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
    <&> \x :: String
    x -> (String
    x, [String] -> Input
    InputArgs [String]
    args)
        (('-':_):_ ) -> Param String -> Maybe String
    forall p. Param p -> Maybe p
    _param_default Param String
    par Maybe String
    -> (String -> (String, Input)) -> Maybe (String, Input)
    forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
    <&> \x :: String
    x -> (String
    x, [String] -> Input
    InputArgs [String]
    args)
        (s1 :: String
    s1     :sR :: [String]
    sR) -> (String, Input) -> Maybe (String, Input)
    forall a. a -> Maybe a
    Just (String
    s1, [String] -> Input
    InputArgs [String]
    sR)

    -- | Like 'addParamStringOpt' but does not match strings starting with a dash.
    -- This prevents misinterpretation of flags as params.
    addParamNoFlagStringOpt
      :: forall f out
       . (Applicative f)
      => String
      -> Param Void
      -> CmdParser f out (Maybe String)
    addParamNoFlagStringOpt :: String -> Param Void -> CmdParser f out (Maybe String)
    addParamNoFlagStringOpt name :: String
    name par :: Param Void
    par = PartDesc
    -> (Input -> Maybe (Maybe String, Input))
    -> CmdParser f out (Maybe String)
    forall (f :: * -> *) p out.
    (Applicative f, Typeable p) =>
    PartDesc -> (Input -> Maybe (p, Input)) -> CmdParser f out p
    addCmdPartInp PartDesc
    desc Input -> Maybe (Maybe String, Input)
    parseF
     where
      desc :: PartDesc
      desc :: PartDesc
    desc =
        PartDesc -> PartDesc
    PartOptional (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ ((PartDesc -> PartDesc)
    -> (Doc -> PartDesc -> PartDesc)
    -> Maybe Doc
    -> PartDesc
    -> PartDesc
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe PartDesc -> PartDesc
    forall a. a -> a
    id Doc -> PartDesc -> PartDesc
    PartWithHelp (Maybe Doc -> PartDesc -> PartDesc)
    -> Maybe Doc -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ Param Void -> Maybe Doc
    forall p. Param p -> Maybe Doc
    _param_help Param Void
    par) (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ String -> PartDesc
    PartVariable String
    name
      parseF :: Input -> Maybe (Maybe String, Input)
      parseF :: Input -> Maybe (Maybe String, Input)
    parseF (InputString str :: String
    str) =
        case (Char -> Bool) -> String -> (String, String)
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break Char -> Bool
    Char.isSpace (String -> (String, String)) -> String -> (String, String)
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> String -> String
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile Char -> Bool
    Char.isSpace String
    str of
          (""   , rest :: String
    rest) -> (Maybe String, Input) -> Maybe (Maybe String, Input)
    forall a. a -> Maybe a
    Just (Maybe String
    forall a. Maybe a
    Nothing, String -> Input
    InputString String
    rest)
          ('-':_, _   ) -> (Maybe String, Input) -> Maybe (Maybe String, Input)
    forall a. a -> Maybe a
    Just (Maybe String
    forall a. Maybe a
    Nothing, String -> Input
    InputString String
    str)
          (x :: String
    x    , rest :: String
    rest) -> (Maybe String, Input) -> Maybe (Maybe String, Input)
    forall a. a -> Maybe a
    Just (String -> Maybe String
    forall a. a -> Maybe a
    Just String
    x, String -> Input
    InputString String
    rest)
      parseF (InputArgs args :: [String]
    args) = case [String]
    args of
        []           -> (Maybe String, Input) -> Maybe (Maybe String, Input)
    forall a. a -> Maybe a
    Just (Maybe String
    forall a. Maybe a
    Nothing, [String] -> Input
    InputArgs [])
        (('-':_):_ ) -> (Maybe String, Input) -> Maybe (Maybe String, Input)
    forall a. a -> Maybe a
    Just (Maybe String
    forall a. Maybe a
    Nothing, [String] -> Input
    InputArgs [String]
    args)
        (s1 :: String
    s1     :sR :: [String]
    sR) -> (Maybe String, Input) -> Maybe (Maybe String, Input)
    forall a. a -> Maybe a
    Just (String -> Maybe String
    forall a. a -> Maybe a
    Just String
    s1, [String] -> Input
    InputArgs [String]
    sR)

    -- | Like 'addParamStrings' but does not match strings starting with a dash.
    -- This prevents misinterpretation of flags as params.
    addParamNoFlagStrings
      :: forall f out
       . (Applicative f)
      => String
      -> Param Void
      -> CmdParser f out [String]
    addParamNoFlagStrings :: String -> Param Void -> CmdParser f out [String]
    addParamNoFlagStrings name :: String
    name par :: Param Void
    par = ManyUpperBound
    -> PartDesc
    -> (Input -> Maybe (String, Input))
    -> CmdParser f out [String]
    forall (f :: * -> *) p out.
    (Applicative f, Typeable p) =>
    ManyUpperBound
    -> PartDesc -> (Input -> Maybe (p, Input)) -> CmdParser f out [p]
    addCmdPartManyInp ManyUpperBound
    ManyUpperBoundN PartDesc
    desc Input -> Maybe (String, Input)
    parseF
     where
      desc :: PartDesc
      desc :: PartDesc
    desc =
        Maybe [CompletionItem] -> PartDesc -> PartDesc
    addSuggestion (Param Void -> Maybe [CompletionItem]
    forall p. Param p -> Maybe [CompletionItem]
    _param_suggestions Param Void
    par)
          (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ ((PartDesc -> PartDesc)
    -> (Doc -> PartDesc -> PartDesc)
    -> Maybe Doc
    -> PartDesc
    -> PartDesc
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe PartDesc -> PartDesc
    forall a. a -> a
    id Doc -> PartDesc -> PartDesc
    PartWithHelp (Maybe Doc -> PartDesc -> PartDesc)
    -> Maybe Doc -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ Param Void -> Maybe Doc
    forall p. Param p -> Maybe Doc
    _param_help Param Void
    par)
          (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ String -> PartDesc
    PartVariable String
    name
      parseF :: Input -> Maybe (String, Input)
      parseF :: Input -> Maybe (String, Input)
    parseF (InputString str :: String
    str) =
        case (Char -> Bool) -> String -> (String, String)
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break Char -> Bool
    Char.isSpace (String -> (String, String)) -> String -> (String, String)
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> String -> String
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile Char -> Bool
    Char.isSpace String
    str of
          (""   , _   ) -> Maybe (String, Input)
    forall a. Maybe a
    Nothing
          ('-':_, _   ) -> Maybe (String, Input)
    forall a. Maybe a
    Nothing
          (x :: String
    x    , rest :: String
    rest) -> (String, Input) -> Maybe (String, Input)
    forall a. a -> Maybe a
    Just (String
    x, String -> Input
    InputString String
    rest)
      parseF (InputArgs args :: [String]
    args) = case [String]
    args of
        []           -> Maybe (String, Input)
    forall a. Maybe a
    Nothing
        (('-':_):_ ) -> Maybe (String, Input)
    forall a. Maybe a
    Nothing
        (s1 :: String
    s1     :sR :: [String]
    sR) -> (String, Input) -> Maybe (String, Input)
    forall a. a -> Maybe a
    Just (String
    s1, [String] -> Input
    InputArgs [String]
    sR)

    -- | Add a parameter that consumes _all_ remaining input. Typical usecase is
    -- after a "--" as common in certain (unix?) commandline tools.
    addParamRestOfInput
      :: forall f out . (Applicative f)
      => String
      -> Param Void
      -> CmdParser f out String
    addParamRestOfInput :: String -> Param Void -> CmdParser f out String
    addParamRestOfInput = String -> Param Void -> CmdParser f out String
    forall (f :: * -> *) out.
    Applicative f =>
    String -> Param Void -> CmdParser f out String
    addRestOfInputStringParam
    {-# DEPRECATED addRestOfInputStringParam "use 'addParamRestOfInput'" #-}
    addRestOfInputStringParam
      :: forall f out
       . (Applicative f)
      => String
      -> Param Void
      -> CmdParser f out String
    addRestOfInputStringParam :: String -> Param Void -> CmdParser f out String
    addRestOfInputStringParam name :: String
    name par :: Param Void
    par = PartDesc
    -> (Input -> Maybe (String, Input)) -> CmdParser f out String
    forall (f :: * -> *) p out.
    (Applicative f, Typeable p) =>
    PartDesc -> (Input -> Maybe (p, Input)) -> CmdParser f out p
    addCmdPartInp PartDesc
    desc Input -> Maybe (String, Input)
    parseF
     where
      desc :: PartDesc
      desc :: PartDesc
    desc =
        Maybe [CompletionItem] -> PartDesc -> PartDesc
    addSuggestion (Param Void -> Maybe [CompletionItem]
    forall p. Param p -> Maybe [CompletionItem]
    _param_suggestions Param Void
    par)
          (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ ((PartDesc -> PartDesc)
    -> (Doc -> PartDesc -> PartDesc)
    -> Maybe Doc
    -> PartDesc
    -> PartDesc
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe PartDesc -> PartDesc
    forall a. a -> a
    id Doc -> PartDesc -> PartDesc
    PartWithHelp (Maybe Doc -> PartDesc -> PartDesc)
    -> Maybe Doc -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ Param Void -> Maybe Doc
    forall p. Param p -> Maybe Doc
    _param_help Param Void
    par)
          (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ String -> PartDesc
    PartVariable String
    name
      parseF :: Input -> Maybe (String, Input)
      parseF :: Input -> Maybe (String, Input)
    parseF (InputString str :: String
    str ) = (String, Input) -> Maybe (String, Input)
    forall a. a -> Maybe a
    Just (String
    str, String -> Input
    InputString "")
      parseF (InputArgs   args :: [String]
    args) = (String, Input) -> Maybe (String, Input)
    forall a. a -> Maybe a
    Just ([String] -> String
    List.unwords [String]
    args, [String] -> Input
    InputArgs [])

    -- | Add a parameter that consumes _all_ remaining input, returning a raw
    -- 'Input' value.
    addParamRestOfInputRaw
      :: forall f out . (Applicative f)
      => String
      -> Param Void
      -> CmdParser f out Input
    addParamRestOfInputRaw :: String -> Param Void -> CmdParser f out Input
    addParamRestOfInputRaw name :: String
    name par :: Param Void
    par = PartDesc
    -> (Input -> Maybe (Input, Input)) -> CmdParser f out Input
    forall (f :: * -> *) p out.
    (Applicative f, Typeable p) =>
    PartDesc -> (Input -> Maybe (p, Input)) -> CmdParser f out p
    addCmdPartInp PartDesc
    desc Input -> Maybe (Input, Input)
    parseF
     where
      desc :: PartDesc
      desc :: PartDesc
    desc =
        Maybe [CompletionItem] -> PartDesc -> PartDesc
    addSuggestion (Param Void -> Maybe [CompletionItem]
    forall p. Param p -> Maybe [CompletionItem]
    _param_suggestions Param Void
    par)
          (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ ((PartDesc -> PartDesc)
    -> (Doc -> PartDesc -> PartDesc)
    -> Maybe Doc
    -> PartDesc
    -> PartDesc
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe PartDesc -> PartDesc
    forall a. a -> a
    id Doc -> PartDesc -> PartDesc
    PartWithHelp (Maybe Doc -> PartDesc -> PartDesc)
    -> Maybe Doc -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ Param Void -> Maybe Doc
    forall p. Param p -> Maybe Doc
    _param_help Param Void
    par)
          (PartDesc -> PartDesc) -> PartDesc -> PartDesc
    forall a b. (a -> b) -> a -> b
    $ String -> PartDesc
    PartVariable String
    name
      parseF :: Input -> Maybe (Input, Input)
      parseF :: Input -> Maybe (Input, Input)
    parseF i :: Input
    i@InputString{} = (Input, Input) -> Maybe (Input, Input)
    forall a. a -> Maybe a
    Just (Input
    i, String -> Input
    InputString "")
      parseF i :: Input
    i@InputArgs{}   = (Input, Input) -> Maybe (Input, Input)
    forall a. a -> Maybe a
    Just (Input
    i, [String] -> Input
    InputArgs [])