module Rasa.Internal.Actions
(
bufDo
, bufDo_
, buffersDo
, buffersDo_
, exit
, newBuffer
, getBufRefs
, getBuffers
, getBuffer
, nextBufRef
, prevBufRef
, overRange
, replaceRange
, deleteRange
, insertAt
, sizeOf
) where
import Rasa.Internal.Editor
import Rasa.Internal.Action
import Rasa.Internal.BufAction
import Rasa.Internal.Range
import Rasa.Internal.Listeners
import Rasa.Internal.Events
import Rasa.Internal.Buffer as B
import Control.Lens
import Control.Monad
import Control.Arrow (first)
import Data.Maybe
import Data.IntMap as M
import qualified Yi.Rope as Y
buffersDo :: BufAction a -> Action [a]
buffersDo bufAct = do
bufRefs <- getBufRefs
catMaybes . foldMap (:[]) <$> mapM (runBufAction bufAct) bufRefs
buffersDo_ :: BufAction a -> Action ()
buffersDo_ = void . buffersDo
bufDo :: BufRef -> BufAction a -> Action (Maybe a)
bufDo bufRef bufAct = runBufAction bufAct bufRef
bufDo_ :: BufRef -> BufAction a -> Action ()
bufDo_ bufRef bufAct = void $ bufDo bufRef bufAct
newBuffer :: Y.YiString -> Action BufRef
newBuffer txt = do
n <- nextBufId <<+= 1
buffers %= insert n (mkBuffer txt)
let bufRef = BufRef n
dispatchEvent (BufAdded bufRef)
return bufRef
getBufRefs :: Action [BufRef]
getBufRefs = fmap BufRef <$> use (buffers.to keys)
getBuffer :: BufRef -> Action (Maybe Buffer)
getBuffer (BufRef bufInt) = use (buffers.at bufInt)
getBuffers :: Action [(BufRef, Buffer)]
getBuffers = fmap (first BufRef) <$> use (buffers.to assocs)
nextBufRef :: BufRef -> Action BufRef
nextBufRef br@(BufRef bufInt) = do
bufMap <- use buffers
if M.null bufMap
then return br
else do
let mGreaterInd = lookupGT bufInt bufMap
case mGreaterInd of
Just (greaterInd, _) -> return $ BufRef greaterInd
Nothing -> return . BufRef . fst . findMin $ bufMap
prevBufRef :: BufRef -> Action BufRef
prevBufRef br@(BufRef bufInt) = do
bufMap <- use buffers
if M.null bufMap
then return br
else do
let mLesserInd = lookupLT bufInt bufMap
case mLesserInd of
Just (lesserInd, _) -> return $ BufRef lesserInd
Nothing -> return . BufRef . fst . findMax $ bufMap
exit :: Action ()
exit = exiting .= True
overRange :: CrdRange -> (Y.YiString -> Y.YiString) -> BufAction ()
overRange r f = getRange r >>= setRange r . f
deleteRange :: CrdRange -> BufAction ()
deleteRange r = replaceRange r ""
replaceRange :: CrdRange -> Y.YiString -> BufAction ()
replaceRange r txt = overRange r (const txt)
insertAt :: Coord -> Y.YiString -> BufAction ()
insertAt c = replaceRange r
where r = Range c c