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

@ -1306,7 +1306,16 @@ impl BufferSearchBar {
done_rx
}
fn reverse_direction_if_backwards(&self, direction: Direction) -> Direction {
if self.search_options.contains(SearchOptions::BACKWARDS) {
direction.opposite()
} else {
direction
}
}
pub fn update_match_index(&mut self, window: &mut Window, cx: &mut Context<Self>) {
let direction = self.reverse_direction_if_backwards(Direction::Next);
let new_index = self
.active_searchable_item
.as_ref()
@ -1314,7 +1323,7 @@ impl BufferSearchBar {
let matches = self
.searchable_items_with_matches
.get(&searchable_item.downgrade())?;
searchable_item.active_match_index(matches, window, cx)
searchable_item.active_match_index(direction, matches, window, cx)
});
if new_index != self.active_match_index {
self.active_match_index = new_index;

View file

@ -1240,6 +1240,7 @@ impl ProjectSearchView {
fn update_match_index(&mut self, cx: &mut Context<Self>) {
let results_editor = self.results_editor.read(cx);
let new_index = active_match_index(
Direction::Next,
&self.entity.read(cx).match_ranges,
&results_editor.selections.newest_anchor().head(),
&results_editor.buffer().read(cx).snapshot(cx),

View file

@ -47,6 +47,8 @@ bitflags! {
const CASE_SENSITIVE = 0b010;
const INCLUDE_IGNORED = 0b100;
const REGEX = 0b1000;
/// If set, reverse direction when finding the active match
const BACKWARDS = 0b10000;
}
}