glirc-2.36: src/Client/Commands/Types.hs
{-# Language ExistentialQuantification #-}
{-|
Module : Client.Commands.Types
Description : Types used to implement client commands
Copyright : (c) Eric Mertens, 2016-2020
License : ISC
Maintainer : emertens@gmail.com
-}
module Client.Commands.Types where
import Client.State (ClientState, clientErrorMsg)
import Client.State.Network (NetworkState)
import Data.Text (Text)
import Data.List.NonEmpty (NonEmpty)
import Client.Commands.Arguments.Spec
import Irc.Identifier (Identifier)
import Control.Lens
-- | Possible results of running a command
data CommandResult
-- | Continue running the client, consume input if command was from input
= CommandSuccess ClientState
-- | Continue running the client, report an error
| CommandFailure ClientState
-- | Client should close
| CommandQuit ClientState
-- | Type of commands that always work
type ClientCommand a = ClientState -> a {- ^ arguments -} -> IO CommandResult
-- | Type of commands that require an active network to be focused
type NetworkCommand a = NetworkState {- ^ current network -} -> ClientCommand a
-- | Type of commands that require an active channel to be focused
type ChannelCommand a = Identifier {- ^ focused channel -} -> NetworkCommand a
-- | Pair of implementations for executing a command and tab completing one.
-- The tab-completion logic is extended with a Bool
-- indicating that tab completion should be reversed
data CommandImpl a
-- | no requirements
= ClientCommand (ClientCommand a) (Bool -> ClientCommand String)
-- | requires an active network
| NetworkCommand (NetworkCommand a) (Bool -> NetworkCommand String)
-- | requires an active chat window
| ChatCommand (ChannelCommand a) (Bool -> ChannelCommand String)
-- | requires an active channel window
| ChannelCommand (ChannelCommand a) (Bool -> ChannelCommand String)
-- | A command is a list of aliases, an argument specification, implementation,
-- and documentation. The arguments and implementation must match so that
-- the parsed arguments will match what the implementation expects.
data Command = forall a. Command
{ -- | Names of this command, first in the list is the "primary" name
cmdNames :: NonEmpty Text
-- | Specification of the arguments of the command
, cmdArgumentSpec :: Args ClientState a
-- | Multi-line IRC-formatted documentation text used for @/help@
, cmdDocumentation :: Text
-- | Implementation of the command for both execution and tab completion
, cmdImplementation :: CommandImpl a
}
-- | A command section is a logical grouping of commands. This allows for
-- showing more structure in the help menu system.
data CommandSection = CommandSection
{ cmdSectionName :: Text
, cmdSectionCmds :: [Command]
}
-- | Consider the text entry successful and resume the client
commandSuccess :: Monad m => ClientState -> m CommandResult
commandSuccess = return . CommandSuccess
-- | Consider the text entry a failure and resume the client
commandFailure :: Monad m => ClientState -> m CommandResult
commandFailure = return . CommandFailure
-- | Command failure with an error message printed to client window
commandFailureMsg :: Text -> ClientState -> IO CommandResult
commandFailureMsg e st =
return $! CommandFailure $! set clientErrorMsg (Just e) st