diff --git a/crates/grammars/src/c/indents.scm b/crates/grammars/src/c/indents.scm index 41f3c4fd3d..d119e5eedc 100644 --- a/crates/grammars/src/c/indents.scm +++ b/crates/grammars/src/c/indents.scm @@ -17,6 +17,15 @@ "{" "}" @end) @indent +(compound_statement + (case_statement + ":" @start) + "}" @end) @indent + +(compound_statement + (case_statement) + (case_statement) @outdent) + (_ "(" ")" @end) @indent diff --git a/crates/grammars/src/cpp/indents.scm b/crates/grammars/src/cpp/indents.scm index d8c71736e9..d8b677348b 100644 --- a/crates/grammars/src/cpp/indents.scm +++ b/crates/grammars/src/cpp/indents.scm @@ -25,6 +25,15 @@ (access_specifier) (access_specifier) @outdent) +(compound_statement + (case_statement + ":" @start) + "}" @end) @indent + +(compound_statement + (case_statement) + (case_statement) @outdent) + (_ "(" ")" @end) @indent diff --git a/crates/languages/src/c.rs b/crates/languages/src/c.rs index 80d794cd61..eb24dea0de 100644 --- a/crates/languages/src/c.rs +++ b/crates/languages/src/c.rs @@ -451,6 +451,70 @@ mod tests { }); } + #[gpui::test] + async fn test_c_autoindent_switch_case(cx: &mut TestAppContext) { + cx.update(|cx| { + let test_settings = SettingsStore::test(cx); + cx.set_global(test_settings); + cx.update_global::(|store, cx| { + store.update_user_settings(cx, |s| { + s.project.all_languages.defaults.tab_size = NonZeroU32::new(2); + }); + }); + }); + let language = crate::language("c", tree_sitter_c::LANGUAGE.into()); + + cx.new(|cx| { + let mut buffer = Buffer::local("", cx).with_language(language, cx); + + buffer.edit( + [( + 0..0, + r#" + int main() { + switch (a) { + case 1: + b++; + break; + case 2: + case 3: + c++; + break; + default: + d++; + } + } + "# + .unindent(), + )], + Some(AutoindentMode::EachLine), + cx, + ); + assert_eq!( + buffer.text(), + r#" + int main() { + switch (a) { + case 1: + b++; + break; + case 2: + case 3: + c++; + break; + default: + d++; + } + } + "# + .unindent(), + "statements under a case label should be indented, and the next label outdented" + ); + + buffer + }); + } + #[gpui::test] async fn test_c_autoindent_if_else(cx: &mut TestAppContext) { cx.update(|cx| { diff --git a/crates/languages/src/cpp.rs b/crates/languages/src/cpp.rs index 0577a55826..f09438a939 100644 --- a/crates/languages/src/cpp.rs +++ b/crates/languages/src/cpp.rs @@ -16,6 +16,70 @@ mod tests { use std::num::NonZeroU32; use unindent::Unindent; + #[gpui::test] + async fn test_cpp_autoindent_switch_case(cx: &mut TestAppContext) { + cx.update(|cx| { + let test_settings = SettingsStore::test(cx); + cx.set_global(test_settings); + cx.update_global::(|store, cx| { + store.update_user_settings(cx, |s| { + s.project.all_languages.defaults.tab_size = NonZeroU32::new(2); + }); + }); + }); + let language = crate::language("cpp", tree_sitter_cpp::LANGUAGE.into()); + + cx.new(|cx| { + let mut buffer = Buffer::local("", cx).with_language(language, cx); + + buffer.edit( + [( + 0..0, + r#" + int main() { + switch (a) { + case 1: + b++; + break; + case 2: + case 3: + c++; + break; + default: + d++; + } + } + "# + .unindent(), + )], + Some(AutoindentMode::EachLine), + cx, + ); + assert_eq!( + buffer.text(), + r#" + int main() { + switch (a) { + case 1: + b++; + break; + case 2: + case 3: + c++; + break; + default: + d++; + } + } + "# + .unindent(), + "statements under a case label should be indented, and the next label outdented" + ); + + buffer + }); + } + #[gpui::test] async fn test_cpp_autoindent_access_specifier(cx: &mut TestAppContext) { cx.update(|cx| {