diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 296f6ca11de775..a6147cde7a5c8b 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -14383,6 +14383,10 @@ impl Editor { let last_selection = selections.iter().max_by_key(|s| s.id).unwrap(); let mut next_selected_range = None; + // Collect and sort selection ranges for efficient overlap checking + let mut selection_ranges: Vec<_> = selections.iter().map(|s| s.range()).collect(); + selection_ranges.sort_by_key(|r| r.start); + let bytes_after_last_selection = buffer.bytes_in_range(last_selection.end..buffer.len()); let bytes_before_first_selection = buffer.bytes_in_range(0..first_selection.start); @@ -14404,11 +14408,20 @@ impl Editor { || (!buffer.is_inside_word(offset_range.start, None) && !buffer.is_inside_word(offset_range.end, None)) { - // TODO: This is n^2, because we might check all the selections - if !selections - .iter() - .any(|selection| selection.range().overlaps(&offset_range)) - { + // Use binary search to check for overlap (O(log n)) + let overlaps = selection_ranges + .binary_search_by(|range| { + if range.end <= offset_range.start { + std::cmp::Ordering::Less + } else if range.start >= offset_range.end { + std::cmp::Ordering::Greater + } else { + std::cmp::Ordering::Equal + } + }) + .is_ok(); + + if !overlaps { next_selected_range = Some(offset_range); break; }