diff --git a/crates/outline/src/outline.rs b/crates/outline/src/outline.rs index 8c5e78d77b..c32f803d89 100644 --- a/crates/outline/src/outline.rs +++ b/crates/outline/src/outline.rs @@ -119,6 +119,7 @@ struct OutlineViewDelegate { active_editor: Entity, outline: Outline, selected_match_index: usize, + manually_selected: Option, prev_scroll_position: Option>, matches: Vec, last_query: String, @@ -139,6 +140,7 @@ impl OutlineViewDelegate { last_query: Default::default(), matches: Default::default(), selected_match_index: 0, + manually_selected: None, prev_scroll_position: Some(editor.update(cx, |editor, cx| editor.scroll_position(cx))), active_editor: editor, outline, @@ -165,6 +167,7 @@ impl OutlineViewDelegate { if navigate && !self.matches.is_empty() { let selected_match = &self.matches[self.selected_match_index]; + self.manually_selected = Some(selected_match.candidate_id); let outline_item = &self.outline.items[selected_match.candidate_id]; self.active_editor.update(cx, |active_editor, cx| { @@ -180,6 +183,8 @@ impl OutlineViewDelegate { ); active_editor.request_autoscroll(Autoscroll::center(), cx); }); + } else if self.manually_selected.is_some() { + self.manually_selected = None; } } } @@ -261,13 +266,29 @@ impl PickerDelegate for OutlineViewDelegate { self.outline .search(&query, cx.background_executor().clone()), ); - selected_index = self - .matches - .iter() - .enumerate() - .max_by_key(|(_, m)| OrderedFloat(m.score)) - .map(|(ix, _)| ix) - .unwrap_or(0); + + if let Some(manually_selected) = self.manually_selected.and_then(|manually_selected| { + self.matches + .iter() + .find(|mtch| mtch.candidate_id == manually_selected) + .map(|mtch| mtch.candidate_id) + }) { + selected_index = self + .matches + .iter() + .enumerate() + .find(|(_, m)| m.candidate_id == manually_selected) + .map(|(ix, _)| ix) + .unwrap_or(0); + } else { + selected_index = self + .matches + .iter() + .enumerate() + .max_by_key(|(_, m)| OrderedFloat(m.score)) + .map(|(ix, _)| ix) + .unwrap_or(0); + } } self.last_query = query; self.set_selected_index(selected_index, !self.last_query.is_empty(), cx); diff --git a/crates/project_symbols/src/project_symbols.rs b/crates/project_symbols/src/project_symbols.rs index 72029e55a0..87928ea628 100644 --- a/crates/project_symbols/src/project_symbols.rs +++ b/crates/project_symbols/src/project_symbols.rs @@ -44,6 +44,7 @@ pub struct ProjectSymbolsDelegate { external_match_candidates: Vec, show_worktree_root_name: bool, matches: Vec, + manually_selected: Option, } impl ProjectSymbolsDelegate { @@ -57,6 +58,7 @@ impl ProjectSymbolsDelegate { external_match_candidates: Default::default(), matches: Default::default(), show_worktree_root_name: false, + manually_selected: None, } } @@ -99,6 +101,18 @@ impl ProjectSymbolsDelegate { } self.matches = matches; + + // Preserve manually selected item if it exists + if let Some(manually_selected) = &self.manually_selected { + if let Some(index) = self.matches.iter().position(|mat| { + let symbol = &self.symbols[mat.candidate_id]; + symbol.path == manually_selected.path && symbol.range == manually_selected.range + }) { + self.set_selected_index(index, window, cx); + return; + } + } + self.set_selected_index(0, window, cx); } } @@ -168,6 +182,11 @@ impl PickerDelegate for ProjectSymbolsDelegate { _cx: &mut Context>, ) { self.selected_match_index = ix; + + // Store the manually selected symbol + if let Some(mat) = self.matches.get(ix) { + self.manually_selected = Some(self.symbols[mat.candidate_id].clone()); + } } fn update_matches( diff --git a/crates/theme_selector/src/theme_selector.rs b/crates/theme_selector/src/theme_selector.rs index 8c48f295dd..8953221146 100644 --- a/crates/theme_selector/src/theme_selector.rs +++ b/crates/theme_selector/src/theme_selector.rs @@ -116,7 +116,7 @@ struct ThemeSelectorDelegate { matches: Vec, original_theme: Arc, selection_completed: bool, - selected_theme: Option>, + manually_selected: Option>, selected_index: usize, selector: WeakEntity, } @@ -165,7 +165,7 @@ impl ThemeSelectorDelegate { original_theme: original_theme.clone(), selected_index: 0, selection_completed: false, - selected_theme: None, + manually_selected: None, selector, }; @@ -271,7 +271,7 @@ impl PickerDelegate for ThemeSelectorDelegate { cx: &mut Context>, ) { self.selected_index = ix; - self.selected_theme = self.show_selected_theme(cx); + self.manually_selected = self.show_selected_theme(cx); } fn update_matches( @@ -315,12 +315,12 @@ impl PickerDelegate for ThemeSelectorDelegate { this.update(cx, |this, cx| { this.delegate.matches = matches; - if query.is_empty() && this.delegate.selected_theme.is_none() { + if query.is_empty() && this.delegate.manually_selected.is_none() { this.delegate.selected_index = this .delegate .selected_index .min(this.delegate.matches.len().saturating_sub(1)); - } else if let Some(selected) = this.delegate.selected_theme.as_ref() { + } else if let Some(selected) = this.delegate.manually_selected.as_ref() { this.delegate.selected_index = this .delegate .matches @@ -332,7 +332,7 @@ impl PickerDelegate for ThemeSelectorDelegate { } else { this.delegate.selected_index = 0; } - this.delegate.selected_theme = this.delegate.show_selected_theme(cx); + this.delegate.manually_selected = this.delegate.show_selected_theme(cx); }) .log_err(); })