Copyright | (c) 2021-2022 Andrew Lelechenko |
---|---|
License | BSD3 |
Maintainer | Andrew Lelechenko <andrew.lelechenko@gmail.com> |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
Since: 0.3
Synopsis
- data Rope
- fromText :: Text -> Rope
- fromTextLines :: TextLines -> Rope
- toText :: Rope -> Text
- toTextLines :: Rope -> TextLines
- null :: Rope -> Bool
- lines :: Rope -> [Text]
- lengthInLines :: Rope -> Word
- splitAtLine :: Word -> Rope -> (Rope, Rope)
- getLine :: Word -> Rope -> Rope
- charLength :: Rope -> Word
- charSplitAt :: Word -> Rope -> (Rope, Rope)
- charLengthAsPosition :: Rope -> Position
- charSplitAtPosition :: Position -> Rope -> (Rope, Rope)
- utf16Length :: Rope -> Word
- utf16SplitAt :: Word -> Rope -> Maybe (Rope, Rope)
- utf16LengthAsPosition :: Rope -> Position
- utf16SplitAtPosition :: Position -> Rope -> Maybe (Rope, Rope)
- utf8Length :: Rope -> Word
- utf8SplitAt :: Word -> Rope -> Maybe (Rope, Rope)
- utf8LengthAsPosition :: Rope -> Position
- utf8SplitAtPosition :: Position -> Rope -> Maybe (Rope, Rope)
Documentation
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.
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
.