Make buffer search aware of search direction (#24974)

This solves a couple of issues with Vim search by making the search
buffer and `SearchableItem` aware of the direction of the search. If
`SearchOptions::BACKWARDS` is set, all operations will be reversed. By
making `SearchableItem` aware of the direction, the correct active match
can be selected when searching backward.

Fixes #22506. This PR does not fix the last problem in that issue, but
that one is also tracked in #8049.

Release Notes:

- Fixes incorrect behavior of backward search in Vim mode
This commit is contained in:
Nico Lehmann 2025-03-04 18:27:37 -08:00 committed by GitHub
parent ed13e05855
commit 229e853874
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 80 additions and 25 deletions

View file

@ -1589,11 +1589,13 @@ impl SearchableItem for Editor {
fn active_match_index(
&mut self,
direction: Direction,
matches: &[Range<Anchor>],
_: &mut Window,
cx: &mut Context<Self>,
) -> Option<usize> {
active_match_index(
direction,
matches,
&self.selections.newest_anchor().head(),
&self.buffer().read(cx).snapshot(cx),
@ -1606,6 +1608,7 @@ impl SearchableItem for Editor {
}
pub fn active_match_index(
direction: Direction,
ranges: &[Range<Anchor>],
cursor: &Anchor,
buffer: &MultiBufferSnapshot,
@ -1613,7 +1616,7 @@ pub fn active_match_index(
if ranges.is_empty() {
None
} else {
match ranges.binary_search_by(|probe| {
let r = ranges.binary_search_by(|probe| {
if probe.end.cmp(cursor, buffer).is_lt() {
Ordering::Less
} else if probe.start.cmp(cursor, buffer).is_gt() {
@ -1621,8 +1624,15 @@ pub fn active_match_index(
} else {
Ordering::Equal
}
}) {
Ok(i) | Err(i) => Some(cmp::min(i, ranges.len() - 1)),
});
match direction {
Direction::Prev => match r {
Ok(i) => Some(i),
Err(i) => Some(i.saturating_sub(1)),
},
Direction::Next => match r {
Ok(i) | Err(i) => Some(cmp::min(i, ranges.len() - 1)),
},
}
}
}