From c074bfd4417719ca34ba267bdd088597115b91f4 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Wed, 13 Sep 2023 14:27:19 -0700 Subject: [PATCH] Add select all command to the editor, equivalent to hitting cmd-d as many times as possible --- assets/keymaps/default.json | 3 +- crates/editor/src/editor.rs | 75 +++++++++++++++++++++++++++---------- 2 files changed, 58 insertions(+), 20 deletions(-) diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index 14b9d01b21..8ac4fcbf8d 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -294,6 +294,7 @@ "replace_newest": false } ], + "cmd-shift-d": "editor::SelectNextAll", "ctrl-cmd-d": [ "editor::SelectPrevious", { @@ -453,7 +454,7 @@ "context": "Editor", "bindings": { "ctrl-shift-k": "editor::DeleteLine", - "cmd-shift-d": "editor::DuplicateLine", + // "cmd-shift-d": "editor::DuplicateLine", "cmd-shift-l": "editor::SplitSelectionIntoLines", "ctrl-j": "editor::JoinLines", "ctrl-cmd-up": "editor::MoveLineUp", diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 8c30859841..fa0663f2cf 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -129,6 +129,12 @@ pub struct SelectPrevious { pub replace_newest: bool, } +#[derive(Clone, Deserialize, PartialEq, Default)] +pub struct SelectNextAll { + #[serde(default)] + pub replace_newest: bool, +} + #[derive(Clone, Deserialize, PartialEq)] pub struct SelectToBeginningOfLine { #[serde(default)] @@ -325,6 +331,7 @@ impl_actions!( [ SelectNext, SelectPrevious, + SelectNextAll, SelectToBeginningOfLine, SelectToEndOfLine, ToggleCodeActions, @@ -427,6 +434,7 @@ pub fn init(cx: &mut AppContext) { cx.add_action(Editor::select_to_beginning); cx.add_action(Editor::select_to_end); cx.add_action(Editor::select_all); + cx.add_action(Editor::select_all_matches); cx.add_action(Editor::select_line); cx.add_action(Editor::split_selection_into_lines); cx.add_action(Editor::add_selection_above); @@ -5936,9 +5944,27 @@ impl Editor { } } - pub fn select_next(&mut self, action: &SelectNext, cx: &mut ViewContext) -> Result<()> { - self.push_to_selection_history(); - let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); + pub fn select_next_match_internal( + &mut self, + display_map: &DisplaySnapshot, + replace_newest: bool, + cx: &mut ViewContext, + ) { + fn select_next_match_ranges( + this: &mut Editor, + range: Range, + replace_newest: bool, + cx: &mut ViewContext, + ) { + this.unfold_ranges([range.clone()], false, true, cx); + this.change_selections(Some(Autoscroll::newest()), cx, |s| { + if replace_newest { + s.delete(s.newest_anchor().id); + } + s.insert_range(range.clone()); + }); + } + let buffer = &display_map.buffer_snapshot; let mut selections = self.selections.all::(cx); if let Some(mut select_next_state) = self.select_next_state.take() { @@ -5976,13 +6002,7 @@ impl Editor { } if let Some(next_selected_range) = next_selected_range { - self.unfold_ranges([next_selected_range.clone()], false, true, cx); - self.change_selections(Some(Autoscroll::newest()), cx, |s| { - if action.replace_newest { - s.delete(s.newest_anchor().id); - } - s.insert_range(next_selected_range); - }); + select_next_match_ranges(self, next_selected_range, replace_newest, cx); } else { select_next_state.done = true; } @@ -6009,10 +6029,7 @@ impl Editor { wordwise: true, done: false, }; - self.unfold_ranges([selection.start..selection.end], false, true, cx); - self.change_selections(Some(Autoscroll::newest()), cx, |s| { - s.select(selections); - }); + select_next_match_ranges(self, selection.start..selection.end, replace_newest, cx); self.select_next_state = Some(select_state); } else { let query = buffer @@ -6029,11 +6046,31 @@ impl Editor { Ok(()) } - pub fn select_previous( - &mut self, - action: &SelectPrevious, - cx: &mut ViewContext, - ) -> Result<()> { + pub fn select_all_matches(&mut self, action: &SelectNextAll, cx: &mut ViewContext) { + self.push_to_selection_history(); + let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); + + loop { + self.select_next_match_internal(&display_map, action.replace_newest, cx); + + if self + .select_next_state + .as_ref() + .map(|selection_state| selection_state.done) + .unwrap_or(true) + { + break; + } + } + } + + pub fn select_next(&mut self, action: &SelectNext, cx: &mut ViewContext) { + self.push_to_selection_history(); + let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); + self.select_next_match_internal(&display_map, action.replace_newest, cx); + } + + pub fn select_previous(&mut self, action: &SelectPrevious, cx: &mut ViewContext) { self.push_to_selection_history(); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let buffer = &display_map.buffer_snapshot;