struct VisualLayout
Swift
struct VisualLayout
Where each visual row begins and ends, in character offsets over the whole buffer.
With wrapping, a visual row is no longer a logical line, and every mapping — caret, hit test, selection, vertical movement — has to use this rather than newline positions.
Sources/LavaText/SoftWrap.swift:115
Constructors
init(rows: [Range<Int>])
Not documented.
Sources/LavaText/SoftWrap.swift:118
Properties
var count: Int { get }
Not documented.
Sources/LavaText/SoftWrap.swift:278
var rows: [Range<Int>]
Not documented.
Sources/LavaText/SoftWrap.swift:116
Methods
func column(ofOffset offset: Int, affinity: CaretAffinity = .downstream) -> Int
Not documented.
Sources/LavaText/SoftWrap.swift:336
static func lineIndex(_ text: String, includingBytes: Bool = true) -> LineIndex
The same scan, also reporting where each line sits in bytes.
Character offsets are what the row table is stated in. Byte offsets
are what a cheap comparison of two buffers produces, and what slicing
one line out of the buffer wants — and a wrapping editor needs both on
every edit, so it asks for them together rather than scanning twice.
Everything else asks for logicalRows and does not pay for the second
array, which on a 200,000-line log is not a rounding error.
Sources/LavaText/SoftWrap.swift:145
static func logical(_ text: String) -> VisualLayout
One row per logical line — the no-wrapping case.
Sources/LavaText/SoftWrap.swift:123
static func logicalRows(_ text: String) -> [Range<Int>]
Row boundaries for logical(_:), exposed separately so a caller (an
editor leaf with wrapping off) can cache the result via
TextEditingState.setVisualRows instead of recomputing this O(length)
scan on every layout access — which, left uncached, is what a large
buffer felt: every caret draw, hit test, and gutter row rescanned the
whole document.
Sources/LavaText/SoftWrap.swift:133
func offset(row: Int, column: Int) -> Int
Offset at row/column, clamped to that row.
Sources/LavaText/SoftWrap.swift:342
func rowIndex(ofOffset offset: Int, affinity: CaretAffinity = .downstream) -> Int
Row containing offset.
At a soft-wrap boundary one offset is both the end of a row and the start of the next, and there is no way to pick from the offset alone — which is why carets carry an affinity. Upstream keeps the caret on the row that ended (where a clamped vertical move should stay); downstream puts it on the row that starts (where a click or Home should land).
Sources/LavaText/SoftWrap.swift:287