|
1 |
| -Prism.languages.cpp = Prism.languages.extend('c', { |
2 |
| - 'class-name': { |
3 |
| - pattern: /(\b(?:class|enum|struct)\s+)(?!class|enum|struct)\w+/, |
4 |
| - lookbehind: true |
5 |
| - }, |
6 |
| - 'keyword': /\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|constinit|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/, |
7 |
| - 'number': { |
8 |
| - pattern: /(?:\b0b[01']+|\b0x(?:[\da-f']+\.?[\da-f']*|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+\.?[\d']*|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]*/i, |
9 |
| - greedy: true |
10 |
| - }, |
11 |
| - 'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/, |
12 |
| - 'boolean': /\b(?:true|false)\b/ |
13 |
| -}); |
| 1 | +(function (Prism) { |
14 | 2 |
|
15 |
| -Prism.languages.insertBefore('cpp', 'string', { |
16 |
| - 'raw-string': { |
17 |
| - pattern: /R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/, |
18 |
| - alias: 'string', |
19 |
| - greedy: true |
20 |
| - } |
21 |
| -}); |
| 3 | + var keyword = /\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|constinit|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/; |
| 4 | + |
| 5 | + Prism.languages.cpp = Prism.languages.extend('c', { |
| 6 | + 'class-name': [ |
| 7 | + { |
| 8 | + pattern: RegExp(/(\b(?:class|enum|struct|typename)\s+)(?!<keyword>)\w+/.source |
| 9 | + .replace(/<keyword>/g, function () { return keyword.source; })), |
| 10 | + lookbehind: true |
| 11 | + }, |
| 12 | + // This is intended to capture the class name of method implementations like: |
| 13 | + // void foo::bar() const {} |
| 14 | + // However! The `foo` in the above example could also be a namespace, so we only capture the class name if |
| 15 | + // it starts with an uppercase letter. This approximation should give decent results. |
| 16 | + /\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/, |
| 17 | + // This will capture the class name before destructors like: |
| 18 | + // Foo::~Foo() {} |
| 19 | + /\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i, |
| 20 | + { |
| 21 | + // This also intends to capture the class name of method implementations but here the class has template |
| 22 | + // parameters, so it can't be a namespace (until C++ adds generic namespaces). |
| 23 | + pattern: /\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/, |
| 24 | + inside: null // see below |
| 25 | + } |
| 26 | + ], |
| 27 | + 'keyword': keyword, |
| 28 | + 'number': { |
| 29 | + pattern: /(?:\b0b[01']+|\b0x(?:[\da-f']+\.?[\da-f']*|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+\.?[\d']*|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]*/i, |
| 30 | + greedy: true |
| 31 | + }, |
| 32 | + 'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/, |
| 33 | + 'boolean': /\b(?:true|false)\b/ |
| 34 | + }); |
| 35 | + |
| 36 | + Prism.languages.insertBefore('cpp', 'string', { |
| 37 | + 'raw-string': { |
| 38 | + pattern: /R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/, |
| 39 | + alias: 'string', |
| 40 | + greedy: true |
| 41 | + } |
| 42 | + }); |
| 43 | + |
| 44 | + Prism.languages.insertBefore('cpp', 'class-name', { |
| 45 | + // the base clause is an optional list of parent classes |
| 46 | + // https://en.cppreference.com/w/cpp/language/class |
| 47 | + 'base-clause': { |
| 48 | + pattern: /(\b(?:class|struct)\s+\w+\s*:\s*)(?:[^;{}"'])+?(?=\s*[;{])/, |
| 49 | + lookbehind: true, |
| 50 | + greedy: true, |
| 51 | + inside: Prism.languages.extend('cpp', {}) |
| 52 | + } |
| 53 | + }); |
| 54 | + Prism.languages.insertBefore('inside', 'operator', { |
| 55 | + // All untokenized words that are not namespaces should be class names |
| 56 | + 'class-name': /\b[a-z_]\w*\b(?!\s*::)/i |
| 57 | + }, Prism.languages.cpp['base-clause']); |
| 58 | + |
| 59 | +}(Prism)); |
0 commit comments