-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Dynamic key binding framework
--   
--   Dynamic key binding framework. See
--   <a>https://github.com/debug-ito/wild-bind</a>
@package wild-bind
@version 0.1.2.1


module WildBind.Description

-- | Human-readable description of an action. <a>ActionDescription</a> is
--   used to describe the current binding to the user.
type ActionDescription = Text

-- | Class for something describable.
class Describable d
describe :: Describable d => d -> ActionDescription
instance (WildBind.Description.Describable a, WildBind.Description.Describable b) => WildBind.Description.Describable (Data.Either.Either a b)


-- | This module exports functions to build and manipulate <a>Binding</a>,
--   an object binding input symbols to actions.
module WildBind.Binding

-- | Action done by WildBind
data Action m a
Action :: ActionDescription -> m a -> Action m a

-- | Human-readable description of the action.
[actDescription] :: Action m a -> ActionDescription

-- | The actual job.
[actDo] :: Action m a -> m a

-- | WildBind back-end binding between inputs and actions. <tt>s</tt> is
--   the front-end state type, and <tt>i</tt> is the input type.
type Binding s i = Binding' () s i

-- | WildBind back-end binding with both explicit and implicit states.
--   <tt>bs</tt> is the explicit back-end state, <tt>fs</tt> is the
--   front-end state, and <tt>i</tt> is the input type.
--   
--   You can make the explicit state <tt>bs</tt> implicit by
--   <a>startFrom</a> function.
data Binding' bs fs i

-- | A <a>Binding'</a> with no bindings. It's the same as <a>mempty</a>,
--   except <a>noBinding</a> requires no context.
noBinding :: Binding' bs fs i

-- | A monad to construct <a>Binding'</a>. <tt>i</tt> is the input symbol,
--   and <tt>v</tt> is supposed to be the <a>Action</a> bound to
--   <tt>i</tt>.
data Binder i v a

-- | Build a <a>Binding</a> with no explicit or implicit state. The bound
--   actions are activated regardless of the back-end or front-end state.
--   
--   If different actions are bound to the same input, the latter action
--   wins.
--   
--   Result of action (<tt>r</tt>) is discarded.
binds :: Ord i => Binder i (Action IO r) a -> Binding' bs fs i

-- | Build a <a>Binding'</a> with an explicit state (but no implicit
--   state). The bound actions are activated regardless of the back-end or
--   front-end state.
binds' :: Ord i => Binder i (Action (StateT bs IO) r) a -> Binding' bs fs i

-- | Like <a>binds</a>, but this function allows actions to use the current
--   front-end state via <a>ReaderT</a>.
bindsF :: Ord i => Binder i (Action (ReaderT fs IO) r) a -> Binding' bs fs i

-- | Like <a>binds'</a>, but this function allows actions to use the
--   current front-end state via <a>ReaderT</a>.
bindsF' :: Ord i => Binder i (Action (StateT bs (ReaderT fs IO)) r) a -> Binding' bs fs i

-- | Create a <a>Binder</a> that binds the action <tt>v</tt> to the input
--   <tt>i</tt>.
on :: i -> v -> Binder i v ()

-- | Transform the given action <tt>m a</tt> into an <a>Action</a> and
--   apply the continuation to it. It discards the result of action (type
--   <tt>a</tt>). Usually used as an operator.
run :: Functor m => (Action m () -> b) -> m a -> b
infixl 2 `run`

-- | Transform the given continuation so that the <a>ActionDescription</a>
--   is set to the <a>Action</a> passed to the continuation. Usually used
--   as an operator.
as :: (Action m a -> b) -> ActionDescription -> Action m a -> b
infixl 2 `as`

-- | Non-monadic version of <a>binds</a>.
binding :: Ord i => [(i, Action IO r)] -> Binding' bs fs i

-- | Non-monadic version of <a>binds'</a>.
binding' :: Ord i => [(i, Action (StateT bs IO) r)] -> Binding' bs fs i

-- | Non-monadic version of <a>bindsF</a>.
bindingF :: Ord i => [(i, Action (ReaderT fs IO) r)] -> Binding' bs fs i

-- | Non-monadic version of <a>bindsF'</a>.
bindingF' :: Ord i => [(i, Action (StateT bs (ReaderT fs IO)) r)] -> Binding' bs fs i

-- | Create a binding that behaves differently for different front-end
--   states <tt>fs</tt>.
ifFront :: (fs -> Bool) -> Binding' bs fs i -> Binding' bs fs i -> Binding' bs fs i

-- | Create a binding that behaves differently for different back-end
--   states <tt>bs</tt>.
ifBack :: (bs -> Bool) -> Binding' bs fs i -> Binding' bs fs i -> Binding' bs fs i

-- | Create a binding that behaves differently for different front-end and
--   back-end states, <tt>fs</tt> and <tt>bs</tt>.
ifBoth :: (bs -> fs -> Bool) -> Binding' bs fs i -> Binding' bs fs i -> Binding' bs fs i

-- | Add a condition on the front-end state to <a>Binding</a>.
whenFront :: (fs -> Bool) -> Binding' bs fs i -> Binding' bs fs i

-- | Add a condition on the back-end state to <a>Binding</a>.
whenBack :: (bs -> Bool) -> Binding' bs fs i -> Binding' bs fs i

-- | Add a condition on the back-end and front-end states to
--   <a>Binding</a>.
whenBoth :: (bs -> fs -> Bool) -> Binding' bs fs i -> Binding' bs fs i

-- | Convert <a>Binding'</a> to <a>Binding</a> by hiding the explicit state
--   <tt>bs</tt>.
startFrom :: bs -> Binding' bs fs i -> Binding fs i

-- | Extend <a>Binding</a> to <a>Binding'</a>. In the result
--   <a>Binding'</a>, the explicit back-end state is just ignored and
--   unmodified.
extend :: Binding fs i -> Binding' bs fs i

-- | Contramap the front-end state.
convFront :: (fs -> fs') -> Binding' bs fs' i -> Binding' bs fs i

-- | Map the front-end input.
convInput :: Ord i' => (i -> i') -> Binding' bs fs i -> Binding' bs fs i'

-- | Convert the back-end state. Intuitively, it converts a small state
--   type <tt>bs</tt> into a bigger state type <tt>bs'</tt>, which includes
--   <tt>bs</tt>.
--   
--   For example, if you have a <a>Lens'</a> <tt>l</tt>, you can do
--   
--   <pre>
--   convBack (set l) (view l) b
--   </pre>
convBack :: (bs -> bs' -> bs') -> (bs' -> bs) -> Binding' bs fs i -> Binding' bs' fs i

-- | Transform the actions in the given <a>Binder</a>.
advice :: (v -> v') -> Binder i v a -> Binder i v' a

-- | Revise (modify) actions in the given <a>Binding'</a>.
revise :: (forall a. bs -> fs -> i -> Action IO a -> Maybe (Action IO a)) -> Binding' bs fs i -> Binding' bs fs i

-- | Like <a>revise</a>, but this function allows revising the back-end
--   state.
revise' :: (forall a. bs -> fs -> i -> Action (StateT bs IO) a -> Maybe (Action (StateT bs IO) a)) -> Binding' bs fs i -> Binding' bs fs i

-- | Make an <a>Action</a> that runs the given monadic action before the
--   original <a>Action</a>.
before :: (Applicative m) => m b -> Action m a -> Action m a

-- | Make an <a>Action</a> that runs the given monadic action after the
--   original <a>Action</a>.
after :: (Applicative m) => m b -> Action m a -> Action m a

-- | Same as <a>before</a>, but it returns <a>Just</a>.
justBefore :: (Applicative m) => m b -> Action m a -> Maybe (Action m a)

-- | Same as <a>after</a>, but it returns <a>Just</a>.
justAfter :: (Applicative m) => m b -> Action m a -> Maybe (Action m a)

-- | Get the <a>Action</a> bound to the specified state <tt>s</tt> and
--   input <tt>i</tt>.
boundAction :: (Ord i) => Binding s i -> s -> i -> Maybe (Action IO (Binding s i))

-- | Get the <a>Action</a> bound to the specified back-end state
--   <tt>bs</tt>, front-end state <tt>fs</tt> and input <tt>i</tt>
boundAction' :: (Ord i) => Binding' bs fs i -> bs -> fs -> i -> Maybe (Action IO (Binding' bs fs i, bs))

-- | Get the list of all bound inputs <tt>i</tt> and their corresponding
--   actions for the specified front-end state <tt>s</tt>.
boundActions :: Binding s i -> s -> [(i, Action IO (Binding s i))]

-- | Get the list of all bound inputs <tt>i</tt> and their corresponding
--   actions for the specified back-end state <tt>bs</tt> and front-end
--   state <tt>fs</tt>.
boundActions' :: Binding' bs fs i -> bs -> fs -> [(i, Action IO (Binding' bs fs i, bs))]

-- | Get the list of all bound inputs <tt>i</tt> for the specified
--   front-end state <tt>s</tt>.
boundInputs :: Binding s i -> s -> [i]

-- | Get the list of all bound inputs <tt>i</tt> for the specified
--   front-end state <tt>fs</tt> and the back-end state <tt>bs</tt>.
boundInputs' :: Binding' bs fs i -> bs -> fs -> [i]
instance GHC.Base.Functor (WildBind.Binding.Binder i v)
instance GHC.Base.Applicative (WildBind.Binding.Binder i v)
instance GHC.Base.Monad (WildBind.Binding.Binder i v)
instance GHC.Classes.Ord i => GHC.Base.Semigroup (WildBind.Binding.Binding' bs fs i)
instance GHC.Classes.Ord i => GHC.Base.Monoid (WildBind.Binding.Binding' bs fs i)
instance GHC.Show.Show (WildBind.Binding.Action m a)
instance GHC.Base.Functor m => GHC.Base.Functor (WildBind.Binding.Action m)


-- | Data types and type classes about front-ends.
--   
--   You have to look at this module if you want to create a front-end
--   implementation.
module WildBind.FrontEnd

-- | Event from the front-end. <tt>s</tt> is the state of the front-end.
--   <tt>i</tt> is the input.
data FrontEvent s i

-- | An event that a new input is made.
FEInput :: i -> FrontEvent s i

-- | An event that the front-end state is changed.
FEChange :: s -> FrontEvent s i

-- | Interface to the front-end. <tt>s</tt> is the state of the front-end,
--   <tt>i</tt> is the input.
data FrontEnd s i
FrontEnd :: i -> ActionDescription -> i -> IO () -> i -> IO () -> IO (FrontEvent s i) -> FrontEnd s i

-- | Default <a>ActionDescription</a> for inputs
[frontDefaultDescription] :: FrontEnd s i -> i -> ActionDescription

-- | Action to grab (or capture) the specified input symbol on the device.
[frontSetGrab] :: FrontEnd s i -> i -> IO ()

-- | Action to release the grab for the input symbol.
[frontUnsetGrab] :: FrontEnd s i -> i -> IO ()

-- | Action to retrieve the next event. It should block if no event is
--   queued.
[frontNextEvent] :: FrontEnd s i -> IO (FrontEvent s i)
instance (GHC.Classes.Ord i, GHC.Classes.Ord s) => GHC.Classes.Ord (WildBind.FrontEnd.FrontEvent s i)
instance (GHC.Classes.Eq i, GHC.Classes.Eq s) => GHC.Classes.Eq (WildBind.FrontEnd.FrontEvent s i)
instance (GHC.Show.Show i, GHC.Show.Show s) => GHC.Show.Show (WildBind.FrontEnd.FrontEvent s i)


module WildBind.Exec

-- | Combines the <a>FrontEnd</a> and the <a>Binding</a> and returns the
--   executable.
wildBind :: (Ord i) => Binding s i -> FrontEnd s i -> IO ()

-- | Build the executable with <a>Option</a>.
wildBind' :: (Ord i) => Option s i -> Binding s i -> FrontEnd s i -> IO ()

-- | WildBind configuration options.
--   
--   You can get the default value of <a>Option</a> by <a>defOption</a>
--   funcion, and modify its members via accessor functions listed below.
data Option s i
defOption :: Option s i

-- | An action executed when current binding may be changed. Default: do
--   nothing.
optBindingHook :: Option s i -> [(i, ActionDescription)] -> IO ()

-- | the handler for exceptions thrown from bound actions. Default: just
--   print the <a>SomeException</a> to <a>stderr</a> and ignore it.
optCatch :: Option s i -> s -> i -> SomeException -> IO ()


-- | Input types for number pad keys.
module WildBind.Input.NumPad

-- | Number pad key input with NumLock disabled.
data NumPadUnlocked
NumInsert :: NumPadUnlocked
NumEnd :: NumPadUnlocked
NumDown :: NumPadUnlocked
NumPageDown :: NumPadUnlocked
NumLeft :: NumPadUnlocked
NumCenter :: NumPadUnlocked
NumRight :: NumPadUnlocked
NumHome :: NumPadUnlocked
NumUp :: NumPadUnlocked
NumPageUp :: NumPadUnlocked
NumDivide :: NumPadUnlocked
NumMulti :: NumPadUnlocked
NumMinus :: NumPadUnlocked
NumPlus :: NumPadUnlocked
NumEnter :: NumPadUnlocked
NumDelete :: NumPadUnlocked

-- | Number pad key input with NumLock enabled.
data NumPadLocked
NumL0 :: NumPadLocked
NumL1 :: NumPadLocked
NumL2 :: NumPadLocked
NumL3 :: NumPadLocked
NumL4 :: NumPadLocked
NumL5 :: NumPadLocked
NumL6 :: NumPadLocked
NumL7 :: NumPadLocked
NumL8 :: NumPadLocked
NumL9 :: NumPadLocked
NumLDivide :: NumPadLocked
NumLMulti :: NumPadLocked
NumLMinus :: NumPadLocked
NumLPlus :: NumPadLocked
NumLEnter :: NumPadLocked
NumLPeriod :: NumPadLocked
instance GHC.Enum.Enum WildBind.Input.NumPad.NumPadLocked
instance GHC.Enum.Bounded WildBind.Input.NumPad.NumPadLocked
instance GHC.Show.Show WildBind.Input.NumPad.NumPadLocked
instance GHC.Classes.Ord WildBind.Input.NumPad.NumPadLocked
instance GHC.Classes.Eq WildBind.Input.NumPad.NumPadLocked
instance GHC.Enum.Enum WildBind.Input.NumPad.NumPadUnlocked
instance GHC.Enum.Bounded WildBind.Input.NumPad.NumPadUnlocked
instance GHC.Show.Show WildBind.Input.NumPad.NumPadUnlocked
instance GHC.Classes.Ord WildBind.Input.NumPad.NumPadUnlocked
instance GHC.Classes.Eq WildBind.Input.NumPad.NumPadUnlocked
instance WildBind.Description.Describable WildBind.Input.NumPad.NumPadLocked
instance WildBind.Description.Describable WildBind.Input.NumPad.NumPadUnlocked


module WildBind


-- | This module defines convenient functions to build <a>Binding</a>s that
--   bind actions to key sequences.
--   
--   For example, see <a>WildBind.Task.X11.Seq.Example in
--   wild-bind-task-x11</a> package.
module WildBind.Seq

-- | Prepend prefix keys to a <a>Binding</a>. In the result <a>Binding</a>,
--   the original <a>Binding</a> is enabled only after you input the prefix
--   input symbols in the same order.
--   
--   During typing prefix keys, you can cancel and reset the key sequence
--   by typing the "cancel keys". This is analogous to <tt>C-g</tt> in
--   Emacs. The binding of cancel keys are weak, that is, they are
--   overridden by the original binding and prefix keys.
--   
--   Note that this function creates an independent implicit state to
--   memorize prefix keys input so far. This means,
--   
--   <pre>
--   (prefix [] [key1, key2] b) /= (prefix [] [key1] $ prefix [] [key2] b)
--   </pre>
--   
--   If you want a more composable way of building a sequence binding, try
--   <a>SeqBinding</a>.
prefix :: Ord i => [i] -> [i] -> Binding fs i -> Binding fs i

-- | Intermediate type of building a <a>Binding</a> for key sequences.
data SeqBinding fs i

-- | Create a <a>SeqBinding</a> from <a>Binding</a>. The result
--   <a>SeqBinding</a> has no prefixes yet.
toSeq :: Eq i => Binding fs i -> SeqBinding fs i

-- | Resolve <a>SeqBinding</a> to build a <a>Binding</a> for key sequences.
fromSeq :: SeqBinding fs i -> Binding fs i

-- | Prepend prefix keys to the <a>SeqBinding</a>.
--   
--   <a>SeqBinding</a> is composable in terms of prefixes, that is,
--   
--   <pre>
--   (withPrefix [key1, key2] seq_b) == (withPrefix [key1] $ withPrefix [key2] seq_b)
--   </pre>
withPrefix :: Ord i => [i] -> SeqBinding fs i -> SeqBinding fs i

-- | Add cancel keys to the <a>SeqBinding</a>.
withCancel :: Ord i => [i] -> SeqBinding fs i -> SeqBinding fs i

-- | Revise actions in <a>SeqBinding</a>. See <a>revise</a>.
reviseSeq :: (forall a. [i] -> fs -> i -> Action IO a -> Maybe (Action IO a)) -> SeqBinding fs i -> SeqBinding fs i
instance GHC.Classes.Ord i => GHC.Base.Semigroup (WildBind.Seq.SeqBinding fs i)
instance GHC.Classes.Ord i => GHC.Base.Monoid (WildBind.Seq.SeqBinding fs i)
