core-text 0.2.2.6 → 0.2.3.3
raw patch · 5 files changed
+100/−5 lines, 5 filesdep ~prettyprinterPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: prettyprinter
API changes (from Hackage documentation)
+ Core.Text.Rope: findIndexRope :: (Char -> Bool) -> Rope -> Maybe Int
+ Core.Text.Rope: replicateChar :: Int -> Char -> Rope
+ Core.Text.Rope: replicateRope :: Int -> Rope -> Rope
+ Core.Text.Utilities: calculatePositionEnd :: Rope -> (Int, Int)
+ Core.Text.Utilities: isNewline :: Char -> Bool
Files
- core-text.cabal +5/−4
- lib/Core/Text/Breaking.hs +6/−0
- lib/Core/Text/Parsing.hs +39/−0
- lib/Core/Text/Rope.hs +47/−1
- lib/Core/Text/Utilities.hs +3/−0
core-text.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 113b0b96cebb913a06d4c3a2344ce4a18fd0e22758bcdef53ce23081b6f5f355+-- hash: 5c58d46f05c4691ff9007d7ad6382aa8f3862076ed33d386efb76431b2e1cd18 name: core-text-version: 0.2.2.6+version: 0.2.3.3 synopsis: A rope type based on a finger tree over UTF-8 fragments description: A rope data type for text, built as a finger tree over UTF-8 text fragments. The package also includes utiltiy functions for breaking and@@ -29,7 +29,7 @@ bug-reports: https://github.com/oprdyn/unbeliever/issues author: Andrew Cowie <andrew@operationaldynamics.com> maintainer: Andrew Cowie <andrew@operationaldynamics.com>-copyright: © 2018-2019 Operational Dynamics Consulting Pty Ltd, and Others+copyright: © 2018-2020 Operational Dynamics Consulting Pty Ltd, and Others license: BSD3 license-file: LICENSE tested-with: GHC == 8.6.5@@ -47,6 +47,7 @@ Core.Text.Utilities other-modules: Core.Text.Breaking+ Core.Text.Parsing hs-source-dirs: lib ghc-options: -Wall -Wwarn -fwarn-tabs@@ -56,7 +57,7 @@ , deepseq , fingertree , hashable >=1.2 && <1.4- , prettyprinter >=1.2.1.1 && <1.6+ , prettyprinter >=1.2.1.1 && <1.7 , prettyprinter-ansi-terminal , template-haskell >=2.14 && <3 , text
lib/Core/Text/Breaking.hs view
@@ -8,6 +8,7 @@ , breakPieces , intoPieces , intoChunks+ , isNewline ) where @@ -62,8 +63,13 @@ then fore else result +{-|+Predicate testing whether a character is a newline. After+'Data.Char.isSpace' et al in "Data.Char".+-} isNewline :: Char -> Bool isNewline c = c == '\n'+{-# INLINEABLE isNewline #-} {-| Break a Rope into pieces whereever the given predicate function returns
+ lib/Core/Text/Parsing.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE BangPatterns #-}+{-# OPTIONS_HADDOCK hide #-}++-- This is an Internal module, hidden from Haddock+module Core.Text.Parsing+ ( calculatePositionEnd+ )+where++import Data.Foldable (foldl')+import qualified Data.Text.Short as S (ShortText, foldl')++import Core.Text.Rope++{-|+Calculate the line number and column number of a Rope (interpreting it as+if is a block of text in a file). By the convention observed by all leading+brands of text editor, lines and columns are @1@ origin, so an empty Rope+is position @(1,1)@.+-}+-- Of course, if Rope itself cached position information in the FingerTree+-- monoid this would be trivial.+calculatePositionEnd :: Rope -> (Int,Int)+calculatePositionEnd text =+ let+ x = unRope text+ (l,c) = foldl' calculateChunk (1,1) x+ in+ (l,c)++calculateChunk :: (Int,Int) -> S.ShortText -> (Int,Int)+calculateChunk loc piece =+ S.foldl' f loc piece+ where+ f :: (Int,Int) -> Char -> (Int,Int)+ f !(!l,!c) ch = if ch == '\n'+ then (l+1,1)+ else (l,c+1)
lib/Core/Text/Rope.hs view
@@ -5,6 +5,7 @@ {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE InstanceSigs #-}+{-# LANGUAGE BangPatterns #-} {-# OPTIONS_GHC -fno-warn-orphans #-} {-|@@ -76,10 +77,13 @@ Rope , emptyRope , singletonRope+ , replicateRope+ , replicateChar , widthRope , splitRope , insertRope , containsCharacter+ , findIndexRope {-* Interoperation and Output -} , Textual(fromRope, intoRope, appendRope) , hWrite@@ -110,7 +114,7 @@ import Data.Text.Prettyprint.Doc (Pretty(..), emptyDoc) import qualified Data.Text.Short as S (ShortText, length, any, null , fromText, toText, fromByteString, pack, unpack, singleton- , append, empty, toBuilder, splitAt)+ , append, empty, toBuilder, splitAt, findIndex, replicate) import qualified Data.Text.Short.Unsafe as S (fromByteStringUnsafe) import GHC.Generics (Generic) import System.IO (Handle)@@ -239,7 +243,38 @@ singletonRope :: Char -> Rope singletonRope = Rope . F.singleton . S.singleton + {-|+Repeat the input 'Rope' @n@ times. The follows the same semantics as other+@replicate@ functions; if you ask for zero copies you'll get an empty text+and if you ask for lots of @""@ you'll get ... an empty text.++/Implementation note/++Rather than copying the input /n/ times, this will simply add structure to hold /n/+references to the provided input text.+-}+replicateRope :: Int -> Rope -> Rope+replicateRope count (Rope x) =+ let+ x' = foldr (\ _ acc -> (F.><) x acc) F.empty [1..count]+ in+ Rope x'++{-|+Repeat the input 'Char' @n@ times. This is a special case of+'replicateRope' above.++/Implementation note/++Rather than making a huge FingerTree full of single characters, this+function will allocate a single ShortText comprised of the repeated input+character.+-}+replicateChar :: Int -> Char -> Rope+replicateChar count = Rope . F.singleton . S.replicate count . S.singleton++{-| Get the length of this text, in characters. -} widthRope :: Rope -> Int@@ -311,6 +346,17 @@ (Rope before,Rope after) = splitRope i text in Rope (mconcat [before, new, after])++findIndexRope :: (Char -> Bool) -> Rope -> Maybe Int+findIndexRope predicate = fst . foldl f (Nothing,0) . unRope+ where+ -- convert this to Maybe monad, maybe+ f :: (Maybe Int,Int) -> S.ShortText -> (Maybe Int,Int)+ f acc piece = case acc of+ (Just j,_) -> (Just j,0)+ (Nothing,!i) -> case S.findIndex predicate piece of+ Nothing -> (Nothing,i + S.length piece)+ Just !j -> (Just (i + j),0) -- -- Manual instance to get around the fact that FingerTree doesn't have a
lib/Core/Text/Utilities.hs view
@@ -22,7 +22,9 @@ , breakWords , breakLines , breakPieces+ , isNewline , wrap+ , calculatePositionEnd , underline , leftPadWith , rightPadWith@@ -62,6 +64,7 @@ import Core.Text.Bytes import Core.Text.Breaking+import Core.Text.Parsing import Core.Text.Rope -- change AnsiStyle to a custom token type, perhaps Ansi, which