-- | 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 [])