Make cursor move to duplicated line when duplicating line up (#41004)
 Closes #40919 Follow-up of #39610 Release Notes: - When duplicating line up, fixed cursor to move to the duplicated line
This commit is contained in:
@@ -11551,7 +11551,7 @@ impl Editor {
|
||||
end
|
||||
} else {
|
||||
text.push('\n');
|
||||
Point::new(rows.end.0, 0)
|
||||
Point::new(rows.start.0, 0)
|
||||
}
|
||||
} else {
|
||||
text.push('\n');
|
||||
@@ -11567,11 +11567,57 @@ impl Editor {
|
||||
}
|
||||
}
|
||||
|
||||
self.transact(window, cx, |this, _, cx| {
|
||||
self.transact(window, cx, |this, window, cx| {
|
||||
this.buffer.update(cx, |buffer, cx| {
|
||||
buffer.edit(edits, None, cx);
|
||||
});
|
||||
|
||||
// When duplicating upward with whole lines, move the cursor to the duplicated line
|
||||
if upwards && whole_lines {
|
||||
let display_map = this.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
|
||||
this.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
let mut new_ranges = Vec::new();
|
||||
let selections = s.all::<Point>(&display_map);
|
||||
let mut selections_iter = selections.iter().peekable();
|
||||
|
||||
while let Some(first_selection) = selections_iter.next() {
|
||||
// Group contiguous selections together to find the total row span
|
||||
let mut group_selections = vec![first_selection];
|
||||
let mut rows = first_selection.spanned_rows(false, &display_map);
|
||||
|
||||
while let Some(next_selection) = selections_iter.peek() {
|
||||
let next_rows = next_selection.spanned_rows(false, &display_map);
|
||||
if next_rows.start < rows.end {
|
||||
rows.end = next_rows.end;
|
||||
group_selections.push(selections_iter.next().unwrap());
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let row_count = rows.end.0 - rows.start.0;
|
||||
|
||||
// Move all selections in this group up by the total number of duplicated rows
|
||||
for selection in group_selections {
|
||||
let new_start = Point::new(
|
||||
selection.start.row.saturating_sub(row_count),
|
||||
selection.start.column,
|
||||
);
|
||||
|
||||
let new_end = Point::new(
|
||||
selection.end.row.saturating_sub(row_count),
|
||||
selection.end.column,
|
||||
);
|
||||
|
||||
new_ranges.push(new_start..new_end);
|
||||
}
|
||||
}
|
||||
|
||||
s.select_ranges(new_ranges);
|
||||
});
|
||||
}
|
||||
|
||||
this.request_autoscroll(Autoscroll::fit(), cx);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5646,8 +5646,8 @@ fn test_duplicate_line(cx: &mut TestAppContext) {
|
||||
);
|
||||
});
|
||||
|
||||
// With `move_upwards` the selections stay in place, except for
|
||||
// the lines inserted above them
|
||||
// With `duplicate_line_up` the selections move to the duplicated lines,
|
||||
// which are inserted above the original lines
|
||||
let editor = cx.add_window(|window, cx| {
|
||||
let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
|
||||
build_editor(buffer, window, cx)
|
||||
@@ -5669,7 +5669,7 @@ fn test_duplicate_line(cx: &mut TestAppContext) {
|
||||
DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 1),
|
||||
DisplayPoint::new(DisplayRow(0), 2)..DisplayPoint::new(DisplayRow(0), 2),
|
||||
DisplayPoint::new(DisplayRow(2), 0)..DisplayPoint::new(DisplayRow(2), 0),
|
||||
DisplayPoint::new(DisplayRow(6), 0)..DisplayPoint::new(DisplayRow(6), 0),
|
||||
DisplayPoint::new(DisplayRow(5), 0)..DisplayPoint::new(DisplayRow(5), 0),
|
||||
]
|
||||
);
|
||||
});
|
||||
@@ -26888,8 +26888,8 @@ fn test_duplicate_line_up_on_last_line_without_newline(cx: &mut TestAppContext)
|
||||
|
||||
assert_eq!(
|
||||
editor.selections.display_ranges(cx),
|
||||
vec![DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 0)],
|
||||
"Selection should remain on the original line"
|
||||
vec![DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 0)],
|
||||
"Selection should move to the duplicated line"
|
||||
);
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
Reference in New Issue
Block a user