···122122 // Rust ranges are end-exclusive, so range 0..10 covers positions 0-9.
123123 // When cursor is exactly at a boundary (e.g., position 10 between 0..10 and 10..20),
124124 // prefer the NEXT mapping so cursor goes "down" to new content.
125125- let idx = offset_map
126126- .binary_search_by(|mapping| {
127127- if mapping.char_range.end <= char_offset {
128128- // Cursor is at or after end of this mapping - look forward
129129- std::cmp::Ordering::Less
130130- } else if mapping.char_range.start > char_offset {
131131- // Cursor is before this mapping
132132- std::cmp::Ordering::Greater
125125+ let result = offset_map.binary_search_by(|mapping| {
126126+ if mapping.char_range.end <= char_offset {
127127+ // Cursor is at or after end of this mapping - look forward
128128+ std::cmp::Ordering::Less
129129+ } else if mapping.char_range.start > char_offset {
130130+ // Cursor is before this mapping
131131+ std::cmp::Ordering::Greater
132132+ } else {
133133+ // Cursor is within [start, end)
134134+ std::cmp::Ordering::Equal
135135+ }
136136+ });
137137+138138+ let mapping = match result {
139139+ Ok(idx) => &offset_map[idx],
140140+ Err(idx) => {
141141+ // No exact match - cursor is at boundary between mappings (or past end)
142142+ // If cursor is exactly at end of previous mapping, return that mapping
143143+ // This handles cursor at end of document or end of last mapping
144144+ if idx > 0 && offset_map[idx - 1].char_range.end == char_offset {
145145+ &offset_map[idx - 1]
133146 } else {
134134- // Cursor is within [start, end)
135135- std::cmp::Ordering::Equal
147147+ return None;
136148 }
137137- })
138138- .ok()?;
149149+ }
150150+ };
139151140140- let mapping = &offset_map[idx];
141152 let should_snap = mapping.is_invisible();
142142-143153 Some((mapping, should_snap))
144154}
145155