Skip to content

Commit 143c16c

Browse files
committed
Fix C++ if/else indentation as well
1 parent 62d8209 commit 143c16c

File tree

4 files changed

+257
-1
lines changed

4 files changed

+257
-1
lines changed

crates/languages/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ text.workspace = true
9797
theme = { workspace = true, features = ["test-support"] }
9898
tree-sitter-bash.workspace = true
9999
tree-sitter-c.workspace = true
100+
tree-sitter-cpp.workspace = true
100101
tree-sitter-css.workspace = true
101102
tree-sitter-go.workspace = true
102103
tree-sitter-python.workspace = true

crates/languages/src/cpp.rs

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
#[cfg(test)]
2+
mod tests {
3+
use gpui::{AppContext as _, BorrowAppContext, TestAppContext};
4+
use language::{AutoindentMode, Buffer};
5+
use settings::SettingsStore;
6+
use std::num::NonZeroU32;
7+
use unindent::Unindent;
8+
9+
#[gpui::test]
10+
async fn test_cpp_autoindent_basic(cx: &mut TestAppContext) {
11+
cx.update(|cx| {
12+
let test_settings = SettingsStore::test(cx);
13+
cx.set_global(test_settings);
14+
language::init(cx);
15+
cx.update_global::<SettingsStore, _>(|store, cx| {
16+
store.update_user_settings(cx, |s| {
17+
s.project.all_languages.defaults.tab_size = NonZeroU32::new(2);
18+
});
19+
});
20+
});
21+
let language = crate::language("cpp", tree_sitter_cpp::LANGUAGE.into());
22+
23+
cx.new(|cx| {
24+
let mut buffer = Buffer::local("", cx).with_language(language, cx);
25+
26+
buffer.edit([(0..0, "int main() {}")], None, cx);
27+
28+
let ix = buffer.len() - 1;
29+
buffer.edit([(ix..ix, "\n\n")], Some(AutoindentMode::EachLine), cx);
30+
assert_eq!(
31+
buffer.text(),
32+
"int main() {\n \n}",
33+
"content inside braces should be indented"
34+
);
35+
36+
buffer
37+
});
38+
}
39+
40+
#[gpui::test]
41+
async fn test_cpp_autoindent_if_else(cx: &mut TestAppContext) {
42+
cx.update(|cx| {
43+
let test_settings = SettingsStore::test(cx);
44+
cx.set_global(test_settings);
45+
language::init(cx);
46+
cx.update_global::<SettingsStore, _>(|store, cx| {
47+
store.update_user_settings(cx, |s| {
48+
s.project.all_languages.defaults.tab_size = NonZeroU32::new(2);
49+
});
50+
});
51+
});
52+
let language = crate::language("cpp", tree_sitter_cpp::LANGUAGE.into());
53+
54+
cx.new(|cx| {
55+
let mut buffer = Buffer::local("", cx).with_language(language, cx);
56+
57+
buffer.edit(
58+
[(
59+
0..0,
60+
r#"
61+
int main() {
62+
if (a)
63+
b;
64+
}
65+
"#
66+
.unindent(),
67+
)],
68+
Some(AutoindentMode::EachLine),
69+
cx,
70+
);
71+
assert_eq!(
72+
buffer.text(),
73+
r#"
74+
int main() {
75+
if (a)
76+
b;
77+
}
78+
"#
79+
.unindent(),
80+
"body of if-statement without braces should be indented"
81+
);
82+
83+
let ix = buffer.len() - 4;
84+
buffer.edit([(ix..ix, "\n.c")], Some(AutoindentMode::EachLine), cx);
85+
assert_eq!(
86+
buffer.text(),
87+
r#"
88+
int main() {
89+
if (a)
90+
b
91+
.c;
92+
}
93+
"#
94+
.unindent(),
95+
"field expression (.c) should be indented further than the statement body"
96+
);
97+
98+
buffer.edit([(0..buffer.len(), "")], Some(AutoindentMode::EachLine), cx);
99+
buffer.edit(
100+
[(
101+
0..0,
102+
r#"
103+
int main() {
104+
if (a) a++;
105+
else b++;
106+
}
107+
"#
108+
.unindent(),
109+
)],
110+
Some(AutoindentMode::EachLine),
111+
cx,
112+
);
113+
assert_eq!(
114+
buffer.text(),
115+
r#"
116+
int main() {
117+
if (a) a++;
118+
else b++;
119+
}
120+
"#
121+
.unindent(),
122+
"single-line if/else without braces should align at the same level"
123+
);
124+
125+
buffer.edit([(0..buffer.len(), "")], Some(AutoindentMode::EachLine), cx);
126+
buffer.edit(
127+
[(
128+
0..0,
129+
r#"
130+
int main() {
131+
if (a)
132+
b++;
133+
else
134+
c++;
135+
}
136+
"#
137+
.unindent(),
138+
)],
139+
Some(AutoindentMode::EachLine),
140+
cx,
141+
);
142+
assert_eq!(
143+
buffer.text(),
144+
r#"
145+
int main() {
146+
if (a)
147+
b++;
148+
else
149+
c++;
150+
}
151+
"#
152+
.unindent(),
153+
"multi-line if/else without braces should indent statement bodies"
154+
);
155+
156+
buffer.edit([(0..buffer.len(), "")], Some(AutoindentMode::EachLine), cx);
157+
buffer.edit(
158+
[(
159+
0..0,
160+
r#"
161+
int main() {
162+
if (a)
163+
if (b)
164+
c++;
165+
}
166+
"#
167+
.unindent(),
168+
)],
169+
Some(AutoindentMode::EachLine),
170+
cx,
171+
);
172+
assert_eq!(
173+
buffer.text(),
174+
r#"
175+
int main() {
176+
if (a)
177+
if (b)
178+
c++;
179+
}
180+
"#
181+
.unindent(),
182+
"nested if statements without braces should indent properly"
183+
);
184+
185+
buffer.edit([(0..buffer.len(), "")], Some(AutoindentMode::EachLine), cx);
186+
buffer.edit(
187+
[(
188+
0..0,
189+
r#"
190+
int main() {
191+
if (a)
192+
b++;
193+
else if (c)
194+
d++;
195+
else
196+
f++;
197+
}
198+
"#
199+
.unindent(),
200+
)],
201+
Some(AutoindentMode::EachLine),
202+
cx,
203+
);
204+
assert_eq!(
205+
buffer.text(),
206+
r#"
207+
int main() {
208+
if (a)
209+
b++;
210+
else if (c)
211+
d++;
212+
else
213+
f++;
214+
}
215+
"#
216+
.unindent(),
217+
"else-if chains should align all conditions at same level with indented bodies"
218+
);
219+
220+
buffer.edit([(0..buffer.len(), "")], Some(AutoindentMode::EachLine), cx);
221+
buffer.edit(
222+
[(
223+
0..0,
224+
r#"
225+
int main() {
226+
if (a) {
227+
b++;
228+
} else
229+
c++;
230+
}
231+
"#
232+
.unindent(),
233+
)],
234+
Some(AutoindentMode::EachLine),
235+
cx,
236+
);
237+
assert_eq!(
238+
buffer.text(),
239+
r#"
240+
int main() {
241+
if (a) {
242+
b++;
243+
} else
244+
c++;
245+
}
246+
"#
247+
.unindent(),
248+
"mixed braces should indent properly"
249+
);
250+
251+
buffer
252+
});
253+
}
254+
}

crates/languages/src/cpp/config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ path_suffixes = ["cc", "hh", "cpp", "h", "hpp", "cxx", "hxx", "c++", "ipp", "inl
44
line_comments = ["// ", "/// ", "//! "]
55
decrease_indent_patterns = [
66
{ pattern = "^\\s*\\{.*\\}?\\s*$", valid_after = ["if", "for", "while", "do", "switch", "else"] },
7-
{ pattern = "^\\s*else\\s*$", valid_after = ["if"] }
7+
{ pattern = "^\\s*else\\b", valid_after = ["if"] }
88
]
99
autoclose_before = ";:.,=}])>"
1010
brackets = [

crates/languages/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::{
1919

2020
mod bash;
2121
mod c;
22+
mod cpp;
2223
mod css;
2324
mod go;
2425
mod json;

0 commit comments

Comments
 (0)