-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | A modular text editor
--
-- A modular text editor This is only a snippet, see the project's
-- README.
--
-- Rasa is a text editor project with a few interesting goals. For better
-- or worse it attempts to be as modular as possible. This means that
-- most functionality which would typically be considered to be
-- core in other editors is implemented as extensions in Rasa.
-- This approach comes with its own share of pros and cons, for instance:
--
-- Pros
--
--
-- - Implementing most core functionality as extensions ensures a
-- powerful and elegant extension interface.
-- - Flexibility; don't like the default cursor implementation? Write
-- your own!
-- - Adaptability; the core of Rasa is miniscule, you can mix and match
-- extensions to build any editor you want.
--
--
-- Cons
--
--
-- - Module cross-dependencies makes the community infrastructure more
-- fragile; We'll likely have to develop a solution to this as a
-- community as time goes on.
-- - Fragmentation; Not having a single implementation for a given
-- feature means extensions that depend on a feature have to pick a
-- specific implementation to augment. Over time data-structures and
-- types will be standardized into Rasa's core to help alleviate
-- this.
--
--
-- While highly experimental, I've found the current API to be quite
-- expressive and adaptable; for instance I was able to implement the
-- notion of multiple cursors using the extension API in less than a day.
-- I hope to keep the learning curve low as development continues.
--
-- Getting Started
--
-- First clone the Github repo and try running the example-config
-- included there. Once you get it running (see the README) then
-- you can customize your keymap to add a few mappings you like. Then I'd
-- check out the Building your own extensions guide. It goes in
-- depth into everything you'd want to know!
--
-- If you have any issues (and I'm sure there'll be a few; it's a new
-- project!) please report them here and we'll talk about it!
@package rasa
@version 0.1.10
module Rasa.Internal.Text
-- | An iso which converts to/from YiString -> Text
asText :: Iso' YiString Text
-- | An iso which converts to/from YiString -> String
asString :: Iso' YiString String
-- | An iso which converts to/from YiString -> [YiString]
asLines :: Iso' YiString [YiString]
module Rasa.Internal.Range
-- | A type alias to Coord' which specializes the types to integers.
type Coord = Coord' Int Int
-- | (Coord Row Column) represents a char in a block of text. (zero
-- indexed) e.g. Coord 0 0 is the first character in the text, Coord 2 1
-- is the second character of the third row
data Coord' a b
Coord :: a -> b -> Coord' a b
[_coordRow] :: Coord' a b -> a
[_coordCol] :: Coord' a b -> b
-- | Applies a function over the row of a Coord
overRow :: (Int -> Int) -> Coord -> Coord
-- | Applies a function over the column of a Coord
overCol :: (Int -> Int) -> Coord -> Coord
-- | Applies a function over both functors in any Bifunctor.
overBoth :: Bifunctor f => (a -> b) -> f a a -> f b b
coordRow :: forall a_agoI b_agoJ a_agxG. Lens (Coord' a_agoI b_agoJ) (Coord' a_agxG b_agoJ) a_agoI a_agxG
coordCol :: forall a_agoI b_agoJ b_agxF. Lens (Coord' a_agoI b_agoJ) (Coord' a_agoI b_agxF) b_agoJ b_agxF
-- | An Offset represents an exact position in a file as a number of
-- characters from the start.
newtype Offset
Offset :: Int -> Offset
-- | Given the text you're operating over, creates an iso from an
-- Offset to a Coord.
asCoord :: YiString -> Iso' Offset Coord
-- | This will restrict a given Coord to a valid one which lies
-- within the given text.
clampCoord :: YiString -> Coord -> Coord
-- | This will restrict a given Range to a valid one which lies
-- within the given text.
clampRange :: YiString -> CrdRange -> CrdRange
-- | This represents a range between two coordinates (Coord)
data Range a b
Range :: a -> b -> Range a b
[_rStart] :: Range a b -> a
[_rEnd] :: Range a b -> b
-- | A type alias to Range' which specializes the types to
-- Coords.
type CrdRange = Range Coord Coord
-- | A lens over text which is encompassed by a Range
range :: CrdRange -> Lens' YiString YiString
rStart :: forall a_aejV b_aejW a_agfq. Lens (Range a_aejV b_aejW) (Range a_agfq b_aejW) a_aejV a_agfq
rEnd :: forall a_aejV b_aejW b_agfp. Lens (Range a_aejV b_aejW) (Range a_aejV b_agfp) b_aejW b_agfp
-- | Returns the number of rows and columns that a chunk of text spans as a
-- Coord
sizeOf :: YiString -> Coord
-- | Returns the number of rows and columns that a Range spans as a
-- Coord
sizeOfR :: CrdRange -> Coord
-- | Moves a Range by a given Coord It may be unintuitive,
-- but for (Coord row col) a given range will be moved down by row and to
-- the right by col.
moveRange :: Coord -> CrdRange -> CrdRange
-- | Moves a range forward by the given amount
moveRangeByN :: Int -> CrdRange -> CrdRange
-- | Moves a Coord forward by the given amount of columns
moveCursorByN :: Int -> Coord -> Coord
-- | Adds the rows and columns of the given two Coords.
moveCursor :: Coord -> Coord -> Coord
-- | A span which maps a piece of Monoidal data over a range.
data Span a b
Span :: a -> b -> Span a b
-- | Combines a list of spans containing some monoidal data into a list of
-- offsets with with the data that applies from each Offset forwards.
combineSpans :: forall a. Monoid a => [Span CrdRange a] -> [(Coord, a)]
-- | clamp min max val restricts val to be within min and max
-- (inclusive)
clamp :: Int -> Int -> Int -> Int
-- | A lens over text before a given Coord
beforeC :: Coord -> Lens' YiString YiString
-- | A lens over text after a given Coord
afterC :: Coord -> Lens' YiString YiString
instance GHC.Classes.Eq Rasa.Internal.Range.Marker
instance GHC.Show.Show Rasa.Internal.Range.Marker
instance GHC.Base.Functor (Rasa.Internal.Range.Span a)
instance (GHC.Classes.Eq b, GHC.Classes.Eq a) => GHC.Classes.Eq (Rasa.Internal.Range.Span a b)
instance (GHC.Show.Show b, GHC.Show.Show a) => GHC.Show.Show (Rasa.Internal.Range.Span a b)
instance GHC.Classes.Eq Rasa.Internal.Range.Offset
instance GHC.Show.Show Rasa.Internal.Range.Offset
instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Rasa.Internal.Range.Coord' a b)
instance Data.Bifunctor.Bifunctor Rasa.Internal.Range.Coord'
instance Data.Biapplicative.Biapplicative Rasa.Internal.Range.Coord'
instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Rasa.Internal.Range.Coord' a b)
instance Data.Bifunctor.Bifunctor Rasa.Internal.Range.Span
instance (GHC.Num.Num a, GHC.Num.Num b) => GHC.Num.Num (Rasa.Internal.Range.Coord' a b)
instance (GHC.Classes.Eq b, GHC.Classes.Eq a) => GHC.Classes.Eq (Rasa.Internal.Range.Coord' a b)
instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Rasa.Internal.Range.Range a b)
instance Data.Bifunctor.Bifunctor Rasa.Internal.Range.Range
instance Data.Bifoldable.Bifoldable Rasa.Internal.Range.Range
instance Data.Bitraversable.Bitraversable Rasa.Internal.Range.Range
instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Rasa.Internal.Range.Range a b)
instance (GHC.Classes.Eq b, GHC.Classes.Eq a) => GHC.Classes.Eq (Rasa.Internal.Range.Range a b)
module Rasa.Internal.Extensions
-- | A wrapper around an extension of any type so it can be stored in an
-- ExtMap
data Ext
Ext :: a -> Ext
-- | A map of extension types to their current value.
type ExtMap = Map TypeRep Ext
-- | Members of this class have access to editor extensions.
class HasExts s
-- | This lens focuses the Extensions States
exts :: HasExts s => Lens' s (Map TypeRep Ext)
class (Typeable m, Monad m) => HasExtMonad m where overExt f = getExt >>= setExt . f
-- | Retrieve some extension state
getExt :: (HasExtMonad m, Typeable ext, Show ext, Default ext) => m ext
-- | Set some extension state
setExt :: (HasExtMonad m, Typeable ext, Show ext, Default ext) => ext -> m ()
-- | Set some extension state
overExt :: (HasExtMonad m, Typeable ext, Show ext, Default ext) => (ext -> ext) -> m ()
-- | This is a lens which will focus the extension state that matches the
-- type inferred as the focal point. It's a little bit of magic, if you
-- treat the focus as a member of your extension state it should just
-- work out.
--
-- This lens falls back on the extension's Default instance (when
-- getting) if nothing has yet been stored.
ext :: forall a e. (Show a, Typeable a, Default a, HasExts e) => Lens' e a
instance GHC.Show.Show Rasa.Internal.Extensions.Ext
module Rasa.Internal.Buffer
-- | A buffer, holds the text in the buffer and any extension states that
-- are set on the buffer.
data Buffer
-- | This allows creation of polymorphic lenses over any type which has
-- access to a Buffer
class HasBuffer a
buffer :: HasBuffer a => Lens' a Buffer
-- | An opaque reference to a buffer. When operating over a BufRef Rasa
-- checks if the Buffer still exists and simply ignores any
-- operations over non-existent buffers; typically returning
-- Nothing
newtype BufRef
BufRef :: Int -> BufRef
-- | This lens focuses the text of the in-scope buffer.
text :: HasBuffer b => Lens' b YiString
-- | Creates a new buffer from the given text.
mkBuffer :: YiString -> BufRef -> Buffer
ref :: Lens' Buffer BufRef
instance Rasa.Internal.Extensions.HasExts Rasa.Internal.Buffer.Buffer
instance GHC.Show.Show Rasa.Internal.Buffer.Buffer
instance Rasa.Internal.Buffer.HasBuffer Rasa.Internal.Buffer.Buffer
instance GHC.Classes.Ord Rasa.Internal.Buffer.BufRef
instance GHC.Classes.Eq Rasa.Internal.Buffer.BufRef
instance GHC.Show.Show Rasa.Internal.Buffer.BufRef
module Rasa.Internal.Editor
-- | This is the primary state of the editor.
data Editor
-- | This allows polymorphic lenses over anything that has access to an
-- Editor context
class HasEditor a
editor :: HasEditor a => Lens' a Editor
-- | A lens over the map of available buffers
buffers :: HasEditor e => Lens' e (IntMap Buffer)
-- | A lens over the exiting status of the editor
exiting :: HasEditor e => Lens' e Bool
-- | An opaque reference to a buffer. When operating over a BufRef Rasa
-- checks if the Buffer still exists and simply ignores any
-- operations over non-existent buffers; typically returning
-- Nothing
newtype BufRef
BufRef :: Int -> BufRef
instance GHC.Show.Show Rasa.Internal.Editor.Editor
instance Rasa.Internal.Editor.HasEditor Rasa.Internal.Editor.Editor
instance Rasa.Internal.Extensions.HasExts Rasa.Internal.Editor.Editor
instance Data.Default.Class.Default Rasa.Internal.Editor.Editor
module Rasa.Internal.Events
-- | This event is dispatched exactly once when the editor starts up.
data Init
Init :: Init
-- | This event is dispatched exactly once when the editor starts up after
-- onInit has occurred.
data AfterInit
AfterInit :: AfterInit
-- | This event is dispatched immediately before dispatching any events
-- from asyncronous event listeners (like Keypresss)
data BeforeEvent
BeforeEvent :: BeforeEvent
-- | This event is dispatched immediately before dispatching the
-- OnRender event.
data BeforeRender
BeforeRender :: BeforeRender
-- | This event is dispatched when it's time for extensions to render to
-- screen.
data OnRender
OnRender :: OnRender
-- | This event is dispatched immediately after dispatching
-- OnRender.
data AfterRender
AfterRender :: AfterRender
-- | This event is dispatched before exiting the editor, listen for this to
-- do any clean-up (saving files, etc.)
data Exit
Exit :: Exit
-- | This event is dispatched after adding a new buffer. The contained
-- BufRef refers to the new buffer.
data BufAdded
BufAdded :: BufRef -> BufAdded
-- | This event is dispatched in response to keyboard key presses. It
-- contains both the char that was pressed and any modifiers (Mod)
-- that where held when the key was pressed.
data Keypress
Keypress :: Char -> [Mod] -> Keypress
KEsc :: [Mod] -> Keypress
KBS :: [Mod] -> Keypress
KEnter :: [Mod] -> Keypress
KLeft :: [Mod] -> Keypress
KRight :: [Mod] -> Keypress
KUp :: [Mod] -> Keypress
KDown :: [Mod] -> Keypress
KPrtScr :: [Mod] -> Keypress
KHome :: [Mod] -> Keypress
KPageUp :: [Mod] -> Keypress
KDel :: [Mod] -> Keypress
KEnd :: [Mod] -> Keypress
KPageDown :: [Mod] -> Keypress
KUnknown :: Keypress
-- | This represents each modifier key that could be pressed along with a
-- key.
data Mod
Ctrl :: Mod
Alt :: Mod
Shift :: Mod
Meta :: Mod
-- | This is triggered when text in a buffer is changed. The Event data
-- includes the CrdRange that changed and the new text which is
-- now contined in that range.
data BufTextChanged
BufTextChanged :: CrdRange -> YiString -> BufTextChanged
instance GHC.Classes.Eq Rasa.Internal.Events.BufTextChanged
instance GHC.Show.Show Rasa.Internal.Events.BufTextChanged
instance GHC.Classes.Eq Rasa.Internal.Events.Keypress
instance GHC.Show.Show Rasa.Internal.Events.Keypress
instance GHC.Classes.Eq Rasa.Internal.Events.Mod
instance GHC.Show.Show Rasa.Internal.Events.Mod
instance GHC.Classes.Eq Rasa.Internal.Events.BufAdded
instance GHC.Show.Show Rasa.Internal.Events.BufAdded
instance GHC.Classes.Eq Rasa.Internal.Events.Exit
instance GHC.Show.Show Rasa.Internal.Events.Exit
instance GHC.Classes.Eq Rasa.Internal.Events.AfterRender
instance GHC.Show.Show Rasa.Internal.Events.AfterRender
instance GHC.Classes.Eq Rasa.Internal.Events.OnRender
instance GHC.Show.Show Rasa.Internal.Events.OnRender
instance GHC.Classes.Eq Rasa.Internal.Events.BeforeRender
instance GHC.Show.Show Rasa.Internal.Events.BeforeRender
instance GHC.Classes.Eq Rasa.Internal.Events.BeforeEvent
instance GHC.Show.Show Rasa.Internal.Events.BeforeEvent
instance GHC.Classes.Eq Rasa.Internal.Events.AfterInit
instance GHC.Show.Show Rasa.Internal.Events.AfterInit
instance GHC.Classes.Eq Rasa.Internal.Events.Init
instance GHC.Show.Show Rasa.Internal.Events.Init
module Rasa.Internal.ActionMonads
-- | This is a monad for performing actions against the editor. You can
-- register Actions to be run in response to events using
-- onEveryTrigger
--
-- Within an Action you can:
--
--
-- - Use liftIO for IO
-- - Access/edit extensions that are stored globally, see
-- ext
-- - Embed any Actions exported other extensions
-- - Embed buffer actions using bufDo or buffersDo
-- - Add/Edit/Focus buffers and a few other Editor-level things, see
-- the Rasa.Internal.Actions module.
--
newtype Action a
Action :: Free ActionF a -> Action a
[getAction] :: Action a -> Free ActionF a
-- | This is a monad for performing actions on a specific buffer. You run
-- BufActions by embedding them in a Action via
-- bufferDo or buffersDo
--
-- Within a BufAction you can:
--
--
-- - Use liftAction to run an Action
-- - Use liftIO for IO
-- - Access/Edit the buffer's text; some commands are available in
-- Rasa.Internal.Actions.
-- - Access/edit buffer extensions; see bufExt
-- - Embed and sequence BufActions from other extensions
--
newtype BufAction a
BufAction :: Free BufActionF a -> BufAction a
[getBufAction] :: BufAction a -> Free BufActionF a
-- | Free Monad Actions for Action
data ActionF next
[LiftIO] :: IO next -> ActionF next
[BufferDo] :: [BufRef] -> BufAction r -> ([r] -> next) -> ActionF next
[DispatchActionAsync] :: IO (Action ()) -> next -> ActionF next
[AsyncActionProvider] :: ((Action () -> IO ()) -> IO ()) -> next -> ActionF next
[AddBuffer] :: YiString -> (BufRef -> next) -> ActionF next
[GetBufRefs] :: ([BufRef] -> next) -> ActionF next
[GetExt] :: (Typeable ext, Show ext, Default ext) => (ext -> next) -> ActionF next
[SetExt] :: (Typeable ext, Show ext, Default ext) => ext -> next -> ActionF next
[GetEditor] :: (Editor -> next) -> ActionF next
[GetBuffer] :: BufRef -> (Maybe Buffer -> next) -> ActionF next
[Exit] :: next -> ActionF next
[ShouldExit] :: (Bool -> next) -> ActionF next
-- | Free Monad Actions for BufAction
data BufActionF next
[GetText] :: (YiString -> next) -> BufActionF next
[SetText] :: YiString -> next -> BufActionF next
[GetBufRef] :: (BufRef -> next) -> BufActionF next
[GetBufExt] :: (Typeable ext, Show ext, Default ext) => (ext -> next) -> BufActionF next
[SetBufExt] :: (Typeable ext, Show ext, Default ext) => ext -> next -> BufActionF next
[SetRange] :: CrdRange -> YiString -> next -> BufActionF next
[LiftAction] :: Action r -> (r -> next) -> BufActionF next
[BufLiftIO] :: IO next -> BufActionF next
-- | Embeds a ActionF type into the Action Monad
liftActionF :: ActionF a -> Action a
-- | Embeds a BufActionF type into the BufAction Monad
liftBufAction :: BufActionF a -> BufAction a
instance GHC.Base.Monad Rasa.Internal.ActionMonads.Action
instance GHC.Base.Applicative Rasa.Internal.ActionMonads.Action
instance GHC.Base.Functor Rasa.Internal.ActionMonads.Action
instance GHC.Base.Monad Rasa.Internal.ActionMonads.BufAction
instance GHC.Base.Applicative Rasa.Internal.ActionMonads.BufAction
instance GHC.Base.Functor Rasa.Internal.ActionMonads.BufAction
instance GHC.Base.Functor Rasa.Internal.ActionMonads.ActionF
instance GHC.Base.Functor Rasa.Internal.ActionMonads.BufActionF
instance Control.Monad.IO.Class.MonadIO Rasa.Internal.ActionMonads.Action
instance Rasa.Internal.Extensions.HasExtMonad Rasa.Internal.ActionMonads.Action
instance Control.Monad.IO.Class.MonadIO Rasa.Internal.ActionMonads.BufAction
instance Rasa.Internal.Extensions.HasExtMonad Rasa.Internal.ActionMonads.BufAction
module Rasa.Internal.BufAction
-- | This is a monad for performing actions on a specific buffer. You run
-- BufActions by embedding them in a Action via
-- bufferDo or buffersDo
--
-- Within a BufAction you can:
--
--
-- - Use liftAction to run an Action
-- - Use liftIO for IO
-- - Access/Edit the buffer's text; some commands are available in
-- Rasa.Internal.Actions.
-- - Access/edit buffer extensions; see bufExt
-- - Embed and sequence BufActions from other extensions
--
newtype BufAction a
BufAction :: Free BufActionF a -> BufAction a
[getBufAction] :: BufAction a -> Free BufActionF a
-- | Returns the text of the current buffer
getText :: BufAction YiString
-- | Sets the text of the current buffer
setText :: YiString -> BufAction ()
-- | Gets the current buffer's BufRef
getBufRef :: BufAction BufRef
-- | Gets the range of text from the buffer
getRange :: CrdRange -> BufAction YiString
-- | Sets the range of text from the buffer
setRange :: CrdRange -> YiString -> BufAction ()
-- | Retrieve some buffer extension state
getBufExt :: (Typeable ext, Show ext, Default ext) => BufAction ext
-- | Set some buffer extension state
setBufExt :: (Typeable ext, Show ext, Default ext) => ext -> BufAction ()
-- | Set some buffer extension state
overBufExt :: (Typeable ext, Show ext, Default ext) => (ext -> ext) -> BufAction ()
-- | This lifts up an Action to be run inside a BufAction
liftAction :: Action r -> BufAction r
module Rasa.Internal.BufActions
-- | Runs function over given range of text
overRange :: CrdRange -> (YiString -> YiString) -> BufAction ()
-- | Replaces the text in the given range with the given text.
replaceRange :: CrdRange -> YiString -> BufAction ()
-- | Deletes the text in the given range from the buffer.
deleteRange :: CrdRange -> BufAction ()
-- | Inserts text into the buffer at the given Coord.
insertAt :: Coord -> YiString -> BufAction ()
-- | Returns the number of rows and columns that a chunk of text spans as a
-- Coord
sizeOf :: YiString -> Coord
-- | Gets the range representing a given row (if that row exists)
getLineRange :: Row -> BufAction (Maybe CrdRange)
module Rasa.Internal.Action
-- | This is a monad for performing actions against the editor. You can
-- register Actions to be run in response to events using
-- onEveryTrigger
--
-- Within an Action you can:
--
--
-- - Use liftIO for IO
-- - Access/edit extensions that are stored globally, see
-- ext
-- - Embed any Actions exported other extensions
-- - Embed buffer actions using bufDo or buffersDo
-- - Add/Edit/Focus buffers and a few other Editor-level things, see
-- the Rasa.Internal.Actions module.
--
newtype Action a
Action :: Free ActionF a -> Action a
[getAction] :: Action a -> Free ActionF a
-- | dispatchActionAsync allows you to perform a task asynchronously and
-- then apply the result. In dispatchActionAsync asyncAction,
-- asyncAction is an IO which resolves to an Action, note that
-- the context in which the second action is executed is NOT the same
-- context in which dispatchActionAsync is called; it is likely that text
-- and other state have changed while the IO executed, so it's a good
-- idea to check (inside the applying Action) that things are in a good
-- state before making changes. Here's an example:
--
--
-- asyncCapitalize :: Action ()
-- asyncCapitalize = do
-- txt <- focusDo getText
-- -- We give dispatchActionAsync an IO which resolves in an action
-- dispatchActionAsync $ ioPart txt
--
-- ioPart :: Text -> IO (Action ())
-- ioPart txt = do
-- result <- longAsyncronousCapitalizationProgram txt
-- -- Note that this returns an Action, but it's still wrapped in IO
-- return $ maybeApplyResult txt result
--
-- maybeApplyResult :: Text -> Text -> Action ()
-- maybeApplyResult oldTxt capitalized = do
-- -- We get the current buffer's text, which may have changed since we started
-- newTxt <- focusDo getText
-- if newTxt == oldTxt
-- -- If the text is the same as it was, we can apply the transformation
-- then focusDo (setText capitalized)
-- -- Otherwise we can choose to re-queue the whole action and try again
-- -- Or we could just give up.
-- else asyncCapitalize
--
dispatchActionAsync :: IO (Action ()) -> Action ()
-- | Don't let the type signature confuse you; it's much simpler than it
-- seems. The first argument is a function which takes an action
-- provider; the action provider will be passed a dispatch function which
-- can be called as often as you like with Action ()s. When it
-- is passed an Action it forks off an IO to dispatch that
-- Action to the main event loop. Note that the dispatch function
-- calls forkIO on its own; so there's no need for you to do so.
--
-- Use this function when you have some long-running process which
-- dispatches multiple Actions.
--
-- Here's an example which fires a Timer event every second.
--
--
-- data Timer = TimerFired
-- dispatchTimer :: Action ()
-- dispatchTimer = mkDispatcher Timer
-- myTimer :: (Action () -> IO ()) -> IO ()
-- myTimer dispatch = forever $ dispatch dispatchTimer >> threadDelay 1000000
--
-- myAction :: Action ()
-- myAction = onInit $ asyncActionProvider myTimer
--
asyncActionProvider :: ((Action () -> IO ()) -> IO ()) -> Action ()
-- | Runs a BufAction over the given BufRefs, returning any results.
--
-- Result list is not guaranteed to be the same length or positioning as
-- input BufRef list; some buffers may no longer exist.
bufferDo :: [BufRef] -> BufAction r -> Action [r]
-- | Adds a new buffer and returns the BufRef
addBuffer :: YiString -> Action BufRef
-- | Returns an up-to-date list of all BufRefs
getBufRefs :: Action [BufRef]
-- | Retrieve some extension state
getExt :: (HasExtMonad m, Typeable ext, Show ext, Default ext) => m ext
-- | Set some extension state
setExt :: (HasExtMonad m, Typeable ext, Show ext, Default ext) => ext -> m ()
-- | Set some extension state
overExt :: (HasExtMonad m, Typeable ext, Show ext, Default ext) => (ext -> ext) -> m ()
-- | This signals to the editor that you'd like to shutdown. The current
-- events will finish processing, then the onExit event will be
-- dispatched, then the editor will exit.
exit :: Action ()
shouldExit :: Action Bool
-- | Retrieve a buffer. This is read-only for
-- loggingrenderingdebugging purposes only.
getBuffer :: BufRef -> Action (Maybe Buffer)
-- | Retrieve the entire editor state. This is read-only for
-- loggingrenderingdebugging purposes only.
getEditor :: Action Editor
module Rasa.Internal.Actions
-- | This lifts a BufAction to an Action which performs the
-- BufAction on the buffer referred to by the BufRef If the
-- buffer referred to no longer exists this returns: Nothing.
bufDo :: BufRef -> BufAction a -> Action (Maybe a)
bufDo_ :: BufRef -> BufAction a -> Action ()
-- | This lifts a BufAction to an Action which performs the
-- BufAction on every buffer and collects the return values as a
-- list.
buffersDo :: BufAction a -> Action [a]
buffersDo_ :: BufAction a -> Action ()
-- | This signals to the editor that you'd like to shutdown. The current
-- events will finish processing, then the onExit event will be
-- dispatched, then the editor will exit.
exit :: Action ()
-- | Returns an up-to-date list of all BufRefs
getBufRefs :: Action [BufRef]
-- | Gets BufRef that comes after the one provided
nextBufRef :: BufRef -> Action BufRef
-- | Gets BufRef that comes before the one provided
prevBufRef :: BufRef -> Action BufRef
module Rasa.Internal.Listeners
-- | Dispatches an event of any type. This should be used to define your
-- own custom event dispatchers (with more concrete types) which you can
-- re-export. You can collect results from all listeners if they were
-- registered to return an Action result where result
-- is a Monoid (for example a list).
dispatchEvent :: forall result eventType. (Monoid result, Typeable eventType, Typeable result) => eventType -> Action result
-- | This adds an event listener which listens for events of
-- eventType and will run the resulting Action result
-- when triggered by some dispatchEvent.
--
-- This should primarily be used to create your own more specific
-- addListener functions which you re-export.
addListener :: (Typeable eventType, Typeable result, Monoid result) => (eventType -> Action result) -> Action ListenerId
addListener_ :: (Typeable eventType, Typeable result, Monoid result) => (eventType -> Action result) -> Action ()
-- | Removes the listener represented by the given ListenerId.
removeListener :: ListenerId -> Action ()
-- | Dispatches an event of any type to the BufAction's buffer. See
-- dispatchEvent
dispatchBufEvent :: (Monoid result, Typeable eventType, Typeable result) => (eventType -> BufAction result)
-- | Adds a listener to the BufAction's buffer. See addListener
addBufListener :: (Typeable eventType, Typeable result, Monoid result) => (eventType -> BufAction result) -> BufAction ListenerId
addBufListener_ :: (Typeable eventType, Typeable result, Monoid result) => (eventType -> BufAction result) -> BufAction ()
-- | Removes a listener from the BufAction's buffer. See
-- removeListener
removeBufListener :: ListenerId -> BufAction ()
-- | This is a type alias to make defining your functions for use with
-- asyncEventProvider easier; It represents the function your
-- event provider function will be passed to allow dispatching events.
-- Using this type requires the RankNTypes language pragma.
type Dispatcher = forall event. Typeable event => event -> IO ()
-- | An opaque reverence to a specific registered event-listener. A
-- ListenerId is used only to remove listeners later with
-- removeListener.
data ListenerId
-- | Registers an action to be performed during the Initialization phase.
--
-- This phase occurs exactly ONCE when the editor starts up. 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 result -> Action ()
-- | Dispatch the Init action.
dispatchInit :: Action ()
afterInit :: Action a -> Action ()
-- | Dispatch the Init action.
dispatchAfterInit :: 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.
beforeEveryRender :: Action a -> Action ListenerId
beforeEveryRender_ :: Action a -> Action ()
-- | Dispatch the BeforeRender action.
dispatchBeforeRender :: Action ()
-- | Registers an action to be performed BEFORE each event phase.
beforeEveryEvent :: Action a -> Action ListenerId
beforeEveryEvent_ :: Action a -> Action ()
-- | Dispatch the BeforeEvent action.
dispatchBeforeEvent :: Action ()
-- | Registers an action to be performed during each render phase.
--
-- This phase should only be used by extensions which actually render
-- something.
onEveryRender :: Action a -> Action ListenerId
onEveryRender_ :: Action a -> Action ()
-- | Dispatch the OnRender action.
dispatchOnRender :: 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.
afterEveryRender :: Action a -> Action ListenerId
afterEveryRender_ :: Action a -> Action ()
-- | Dispatch the AfterRender action.
dispatchAfterRender :: 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 a -> Action ()
-- | Dispatch the Exit action.
dispatchExit :: 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 :: (BufAdded -> Action result) -> Action ListenerId
onBufAdded_ :: (BufAdded -> Action result) -> Action ()
-- | Dispatch the BufAdded action.
dispatchBufAdded :: BufAdded -> Action ()
-- | Run the given BufAction over all new buffers
onEveryNewBuffer :: BufAction a -> Action ListenerId
onEveryNewBuffer_ :: BufAction a -> Action ()
-- | This is fired every time text in a buffer changes.
--
-- The range of text which was altered and the new value of that text are
-- provided inside a BufTextChanged event.
onBufTextChanged :: (BufTextChanged -> BufAction result) -> BufAction ListenerId
-- | Dispatch the BufBufTextChanged action.
dispatchBufTextChanged :: BufTextChanged -> BufAction ()
-- | Trigger an Action on a Keypress
onKeypress :: (Keypress -> Action result) -> Action ListenerId
-- | Dispatch a Keypress event.
dispatchKeypress :: Keypress -> Action ()
-- | This allows long-running IO processes to provide Events to Rasa
-- asyncronously.
--
-- Don't let the type signature confuse you; it's much simpler than it
-- seems.
--
-- Let's break it down:
--
-- Using the Dispatcher type with asyncEventProvider requires the
-- RankNTypes language pragma.
--
-- This type as a whole represents a function which accepts a
-- Dispatcher and returns an IO; the dispatcher itself
-- accepts data of ANY Typeable type and emits it as an event (see
-- Rasa.Internal.Events).
--
-- When you call asyncEventProvider you pass it a function which
-- accepts a dispatch function as an argument and then calls it
-- with various events within the resulting IO.
--
-- Note that asyncEventProvider calls forkIO internally, so there's no
-- need to do that yourself.
--
-- Here's an example which fires a Timer event every second.
--
--
-- {-# language RankNTypes #-}
-- data Timer = Timer
-- myTimer :: Dispatcher -> IO ()
-- myTimer dispatch = forever $ dispatch Timer >> threadDelay 1000000
--
-- myAction :: Action ()
-- myAction = onInit $ asyncEventProvider myTimer
--
asyncEventProvider :: (Dispatcher -> IO ()) -> Action ()
-- | This function takes an IO which results in some Event, it runs the IO
-- asynchronously and dispatches the event
dispatchEventAsync :: Typeable event => IO event -> Action ()
instance GHC.Show.Show Rasa.Internal.Listeners.LocalListeners
instance GHC.Show.Show Rasa.Internal.Listeners.ListenerId
instance GHC.Show.Show Rasa.Internal.Listeners.Listener
instance GHC.Classes.Eq Rasa.Internal.Listeners.ListenerId
instance Data.Default.Class.Default Rasa.Internal.Listeners.LocalListeners
module Rasa.Internal.Interpreters
-- | Runs an Action into an IO
runAction :: ActionState -> Action a -> IO (a, ActionState)
-- | Evals an Action into an IO
evalAction :: ActionState -> Action a -> IO a
-- | Execs an Action into an IO
execAction :: ActionState -> Action a -> IO ActionState
-- | Spawn the channels necessary to run action and do so.
bootstrapAction :: Action a -> IO a
mkActionState :: Output (Action ()) -> ActionState
-- | This lifts up a bufAction into an Action which performs the
-- BufAction over the referenced buffer and returns the result (if
-- the buffer existed)
runBufAction :: BufAction a -> Buffer -> Action (a, Buffer)
instance GHC.Show.Show Rasa.Internal.Interpreters.ActionState
instance Rasa.Internal.Editor.HasEditor Rasa.Internal.Interpreters.ActionState
instance Rasa.Internal.Extensions.HasExts Rasa.Internal.Interpreters.ActionState
module Rasa.Internal.Styles
-- | Create a new Style with the given Color as the
-- foreground.
fg :: Color -> Style
-- | Create a new Style with the given Color as the
-- background.
bg :: Color -> Style
-- | Create a new Style with the given Flair as its flair.
flair :: Flair -> Style
-- | These represent the possible colors for fg or bg.
-- DefColor represents the renderer's default color.
data Color
Black :: Color
Red :: Color
Green :: Color
Yellow :: Color
Blue :: Color
Magenta :: Color
Cyan :: Color
White :: Color
DefColor :: Color
-- | These represent the possible extra attributes which may be applied.
-- DefFlair represents the renderer's default text attributes.
data Flair
Standout :: Flair
Underline :: Flair
ReverseVideo :: Flair
Blink :: Flair
Dim :: Flair
Bold :: Flair
DefFlair :: Flair
-- | A container which holds a foreground color, background color, and a
-- flair. a Nothing represents that we should not change that
-- attribute.
newtype Style
Style :: (Maybe Color, Maybe Color, Maybe Flair) -> Style
type Styles = [Span CrdRange Style]
-- | Pass this a BufAction which computes styles based on the
-- current buffer and they'll be collected for the renderer.
addStyleProvider :: BufAction Styles -> BufAction ListenerId
-- | Collect all provided styles, this is useful for renderers.
getStyles :: BufAction Styles
instance GHC.Base.Monoid Rasa.Internal.Styles.StyleMap
instance GHC.Classes.Eq Rasa.Internal.Styles.StyleMap
instance GHC.Show.Show Rasa.Internal.Styles.StyleMap
instance GHC.Classes.Eq Rasa.Internal.Styles.Style
instance GHC.Show.Show Rasa.Internal.Styles.Style
instance GHC.Classes.Eq Rasa.Internal.Styles.Flair
instance GHC.Show.Show Rasa.Internal.Styles.Flair
instance GHC.Classes.Eq Rasa.Internal.Styles.Color
instance GHC.Show.Show Rasa.Internal.Styles.Color
instance Data.Default.Class.Default Rasa.Internal.Styles.Style
instance GHC.Base.Monoid Rasa.Internal.Styles.Style
instance Data.Default.Class.Default Rasa.Internal.Styles.StyleMap
module Rasa.Internal.Utility
type Width = Int
type Height = Int
-- | Represents how to render an entity
class Renderable r
render :: Renderable r => Width -> Height -> ScrollPos -> r -> Action (Maybe RenderInfo)
-- | RenderInfo is the data necessary to render something; it consists of a
-- block of text with its associated styles. It is a Monoid and can be
-- appended with other RenderInfos.
data RenderInfo
RenderInfo :: YiString -> Styles -> RenderInfo
type ScrollPos = Int
-- | Crop text verticaly to only the visible portion according to viewport
-- height and scroll position.
cropToViewport :: Height -> ScrollPos -> RenderInfo -> RenderInfo
-- | Add a style to some text resulting in a RenderInfo
styleText :: YiString -> Style -> RenderInfo
instance GHC.Base.Monoid Rasa.Internal.Utility.RenderInfo
instance Rasa.Internal.Utility.Renderable r => Rasa.Internal.Utility.Renderable (GHC.Base.Maybe r)
instance Rasa.Internal.Utility.Renderable Rasa.Internal.Buffer.BufRef
instance Rasa.Internal.Utility.Renderable Yi.Rope.YiString
instance Rasa.Internal.Utility.Renderable Rasa.Internal.Utility.RenderInfo
module Rasa.Testing
testBufAction :: (Show a, Eq a) => String -> YiString -> a -> BufAction a -> Spec
-- | This module contains the public API for building an extension for
-- Rasa. It re-exports the parts of rasa that are public API for creating
-- extensions.
--
-- There are two main things that an extension can do, either react to
-- editor events, or expose useful actions and/or state for other
-- extensions to use.
--
-- Whether performing its own actions or being used by a different
-- extension an extension will want to define some Actions to
-- perform. Actions can operate over buffers or even perform IO and
-- comprise the main way in which extensons do what they need to do. Read
-- more here: Action, BufAction.
--
-- To sum it all up, Here's an example of a simple logging extension that
-- simply writes each keypress to a file.
--
--
-- logKeypress :: Keypress -> Action ()
-- logKeypress (Keypress char _) = liftIO $ appendFile "logs" ("You pressed " ++ [char] ++ "\n")
-- logKeypress _ = return ()
--
-- logger :: Action ()
-- logger = do
-- onInit $ liftIO $ writeFile "logs" "==Logs==\n"
-- -- Listeners should also be registered using 'onInit'.
-- -- It ensures all listeners are ready before any actions occur.
-- onInit $ onKeypress logKeypress
-- onExit $ liftIO $ appendFile "logs" "==Done=="
--
--
-- Check out this tutorial on building extensions, it's also just a great
-- way to learn how the editor works: Extension-Guide.
module Rasa.Ext
-- | This is a monad for performing actions against the editor. You can
-- register Actions to be run in response to events using
-- onEveryTrigger
--
-- Within an Action you can:
--
--
-- - Use liftIO for IO
-- - Access/edit extensions that are stored globally, see
-- ext
-- - Embed any Actions exported other extensions
-- - Embed buffer actions using bufDo or buffersDo
-- - Add/Edit/Focus buffers and a few other Editor-level things, see
-- the Rasa.Internal.Actions module.
--
data Action a
-- | Retrieve a buffer. This is read-only for
-- loggingrenderingdebugging purposes only.
getBuffer :: BufRef -> Action (Maybe Buffer)
-- | Retrieve the entire editor state. This is read-only for
-- loggingrenderingdebugging purposes only.
getEditor :: Action Editor
-- | This signals to the editor that you'd like to shutdown. The current
-- events will finish processing, then the onExit event will be
-- dispatched, then the editor will exit.
exit :: Action ()
-- | Adds a new buffer and returns the BufRef
addBuffer :: YiString -> Action BufRef
-- | Gets BufRef that comes after the one provided
nextBufRef :: BufRef -> Action BufRef
-- | Gets BufRef that comes before the one provided
prevBufRef :: BufRef -> Action BufRef
-- | Returns an up-to-date list of all BufRefs
getBufRefs :: Action [BufRef]
-- | A buffer, holds the text in the buffer and any extension states that
-- are set on the buffer.
data Buffer
-- | This allows creation of polymorphic lenses over any type which has
-- access to a Buffer
class HasBuffer a
buffer :: HasBuffer a => Lens' a Buffer
-- | An opaque reference to a buffer. When operating over a BufRef Rasa
-- checks if the Buffer still exists and simply ignores any
-- operations over non-existent buffers; typically returning
-- Nothing
data BufRef
-- | This lens focuses the text of the in-scope buffer.
text :: HasBuffer b => Lens' b YiString
-- | This allows polymorphic lenses over anything that has access to an
-- Editor context
class HasEditor a
-- | Returns the text of the current buffer
getText :: BufAction YiString
-- | Gets the range of text from the buffer
getRange :: CrdRange -> BufAction YiString
-- | Gets the current buffer's BufRef
getBufRef :: BufAction BufRef
-- | This is a monad for performing actions on a specific buffer. You run
-- BufActions by embedding them in a Action via
-- bufferDo or buffersDo
--
-- Within a BufAction you can:
--
--
-- - Use liftAction to run an Action
-- - Use liftIO for IO
-- - Access/Edit the buffer's text; some commands are available in
-- Rasa.Internal.Actions.
-- - Access/edit buffer extensions; see bufExt
-- - Embed and sequence BufActions from other extensions
--
data BufAction a
-- | This lifts up an Action to be run inside a BufAction
liftAction :: Action r -> BufAction r
-- | This lifts a BufAction to an Action which performs the
-- BufAction on the buffer referred to by the BufRef If the
-- buffer referred to no longer exists this returns: Nothing.
bufDo :: BufRef -> BufAction a -> Action (Maybe a)
bufDo_ :: BufRef -> BufAction a -> Action ()
-- | This lifts a BufAction to an Action which performs the
-- BufAction on every buffer and collects the return values as a
-- list.
buffersDo :: BufAction a -> Action [a]
buffersDo_ :: BufAction a -> Action ()
-- | Runs function over given range of text
overRange :: CrdRange -> (YiString -> YiString) -> BufAction ()
-- | Replaces the text in the given range with the given text.
replaceRange :: CrdRange -> YiString -> BufAction ()
-- | Deletes the text in the given range from the buffer.
deleteRange :: CrdRange -> BufAction ()
-- | Inserts text into the buffer at the given Coord.
insertAt :: Coord -> YiString -> BufAction ()
-- | Returns the number of rows and columns that a chunk of text spans as a
-- Coord
sizeOf :: YiString -> Coord
-- | Gets the range representing a given row (if that row exists)
getLineRange :: Row -> BufAction (Maybe CrdRange)
-- | Members of this class have access to editor extensions.
class HasExts s
-- | This lens focuses the Extensions States
exts :: HasExts s => Lens' s (Map TypeRep Ext)
-- | This is a lens which will focus the extension state that matches the
-- type inferred as the focal point. It's a little bit of magic, if you
-- treat the focus as a member of your extension state it should just
-- work out.
--
-- This lens falls back on the extension's Default instance (when
-- getting) if nothing has yet been stored.
ext :: forall a e. (Show a, Typeable a, Default a, HasExts e) => Lens' e a
-- | Retrieve some extension state
getExt :: (HasExtMonad m, Typeable ext, Show ext, Default ext) => m ext
-- | Set some extension state
setExt :: (HasExtMonad m, Typeable ext, Show ext, Default ext) => ext -> m ()
-- | Set some extension state
overExt :: (HasExtMonad m, Typeable ext, Show ext, Default ext) => (ext -> ext) -> m ()
-- | Retrieve some buffer extension state
getBufExt :: (Typeable ext, Show ext, Default ext) => BufAction ext
-- | Set some buffer extension state
setBufExt :: (Typeable ext, Show ext, Default ext) => ext -> BufAction ()
-- | Set some buffer extension state
overBufExt :: (Typeable ext, Show ext, Default ext) => (ext -> ext) -> BufAction ()
-- | Dispatches an event of any type. This should be used to define your
-- own custom event dispatchers (with more concrete types) which you can
-- re-export. You can collect results from all listeners if they were
-- registered to return an Action result where result
-- is a Monoid (for example a list).
dispatchEvent :: forall result eventType. (Monoid result, Typeable eventType, Typeable result) => eventType -> Action result
-- | This adds an event listener which listens for events of
-- eventType and will run the resulting Action result
-- when triggered by some dispatchEvent.
--
-- This should primarily be used to create your own more specific
-- addListener functions which you re-export.
addListener :: (Typeable eventType, Typeable result, Monoid result) => (eventType -> Action result) -> Action ListenerId
addListener_ :: (Typeable eventType, Typeable result, Monoid result) => (eventType -> Action result) -> Action ()
-- | Removes the listener represented by the given ListenerId.
removeListener :: ListenerId -> Action ()
-- | Dispatches an event of any type to the BufAction's buffer. See
-- dispatchEvent
dispatchBufEvent :: (Monoid result, Typeable eventType, Typeable result) => (eventType -> BufAction result)
-- | Adds a listener to the BufAction's buffer. See addListener
addBufListener :: (Typeable eventType, Typeable result, Monoid result) => (eventType -> BufAction result) -> BufAction ListenerId
addBufListener_ :: (Typeable eventType, Typeable result, Monoid result) => (eventType -> BufAction result) -> BufAction ()
-- | Removes a listener from the BufAction's buffer. See
-- removeListener
removeBufListener :: ListenerId -> BufAction ()
-- | An opaque reverence to a specific registered event-listener. A
-- ListenerId is used only to remove listeners later with
-- removeListener.
data ListenerId
-- | This event is dispatched in response to keyboard key presses. It
-- contains both the char that was pressed and any modifiers (Mod)
-- that where held when the key was pressed.
data Keypress
Keypress :: Char -> [Mod] -> Keypress
KEsc :: [Mod] -> Keypress
KBS :: [Mod] -> Keypress
KEnter :: [Mod] -> Keypress
KLeft :: [Mod] -> Keypress
KRight :: [Mod] -> Keypress
KUp :: [Mod] -> Keypress
KDown :: [Mod] -> Keypress
KPrtScr :: [Mod] -> Keypress
KHome :: [Mod] -> Keypress
KPageUp :: [Mod] -> Keypress
KDel :: [Mod] -> Keypress
KEnd :: [Mod] -> Keypress
KPageDown :: [Mod] -> Keypress
KUnknown :: Keypress
-- | This represents each modifier key that could be pressed along with a
-- key.
data Mod
Ctrl :: Mod
Alt :: Mod
Shift :: Mod
Meta :: Mod
-- | Dispatch a Keypress event.
dispatchKeypress :: Keypress -> Action ()
-- | This event is dispatched after adding a new buffer. The contained
-- BufRef refers to the new buffer.
data BufAdded
BufAdded :: BufRef -> BufAdded
-- | This is triggered when text in a buffer is changed. The Event data
-- includes the CrdRange that changed and the new text which is
-- now contined in that range.
data BufTextChanged
BufTextChanged :: CrdRange -> YiString -> BufTextChanged
-- | Registers an action to be performed during the Initialization phase.
--
-- This phase occurs exactly ONCE when the editor starts up. 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 result -> Action ()
afterInit :: Action a -> Action ()
-- | Registers an action to be performed BEFORE each event phase.
beforeEveryEvent :: Action a -> Action ListenerId
beforeEveryEvent_ :: Action a -> 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.
beforeEveryRender :: Action a -> Action ListenerId
beforeEveryRender_ :: Action a -> Action ()
-- | Registers an action to be performed during each render phase.
--
-- This phase should only be used by extensions which actually render
-- something.
onEveryRender :: Action a -> Action ListenerId
onEveryRender_ :: Action a -> 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.
afterEveryRender :: Action a -> Action ListenerId
afterEveryRender_ :: Action a -> 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 a -> 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 :: (BufAdded -> Action result) -> Action ListenerId
onBufAdded_ :: (BufAdded -> Action result) -> Action ()
-- | Run the given BufAction over all new buffers
onEveryNewBuffer :: BufAction a -> Action ListenerId
onEveryNewBuffer_ :: BufAction a -> Action ()
-- | This is fired every time text in a buffer changes.
--
-- The range of text which was altered and the new value of that text are
-- provided inside a BufTextChanged event.
onBufTextChanged :: (BufTextChanged -> BufAction result) -> BufAction ListenerId
-- | Trigger an Action on a Keypress
onKeypress :: (Keypress -> Action result) -> Action ListenerId
-- | dispatchActionAsync allows you to perform a task asynchronously and
-- then apply the result. In dispatchActionAsync asyncAction,
-- asyncAction is an IO which resolves to an Action, note that
-- the context in which the second action is executed is NOT the same
-- context in which dispatchActionAsync is called; it is likely that text
-- and other state have changed while the IO executed, so it's a good
-- idea to check (inside the applying Action) that things are in a good
-- state before making changes. Here's an example:
--
--
-- asyncCapitalize :: Action ()
-- asyncCapitalize = do
-- txt <- focusDo getText
-- -- We give dispatchActionAsync an IO which resolves in an action
-- dispatchActionAsync $ ioPart txt
--
-- ioPart :: Text -> IO (Action ())
-- ioPart txt = do
-- result <- longAsyncronousCapitalizationProgram txt
-- -- Note that this returns an Action, but it's still wrapped in IO
-- return $ maybeApplyResult txt result
--
-- maybeApplyResult :: Text -> Text -> Action ()
-- maybeApplyResult oldTxt capitalized = do
-- -- We get the current buffer's text, which may have changed since we started
-- newTxt <- focusDo getText
-- if newTxt == oldTxt
-- -- If the text is the same as it was, we can apply the transformation
-- then focusDo (setText capitalized)
-- -- Otherwise we can choose to re-queue the whole action and try again
-- -- Or we could just give up.
-- else asyncCapitalize
--
dispatchActionAsync :: IO (Action ()) -> Action ()
-- | This function takes an IO which results in some Event, it runs the IO
-- asynchronously and dispatches the event
dispatchEventAsync :: Typeable event => IO event -> Action ()
-- | Don't let the type signature confuse you; it's much simpler than it
-- seems. The first argument is a function which takes an action
-- provider; the action provider will be passed a dispatch function which
-- can be called as often as you like with Action ()s. When it
-- is passed an Action it forks off an IO to dispatch that
-- Action to the main event loop. Note that the dispatch function
-- calls forkIO on its own; so there's no need for you to do so.
--
-- Use this function when you have some long-running process which
-- dispatches multiple Actions.
--
-- Here's an example which fires a Timer event every second.
--
--
-- data Timer = TimerFired
-- dispatchTimer :: Action ()
-- dispatchTimer = mkDispatcher Timer
-- myTimer :: (Action () -> IO ()) -> IO ()
-- myTimer dispatch = forever $ dispatch dispatchTimer >> threadDelay 1000000
--
-- myAction :: Action ()
-- myAction = onInit $ asyncActionProvider myTimer
--
asyncActionProvider :: ((Action () -> IO ()) -> IO ()) -> Action ()
-- | This allows long-running IO processes to provide Events to Rasa
-- asyncronously.
--
-- Don't let the type signature confuse you; it's much simpler than it
-- seems.
--
-- Let's break it down:
--
-- Using the Dispatcher type with asyncEventProvider requires the
-- RankNTypes language pragma.
--
-- This type as a whole represents a function which accepts a
-- Dispatcher and returns an IO; the dispatcher itself
-- accepts data of ANY Typeable type and emits it as an event (see
-- Rasa.Internal.Events).
--
-- When you call asyncEventProvider you pass it a function which
-- accepts a dispatch function as an argument and then calls it
-- with various events within the resulting IO.
--
-- Note that asyncEventProvider calls forkIO internally, so there's no
-- need to do that yourself.
--
-- Here's an example which fires a Timer event every second.
--
--
-- {-# language RankNTypes #-}
-- data Timer = Timer
-- myTimer :: Dispatcher -> IO ()
-- myTimer dispatch = forever $ dispatch Timer >> threadDelay 1000000
--
-- myAction :: Action ()
-- myAction = onInit $ asyncEventProvider myTimer
--
asyncEventProvider :: (Dispatcher -> IO ()) -> Action ()
-- | This is a type alias to make defining your functions for use with
-- asyncEventProvider easier; It represents the function your
-- event provider function will be passed to allow dispatching events.
-- Using this type requires the RankNTypes language pragma.
type Dispatcher = forall event. Typeable event => event -> IO ()
-- | This represents a range between two coordinates (Coord)
data Range a b
Range :: a -> b -> Range a b
[_rStart] :: Range a b -> a
[_rEnd] :: Range a b -> b
-- | A type alias to Range' which specializes the types to
-- Coords.
type CrdRange = Range Coord Coord
-- | A type alias to Coord' which specializes the types to integers.
type Coord = Coord' Int Int
-- | (Coord Row Column) represents a char in a block of text. (zero
-- indexed) e.g. Coord 0 0 is the first character in the text, Coord 2 1
-- is the second character of the third row
data Coord' a b
Coord :: a -> b -> Coord' a b
[_coordRow] :: Coord' a b -> a
[_coordCol] :: Coord' a b -> b
-- | An Offset represents an exact position in a file as a number of
-- characters from the start.
newtype Offset
Offset :: Int -> Offset
-- | A span which maps a piece of Monoidal data over a range.
data Span a b
Span :: a -> b -> Span a b
-- | Applies a function over the row of a Coord
overRow :: (Int -> Int) -> Coord -> Coord
-- | Applies a function over the column of a Coord
overCol :: (Int -> Int) -> Coord -> Coord
coordRow :: forall a_agoI b_agoJ a_agxG. Lens (Coord' a_agoI b_agoJ) (Coord' a_agxG b_agoJ) a_agoI a_agxG
coordCol :: forall a_agoI b_agoJ b_agxF. Lens (Coord' a_agoI b_agoJ) (Coord' a_agoI b_agxF) b_agoJ b_agxF
-- | Applies a function over both functors in any Bifunctor.
overBoth :: Bifunctor f => (a -> b) -> f a a -> f b b
-- | Combines a list of spans containing some monoidal data into a list of
-- offsets with with the data that applies from each Offset forwards.
combineSpans :: forall a. Monoid a => [Span CrdRange a] -> [(Coord, a)]
-- | Given the text you're operating over, creates an iso from an
-- Offset to a Coord.
asCoord :: YiString -> Iso' Offset Coord
-- | This will restrict a given Coord to a valid one which lies
-- within the given text.
clampCoord :: YiString -> Coord -> Coord
-- | This will restrict a given Range to a valid one which lies
-- within the given text.
clampRange :: YiString -> CrdRange -> CrdRange
rStart :: forall a_aejV b_aejW a_agfq. Lens (Range a_aejV b_aejW) (Range a_agfq b_aejW) a_aejV a_agfq
rEnd :: forall a_aejV b_aejW b_agfp. Lens (Range a_aejV b_aejW) (Range a_aejV b_agfp) b_aejW b_agfp
-- | Returns the number of rows and columns that a Range spans as a
-- Coord
sizeOfR :: CrdRange -> Coord
-- | A lens over text after a given Coord
afterC :: Coord -> Lens' YiString YiString
-- | A lens over text before a given Coord
beforeC :: Coord -> Lens' YiString YiString
-- | Moves a Range by a given Coord It may be unintuitive,
-- but for (Coord row col) a given range will be moved down by row and to
-- the right by col.
moveRange :: Coord -> CrdRange -> CrdRange
-- | Moves a range forward by the given amount
moveRangeByN :: Int -> CrdRange -> CrdRange
-- | Moves a Coord forward by the given amount of columns
moveCursorByN :: Int -> Coord -> Coord
-- | Create a new Style with the given Color as the
-- foreground.
fg :: Color -> Style
-- | Create a new Style with the given Color as the
-- background.
bg :: Color -> Style
-- | Create a new Style with the given Flair as its flair.
flair :: Flair -> Style
-- | These represent the possible colors for fg or bg.
-- DefColor represents the renderer's default color.
data Color
Black :: Color
Red :: Color
Green :: Color
Yellow :: Color
Blue :: Color
Magenta :: Color
Cyan :: Color
White :: Color
DefColor :: Color
-- | These represent the possible extra attributes which may be applied.
-- DefFlair represents the renderer's default text attributes.
data Flair
Standout :: Flair
Underline :: Flair
ReverseVideo :: Flair
Blink :: Flair
Dim :: Flair
Bold :: Flair
DefFlair :: Flair
-- | A container which holds a foreground color, background color, and a
-- flair. a Nothing represents that we should not change that
-- attribute.
newtype Style
Style :: (Maybe Color, Maybe Color, Maybe Flair) -> Style
type Styles = [Span CrdRange Style]
-- | Pass this a BufAction which computes styles based on the
-- current buffer and they'll be collected for the renderer.
addStyleProvider :: BufAction Styles -> BufAction ListenerId
-- | Collect all provided styles, this is useful for renderers.
getStyles :: BufAction Styles
-- | Add a style to some text resulting in a RenderInfo
styleText :: YiString -> Style -> RenderInfo
-- | An iso which converts to/from YiString -> Text
asText :: Iso' YiString Text
-- | An iso which converts to/from YiString -> String
asString :: Iso' YiString String
-- | An iso which converts to/from YiString -> [YiString]
asLines :: Iso' YiString [YiString]
-- | clamp min max val restricts val to be within min and max
-- (inclusive)
clamp :: Int -> Int -> Int -> Int
-- | Crop text verticaly to only the visible portion according to viewport
-- height and scroll position.
cropToViewport :: Height -> ScrollPos -> RenderInfo -> RenderInfo
type Width = Int
type Height = Int
type ScrollPos = Int
-- | RenderInfo is the data necessary to render something; it consists of a
-- block of text with its associated styles. It is a Monoid and can be
-- appended with other RenderInfos.
data RenderInfo
RenderInfo :: YiString -> Styles -> RenderInfo
-- | Represents how to render an entity
class Renderable r
render :: Renderable r => Width -> Height -> ScrollPos -> r -> Action (Maybe RenderInfo)
module Rasa
-- | The main function to run rasa.
--
--
-- rasa eventProviders extensions
--
--
-- This should be imported by a user-config with and called with an
-- Action containing any extensions which have event listeners.
--
--
-- rasa $ do
-- cursor
-- vim
-- slate
--
rasa :: Action () -> IO ()