struct TextEdit
Swift
struct TextEdit
One reversible edit: replace a range of the buffer with new text.
Offsets are UTF-8 byte offsets, not String.Index and not characters.
Indices are invalidated by the very mutation being recorded, so they cannot
survive in a history — but the choice between bytes and characters is a
performance one, and it is the difference between a usable editor and an
unusable one on a large file.
A character offset costs String.distance(from: startIndex, to:) to
produce and the same to consume: a full grapheme-break walk of everything
before the edit. Recording one keystroke needs three of them (the edit
position, the anchor, the focus) and restoring the caret needs a fourth, so
typing at the end of a 10 MB buffer cost ~64 ms per keypress. A UTF-8
offset is O(1) in both directions — String.Index stores the encoded byte
offset, so producing one is a subtraction.
Bytes are no less grapheme-correct here, because every offset stored is
produced from a real String.Index, which is always on a character
boundary. Converting back snaps down (see index(atUTF8Offset:)) so a
buffer edited into a different shape can never leave a caret inside a
"\r\n" or a ZWJ sequence.
Sources/LavaText/TextEdit.swift:24
Constructors
init(offset: Int, removed: String, inserted: String, anchorBefore: Int, focusBefore: Int)
Not documented.
Sources/LavaText/TextEdit.swift:36
Properties
var anchorBefore: Int
Selection at the moment before the edit, so undo restores not just the text but where the user was. Restoring text alone feels broken.
Sources/LavaText/TextEdit.swift:33
var focusBefore: Int
Not documented.
Sources/LavaText/TextEdit.swift:34
var inserted: String
What replaced it.
Sources/LavaText/TextEdit.swift:30
var inverted: TextEdit { get }
The same edit run backwards.
Sources/LavaText/TextEdit.swift:48
var offset: Int
UTF-8 offset where the replacement begins.
Sources/LavaText/TextEdit.swift:26
var removed: String
What used to be there — this is what makes the edit reversible.
Sources/LavaText/TextEdit.swift:28