Add stop_at_indent for Editor::DeleteToBeginningOfLine (#25688)
Added test_beginning_of_line_stop_at_indent editor test - Follow-up to: https://github.com/zed-industries/zed/pull/25428 - Replaces: https://github.com/zed-industries/zed/pull/25346 This is all authored by @felixpackard in #25346 I just updated it to use `stop_at_indent` instead of `stop_at_first_char`. Release Notes: - Added support for `stop_at_indent` to `Editor::DeleteToBeginningOfLine` (thanks [@felixpackard](https://github.com/felixpackard)) Co-authored-by: Felix Packard <felix@rigr.gg>
This commit is contained in:
parent
d115cb1944
commit
aa1ab50656
3 changed files with 123 additions and 5 deletions
|
@ -35,6 +35,13 @@ pub struct SelectToBeginningOfLine {
|
|||
pub stop_at_indent: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct DeleteToBeginningOfLine {
|
||||
#[serde(default)]
|
||||
pub(super) stop_at_indent: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct MovePageUp {
|
||||
|
@ -226,6 +233,7 @@ impl_actions!(
|
|||
ComposeCompletion,
|
||||
ConfirmCodeAction,
|
||||
ConfirmCompletion,
|
||||
DeleteToBeginningOfLine,
|
||||
DeleteToNextWordEnd,
|
||||
DeleteToPreviousWordStart,
|
||||
ExpandExcerpts,
|
||||
|
@ -292,7 +300,6 @@ gpui::actions!(
|
|||
CutToEndOfLine,
|
||||
Delete,
|
||||
DeleteLine,
|
||||
DeleteToBeginningOfLine,
|
||||
DeleteToEndOfLine,
|
||||
DeleteToNextSubwordEnd,
|
||||
DeleteToPreviousSubwordStart,
|
||||
|
|
|
@ -9516,7 +9516,7 @@ impl Editor {
|
|||
|
||||
pub fn delete_to_beginning_of_line(
|
||||
&mut self,
|
||||
_: &DeleteToBeginningOfLine,
|
||||
action: &DeleteToBeginningOfLine,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
|
@ -9530,7 +9530,7 @@ impl Editor {
|
|||
this.select_to_beginning_of_line(
|
||||
&SelectToBeginningOfLine {
|
||||
stop_at_soft_wraps: false,
|
||||
stop_at_indent: false,
|
||||
stop_at_indent: action.stop_at_indent,
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
|
|
|
@ -1514,6 +1514,10 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) {
|
|||
stop_at_indent: true,
|
||||
};
|
||||
|
||||
let delete_to_beg = DeleteToBeginningOfLine {
|
||||
stop_at_indent: false,
|
||||
};
|
||||
|
||||
let move_to_end = MoveToEndOfLine {
|
||||
stop_at_soft_wraps: true,
|
||||
};
|
||||
|
@ -1672,7 +1676,7 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) {
|
|||
});
|
||||
|
||||
_ = editor.update(cx, |editor, window, cx| {
|
||||
editor.delete_to_beginning_of_line(&DeleteToBeginningOfLine, window, cx);
|
||||
editor.delete_to_beginning_of_line(&delete_to_beg, window, cx);
|
||||
assert_eq!(editor.display_text(cx), "\n");
|
||||
assert_eq!(
|
||||
editor.selections.display_ranges(cx),
|
||||
|
@ -1778,6 +1782,107 @@ fn test_beginning_end_of_line_ignore_soft_wrap(cx: &mut TestAppContext) {
|
|||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn test_beginning_of_line_stop_at_indent(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
|
||||
let move_to_beg = MoveToBeginningOfLine {
|
||||
stop_at_soft_wraps: true,
|
||||
stop_at_indent: true,
|
||||
};
|
||||
|
||||
let select_to_beg = SelectToBeginningOfLine {
|
||||
stop_at_soft_wraps: true,
|
||||
stop_at_indent: true,
|
||||
};
|
||||
|
||||
let delete_to_beg = DeleteToBeginningOfLine {
|
||||
stop_at_indent: true,
|
||||
};
|
||||
|
||||
let move_to_end = MoveToEndOfLine {
|
||||
stop_at_soft_wraps: false,
|
||||
};
|
||||
|
||||
let editor = cx.add_window(|window, cx| {
|
||||
let buffer = MultiBuffer::build_simple("abc\n def", cx);
|
||||
build_editor(buffer, window, cx)
|
||||
});
|
||||
|
||||
_ = editor.update(cx, |editor, window, cx| {
|
||||
editor.change_selections(None, window, cx, |s| {
|
||||
s.select_display_ranges([
|
||||
DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(0), 1),
|
||||
DisplayPoint::new(DisplayRow(1), 4)..DisplayPoint::new(DisplayRow(1), 4),
|
||||
]);
|
||||
});
|
||||
|
||||
// Moving to the beginning of the line should put the first cursor at the beginning of the line,
|
||||
// and the second cursor at the first non-whitespace character in the line.
|
||||
editor.move_to_beginning_of_line(&move_to_beg, window, cx);
|
||||
assert_eq!(
|
||||
editor.selections.display_ranges(cx),
|
||||
&[
|
||||
DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 0),
|
||||
DisplayPoint::new(DisplayRow(1), 2)..DisplayPoint::new(DisplayRow(1), 2),
|
||||
]
|
||||
);
|
||||
|
||||
// Moving to the beginning of the line again should be a no-op for the first cursor,
|
||||
// and should move the second cursor to the beginning of the line.
|
||||
editor.move_to_beginning_of_line(&move_to_beg, window, cx);
|
||||
assert_eq!(
|
||||
editor.selections.display_ranges(cx),
|
||||
&[
|
||||
DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 0),
|
||||
DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 0),
|
||||
]
|
||||
);
|
||||
|
||||
// Moving to the beginning of the line again should still be a no-op for the first cursor,
|
||||
// and should move the second cursor back to the first non-whitespace character in the line.
|
||||
editor.move_to_beginning_of_line(&move_to_beg, window, cx);
|
||||
assert_eq!(
|
||||
editor.selections.display_ranges(cx),
|
||||
&[
|
||||
DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 0),
|
||||
DisplayPoint::new(DisplayRow(1), 2)..DisplayPoint::new(DisplayRow(1), 2),
|
||||
]
|
||||
);
|
||||
|
||||
// Selecting to the beginning of the line should select to the beginning of the line for the first cursor,
|
||||
// and to the first non-whitespace character in the line for the second cursor.
|
||||
editor.move_to_end_of_line(&move_to_end, window, cx);
|
||||
editor.move_left(&MoveLeft, window, cx);
|
||||
editor.select_to_beginning_of_line(&select_to_beg, window, cx);
|
||||
assert_eq!(
|
||||
editor.selections.display_ranges(cx),
|
||||
&[
|
||||
DisplayPoint::new(DisplayRow(0), 2)..DisplayPoint::new(DisplayRow(0), 0),
|
||||
DisplayPoint::new(DisplayRow(1), 4)..DisplayPoint::new(DisplayRow(1), 2),
|
||||
]
|
||||
);
|
||||
|
||||
// Selecting to the beginning of the line again should be a no-op for the first cursor,
|
||||
// and should select to the beginning of the line for the second cursor.
|
||||
editor.select_to_beginning_of_line(&select_to_beg, window, cx);
|
||||
assert_eq!(
|
||||
editor.selections.display_ranges(cx),
|
||||
&[
|
||||
DisplayPoint::new(DisplayRow(0), 2)..DisplayPoint::new(DisplayRow(0), 0),
|
||||
DisplayPoint::new(DisplayRow(1), 4)..DisplayPoint::new(DisplayRow(1), 0),
|
||||
]
|
||||
);
|
||||
|
||||
// Deleting to the beginning of the line should delete to the beginning of the line for the first cursor,
|
||||
// and should delete to the first non-whitespace character in the line for the second cursor.
|
||||
editor.move_to_end_of_line(&move_to_end, window, cx);
|
||||
editor.move_left(&MoveLeft, window, cx);
|
||||
editor.delete_to_beginning_of_line(&delete_to_beg, window, cx);
|
||||
assert_eq!(editor.text(cx), "c\n f");
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn test_prev_next_word_boundary(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
|
@ -2295,7 +2400,13 @@ async fn test_delete_to_beginning_of_line(cx: &mut TestAppContext) {
|
|||
let mut cx = EditorTestContext::new(cx).await;
|
||||
cx.set_state("one «two threeˇ» four");
|
||||
cx.update_editor(|editor, window, cx| {
|
||||
editor.delete_to_beginning_of_line(&DeleteToBeginningOfLine, window, cx);
|
||||
editor.delete_to_beginning_of_line(
|
||||
&DeleteToBeginningOfLine {
|
||||
stop_at_indent: false,
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
assert_eq!(editor.text(cx), " four");
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue