editor: Fix inconsistent relative indent when using tab with multi cursors (#29519)
Do not insert hard/soft tabs for cursors at the suggested indent level if any other cursor lies before the suggested indent level. This PR brings us one step closer to fixing https://github.com/zed-industries/zed/issues/26157. Before: https://github.com/user-attachments/assets/8fd5cde4-99f4-4363-9292-5da8dadab658 After: https://github.com/user-attachments/assets/17c9f8ca-5842-452b-8665-7c7138d50162 Release Notes: - Fixed an issue where using tab with multiple cursors would result in inconsistent relative indentation across lines.
This commit is contained in:
parent
f060918b57
commit
52eef3c35d
@ -8620,6 +8620,15 @@ impl Editor {
|
||||
let rows_iter = selections.iter().map(|s| s.head().row);
|
||||
let suggested_indents = snapshot.suggested_indents(rows_iter, cx);
|
||||
|
||||
let has_some_cursor_in_whitespace = selections
|
||||
.iter()
|
||||
.filter(|selection| selection.is_empty())
|
||||
.any(|selection| {
|
||||
let cursor = selection.head();
|
||||
let current_indent = snapshot.indent_size_for_line(MultiBufferRow(cursor.row));
|
||||
cursor.column < current_indent.len
|
||||
});
|
||||
|
||||
let mut edits = Vec::new();
|
||||
let mut prev_edited_row = 0;
|
||||
let mut row_delta = 0;
|
||||
@ -8643,6 +8652,15 @@ impl Editor {
|
||||
if let Some(suggested_indent) =
|
||||
suggested_indents.get(&MultiBufferRow(cursor.row)).copied()
|
||||
{
|
||||
// If there exist any empty selection in the leading whitespace, then skip
|
||||
// indent for selections at the boundary.
|
||||
if has_some_cursor_in_whitespace
|
||||
&& cursor.column == current_indent.len
|
||||
&& current_indent.len == suggested_indent.len
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if cursor.column < suggested_indent.len
|
||||
&& cursor.column <= current_indent.len
|
||||
&& current_indent.len <= suggested_indent.len
|
||||
|
@ -2870,9 +2870,26 @@ async fn test_tab_in_leading_whitespace_auto_indents_lines(cx: &mut TestAppConte
|
||||
);
|
||||
cx.update_buffer(|buffer, cx| buffer.set_language(Some(language), cx));
|
||||
|
||||
// cursors that are already at the suggested indent level insert
|
||||
// a soft tab. cursors that are to the left of the suggested indent
|
||||
// auto-indent their line.
|
||||
// when all cursors are to the left of the suggested indent, then auto-indent all.
|
||||
cx.set_state(indoc! {"
|
||||
const a: B = (
|
||||
c(
|
||||
ˇ
|
||||
ˇ )
|
||||
);
|
||||
"});
|
||||
cx.update_editor(|e, window, cx| e.tab(&Tab, window, cx));
|
||||
cx.assert_editor_state(indoc! {"
|
||||
const a: B = (
|
||||
c(
|
||||
ˇ
|
||||
ˇ)
|
||||
);
|
||||
"});
|
||||
|
||||
// cursors that are already at the suggested indent level do not move
|
||||
// until other cursors that are to the left of the suggested indent
|
||||
// auto-indent.
|
||||
cx.set_state(indoc! {"
|
||||
ˇ
|
||||
const a: B = (
|
||||
@ -2886,7 +2903,7 @@ async fn test_tab_in_leading_whitespace_auto_indents_lines(cx: &mut TestAppConte
|
||||
"});
|
||||
cx.update_editor(|e, window, cx| e.tab(&Tab, window, cx));
|
||||
cx.assert_editor_state(indoc! {"
|
||||
ˇ
|
||||
ˇ
|
||||
const a: B = (
|
||||
c(
|
||||
d(
|
||||
@ -2896,6 +2913,20 @@ async fn test_tab_in_leading_whitespace_auto_indents_lines(cx: &mut TestAppConte
|
||||
ˇ)
|
||||
);
|
||||
"});
|
||||
// once all multi-cursors are at the suggested
|
||||
// indent level, they all insert a soft tab together.
|
||||
cx.update_editor(|e, window, cx| e.tab(&Tab, window, cx));
|
||||
cx.assert_editor_state(indoc! {"
|
||||
ˇ
|
||||
const a: B = (
|
||||
c(
|
||||
d(
|
||||
ˇ
|
||||
)
|
||||
ˇ
|
||||
ˇ)
|
||||
);
|
||||
"});
|
||||
|
||||
// handle auto-indent when there are multiple cursors on the same line
|
||||
cx.set_state(indoc! {"
|
||||
|
Loading…
x
Reference in New Issue
Block a user