yi-rope 0.8 → 0.9
raw patch · 3 files changed
+24/−40 lines, 3 files
Files
- bench/MainBenchmarkSuite.hs +2/−1
- src/Yi/Rope.hs +18/−35
- yi-rope.cabal +4/−4
bench/MainBenchmarkSuite.hs view
@@ -84,7 +84,7 @@ mkTexts x t = (x, F.fromText' x t) allTexts :: [(Int -> String, [(Int, F.YiString)])]-allTexts = [longTexts {-, wideTexts, shortTexts, tinyTexts -}]+allTexts = [longTexts, wideTexts, shortTexts, tinyTexts] allChars :: [(Int -> String, [(Int, Char)])] allChars = map mkChar "λa"@@ -160,6 +160,7 @@ , onCharGroup "singleton" F.singleton , onTextGroup "countNewLines" F.countNewLines , onTextGroup "lines" F.lines+ , onTextGroup "lines'" F.lines' , onSplitGroup "splitAt" F.splitAt , onSplitGroup "splitAtLine" F.splitAtLine , onTextGroup "toReverseString" F.toReverseString
src/Yi/Rope.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ViewPatterns #-} {-# OPTIONS_HADDOCK show-extensions #-} -- |@@ -70,6 +71,7 @@ import Data.Default import qualified Data.FingerTree as T import Data.FingerTree hiding (null, empty, reverse, split)+import Data.Function (fix) import qualified Data.List as L (foldl') import Data.Maybe import Data.Monoid@@ -501,24 +503,18 @@ go acc (t':ts') = go (acc <> (c `cons` t')) ts' -- | Add a 'Char' in front of a 'YiString'.------ We add the character to the front of the first chunk. This does--- mean that a lot of 'cons' might result in an abnormally large first--- chunk so if you have to do that, consider using 'append' instead.. cons :: Char -> YiString -> YiString cons c (YiString t) = case viewl t of EmptyL -> Yi.Rope.singleton c- Chunk !l x :< ts -> YiString $ Chunk (l + 1) (c `TX.cons` x) <| ts+ Chunk l x :< ts | l < defaultChunkSize -> YiString $ Chunk (l + 1) (c `TX.cons` x) <| ts+ _ -> YiString $ Chunk 1 (TX.singleton c) <| t -- | Add a 'Char' in the back of a 'YiString'.------ We add the character to the end of the last chunk. This does mean--- that a lot of 'snoc' might result in an abnormally large last chunk--- so if you have to do that, consider using 'append' instead.. snoc :: YiString -> Char -> YiString snoc (YiString t) c = case viewr t of EmptyR -> Yi.Rope.singleton c- ts :> Chunk l x -> YiString $ ts |> Chunk (l + 1) (x `TX.snoc` c)+ ts :> Chunk l x | l < defaultChunkSize -> YiString $ ts |> Chunk (l + 1) (x `TX.snoc` c)+ _ -> YiString $ t |> Chunk 1 (TX.singleton c) -- | Single character 'YiString'. Consider whether it's worth creating -- this, maybe you can use 'cons' or 'snoc' instead?@@ -569,26 +565,11 @@ -- | This is like 'lines'' but it does *not* preserve newlines. ----- Specifically, we just strip the newlines from the result of--- 'lines''.------ This behaves slightly differently than the old split: the number of--- resulting strings here is equal to the number of newline characters--- in the underlying string. This is much more consistent than the old--- behaviour which blindly used @ByteString@s split and stitched the--- result back together which was inconsistent with the rest of the--- interface which worked with number of newlines.+-- Implementation note: GHC does a pretty good job of optimizing+-- this naive version. Hand coding a loop should be unnecessary+-- here. lines :: YiString -> [YiString]-lines = Prelude.map dropNl . lines'- where- dropNl (YiString t) = case viewr t of- EmptyR -> Yi.Rope.empty- ts :> ch@(Chunk l tx) ->- YiString $ ts |- if TX.null tx- then ch- else case TX.last tx of- '\n' -> Chunk (l - 1) (TX.init tx)- _ -> ch+lines = fmap fromText . TX.lines . toText -- | Splits the 'YiString' into a list of 'YiString' each containing a -- line.@@ -603,13 +584,15 @@ -- -- > 'toText' . 'concat' . 'lines'' ≡ 'toText' ----- but the underlying structure might change: notably, chunks will--- most likely change sizes. lines' :: YiString -> [YiString]-lines' t = let (YiString f, YiString s) = splitAtLine' 0 t- in if T.null s- then if T.null f then [] else [YiString f]- else YiString f : lines' (YiString s)+lines' = splitByKeepingDelim '\n'++splitByKeepingDelim :: Char -> YiString -> [YiString]+splitByKeepingDelim x = fmap fromText . fix go x . toText+ where+ go :: (Char -> TX.Text -> [TX.Text]) -> Char -> TX.Text -> [TX.Text]+ go _ c (TX.span (/=c) -> (_, TX.null -> True)) = []+ go f c (TX.span (/=c) -> (a,b)) = a `TX.snoc` c : f c (TX.tail b) -- | Joins up lines by a newline character. It does not leave a -- newline after the last line. If you want a more classical
yi-rope.cabal view
@@ -1,17 +1,17 @@ name: yi-rope-version: 0.8+version: 0.9 synopsis: A rope data structure used by Yi description: A rope data structure used by Yi license: GPL-2 license-file: LICENSE-author: Mateusz Kowalczyk-maintainer: fuuzetsu@fuuzetsu.co.uk+author: AUTHORS+maintainer: yi-devel@googlegroups.com category: Yi build-type: Simple cabal-version: >=1.10 library- ghc-options: -fpedantic-bottoms -fexpose-all-unfoldings -Wall -O2 -flate-dmd-anal+ ghc-options: -fpedantic-bottoms -fexpose-all-unfoldings -ferror-spans -Wall -O2 -flate-dmd-anal exposed-modules: Yi.Rope