packages feed

yi-0.6.0: Yi/Buffer/Basic.hs

{-# LANGUAGE StandaloneDeriving, DeriveDataTypeable, ScopedTypeVariables, ExistentialQuantification, GeneralizedNewtypeDeriving, MultiParamTypeClasses, TemplateHaskell #-}
-- Copyright 2008 JP Bernardy
-- | Basic types useful everywhere we play with buffers.
module Yi.Buffer.Basic where
import Prelude (reverse)
import Data.Binary    
import Yi.Prelude
import qualified Data.ByteString.UTF8 as UTF8
import qualified Data.ByteString.Lazy.UTF8 as LazyUTF8
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as LB
import Data.Char (ord)
import Data.Typeable
import Data.DeriveTH
import Data.Derive.Binary

-- | Direction of movement inside a buffer
data Direction = Backward
               | Forward
                 deriving (Eq,Ord,Typeable,Show)

$(derive makeBinary ''Direction)

reverseDir :: Direction -> Direction
reverseDir Forward = Backward
reverseDir Backward = Forward


-- | reverse if Backward
mayReverse :: Direction -> [a] -> [a]
mayReverse Forward = id
mayReverse Backward = reverse

-- | 'direction' is in the same style of 'maybe' or 'either' functions,
-- It takes one argument per direction (backward, then forward) and a
-- direction to select the output.
directionElim :: Direction -> a -> a -> a
directionElim Backward b _ = b
directionElim Forward  _ f = f

-- | A mark in a buffer
newtype Mark = Mark {markId::Int} deriving (Eq, Ord, Show, Typeable, Binary)

-- | Reference to a buffer.
newtype BufferRef = BufferRef Int
    deriving (Eq, Ord, Typeable, Binary)
deriving instance Num BufferRef

instance Show BufferRef where
    show (BufferRef r) = "B#" ++ show r

-- | A point in a buffer
newtype Point = Point {fromPoint :: Int}           -- offset in the buffer (#bytes, NOT codepoints)
    deriving (Eq, Ord, Enum, Bounded, Typeable, Binary)

deriving instance Num Point
deriving instance Real Point
deriving instance Integral Point
instance Show Point where
    show (Point p) = show p

-- | Size of a buffer region
newtype Size = Size {fromSize :: Int}             -- size in bytes (#bytes, NOT codepoints)
    deriving (Show, Eq, Ord, Num, Enum, Real, Integral, Binary)

instance SemiNum Point Size where
    Point p +~ Size s = Point (p + s)
    Point p -~ Size s = Point (p - s)
    Point p ~- Point q = Size (abs (p - q))

utf8Size :: String -> Size
utf8Size = Size . B.length . UTF8.fromString

utf8CharSize :: Char -> Size
utf8CharSize c = case ord c of i | i < 0x80    -> 1
                                 | i < 0x800   -> 2
                                 | i < 0x10000 -> 3
                                 | otherwise   -> 4

-- fromUTF8ByteString :: B.ByteString -> String
-- fromUTF8ByteString = UTF8.toString

fromString :: String -> LB.ByteString
fromString = LazyUTF8.fromString