diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json index ccada4add7..294521f75f 100644 --- a/assets/keymaps/default-macos.json +++ b/assets/keymaps/default-macos.json @@ -108,8 +108,8 @@ "cmd-right": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": true }], "ctrl-e": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": false }], "end": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": true }], - "cmd-up": "editor::MoveToStartOfExcerpt", - "cmd-down": "editor::MoveToEndOfExcerpt", + "cmd-up": "editor::MoveToBeginning", + "cmd-down": "editor::MoveToEnd", "cmd-home": "editor::MoveToBeginning", // Typed via `cmd-fn-left` "cmd-end": "editor::MoveToEnd", // Typed via `cmd-fn-right` "shift-up": "editor::SelectUp", @@ -124,8 +124,8 @@ "alt-shift-right": "editor::SelectToNextWordEnd", // cursorWordRightSelect "ctrl-shift-up": "editor::SelectToStartOfParagraph", "ctrl-shift-down": "editor::SelectToEndOfParagraph", - "cmd-shift-up": "editor::SelectToStartOfExcerpt", - "cmd-shift-down": "editor::SelectToEndOfExcerpt", + "cmd-shift-up": "editor::SelectToBeginning", + "cmd-shift-down": "editor::SelectToEnd", "cmd-a": "editor::SelectAll", "cmd-l": "editor::SelectLine", "cmd-shift-i": "editor::Format", @@ -172,6 +172,16 @@ "alt-enter": "editor::OpenSelectionsInMultibuffer" } }, + { + "context": "Editor && multibuffer", + "use_key_equivalents": true, + "bindings": { + "cmd-up": "editor::MoveToStartOfExcerpt", + "cmd-down": "editor::MoveToStartOfNextExcerpt", + "cmd-shift-up": "editor::SelectToStartOfExcerpt", + "cmd-shift-down": "editor::SelectToStartOfNextExcerpt" + } + }, { "context": "Editor && mode == full && edit_prediction", "use_key_equivalents": true, diff --git a/crates/editor/src/actions.rs b/crates/editor/src/actions.rs index 5422cf7061..c386ba3dc1 100644 --- a/crates/editor/src/actions.rs +++ b/crates/editor/src/actions.rs @@ -340,7 +340,9 @@ gpui::actions!( MoveToPreviousWordStart, MoveToStartOfParagraph, MoveToStartOfExcerpt, + MoveToStartOfNextExcerpt, MoveToEndOfExcerpt, + MoveToEndOfPreviousExcerpt, MoveUp, Newline, NewlineAbove, @@ -378,7 +380,9 @@ gpui::actions!( SelectAll, SelectAllMatches, SelectToStartOfExcerpt, + SelectToStartOfNextExcerpt, SelectToEndOfExcerpt, + SelectToEndOfPreviousExcerpt, SelectDown, SelectEnclosingSymbol, SelectLargerSyntaxNode, diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 6400fe6a25..1404ccf3a1 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -1573,13 +1573,16 @@ impl Editor { } } - if let Some(extension) = self - .buffer - .read(cx) - .as_singleton() - .and_then(|buffer| buffer.read(cx).file()?.path().extension()?.to_str()) - { - key_context.set("extension", extension.to_string()); + if let Some(singleton_buffer) = self.buffer.read(cx).as_singleton() { + if let Some(extension) = singleton_buffer + .read(cx) + .file() + .and_then(|file| file.path().extension()?.to_str()) + { + key_context.set("extension", extension.to_string()); + } + } else { + key_context.add("multibuffer"); } if has_active_edit_prediction { @@ -9845,6 +9848,31 @@ impl Editor { }) } + pub fn move_to_start_of_next_excerpt( + &mut self, + _: &MoveToStartOfNextExcerpt, + window: &mut Window, + cx: &mut Context, + ) { + if matches!(self.mode, EditorMode::SingleLine { .. }) { + cx.propagate(); + return; + } + + self.change_selections(Some(Autoscroll::fit()), window, cx, |s| { + s.move_with(|map, selection| { + selection.collapse_to( + movement::start_of_excerpt( + map, + selection.head(), + workspace::searchable::Direction::Next, + ), + SelectionGoal::None, + ) + }); + }) + } + pub fn move_to_end_of_excerpt( &mut self, _: &MoveToEndOfExcerpt, @@ -9870,6 +9898,31 @@ impl Editor { }) } + pub fn move_to_end_of_previous_excerpt( + &mut self, + _: &MoveToEndOfPreviousExcerpt, + window: &mut Window, + cx: &mut Context, + ) { + if matches!(self.mode, EditorMode::SingleLine { .. }) { + cx.propagate(); + return; + } + + self.change_selections(Some(Autoscroll::fit()), window, cx, |s| { + s.move_with(|map, selection| { + selection.collapse_to( + movement::end_of_excerpt( + map, + selection.head(), + workspace::searchable::Direction::Prev, + ), + SelectionGoal::None, + ) + }); + }) + } + pub fn select_to_start_of_excerpt( &mut self, _: &SelectToStartOfExcerpt, @@ -9891,6 +9944,27 @@ impl Editor { }) } + pub fn select_to_start_of_next_excerpt( + &mut self, + _: &SelectToStartOfNextExcerpt, + window: &mut Window, + cx: &mut Context, + ) { + if matches!(self.mode, EditorMode::SingleLine { .. }) { + cx.propagate(); + return; + } + + self.change_selections(Some(Autoscroll::fit()), window, cx, |s| { + s.move_heads_with(|map, head, _| { + ( + movement::start_of_excerpt(map, head, workspace::searchable::Direction::Next), + SelectionGoal::None, + ) + }); + }) + } + pub fn select_to_end_of_excerpt( &mut self, _: &SelectToEndOfExcerpt, @@ -9912,6 +9986,27 @@ impl Editor { }) } + pub fn select_to_end_of_previous_excerpt( + &mut self, + _: &SelectToEndOfPreviousExcerpt, + window: &mut Window, + cx: &mut Context, + ) { + if matches!(self.mode, EditorMode::SingleLine { .. }) { + cx.propagate(); + return; + } + + self.change_selections(Some(Autoscroll::fit()), window, cx, |s| { + s.move_heads_with(|map, head, _| { + ( + movement::end_of_excerpt(map, head, workspace::searchable::Direction::Prev), + SelectionGoal::None, + ) + }); + }) + } + pub fn move_to_beginning( &mut self, _: &MoveToBeginning, diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index c4e7b08fa8..9ac4ce5ae0 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -282,7 +282,9 @@ impl EditorElement { register_action(editor, window, Editor::move_to_beginning); register_action(editor, window, Editor::move_to_end); register_action(editor, window, Editor::move_to_start_of_excerpt); + register_action(editor, window, Editor::move_to_start_of_next_excerpt); register_action(editor, window, Editor::move_to_end_of_excerpt); + register_action(editor, window, Editor::move_to_end_of_previous_excerpt); register_action(editor, window, Editor::select_up); register_action(editor, window, Editor::select_down); register_action(editor, window, Editor::select_left); @@ -296,7 +298,9 @@ impl EditorElement { register_action(editor, window, Editor::select_to_start_of_paragraph); register_action(editor, window, Editor::select_to_end_of_paragraph); register_action(editor, window, Editor::select_to_start_of_excerpt); + register_action(editor, window, Editor::select_to_start_of_next_excerpt); register_action(editor, window, Editor::select_to_end_of_excerpt); + register_action(editor, window, Editor::select_to_end_of_previous_excerpt); register_action(editor, window, Editor::select_to_beginning); register_action(editor, window, Editor::select_to_end); register_action(editor, window, Editor::select_all); diff --git a/crates/editor/src/movement.rs b/crates/editor/src/movement.rs index e3c5ca7dd1..47edb2cee1 100644 --- a/crates/editor/src/movement.rs +++ b/crates/editor/src/movement.rs @@ -448,7 +448,9 @@ pub fn end_of_excerpt( if start.row() > DisplayRow(0) { *start.row_mut() -= 1; } - map.clip_point(start, Bias::Left) + start = map.clip_point(start, Bias::Left); + *start.column_mut() = 0; + start } Direction::Next => { let mut end = excerpt.end_anchor().to_display_point(&map);