module Offset where
import Text.Regex.Posix
import Data.List (find)
import Data.Maybe (fromJust)
import Control.Monad.State
import Editor
import Engine
jumpE :: Ctx m
=> Offset
-> Editor m Engine
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
rangeResolve :: Ctx m
=> Range
-> Editor m (Int, Engine)
rangeResolve (Range o1 o2) = do
w1 <- jumpE o1
w2 <- jumpE o2
return (distance (pos w1) (pos w2) , w1)
doOffset :: Ctx m
=> Offset
-> (a -> Editor m b)
-> (Engine -> Maybe a)
-> Editor m b
doOffset o ef mf = jumpE o >>= backend . mf >>= ef
editOffset :: Ctx m
=> Offset
-> (Engine -> Maybe Engine)
-> Editor m ()
editOffset o = doOffset o hputfile
doRange :: Ctx m
=> Range
-> (a -> Editor m b)
-> (Int -> Engine -> Maybe a)
-> Editor m b
doRange r ef mf = rangeResolve r >>= backend . uncurry mf >>= ef
editRange :: Ctx m
=> Range
-> (Int -> Engine -> Maybe Engine)
-> Editor m ()
editRange r = doRange r hputfile