{-# language CPP #-}
{-# language BangPatterns #-}
{-# language DeriveDataTypeable #-}
{-# language LambdaCase #-}
{-# language MultiParamTypeClasses #-}
{-# language OverloadedStrings #-}
{-# language ScopedTypeVariables #-}
{-# language ViewPatterns #-}
{-# options_haddock show-extensions #-}
module Yi.Rope (
Yi.Rope.YiString,
Yi.Rope.fromString, Yi.Rope.fromText,
Yi.Rope.fromString', Yi.Rope.fromText',
Yi.Rope.toString, Yi.Rope.toReverseString,
Yi.Rope.toText, Yi.Rope.toReverseText,
Yi.Rope.null, Yi.Rope.empty, Yi.Rope.take, Yi.Rope.drop,
Yi.Rope.length, Yi.Rope.reverse, Yi.Rope.countNewLines,
Yi.Rope.lines, Yi.Rope.lines', Yi.Rope.unlines,
Yi.Rope.splitAt, Yi.Rope.splitAtLine,
Yi.Rope.cons, Yi.Rope.snoc, Yi.Rope.singleton,
Yi.Rope.head, Yi.Rope.last,
Yi.Rope.append, Yi.Rope.concat,
Yi.Rope.any, Yi.Rope.all,
Yi.Rope.dropWhile, Yi.Rope.takeWhile,
Yi.Rope.dropWhileEnd, Yi.Rope.takeWhileEnd,
Yi.Rope.intercalate, Yi.Rope.intersperse,
Yi.Rope.filter, Yi.Rope.map,
Yi.Rope.words, Yi.Rope.unwords,
Yi.Rope.split, Yi.Rope.init, Yi.Rope.tail,
Yi.Rope.span, Yi.Rope.break, Yi.Rope.foldl',
Yi.Rope.replicate, Yi.Rope.replicateChar,
Yi.Rope.readFile, Yi.Rope.writeFile,
Yi.Rope.fromRope, Yi.Rope.withText, Yi.Rope.unsafeWithText
) where
import Control.DeepSeq
import Control.Exception (try)
import Data.Binary
import qualified Data.ByteString.Lazy as BSL
import Data.Char (isSpace)
import qualified Data.FingerTree as T
import Data.FingerTree hiding (null, empty, reverse, split)
import qualified Data.List as L (foldl')
import Data.Maybe
import Data.Monoid
import Data.String (IsString(..))
import qualified Data.Text as TX
import qualified Data.Text.Encoding.Error as TXEE
import qualified Data.Text.Lazy as TXL
import qualified Data.Text.Lazy.Encoding as TXLE
import qualified Data.Text.IO as TXIO (writeFile)
import Data.Typeable
import Prelude hiding (drop)
data Size = Indices { Size -> Int
charIndex :: {-# UNPACK #-} !Int
, Size -> Int
lineIndex :: Int
} deriving (Size -> Size -> Bool
(Size -> Size -> Bool) -> (Size -> Size -> Bool) -> Eq Size
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Size -> Size -> Bool
$c/= :: Size -> Size -> Bool
== :: Size -> Size -> Bool
$c== :: Size -> Size -> Bool
Eq, Int -> Size -> ShowS
[Size] -> ShowS
Size -> String
(Int -> Size -> ShowS)
-> (Size -> String) -> ([Size] -> ShowS) -> Show Size
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Size] -> ShowS
$cshowList :: [Size] -> ShowS
show :: Size -> String
$cshow :: Size -> String
showsPrec :: Int -> Size -> ShowS
$cshowsPrec :: Int -> Size -> ShowS
Show, Typeable)
data YiChunk = Chunk { YiChunk -> Int
chunkSize :: {-# UNPACK #-} !Int
, YiChunk -> Text
_fromChunk :: {-# UNPACK #-} !TX.Text
} deriving (Int -> YiChunk -> ShowS
[YiChunk] -> ShowS
YiChunk -> String
(Int -> YiChunk -> ShowS)
-> (YiChunk -> String) -> ([YiChunk] -> ShowS) -> Show YiChunk
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [YiChunk] -> ShowS
$cshowList :: [YiChunk] -> ShowS
show :: YiChunk -> String
$cshow :: YiChunk -> String
showsPrec :: Int -> YiChunk -> ShowS
$cshowsPrec :: Int -> YiChunk -> ShowS
Show, YiChunk -> YiChunk -> Bool
(YiChunk -> YiChunk -> Bool)
-> (YiChunk -> YiChunk -> Bool) -> Eq YiChunk
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: YiChunk -> YiChunk -> Bool
$c/= :: YiChunk -> YiChunk -> Bool
== :: YiChunk -> YiChunk -> Bool
$c== :: YiChunk -> YiChunk -> Bool
Eq, Typeable)
mkChunk :: (TX.Text -> Int)
-> TX.Text
-> YiChunk
mkChunk :: (Text -> Int) -> Text -> YiChunk
mkChunk l :: Text -> Int
l t :: Text
t = Int -> Text -> YiChunk
Chunk (Text -> Int
l Text
t) Text
t
overChunk :: (TX.Text -> TX.Text)
-> YiChunk -> YiChunk
overChunk :: (Text -> Text) -> YiChunk -> YiChunk
overChunk f :: Text -> Text
f (Chunk l :: Int
l t :: Text
t) = Int -> Text -> YiChunk
Chunk Int
l (Text -> Text
f Text
t)
countNl :: TX.Text -> Int
countNl :: Text -> Int
countNl = Text -> Text -> Int
TX.count "\n"
#if __GLASGOW_HASKELL__ >= 804
instance Semigroup Size where
<> :: Size -> Size -> Size
(<>) = Size -> Size -> Size
forall a. Monoid a => a -> a -> a
mappend
#endif
instance Monoid Size where
mempty :: Size
mempty = Int -> Int -> Size
Indices 0 0
Indices c :: Int
c l :: Int
l mappend :: Size -> Size -> Size
`mappend` Indices c' :: Int
c' l' :: Int
l' = Int -> Int -> Size
Indices (Int
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
c') (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l')
instance Measured Size YiChunk where
measure :: YiChunk -> Size
measure (Chunk l :: Int
l t :: Text
t) = Int -> Int -> Size
Indices Int
l (Text -> Int
countNl Text
t)
newtype YiString = YiString { YiString -> FingerTree Size YiChunk
fromRope :: FingerTree Size YiChunk }
deriving (Int -> YiString -> ShowS
[YiString] -> ShowS
YiString -> String
(Int -> YiString -> ShowS)
-> (YiString -> String) -> ([YiString] -> ShowS) -> Show YiString
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [YiString] -> ShowS
$cshowList :: [YiString] -> ShowS
show :: YiString -> String
$cshow :: YiString -> String
showsPrec :: Int -> YiString -> ShowS
$cshowsPrec :: Int -> YiString -> ShowS
Show, Typeable)
instance Eq YiString where
t :: YiString
t == :: YiString -> YiString -> Bool
== t' :: YiString
t' = YiString -> Int
Yi.Rope.length YiString
t Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== YiString -> Int
Yi.Rope.length YiString
t' Bool -> Bool -> Bool
&& YiString -> Text
toText YiString
t Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== YiString -> Text
toText YiString
t'
instance NFData Size where
rnf :: Size -> ()
rnf (Indices !Int
c !Int
l) = Int
c Int -> () -> ()
forall a b. a -> b -> b
`seq` Int
l Int -> () -> ()
forall a b. a -> b -> b
`seq` ()
instance NFData YiChunk where
rnf :: YiChunk -> ()
rnf (Chunk !Int
i !Text
t) = Int
i Int -> () -> ()
forall a b. a -> b -> b
`seq` Text -> ()
forall a. NFData a => a -> ()
rnf Text
t
instance NFData YiString where
rnf :: YiString -> ()
rnf = Text -> ()
forall a. NFData a => a -> ()
rnf (Text -> ()) -> (YiString -> Text) -> YiString -> ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> Text
toText
instance IsString YiString where
fromString :: String -> YiString
fromString = String -> YiString
Yi.Rope.fromString
#if __GLASGOW_HASKELL__ >= 804
instance Semigroup YiString where
<> :: YiString -> YiString -> YiString
(<>) = YiString -> YiString -> YiString
forall a. Monoid a => a -> a -> a
mappend
#endif
instance Monoid YiString where
mempty :: YiString
mempty = YiString
Yi.Rope.empty
mappend :: YiString -> YiString -> YiString
mappend = YiString -> YiString -> YiString
Yi.Rope.append
mconcat :: [YiString] -> YiString
mconcat = [YiString] -> YiString
Yi.Rope.concat
instance Ord YiString where
compare :: YiString -> YiString -> Ordering
compare x :: YiString
x y :: YiString
y = YiString -> Text
toText YiString
x Text -> Text -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` YiString -> Text
toText YiString
y
(-|) :: YiChunk -> FingerTree Size YiChunk -> FingerTree Size YiChunk
b :: YiChunk
b -| :: YiChunk -> FingerTree Size YiChunk -> FingerTree Size YiChunk
-| t :: FingerTree Size YiChunk
t | YiChunk -> Int
chunkSize YiChunk
b Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0 = FingerTree Size YiChunk
t
| Bool
otherwise = YiChunk
b YiChunk -> FingerTree Size YiChunk -> FingerTree Size YiChunk
forall v a. Measured v a => a -> FingerTree v a -> FingerTree v a
<| FingerTree Size YiChunk
t
(|-) :: FingerTree Size YiChunk -> YiChunk -> FingerTree Size YiChunk
t :: FingerTree Size YiChunk
t |- :: FingerTree Size YiChunk -> YiChunk -> FingerTree Size YiChunk
|- b :: YiChunk
b | YiChunk -> Int
chunkSize YiChunk
b Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0 = FingerTree Size YiChunk
t
| Bool
otherwise = FingerTree Size YiChunk
t FingerTree Size YiChunk -> YiChunk -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a -> a -> FingerTree v a
|> YiChunk
b
defaultChunkSize :: Int
defaultChunkSize :: Int
defaultChunkSize = 1200
reverse :: YiString -> YiString
reverse :: YiString -> YiString
reverse = FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> (YiString -> FingerTree Size YiChunk) -> YiString -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (YiChunk -> YiChunk)
-> FingerTree Size YiChunk -> FingerTree Size YiChunk
forall v1 a1 v2 a2.
(Measured v1 a1, Measured v2 a2) =>
(a1 -> a2) -> FingerTree v1 a1 -> FingerTree v2 a2
fmap' ((Text -> Text) -> YiChunk -> YiChunk
overChunk Text -> Text
TX.reverse) (FingerTree Size YiChunk -> FingerTree Size YiChunk)
-> (YiString -> FingerTree Size YiChunk)
-> YiString
-> FingerTree Size YiChunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FingerTree Size YiChunk -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a -> FingerTree v a
T.reverse (FingerTree Size YiChunk -> FingerTree Size YiChunk)
-> (YiString -> FingerTree Size YiChunk)
-> YiString
-> FingerTree Size YiChunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> FingerTree Size YiChunk
fromRope
fromString :: String -> YiString
fromString :: String -> YiString
fromString = Text -> YiString
fromText (Text -> YiString) -> (String -> Text) -> String -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
TX.pack
fromString' :: Int -> String -> YiString
fromString' :: Int -> String -> YiString
fromString' n :: Int
n = Int -> Text -> YiString
fromText' Int
n (Text -> YiString) -> (String -> Text) -> String -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
TX.pack
toString :: YiString -> String
toString :: YiString -> String
toString = Text -> String
TX.unpack (Text -> String) -> (YiString -> Text) -> YiString -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> Text
toText
toReverseString :: YiString -> String
toReverseString :: YiString -> String
toReverseString = Text -> String
TX.unpack (Text -> String) -> (YiString -> Text) -> YiString -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> Text
toReverseText
fromText' :: Int -> TX.Text -> YiString
fromText' :: Int -> Text -> YiString
fromText' n :: Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 0 = Int -> Text -> YiString
fromText' Int
defaultChunkSize
| Bool
otherwise = FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> (Text -> FingerTree Size YiChunk) -> Text -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FingerTree Size YiChunk -> [Text] -> FingerTree Size YiChunk
r FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a
T.empty ([Text] -> FingerTree Size YiChunk)
-> (Text -> [Text]) -> Text -> FingerTree Size YiChunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text]
f
where
f :: Text -> [Text]
f = Int -> Text -> [Text]
TX.chunksOf Int
n
r :: FingerTree Size YiChunk -> [TX.Text] -> FingerTree Size YiChunk
r :: FingerTree Size YiChunk -> [Text] -> FingerTree Size YiChunk
r !FingerTree Size YiChunk
tr [] = FingerTree Size YiChunk
tr
r !FingerTree Size YiChunk
tr (t :: Text
t:[]) = FingerTree Size YiChunk
tr FingerTree Size YiChunk -> YiChunk -> FingerTree Size YiChunk
|- (Text -> Int) -> Text -> YiChunk
mkChunk Text -> Int
TX.length Text
t
r !FingerTree Size YiChunk
tr (t :: Text
t:ts :: [Text]
ts) = let r' :: FingerTree Size YiChunk
r' = FingerTree Size YiChunk
tr FingerTree Size YiChunk -> YiChunk -> FingerTree Size YiChunk
|- (Text -> Int) -> Text -> YiChunk
mkChunk (Int -> Text -> Int
forall a b. a -> b -> a
const Int
n) Text
t
in FingerTree Size YiChunk -> [Text] -> FingerTree Size YiChunk
r FingerTree Size YiChunk
r' [Text]
ts
fromText :: TX.Text -> YiString
fromText :: Text -> YiString
fromText = Int -> Text -> YiString
fromText' Int
defaultChunkSize
fromLazyText :: TXL.Text -> YiString
fromLazyText :: Text -> YiString
fromLazyText = FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> (Text -> FingerTree Size YiChunk) -> Text -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [YiChunk] -> FingerTree Size YiChunk
forall v a. Measured v a => [a] -> FingerTree v a
T.fromList ([YiChunk] -> FingerTree Size YiChunk)
-> (Text -> [YiChunk]) -> Text -> FingerTree Size YiChunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> YiChunk) -> [Text] -> [YiChunk]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Text -> Int) -> Text -> YiChunk
mkChunk Text -> Int
TX.length) ([Text] -> [YiChunk]) -> (Text -> [Text]) -> Text -> [YiChunk]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text]
TXL.toChunks
toText :: YiString -> TX.Text
toText :: YiString -> Text
toText = [Text] -> Text
TX.concat ([Text] -> Text) -> (YiString -> [Text]) -> YiString -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FingerTree Size YiChunk -> [Text]
go (FingerTree Size YiChunk -> [Text])
-> (YiString -> FingerTree Size YiChunk) -> YiString -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> FingerTree Size YiChunk
fromRope
where
go :: FingerTree Size YiChunk -> [TX.Text]
go :: FingerTree Size YiChunk -> [Text]
go t :: FingerTree Size YiChunk
t = case FingerTree Size YiChunk -> ViewL (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewL (FingerTree v) a
viewl FingerTree Size YiChunk
t of
Chunk _ !Text
c :< cs :: FingerTree Size YiChunk
cs -> Text
c Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: FingerTree Size YiChunk -> [Text]
go FingerTree Size YiChunk
cs
EmptyL -> []
toReverseText :: YiString -> TX.Text
toReverseText :: YiString -> Text
toReverseText = Text -> Text
TX.reverse (Text -> Text) -> (YiString -> Text) -> YiString -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> Text
toText
null :: YiString -> Bool
null :: YiString -> Bool
null = FingerTree Size YiChunk -> Bool
forall v a. FingerTree v a -> Bool
T.null (FingerTree Size YiChunk -> Bool)
-> (YiString -> FingerTree Size YiChunk) -> YiString -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> FingerTree Size YiChunk
fromRope
empty :: YiString
empty :: YiString
empty = FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a
T.empty
length :: YiString -> Int
length :: YiString -> Int
length = Size -> Int
charIndex (Size -> Int) -> (YiString -> Size) -> YiString -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FingerTree Size YiChunk -> Size
forall v a. Measured v a => a -> v
measure (FingerTree Size YiChunk -> Size)
-> (YiString -> FingerTree Size YiChunk) -> YiString -> Size
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> FingerTree Size YiChunk
fromRope
countNewLines :: YiString -> Int
countNewLines :: YiString -> Int
countNewLines = Size -> Int
lineIndex (Size -> Int) -> (YiString -> Size) -> YiString -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FingerTree Size YiChunk -> Size
forall v a. Measured v a => a -> v
measure (FingerTree Size YiChunk -> Size)
-> (YiString -> FingerTree Size YiChunk) -> YiString -> Size
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> FingerTree Size YiChunk
fromRope
append :: YiString -> YiString -> YiString
append :: YiString -> YiString -> YiString
append (YiString t :: FingerTree Size YiChunk
t) (YiString t' :: FingerTree Size YiChunk
t') = case (FingerTree Size YiChunk -> ViewR (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewR (FingerTree v) a
viewr FingerTree Size YiChunk
t, FingerTree Size YiChunk -> ViewL (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewL (FingerTree v) a
viewl FingerTree Size YiChunk
t') of
(EmptyR, _) -> FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
t'
(_, EmptyL) -> FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
t
(ts :: FingerTree Size YiChunk
ts :> Chunk l :: Int
l x :: Text
x, Chunk l' :: Int
l' x' :: Text
x' :< ts' :: FingerTree Size YiChunk
ts') ->
let len :: Int
len = Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l' in case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
len Int
defaultChunkSize of
GT -> FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk
t FingerTree Size YiChunk
-> FingerTree Size YiChunk -> FingerTree Size YiChunk
forall a. Semigroup a => a -> a -> a
<> FingerTree Size YiChunk
t')
_ -> FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk
ts FingerTree Size YiChunk -> YiChunk -> FingerTree Size YiChunk
|- Int -> Text -> YiChunk
Chunk Int
len (Text
x Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
x') FingerTree Size YiChunk
-> FingerTree Size YiChunk -> FingerTree Size YiChunk
forall a. Semigroup a => a -> a -> a
<> FingerTree Size YiChunk
ts')
concat :: [YiString] -> YiString
concat :: [YiString] -> YiString
concat = (YiString -> YiString -> YiString)
-> YiString -> [YiString] -> YiString
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl' YiString -> YiString -> YiString
append YiString
empty
head :: YiString -> Maybe Char
head :: YiString -> Maybe Char
head (YiString t :: FingerTree Size YiChunk
t) = case FingerTree Size YiChunk -> ViewL (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewL (FingerTree v) a
viewl FingerTree Size YiChunk
t of
EmptyL -> Maybe Char
forall a. Maybe a
Nothing
Chunk _ x :: Text
x :< _ -> if Text -> Bool
TX.null Text
x then Maybe Char
forall a. Maybe a
Nothing else Char -> Maybe Char
forall a. a -> Maybe a
Just (Text -> Char
TX.head Text
x)
last :: YiString -> Maybe Char
last :: YiString -> Maybe Char
last (YiString t :: FingerTree Size YiChunk
t) = case FingerTree Size YiChunk -> ViewR (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewR (FingerTree v) a
viewr FingerTree Size YiChunk
t of
EmptyR -> Maybe Char
forall a. Maybe a
Nothing
_ :> Chunk _ x :: Text
x -> if Text -> Bool
TX.null Text
x then Maybe Char
forall a. Maybe a
Nothing else Char -> Maybe Char
forall a. a -> Maybe a
Just (Text -> Char
TX.last Text
x)
init :: YiString -> Maybe YiString
init :: YiString -> Maybe YiString
init (YiString t :: FingerTree Size YiChunk
t) = case FingerTree Size YiChunk -> ViewR (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewR (FingerTree v) a
viewr FingerTree Size YiChunk
t of
EmptyR -> Maybe YiString
forall a. Maybe a
Nothing
ts :: FingerTree Size YiChunk
ts :> Chunk 0 _ -> YiString -> Maybe YiString
Yi.Rope.init (FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
ts)
ts :: FingerTree Size YiChunk
ts :> Chunk l :: Int
l x :: Text
x -> YiString -> Maybe YiString
forall a. a -> Maybe a
Just (YiString -> Maybe YiString)
-> (FingerTree Size YiChunk -> YiString)
-> FingerTree Size YiChunk
-> Maybe YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> Maybe YiString)
-> FingerTree Size YiChunk -> Maybe YiString
forall a b. (a -> b) -> a -> b
$ FingerTree Size YiChunk
ts FingerTree Size YiChunk -> YiChunk -> FingerTree Size YiChunk
|- Int -> Text -> YiChunk
Chunk (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) (Text -> Text
TX.init Text
x)
tail :: YiString -> Maybe YiString
tail :: YiString -> Maybe YiString
tail (YiString t :: FingerTree Size YiChunk
t) = case FingerTree Size YiChunk -> ViewL (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewL (FingerTree v) a
viewl FingerTree Size YiChunk
t of
EmptyL -> Maybe YiString
forall a. Maybe a
Nothing
Chunk 0 _ :< ts :: FingerTree Size YiChunk
ts -> YiString -> Maybe YiString
Yi.Rope.tail (FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
ts)
Chunk l :: Int
l x :: Text
x :< ts :: FingerTree Size YiChunk
ts -> YiString -> Maybe YiString
forall a. a -> Maybe a
Just (YiString -> Maybe YiString)
-> (FingerTree Size YiChunk -> YiString)
-> FingerTree Size YiChunk
-> Maybe YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> Maybe YiString)
-> FingerTree Size YiChunk -> Maybe YiString
forall a b. (a -> b) -> a -> b
$ Int -> Text -> YiChunk
Chunk (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) (Text -> Text
TX.tail Text
x) YiChunk -> FingerTree Size YiChunk -> FingerTree Size YiChunk
-| FingerTree Size YiChunk
ts
splitAt :: Int -> YiString -> (YiString, YiString)
splitAt :: Int -> YiString -> (YiString, YiString)
splitAt n :: Int
n (YiString t :: FingerTree Size YiChunk
t)
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 0 = (YiString
forall a. Monoid a => a
mempty, FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
t)
| Bool
otherwise = case FingerTree Size YiChunk -> ViewL (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewL (FingerTree v) a
viewl FingerTree Size YiChunk
s of
Chunk l :: Int
l x :: Text
x :< ts :: FingerTree Size YiChunk
ts | Int
n' Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= 0 ->
let (lx :: Text
lx, rx :: Text
rx) = Int -> Text -> (Text, Text)
TX.splitAt Int
n' Text
x
in (FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> FingerTree Size YiChunk -> YiString
forall a b. (a -> b) -> a -> b
$ FingerTree Size YiChunk
f FingerTree Size YiChunk -> YiChunk -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a -> a -> FingerTree v a
|> Int -> Text -> YiChunk
Chunk Int
n' Text
lx,
FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> FingerTree Size YiChunk -> YiString
forall a b. (a -> b) -> a -> b
$ Int -> Text -> YiChunk
Chunk (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n') Text
rx YiChunk -> FingerTree Size YiChunk -> FingerTree Size YiChunk
-| FingerTree Size YiChunk
ts)
_ -> (FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
f, FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
s)
where
(f :: FingerTree Size YiChunk
f, s :: FingerTree Size YiChunk
s) = (Size -> Bool)
-> FingerTree Size YiChunk
-> (FingerTree Size YiChunk, FingerTree Size YiChunk)
forall v a.
Measured v a =>
(v -> Bool) -> FingerTree v a -> (FingerTree v a, FingerTree v a)
T.split ((Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
n) (Int -> Bool) -> (Size -> Int) -> Size -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Size -> Int
charIndex) FingerTree Size YiChunk
t
n' :: Int
n' = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Size -> Int
charIndex (FingerTree Size YiChunk -> Size
forall v a. Measured v a => a -> v
measure FingerTree Size YiChunk
f)
take :: Int -> YiString -> YiString
take :: Int -> YiString -> YiString
take 1 = YiString -> (Char -> YiString) -> Maybe Char -> YiString
forall b a. b -> (a -> b) -> Maybe a -> b
maybe YiString
forall a. Monoid a => a
mempty Char -> YiString
Yi.Rope.singleton (Maybe Char -> YiString)
-> (YiString -> Maybe Char) -> YiString -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> Maybe Char
Yi.Rope.head
take n :: Int
n = (YiString, YiString) -> YiString
forall a b. (a, b) -> a
fst ((YiString, YiString) -> YiString)
-> (YiString -> (YiString, YiString)) -> YiString -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> YiString -> (YiString, YiString)
Yi.Rope.splitAt Int
n
drop :: Int -> YiString -> YiString
drop :: Int -> YiString -> YiString
drop 1 = YiString -> Maybe YiString -> YiString
forall a. a -> Maybe a -> a
fromMaybe YiString
forall a. Monoid a => a
mempty (Maybe YiString -> YiString)
-> (YiString -> Maybe YiString) -> YiString -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> Maybe YiString
Yi.Rope.tail
drop n :: Int
n = (YiString, YiString) -> YiString
forall a b. (a, b) -> b
snd ((YiString, YiString) -> YiString)
-> (YiString -> (YiString, YiString)) -> YiString -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> YiString -> (YiString, YiString)
Yi.Rope.splitAt Int
n
dropWhile :: (Char -> Bool) -> YiString -> YiString
dropWhile :: (Char -> Bool) -> YiString -> YiString
dropWhile p :: Char -> Bool
p = FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> (YiString -> FingerTree Size YiChunk) -> YiString -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FingerTree Size YiChunk -> FingerTree Size YiChunk
go (FingerTree Size YiChunk -> FingerTree Size YiChunk)
-> (YiString -> FingerTree Size YiChunk)
-> YiString
-> FingerTree Size YiChunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> FingerTree Size YiChunk
fromRope
where
go :: FingerTree Size YiChunk -> FingerTree Size YiChunk
go t :: FingerTree Size YiChunk
t = case FingerTree Size YiChunk -> ViewL (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewL (FingerTree v) a
viewl FingerTree Size YiChunk
t of
EmptyL -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a
T.empty
Chunk 0 _ :< ts :: FingerTree Size YiChunk
ts -> FingerTree Size YiChunk -> FingerTree Size YiChunk
go FingerTree Size YiChunk
ts
Chunk l :: Int
l x :: Text
x :< ts :: FingerTree Size YiChunk
ts ->
let r :: Text
r = (Char -> Bool) -> Text -> Text
TX.dropWhile Char -> Bool
p Text
x
l' :: Int
l' = Text -> Int
TX.length Text
r
in case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
l' Int
l of
EQ -> FingerTree Size YiChunk
t
LT | Text -> Bool
TX.null Text
r -> FingerTree Size YiChunk -> FingerTree Size YiChunk
go FingerTree Size YiChunk
ts
| Bool
otherwise -> Int -> Text -> YiChunk
Chunk Int
l' Text
r YiChunk -> FingerTree Size YiChunk -> FingerTree Size YiChunk
forall v a. Measured v a => a -> FingerTree v a -> FingerTree v a
<| FingerTree Size YiChunk
ts
_ -> Int -> Text -> YiChunk
Chunk Int
l' Text
r YiChunk -> FingerTree Size YiChunk -> FingerTree Size YiChunk
-| FingerTree Size YiChunk
ts
dropWhileEnd :: (Char -> Bool) -> YiString -> YiString
dropWhileEnd :: (Char -> Bool) -> YiString -> YiString
dropWhileEnd p :: Char -> Bool
p = FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> (YiString -> FingerTree Size YiChunk) -> YiString -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FingerTree Size YiChunk -> FingerTree Size YiChunk
go (FingerTree Size YiChunk -> FingerTree Size YiChunk)
-> (YiString -> FingerTree Size YiChunk)
-> YiString
-> FingerTree Size YiChunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> FingerTree Size YiChunk
fromRope
where
go :: FingerTree Size YiChunk -> FingerTree Size YiChunk
go t :: FingerTree Size YiChunk
t = case FingerTree Size YiChunk -> ViewR (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewR (FingerTree v) a
viewr FingerTree Size YiChunk
t of
EmptyR -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a
T.empty
ts :: FingerTree Size YiChunk
ts :> Chunk 0 _ -> FingerTree Size YiChunk -> FingerTree Size YiChunk
go FingerTree Size YiChunk
ts
ts :: FingerTree Size YiChunk
ts :> Chunk l :: Int
l x :: Text
x ->
let r :: Text
r = (Char -> Bool) -> Text -> Text
TX.dropWhileEnd Char -> Bool
p Text
x
l' :: Int
l' = Text -> Int
TX.length Text
r
in case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
l' Int
l of
EQ -> FingerTree Size YiChunk
t
LT | Text -> Bool
TX.null Text
r -> FingerTree Size YiChunk -> FingerTree Size YiChunk
go FingerTree Size YiChunk
ts
| Bool
otherwise -> FingerTree Size YiChunk
ts FingerTree Size YiChunk -> YiChunk -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a -> a -> FingerTree v a
|> Int -> Text -> YiChunk
Chunk Int
l' Text
r
_ -> FingerTree Size YiChunk
ts FingerTree Size YiChunk -> YiChunk -> FingerTree Size YiChunk
|- Int -> Text -> YiChunk
Chunk Int
l' Text
r
takeWhile :: (Char -> Bool) -> YiString -> YiString
takeWhile :: (Char -> Bool) -> YiString -> YiString
takeWhile p :: Char -> Bool
p = FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> (YiString -> FingerTree Size YiChunk) -> YiString -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FingerTree Size YiChunk -> FingerTree Size YiChunk
go (FingerTree Size YiChunk -> FingerTree Size YiChunk)
-> (YiString -> FingerTree Size YiChunk)
-> YiString
-> FingerTree Size YiChunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> FingerTree Size YiChunk
fromRope
where
go :: FingerTree Size YiChunk -> FingerTree Size YiChunk
go t :: FingerTree Size YiChunk
t = case FingerTree Size YiChunk -> ViewL (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewL (FingerTree v) a
viewl FingerTree Size YiChunk
t of
EmptyL -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a
T.empty
Chunk 0 _ :< ts :: FingerTree Size YiChunk
ts -> FingerTree Size YiChunk -> FingerTree Size YiChunk
go FingerTree Size YiChunk
ts
Chunk l :: Int
l x :: Text
x :< ts :: FingerTree Size YiChunk
ts ->
let r :: Text
r = (Char -> Bool) -> Text -> Text
TX.takeWhile Char -> Bool
p Text
x
l' :: Int
l' = Text -> Int
TX.length Text
r
in case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
l' Int
l of
EQ -> Int -> Text -> YiChunk
Chunk Int
l Text
x YiChunk -> FingerTree Size YiChunk -> FingerTree Size YiChunk
-| FingerTree Size YiChunk -> FingerTree Size YiChunk
go FingerTree Size YiChunk
ts
_ -> YiChunk -> FingerTree Size YiChunk
forall v a. Measured v a => a -> FingerTree v a
T.singleton (YiChunk -> FingerTree Size YiChunk)
-> YiChunk -> FingerTree Size YiChunk
forall a b. (a -> b) -> a -> b
$ Int -> Text -> YiChunk
Chunk Int
l' Text
r
takeWhileEnd :: (Char -> Bool) -> YiString -> YiString
takeWhileEnd :: (Char -> Bool) -> YiString -> YiString
takeWhileEnd p :: Char -> Bool
p = FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> (YiString -> FingerTree Size YiChunk) -> YiString -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FingerTree Size YiChunk -> FingerTree Size YiChunk
go (FingerTree Size YiChunk -> FingerTree Size YiChunk)
-> (YiString -> FingerTree Size YiChunk)
-> YiString
-> FingerTree Size YiChunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> FingerTree Size YiChunk
fromRope
where
go :: FingerTree Size YiChunk -> FingerTree Size YiChunk
go t :: FingerTree Size YiChunk
t = case FingerTree Size YiChunk -> ViewR (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewR (FingerTree v) a
viewr FingerTree Size YiChunk
t of
EmptyR -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a
T.empty
ts :: FingerTree Size YiChunk
ts :> Chunk 0 _ -> FingerTree Size YiChunk -> FingerTree Size YiChunk
go FingerTree Size YiChunk
ts
ts :: FingerTree Size YiChunk
ts :> Chunk l :: Int
l x :: Text
x -> case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
l' Int
l of
EQ -> FingerTree Size YiChunk -> FingerTree Size YiChunk
go FingerTree Size YiChunk
ts FingerTree Size YiChunk -> YiChunk -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a -> a -> FingerTree v a
|> Int -> Text -> YiChunk
Chunk Int
l Text
x
_ -> YiChunk -> FingerTree Size YiChunk
forall v a. Measured v a => a -> FingerTree v a
T.singleton (YiChunk -> FingerTree Size YiChunk)
-> YiChunk -> FingerTree Size YiChunk
forall a b. (a -> b) -> a -> b
$ Int -> Text -> YiChunk
Chunk Int
l' Text
r
where
r :: Text
r = Text -> Text
TX.reverse (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> Text -> Text
TX.takeWhile Char -> Bool
p (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
TX.reverse (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Text
x
l' :: Int
l' = Text -> Int
TX.length Text
r
span :: (Char -> Bool) -> YiString -> (YiString, YiString)
span :: (Char -> Bool) -> YiString -> (YiString, YiString)
span p :: Char -> Bool
p y :: YiString
y = let x :: YiString
x = (Char -> Bool) -> YiString -> YiString
Yi.Rope.takeWhile Char -> Bool
p YiString
y
in case Int -> YiString -> (YiString, YiString)
Yi.Rope.splitAt (YiString -> Int
Yi.Rope.length YiString
x) YiString
y of
(_, y' :: YiString
y') -> (YiString
x, YiString
y')
break :: (Char -> Bool) -> YiString -> (YiString, YiString)
break :: (Char -> Bool) -> YiString -> (YiString, YiString)
break p :: Char -> Bool
p = (Char -> Bool) -> YiString -> (YiString, YiString)
Yi.Rope.span (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
p)
intercalate :: YiString -> [YiString] -> YiString
intercalate :: YiString -> [YiString] -> YiString
intercalate _ [] = YiString
forall a. Monoid a => a
mempty
intercalate (YiString t' :: FingerTree Size YiChunk
t') (YiString s :: FingerTree Size YiChunk
s:ss :: [YiString]
ss) = FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> FingerTree Size YiChunk -> YiString
forall a b. (a -> b) -> a -> b
$ FingerTree Size YiChunk -> [YiString] -> FingerTree Size YiChunk
go FingerTree Size YiChunk
s [YiString]
ss
where
go :: FingerTree Size YiChunk -> [YiString] -> FingerTree Size YiChunk
go !FingerTree Size YiChunk
acc [] = FingerTree Size YiChunk
acc
go acc :: FingerTree Size YiChunk
acc (YiString t :: FingerTree Size YiChunk
t : ts' :: [YiString]
ts') = FingerTree Size YiChunk -> [YiString] -> FingerTree Size YiChunk
go (FingerTree Size YiChunk
acc FingerTree Size YiChunk
-> FingerTree Size YiChunk -> FingerTree Size YiChunk
forall v a.
Measured v a =>
FingerTree v a -> FingerTree v a -> FingerTree v a
>< FingerTree Size YiChunk
t' FingerTree Size YiChunk
-> FingerTree Size YiChunk -> FingerTree Size YiChunk
forall v a.
Measured v a =>
FingerTree v a -> FingerTree v a -> FingerTree v a
>< FingerTree Size YiChunk
t) [YiString]
ts'
intersperse :: Char -> [YiString] -> YiString
intersperse :: Char -> [YiString] -> YiString
intersperse _ [] = YiString
forall a. Monoid a => a
mempty
intersperse c :: Char
c (t :: YiString
t:ts :: [YiString]
ts) = YiString -> [YiString] -> YiString
go YiString
t [YiString]
ts
where
go :: YiString -> [YiString] -> YiString
go !YiString
acc [] = YiString
acc
go acc :: YiString
acc (t' :: YiString
t':ts' :: [YiString]
ts') = YiString -> [YiString] -> YiString
go (YiString
acc YiString -> YiString -> YiString
forall a. Semigroup a => a -> a -> a
<> (Char
c Char -> YiString -> YiString
`cons` YiString
t')) [YiString]
ts'
cons :: Char -> YiString -> YiString
cons :: Char -> YiString -> YiString
cons c :: Char
c (YiString t :: FingerTree Size YiChunk
t) = case FingerTree Size YiChunk -> ViewL (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewL (FingerTree v) a
viewl FingerTree Size YiChunk
t of
EmptyL -> Char -> YiString
Yi.Rope.singleton Char
c
Chunk l :: Int
l x :: Text
x :< ts :: FingerTree Size YiChunk
ts | Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
defaultChunkSize -> FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> FingerTree Size YiChunk -> YiString
forall a b. (a -> b) -> a -> b
$ Int -> Text -> YiChunk
Chunk (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) (Char
c Char -> Text -> Text
`TX.cons` Text
x) YiChunk -> FingerTree Size YiChunk -> FingerTree Size YiChunk
forall v a. Measured v a => a -> FingerTree v a -> FingerTree v a
<| FingerTree Size YiChunk
ts
_ -> FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> FingerTree Size YiChunk -> YiString
forall a b. (a -> b) -> a -> b
$ Int -> Text -> YiChunk
Chunk 1 (Char -> Text
TX.singleton Char
c) YiChunk -> FingerTree Size YiChunk -> FingerTree Size YiChunk
forall v a. Measured v a => a -> FingerTree v a -> FingerTree v a
<| FingerTree Size YiChunk
t
snoc :: YiString -> Char -> YiString
snoc :: YiString -> Char -> YiString
snoc (YiString t :: FingerTree Size YiChunk
t) c :: Char
c = case FingerTree Size YiChunk -> ViewR (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewR (FingerTree v) a
viewr FingerTree Size YiChunk
t of
EmptyR -> Char -> YiString
Yi.Rope.singleton Char
c
ts :: FingerTree Size YiChunk
ts :> Chunk l :: Int
l x :: Text
x | Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
defaultChunkSize -> FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> FingerTree Size YiChunk -> YiString
forall a b. (a -> b) -> a -> b
$ FingerTree Size YiChunk
ts FingerTree Size YiChunk -> YiChunk -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a -> a -> FingerTree v a
|> Int -> Text -> YiChunk
Chunk (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) (Text
x Text -> Char -> Text
`TX.snoc` Char
c)
_ -> FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> FingerTree Size YiChunk -> YiString
forall a b. (a -> b) -> a -> b
$ FingerTree Size YiChunk
t FingerTree Size YiChunk -> YiChunk -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a -> a -> FingerTree v a
|> Int -> Text -> YiChunk
Chunk 1 (Char -> Text
TX.singleton Char
c)
singleton :: Char -> YiString
singleton :: Char -> YiString
singleton c :: Char
c = FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> (YiChunk -> FingerTree Size YiChunk) -> YiChunk -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiChunk -> FingerTree Size YiChunk
forall v a. Measured v a => a -> FingerTree v a
T.singleton (YiChunk -> YiString) -> YiChunk -> YiString
forall a b. (a -> b) -> a -> b
$ Int -> Text -> YiChunk
Chunk 1 (Char -> Text
TX.singleton Char
c)
splitAtLine :: Int -> YiString -> (YiString, YiString)
splitAtLine :: Int -> YiString -> (YiString, YiString)
splitAtLine n :: Int
n r :: YiString
r | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 0 = (YiString
empty, YiString
r)
| Bool
otherwise = Int -> YiString -> (YiString, YiString)
splitAtLine' (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) YiString
r
splitAtLine' :: Int -> YiString -> (YiString, YiString)
splitAtLine' :: Int -> YiString -> (YiString, YiString)
splitAtLine' p :: Int
p (YiString tr :: FingerTree Size YiChunk
tr) = case FingerTree Size YiChunk -> ViewL (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewL (FingerTree v) a
viewl FingerTree Size YiChunk
s of
ch :: YiChunk
ch@(Chunk _ x :: Text
x) :< r :: FingerTree Size YiChunk
r ->
let excess :: Int
excess = Size -> Int
lineIndex (FingerTree Size YiChunk -> Size
forall v a. Measured v a => a -> v
measure FingerTree Size YiChunk
f) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Size -> Int
lineIndex (YiChunk -> Size
forall v a. Measured v a => a -> v
measure YiChunk
ch) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
p Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1
(lx :: Text
lx, rx :: Text
rx) = Int -> Text -> (Text, Text)
cutExcess Int
excess Text
x
in (FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> FingerTree Size YiChunk -> YiString
forall a b. (a -> b) -> a -> b
$ FingerTree Size YiChunk
f FingerTree Size YiChunk -> YiChunk -> FingerTree Size YiChunk
|- (Text -> Int) -> Text -> YiChunk
mkChunk Text -> Int
TX.length Text
lx,
FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> FingerTree Size YiChunk -> YiString
forall a b. (a -> b) -> a -> b
$ (Text -> Int) -> Text -> YiChunk
mkChunk Text -> Int
TX.length Text
rx YiChunk -> FingerTree Size YiChunk -> FingerTree Size YiChunk
-| FingerTree Size YiChunk
r)
_ -> (FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
f, FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
s)
where
(f :: FingerTree Size YiChunk
f, s :: FingerTree Size YiChunk
s) = (Size -> Bool)
-> FingerTree Size YiChunk
-> (FingerTree Size YiChunk, FingerTree Size YiChunk)
forall v a.
Measured v a =>
(v -> Bool) -> FingerTree v a -> (FingerTree v a, FingerTree v a)
T.split ((Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<) (Int -> Bool) -> (Size -> Int) -> Size -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Size -> Int
lineIndex) FingerTree Size YiChunk
tr
cutExcess :: Int -> TX.Text -> (TX.Text, TX.Text)
cutExcess :: Int -> Text -> (Text, Text)
cutExcess n :: Int
n t :: Text
t = case Text -> Int
TX.length Text
t of
0 -> (Text
TX.empty, Text
TX.empty)
_ -> let ns :: Int
ns = Text -> Int
countNl Text
t
ls :: [Text]
ls = Text -> [Text]
TX.lines Text
t
front :: Text
front = [Text] -> Text
TX.unlines ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Int -> [Text] -> [Text]
forall a. Int -> [a] -> [a]
Prelude.take (Int
ns Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) [Text]
ls
back :: Text
back = Int -> Text -> Text
TX.drop (Text -> Int
TX.length Text
front) Text
t
in if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
ns
then (Text
t, Text
TX.empty)
else (Text
front, Text
back)
lines :: YiString -> [YiString]
lines :: YiString -> [YiString]
lines = (YiString -> YiString) -> [YiString] -> [YiString]
forall a b. (a -> b) -> [a] -> [b]
Prelude.map YiString -> YiString
dropNl ([YiString] -> [YiString])
-> (YiString -> [YiString]) -> YiString -> [YiString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> [YiString]
lines'
where
dropNl :: YiString -> YiString
dropNl (YiString t :: FingerTree Size YiChunk
t) = case FingerTree Size YiChunk -> ViewR (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewR (FingerTree v) a
viewr FingerTree Size YiChunk
t of
EmptyR -> YiString
Yi.Rope.empty
ts :: FingerTree Size YiChunk
ts :> ch :: YiChunk
ch@(Chunk l :: Int
l tx :: Text
tx) ->
FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> FingerTree Size YiChunk -> YiString
forall a b. (a -> b) -> a -> b
$ FingerTree Size YiChunk
ts FingerTree Size YiChunk -> YiChunk -> FingerTree Size YiChunk
|- if Text -> Bool
TX.null Text
tx
then YiChunk
ch
else case Text -> Char
TX.last Text
tx of
'\n' -> Int -> Text -> YiChunk
Chunk (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) (Text -> Text
TX.init Text
tx)
_ -> YiChunk
ch
lines' :: YiString -> [YiString]
lines' :: YiString -> [YiString]
lines' t :: YiString
t = let (YiString f :: FingerTree Size YiChunk
f, YiString s :: FingerTree Size YiChunk
s) = Int -> YiString -> (YiString, YiString)
splitAtLine' 0 YiString
t
in if FingerTree Size YiChunk -> Bool
forall v a. FingerTree v a -> Bool
T.null FingerTree Size YiChunk
s
then if FingerTree Size YiChunk -> Bool
forall v a. FingerTree v a -> Bool
T.null FingerTree Size YiChunk
f then [] else [FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
f]
else FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
f YiString -> [YiString] -> [YiString]
forall a. a -> [a] -> [a]
: YiString -> [YiString]
lines' (FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
s)
unlines :: [YiString] -> YiString
unlines :: [YiString] -> YiString
unlines = Char -> [YiString] -> YiString
Yi.Rope.intersperse '\n'
any :: (Char -> Bool) -> YiString -> Bool
any :: (Char -> Bool) -> YiString -> Bool
any p :: Char -> Bool
p = FingerTree Size YiChunk -> Bool
go (FingerTree Size YiChunk -> Bool)
-> (YiString -> FingerTree Size YiChunk) -> YiString -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> FingerTree Size YiChunk
fromRope
where
go :: FingerTree Size YiChunk -> Bool
go x :: FingerTree Size YiChunk
x = case FingerTree Size YiChunk -> ViewL (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewL (FingerTree v) a
viewl FingerTree Size YiChunk
x of
EmptyL -> Bool
False
Chunk _ t :: Text
t :< ts :: FingerTree Size YiChunk
ts -> (Char -> Bool) -> Text -> Bool
TX.any Char -> Bool
p Text
t Bool -> Bool -> Bool
|| FingerTree Size YiChunk -> Bool
go FingerTree Size YiChunk
ts
all :: (Char -> Bool) -> YiString -> Bool
all :: (Char -> Bool) -> YiString -> Bool
all p :: Char -> Bool
p = FingerTree Size YiChunk -> Bool
go (FingerTree Size YiChunk -> Bool)
-> (YiString -> FingerTree Size YiChunk) -> YiString -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> FingerTree Size YiChunk
fromRope
where
go :: FingerTree Size YiChunk -> Bool
go x :: FingerTree Size YiChunk
x = case FingerTree Size YiChunk -> ViewL (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewL (FingerTree v) a
viewl FingerTree Size YiChunk
x of
EmptyL -> Bool
True
Chunk _ t :: Text
t :< ts :: FingerTree Size YiChunk
ts -> (Char -> Bool) -> Text -> Bool
TX.all Char -> Bool
p Text
t Bool -> Bool -> Bool
&& FingerTree Size YiChunk -> Bool
go FingerTree Size YiChunk
ts
instance Binary YiString where
put :: YiString -> Put
put = String -> Put
forall t. Binary t => t -> Put
put (String -> Put) -> (YiString -> String) -> YiString -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> String
toString
get :: Get YiString
get = String -> YiString
Yi.Rope.fromString (String -> YiString) -> Get String -> Get YiString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get String
forall t. Binary t => Get t
get
writeFile :: FilePath -> YiString -> IO ()
writeFile :: String -> YiString -> IO ()
writeFile f :: String
f = String -> Text -> IO ()
TXIO.writeFile String
f (Text -> IO ()) -> (YiString -> Text) -> YiString -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> Text
toText
readFile :: FilePath -> IO (Either TX.Text YiString)
readFile :: String -> IO (Either Text YiString)
readFile fp :: String
fp = String -> IO ByteString
BSL.readFile String
fp IO ByteString
-> (ByteString -> IO (Either Text YiString))
-> IO (Either Text YiString)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [ByteString -> Text] -> ByteString -> IO (Either Text YiString)
forall t. [t -> Text] -> t -> IO (Either Text YiString)
go [ByteString -> Text]
decoders
where
go :: [t -> Text] -> t -> IO (Either Text YiString)
go [] _ = Either Text YiString -> IO (Either Text YiString)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Either Text YiString
forall a b. a -> Either a b
Left Text
err)
go (d :: t -> Text
d : ds :: [t -> Text]
ds) bytes :: t
bytes =
IO Text -> IO (Either UnicodeException Text)
forall e a. Exception e => IO a -> IO (Either e a)
try (Text -> IO Text
forall (f :: * -> *) a. Applicative f => a -> f a
pure (t -> Text
d t
bytes)) IO (Either UnicodeException Text)
-> (Either UnicodeException Text -> IO (Either Text YiString))
-> IO (Either Text YiString)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Left (UnicodeException
_ :: TXEE.UnicodeException) -> [t -> Text] -> t -> IO (Either Text YiString)
go [t -> Text]
ds t
bytes
Right text :: Text
text -> Either Text YiString -> IO (Either Text YiString)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (YiString -> Either Text YiString
forall a b. b -> Either a b
Right (Text -> YiString
fromLazyText Text
text))
err :: Text
err = "Could not guess the encoding of " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
TX.pack String
fp
decoders :: [ByteString -> Text]
decoders =
[ ByteString -> Text
TXLE.decodeUtf8
, ByteString -> Text
TXLE.decodeUtf16LE
, ByteString -> Text
TXLE.decodeUtf16BE
, ByteString -> Text
TXLE.decodeUtf32LE
, ByteString -> Text
TXLE.decodeUtf32BE
]
filter :: (Char -> Bool) -> YiString -> YiString
filter :: (Char -> Bool) -> YiString -> YiString
filter p :: Char -> Bool
p = FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> (YiString -> FingerTree Size YiChunk) -> YiString -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FingerTree Size YiChunk -> FingerTree Size YiChunk
go (FingerTree Size YiChunk -> FingerTree Size YiChunk)
-> (YiString -> FingerTree Size YiChunk)
-> YiString
-> FingerTree Size YiChunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> FingerTree Size YiChunk
fromRope
where
go :: FingerTree Size YiChunk -> FingerTree Size YiChunk
go t :: FingerTree Size YiChunk
t = case FingerTree Size YiChunk -> ViewL (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewL (FingerTree v) a
viewl FingerTree Size YiChunk
t of
EmptyL -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a
T.empty
Chunk _ x :: Text
x :< ts :: FingerTree Size YiChunk
ts -> (Text -> Int) -> Text -> YiChunk
mkChunk Text -> Int
TX.length ((Char -> Bool) -> Text -> Text
TX.filter Char -> Bool
p Text
x) YiChunk -> FingerTree Size YiChunk -> FingerTree Size YiChunk
-| FingerTree Size YiChunk -> FingerTree Size YiChunk
go FingerTree Size YiChunk
ts
map :: (Char -> Char) -> YiString -> YiString
map :: (Char -> Char) -> YiString -> YiString
map f :: Char -> Char
f = FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> (YiString -> FingerTree Size YiChunk) -> YiString -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FingerTree Size YiChunk -> FingerTree Size YiChunk
go (FingerTree Size YiChunk -> FingerTree Size YiChunk)
-> (YiString -> FingerTree Size YiChunk)
-> YiString
-> FingerTree Size YiChunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> FingerTree Size YiChunk
fromRope
where
go :: FingerTree Size YiChunk -> FingerTree Size YiChunk
go t :: FingerTree Size YiChunk
t = case FingerTree Size YiChunk -> ViewL (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewL (FingerTree v) a
viewl FingerTree Size YiChunk
t of
EmptyL -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a
T.empty
Chunk l :: Int
l x :: Text
x :< ts :: FingerTree Size YiChunk
ts -> Int -> Text -> YiChunk
Chunk Int
l ((Char -> Char) -> Text -> Text
TX.map Char -> Char
f Text
x) YiChunk -> FingerTree Size YiChunk -> FingerTree Size YiChunk
forall v a. Measured v a => a -> FingerTree v a -> FingerTree v a
<| FingerTree Size YiChunk -> FingerTree Size YiChunk
go FingerTree Size YiChunk
ts
unwords :: [YiString] -> YiString
unwords :: [YiString] -> YiString
unwords = Char -> [YiString] -> YiString
Yi.Rope.intersperse ' '
words :: YiString -> [YiString]
words :: YiString -> [YiString]
words = (YiString -> Bool) -> [YiString] -> [YiString]
forall a. (a -> Bool) -> [a] -> [a]
Prelude.filter (Bool -> Bool
not (Bool -> Bool) -> (YiString -> Bool) -> YiString -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> Bool
Yi.Rope.null) ([YiString] -> [YiString])
-> (YiString -> [YiString]) -> YiString -> [YiString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> YiString -> [YiString]
Yi.Rope.split Char -> Bool
isSpace
split :: (Char -> Bool) -> YiString -> [YiString]
split :: (Char -> Bool) -> YiString -> [YiString]
split p :: Char -> Bool
p = (Text -> YiString) -> [Text] -> [YiString]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> YiString
fromText ([Text] -> [YiString])
-> (YiString -> [Text]) -> YiString -> [YiString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> Text -> [Text]
TX.split Char -> Bool
p (Text -> [Text]) -> (YiString -> Text) -> YiString -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> Text
toText
foldl' :: (a -> Char -> a) -> a -> YiString -> a
foldl' :: (a -> Char -> a) -> a -> YiString -> a
foldl' f :: a -> Char -> a
f a :: a
a = a -> FingerTree Size YiChunk -> a
go a
a (FingerTree Size YiChunk -> a)
-> (YiString -> FingerTree Size YiChunk) -> YiString -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> FingerTree Size YiChunk
fromRope
where
go :: a -> FingerTree Size YiChunk -> a
go acc :: a
acc t :: FingerTree Size YiChunk
t = case FingerTree Size YiChunk -> ViewL (FingerTree Size) YiChunk
forall v a.
Measured v a =>
FingerTree v a -> ViewL (FingerTree v) a
viewl FingerTree Size YiChunk
t of
EmptyL -> a
acc
Chunk _ x :: Text
x :< ts :: FingerTree Size YiChunk
ts -> let r :: a
r = (a -> Char -> a) -> a -> Text -> a
forall a. (a -> Char -> a) -> a -> Text -> a
TX.foldl' a -> Char -> a
f a
acc Text
x
in a
r a -> a -> a
forall a b. a -> b -> b
`seq` a -> FingerTree Size YiChunk -> a
go a
r FingerTree Size YiChunk
ts
replicate :: Int -> YiString -> YiString
replicate :: Int -> YiString -> YiString
replicate n :: Int
n t :: YiString
t | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 0 = YiString
forall a. Monoid a => a
mempty
| Bool
otherwise = YiString
t YiString -> YiString -> YiString
forall a. Semigroup a => a -> a -> a
<> Int -> YiString -> YiString
Yi.Rope.replicate (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) YiString
t
replicateChar :: Int -> Char -> YiString
replicateChar :: Int -> Char -> YiString
replicateChar n :: Int
n = Text -> YiString
fromText (Text -> YiString) -> (Char -> Text) -> Char -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Text -> Text
TX.replicate Int
n (Text -> Text) -> (Char -> Text) -> Char -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Text
TX.singleton
withText :: (TX.Text -> TX.Text) -> YiString -> YiString
withText :: (Text -> Text) -> YiString -> YiString
withText f :: Text -> Text
f = FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> (YiString -> FingerTree Size YiChunk) -> YiString -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (YiChunk -> YiChunk)
-> FingerTree Size YiChunk -> FingerTree Size YiChunk
forall v1 a1 v2 a2.
(Measured v1 a1, Measured v2 a2) =>
(a1 -> a2) -> FingerTree v1 a1 -> FingerTree v2 a2
T.fmap' ((Text -> Int) -> Text -> YiChunk
mkChunk Text -> Int
TX.length (Text -> YiChunk) -> (YiChunk -> Text) -> YiChunk -> YiChunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
f (Text -> Text) -> (YiChunk -> Text) -> YiChunk -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiChunk -> Text
_fromChunk) (FingerTree Size YiChunk -> FingerTree Size YiChunk)
-> (YiString -> FingerTree Size YiChunk)
-> YiString
-> FingerTree Size YiChunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> FingerTree Size YiChunk
fromRope
unsafeWithText :: (TX.Text -> TX.Text) -> YiString -> YiString
unsafeWithText :: (Text -> Text) -> YiString -> YiString
unsafeWithText f :: Text -> Text
f = FingerTree Size YiChunk -> YiString
YiString (FingerTree Size YiChunk -> YiString)
-> (YiString -> FingerTree Size YiChunk) -> YiString -> YiString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (YiChunk -> YiChunk)
-> FingerTree Size YiChunk -> FingerTree Size YiChunk
forall a b v. (a -> b) -> FingerTree v a -> FingerTree v b
T.unsafeFmap YiChunk -> YiChunk
g (FingerTree Size YiChunk -> FingerTree Size YiChunk)
-> (YiString -> FingerTree Size YiChunk)
-> YiString
-> FingerTree Size YiChunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> FingerTree Size YiChunk
fromRope
where
g :: YiChunk -> YiChunk
g (Chunk l :: Int
l t :: Text
t) = Int -> Text -> YiChunk
Chunk Int
l (Text -> Text
f Text
t)