Rope class
A persistent (immutable-node) B-tree rope indexed in UTF-16 code units.
Design notes
- All offsets and lengths are UTF-16 code units, so they line up with
Flutter's
TextSelection/TextPosition,String.lengthand LSP. Leaf boundaries never split a surrogate pair. Callers must not pass an offset that lands in the middle of a pair. - Nodes are immutable. An edit copies only the O(log n) nodes on the path
and shares the rest, so copy is O(1) and the
*Immutablehelpers cost O(log n). Cheap snapshots make undo history simple. - Every node caches length, newline count and strong RTL/LTR counts, so line seeks and textDirection are O(log n) / O(1).
- Deletes merge underfull siblings so the tree does not degrade.
Only \n counts as a line break. \r before \n is stripped from line
text. Normalise lone \r on load if you need to support old Mac files.
Complexity (n = document length, k = result size): insert/delete/replace O(log n + leaf size) getLineStartOffset etc. O(log n + leaf size) slice / lineRange O(log n + k) getText / lineLengths O(n) (export, save, stats only)
Properties
-
bidiSegments
→ List<
BiDiSegment> -
Direction runs for the whole document. O(n). Prefer
getBiDiSegmentsForLine / getBiDiSegmentsInRange when rendering.
no setter
-
cachedLines
→ List<
String> -
no setter
- containsRtl → bool
-
no setter
- core → Rope
-
no setter
- hashCode → int
-
The hash code for this object.
no setterinherited
- isLtr → bool
-
no setter
- isMixed → bool
-
True when the document has both strong RTL and strong LTR text. O(1).
no setter
- isRtl → bool
-
no setter
- length → int
-
no setter
- lineCount → int
-
no setter
-
lines
→ Iterable<
String> -
Lazily yields lines in batches. Still O(n) if fully consumed.
no setter
- primaryDirection → TextDirection
-
no setter
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- selection → TextSelection
-
no setter
- textDirection → TextDirection
-
no setter
Methods
-
cachedLinesRange(
int startLine, int endLine) → List< String> -
charAt(
int position) → String -
The character at
position. Returns the whole pair for an astral character whose high surrogate sits atposition. -
codeUnitAt(
int position) → int -
UTF-16 code unit at
position, or -1 when out of range. -
concatImmutable(
Rope other) → Rope -
Appends
otherleaf by leaf. Never materialises either document. -
copy(
) → Rope - O(1): nodes are immutable, so the snapshot shares the whole tree.
-
delete(
int start, int end) → void -
deleteImmutable(
int start, int end) → Rope -
findLineEnd(
int offset) → int -
findLineStart(
int offset) → int -
getBiDiSegmentsForLine(
int lineIndex) → List< BiDiSegment> -
getBiDiSegmentsInRange(
int start, int end) → List< BiDiSegment> -
Splits
[start, end)into runs of one strong direction. Neutral characters attach to the run before them (leading neutrals join the first run). Costs O(log n + range length). -
getLineAtOffset(
int charOffset) → int -
getLineStartOffset(
int lineIndex) → int -
getLineText(
int lineIndex) → String -
getRtlSegments(
) → List< (int, int)> -
getText(
) → String - O(n). Use for save/export only, never per keystroke.
-
insert(
int position, String text) → void -
insertImmutable(
int position, String text) → Rope -
lineLengthAt(
int lineIndex) → int -
Length of the line in code units, excluding
\nand a preceding\r. -
lineLengths(
) → List< int> - O(n). Length of every line in code units.
-
lineRange(
int startLine, int endLine) → List< String> -
Lines
[startLine, endLine)fetched with a single slice and split. Use this for viewport rendering, highlighting and gutters. -
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
replace(
int start, int end, String text) → void -
replaceRangeAndUpdateSelection(
{required int start, required int end, required String replacement, required bool preserveOldCursor, required int oldBase, required int oldExtent}) → SelectionState -
Replaces
[start, end)withreplacementand remaps the selection. -
setSelection(
TextSelection value) → void -
slice(
int start, int end) → String -
splitImmutable(
int position) → (Rope, Rope) -
Both halves share structure with this rope.
positionmust not be in the middle of a surrogate pair. -
substring(
int start, [int? end]) → String -
toString(
) → String -
A string representation of this object.
inherited
-
toStringWithBiDiControls(
) → String
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited