Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T04:25:09.518Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

cpp.rs

653 lines · 19.7 KB · rust
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_switch_case(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(
36                [(
37                    0..0,
38                    r#"
39                    int main() {
40                    switch (a) {
41                    case 1:
42                    b++;
43                    break;
44                    case 2:
45                    case 3:
46                    c++;
47                    break;
48                    default:
49                    d++;
50                    }
51                    }
52                    "#
53                    .unindent(),
54                )],
55                Some(AutoindentMode::EachLine),
56                cx,
57            );
58            assert_eq!(
59                buffer.text(),
60                r#"
61                int main() {
62                  switch (a) {
63                    case 1:
64                      b++;
65                      break;
66                    case 2:
67                    case 3:
68                      c++;
69                      break;
70                    default:
71                      d++;
72                  }
73                }
74                "#
75                .unindent(),
76                "statements under a case label should be indented, and the next label outdented"
77            );
78
79            buffer
80        });
81    }
82
83    #[gpui::test]
84    async fn test_cpp_autoindent_access_specifier(cx: &mut TestAppContext) {
85        cx.update(|cx| {
86            let test_settings = SettingsStore::test(cx);
87            cx.set_global(test_settings);
88            cx.update_global::<SettingsStore, _>(|store, cx| {
89                store.update_user_settings(cx, |s| {
90                    s.project.all_languages.defaults.tab_size = NonZeroU32::new(2);
91                });
92            });
93        });
94        let language = crate::language("cpp", tree_sitter_cpp::LANGUAGE.into());
95
96        cx.new(|cx| {
97            let mut buffer = Buffer::local("", cx).with_language(language, cx);
98
99            buffer.edit(
100                [(
101                    0..0,
102                    r#"
103                    class Foo {
104                    public:
105                    void bar();
106                    private:
107                    int x;
108                    };
109                    "#
110                    .unindent(),
111                )],
112                Some(AutoindentMode::EachLine),
113                cx,
114            );
115            assert_eq!(
116                buffer.text(),
117                r#"
118                class Foo {
119                  public:
120                    void bar();
121                  private:
122                    int x;
123                };
124                "#
125                .unindent(),
126                "members after access specifiers should be indented one level deeper than the specifier"
127            );
128
129            buffer
130        });
131    }
132
133    #[gpui::test]
134    async fn test_cpp_autoindent_access_specifier_next_line(cx: &mut TestAppContext) {
135        cx.update(|cx| {
136            let test_settings = SettingsStore::test(cx);
137            cx.set_global(test_settings);
138            cx.update_global::<SettingsStore, _>(|store, cx| {
139                store.update_user_settings(cx, |s| {
140                    s.project.all_languages.defaults.tab_size = NonZeroU32::new(2);
141                });
142            });
143        });
144        let language = crate::language("cpp", tree_sitter_cpp::LANGUAGE.into());
145
146        cx.new(|cx| {
147            let mut buffer = Buffer::local("", cx).with_language(language, cx);
148
149            buffer.edit(
150                [(
151                    0..0,
152                    r#"
153                    class Foo {
154                    public:
155                      void bar();
156                    void baz();
157                    private:
158                      int x;
159                    };
160                    "#
161                    .unindent(),
162                )],
163                Some(AutoindentMode::EachLine),
164                cx,
165            );
166            assert_eq!(
167                buffer.text(),
168                r#"
169                class Foo {
170                  public:
171                    void bar();
172                    void baz();
173                  private:
174                    int x;
175                };
176                "#
177                .unindent(),
178                "members after access specifiers should be indented one level deeper than the specifier"
179            );
180
181            buffer
182        });
183    }
184
185    #[gpui::test]
186    async fn test_cpp_autoindent_nested_class_access_specifiers(cx: &mut TestAppContext) {
187        cx.update(|cx| {
188            let test_settings = SettingsStore::test(cx);
189            cx.set_global(test_settings);
190            cx.update_global::<SettingsStore, _>(|store, cx| {
191                store.update_user_settings(cx, |s| {
192                    s.project.all_languages.defaults.tab_size = NonZeroU32::new(2);
193                });
194            });
195        });
196        let language = crate::language("cpp", tree_sitter_cpp::LANGUAGE.into());
197
198        cx.new(|cx| {
199            let mut buffer = Buffer::local("", cx).with_language(language, cx);
200
201            buffer.edit(
202                [(
203                    0..0,
204                    r#"
205                    class Outer {
206                    public:
207                    class Inner {
208                    public:
209                    void inner_pub();
210                    private:
211                    int inner_priv;
212                    };
213                    private:
214                    int outer_priv;
215                    };
216                    "#
217                    .unindent(),
218                )],
219                Some(AutoindentMode::EachLine),
220                cx,
221            );
222            assert_eq!(
223                buffer.text(),
224                r#"
225                class Outer {
226                  public:
227                    class Inner {
228                      public:
229                        void inner_pub();
230                      private:
231                        int inner_priv;
232                    };
233                  private:
234                    int outer_priv;
235                };
236                "#
237                .unindent(),
238                "nested class access specifiers should indent independently at each nesting level"
239            );
240
241            buffer
242        });
243    }
244
245    #[gpui::test]
246    async fn test_cpp_autoindent_consecutive_access_specifiers(cx: &mut TestAppContext) {
247        cx.update(|cx| {
248            let test_settings = SettingsStore::test(cx);
249            cx.set_global(test_settings);
250            cx.update_global::<SettingsStore, _>(|store, cx| {
251                store.update_user_settings(cx, |s| {
252                    s.project.all_languages.defaults.tab_size = NonZeroU32::new(2);
253                });
254            });
255        });
256        let language = crate::language("cpp", tree_sitter_cpp::LANGUAGE.into());
257
258        cx.new(|cx| {
259            let mut buffer = Buffer::local("", cx).with_language(language, cx);
260
261            buffer.edit(
262                [(
263                    0..0,
264                    r#"
265                    class Foo {
266                    public:
267                    protected:
268                    private:
269                    int x;
270                    };
271                    "#
272                    .unindent(),
273                )],
274                Some(AutoindentMode::EachLine),
275                cx,
276            );
277            assert_eq!(
278                buffer.text(),
279                r#"
280                class Foo {
281                  public:
282                  protected:
283                  private:
284                    int x;
285                };
286                "#
287                .unindent(),
288                "consecutive access specifiers with no members between them should all align at class level"
289            );
290
291            buffer
292        });
293    }
294
295    #[gpui::test]
296    async fn test_cpp_autoindent_indented_access_specifiers(cx: &mut TestAppContext) {
297        cx.update(|cx| {
298            let test_settings = SettingsStore::test(cx);
299            cx.set_global(test_settings);
300            cx.update_global::<SettingsStore, _>(|store, cx| {
301                store.update_user_settings(cx, |s| {
302                    s.project.all_languages.defaults.tab_size = NonZeroU32::new(2);
303                });
304            });
305        });
306        let language = crate::language("cpp", tree_sitter_cpp::LANGUAGE.into());
307
308        cx.new(|cx| {
309            let mut buffer = Buffer::local("", cx).with_language(language, cx);
310
311            buffer.edit(
312                [(
313                    0..0,
314                    r#"
315                    class Foo {
316                    int default_member;
317                    public:
318                    void pub_method();
319                    private:
320                    int priv_member;
321                    };
322                    "#
323                    .unindent(),
324                )],
325                Some(AutoindentMode::EachLine),
326                cx,
327            );
328            assert_eq!(
329                buffer.text(),
330                r#"
331                class Foo {
332                  int default_member;
333                  public:
334                    void pub_method();
335                  private:
336                    int priv_member;
337                };
338                "#
339                .unindent(),
340                "access specifiers should be indented one level inside class braces"
341            );
342
343            buffer
344        });
345    }
346
347    #[gpui::test]
348    async fn test_cpp_autoindent_access_specifier_with_method_bodies(cx: &mut TestAppContext) {
349        cx.update(|cx| {
350            let test_settings = SettingsStore::test(cx);
351            cx.set_global(test_settings);
352            cx.update_global::<SettingsStore, _>(|store, cx| {
353                store.update_user_settings(cx, |s| {
354                    s.project.all_languages.defaults.tab_size = NonZeroU32::new(2);
355                });
356            });
357        });
358        let language = crate::language("cpp", tree_sitter_cpp::LANGUAGE.into());
359
360        cx.new(|cx| {
361            let mut buffer = Buffer::local("", cx).with_language(language, cx);
362
363            buffer.edit(
364                [(
365                    0..0,
366                    r#"
367                    class Foo {
368                    public:
369                    void bar() {
370                    if (x)
371                    y++;
372                    }
373                    private:
374                    int get_x() {
375                    return x;
376                    }
377                    int x;
378                    };
379                    "#
380                    .unindent(),
381                )],
382                Some(AutoindentMode::EachLine),
383                cx,
384            );
385            assert_eq!(
386                buffer.text(),
387                r#"
388                class Foo {
389                  public:
390                    void bar() {
391                      if (x)
392                        y++;
393                    }
394                  private:
395                    int get_x() {
396                      return x;
397                    }
398                    int x;
399                };
400                "#
401                .unindent(),
402                "method bodies inside access specifier sections should compose brace and specifier indent"
403            );
404
405            buffer
406        });
407    }
408
409    #[gpui::test]
410    async fn test_cpp_autoindent_basic(cx: &mut TestAppContext) {
411        cx.update(|cx| {
412            let test_settings = SettingsStore::test(cx);
413            cx.set_global(test_settings);
414            cx.update_global::<SettingsStore, _>(|store, cx| {
415                store.update_user_settings(cx, |s| {
416                    s.project.all_languages.defaults.tab_size = NonZeroU32::new(2);
417                });
418            });
419        });
420        let language = crate::language("cpp", tree_sitter_cpp::LANGUAGE.into());
421
422        cx.new(|cx| {
423            let mut buffer = Buffer::local("", cx).with_language(language, cx);
424
425            buffer.edit([(0..0, "int main() {}")], None, cx);
426
427            let ix = buffer.len() - 1;
428            buffer.edit([(ix..ix, "\n\n")], Some(AutoindentMode::EachLine), cx);
429            assert_eq!(
430                buffer.text(),
431                "int main() {\n  \n}",
432                "content inside braces should be indented"
433            );
434
435            buffer
436        });
437    }
438
439    #[gpui::test]
440    async fn test_cpp_autoindent_if_else(cx: &mut TestAppContext) {
441        cx.update(|cx| {
442            let test_settings = SettingsStore::test(cx);
443            cx.set_global(test_settings);
444            cx.update_global::<SettingsStore, _>(|store, cx| {
445                store.update_user_settings(cx, |s| {
446                    s.project.all_languages.defaults.tab_size = NonZeroU32::new(2);
447                });
448            });
449        });
450        let language = crate::language("cpp", tree_sitter_cpp::LANGUAGE.into());
451
452        cx.new(|cx| {
453            let mut buffer = Buffer::local("", cx).with_language(language, cx);
454
455            buffer.edit(
456                [(
457                    0..0,
458                    r#"
459                    int main() {
460                    if (a)
461                    b;
462                    }
463                    "#
464                    .unindent(),
465                )],
466                Some(AutoindentMode::EachLine),
467                cx,
468            );
469            assert_eq!(
470                buffer.text(),
471                r#"
472                int main() {
473                  if (a)
474                    b;
475                }
476                "#
477                .unindent(),
478                "body of if-statement without braces should be indented"
479            );
480
481            let ix = buffer.len() - 4;
482            buffer.edit([(ix..ix, "\n.c")], Some(AutoindentMode::EachLine), cx);
483            assert_eq!(
484                buffer.text(),
485                r#"
486                int main() {
487                  if (a)
488                    b
489                      .c;
490                }
491                "#
492                .unindent(),
493                "field expression (.c) should be indented further than the statement body"
494            );
495
496            buffer.edit([(0..buffer.len(), "")], Some(AutoindentMode::EachLine), cx);
497            buffer.edit(
498                [(
499                    0..0,
500                    r#"
501                    int main() {
502                    if (a) a++;
503                    else b++;
504                    }
505                    "#
506                    .unindent(),
507                )],
508                Some(AutoindentMode::EachLine),
509                cx,
510            );
511            assert_eq!(
512                buffer.text(),
513                r#"
514                int main() {
515                  if (a) a++;
516                  else b++;
517                }
518                "#
519                .unindent(),
520                "single-line if/else without braces should align at the same level"
521            );
522
523            buffer.edit([(0..buffer.len(), "")], Some(AutoindentMode::EachLine), cx);
524            buffer.edit(
525                [(
526                    0..0,
527                    r#"
528                    int main() {
529                    if (a)
530                    b++;
531                    else
532                    c++;
533                    }
534                    "#
535                    .unindent(),
536                )],
537                Some(AutoindentMode::EachLine),
538                cx,
539            );
540            assert_eq!(
541                buffer.text(),
542                r#"
543                int main() {
544                  if (a)
545                    b++;
546                  else
547                    c++;
548                }
549                "#
550                .unindent(),
551                "multi-line if/else without braces should indent statement bodies"
552            );
553
554            buffer.edit([(0..buffer.len(), "")], Some(AutoindentMode::EachLine), cx);
555            buffer.edit(
556                [(
557                    0..0,
558                    r#"
559                    int main() {
560                    if (a)
561                    if (b)
562                    c++;
563                    }
564                    "#
565                    .unindent(),
566                )],
567                Some(AutoindentMode::EachLine),
568                cx,
569            );
570            assert_eq!(
571                buffer.text(),
572                r#"
573                int main() {
574                  if (a)
575                    if (b)
576                      c++;
577                }
578                "#
579                .unindent(),
580                "nested if statements without braces should indent properly"
581            );
582
583            buffer.edit([(0..buffer.len(), "")], Some(AutoindentMode::EachLine), cx);
584            buffer.edit(
585                [(
586                    0..0,
587                    r#"
588                    int main() {
589                    if (a)
590                    b++;
591                    else if (c)
592                    d++;
593                    else
594                    f++;
595                    }
596                    "#
597                    .unindent(),
598                )],
599                Some(AutoindentMode::EachLine),
600                cx,
601            );
602            assert_eq!(
603                buffer.text(),
604                r#"
605                int main() {
606                  if (a)
607                    b++;
608                  else if (c)
609                    d++;
610                  else
611                    f++;
612                }
613                "#
614                .unindent(),
615                "else-if chains should align all conditions at same level with indented bodies"
616            );
617
618            buffer.edit([(0..buffer.len(), "")], Some(AutoindentMode::EachLine), cx);
619            buffer.edit(
620                [(
621                    0..0,
622                    r#"
623                    int main() {
624                    if (a) {
625                    b++;
626                    } else
627                    c++;
628                    }
629                    "#
630                    .unindent(),
631                )],
632                Some(AutoindentMode::EachLine),
633                cx,
634            );
635            assert_eq!(
636                buffer.text(),
637                r#"
638                int main() {
639                  if (a) {
640                    b++;
641                  } else
642                    c++;
643                }
644                "#
645                .unindent(),
646                "mixed braces should indent properly"
647            );
648
649            buffer
650        });
651    }
652}
653
Served at tenant.openagents/omega Member data and write actions are omitted.