rasa 0.1.6 → 0.1.7
raw patch · 5 files changed
+94/−41 lines, 5 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Rasa.Ext: afterRender :: Action () -> Action HookId
- Rasa.Ext: beforeEvent :: Action () -> Action HookId
- Rasa.Ext: beforeRender :: Action () -> Action HookId
- Rasa.Ext: eventListener :: forall a. Typeable a => (a -> Action ()) -> Action HookId
- Rasa.Ext: onRender :: Action () -> Action HookId
- Rasa.Internal.Scheduler: afterRender :: Action () -> Action HookId
- Rasa.Internal.Scheduler: beforeEvent :: Action () -> Action HookId
- Rasa.Internal.Scheduler: beforeRender :: Action () -> Action HookId
- Rasa.Internal.Scheduler: eventListener :: forall a. Typeable a => (a -> Action ()) -> Action HookId
- Rasa.Internal.Scheduler: onRender :: Action () -> Action HookId
+ Rasa.Ext: afterEveryRender :: Action () -> Action HookId
+ Rasa.Ext: afterEveryRender_ :: Action () -> Action ()
+ Rasa.Ext: afterNextRender :: Action () -> Action ()
+ Rasa.Ext: beforeEveryEvent :: Action () -> Action HookId
+ Rasa.Ext: beforeEveryEvent_ :: Action () -> Action ()
+ Rasa.Ext: beforeEveryRender :: Action () -> Action HookId
+ Rasa.Ext: beforeEveryRender_ :: Action () -> Action ()
+ Rasa.Ext: beforeNextEvent :: Action () -> Action ()
+ Rasa.Ext: beforeNextRender :: Action () -> Action ()
+ Rasa.Ext: onEveryRender :: Action () -> Action HookId
+ Rasa.Ext: onEveryRender_ :: Action () -> Action ()
+ Rasa.Ext: onEveryTrigger :: forall a. Typeable a => (a -> Action ()) -> Action HookId
+ Rasa.Ext: onEveryTrigger_ :: forall a. Typeable a => (a -> Action ()) -> Action ()
+ Rasa.Ext: onNextEvent :: forall a. Typeable a => (a -> Action ()) -> Action ()
+ Rasa.Ext: onNextRender :: Action () -> Action ()
+ Rasa.Internal.Scheduler: afterEveryRender :: Action () -> Action HookId
+ Rasa.Internal.Scheduler: afterEveryRender_ :: Action () -> Action ()
+ Rasa.Internal.Scheduler: afterNextRender :: Action () -> Action ()
+ Rasa.Internal.Scheduler: beforeEveryEvent :: Action () -> Action HookId
+ Rasa.Internal.Scheduler: beforeEveryEvent_ :: Action () -> Action ()
+ Rasa.Internal.Scheduler: beforeEveryRender :: Action () -> Action HookId
+ Rasa.Internal.Scheduler: beforeEveryRender_ :: Action () -> Action ()
+ Rasa.Internal.Scheduler: beforeNextEvent :: Action () -> Action ()
+ Rasa.Internal.Scheduler: beforeNextRender :: Action () -> Action ()
+ Rasa.Internal.Scheduler: onEveryRender :: Action () -> Action HookId
+ Rasa.Internal.Scheduler: onEveryRender_ :: Action () -> Action ()
+ Rasa.Internal.Scheduler: onEveryTrigger :: forall a. Typeable a => (a -> Action ()) -> Action HookId
+ Rasa.Internal.Scheduler: onEveryTrigger_ :: forall a. Typeable a => (a -> Action ()) -> Action ()
+ Rasa.Internal.Scheduler: onNextEvent :: forall a. Typeable a => (a -> Action ()) -> Action ()
+ Rasa.Internal.Scheduler: onNextRender :: Action () -> Action ()
- Rasa.Ext: onExit :: Action () -> Action HookId
+ Rasa.Ext: onExit :: Action () -> Action ()
- Rasa.Ext: onInit :: Action () -> Action HookId
+ Rasa.Ext: onInit :: Action () -> Action ()
- Rasa.Internal.Action: Hook :: HookId -> a -> Hook
+ Rasa.Internal.Action: Hook :: HookId -> (a -> Action ()) -> Hook
- Rasa.Internal.Scheduler: onExit :: Action () -> Action HookId
+ Rasa.Internal.Scheduler: onExit :: Action () -> Action ()
- Rasa.Internal.Scheduler: onInit :: Action () -> Action HookId
+ Rasa.Internal.Scheduler: onInit :: Action () -> Action ()
Files
- rasa.cabal +1/−1
- src/Rasa.hs +1/−1
- src/Rasa/Ext.hs +17/−12
- src/Rasa/Internal/Action.hs +2/−2
- src/Rasa/Internal/Scheduler.hs +73/−25
rasa.cabal view
@@ -1,5 +1,5 @@ name: rasa-version: 0.1.6+version: 0.1.7 cabal-version: >=1.10 build-type: Simple license: MIT
src/Rasa.hs view
@@ -17,7 +17,7 @@ -- -- @rasa eventProviders extensions@ ----- This should be imported by a user-config with and called with a 'Scheduler'+-- This should be imported by a user-config with and called with an 'Action' -- containing any extensions which have event listeners. -- -- > rasa $ do
src/Rasa/Ext.hs view
@@ -14,11 +14,6 @@ -- to editor events, or expose useful actions and/or state for other extensions -- to use. ----- To react to events an extension defines a 'Scheduler'--- which the user puts in their config file. The 'Scheduler'--- defines listeners for events which the extension will react to.--- See 'Scheduler' for more detailed information.--- -- Whether performing its own actions or being used by a different extension -- an extension will want to define some 'Action's to perform. Actions -- can operate over buffers or even perform IO and comprise the main way in which@@ -30,10 +25,10 @@ -- > logKeypress :: Keypress -> Action () -- > logKeypress (Keypress char _) = liftIO $ appendFile "logs" ("You pressed " ++ [char] ++ "\n") -- >--- > logger :: Scheduler ()+-- > logger :: Action HookId -- > logger = do -- > onInit $ liftIO $ writeFile "logs" "==Logs==\n"--- > eventListener logKeypress+-- > onEveryTrigger_ logKeypress -- > onExit $ liftIO $ appendFile "logs" "==Done==" -- -- Check out this tutorial on building extensions, it's also just a great way to learn@@ -126,16 +121,26 @@ , Hook , HookId , dispatchEvent- , eventListener+ , onEveryTrigger+ , onEveryTrigger_+ , onNextEvent , removeListener , eventProvider -- * Built-in Event Hooks- , beforeEvent- , beforeRender- , onRender- , afterRender , onInit+ , beforeEveryEvent+ , beforeEveryEvent_+ , beforeNextEvent+ , beforeEveryRender+ , beforeEveryRender_+ , beforeNextRender+ , onEveryRender+ , onEveryRender_+ , onNextRender+ , afterEveryRender+ , afterEveryRender_+ , afterNextRender , onExit , onBufAdded
src/Rasa/Internal/Action.hs view
@@ -15,7 +15,7 @@ -- | A wrapper around event listeners so they can be stored in 'Hooks'.-data Hook = forall a. Hook HookId a+data Hook = forall a. Hook HookId (a -> Action ()) data HookId = HookId Int TypeRep @@ -26,7 +26,7 @@ type Hooks = Map TypeRep [Hook] -- | This is a monad-transformer stack for performing actions against the editor.--- You register Actions to be run in response to events using 'Rasa.Internal.Scheduler.eventListener'+-- You register Actions to be run in response to events using 'Rasa.Internal.Scheduler.onEveryTrigger' -- -- Within an Action you can: --
src/Rasa/Internal/Scheduler.hs view
@@ -3,16 +3,26 @@ module Rasa.Internal.Scheduler ( Hook , Hooks- , afterRender- , beforeEvent- , beforeRender+ , onEveryTrigger+ , onEveryTrigger_+ , onNextEvent+ , onInit+ , beforeEveryEvent+ , beforeEveryEvent_+ , beforeNextEvent+ , beforeEveryRender+ , beforeEveryRender_+ , beforeNextRender+ , onEveryRender+ , onEveryRender_+ , onNextRender+ , afterEveryRender+ , afterEveryRender_+ , afterNextRender , dispatchEvent- , eventListener+ , onExit , removeListener , matchingHooks- , onInit- , onExit- , onRender , onBufAdded ) where @@ -22,6 +32,7 @@ import Rasa.Internal.Editor import Control.Lens+import Control.Monad import Data.Dynamic import Data.Foldable import Data.Map hiding (filter)@@ -47,21 +58,34 @@ let hookId = HookId n (typeRep (Proxy :: Proxy a)) return (hookId, Hook hookId hookFunc) +extendHook :: Hook -> Action () -> Hook+extendHook (Hook hookId hookFunc) act = Hook hookId (\a -> hookFunc a >> act)+ -- | This extracts all event listener hooks from a map of hooks which match the type of the provided event. matchingHooks :: forall a. Typeable a => Hooks -> [a -> Action ()] matchingHooks hooks' = getHook <$> (hooks'^.at (typeRep (Proxy :: Proxy a))._Just) -- | This registers an event listener hook, as long as the listener is well-typed similar to this: ----- @MyEventType -> Action ()@ then it will be registered to listen for dispatched events of that type.--- Use within the 'Rasa.Internal.Scheduler.Scheduler' and add have the user add it to their config.--- It returns an ID which may be used with 'removeListener'-eventListener :: forall a. Typeable a => (a -> Action ()) -> Action HookId-eventListener hookFunc = do+-- @MyEventType -> Action ()@ then it will be triggered on all dispatched events of that type.+-- It returns an ID which may be used with 'removeListener' to cancel the listener+onEveryTrigger :: forall a. Typeable a => (a -> Action ()) -> Action HookId+onEveryTrigger hookFunc = do (hookId, hook) <- makeHook hookFunc hooks %= insertWith mappend (typeRep (Proxy :: Proxy a)) [hook] return hookId +onEveryTrigger_ :: forall a. Typeable a => (a -> Action ()) -> Action ()+onEveryTrigger_ = void . onEveryTrigger+++-- | This acts as 'onEveryTrigger' but listens only for the first event of a given type.+onNextEvent :: forall a. Typeable a => (a -> Action ()) -> Action ()+onNextEvent hookFunc = do+ (hookId, hook) <- makeHook hookFunc+ let selfCancellingHook = extendHook hook (removeListener hookId)+ hooks %= insertWith mappend (typeRep (Proxy :: Proxy a)) [selfCancellingHook]+ -- | This removes a listener and prevents it from responding to any more events. removeListener :: HookId -> Action () removeListener hkIdA@(HookId _ typ) =@@ -75,47 +99,71 @@ -- Though arbitrary actions may be performed in the configuration block; -- it's recommended to embed such actions in the onInit event listener -- so that all event listeners are registered before anything Actions occur.-onInit :: Action () -> Action HookId-onInit action = eventListener (const action :: Init -> Action ())+onInit :: Action () -> Action ()+onInit action = void $ onEveryTrigger (const action :: Init -> Action ()) -- | Registers an action to be performed BEFORE each event phase.-beforeEvent :: Action () -> Action HookId-beforeEvent action = eventListener (const action :: BeforeEvent -> Action ())+beforeEveryEvent :: Action () -> Action HookId+beforeEveryEvent action = onEveryTrigger (const action :: BeforeEvent -> Action ()) +beforeEveryEvent_ :: Action () -> Action ()+beforeEveryEvent_ = void . beforeEveryEvent++beforeNextEvent :: Action () -> Action ()+beforeNextEvent action = onNextEvent (const action :: BeforeEvent -> Action ())+ -- | Registers an action to be performed BEFORE each render phase. -- -- This is a good spot to add information useful to the renderer -- since all actions have been performed. Only cosmetic changes should -- occur during this phase.-beforeRender :: Action () -> Action HookId-beforeRender action = eventListener (const action :: BeforeRender -> Action ())+beforeEveryRender :: Action () -> Action HookId+beforeEveryRender action = onEveryTrigger (const action :: BeforeRender -> Action ()) +beforeEveryRender_ :: Action () -> Action ()+beforeEveryRender_ = void . beforeEveryRender++beforeNextRender :: Action () -> Action ()+beforeNextRender action = onNextEvent (const action :: BeforeRender -> Action ())+ -- | Registers an action to be performed during each render phase. -- -- This phase should only be used by extensions which actually render something.-onRender :: Action () -> Action HookId-onRender action = eventListener (const action :: OnRender -> Action ())+onEveryRender :: Action () -> Action HookId+onEveryRender action = onEveryTrigger (const action :: OnRender -> Action ()) +onEveryRender_ :: Action () -> Action ()+onEveryRender_ = void . onEveryRender++onNextRender :: Action () -> Action ()+onNextRender action = onNextEvent (const action :: OnRender -> Action ())+ -- | Registers an action to be performed AFTER each render phase. -- -- This is useful for cleaning up extension state that was registered for the -- renderer, but needs to be cleared before the next iteration.-afterRender :: Action () -> Action HookId-afterRender action = eventListener (const action :: AfterRender -> Action ())+afterEveryRender :: Action () -> Action HookId+afterEveryRender action = onEveryTrigger (const action :: AfterRender -> Action ()) +afterEveryRender_ :: Action () -> Action ()+afterEveryRender_ = void . afterEveryRender++afterNextRender :: Action () -> Action ()+afterNextRender action = onNextEvent (const action :: AfterRender -> Action ())+ -- | Registers an action to be performed during the exit phase. -- -- This is only triggered exactly once when the editor is shutting down. It -- allows an opportunity to do clean-up, kill any processes you've started, or -- save any data before the editor terminates. -onExit :: Action () -> Action HookId-onExit action = eventListener (const action :: Exit -> Action ())+onExit :: Action () -> Action ()+onExit action = void $ onEveryTrigger (const action :: Exit -> Action ()) -- | Registers an action to be performed after a new buffer is added. -- -- The supplied function will be called with a 'BufRef' to the new buffer, and the resulting 'Action' will be run. onBufAdded :: (BufRef -> Action ()) -> Action HookId-onBufAdded f = eventListener listener+onBufAdded f = onEveryTrigger listener where listener (BufAdded bRef) = f bRef