editor: Add MoveUpByLines and MoveDownByLines actions (#7208)

This adds four new actions:

- `editor::MoveUpByLines`
- `editor::MoveDownByLines`
- `editor::SelectUpByLines`
- `editor::SelectDownByLines`

They all take a count by which to move the cursor up and down.
(Requested by Adam here:
https://twitter.com/adamwathan/status/1753017094248018302)


Example `keymap.json` entries:

```json
{
  "context": "Editor",
  "bindings": [
    "alt-up":         [ "editor::MoveUpByLines",     { "lines": 3 } ],
    "alt-down":       [ "editor::MoveDownByLines",   { "lines": 3 } ],
    "alt-shift-up":   [ "editor::SelectUpByLines",   { "lines": 3 } ],
    "alt-shift-down": [ "editor::SelectDownByLines", { "lines": 3 } ]
  ]
}
```

They are *not* bound by default, so as to not conflict with the
`alt-up/down` bindings that already exist.

Release Notes:

- Added four new actions: `editor::MoveUpByLines`,
`editor::MoveDownByLines`, `editor::SelectUpByLines`,
`editor::SelectDownByLines` that can take a line count configuration and
move the cursor up by the count.

### Demo



https://github.com/zed-industries/zed/assets/1185253/e78d4077-5bd5-4d72-a806-67695698af5d




https://github.com/zed-industries/zed/assets/1185253/0b086ec9-eb90-40a2-9009-844a215e6378
This commit is contained in:
Thorsten Ball 2024-02-02 16:48:04 +01:00 committed by GitHub
parent 01ddf840f5
commit 11bd28870a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 113 additions and 1 deletions

View File

@ -70,6 +70,30 @@ pub struct FoldAt {
pub struct UnfoldAt {
pub buffer_row: u32,
}
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct MoveUpByLines {
#[serde(default)]
pub(super) lines: u32,
}
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct MoveDownByLines {
#[serde(default)]
pub(super) lines: u32,
}
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct SelectUpByLines {
#[serde(default)]
pub(super) lines: u32,
}
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct SelectDownByLines {
#[serde(default)]
pub(super) lines: u32,
}
impl_actions!(
editor,
[
@ -84,7 +108,11 @@ impl_actions!(
ConfirmCodeAction,
ToggleComments,
FoldAt,
UnfoldAt
UnfoldAt,
MoveUpByLines,
MoveDownByLines,
SelectUpByLines,
SelectDownByLines,
]
);

View File

@ -5379,6 +5379,86 @@ impl Editor {
})
}
pub fn move_up_by_lines(&mut self, action: &MoveUpByLines, cx: &mut ViewContext<Self>) {
if self.take_rename(true, cx).is_some() {
return;
}
if matches!(self.mode, EditorMode::SingleLine) {
cx.propagate();
return;
}
let text_layout_details = &self.text_layout_details(cx);
self.change_selections(Some(Autoscroll::fit()), cx, |s| {
let line_mode = s.line_mode;
s.move_with(|map, selection| {
if !selection.is_empty() && !line_mode {
selection.goal = SelectionGoal::None;
}
let (cursor, goal) = movement::up_by_rows(
map,
selection.start,
action.lines,
selection.goal,
false,
&text_layout_details,
);
selection.collapse_to(cursor, goal);
});
})
}
pub fn move_down_by_lines(&mut self, action: &MoveDownByLines, cx: &mut ViewContext<Self>) {
if self.take_rename(true, cx).is_some() {
return;
}
if matches!(self.mode, EditorMode::SingleLine) {
cx.propagate();
return;
}
let text_layout_details = &self.text_layout_details(cx);
self.change_selections(Some(Autoscroll::fit()), cx, |s| {
let line_mode = s.line_mode;
s.move_with(|map, selection| {
if !selection.is_empty() && !line_mode {
selection.goal = SelectionGoal::None;
}
let (cursor, goal) = movement::down_by_rows(
map,
selection.start,
action.lines,
selection.goal,
false,
&text_layout_details,
);
selection.collapse_to(cursor, goal);
});
})
}
pub fn select_down_by_lines(&mut self, action: &SelectDownByLines, cx: &mut ViewContext<Self>) {
let text_layout_details = &self.text_layout_details(cx);
self.change_selections(Some(Autoscroll::fit()), cx, |s| {
s.move_heads_with(|map, head, goal| {
movement::down_by_rows(map, head, action.lines, goal, false, &text_layout_details)
})
})
}
pub fn select_up_by_lines(&mut self, action: &SelectUpByLines, cx: &mut ViewContext<Self>) {
let text_layout_details = &self.text_layout_details(cx);
self.change_selections(Some(Autoscroll::fit()), cx, |s| {
s.move_heads_with(|map, head, goal| {
movement::up_by_rows(map, head, action.lines, goal, false, &text_layout_details)
})
})
}
pub fn move_page_up(&mut self, action: &MovePageUp, cx: &mut ViewContext<Self>) {
if self.take_rename(true, cx).is_some() {
return;

View File

@ -147,7 +147,11 @@ impl EditorElement {
register_action(view, cx, Editor::move_left);
register_action(view, cx, Editor::move_right);
register_action(view, cx, Editor::move_down);
register_action(view, cx, Editor::move_down_by_lines);
register_action(view, cx, Editor::select_down_by_lines);
register_action(view, cx, Editor::move_up);
register_action(view, cx, Editor::move_up_by_lines);
register_action(view, cx, Editor::select_up_by_lines);
register_action(view, cx, Editor::cancel);
register_action(view, cx, Editor::newline);
register_action(view, cx, Editor::newline_above);