-- | Operations involving Offset and Range through an Engine module Offset where import Text.Regex.Posix import Data.List (find) import Data.Maybe (fromJust) import Control.Monad.State import Editor import Engine -- | move the cursor in the engine jumpE :: Ctx m => Offset -- ^ the new position for the cursor -> Editor m Engine -- ^ the modified engine under the Editor jumpE Current = through Just jumpE LastLine = through Engine.last jumpE (Next n) = through $ nextn n jumpE (Prev n) = through $ prevn n jumpE (Absolute n) = through $ jump n jumpE (ReNext s) = putlastre s >> (through . finder fwdcycle) s jumpE LastReNext = gets lastre >>= through . finder fwdcycle jumpE (RePrev s) = putlastre s >> (through . finder bwdcycle) s jumpE LastRePrev = gets lastre >>= through . finder bwdcycle finder f s = find ((=~ s) . fromJust . line) . f -- | From a range to the tuple (nelements,starting range element) rangeResolve :: Ctx m => Range -- ^ the range to focus -> Editor m (Int, Engine) -- ^ the tuple (nelements,engine placed -- at first offset of range) rangeResolve (Range o1 o2) = do w1 <- jumpE o1 w2 <- jumpE o2 return (distance (pos w1) (pos w2) , w1) -- | a complete backend + Editor action on an Offset doOffset :: Ctx m => Offset -- ^ Offset for the action -> (a -> Editor m b) -- ^ the final action -> (Engine -> Maybe a) -- ^ the backend ation -> Editor m b -- ^ .. doOffset o ef mf = jumpE o >>= backend . mf >>= ef -- | a backend action ending in a save state for the file editOffset :: Ctx m => Offset -- ^ Offset for the backend action -> (Engine -> Maybe Engine) -- ^ the backend ation -> Editor m () -- ^ modified monad editOffset o = doOffset o hputfile -- | a complete backend + Editor action on a Range doRange :: Ctx m => Range -- ^ the addressed range -> (a -> Editor m b) -- ^ the closing Editor action -> (Int -> Engine -> Maybe a) -- ^ the backend action -> Editor m b -- ^ ... doRange r ef mf = rangeResolve r >>= backend . uncurry mf >>= ef editRange :: Ctx m => Range -- ^ the addressed range -> (Int -> Engine -> Maybe Engine) -- ^ the backend action -> Editor m () -- ^ modified monad editRange r = doRange r hputfile