-- This module defines the Region ADT module Yi.Buffer.Region (Region, mkRegion, mkVimRegion, regionStart, regionEnd, swapRegionsB, deleteRegionB, replaceRegionB, readRegionB, mapRegionB, inRegion) where import Yi.Buffer -- | The region data type. --The region is semi open: it includes the start but not the end bound. This allows simpler region-manipulation algorithms. -- Invariant : regionStart r <= regionEnd r data Region = Region {regionStart, regionEnd :: !Point} -- | Construct a region from its bounds, vim style: -- the right bound in included. mkVimRegion :: Point -> Point -> Region mkVimRegion x y = if x < y then Region x (y+1) else Region y (x+1) -- | Construct a region from its bounds, emacs style: -- the right bound is excluded mkRegion :: Point -> Point -> Region mkRegion x y = if x < y then Region x y else Region y x -- | Delete an arbitrary part of the buffer deleteRegionB :: Region -> BufferM () deleteRegionB r = deleteNAt (regionEnd r - regionStart r) (regionStart r) -- | Read an arbitrary part of the buffer readRegionB :: Region -> BufferM String readRegionB r = nelemsB (regionEnd r - i) i where i = regionStart r replaceRegionB :: Region -> String -> BufferM () replaceRegionB r s = savingPointB $ do deleteRegionB r insertNAt s (regionStart r) mapRegionB :: Region -> (Char -> Char) -> BufferM () mapRegionB r f = do text <- readRegionB r replaceRegionB r (map f text) -- | swap the content of two Regions swapRegionsB :: Region -> Region -> BufferM () swapRegionsB r r' | regionStart r > regionStart r' = swapRegionsB r' r | otherwise = do w0 <- readRegionB r w1 <- readRegionB r' replaceRegionB r' w0 replaceRegionB r w1 -- | True if the given point is inside the given region. inRegion :: Point -> Region -> Bool p `inRegion` (Region start stop) = start <= p && p < stop