cpp.rs

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