Skip to content

Commit 450d727

Browse files
authored
Fixes to excerpt movement actions and bindings + add multibuffer and singleton_buffer key contexts (#26264)
Closes #26002 Release Notes: - Added `multibuffer` key context. - `cmd-down` and `cmd-shift-down` on Mac now moves to the end of the last line of a singleton buffer instead of the beginning. In multibuffers, these now move to the start of the next excerpt. - Fixed `vim::PreviousSectionEnd` (bound to `[ ]`) to move to the beginning of the line, matching the behavior of `vim::NextSectionEnd`. - Added `editor::MoveToStartOfNextExcerpt` and `editor::MoveToEndOfPreviousExcerpt`.
1 parent 60b3eb3 commit 450d727

File tree

5 files changed

+127
-12
lines changed

5 files changed

+127
-12
lines changed

assets/keymaps/default-macos.json

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@
108108
"cmd-right": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": true }],
109109
"ctrl-e": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": false }],
110110
"end": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": true }],
111-
"cmd-up": "editor::MoveToStartOfExcerpt",
112-
"cmd-down": "editor::MoveToEndOfExcerpt",
111+
"cmd-up": "editor::MoveToBeginning",
112+
"cmd-down": "editor::MoveToEnd",
113113
"cmd-home": "editor::MoveToBeginning", // Typed via `cmd-fn-left`
114114
"cmd-end": "editor::MoveToEnd", // Typed via `cmd-fn-right`
115115
"shift-up": "editor::SelectUp",
@@ -124,8 +124,8 @@
124124
"alt-shift-right": "editor::SelectToNextWordEnd", // cursorWordRightSelect
125125
"ctrl-shift-up": "editor::SelectToStartOfParagraph",
126126
"ctrl-shift-down": "editor::SelectToEndOfParagraph",
127-
"cmd-shift-up": "editor::SelectToStartOfExcerpt",
128-
"cmd-shift-down": "editor::SelectToEndOfExcerpt",
127+
"cmd-shift-up": "editor::SelectToBeginning",
128+
"cmd-shift-down": "editor::SelectToEnd",
129129
"cmd-a": "editor::SelectAll",
130130
"cmd-l": "editor::SelectLine",
131131
"cmd-shift-i": "editor::Format",
@@ -172,6 +172,16 @@
172172
"alt-enter": "editor::OpenSelectionsInMultibuffer"
173173
}
174174
},
175+
{
176+
"context": "Editor && multibuffer",
177+
"use_key_equivalents": true,
178+
"bindings": {
179+
"cmd-up": "editor::MoveToStartOfExcerpt",
180+
"cmd-down": "editor::MoveToStartOfNextExcerpt",
181+
"cmd-shift-up": "editor::SelectToStartOfExcerpt",
182+
"cmd-shift-down": "editor::SelectToStartOfNextExcerpt"
183+
}
184+
},
175185
{
176186
"context": "Editor && mode == full && edit_prediction",
177187
"use_key_equivalents": true,

crates/editor/src/actions.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,9 @@ gpui::actions!(
340340
MoveToPreviousWordStart,
341341
MoveToStartOfParagraph,
342342
MoveToStartOfExcerpt,
343+
MoveToStartOfNextExcerpt,
343344
MoveToEndOfExcerpt,
345+
MoveToEndOfPreviousExcerpt,
344346
MoveUp,
345347
Newline,
346348
NewlineAbove,
@@ -378,7 +380,9 @@ gpui::actions!(
378380
SelectAll,
379381
SelectAllMatches,
380382
SelectToStartOfExcerpt,
383+
SelectToStartOfNextExcerpt,
381384
SelectToEndOfExcerpt,
385+
SelectToEndOfPreviousExcerpt,
382386
SelectDown,
383387
SelectEnclosingSymbol,
384388
SelectLargerSyntaxNode,

crates/editor/src/editor.rs

Lines changed: 102 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,13 +1573,16 @@ impl Editor {
15731573
}
15741574
}
15751575

1576-
if let Some(extension) = self
1577-
.buffer
1578-
.read(cx)
1579-
.as_singleton()
1580-
.and_then(|buffer| buffer.read(cx).file()?.path().extension()?.to_str())
1581-
{
1582-
key_context.set("extension", extension.to_string());
1576+
if let Some(singleton_buffer) = self.buffer.read(cx).as_singleton() {
1577+
if let Some(extension) = singleton_buffer
1578+
.read(cx)
1579+
.file()
1580+
.and_then(|file| file.path().extension()?.to_str())
1581+
{
1582+
key_context.set("extension", extension.to_string());
1583+
}
1584+
} else {
1585+
key_context.add("multibuffer");
15831586
}
15841587

15851588
if has_active_edit_prediction {
@@ -9845,6 +9848,31 @@ impl Editor {
98459848
})
98469849
}
98479850

9851+
pub fn move_to_start_of_next_excerpt(
9852+
&mut self,
9853+
_: &MoveToStartOfNextExcerpt,
9854+
window: &mut Window,
9855+
cx: &mut Context<Self>,
9856+
) {
9857+
if matches!(self.mode, EditorMode::SingleLine { .. }) {
9858+
cx.propagate();
9859+
return;
9860+
}
9861+
9862+
self.change_selections(Some(Autoscroll::fit()), window, cx, |s| {
9863+
s.move_with(|map, selection| {
9864+
selection.collapse_to(
9865+
movement::start_of_excerpt(
9866+
map,
9867+
selection.head(),
9868+
workspace::searchable::Direction::Next,
9869+
),
9870+
SelectionGoal::None,
9871+
)
9872+
});
9873+
})
9874+
}
9875+
98489876
pub fn move_to_end_of_excerpt(
98499877
&mut self,
98509878
_: &MoveToEndOfExcerpt,
@@ -9870,6 +9898,31 @@ impl Editor {
98709898
})
98719899
}
98729900

9901+
pub fn move_to_end_of_previous_excerpt(
9902+
&mut self,
9903+
_: &MoveToEndOfPreviousExcerpt,
9904+
window: &mut Window,
9905+
cx: &mut Context<Self>,
9906+
) {
9907+
if matches!(self.mode, EditorMode::SingleLine { .. }) {
9908+
cx.propagate();
9909+
return;
9910+
}
9911+
9912+
self.change_selections(Some(Autoscroll::fit()), window, cx, |s| {
9913+
s.move_with(|map, selection| {
9914+
selection.collapse_to(
9915+
movement::end_of_excerpt(
9916+
map,
9917+
selection.head(),
9918+
workspace::searchable::Direction::Prev,
9919+
),
9920+
SelectionGoal::None,
9921+
)
9922+
});
9923+
})
9924+
}
9925+
98739926
pub fn select_to_start_of_excerpt(
98749927
&mut self,
98759928
_: &SelectToStartOfExcerpt,
@@ -9891,6 +9944,27 @@ impl Editor {
98919944
})
98929945
}
98939946

9947+
pub fn select_to_start_of_next_excerpt(
9948+
&mut self,
9949+
_: &SelectToStartOfNextExcerpt,
9950+
window: &mut Window,
9951+
cx: &mut Context<Self>,
9952+
) {
9953+
if matches!(self.mode, EditorMode::SingleLine { .. }) {
9954+
cx.propagate();
9955+
return;
9956+
}
9957+
9958+
self.change_selections(Some(Autoscroll::fit()), window, cx, |s| {
9959+
s.move_heads_with(|map, head, _| {
9960+
(
9961+
movement::start_of_excerpt(map, head, workspace::searchable::Direction::Next),
9962+
SelectionGoal::None,
9963+
)
9964+
});
9965+
})
9966+
}
9967+
98949968
pub fn select_to_end_of_excerpt(
98959969
&mut self,
98969970
_: &SelectToEndOfExcerpt,
@@ -9912,6 +9986,27 @@ impl Editor {
99129986
})
99139987
}
99149988

9989+
pub fn select_to_end_of_previous_excerpt(
9990+
&mut self,
9991+
_: &SelectToEndOfPreviousExcerpt,
9992+
window: &mut Window,
9993+
cx: &mut Context<Self>,
9994+
) {
9995+
if matches!(self.mode, EditorMode::SingleLine { .. }) {
9996+
cx.propagate();
9997+
return;
9998+
}
9999+
10000+
self.change_selections(Some(Autoscroll::fit()), window, cx, |s| {
10001+
s.move_heads_with(|map, head, _| {
10002+
(
10003+
movement::end_of_excerpt(map, head, workspace::searchable::Direction::Prev),
10004+
SelectionGoal::None,
10005+
)
10006+
});
10007+
})
10008+
}
10009+
991510010
pub fn move_to_beginning(
991610011
&mut self,
991710012
_: &MoveToBeginning,

crates/editor/src/element.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,9 @@ impl EditorElement {
282282
register_action(editor, window, Editor::move_to_beginning);
283283
register_action(editor, window, Editor::move_to_end);
284284
register_action(editor, window, Editor::move_to_start_of_excerpt);
285+
register_action(editor, window, Editor::move_to_start_of_next_excerpt);
285286
register_action(editor, window, Editor::move_to_end_of_excerpt);
287+
register_action(editor, window, Editor::move_to_end_of_previous_excerpt);
286288
register_action(editor, window, Editor::select_up);
287289
register_action(editor, window, Editor::select_down);
288290
register_action(editor, window, Editor::select_left);
@@ -296,7 +298,9 @@ impl EditorElement {
296298
register_action(editor, window, Editor::select_to_start_of_paragraph);
297299
register_action(editor, window, Editor::select_to_end_of_paragraph);
298300
register_action(editor, window, Editor::select_to_start_of_excerpt);
301+
register_action(editor, window, Editor::select_to_start_of_next_excerpt);
299302
register_action(editor, window, Editor::select_to_end_of_excerpt);
303+
register_action(editor, window, Editor::select_to_end_of_previous_excerpt);
300304
register_action(editor, window, Editor::select_to_beginning);
301305
register_action(editor, window, Editor::select_to_end);
302306
register_action(editor, window, Editor::select_all);

crates/editor/src/movement.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,9 @@ pub fn end_of_excerpt(
448448
if start.row() > DisplayRow(0) {
449449
*start.row_mut() -= 1;
450450
}
451-
map.clip_point(start, Bias::Left)
451+
start = map.clip_point(start, Bias::Left);
452+
*start.column_mut() = 0;
453+
start
452454
}
453455
Direction::Next => {
454456
let mut end = excerpt.end_anchor().to_display_point(&map);

0 commit comments

Comments
 (0)