module Rasa.Internal.Buffer
( Buffer
, HasBuffer(..)
, text
, bufExt
, Ext(..)
, mkBuffer
) where
import Rasa.Internal.Extensions
import qualified Yi.Rope as Y
import Control.Lens hiding (matching)
import Data.Map
import Data.Typeable
import Data.Default
import Data.Maybe
import Unsafe.Coerce
data Buffer = Buffer
{ _text' :: Y.YiString
, _bufExts' :: ExtMap
}
makeLenses ''Buffer
instance Show Buffer where
show b = "<Buffer {text:" ++ show (b^..text . to (Y.take 30)) ++ "...,\n"
++ "exts: " ++ show (b^.bufExts) ++ "}>\n"
class HasBuffer a where
buffer :: Lens' a Buffer
instance HasBuffer Buffer where
buffer = lens id (flip const)
text :: HasBuffer b => Lens' b Y.YiString
text = buffer.text'
bufExts :: HasBuffer b => Lens' b ExtMap
bufExts = buffer.bufExts'
bufExt
:: forall a s.
(Show a, Typeable a, Default a, HasBuffer s)
=> Lens' s a
bufExt = lens getter setter
where
getter buf =
fromMaybe def $ buf ^. bufExts . at (typeRep (Proxy :: Proxy a)) .
mapping coerce
setter buf new =
set
(bufExts . at (typeRep (Proxy :: Proxy a)) . mapping coerce)
(Just new)
buf
coerce = iso (\(Ext x) -> unsafeCoerce x) Ext
mkBuffer :: Y.YiString -> Buffer
mkBuffer txt =
Buffer
{ _text' = txt
, _bufExts' = empty
}