core-text 0.3.5.0 → 0.3.7.0
raw patch · 4 files changed
+80/−16 lines, 4 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Core.Text.Rope: copyRope :: Rope -> Rope
+ Core.Text.Rope: unconsRope :: Rope -> Maybe (Char, Rope)
+ Core.Text.Utilities: breakRope :: (Char -> Bool) -> Rope -> (Rope, Rope)
- Core.Text.Utilities: type family Token α :: *;
+ Core.Text.Utilities: type family Token α :: Type;
Files
- core-text.cabal +3/−3
- lib/Core/Text/Breaking.hs +22/−0
- lib/Core/Text/Rope.hs +51/−11
- lib/Core/Text/Utilities.hs +4/−2
core-text.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: core-text-version: 0.3.5.0+version: 0.3.7.0 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@@ -22,12 +22,12 @@ <https://github.com/aesiniath/unbeliever/blob/master/README.markdown README> on GitHub. category: System-stability: experimental+stability: stable homepage: https://github.com/aesiniath/unbeliever#readme bug-reports: https://github.com/aesiniath/unbeliever/issues author: Andrew Cowie <istathar@gmail.com> maintainer: Andrew Cowie <istathar@gmail.com>-copyright: © 2018-2021 Athae Eredh Siniath and Others+copyright: © 2018-2022 Athae Eredh Siniath and Others license: MIT license-file: LICENSE build-type: Simple
lib/Core/Text/Breaking.hs view
@@ -3,6 +3,7 @@ -- This is an Internal module, hidden from Haddock module Core.Text.Breaking (+ breakRope, breakWords, breakLines, breakPieces,@@ -142,3 +143,24 @@ in if trailing then intoRope chunk : emptyRope : [] else intoRope chunk : intoChunks predicate remainder'++{-+The utilities breakPieces and its helpers above were written long before this+code. The special purpose functions above might have been written more easily+if this below had been written first, but they _are_ special cases and they're+done, so {shrug} if someone wants to unify these go right head, otherwise this+can stand as almost but not-quite repetition.+-}++{- |+Given a piece of 'Rope' and a predicate, break the text into two pieces at the first+site where that predicate returns 'True'.++@since 0.3.7+-}+breakRope :: (Char -> Bool) -> Rope -> (Rope, Rope)+breakRope predicate text =+ let possibleIndex = findIndexRope predicate text+ in case possibleIndex of+ Nothing -> (text, emptyRope)+ Just i -> splitRope i text
lib/Core/Text/Rope.hs view
@@ -79,6 +79,7 @@ replicateRope, replicateChar, widthRope,+ unconsRope, splitRope, takeRope, insertRope,@@ -93,6 +94,7 @@ unRope, nullRope, unsafeIntoRope,+ copyRope, Width (..), ) where @@ -137,7 +139,6 @@ fromText, toLazyText, )-import Prettyprinter (Pretty (..), emptyDoc) import qualified Data.Text.Short as S ( ShortText, any,@@ -154,10 +155,11 @@ splitAt, toBuilder, toText,- unpack,+ unpack, uncons ) import qualified Data.Text.Short.Unsafe as S (fromByteStringUnsafe) import GHC.Generics (Generic)+import Prettyprinter (Pretty (..), emptyDoc) import System.IO (Handle) {- |@@ -291,7 +293,6 @@ packRope :: String -> Rope packRope xs = Rope . F.singleton . S.pack $ xs - {- | 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@@ -333,6 +334,24 @@ (F.:<) piece _ -> S.null piece {- |+Read the first character from a 'Rope', assuming it's length 1 or greater,+returning 'Just' that character and the remainder of the text. Returns+'Nothing' if the input is 0 length.++@since 0.3.7+-}+unconsRope :: Rope -> Maybe (Char, Rope)+unconsRope text =+ let x = unRope text+ in case F.viewl x of+ F.EmptyL -> Nothing+ (F.:<) piece x' ->+ case S.uncons piece of+ Nothing -> Nothing+ Just (c, piece') -> Just (c, Rope ((F.<|) piece' x'))+++{- | Break the text into two pieces at the specified offset. Examples:@@ -423,12 +442,36 @@ -- corresponding tree. -- instance Hashable Rope where- hashWithSalt salt (Rope x) = foldl' f salt x- where- f :: Int -> S.ShortText -> Int- f num piece = hashWithSalt num piece+ hashWithSalt salt text =+ let (Rope x') = copyRope text+ piece = case F.viewl x' of+ F.EmptyL -> S.empty+ (F.:<) first _ -> first+ in hashWithSalt salt piece {- |+Copy the pieces underlying a 'Rope' into a single piece object.++/Warning/++This function was necessary to have a reliable 'Hashable' instance. Currently+constructing this new @Rope@ is quite inefficient if the number of pieces or+their respective lengths are large. Usually, however, we're calling 'hash' so+the value can be used as a key in a hash table and such keys are typically+simple (or at least not ridiculously long), so this is not an issue in normal+usage.+-}+copyRope :: Rope -> Rope+copyRope text@(Rope x) =+ case F.viewl x of+ F.EmptyL -> text+ (F.:<) _ x' -> case F.viewl x' of+ F.EmptyL -> text+ -- TODO replace this with a function that allocates a ByteArray#+ -- of the appropriate length then copies the pieces in+ _ -> Rope (F.singleton (foldl' S.append S.empty x))++{- | Machinery to interpret a type as containing valid Unicode that can be represented as a @Rope@ object. @@ -457,10 +500,7 @@ -- | Take another text-like type and convert it to a @Rope@. intoRope :: α -> Rope - -- | Append some text to this @Rope@. The default implementation is- -- basically a convenience wrapper around calling 'intoRope' and- -- 'mappend'ing it to your text (which will work just fine, but for some- -- types more efficient implementations are possible).+ -- | Append some text to this @Rope@. The default implementation is basically a convenience wrapper around calling 'intoRope' and 'mappend'ing it to your text (which will work just fine, but for some types more efficient implementations are possible). appendRope :: α -> Rope -> Rope appendRope thing text = text <> intoRope thing
lib/Core/Text/Utilities.hs view
@@ -21,6 +21,7 @@ -- * Helpers indefinite, oxford,+ breakRope, breakWords, breakLines, breakPieces,@@ -54,6 +55,7 @@ import qualified Data.ByteString as B (ByteString, length, splitAt, unpack) import Data.Char (intToDigit) import qualified Data.FingerTree as F (ViewL (..), viewl, (<|))+import Data.Kind (Type) import qualified Data.List as List (dropWhileEnd, foldl', splitAt) import qualified Data.Text as T import qualified Data.Text.Short as S (@@ -98,7 +100,7 @@ -} class Render α where -- | Which type are the annotations of your Doc going to be expressed in?- type Token α :: *+ type Token α :: Type -- | Convert semantic tokens to specific ANSI escape tokens colourize :: Token α -> AnsiColour@@ -291,7 +293,7 @@ {- | Given a list of items (one word per Rope in the list) enumerate them with commas and-an oxford comma before the last item. As you'd expect:+an Oxford comma before the last item. As you'd expect: @ λ> __oxford ["one", "two", "three"]__