text-rope-0.3: Text lines and ropes
Copyright(c) 2021-2022 Andrew Lelechenko
LicenseBSD3
MaintainerAndrew Lelechenko <andrew.lelechenko@gmail.com>
Safe HaskellSafe-Inferred
LanguageHaskell2010

Data.Text.Mixed.Rope

Description

Since: 0.3

Synopsis

Documentation

data Rope Source #

Rope of Text chunks with logarithmic concatenation. This rope offers three interfaces: one based on code points, one based on UTF-16 code units, and one based on UTF-8 code units. This comes with a price of more bookkeeping and is less performant than Data.Text.Rope, Data.Text.Utf8.Rope, or Data.Text.Utf16.Rope.

Instances

Instances details
IsString Rope Source # 
Instance details

Defined in Data.Text.Mixed.Rope

Methods

fromString :: String -> Rope #

Monoid Rope Source # 
Instance details

Defined in Data.Text.Mixed.Rope

Methods

mempty :: Rope #

mappend :: Rope -> Rope -> Rope #

mconcat :: [Rope] -> Rope #

Semigroup Rope Source # 
Instance details

Defined in Data.Text.Mixed.Rope

Methods

(<>) :: Rope -> Rope -> Rope #

sconcat :: NonEmpty Rope -> Rope #

stimes :: Integral b => b -> Rope -> Rope #

Show Rope Source # 
Instance details

Defined in Data.Text.Mixed.Rope

Methods

showsPrec :: Int -> Rope -> ShowS #

show :: Rope -> String #

showList :: [Rope] -> ShowS #

NFData Rope Source # 
Instance details

Defined in Data.Text.Mixed.Rope

Methods

rnf :: Rope -> () #

Eq Rope Source # 
Instance details

Defined in Data.Text.Mixed.Rope

Methods

(==) :: Rope -> Rope -> Bool #

(/=) :: Rope -> Rope -> Bool #

Ord Rope Source # 
Instance details

Defined in Data.Text.Mixed.Rope

Methods

compare :: Rope -> Rope -> Ordering #

(<) :: Rope -> Rope -> Bool #

(<=) :: Rope -> Rope -> Bool #

(>) :: Rope -> Rope -> Bool #

(>=) :: Rope -> Rope -> Bool #

max :: Rope -> Rope -> Rope #

min :: Rope -> Rope -> Rope #

fromText :: Text -> Rope Source #

Create from Text, linear time.

fromTextLines :: TextLines -> Rope Source #

Create from TextLines, linear time.

toText :: Rope -> Text Source #

Glue chunks into Text, linear time.

toTextLines :: Rope -> TextLines Source #

Glue chunks into TextLines, linear time.

null :: Rope -> Bool Source #

Check whether a rope is empty, O(1).

Lines

lines :: Rope -> [Text] Source #

Split into lines by \n, similar to Data.Text.lines. Each line is produced in O(1).

>>> :set -XOverloadedStrings
>>> lines ""
[]
>>> lines "foo"
["foo"]
>>> lines "foo\n"
["foo"]
>>> lines "foo\n\n"
["foo",""]
>>> lines "foo\nbar"
["foo","bar"]

lengthInLines :: Rope -> Word Source #

Equivalent to length . lines, but in logarithmic time.

>>> :set -XOverloadedStrings
>>> lengthInLines ""
0
>>> lengthInLines "foo"
1
>>> lengthInLines "foo\n"
1
>>> lengthInLines "foo\n\n"
2
>>> lengthInLines "foo\nbar"
2

If you do not care about ignoring the last newline character, you can use posLine . charLengthAsPosition instead, which works in O(1).

splitAtLine :: Word -> Rope -> (Rope, Rope) Source #

Split at given line, logarithmic time.

>>> :set -XOverloadedStrings
>>> map (\l -> splitAtLine l "foo\nbar") [0..3]
[("","foo\nbar"),("foo\n","bar"),("foo\nbar",""),("foo\nbar","")]

getLine :: Word -> Rope -> Rope Source #

Get a line by its 0-based index. Returns mempty if the index is out of bounds. The result doesn't contain \n characters.

>>> :set -XOverloadedStrings
>>> map (\l -> getLine l "foo\nbar\n😊😊\n\n") [0..3]
["foo","bar","😊😊",""]

Since: 0.3

Code points

charLength :: Rope -> Word Source #

Length in code points, similar to Data.Text.length, O(1).

>>> :set -XOverloadedStrings
>>> charLength "fя𐀀"
3

charSplitAt :: Word -> Rope -> (Rope, Rope) Source #

Split at given code point, similar to Data.Text.splitAt. Takes linear time.

>>> :set -XOverloadedStrings
>>> map (\c -> charSplitAt c "fя𐀀") [0..4]
[("","fя𐀀"),("f","я𐀀"),("fя","𐀀"),("fя𐀀",""),("fя𐀀","")]

charLengthAsPosition :: Rope -> Position Source #

Measure text length as an amount of lines and columns. Time is linear in the length of the last line.

>>> :set -XOverloadedStrings
>>> charLengthAsPosition "f𐀀"
Position {posLine = 0, posColumn = 2}
>>> charLengthAsPosition "f\n𐀀"
Position {posLine = 1, posColumn = 1}
>>> charLengthAsPosition "f\n𐀀\n"
Position {posLine = 2, posColumn = 0}

charSplitAtPosition :: Position -> Rope -> (Rope, Rope) Source #

Combination of splitAtLine and subsequent charSplitAt. Time is linear in posColumn and logarithmic in posLine.

>>> :set -XOverloadedStrings
>>> charSplitAtPosition (Position 1 0) "f\n𐀀я"
("f\n","𐀀я")
>>> charSplitAtPosition (Position 1 1) "f\n𐀀я"
("f\n𐀀","я")
>>> charSplitAtPosition (Position 1 2) "f\n𐀀я"
("f\n𐀀я","")
>>> charSplitAtPosition (Position 0 2) "f\n𐀀я"
("f\n","𐀀я")
>>> charSplitAtPosition (Position 0 3) "f\n𐀀я"
("f\n𐀀","я")
>>> charSplitAtPosition (Position 0 4) "f\n𐀀я"
("f\n𐀀я","")

UTF-16 code units

utf16Length :: Rope -> Word Source #

Length in UTF-16 code units, O(1).

>>> :set -XOverloadedStrings
>>> utf16Length "fя𐀀"
4

utf16SplitAt :: Word -> Rope -> Maybe (Rope, Rope) Source #

Split at given UTF-16 code unit. If requested number of code units splits a code point in half, return Nothing. Takes linear time.

>>> :set -XOverloadedStrings
>>> map (\c -> utf16SplitAt c "fя𐀀") [0..4]
[Just ("","fя𐀀"),Just ("f","я𐀀"),Just ("fя","𐀀"),Nothing,Just ("fя𐀀","")]

utf16LengthAsPosition :: Rope -> Position Source #

Measure text length as an amount of lines and columns. Time is linear in the length of the last line.

>>> :set -XOverloadedStrings
>>> utf16LengthAsPosition "f𐀀"
Position {posLine = 0, posColumn = 3}
>>> utf16LengthAsPosition "f\n𐀀"
Position {posLine = 1, posColumn = 2}
>>> utf16LengthAsPosition "f\n𐀀\n"
Position {posLine = 2, posColumn = 0}

utf16SplitAtPosition :: Position -> Rope -> Maybe (Rope, Rope) Source #

Combination of splitAtLine and subsequent utf16SplitAt. Time is linear in posColumn and logarithmic in posLine.

>>> :set -XOverloadedStrings
>>> utf16SplitAtPosition (Position 1 0) "f\n𐀀я"
Just ("f\n","𐀀я")
>>> utf16SplitAtPosition (Position 1 1) "f\n𐀀я"
Nothing
>>> utf16SplitAtPosition (Position 1 2) "f\n𐀀я"
Just ("f\n𐀀","я")
>>> utf16SplitAtPosition (Position 0 2) "f\n𐀀я"
Just ("f\n","𐀀я")
>>> utf16SplitAtPosition (Position 0 3) "f\n𐀀я"
Nothing
>>> utf16SplitAtPosition (Position 0 4) "f\n𐀀я"
Just ("f\n𐀀","я")

UTF-8 code units

utf8Length :: Rope -> Word Source #

Length in UTF-8 code units aka bytes, O(1).

>>> :set -XOverloadedStrings
>>> utf8Length "fя𐀀"
4

utf8SplitAt :: Word -> Rope -> Maybe (Rope, Rope) Source #

Split at given UTF-8 code unit aka byte. If requested number of code units splits a code point in half, return Nothing. Takes linear time.

utf8LengthAsPosition :: Rope -> Position Source #

Measure text length as an amount of lines and columns. Time is linear in the length of the last line.

utf8SplitAtPosition :: Position -> Rope -> Maybe (Rope, Rope) Source #

Combination of splitAtLine and subsequent utf8SplitAt. Time is linear in posColumn and logarithmic in posLine.