Add alt-s to helix mode (#33918)
Closes #31562 Release Notes: - Helix: bind alt-s to SplitSelectionIntoLines --------- Co-authored-by: Ben Kunkle <ben@zed.dev>
This commit is contained in:
parent
9a2b7ef372
commit
5a9546ff4b
4 changed files with 40 additions and 9 deletions
|
@ -407,6 +407,7 @@
|
||||||
"g w": "vim::PushRewrap",
|
"g w": "vim::PushRewrap",
|
||||||
"insert": "vim::InsertBefore",
|
"insert": "vim::InsertBefore",
|
||||||
"alt-.": "vim::RepeatFind",
|
"alt-.": "vim::RepeatFind",
|
||||||
|
"alt-s": ["editor::SplitSelectionIntoLines", { "keep_selections": true }],
|
||||||
// tree-sitter related commands
|
// tree-sitter related commands
|
||||||
"[ x": "editor::SelectLargerSyntaxNode",
|
"[ x": "editor::SelectLargerSyntaxNode",
|
||||||
"] x": "editor::SelectSmallerSyntaxNode",
|
"] x": "editor::SelectSmallerSyntaxNode",
|
||||||
|
|
|
@ -273,6 +273,16 @@ pub enum UuidVersion {
|
||||||
V7,
|
V7,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Splits selection into individual lines.
|
||||||
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub struct SplitSelectionIntoLines {
|
||||||
|
/// Keep the text selected after splitting instead of collapsing to cursors.
|
||||||
|
#[serde(default)]
|
||||||
|
pub keep_selections: bool,
|
||||||
|
}
|
||||||
|
|
||||||
/// Goes to the next diagnostic in the file.
|
/// Goes to the next diagnostic in the file.
|
||||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)]
|
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)]
|
||||||
#[action(namespace = editor)]
|
#[action(namespace = editor)]
|
||||||
|
@ -672,8 +682,6 @@ actions!(
|
||||||
SortLinesCaseInsensitive,
|
SortLinesCaseInsensitive,
|
||||||
/// Sorts selected lines case-sensitively.
|
/// Sorts selected lines case-sensitively.
|
||||||
SortLinesCaseSensitive,
|
SortLinesCaseSensitive,
|
||||||
/// Splits selection into individual lines.
|
|
||||||
SplitSelectionIntoLines,
|
|
||||||
/// Stops the language server for the current file.
|
/// Stops the language server for the current file.
|
||||||
StopLanguageServer,
|
StopLanguageServer,
|
||||||
/// Switches between source and header files.
|
/// Switches between source and header files.
|
||||||
|
|
|
@ -13612,7 +13612,7 @@ impl Editor {
|
||||||
|
|
||||||
pub fn split_selection_into_lines(
|
pub fn split_selection_into_lines(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &SplitSelectionIntoLines,
|
action: &SplitSelectionIntoLines,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
|
@ -13629,8 +13629,21 @@ impl Editor {
|
||||||
let buffer = self.buffer.read(cx).read(cx);
|
let buffer = self.buffer.read(cx).read(cx);
|
||||||
for selection in selections {
|
for selection in selections {
|
||||||
for row in selection.start.row..selection.end.row {
|
for row in selection.start.row..selection.end.row {
|
||||||
let cursor = Point::new(row, buffer.line_len(MultiBufferRow(row)));
|
let line_start = Point::new(row, 0);
|
||||||
new_selection_ranges.push(cursor..cursor);
|
let line_end = Point::new(row, buffer.line_len(MultiBufferRow(row)));
|
||||||
|
|
||||||
|
if action.keep_selections {
|
||||||
|
// Keep the selection range for each line
|
||||||
|
let selection_start = if row == selection.start.row {
|
||||||
|
selection.start
|
||||||
|
} else {
|
||||||
|
line_start
|
||||||
|
};
|
||||||
|
new_selection_ranges.push(selection_start..line_end);
|
||||||
|
} else {
|
||||||
|
// Collapse to cursor at end of line
|
||||||
|
new_selection_ranges.push(line_end..line_end);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_multiline_selection = selection.start.row != selection.end.row;
|
let is_multiline_selection = selection.start.row != selection.end.row;
|
||||||
|
@ -13638,7 +13651,16 @@ impl Editor {
|
||||||
// so this action feels more ergonomic when paired with other selection operations
|
// so this action feels more ergonomic when paired with other selection operations
|
||||||
let should_skip_last = is_multiline_selection && selection.end.column == 0;
|
let should_skip_last = is_multiline_selection && selection.end.column == 0;
|
||||||
if !should_skip_last {
|
if !should_skip_last {
|
||||||
new_selection_ranges.push(selection.end..selection.end);
|
if action.keep_selections {
|
||||||
|
if is_multiline_selection {
|
||||||
|
let line_start = Point::new(selection.end.row, 0);
|
||||||
|
new_selection_ranges.push(line_start..selection.end);
|
||||||
|
} else {
|
||||||
|
new_selection_ranges.push(selection.start..selection.end);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
new_selection_ranges.push(selection.end..selection.end);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6401,7 +6401,7 @@ async fn test_split_selection_into_lines(cx: &mut TestAppContext) {
|
||||||
fn test(cx: &mut EditorTestContext, initial_state: &'static str, expected_state: &'static str) {
|
fn test(cx: &mut EditorTestContext, initial_state: &'static str, expected_state: &'static str) {
|
||||||
cx.set_state(initial_state);
|
cx.set_state(initial_state);
|
||||||
cx.update_editor(|e, window, cx| {
|
cx.update_editor(|e, window, cx| {
|
||||||
e.split_selection_into_lines(&SplitSelectionIntoLines, window, cx)
|
e.split_selection_into_lines(&Default::default(), window, cx)
|
||||||
});
|
});
|
||||||
cx.assert_editor_state(expected_state);
|
cx.assert_editor_state(expected_state);
|
||||||
}
|
}
|
||||||
|
@ -6489,7 +6489,7 @@ async fn test_split_selection_into_lines_interacting_with_creases(cx: &mut TestA
|
||||||
DisplayPoint::new(DisplayRow(4), 4)..DisplayPoint::new(DisplayRow(4), 4),
|
DisplayPoint::new(DisplayRow(4), 4)..DisplayPoint::new(DisplayRow(4), 4),
|
||||||
])
|
])
|
||||||
});
|
});
|
||||||
editor.split_selection_into_lines(&SplitSelectionIntoLines, window, cx);
|
editor.split_selection_into_lines(&Default::default(), window, cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
editor.display_text(cx),
|
editor.display_text(cx),
|
||||||
"aaaaa\nbbbbb\nccc⋯eeee\nfffff\nggggg\n⋯i"
|
"aaaaa\nbbbbb\nccc⋯eeee\nfffff\nggggg\n⋯i"
|
||||||
|
@ -6505,7 +6505,7 @@ async fn test_split_selection_into_lines_interacting_with_creases(cx: &mut TestA
|
||||||
DisplayPoint::new(DisplayRow(5), 0)..DisplayPoint::new(DisplayRow(0), 1)
|
DisplayPoint::new(DisplayRow(5), 0)..DisplayPoint::new(DisplayRow(0), 1)
|
||||||
])
|
])
|
||||||
});
|
});
|
||||||
editor.split_selection_into_lines(&SplitSelectionIntoLines, window, cx);
|
editor.split_selection_into_lines(&Default::default(), window, cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
editor.display_text(cx),
|
editor.display_text(cx),
|
||||||
"aaaaa\nbbbbb\nccccc\nddddd\neeeee\nfffff\nggggg\nhhhhh\niiiii"
|
"aaaaa\nbbbbb\nccccc\nddddd\neeeee\nfffff\nggggg\nhhhhh\niiiii"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue