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:
parent
ed13e05855
commit
229e853874
9 changed files with 80 additions and 25 deletions
|
@ -41,7 +41,7 @@ use workspace::{
|
|||
BreadcrumbText, Item, ItemEvent, SerializableItem, TabContentParams, TabTooltipContent,
|
||||
},
|
||||
register_serializable_item,
|
||||
searchable::{SearchEvent, SearchOptions, SearchableItem, SearchableItemHandle},
|
||||
searchable::{Direction, SearchEvent, SearchOptions, SearchableItem, SearchableItemHandle},
|
||||
CloseActiveItem, NewCenterTerminal, NewTerminal, OpenVisible, ToolbarItemLocation, Workspace,
|
||||
WorkspaceId,
|
||||
};
|
||||
|
@ -1583,6 +1583,7 @@ impl SearchableItem for TerminalView {
|
|||
/// Reports back to the search toolbar what the active match should be (the selection)
|
||||
fn active_match_index(
|
||||
&mut self,
|
||||
direction: Direction,
|
||||
matches: &[Self::Match],
|
||||
_: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
|
@ -1593,19 +1594,36 @@ impl SearchableItem for TerminalView {
|
|||
let res = if !matches.is_empty() {
|
||||
if let Some(selection_head) = self.terminal().read(cx).selection_head {
|
||||
// If selection head is contained in a match. Return that match
|
||||
if let Some(ix) = matches
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, search_match)| {
|
||||
search_match.contains(&selection_head)
|
||||
|| search_match.start() > &selection_head
|
||||
})
|
||||
.map(|(ix, _)| ix)
|
||||
{
|
||||
Some(ix)
|
||||
} else {
|
||||
// If no selection after selection head, return the last match
|
||||
Some(matches.len().saturating_sub(1))
|
||||
match direction {
|
||||
Direction::Prev => {
|
||||
// If no selection before selection head, return the first match
|
||||
Some(
|
||||
matches
|
||||
.iter()
|
||||
.enumerate()
|
||||
.rev()
|
||||
.find(|(_, search_match)| {
|
||||
search_match.contains(&selection_head)
|
||||
|| search_match.start() < &selection_head
|
||||
})
|
||||
.map(|(ix, _)| ix)
|
||||
.unwrap_or(0),
|
||||
)
|
||||
}
|
||||
Direction::Next => {
|
||||
// If no selection after selection head, return the last match
|
||||
Some(
|
||||
matches
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, search_match)| {
|
||||
search_match.contains(&selection_head)
|
||||
|| search_match.start() > &selection_head
|
||||
})
|
||||
.map(|(ix, _)| ix)
|
||||
.unwrap_or(matches.len().saturating_sub(1)),
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Matches found but no active selection, return the first last one (closest to cursor)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue