core-text 0.3.8.0 → 0.3.8.1
raw patch · 8 files changed
+268/−263 lines, 8 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Core.Text.Utilities: type family Token α :: Type;
+ Core.Text.Utilities: -- expressed in?
+ Core.Text.Utilities: type Token α :: Type;
- Core.Text.Utilities: -- | Which type are the annotations of your Doc going to be expressed in?
+ Core.Text.Utilities: -- | Which type are the annotations of your <a>Doc</a> going to be
Files
- core-text.cabal +4/−4
- lib/Core/Text.hs +25/−24
- lib/Core/Text/Breaking.hs +14/−14
- lib/Core/Text/Bytes.hs +23/−23
- lib/Core/Text/Colour.hs +32/−32
- lib/Core/Text/Parsing.hs +10/−9
- lib/Core/Text/Rope.hs +86/−86
- lib/Core/Text/Utilities.hs +74/−71
core-text.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.18 --- This file has been generated from package.yaml by hpack version 0.34.4.+-- This file has been generated from package.yaml by hpack version 0.35.1. -- -- see: https://github.com/sol/hpack name: core-text-version: 0.3.8.0+version: 0.3.8.1 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@@ -27,12 +27,12 @@ bug-reports: https://github.com/aesiniath/unbeliever/issues author: Andrew Cowie <istathar@gmail.com> maintainer: Andrew Cowie <istathar@gmail.com>-copyright: © 2018-2022 Athae Eredh Siniath and Others+copyright: © 2018-2023 Athae Eredh Siniath and Others license: MIT license-file: LICENSE build-type: Simple tested-with:- GHC == 8.10.7+ GHC == 8.10.7, GHC == 9.2.5 extra-doc-files: AnsiColours.png
lib/Core/Text.hs view
@@ -1,33 +1,34 @@ {-# OPTIONS_HADDOCK not-home #-} --- |--- A unified Text type providing interoperability between various text--- back-ends present in the Haskell ecosystem.------ This is intended to be used directly:------ @--- import "Core.Text"--- @------ as this module re-exports all of the various components making up this--- library's text handling subsystem.+{- |+A unified Text type providing interoperability between various text+back-ends present in the Haskell ecosystem.++This is intended to be used directly:++@+import "Core.Text"+@++as this module re-exports all of the various components making up this+library's text handling subsystem.+-} module Core.Text- ( -- * Internal representation+ ( -- * Internal representation - -- |- -- Exposes 'Bytes', a wrapper around different types of binary data, and 'Rope',- -- a finger-tree over buffers containing text.- module Core.Text.Bytes,- module Core.Text.Rope,+ -- |+ -- Exposes 'Bytes', a wrapper around different types of binary data, and 'Rope',+ -- a finger-tree over buffers containing text.+ module Core.Text.Bytes+ , module Core.Text.Rope - -- * Useful utilities+ -- * Useful utilities - -- |- -- Useful functions for common use cases.- module Core.Text.Colour,- module Core.Text.Utilities,- )+ -- |+ -- Useful functions for common use cases.+ , module Core.Text.Colour+ , module Core.Text.Utilities+ ) where import Core.Text.Bytes
lib/Core/Text/Breaking.hs view
@@ -2,15 +2,15 @@ {-# OPTIONS_HADDOCK hide #-} -- This is an Internal module, hidden from Haddock-module Core.Text.Breaking (- breakRope,- breakWords,- breakLines,- breakPieces,- intoPieces,- intoChunks,- isNewline,-) where+module Core.Text.Breaking+ ( breakRope+ , breakWords+ , breakLines+ , breakPieces+ , intoPieces+ , intoChunks+ , isNewline+ ) where import Core.Text.Rope import Data.Char (isSpace)@@ -53,7 +53,7 @@ let result = breakPieces isNewline text n = length result - 1 (fore, aft) = splitAt n result- in case result of+ in case result of [] -> [] [p] -> [p] _ ->@@ -78,7 +78,7 @@ breakPieces predicate text = let x = unRope text (final, result) = foldr (intoPieces predicate) (Nothing, []) x- in case final of+ in case final of Nothing -> result Just piece -> intoRope piece : result @@ -94,7 +94,7 @@ Nothing -> piece Just previous -> piece <> previous -- more rope, less text? pieces = intoChunks predicate piece'- in case uncons pieces of+ in case uncons pieces of Nothing -> (Nothing, list) Just (text, remainder) -> (Just (fromRope text), remainder ++ list) @@ -140,7 +140,7 @@ if S.null remaining then (predicate c, S.empty) else (False, remaining)- in if trailing+ in if trailing then intoRope chunk : emptyRope : [] else intoRope chunk : intoChunks predicate remainder' @@ -161,6 +161,6 @@ breakRope :: (Char -> Bool) -> Rope -> (Rope, Rope) breakRope predicate text = let possibleIndex = findIndexRope predicate text- in case possibleIndex of+ in case possibleIndex of Nothing -> (text, emptyRope) Just i -> splitRope i text
lib/Core/Text/Bytes.hs view
@@ -23,30 +23,30 @@ data to make it easier to interoperate with libraries supplying or consuming bytes. -}-module Core.Text.Bytes (- Bytes,- emptyBytes,- packBytes,- Binary (fromBytes, intoBytes),- hOutput,- hInput,+module Core.Text.Bytes+ ( Bytes+ , emptyBytes+ , packBytes+ , Binary (fromBytes, intoBytes)+ , hOutput+ , hInput - -- * Internals- unBytes,-) where+ -- * Internals+ , unBytes+ ) where -import qualified Data.ByteString as B (- ByteString,- empty,- hGetContents,- hPut,- pack,- unpack,- )+import qualified Data.ByteString as B+ ( ByteString+ , empty+ , hGetContents+ , hPut+ , pack+ , unpack+ ) import qualified Data.ByteString.Builder as B (Builder, byteString, toLazyByteString)-import qualified Data.ByteString.Char8 as C (- pack- )+import qualified Data.ByteString.Char8 as C+ ( pack+ ) import qualified Data.ByteString.Lazy as L (ByteString, fromStrict, toStrict) import Data.Hashable (Hashable) import Data.Word (Word8)@@ -135,7 +135,7 @@ hOutput h b @ -'Core.Program.Execute.output' provides a convenient way to write a @Bytes@ to+'Core.Program.Execute.outputEntire' provides a convenient way to write a @Bytes@ to a file or socket handle from within the 'Core.Program.Execute.Program' monad. Don't use this function to write to @stdout@ if you are using any of the other@@ -143,7 +143,7 @@ ordering of output on the user's terminal. Instead do: @- 'Core.Program.Execute.write' ('Core.Text.Rope.intoRope' b)+ 'Core.Program.Logging.write' ('Core.Text.Rope.intoRope' b) @ on the assumption that the bytes in question are UTF-8 (or plain ASCII)
lib/Core/Text/Colour.hs view
@@ -7,37 +7,37 @@  -}-module Core.Text.Colour (- AnsiColour,- intoEscapes,- boldColour,- dullRed,- brightRed,- pureRed,- dullGreen,- brightGreen,- pureGreen,- dullBlue,- brightBlue,- pureBlue,- dullCyan,- brightCyan,- pureCyan,- dullMagenta,- brightMagenta,- pureMagenta,- dullYellow,- brightYellow,- pureYellow,- pureBlack,- dullGrey,- brightGrey,- pureGrey,- pureWhite,- dullWhite,- brightWhite,- resetColour,-) where+module Core.Text.Colour+ ( AnsiColour+ , intoEscapes+ , boldColour+ , dullRed+ , brightRed+ , pureRed+ , dullGreen+ , brightGreen+ , pureGreen+ , dullBlue+ , brightBlue+ , pureBlue+ , dullCyan+ , brightCyan+ , pureCyan+ , dullMagenta+ , brightMagenta+ , pureMagenta+ , dullYellow+ , brightYellow+ , pureYellow+ , pureBlack+ , dullGrey+ , brightGrey+ , pureGrey+ , pureWhite+ , dullWhite+ , brightWhite+ , resetColour+ ) where import Core.Text.Rope import Data.Colour.SRGB (sRGB, sRGB24read)@@ -50,7 +50,7 @@ -} newtype AnsiColour = Escapes [SGR] -{-|+{- | Convert an AnsiColour into the ANSI escape sequences which will make that colour appear in the user's terminal. -}
lib/Core/Text/Parsing.hs view
@@ -4,8 +4,8 @@ -- This is an Internal module, hidden from Haddock module Core.Text.Parsing- ( calculatePositionEnd,- )+ ( calculatePositionEnd+ ) where import Core.Text.Rope@@ -18,20 +18,21 @@ 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)+ 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+ 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)+ if ch == '\n'+ then (l + 1, 1)+ else (l, c + 1)
lib/Core/Text/Rope.hs view
@@ -73,94 +73,94 @@ of) small pieces, and then efficiently taking the resultant text object out to a file handle, be that the terminal console, a file, or a network socket. -}-module Core.Text.Rope (- -- * Rope type- Rope,- emptyRope,- singletonRope,- packRope,- replicateRope,- replicateChar,- widthRope,- unconsRope,- splitRope,- takeRope,- insertRope,- containsCharacter,- findIndexRope,+module Core.Text.Rope+ ( -- * Rope type+ Rope+ , emptyRope+ , singletonRope+ , packRope+ , replicateRope+ , replicateChar+ , widthRope+ , unconsRope+ , splitRope+ , takeRope+ , insertRope+ , containsCharacter+ , findIndexRope - -- * Interoperation and Output- Textual (fromRope, intoRope, appendRope),- hWrite,+ -- * Interoperation and Output+ , Textual (fromRope, intoRope, appendRope)+ , hWrite - -- * Internals- unRope,- nullRope,- unsafeIntoRope,- copyRope,- Width (..),-) where+ -- * Internals+ , unRope+ , nullRope+ , unsafeIntoRope+ , copyRope+ , Width (..)+ ) where import Control.DeepSeq (NFData (..)) import Core.Text.Bytes import Data.ByteString qualified as B (ByteString)-import Data.ByteString.Builder qualified as B (- Builder,- hPutBuilder,- toLazyByteString,- )-import Data.ByteString.Lazy qualified as L (- ByteString,- foldrChunks,- toStrict,- )-import Data.FingerTree qualified as F (- FingerTree,- Measured (..),- SearchResult (..),- ViewL (..),- empty,- null,- search,- singleton,- viewl,- (<|),- (><),- (|>),- )+import Data.ByteString.Builder qualified as B+ ( Builder+ , hPutBuilder+ , toLazyByteString+ )+import Data.ByteString.Lazy qualified as L+ ( ByteString+ , foldrChunks+ , toStrict+ )+import Data.FingerTree qualified as F+ ( FingerTree+ , Measured (..)+ , SearchResult (..)+ , ViewL (..)+ , empty+ , null+ , search+ , singleton+ , viewl+ , (<|)+ , (><)+ , (|>)+ ) import Data.Foldable (foldl', toList) import Data.Hashable (Hashable, hashWithSalt) import Data.String (IsString (..)) import Data.Text qualified as T (Text)-import Data.Text.Lazy qualified as U (- Text,- foldrChunks,- fromChunks,- toStrict,- )-import Data.Text.Lazy.Builder qualified as U (- Builder,- fromText,- toLazyText,- )-import Data.Text.Short qualified as S (- ShortText,- any,- append,- empty,- findIndex,- fromByteString,- fromText,- length,- pack,- replicate,- singleton,- splitAt,- toBuilder,- toText,- uncons,- unpack,- )+import Data.Text.Lazy qualified as U+ ( Text+ , foldrChunks+ , fromChunks+ , toStrict+ )+import Data.Text.Lazy.Builder qualified as U+ ( Builder+ , fromText+ , toLazyText+ )+import Data.Text.Short qualified as S+ ( ShortText+ , any+ , append+ , empty+ , findIndex+ , fromByteString+ , fromText+ , length+ , pack+ , replicate+ , singleton+ , splitAt+ , toBuilder+ , toText+ , uncons+ , unpack+ ) import Data.Text.Short.Unsafe qualified as S (fromByteStringUnsafe) import GHC.Generics (Generic) import Prettyprinter (Pretty (..), emptyDoc)@@ -310,7 +310,7 @@ replicateRope :: Int -> Rope -> Rope replicateRope count (Rope x) = let x' = foldr (\_ acc -> (F.><) x acc) F.empty [1 .. count]- in Rope x'+ in Rope x' {- | Repeat the input 'Char' @n@ times. This is a special case of 'replicateRope'@@ -331,7 +331,7 @@ widthRope text = let x = unRope text (Width w) = F.measure x- in w+ in w nullRope :: Rope -> Bool nullRope text = widthRope text == 0@@ -346,7 +346,7 @@ unconsRope :: Rope -> Maybe (Char, Rope) unconsRope text = let x = unRope text- in case F.viewl x of+ in case F.viewl x of F.EmptyL -> Nothing (F.:<) piece x' -> case S.uncons piece of@@ -380,11 +380,11 @@ splitRope i text@(Rope x) = let pos = Width i result = F.search (\w1 _ -> w1 >= pos) x- in case result of+ in case result of F.Position before piece after -> let (Width w) = F.measure before (one, two) = S.splitAt (i - w) piece- in (Rope ((F.|>) before one), Rope ((F.<|) two after))+ in (Rope ((F.|>) before one), Rope ((F.<|) two after)) F.OnLeft -> (Rope F.empty, text) F.OnRight -> (text, Rope F.empty) F.Nowhere -> error "Position not found in split. Probable cause: predicate function given not monotonic. This is supposed to be unreachable"@@ -400,7 +400,7 @@ takeRope :: Int -> Rope -> Rope takeRope i text = let (before, _) = splitRope i text- in before+ in before {- | Insert a new piece of text into an existing @Rope@ at the specified offset.@@ -418,7 +418,7 @@ insertRope 0 (Rope new) (Rope x) = Rope ((F.><) new x) insertRope i (Rope new) text = let (Rope before, Rope after) = splitRope i text- in Rope (mconcat [before, new, after])+ in Rope (mconcat [before, new, after]) findIndexRope :: (Char -> Bool) -> Rope -> Maybe Int findIndexRope predicate = fst . foldl f (Nothing, 0) . unRope@@ -449,7 +449,7 @@ piece = case F.viewl x' of F.EmptyL -> S.empty (F.:<) first _ -> first- in hashWithSalt salt piece+ in hashWithSalt salt piece {- | Copy the pieces underlying a 'Rope' into a single piece object.
lib/Core/Text/Utilities.hs view
@@ -13,39 +13,39 @@ Useful tools for working with 'Rope's. Support for pretty printing, multi-line strings, and... -}-module Core.Text.Utilities (- -- * Pretty printing- Render (..),- render,- renderNoAnsi,+module Core.Text.Utilities+ ( -- * Pretty printing+ Render (..)+ , render+ , renderNoAnsi - -- * Helpers- indefinite,- oxford,- breakRope,- breakWords,- breakLines,- breakPieces,- isNewline,- wrap,- calculatePositionEnd,- underline,- leftPadWith,- rightPadWith,+ -- * Helpers+ , indefinite+ , oxford+ , breakRope+ , breakWords+ , breakLines+ , breakPieces+ , isNewline+ , wrap+ , calculatePositionEnd+ , underline+ , leftPadWith+ , rightPadWith - -- * Multi-line strings- quote,+ -- * Multi-line strings+ , quote -- for testing- intoPieces,- intoChunks,- byteChunk,+ , intoPieces+ , intoChunks+ , byteChunk - -- * Deprecated- intoDocA,- module Core.Text.Colour,- bold,- -- | AnsiColour and colour constants moved to this module.-) where+ -- * Deprecated+ , intoDocA+ , module Core.Text.Colour+ , bold+ -- | AnsiColour and colour constants moved to this module.+ ) where import Core.Text.Breaking import Core.Text.Bytes@@ -59,48 +59,46 @@ import Data.Kind (Type) import Data.List qualified as List (dropWhileEnd, foldl', splitAt) import Data.Text qualified as T-import Data.Text.Short qualified as S (- ShortText,- replicate,- singleton,- toText,- uncons,- )+import Data.Text.Short qualified as S+ ( ShortText+ , replicate+ , singleton+ , toText+ , uncons+ ) import Data.Word (Word8) import Language.Haskell.TH (litE, stringL) import Language.Haskell.TH.Quote (QuasiQuoter (QuasiQuoter))-import Prettyprinter (- Doc,- LayoutOptions (LayoutOptions),- PageWidth (AvailablePerLine),- Pretty (..),- SimpleDocStream (..),- annotate,- emptyDoc,- flatAlt,- group,- hsep,- layoutPretty,- pretty,- reAnnotateS,- softline',- unAnnotateS,- vcat,- )+import Prettyprinter+ ( Doc+ , LayoutOptions (LayoutOptions)+ , PageWidth (AvailablePerLine)+ , Pretty (..)+ , SimpleDocStream (..)+ , annotate+ , emptyDoc+ , flatAlt+ , group+ , hsep+ , layoutPretty+ , pretty+ , reAnnotateS+ , softline'+ , unAnnotateS+ , vcat+ ) import Prettyprinter.Render.Text (renderLazy) {- | Types which can be rendered "prettily", that is, formatted by a pretty printer and embossed with beautiful ANSI colours when printed to the terminal. -Use 'render' to build text object for later use or-<https://hackage.haskell.org/package/core-program/docs/Core-Program-Logging.html-Control.Program.Logging>'s-<https://hackage.haskell.org/package/core-program/docs/Core-Program-Logging.html#v:writeR-writeR> if you're writing directly to console now.+Use 'render' to build text object for later use, or+"Control.Program.Logging"'s 'Core.Program.Logging.writeR' if you're writing+directly to console now. -} class Render α where- -- | Which type are the annotations of your Doc going to be expressed in?+ -- | Which type are the annotations of your 'Doc' going to be expressed in? type Token α :: Type -- | Convert semantic tokens to specific ANSI escape tokens@@ -155,7 +153,9 @@ prettyBytes :: Bytes -> Doc () prettyBytes =- annotate () . vcat . twoWords+ annotate ()+ . vcat+ . twoWords . fmap wordToHex . byteChunk . unBytes@@ -175,7 +175,7 @@ where go acc blob = let (eight, remainder) = B.splitAt 8 blob- in if B.length remainder == 0+ in if B.length remainder == 0 then eight : acc else go (eight : acc) remainder @@ -184,7 +184,7 @@ wordToHex eight = let ws = B.unpack eight ds = fmap byteToHex ws- in hsep ds+ in hsep ds byteToHex :: Word8 -> Doc ann byteToHex c = pretty hi <> pretty low@@ -204,13 +204,13 @@ Rope to console with: @- 'Core.Program.Execute.write' ('render' 80 thing)+ 'Core.Program.Logging.write' ('render' 80 thing) @ However, the /better/ thing to do is to instead use: @- 'Core.Program.Execute.writeR' thing+ 'Core.Program.Logging.writeR' thing @ which is able to pretty print the document text respecting the available width@@ -224,7 +224,8 @@ render :: Render α => Int -> α -> Rope render columns (thing :: α) = let options = LayoutOptions (AvailablePerLine (columns - 1) 1.0)- in go [] . reAnnotateS (colourize @α)+ in go []+ . reAnnotateS (colourize @α) . layoutPretty options . highlight $ thing@@ -268,7 +269,9 @@ renderNoAnsi :: Render α => Int -> α -> Rope renderNoAnsi columns (thing :: α) = let options = LayoutOptions (AvailablePerLine (columns - 1) 1.0)- in intoRope . renderLazy . unAnnotateS+ in intoRope+ . renderLazy+ . unAnnotateS . layoutPretty options . highlight $ thing@@ -282,7 +285,7 @@ indefinite :: Rope -> Rope indefinite text = let x = unRope text- in case F.viewl x of+ in case F.viewl x of F.EmptyL -> text piece F.:< _ -> case S.uncons piece of Nothing -> text@@ -341,7 +344,7 @@ wrap :: Int -> Rope -> Rope wrap margin text = let built = wrapHelper margin (breakWords text)- in built+ in built wrapHelper :: Int -> [Rope] -> Rope wrapHelper _ [] = ""@@ -353,7 +356,7 @@ wrapLine margin (pos, builder) word = let wide = widthRope word wide' = pos + wide + 1- in if wide' > margin+ in if wide' > margin then (wide, builder <> "\n" <> word) else (wide', builder <> " " <> word) @@ -361,7 +364,7 @@ underline level text = let title = fromRope text line = T.map (\_ -> level) title- in intoRope line+ in intoRope line {- | Pad a piece of text on the left with a specified character to the desired