pub fn display_col_to_source_byte(
col: u32,
max_source_byte: u32,
inlay_offsets: &[(u32, u32)],
conceals: &[ConcealRange],
) -> u32Expand description
Map a display column back to the source position under it — the
inverse of source_byte_to_display_col, and what a mouse click
needs.
max_source_byte is the source line’s length in the same
already-char-resolved space the forward map uses (see the
byte-vs-char note on crate::row::CellRow::byte_to_combined_col):
the caller resolves char ↔ byte, this only undoes the column
arithmetic. The result is clamped to [0, max_source_byte], so a
click past the end of a line lands on its end rather than failing.
§Derived from the forward map, not re-derived
This binary-searches source_byte_to_display_col for the largest
source position whose column is still <= col, rather than running
the inlay and conceal arithmetic backwards. That costs
O(log line_len) forward evaluations — nothing, on a path driven by
a human’s hand — and buys the one property that matters: the inverse
cannot disagree with the forward map, because it is the forward
map. This module exists because three copies of the forward
arithmetic drifted; a hand-written inverse would be a fourth copy
with the same failure mode and a worse symptom, since a click that
lands one column off reads as a shaping bug rather than a missing
conceal rule.
The search is sound because the forward map is monotonic non-decreasing: each source position adds one column plus any inlay spliced ahead of it, and a position inside a hidden range adds zero.
§Where a click inside hidden or virtual text lands
On a concealed range, the first VISIBLE position at that column.
Every position in [start, end] maps to the range’s start column, so
the largest of them wins — which is the position just past the hidden
text, i.e. the character actually drawn there. That is the right
answer for a click and the mirror image of the forward map’s clamp,
which sends a hidden position back to the range’s start column.
On inlay text, the source position before the splice. Inlay columns have no source position of their own; the one before them is the only truthful answer, and it is where the caret would already be drawn.