From 00097df0d585c65103e1c1fd170cce3a28c631aa Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 18 Jul 2025 03:24:20 -0700 Subject: [PATCH] Improve C/C++ indentation flow for single statement blocks (#34549) Before this, indentation did not automatically increase after if/for/while/do/else statements in C++, and only increased after if/for in C. This led to Zed using last line logic when inserting lines *after* the indented statement, as well as not indenting the statement itself, resulting in irregular indentation during typing. Just adding indentation (similar to C) creates a new problem: now if a scope is started with a brace on a new line, that brace is indented. Thus we need to deindent it. Using else_clause in the indent guide results in the else statement being indented forward as well, so we need to deindent that too. Note: the most significant issue for me is the one where indentation jumps forward when inserting lines after indented lines. Unfortunately, it appears that fixing that issue requires all of these other changes. I would have preferred a simpler fix, but I'm not sure if disabling last line behavior for C/C++ is appropriate as it probably breaks something else, like cases where the file is incomplete and the statements can't be parsed properly. Editing flow before this change: [Screencast From 2025-07-16 08-31-36.webm](https://github.com/user-attachments/assets/3dea86c5-47bd-47c2-aee8-b0aa613948e6) Editing flow after this change: [Screencast From 2025-07-16 08-35-36.webm](https://github.com/user-attachments/assets/7ef23e60-1ee3-49fd-90f9-d53f909ca674) (note: the "else" snippet is completely breaking the flow here, but I think that comes from clangd by default? Unfortunately I haven't found a way to disable it cleanly but that is a separate problem that happens right now too.) Release Notes: - Improve indentation during typing for C/C++ around if/for/while/do blocks --- crates/languages/src/c/config.toml | 4 ++++ crates/languages/src/c/indents.scm | 10 ++++++++++ crates/languages/src/cpp/config.toml | 4 ++++ crates/languages/src/cpp/indents.scm | 12 ++++++++++++ 4 files changed, 30 insertions(+) diff --git a/crates/languages/src/c/config.toml b/crates/languages/src/c/config.toml index 08cd100f4d..78213da5be 100644 --- a/crates/languages/src/c/config.toml +++ b/crates/languages/src/c/config.toml @@ -2,6 +2,10 @@ name = "C" grammar = "c" path_suffixes = ["c"] line_comments = ["// "] +decrease_indent_patterns = [ + { pattern = "^\\s*\\{.*\\}?\\s*$", valid_after = ["if", "for", "while", "do", "switch", "else"] }, + { pattern = "^\\s*else\\s*$", valid_after = ["if"] } +] autoclose_before = ";:.,=}])>" brackets = [ { start = "{", end = "}", close = true, newline = true }, diff --git a/crates/languages/src/c/indents.scm b/crates/languages/src/c/indents.scm index fa40ce215e..3b6d5135ab 100644 --- a/crates/languages/src/c/indents.scm +++ b/crates/languages/src/c/indents.scm @@ -3,7 +3,17 @@ (assignment_expression) (if_statement) (for_statement) + (while_statement) + (do_statement) + (else_clause) ] @indent (_ "{" "}" @end) @indent (_ "(" ")" @end) @indent + +(if_statement) @start.if +(for_statement) @start.for +(while_statement) @start.while +(do_statement) @start.do +(switch_statement) @start.switch +(else_clause) @start.else diff --git a/crates/languages/src/cpp/config.toml b/crates/languages/src/cpp/config.toml index a81cbe09cd..1e28381605 100644 --- a/crates/languages/src/cpp/config.toml +++ b/crates/languages/src/cpp/config.toml @@ -2,6 +2,10 @@ name = "C++" grammar = "cpp" path_suffixes = ["cc", "hh", "cpp", "h", "hpp", "cxx", "hxx", "c++", "ipp", "inl", "ixx", "cu", "cuh", "C", "H"] line_comments = ["// ", "/// ", "//! "] +decrease_indent_patterns = [ + { pattern = "^\\s*\\{.*\\}?\\s*$", valid_after = ["if", "for", "while", "do", "switch", "else"] }, + { pattern = "^\\s*else\\s*$", valid_after = ["if"] } +] autoclose_before = ";:.,=}])>" brackets = [ { start = "{", end = "}", close = true, newline = true }, diff --git a/crates/languages/src/cpp/indents.scm b/crates/languages/src/cpp/indents.scm index a17f4c4821..d95dfe178c 100644 --- a/crates/languages/src/cpp/indents.scm +++ b/crates/languages/src/cpp/indents.scm @@ -1,7 +1,19 @@ [ (field_expression) (assignment_expression) + (if_statement) + (for_statement) + (while_statement) + (do_statement) + (else_clause) ] @indent (_ "{" "}" @end) @indent (_ "(" ")" @end) @indent + +(if_statement) @start.if +(for_statement) @start.for +(while_statement) @start.while +(do_statement) @start.do +(switch_statement) @start.switch +(else_clause) @start.else