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:
Smit Barmase 2025-04-28 13:13:53 +05:30 committed by GitHub
parent f060918b57
commit 52eef3c35d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 53 additions and 4 deletions

View file

@ -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