{-# LANGUAGE CPP #-} -- | A normalized API to many buffer operations. -- The idea is that most operations should be parametric in both -- * the textual units they work on -- * the direction towards which they operate (if applicable) module Yi.Buffer.Normal ( TextUnit(Character, Line, VLine, Document, GenUnit) , isAnySep , isWordChar , leftBoundaryUnit , outsideUnit , unitDelimited , unitEmacsParagraph , unitParagraph , unitSentence , unitSep , unitSepThisLine , unitViWORD , unitViWORDAnyBnd , unitViWORDOnLine , unitViWord , unitViWordAnyBnd , unitViWordOnLine , unitWord -- TextUnit is exported abstract intentionally: -- we'd like to move more units to the GenUnit format. , atBoundaryB , deleteB , doIfCharB , doUntilB_ , genMaybeMoveB , genMoveB , maybeMoveB , moveB , numberOfB , readPrevUnitB , readUnitB , regionOfB , regionOfNonEmptyB , regionOfPartB , regionOfPartNonEmptyAtB , regionOfPartNonEmptyB , transformB , transposeB , untilB , untilB_ , whileB , BoundarySide(..) , checkPeekB , genAtBoundaryB , genEnclosingUnit , genUnitBoundary , RegionStyle(..) , convertRegionToStyleB , extendRegionToBoundaries , getRegionStyle , mkRegionOfStyleB , putRegionStyle , unitWiseRegion ) where import Data.List (sort) import Yi.Buffer.Basic (Direction (Backward, Forward), Point) import Yi.Buffer.Misc (BufferM, getBufferDyn, moveTo, pointB, putBufferDyn, savingPointB) import Yi.Buffer.Region (Region (..), inclusiveRegionB, mkRegion, mkRegion') import Yi.Buffer.TextUnit import Yi.Types (RegionStyle (..)) getRegionStyle :: BufferM RegionStyle getRegionStyle = getBufferDyn putRegionStyle :: RegionStyle -> BufferM () putRegionStyle = putBufferDyn convertRegionToStyleB :: Region -> RegionStyle -> BufferM Region convertRegionToStyleB r = mkRegionOfStyleB (regionStart r) (regionEnd r) mkRegionOfStyleB :: Point -> Point -> RegionStyle -> BufferM Region mkRegionOfStyleB start' stop' regionStyle = let [start, stop] = sort [start', stop'] region = mkRegion start stop in case regionStyle of LineWise -> inclusiveRegionB =<< unitWiseRegion Line region Inclusive -> inclusiveRegionB region Exclusive -> return region Block -> return region unitWiseRegion :: TextUnit -> Region -> BufferM Region unitWiseRegion unit = extendRegionToBoundaries unit InsideBound OutsideBound -- | Extend the given region to boundaries of the text unit. -- For instance one can extend the selection to complete lines, or -- paragraphs. extendRegionToBoundaries :: TextUnit -> BoundarySide -> BoundarySide -> Region -> BufferM Region extendRegionToBoundaries unit bs1 bs2 region = savingPointB $ do moveTo $ regionStart region genMaybeMoveB unit (Backward, bs1) Backward start <- pointB moveTo $ regionEnd region genMaybeMoveB unit (Forward, bs2) Forward stop <- pointB return $ mkRegion' (regionDirection region) start stop