diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json index d6bdff1cd02fcd0bfb31fb48d2c47a321c54de2c..9bde6ca7575b958d456d46a002a14e4289fe10fd 100644 --- a/assets/keymaps/vim.json +++ b/assets/keymaps/vim.json @@ -421,6 +421,12 @@ "ctrl-[": "editor::Cancel" } }, + { + "context": "vim_mode == helix_select && !menu", + "bindings": { + "escape": "vim::SwitchToHelixNormalMode" + } + }, { "context": "(vim_mode == helix_normal || vim_mode == helix_select) && !menu", "bindings": { diff --git a/crates/agent_ui/src/text_thread_editor.rs b/crates/agent_ui/src/text_thread_editor.rs index 667ccb8938b892dcf59232d5cd7ea8dda04bc4b2..44c80a2258d1146fb7a5f2fb6124d08d61d8cb57 100644 --- a/crates/agent_ui/src/text_thread_editor.rs +++ b/crates/agent_ui/src/text_thread_editor.rs @@ -2591,11 +2591,12 @@ impl SearchableItem for TextThreadEditor { &mut self, index: usize, matches: &[Self::Match], + collapse: bool, window: &mut Window, cx: &mut Context, ) { self.editor.update(cx, |editor, cx| { - editor.activate_match(index, matches, window, cx); + editor.activate_match(index, matches, collapse, window, cx); }); } diff --git a/crates/debugger_tools/src/dap_log.rs b/crates/debugger_tools/src/dap_log.rs index 4c994ad7eb749dcb5828daa83bad34a579f9f14c..738c60870f2200e11e710f9c94d02682b94677f7 100644 --- a/crates/debugger_tools/src/dap_log.rs +++ b/crates/debugger_tools/src/dap_log.rs @@ -1029,11 +1029,13 @@ impl SearchableItem for DapLogView { &mut self, index: usize, matches: &[Self::Match], + collapse: bool, window: &mut Window, cx: &mut Context, ) { - self.editor - .update(cx, |e, cx| e.activate_match(index, matches, window, cx)) + self.editor.update(cx, |e, cx| { + e.activate_match(index, matches, collapse, window, cx) + }) } fn select_matches( diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 3839da917078ae2340ead97f9cf4fa624b5c588a..9bdebcd24a20697fb041ae14fa7dc2f034d00d92 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -1069,7 +1069,6 @@ pub struct Editor { searchable: bool, cursor_shape: CursorShape, current_line_highlight: Option, - collapse_matches: bool, autoindent_mode: Option, workspace: Option<(WeakEntity, Option)>, input_enabled: bool, @@ -2119,7 +2118,7 @@ impl Editor { .unwrap_or_default(), current_line_highlight: None, autoindent_mode: Some(AutoindentMode::EachLine), - collapse_matches: false, + workspace: None, input_enabled: !is_minimap, use_modal_editing: full_mode, @@ -2272,7 +2271,7 @@ impl Editor { } } EditorEvent::Edited { .. } => { - if !vim_enabled(cx) { + if vim_flavor(cx).is_none() { let display_map = editor.display_snapshot(cx); let selections = editor.selections.all_adjusted_display(&display_map); let pop_state = editor @@ -2881,12 +2880,12 @@ impl Editor { self.current_line_highlight = current_line_highlight; } - pub fn set_collapse_matches(&mut self, collapse_matches: bool) { - self.collapse_matches = collapse_matches; - } - - pub fn range_for_match(&self, range: &Range) -> Range { - if self.collapse_matches { + pub fn range_for_match( + &self, + range: &Range, + collapse: bool, + ) -> Range { + if collapse { return range.start..range.start; } range.clone() @@ -16654,7 +16653,7 @@ impl Editor { editor.update_in(cx, |editor, window, cx| { let range = target_range.to_point(target_buffer.read(cx)); - let range = editor.range_for_match(&range); + let range = editor.range_for_match(&range, false); let range = collapse_multiline_range(range); if !split @@ -21457,7 +21456,7 @@ impl Editor { .and_then(|e| e.to_str()) .map(|a| a.to_string())); - let vim_mode = vim_enabled(cx); + let vim_mode = vim_flavor(cx).is_some(); let edit_predictions_provider = all_language_settings(file, cx).edit_predictions.provider; let copilot_enabled = edit_predictions_provider @@ -22088,10 +22087,26 @@ fn edit_for_markdown_paste<'a>( (range, new_text) } -fn vim_enabled(cx: &App) -> bool { - vim_mode_setting::VimModeSetting::try_get(cx) +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum VimFlavor { + Vim, + Helix, +} + +pub fn vim_flavor(cx: &App) -> Option { + if vim_mode_setting::HelixModeSetting::try_get(cx) + .map(|helix_mode| helix_mode.0) + .unwrap_or(false) + { + Some(VimFlavor::Helix) + } else if vim_mode_setting::VimModeSetting::try_get(cx) .map(|vim_mode| vim_mode.0) .unwrap_or(false) + { + Some(VimFlavor::Vim) + } else { + None // neither vim nor helix mode + } } fn process_completion_for_edit( diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 346574eba440622a40139a52be6977e55e909980..c064e3dbaf2873fef03d65dbd5794e6453599cec 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -1587,11 +1587,12 @@ impl SearchableItem for Editor { &mut self, index: usize, matches: &[Range], + collapse: bool, window: &mut Window, cx: &mut Context, ) { self.unfold_ranges(&[matches[index].clone()], false, true, cx); - let range = self.range_for_match(&matches[index]); + let range = self.range_for_match(&matches[index], collapse); self.change_selections(Default::default(), window, cx, |s| { s.select_ranges([range]); }) diff --git a/crates/language_tools/src/lsp_log_view.rs b/crates/language_tools/src/lsp_log_view.rs index d480eadc73b9546e5a59b204b036a3ff88a018c7..ef9cc1ef3af88310d5870aa4d2da3d1a077139f1 100644 --- a/crates/language_tools/src/lsp_log_view.rs +++ b/crates/language_tools/src/lsp_log_view.rs @@ -812,11 +812,13 @@ impl SearchableItem for LspLogView { &mut self, index: usize, matches: &[Self::Match], + collapse: bool, window: &mut Window, cx: &mut Context, ) { - self.editor - .update(cx, |e, cx| e.activate_match(index, matches, window, cx)) + self.editor.update(cx, |e, cx| { + e.activate_match(index, matches, collapse, window, cx) + }) } fn select_matches( diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 25697bb45ac5f617b586d7a4346ee8761b7a4ed3..f01073b6228ed3d314990187e63262a111f365c5 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -10,8 +10,9 @@ use any_vec::AnyVec; use anyhow::Context as _; use collections::HashMap; use editor::{ - DisplayPoint, Editor, EditorSettings, + DisplayPoint, Editor, EditorSettings, VimFlavor, actions::{Backtab, Tab}, + vim_flavor, }; use futures::channel::oneshot; use gpui::{ @@ -825,7 +826,8 @@ impl BufferSearchBar { .searchable_items_with_matches .get(&active_searchable_item.downgrade()) { - active_searchable_item.activate_match(match_ix, matches, window, cx) + let collapse = editor::vim_flavor(cx) == Some(VimFlavor::Vim); + active_searchable_item.activate_match(match_ix, matches, collapse, window, cx) } } @@ -970,7 +972,8 @@ impl BufferSearchBar { window: &mut Window, cx: &mut Context, ) { - self.select_match(Direction::Next, 1, window, cx); + let collapse = vim_flavor(cx) == Some(VimFlavor::Vim); + self.select_match(Direction::Next, 1, collapse, window, cx); } fn select_prev_match( @@ -979,7 +982,8 @@ impl BufferSearchBar { window: &mut Window, cx: &mut Context, ) { - self.select_match(Direction::Prev, 1, window, cx); + let collapse = vim_flavor(cx) == Some(VimFlavor::Vim); + self.select_match(Direction::Prev, 1, collapse, window, cx); } pub fn select_all_matches( @@ -1004,6 +1008,7 @@ impl BufferSearchBar { &mut self, direction: Direction, count: usize, + collapse: bool, window: &mut Window, cx: &mut Context, ) { @@ -1026,7 +1031,7 @@ impl BufferSearchBar { .match_index_for_direction(matches, index, direction, count, window, cx); searchable_item.update_matches(matches, window, cx); - searchable_item.activate_match(new_match_index, matches, window, cx); + searchable_item.activate_match(new_match_index, matches, collapse, window, cx); } } @@ -1040,7 +1045,8 @@ impl BufferSearchBar { return; } searchable_item.update_matches(matches, window, cx); - searchable_item.activate_match(0, matches, window, cx); + let collapse = vim_flavor(cx) == Some(VimFlavor::Vim); + searchable_item.activate_match(0, matches, collapse, window, cx); } } @@ -1055,7 +1061,8 @@ impl BufferSearchBar { } let new_match_index = matches.len() - 1; searchable_item.update_matches(matches, window, cx); - searchable_item.activate_match(new_match_index, matches, window, cx); + let collapse = vim_flavor(cx) == Some(VimFlavor::Vim); + searchable_item.activate_match(new_match_index, matches, collapse, window, cx); } } diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index a8be82d5d5a3fcb20b8ea964af19e3f60fea0573..0bb05ecb93cd5cc6c9730307792c1737531a39a5 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -9,10 +9,10 @@ use anyhow::Context as _; use collections::HashMap; use editor::{ Anchor, Editor, EditorEvent, EditorSettings, MAX_TAB_TITLE_LEN, MultiBuffer, PathKey, - SelectionEffects, + SelectionEffects, VimFlavor, actions::{Backtab, SelectAll, Tab}, items::active_match_index, - multibuffer_context_lines, + multibuffer_context_lines, vim_flavor, }; use futures::{StreamExt, stream::FuturesOrdered}; use gpui::{ @@ -1344,7 +1344,8 @@ impl ProjectSearchView { let range_to_select = match_ranges[new_index].clone(); self.results_editor.update(cx, |editor, cx| { - let range_to_select = editor.range_for_match(&range_to_select); + let collapse = vim_flavor(cx) == Some(VimFlavor::Vim); + let range_to_select = editor.range_for_match(&range_to_select, collapse); editor.unfold_ranges(std::slice::from_ref(&range_to_select), false, true, cx); editor.change_selections(Default::default(), window, cx, |s| { s.select_ranges([range_to_select]) @@ -1415,9 +1416,10 @@ impl ProjectSearchView { let is_new_search = self.search_id != prev_search_id; self.results_editor.update(cx, |editor, cx| { if is_new_search { + let collapse = vim_flavor(cx) == Some(VimFlavor::Vim); let range_to_select = match_ranges .first() - .map(|range| editor.range_for_match(range)); + .map(|range| editor.range_for_match(range, collapse)); editor.change_selections(Default::default(), window, cx, |s| { s.select_ranges(range_to_select) }); diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index 63d6c503b29d1eec6500bd4acb5c2f0f6ef36e33..2a9720357b27b91f3a5ff7689f4cb0f16787031b 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -1447,6 +1447,7 @@ impl SearchableItem for TerminalView { &mut self, index: usize, _: &[Self::Match], + _collapse: bool, _window: &mut Window, cx: &mut Context, ) { diff --git a/crates/vim/src/helix.rs b/crates/vim/src/helix.rs index 6788a186fb45222f7b09fe756862e6cb337c6d90..ee7c0a14fb721116c3fc1f2c3d1bf7b716b43f18 100644 --- a/crates/vim/src/helix.rs +++ b/crates/vim/src/helix.rs @@ -450,7 +450,7 @@ impl Vim { prior_selections, prior_operator: self.operator_stack.last().cloned(), prior_mode: self.mode, - helix_select: true, + is_helix_regex_search: true, } }); } @@ -1278,6 +1278,24 @@ mod test { cx.assert_state("«one ˇ»two", Mode::HelixSelect); } + #[gpui::test] + async fn test_exit_visual_mode(cx: &mut gpui::TestAppContext) { + let mut cx = VimTestContext::new(cx, true).await; + + cx.set_state("ˇone two", Mode::Normal); + cx.simulate_keystrokes("v w"); + cx.assert_state("«one tˇ»wo", Mode::Visual); + cx.simulate_keystrokes("escape"); + cx.assert_state("one ˇtwo", Mode::Normal); + + cx.enable_helix(); + cx.set_state("ˇone two", Mode::HelixNormal); + cx.simulate_keystrokes("v w"); + cx.assert_state("«one ˇ»two", Mode::HelixSelect); + cx.simulate_keystrokes("escape"); + cx.assert_state("«one ˇ»two", Mode::HelixNormal); + } + #[gpui::test] async fn test_helix_select_regex(cx: &mut gpui::TestAppContext) { let mut cx = VimTestContext::new(cx, true).await; @@ -1297,9 +1315,47 @@ mod test { cx.simulate_keystrokes("enter"); cx.assert_state("«oneˇ» two «oneˇ»", Mode::HelixNormal); - cx.set_state("ˇone two one", Mode::HelixNormal); - cx.simulate_keystrokes("s o n e enter"); - cx.assert_state("ˇone two one", Mode::HelixNormal); + // TODO: change "search_in_selection" to not perform any search when in helix select mode with no selection + // cx.set_state("ˇstuff one two one", Mode::HelixNormal); + // cx.simulate_keystrokes("s o n e enter"); + // cx.assert_state("ˇstuff one two one", Mode::HelixNormal); + } + + #[gpui::test] + async fn test_helix_select_next_match(cx: &mut gpui::TestAppContext) { + let mut cx = VimTestContext::new(cx, true).await; + + cx.set_state("ˇhello two one two one two one", Mode::Visual); + cx.simulate_keystrokes("/ o n e"); + cx.simulate_keystrokes("enter"); + cx.simulate_keystrokes("n n"); + cx.assert_state("«hello two one two one two oˇ»ne", Mode::Visual); + + cx.set_state("ˇhello two one two one two one", Mode::Normal); + cx.simulate_keystrokes("/ o n e"); + cx.simulate_keystrokes("enter"); + cx.simulate_keystrokes("n n"); + cx.assert_state("hello two one two one two ˇone", Mode::Normal); + + cx.set_state("ˇhello two one two one two one", Mode::Normal); + cx.simulate_keystrokes("/ o n e"); + cx.simulate_keystrokes("enter"); + cx.simulate_keystrokes("n g n g n"); + cx.assert_state("hello two one two «one two oneˇ»", Mode::Visual); + + cx.enable_helix(); + + cx.set_state("ˇhello two one two one two one", Mode::HelixNormal); + cx.simulate_keystrokes("/ o n e"); + cx.simulate_keystrokes("enter"); + cx.simulate_keystrokes("n n"); + cx.assert_state("hello two one two one two «oneˇ»", Mode::HelixNormal); + + cx.set_state("ˇhello two one two one two one", Mode::HelixSelect); + cx.simulate_keystrokes("/ o n e"); + cx.simulate_keystrokes("enter"); + cx.simulate_keystrokes("n n"); + cx.assert_state("ˇhello two «oneˇ» two «oneˇ» two «oneˇ»", Mode::HelixSelect); } #[gpui::test] diff --git a/crates/vim/src/motion.rs b/crates/vim/src/motion.rs index 1a617e36c18ffa52906cac06d4b9eddb11a91f8e..2da1083ee6623cc8a463ef31be7e90dca0063b34 100644 --- a/crates/vim/src/motion.rs +++ b/crates/vim/src/motion.rs @@ -672,31 +672,40 @@ pub fn register(editor: &mut Editor, cx: &mut Context) { impl Vim { pub(crate) fn search_motion(&mut self, m: Motion, window: &mut Window, cx: &mut Context) { - if let Motion::ZedSearchResult { - prior_selections, .. + let Motion::ZedSearchResult { + prior_selections, + new_selections, } = &m - { - match self.mode { - Mode::Visual | Mode::VisualLine | Mode::VisualBlock => { - if !prior_selections.is_empty() { - self.update_editor(cx, |_, editor, cx| { - editor.change_selections(Default::default(), window, cx, |s| { - s.select_ranges(prior_selections.iter().cloned()) - }) + else { + return; + }; + + match self.mode { + Mode::Visual | Mode::VisualLine | Mode::VisualBlock => { + if !prior_selections.is_empty() { + self.update_editor(cx, |_, editor, cx| { + editor.change_selections(Default::default(), window, cx, |s| { + s.select_ranges(prior_selections.iter().cloned()); }); - } + }); } - Mode::Normal | Mode::Replace | Mode::Insert => { - if self.active_operator().is_none() { - return; - } + self.motion(m, window, cx); + } + Mode::Normal | Mode::Replace | Mode::Insert => { + if self.active_operator().is_some() { + self.motion(m, window, cx); } + } - Mode::HelixNormal | Mode::HelixSelect => {} + Mode::HelixNormal => {} + Mode::HelixSelect => { + self.update_editor(cx, |_, editor, cx| { + editor.change_selections(Default::default(), window, cx, |s| { + s.select_ranges(prior_selections.iter().chain(new_selections).cloned()); + }); + }); } } - - self.motion(m, window, cx) } pub(crate) fn motion(&mut self, motion: Motion, window: &mut Window, cx: &mut Context) { diff --git a/crates/vim/src/normal/search.rs b/crates/vim/src/normal/search.rs index 6c4294a474dad13c9d00e58ab117a4a6a74c28d3..2e80a08eb824b93783bf1249970e5e7ad7378ff2 100644 --- a/crates/vim/src/normal/search.rs +++ b/crates/vim/src/normal/search.rs @@ -1,5 +1,6 @@ -use editor::{Editor, EditorSettings}; +use editor::{Editor, EditorSettings, VimFlavor}; use gpui::{Action, Context, Window, actions}; + use language::Point; use schemars::JsonSchema; use search::{BufferSearchBar, SearchOptions, buffer_search}; @@ -195,7 +196,7 @@ impl Vim { prior_selections, prior_operator: self.operator_stack.last().cloned(), prior_mode, - helix_select: false, + is_helix_regex_search: false, } }); } @@ -219,7 +220,7 @@ impl Vim { let new_selections = self.editor_selections(window, cx); let result = pane.update(cx, |pane, cx| { let search_bar = pane.toolbar().read(cx).item_of_type::()?; - if self.search.helix_select { + if self.search.is_helix_regex_search { search_bar.update(cx, |search_bar, cx| { search_bar.select_all_matches(&Default::default(), window, cx) }); @@ -240,7 +241,8 @@ impl Vim { count = count.saturating_sub(1) } self.search.count = 1; - search_bar.select_match(direction, count, window, cx); + let collapse = !self.mode.is_helix(); + search_bar.select_match(direction, count, collapse, window, cx); search_bar.focus_editor(&Default::default(), window, cx); let prior_selections: Vec<_> = self.search.prior_selections.drain(..).collect(); @@ -307,7 +309,8 @@ impl Vim { if !search_bar.has_active_match() || !search_bar.show(window, cx) { return false; } - search_bar.select_match(direction, count, window, cx); + let collapse = !self.mode.is_helix(); + search_bar.select_match(direction, count, collapse, window, cx); true }) }); @@ -316,6 +319,7 @@ impl Vim { } let new_selections = self.editor_selections(window, cx); + self.search_motion( Motion::ZedSearchResult { prior_selections, @@ -381,7 +385,8 @@ impl Vim { cx.spawn_in(window, async move |_, cx| { search.await?; search_bar.update_in(cx, |search_bar, window, cx| { - search_bar.select_match(direction, count, window, cx); + let collapse = editor::vim_flavor(cx) == Some(VimFlavor::Vim); + search_bar.select_match(direction, count, collapse, window, cx); vim.update(cx, |vim, cx| { let new_selections = vim.editor_selections(window, cx); @@ -444,7 +449,7 @@ impl Vim { cx.spawn_in(window, async move |_, cx| { search.await?; search_bar.update_in(cx, |search_bar, window, cx| { - search_bar.select_match(direction, 1, window, cx) + search_bar.select_match(direction, 1, true, window, cx) })?; anyhow::Ok(()) }) diff --git a/crates/vim/src/state.rs b/crates/vim/src/state.rs index 959edff63dd50fa549edcbae1bea213224b923af..dc9ac7104c00a5f49758dbab219ec72d46023b27 100644 --- a/crates/vim/src/state.rs +++ b/crates/vim/src/state.rs @@ -66,12 +66,16 @@ impl Display for Mode { } impl Mode { - pub fn is_visual(&self) -> bool { + pub fn is_visual(self) -> bool { match self { Self::Visual | Self::VisualLine | Self::VisualBlock | Self::HelixSelect => true, Self::Normal | Self::Insert | Self::Replace | Self::HelixNormal => false, } } + + pub fn is_helix(self) -> bool { + matches!(self, Mode::HelixNormal | Mode::HelixSelect) + } } impl Default for Mode { @@ -990,7 +994,7 @@ pub struct SearchState { pub prior_selections: Vec>, pub prior_operator: Option, pub prior_mode: Mode, - pub helix_select: bool, + pub is_helix_regex_search: bool, } impl Operator { diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index cb553b64e91eadbb5e529d56bb1e1a5a7da2c7be..91ce66d43e76f3a40a5e074f01527953def1b188 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -669,7 +669,7 @@ impl Vim { editor, cx, |vim, _: &SwitchToHelixNormalMode, window, cx| { - vim.switch_mode(Mode::HelixNormal, false, window, cx) + vim.switch_mode(Mode::HelixNormal, true, window, cx) }, ); Vim::action(editor, cx, |_, _: &PushForcedMotion, _, cx| { @@ -953,7 +953,6 @@ impl Vim { fn deactivate(editor: &mut Editor, cx: &mut Context) { editor.set_cursor_shape(CursorShape::Bar, cx); editor.set_clip_at_line_ends(false, cx); - editor.set_collapse_matches(false); editor.set_input_enabled(true); editor.set_autoindent(true); editor.selections.set_line_mode(false); @@ -1929,7 +1928,6 @@ impl Vim { self.update_editor(cx, |vim, editor, cx| { editor.set_cursor_shape(vim.cursor_shape(cx), cx); editor.set_clip_at_line_ends(vim.clip_at_line_ends(), cx); - editor.set_collapse_matches(true); editor.set_input_enabled(vim.editor_input_enabled()); editor.set_autoindent(vim.should_autoindent()); editor diff --git a/crates/vim/src/visual.rs b/crates/vim/src/visual.rs index 59555205d9862e51c2778eec1f321338fd5e7569..17423f32dc9c235effe53d5a47edca0573bcda6f 100644 --- a/crates/vim/src/visual.rs +++ b/crates/vim/src/visual.rs @@ -847,9 +847,6 @@ impl Vim { let mut start_selection = 0usize; let mut end_selection = 0usize; - self.update_editor(cx, |_, editor, _| { - editor.set_collapse_matches(false); - }); if vim_is_normal { pane.update(cx, |pane, cx| { if let Some(search_bar) = pane.toolbar().read(cx).item_of_type::() @@ -860,7 +857,7 @@ impl Vim { } // without update_match_index there is a bug when the cursor is before the first match search_bar.update_match_index(window, cx); - search_bar.select_match(direction.opposite(), 1, window, cx); + search_bar.select_match(direction.opposite(), 1, false, window, cx); }); } }); @@ -878,7 +875,7 @@ impl Vim { if let Some(search_bar) = pane.toolbar().read(cx).item_of_type::() { search_bar.update(cx, |search_bar, cx| { search_bar.update_match_index(window, cx); - search_bar.select_match(direction, count, window, cx); + search_bar.select_match(direction, count, false, window, cx); match_exists = search_bar.match_exists(window, cx); }); } @@ -905,7 +902,6 @@ impl Vim { editor.change_selections(Default::default(), window, cx, |s| { s.select_ranges([start_selection..end_selection]); }); - editor.set_collapse_matches(true); }); match self.maybe_pop_operator() { diff --git a/crates/workspace/src/searchable.rs b/crates/workspace/src/searchable.rs index 310fae908dbd6864c1636ebd393e4920d0f9ad02..18da3f16f2e7a1e57dd42287059c0041d9309a78 100644 --- a/crates/workspace/src/searchable.rs +++ b/crates/workspace/src/searchable.rs @@ -104,6 +104,7 @@ pub trait SearchableItem: Item + EventEmitter { &mut self, index: usize, matches: &[Self::Match], + collapse: bool, window: &mut Window, cx: &mut Context, ); @@ -184,6 +185,7 @@ pub trait SearchableItemHandle: ItemHandle { &self, index: usize, matches: &AnyVec, + collapse: bool, window: &mut Window, cx: &mut App, ); @@ -274,12 +276,13 @@ impl SearchableItemHandle for Entity { &self, index: usize, matches: &AnyVec, + collapse: bool, window: &mut Window, cx: &mut App, ) { let matches = matches.downcast_ref().unwrap(); self.update(cx, |this, cx| { - this.activate_match(index, matches.as_slice(), window, cx) + this.activate_match(index, matches.as_slice(), collapse, window, cx) }); }