Delete till previous tabstop when backspacing within indent column
This commit is contained in:
parent
9076345a8f
commit
ee6d7fc6d5
3 changed files with 68 additions and 23 deletions
|
@ -2638,11 +2638,25 @@ impl Editor {
|
|||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
for selection in &mut selections {
|
||||
if selection.is_empty() {
|
||||
let head = selection.head().to_display_point(&display_map);
|
||||
let cursor = movement::left(&display_map, head)
|
||||
.unwrap()
|
||||
.to_point(&display_map);
|
||||
selection.set_head(cursor);
|
||||
let old_head = selection.head();
|
||||
let (buffer, line_buffer_range) = display_map
|
||||
.buffer_snapshot
|
||||
.buffer_line_for_row(old_head.row)
|
||||
.unwrap();
|
||||
let indent_column = buffer.indent_column_for_line(line_buffer_range.start.row);
|
||||
let mut new_head =
|
||||
movement::left(&display_map, old_head.to_display_point(&display_map))
|
||||
.unwrap()
|
||||
.to_point(&display_map);
|
||||
if old_head.column <= indent_column && old_head.column > 0 {
|
||||
let indent = buffer.indent_size();
|
||||
new_head = cmp::min(
|
||||
new_head,
|
||||
Point::new(old_head.row, ((old_head.column - 1) / indent) * indent),
|
||||
);
|
||||
}
|
||||
|
||||
selection.set_head(new_head);
|
||||
selection.goal = SelectionGoal::None;
|
||||
}
|
||||
}
|
||||
|
@ -7153,14 +7167,13 @@ mod tests {
|
|||
|
||||
#[gpui::test]
|
||||
fn test_backspace(cx: &mut gpui::MutableAppContext) {
|
||||
let buffer =
|
||||
MultiBuffer::build_simple("one two three\nfour five six\nseven eight nine\nten\n", cx);
|
||||
let settings = Settings::test(&cx);
|
||||
let (_, view) = cx.add_window(Default::default(), |cx| {
|
||||
build_editor(buffer.clone(), settings, cx)
|
||||
build_editor(MultiBuffer::build_simple("", cx), settings, cx)
|
||||
});
|
||||
|
||||
view.update(cx, |view, cx| {
|
||||
view.set_text("one two three\nfour five six\nseven eight nine\nten\n", cx);
|
||||
view.select_display_ranges(
|
||||
&[
|
||||
// an empty selection - the preceding character is deleted
|
||||
|
@ -7173,12 +7186,28 @@ mod tests {
|
|||
cx,
|
||||
);
|
||||
view.backspace(&Backspace, cx);
|
||||
});
|
||||
assert_eq!(view.text(cx), "oe two three\nfou five six\nseven ten\n");
|
||||
|
||||
assert_eq!(
|
||||
buffer.read(cx).read(cx).text(),
|
||||
"oe two three\nfou five six\nseven ten\n"
|
||||
);
|
||||
view.set_text(" one\n two\n three\n four", cx);
|
||||
view.select_display_ranges(
|
||||
&[
|
||||
// cursors at the the end of leading indent - last indent is deleted
|
||||
DisplayPoint::new(0, 4)..DisplayPoint::new(0, 4),
|
||||
DisplayPoint::new(1, 8)..DisplayPoint::new(1, 8),
|
||||
// cursors inside leading indent - overlapping indent deletions are coalesced
|
||||
DisplayPoint::new(2, 4)..DisplayPoint::new(2, 4),
|
||||
DisplayPoint::new(2, 5)..DisplayPoint::new(2, 5),
|
||||
DisplayPoint::new(2, 6)..DisplayPoint::new(2, 6),
|
||||
// cursor at the beginning of a line - preceding newline is deleted
|
||||
DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0),
|
||||
// selection inside leading indent - only the selected character is deleted
|
||||
DisplayPoint::new(3, 2)..DisplayPoint::new(3, 3),
|
||||
],
|
||||
cx,
|
||||
);
|
||||
view.backspace(&Backspace, cx);
|
||||
assert_eq!(view.text(cx), "one\n two\n three four");
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
|
|
|
@ -1657,7 +1657,7 @@ impl MultiBufferSnapshot {
|
|||
}
|
||||
}
|
||||
|
||||
fn buffer_line_for_row(&self, row: u32) -> Option<(&BufferSnapshot, Range<Point>)> {
|
||||
pub fn buffer_line_for_row(&self, row: u32) -> Option<(&BufferSnapshot, Range<Point>)> {
|
||||
let mut cursor = self.excerpts.cursor::<Point>();
|
||||
cursor.seek(&Point::new(row, 0), Bias::Right, &());
|
||||
if let Some(excerpt) = cursor.item() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue