diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 8f43eeab61..6e1d3fc443 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -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 diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 44db047ded..739233ea8d 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -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! {"