{-# 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
$c== :: Size -> Size -> Bool
== :: Size -> Size -> Bool
$c/= :: Size -> Size -> Bool
/= :: 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
$cshowsPrec :: Int -> Size -> ShowS
showsPrec :: Int -> Size -> ShowS
$cshow :: Size -> String
show :: Size -> String
$cshowList :: [Size] -> ShowS
showList :: [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
$cshowsPrec :: Int -> YiChunk -> ShowS
showsPrec :: Int -> YiChunk -> ShowS
$cshow :: YiChunk -> String
show :: YiChunk -> String
$cshowList :: [YiChunk] -> ShowS
showList :: [YiChunk] -> ShowS
Show, YiChunk -> YiChunk -> Bool
(YiChunk -> YiChunk -> Bool)
-> (YiChunk -> YiChunk -> Bool) -> Eq YiChunk
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: YiChunk -> YiChunk -> Bool
== :: YiChunk -> YiChunk -> Bool
$c/= :: YiChunk -> YiChunk -> Bool
/= :: YiChunk -> YiChunk -> Bool
Eq, Typeable)
mkChunk :: (TX.Text -> Int)
-> TX.Text
-> YiChunk
mkChunk :: (Text -> Int) -> Text -> YiChunk
mkChunk Text -> Int
l 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 Text -> Text
f (Chunk Int
l Text
t) = Int -> Text -> YiChunk
Chunk Int
l (Text -> Text
f Text
t)
countNl :: TX.Text -> Int
countNl :: Text -> Int
countNl = HasCallStack => Text -> Text -> Int
Text -> Text -> Int
TX.count Text
"\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 Int
0 Int
0
Indices Int
c Int
l mappend :: Size -> Size -> Size
`mappend` Indices Int
c' 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 Int
l 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
$cshowsPrec :: Int -> YiString -> ShowS
showsPrec :: Int -> YiString -> ShowS
$cshow :: YiString -> String
show :: YiString -> String
$cshowList :: [YiString] -> ShowS
showList :: [YiString] -> ShowS
Show, Typeable)
instance Eq YiString where
YiString
t == :: YiString -> YiString -> Bool
== 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 YiString
x 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
YiChunk
b -| :: YiChunk -> FingerTree Size YiChunk -> FingerTree Size YiChunk
-| FingerTree Size YiChunk
t | YiChunk -> Int
chunkSize YiChunk
b Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
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
FingerTree Size YiChunk
t |- :: FingerTree Size YiChunk -> YiChunk -> FingerTree Size YiChunk
|- YiChunk
b | YiChunk -> Int
chunkSize YiChunk
b Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
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 = Int
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' 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' Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
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 (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 (Text
t:[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 a b. (a -> b) -> [a] -> [b]
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 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 Int
_ !Text
c :< FingerTree Size YiChunk
cs -> Text
c Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: FingerTree Size YiChunk -> [Text]
go FingerTree Size YiChunk
cs
ViewL (FingerTree Size) YiChunk
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 FingerTree Size YiChunk
t) (YiString 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
(ViewR (FingerTree Size) YiChunk
EmptyR, ViewL (FingerTree Size) YiChunk
_) -> FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
t'
(ViewR (FingerTree Size) YiChunk
_, ViewL (FingerTree Size) YiChunk
EmptyL) -> FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
t
(FingerTree Size YiChunk
ts :> Chunk Int
l Text
x, Chunk Int
l' Text
x' :< 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
Ordering
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')
Ordering
_ -> 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 b a. (b -> a -> b) -> b -> [a] -> b
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 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
ViewL (FingerTree Size) YiChunk
EmptyL -> Maybe Char
forall a. Maybe a
Nothing
Chunk Int
_ Text
x :< FingerTree Size YiChunk
_ -> 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 (HasCallStack => Text -> Char
Text -> Char
TX.head Text
x)
last :: YiString -> Maybe Char
last :: YiString -> Maybe Char
last (YiString 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
ViewR (FingerTree Size) YiChunk
EmptyR -> Maybe Char
forall a. Maybe a
Nothing
FingerTree Size YiChunk
_ :> Chunk Int
_ 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 (HasCallStack => Text -> Char
Text -> Char
TX.last Text
x)
init :: YiString -> Maybe YiString
init :: YiString -> Maybe YiString
init (YiString 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
ViewR (FingerTree Size) YiChunk
EmptyR -> Maybe YiString
forall a. Maybe a
Nothing
FingerTree Size YiChunk
ts :> Chunk Int
0 Text
_ -> YiString -> Maybe YiString
Yi.Rope.init (FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
ts)
FingerTree Size YiChunk
ts :> Chunk Int
l 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
- Int
1) (HasCallStack => Text -> Text
Text -> Text
TX.init Text
x)
tail :: YiString -> Maybe YiString
tail :: YiString -> Maybe YiString
tail (YiString 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
ViewL (FingerTree Size) YiChunk
EmptyL -> Maybe YiString
forall a. Maybe a
Nothing
Chunk Int
0 Text
_ :< FingerTree Size YiChunk
ts -> YiString -> Maybe YiString
Yi.Rope.tail (FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
ts)
Chunk Int
l Text
x :< 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
- Int
1) (HasCallStack => Text -> Text
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 Int
n (YiString FingerTree Size YiChunk
t)
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
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 Int
l Text
x :< FingerTree Size YiChunk
ts | Int
n' Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0 ->
let (Text
lx, 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)
ViewL (FingerTree Size) YiChunk
_ -> (FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
f, FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
s)
where
(FingerTree Size YiChunk
f, 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 Int
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 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 Int
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 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 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 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
ViewL (FingerTree Size) YiChunk
EmptyL -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a
T.empty
Chunk Int
0 Text
_ :< FingerTree Size YiChunk
ts -> FingerTree Size YiChunk -> FingerTree Size YiChunk
go FingerTree Size YiChunk
ts
Chunk Int
l Text
x :< 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
Ordering
EQ -> FingerTree Size YiChunk
t
Ordering
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
Ordering
_ -> 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 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 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
ViewR (FingerTree Size) YiChunk
EmptyR -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a
T.empty
FingerTree Size YiChunk
ts :> Chunk Int
0 Text
_ -> FingerTree Size YiChunk -> FingerTree Size YiChunk
go FingerTree Size YiChunk
ts
FingerTree Size YiChunk
ts :> Chunk Int
l 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
Ordering
EQ -> FingerTree Size YiChunk
t
Ordering
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
Ordering
_ -> 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 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 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
ViewL (FingerTree Size) YiChunk
EmptyL -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a
T.empty
Chunk Int
0 Text
_ :< FingerTree Size YiChunk
ts -> FingerTree Size YiChunk -> FingerTree Size YiChunk
go FingerTree Size YiChunk
ts
Chunk Int
l Text
x :< 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
Ordering
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
Ordering
_ -> 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 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 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
ViewR (FingerTree Size) YiChunk
EmptyR -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a
T.empty
FingerTree Size YiChunk
ts :> Chunk Int
0 Text
_ -> FingerTree Size YiChunk -> FingerTree Size YiChunk
go FingerTree Size YiChunk
ts
FingerTree Size YiChunk
ts :> Chunk Int
l Text
x -> case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
l' Int
l of
Ordering
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
Ordering
_ -> 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 Char -> Bool
p 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
(YiString
_, YiString
y') -> (YiString
x, YiString
y')
break :: (Char -> Bool) -> YiString -> (YiString, YiString)
break :: (Char -> Bool) -> YiString -> (YiString, YiString)
break 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
_ [] = YiString
forall a. Monoid a => a
mempty
intercalate (YiString FingerTree Size YiChunk
t') (YiString FingerTree Size YiChunk
s:[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 FingerTree Size YiChunk
acc (YiString FingerTree Size YiChunk
t : [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 Char
_ [] = YiString
forall a. Monoid a => a
mempty
intersperse Char
c (YiString
t:[YiString]
ts) = YiString -> [YiString] -> YiString
go YiString
t [YiString]
ts
where
go :: YiString -> [YiString] -> YiString
go !YiString
acc [] = YiString
acc
go YiString
acc (YiString
t':[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 Char
c (YiString 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
ViewL (FingerTree Size) YiChunk
EmptyL -> Char -> YiString
Yi.Rope.singleton Char
c
Chunk Int
l Text
x :< 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
+ Int
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
ViewL (FingerTree Size) YiChunk
_ -> 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
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 FingerTree Size YiChunk
t) 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
ViewR (FingerTree Size) YiChunk
EmptyR -> Char -> YiString
Yi.Rope.singleton Char
c
FingerTree Size YiChunk
ts :> Chunk Int
l 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
+ Int
1) (Text
x Text -> Char -> Text
`TX.snoc` Char
c)
ViewR (FingerTree Size) YiChunk
_ -> 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 Int
1 (Char -> Text
TX.singleton Char
c)
singleton :: Char -> YiString
singleton :: Char -> YiString
singleton 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 Int
1 (Char -> Text
TX.singleton Char
c)
splitAtLine :: Int -> YiString -> (YiString, YiString)
splitAtLine :: Int -> YiString -> (YiString, YiString)
splitAtLine Int
n YiString
r | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = (YiString
empty, YiString
r)
| Bool
otherwise = Int -> YiString -> (YiString, YiString)
splitAtLine' (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) YiString
r
splitAtLine' :: Int -> YiString -> (YiString, YiString)
splitAtLine' :: Int -> YiString -> (YiString, YiString)
splitAtLine' Int
p (YiString 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 Int
_ Text
x) :< 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
- Int
1
(Text
lx, 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)
ViewL (FingerTree Size) YiChunk
_ -> (FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
f, FingerTree Size YiChunk -> YiString
YiString FingerTree Size YiChunk
s)
where
(FingerTree Size YiChunk
f, 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 Int
n Text
t = case Text -> Int
TX.length Text
t of
Int
0 -> (Text
TX.empty, Text
TX.empty)
Int
_ -> 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 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
ViewR (FingerTree Size) YiChunk
EmptyR -> YiString
Yi.Rope.empty
FingerTree Size YiChunk
ts :> ch :: YiChunk
ch@(Chunk Int
l 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 HasCallStack => Text -> Char
Text -> Char
TX.last Text
tx of
Char
'\n' -> Int -> Text -> YiChunk
Chunk (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (HasCallStack => Text -> Text
Text -> Text
TX.init Text
tx)
Char
_ -> YiChunk
ch
lines' :: YiString -> [YiString]
lines' :: YiString -> [YiString]
lines' YiString
t = let (YiString FingerTree Size YiChunk
f, YiString FingerTree Size YiChunk
s) = Int -> YiString -> (YiString, YiString)
splitAtLine' Int
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 Char
'\n'
any :: (Char -> Bool) -> YiString -> Bool
any :: (Char -> Bool) -> YiString -> Bool
any 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 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
ViewL (FingerTree Size) YiChunk
EmptyL -> Bool
False
Chunk Int
_ Text
t :< 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 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 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
ViewL (FingerTree Size) YiChunk
EmptyL -> Bool
True
Chunk Int
_ Text
t :< 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 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 String
fp = String -> IO ByteString
BSL.readFile String
fp IO ByteString
-> (ByteString -> IO (Either Text YiString))
-> IO (Either Text YiString)
forall a b. IO a -> (a -> IO b) -> IO b
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 [] t
_ = Either Text YiString -> IO (Either Text YiString)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Either Text YiString
forall a b. a -> Either a b
Left Text
err)
go (t -> Text
d : [t -> Text]
ds) t
bytes =
IO Text -> IO (Either UnicodeException Text)
forall e a. Exception e => IO a -> IO (Either e a)
try (Text -> IO Text
forall a. a -> IO a
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 a b. IO a -> (a -> IO b) -> IO b
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 -> Either Text YiString -> IO (Either Text YiString)
forall a. a -> IO a
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 = Text
"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 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 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
ViewL (FingerTree Size) YiChunk
EmptyL -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a
T.empty
Chunk Int
_ Text
x :< 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 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 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
ViewL (FingerTree Size) YiChunk
EmptyL -> FingerTree Size YiChunk
forall v a. Measured v a => FingerTree v a
T.empty
Chunk Int
l Text
x :< 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 Char
' '
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 Char -> Bool
p = (Text -> YiString) -> [Text] -> [YiString]
forall a b. (a -> b) -> [a] -> [b]
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' :: forall a. (a -> Char -> a) -> a -> YiString -> a
foldl' a -> Char -> a
f 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 a
acc 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
ViewL (FingerTree Size) YiChunk
EmptyL -> a
acc
Chunk Int
_ Text
x :< 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 Int
n YiString
t | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
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
- Int
1) YiString
t
replicateChar :: Int -> Char -> YiString
replicateChar :: Int -> Char -> YiString
replicateChar 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 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 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 Int
l Text
t) = Int -> Text -> YiChunk
Chunk Int
l (Text -> Text
f Text
t)