diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 7dbb1a7c1b..0e4be2058c 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -8779,15 +8779,13 @@ impl Editor { continue; } - // If the selection is empty and the cursor is in the leading whitespace before the - // suggested indentation, then auto-indent the line. let cursor = selection.head(); let current_indent = snapshot.indent_size_for_line(MultiBufferRow(cursor.row)); 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. + // Don't do anything if already at suggested indent + // and there is any other cursor which is not if has_some_cursor_in_whitespace && cursor.column == current_indent.len && current_indent.len == suggested_indent.len @@ -8795,6 +8793,8 @@ impl Editor { continue; } + // Adjust line and move cursor to suggested indent + // if cursor is not at suggested indent if cursor.column < suggested_indent.len && cursor.column <= current_indent.len && current_indent.len <= suggested_indent.len @@ -8811,6 +8811,14 @@ impl Editor { } continue; } + + // If current indent is more than suggested indent + // only move cursor to current indent and skip indent + if cursor.column < current_indent.len && current_indent.len > suggested_indent.len { + selection.start = Point::new(cursor.row, current_indent.len); + selection.end = selection.start; + continue; + } } // Otherwise, insert a hard or soft tab. diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index f4ef0b899c..df82854d18 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -2871,7 +2871,8 @@ async fn test_tab_in_leading_whitespace_auto_indents_lines(cx: &mut TestAppConte ); cx.update_buffer(|buffer, cx| buffer.set_language(Some(language), cx)); - // when all cursors are to the left of the suggested indent, then auto-indent all. + // test when all cursors are not at suggested indent + // then simply move to their suggested indent location cx.set_state(indoc! {" const a: B = ( c( @@ -2888,9 +2889,8 @@ async fn test_tab_in_leading_whitespace_auto_indents_lines(cx: &mut TestAppConte ); "}); - // 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. + // test cursor already at suggested indent not moving when + // other cursors are yet to reach their suggested indents cx.set_state(indoc! {" ˇ const a: B = ( @@ -2914,8 +2914,7 @@ 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. + // test when all cursors are at suggested indent then tab is inserted cx.update_editor(|e, window, cx| e.tab(&Tab, window, cx)); cx.assert_editor_state(indoc! {" ˇ @@ -2929,6 +2928,112 @@ async fn test_tab_in_leading_whitespace_auto_indents_lines(cx: &mut TestAppConte ); "}); + // test when current indent is less than suggested indent, + // we adjust line to match suggested indent and move cursor to it + // + // when no other cursor is at word boundary, all of them should move + cx.set_state(indoc! {" + const a: B = ( + c( + d( + ˇ + ˇ ) + ˇ ) + ); + "}); + cx.update_editor(|e, window, cx| e.tab(&Tab, window, cx)); + cx.assert_editor_state(indoc! {" + const a: B = ( + c( + d( + ˇ + ˇ) + ˇ) + ); + "}); + + // test when current indent is less than suggested indent, + // we adjust line to match suggested indent and move cursor to it + // + // when some other cursor is at word boundary, it should not move + cx.set_state(indoc! {" + const a: B = ( + c( + d( + ˇ + ˇ ) + ˇ) + ); + "}); + cx.update_editor(|e, window, cx| e.tab(&Tab, window, cx)); + cx.assert_editor_state(indoc! {" + const a: B = ( + c( + d( + ˇ + ˇ) + ˇ) + ); + "}); + + // test when current indent is more than suggested indent, + // we just move cursor to current indent instead of suggested indent + // + // when no other cursor is at word boundary, all of them should move + cx.set_state(indoc! {" + const a: B = ( + c( + d( + ˇ + ˇ ) + ˇ ) + ); + "}); + cx.update_editor(|e, window, cx| e.tab(&Tab, window, cx)); + cx.assert_editor_state(indoc! {" + const a: B = ( + c( + d( + ˇ + ˇ) + ˇ) + ); + "}); + cx.update_editor(|e, window, cx| e.tab(&Tab, window, cx)); + cx.assert_editor_state(indoc! {" + const a: B = ( + c( + d( + ˇ + ˇ) + ˇ) + ); + "}); + + // test when current indent is more than suggested indent, + // we just move cursor to current indent instead of suggested indent + // + // when some other cursor is at word boundary, it doesn't move + cx.set_state(indoc! {" + const a: B = ( + c( + d( + ˇ + ˇ ) + ˇ) + ); + "}); + 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! {" const a: B = (