Created
February 8, 2019 21:26
-
-
Save Kronuz/8ccba85296587243c3ffa07bb5cb19c8 to your computer and use it in GitHub Desktop.
C++ syntax for Sublime Text with fmt formatting support in the strings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%YAML 1.2 | |
--- | |
# http://www.sublimetext.com/docs/3/syntax.html | |
name: C++ (fmt) | |
comment: I don't think anyone uses .hp. .cp tends to be paired with .h. (I could be wrong. :) -- chris | |
file_extensions: | |
- cpp | |
- cc | |
- cp | |
- cxx | |
- c++ | |
- C | |
- h | |
- hh | |
- hpp | |
- hxx | |
- h++ | |
- inl | |
- ipp | |
first_line_match: '-\*- C\+\+ -\*-' | |
scope: source.c++ | |
variables: | |
identifier: \b[[:alpha:]_][[:alnum:]_]*\b # upper and lowercase | |
macro_identifier: \b[[:upper:]_][[:upper:][:digit:]_]{2,}\b # only uppercase, at least 3 chars | |
path_lookahead: '(?:::\s*)?(?:{{identifier}}\s*::\s*)*(?:template\s+)?{{identifier}}' | |
operator_method_name: '\boperator\s*(?:[-+*/%^&|~!=<>]|[-+*/%^&|=!<>]=|<<=?|>>=?|&&|\|\||\+\+|--|,|->\*?|\(\)|\[\]|""\s*{{identifier}})' | |
casts: 'const_cast|dynamic_cast|reinterpret_cast|static_cast' | |
operator_keywords: 'and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|xor|xor_eq|noexcept' | |
control_keywords: 'break|case|catch|continue|default|do|else|for|goto|if|_Pragma|return|switch|throw|try|while' | |
memory_operators: 'new|delete' | |
basic_types: 'asm|__asm__|auto|bool|_Bool|char|_Complex|double|float|_Imaginary|int|long|short|signed|unsigned|void' | |
before_tag: 'struct|union|enum\s+class|enum\s+struct|enum|class' | |
declspec: '__declspec\(\s*\w+(?:\([^)]+\))?\s*\)' | |
storage_classes: 'static|export|extern|friend|explicit|virtual|register|thread_local' | |
type_qualifier: 'const|constexpr|mutable|typename|volatile' | |
compiler_directive: 'inline|restrict|__restrict__|__restrict' | |
visibility_modifiers: 'private|protected|public' | |
other_keywords: 'typedef|nullptr|{{visibility_modifiers}}|static_assert|sizeof|using|typeid|alignof|alignas|namespace|template' | |
modifiers: '{{storage_classes}}|{{type_qualifier}}|{{compiler_directive}}' | |
non_angle_brackets: '(?=<<|<=)' | |
regular: '[^(){}&;*^%=<>-]*' | |
paren_open: (?:\( | |
paren_close: '\))?' | |
generic_open: (?:< | |
generic_close: '>)?' | |
balance_parentheses: '{{regular}}{{paren_open}}{{regular}}{{paren_close}}{{regular}}' | |
generic_lookahead: <{{regular}}{{generic_open}}{{regular}}{{generic_open}}{{regular}}{{generic_close}}\s*{{generic_close}}{{balance_parentheses}}> | |
data_structures_forward_decl_lookahead: '(\s+{{macro_identifier}})*\s*(:\s*({{path_lookahead}}|{{visibility_modifiers}}|,|\s|<[^;]*>)+)?;' | |
non_func_keywords: 'if|for|switch|while|decltype|sizeof|__declspec|__attribute__|typeid|alignof|alignas|static_assert' | |
format_spec: |- | |
(?x: | |
(?:.? [<>=^])? # fill align | |
[ +-]? # sign | |
\#? # alternate form | |
# technically, octal and hexadecimal integers are also supported as 'width', but rarely used | |
\d* # width | |
,? # thousands separator | |
(?:\.\d+)? # precision | |
[bcdeEfFgGnosxX%]? # type | |
) | |
contexts: | |
main: | |
- include: preprocessor-global | |
- include: global | |
############################################################################# | |
# Reusable contexts | |
# | |
# The follow contexts are currently constructed to be reused in the | |
# Objetive-C++ syntax. They are specifically constructed to not push into | |
# sub-contexts, which ensures that Objective-C++ code isn't accidentally | |
# lexed as plain C++. | |
# | |
# The "unique-*" contexts are additions that C++ makes over C, and thus can | |
# be directly reused in Objective-C++ along with contexts from Objective-C | |
# and C. | |
############################################################################# | |
unique-late-expressions: | |
# This is highlighted after all of the other control keywords | |
# to allow operator overloading to be lexed properly | |
- match: \boperator\b | |
scope: keyword.control.c++ | |
unique-modifiers: | |
- match: \b({{modifiers}})\b | |
scope: storage.modifier.c++ | |
unique-variables: | |
- match: \bthis\b | |
scope: variable.language.c++ | |
# common C++ instance var naming idiom -- fMemberName | |
- match: '\b(f|m)[[:upper:]]\w*\b' | |
scope: variable.other.readwrite.member.c++ | |
# common C++ instance var naming idiom -- m_member_name | |
- match: '\bm_[[:alnum:]_]+\b' | |
scope: variable.other.readwrite.member.c++ | |
unique-constants: | |
- match: \bnullptr\b | |
scope: constant.language.c++ | |
unique-keywords: | |
- match: \busing\b | |
scope: keyword.control.c++ | |
- match: \bbreak\b | |
scope: keyword.control.flow.break.c++ | |
- match: \bcontinue\b | |
scope: keyword.control.flow.continue.c++ | |
- match: \bgoto\b | |
scope: keyword.control.flow.goto.c++ | |
- match: \breturn\b | |
scope: keyword.control.flow.return.c++ | |
- match: \bthrow\b | |
scope: keyword.control.flow.throw.c++ | |
- match: \b({{control_keywords}})\b | |
scope: keyword.control.c++ | |
- match: '\bdelete\b(\s*\[\])?|\bnew\b(?!])' | |
scope: keyword.control.c++ | |
- match: \b({{operator_keywords}})\b | |
scope: keyword.operator.word.c++ | |
unique-types: | |
- match: \b(char16_t|char32_t|wchar_t|nullptr_t)\b | |
scope: storage.type.c++ | |
- match: \bclass\b | |
scope: storage.type.c++ | |
unique-strings: | |
- match: '((?:L|u8|u|U)?R)("([^\(\)\\ ]{0,16})\()' | |
captures: | |
1: storage.type.string.c++ | |
2: punctuation.definition.string.begin.c++ | |
push: | |
- meta_scope: string.quoted.double.c++ | |
- match: '\)\3"' | |
scope: punctuation.definition.string.end.c++ | |
pop: true | |
- match: '\{\{|\}\}' | |
scope: constant.character.escape.c++ | |
- include: formatting-syntax | |
unique-numbers: | |
- match: |- | |
(?x) | |
(?: | |
# floats | |
(?: | |
(?:\b\d(?:[\d']*\d)?\.\d(?:[\d']*\d)?|\B\.\d(?:[\d']*\d)?)(?:[Ee][+-]?\d(?:[\d']*\d)?)?(?:[fFlL]|(?:i[fl]?|h|min|[mun]?s|_\w*))?\b | |
| | |
(?:\b\d(?:[\d']*\d)?\.)(?:\B|(?:[fFlL]|(?:i[fl]?|h|min|[mun]?s|_\w*))\b|(?:[Ee][+-]?\d(?:[\d']*\d)?)(?:[fFlL]|(?:i[fl]?|h|min|[mun]?s|_\w*))?\b) | |
| | |
\b\d(?:[\d']*\d)?(?:[Ee][+-]?\d(?:[\d']*\d)?)(?:[fFlL]|(?:i[fl]?|h|min|[mun]?s|_\w*))?\b | |
) | |
| | |
# ints | |
\b(?: | |
(?: | |
# dec | |
[1-9](?:[\d']*\d)? | |
| | |
# oct | |
0(?:[0-7']*[0-7])? | |
| | |
# hex | |
0[Xx][\da-fA-F](?:[\da-fA-F']*[\da-fA-F])? | |
| | |
# bin | |
0[Bb][01](?:[01']*[01])? | |
) | |
# int suffixes | |
(?:(?:l{1,2}|L{1,2})[uU]?|[uU](?:l{0,2}|L{0,2})|(?:i[fl]?|h|min|[mun]?s|_\w*))?)\b | |
) | |
(?!\.) # Number must not be followed by a decimal point | |
scope: constant.numeric.c++ | |
identifiers: | |
- match: '{{identifier}}\s*(::)\s*' | |
captures: | |
1: punctuation.accessor.c++ | |
- match: '(?:(::)\s*)?{{identifier}}' | |
captures: | |
1: punctuation.accessor.c++ | |
function-specifiers: | |
- match: \b(const|final|noexcept|override)\b | |
scope: storage.modifier.c++ | |
############################################################################# | |
# The following are C++-specific contexts that should not be reused. This is | |
# because they push into subcontexts and use variables that are C++-specific. | |
############################################################################# | |
## Common context layout | |
global: | |
- match: '(?=\btemplate\b)' | |
push: | |
- include: template | |
- match: (?=\S) | |
set: global-modifier | |
- include: namespace | |
- include: keywords-angle-brackets | |
- match: '(?={{path_lookahead}}\s*<)' | |
push: global-modifier | |
# Take care of comments just before a function definition. | |
- match: /\* | |
scope: punctuation.definition.comment.c | |
push: | |
- - match: \s*(?=\w) | |
set: global-modifier | |
- match: "" | |
pop: true | |
- - meta_scope: comment.block.c | |
- match: \*/ | |
scope: punctuation.definition.comment.c | |
pop: true | |
- include: early-expressions | |
- match: ^\s*\b(extern)(?=\s+"C(\+\+)?") | |
scope: storage.modifier.c++ | |
push: | |
- include: comments | |
- include: strings | |
- match: '\{' | |
scope: punctuation.section.block.begin.c++ | |
set: | |
- meta_scope: meta.extern-c.c++ | |
- match: '^\s*(#\s*ifdef)\s*__cplusplus\s*' | |
scope: meta.preprocessor.c++ | |
captures: | |
1: keyword.control.import.c++ | |
set: | |
- match: '\}' | |
scope: punctuation.section.block.end.c++ | |
pop: true | |
- include: preprocessor-global | |
- include: global | |
- match: '\}' | |
scope: punctuation.section.block.end.c++ | |
pop: true | |
- include: preprocessor-global | |
- include: global | |
- match: (?=\S) | |
set: global-modifier | |
- match: ^\s*(?=\w) | |
push: global-modifier | |
- include: late-expressions | |
statements: | |
- include: preprocessor-statements | |
- include: scope:source.c#label | |
- include: expressions | |
expressions: | |
- include: early-expressions | |
- include: late-expressions | |
early-expressions: | |
- include: early-expressions-before-generic-type | |
- include: generic-type | |
- include: early-expressions-after-generic-type | |
early-expressions-before-generic-type: | |
- include: preprocessor-expressions | |
- include: comments | |
- include: case-default | |
- include: typedef | |
- include: keywords-angle-brackets | |
- include: keywords-parens | |
- include: keywords | |
- include: numbers | |
# Prevent a '<' from getting scoped as the start of another template | |
# parameter list, if in reality a less-than-or-equals sign is meant. | |
- match: <= | |
scope: keyword.operator.comparison.c | |
early-expressions-after-generic-type: | |
- include: members-arrow | |
- include: operators | |
- include: members-dot | |
- include: strings | |
- include: parens | |
- include: brackets | |
- include: block | |
- include: variables | |
- include: constants | |
- match: ',' | |
scope: punctuation.separator.c++ | |
- match: '\)|\}' | |
scope: invalid.illegal.stray-bracket-end.c++ | |
expressions-minus-generic-type: | |
- include: early-expressions-before-generic-type | |
- include: angle-brackets | |
- include: early-expressions-after-generic-type | |
- include: late-expressions | |
expressions-minus-generic-type-function-call: | |
- include: early-expressions-before-generic-type | |
- include: angle-brackets | |
- include: early-expressions-after-generic-type | |
- include: late-expressions-before-function-call | |
- include: identifiers | |
- match: ';' | |
scope: punctuation.terminator.c++ | |
late-expressions: | |
- include: late-expressions-before-function-call | |
- include: function-call | |
- include: identifiers | |
- match: ';' | |
scope: punctuation.terminator.c++ | |
late-expressions-before-function-call: | |
- include: unique-late-expressions | |
- include: modifiers-parens | |
- include: modifiers | |
- include: types | |
expressions-minus-function-call: | |
- include: early-expressions | |
- include: late-expressions-before-function-call | |
- include: identifiers | |
- match: ';' | |
scope: punctuation.terminator.c++ | |
comments: | |
- include: scope:source.c#comments | |
operators: | |
- include: scope:source.c#operators | |
modifiers: | |
- include: unique-modifiers | |
- include: scope:source.c#modifiers | |
variables: | |
- include: unique-variables | |
- include: scope:source.c#variables | |
constants: | |
- include: unique-constants | |
- include: scope:source.c#constants | |
keywords: | |
- include: unique-keywords | |
- include: scope:source.c#keywords | |
types: | |
- include: unique-types | |
- include: types-parens | |
- include: scope:source.c#types | |
strings: | |
- include: unique-strings | |
- match: '(L|u8|u|U)?(")' | |
captures: | |
1: storage.type.string.c++ | |
2: punctuation.definition.string.begin.c++ | |
push: | |
- meta_scope: string.quoted.double.c++ | |
- match: '"' | |
scope: punctuation.definition.string.end.c++ | |
pop: true | |
- include: scope:source.c#string_escaped_char | |
- match: |- | |
(?x)% | |
(\d+\$)? # field (argument #) | |
[#0\- +']* # flags | |
[,;:_]? # separator character (AltiVec) | |
((-?\d+)|\*(-?\d+\$)?)? # minimum field width | |
(\.((-?\d+)|\*(-?\d+\$)?)?)? # precision | |
(hh|h|ll|l|j|t|z|q|L|vh|vl|v|hv|hl)? # length modifier | |
(\[[^\]]+\]|[am]s|[diouxXDOUeEfFgGaACcSspn%]) # conversion type | |
scope: constant.other.placeholder.c++ | |
- match: '\{\{|\}\}' | |
scope: constant.character.escape.c++ | |
- include: formatting-syntax | |
- include: scope:source.c#strings | |
formatting-syntax: | |
# https://docs.python.org/3.6/library/string.html#formatstrings | |
- match: |- # simple form | |
(?x) | |
(\{) | |
(?: [\w.\[\]]+)? # field_name | |
( ! [ars])? # conversion | |
( : (?:{{format_spec}}| # format_spec OR | |
[^}%]*%.[^}]*) # any format-like string | |
)? | |
(\}) | |
scope: constant.other.placeholder.c++ | |
captures: | |
1: punctuation.definition.placeholder.begin.c++ | |
2: storage.modifier.c++onversion.c++ | |
3: constant.other.format-spec.c++ | |
4: punctuation.definition.placeholder.end.c++ | |
- match: \{(?=[^\}"']+\{[^"']*\}) # complex (nested) form | |
scope: punctuation.definition.placeholder.begin.c++ | |
push: | |
- meta_scope: constant.other.placeholder.c++ | |
- match: \} | |
scope: punctuation.definition.placeholder.end.c++ | |
pop: true | |
- match: '[\w.\[\]]+' | |
- match: '![ars]' | |
scope: storage.modifier.conversion.c++ | |
- match: ':' | |
push: | |
- meta_scope: meta.format-spec.c++ constant.other.format-spec.c++ | |
- match: (?=\}) | |
pop: true | |
- include: formatting-syntax | |
numbers: | |
- include: unique-numbers | |
- include: scope:source.c#numbers | |
## C++-specific contexts | |
case-default: | |
- match: '\b(default|case)\b' | |
scope: keyword.control.c++ | |
push: | |
- match: (?=[);,]) | |
pop: true | |
- match: ':' | |
scope: punctuation.separator.c++ | |
pop: true | |
- include: expressions | |
modifiers-parens: | |
- match: '\b(alignas)\b\s*(\()' | |
captures: | |
1: storage.modifier.c++ | |
2: meta.group.c++ punctuation.section.group.begin.c++ | |
push: | |
- meta_content_scope: meta.group.c++ | |
- match: '\)' | |
scope: meta.group.c++ punctuation.section.group.end.c++ | |
pop: true | |
- include: expressions | |
- match: \b(__attribute__)\s*(\(\() | |
captures: | |
1: storage.modifier.c++ | |
2: meta.group.c++ punctuation.section.group.begin.c++ | |
push : | |
- meta_scope: meta.attribute.c++ | |
- meta_content_scope: meta.group.c++ | |
- include: parens | |
- include: strings | |
- match: \)\) | |
scope: meta.group.c++ punctuation.section.group.end.c++ | |
pop: true | |
- match: \b(__declspec)(\() | |
captures: | |
1: storage.modifier.c++ | |
2: meta.group.c++ punctuation.section.group.begin.c++ | |
push: | |
- meta_content_scope: meta.group.c++ | |
- match: '\)' | |
scope: meta.group.c++ punctuation.section.group.end.c++ | |
pop: true | |
- match: '\b(align|allocate|code_seg|deprecated|property|uuid)\b\s*(\()' | |
captures: | |
1: storage.modifier.c++ | |
2: meta.group.c++ punctuation.section.group.begin.c++ | |
push: | |
- meta_content_scope: meta.group.c++ | |
- match: '\)' | |
scope: meta.group.c++ punctuation.section.group.end.c++ | |
pop: true | |
- include: numbers | |
- include: strings | |
- match: \b(get|put)\b | |
scope: variable.parameter.c++ | |
- match: ',' | |
scope: punctuation.separator.c++ | |
- match: '=' | |
scope: keyword.operator.assignment.c++ | |
- match: '\b(appdomain|deprecated|dllimport|dllexport|jintrinsic|naked|noalias|noinline|noreturn|nothrow|novtable|process|restrict|safebuffers|selectany|thread)\b' | |
scope: constant.other.c++ | |
types-parens: | |
- match: '\b(decltype)\b\s*(\()' | |
captures: | |
1: storage.type.c++ | |
2: meta.group.c++ punctuation.section.group.begin.c++ | |
push: | |
- meta_content_scope: meta.group.c++ | |
- match: '\)' | |
scope: meta.group.c++ punctuation.section.group.end.c++ | |
pop: true | |
- include: expressions | |
keywords-angle-brackets: | |
- match: \b({{casts}})\b\s* | |
scope: keyword.operator.word.cast.c++ | |
push: | |
- match: '>' | |
scope: punctuation.section.generic.end.c++ | |
pop: true | |
- match: '<' | |
scope: punctuation.section.generic.begin.c++ | |
push: | |
- match: '(?=>)' | |
pop: true | |
- include: expressions-minus-generic-type-function-call | |
keywords-parens: | |
- match: '\b(alignof|typeid|static_assert|sizeof)\b\s*(\()' | |
captures: | |
1: keyword.operator.word.c++ | |
2: meta.group.c++ punctuation.section.group.begin.c++ | |
push: | |
- meta_content_scope: meta.group.c++ | |
- match: '\)' | |
scope: meta.group.c++ punctuation.section.group.end.c++ | |
pop: true | |
- include: expressions | |
namespace: | |
- match: '\b(using)\s+(namespace)\s+(?={{path_lookahead}})' | |
captures: | |
1: keyword.control.c++ | |
2: keyword.control.c++ | |
push: | |
- include: identifiers | |
- match: '' | |
pop: true | |
- match: '\b(namespace)\s+(?=({{path_lookahead}})?(?!\s*[;,]))' | |
scope: meta.namespace.c++ | |
captures: | |
1: keyword.control.c++ | |
push: | |
- meta_content_scope: meta.namespace.c++ entity.name.namespace.c++ | |
- include: identifiers | |
- match: '' | |
set: | |
- meta_scope: meta.namespace.c++ | |
- include: comments | |
- match: '=' | |
scope: keyword.operator.alias.c++ | |
- match: '(?=;)' | |
pop: true | |
- match: '\}' | |
scope: meta.block.c++ punctuation.section.block.end.c++ | |
pop: true | |
- match: '\{' | |
scope: punctuation.section.block.begin.c++ | |
push: | |
- meta_scope: meta.block.c++ | |
- match: '(?=\})' | |
pop: true | |
- include: preprocessor-global | |
- include: global | |
- include: expressions | |
template-common: | |
# Exit the template scope if we hit some basic invalid characters. This | |
# helps when a user is in the middle of typing their template types and | |
# prevents re-highlighting the whole file until the next > is found. | |
- match: (?=[{};]) | |
pop: true | |
- include: expressions | |
template: | |
- match: \btemplate\b | |
scope: storage.type.template.c++ | |
push: | |
- meta_scope: meta.template.c++ | |
# Explicitly include comments here at the top, in order to NOT match the | |
# \S lookahead in the case of comments. | |
- include: comments | |
- match: < | |
scope: punctuation.section.generic.begin.c++ | |
set: | |
- meta_content_scope: meta.template.c++ | |
- match: '>' | |
scope: meta.template.c++ punctuation.section.generic.end.c++ | |
pop: true | |
- match: \.{3} | |
scope: keyword.operator.variadic.c++ | |
- match: \b(typename|{{before_tag}})\b | |
scope: storage.type.c++ | |
- include: template # include template here for nested templates | |
- include: template-common | |
- match: (?=\S) | |
set: | |
- meta_content_scope: meta.template.c++ | |
- match: \b({{before_tag}})\b | |
scope: storage.type.c++ | |
- include: template-common | |
generic-type: | |
- match: '(?=(?!template){{path_lookahead}}\s*{{generic_lookahead}}\s*\()' | |
push: | |
- meta_scope: meta.function-call.c++ | |
- match: \btemplate\b | |
scope: storage.type.template.c++ | |
- match: '(?:(::)\s*)?{{identifier}}\s*(::)\s*' | |
captures: | |
1: punctuation.accessor.double-colon.c++ | |
2: punctuation.accessor.double-colon.c++ | |
- match: (?:(::)\s*)?({{identifier}})\s*(<) | |
captures: | |
1: punctuation.accessor.double-colon.c++ | |
2: variable.function.c++ | |
3: punctuation.section.generic.begin.c++ | |
push: | |
- match: '>' | |
scope: punctuation.section.generic.end.c++ | |
pop: true | |
- include: expressions-minus-generic-type-function-call | |
- match: (?:(::)\s*)?({{identifier}})\s*(\() | |
captures: | |
1: punctuation.accessor.double-colon.c++ | |
2: variable.function.c++ | |
3: punctuation.section.group.begin.c++ | |
set: | |
- meta_scope: meta.function-call.c++ | |
- meta_content_scope: meta.group.c++ | |
- match: '\)' | |
scope: meta.group.c++ punctuation.section.group.end.c++ | |
pop: true | |
- include: expressions | |
- include: angle-brackets | |
- match: '\(' | |
scope: meta.group.c++ punctuation.section.group.begin.c++ | |
set: | |
- meta_scope: meta.function-call.c++ | |
- meta_content_scope: meta.group.c++ | |
- match: '\)' | |
scope: meta.group.c++ punctuation.section.group.end.c++ | |
pop: true | |
- include: expressions | |
- match: '(?=(?!template){{path_lookahead}}\s*{{generic_lookahead}})' | |
push: | |
- include: identifiers | |
- match: '<' | |
scope: punctuation.section.generic.begin.c++ | |
set: | |
- match: '>' | |
scope: punctuation.section.generic.end.c++ | |
pop: true | |
- include: expressions-minus-generic-type-function-call | |
angle-brackets: | |
- match: '<(?!<)' | |
scope: punctuation.section.generic.begin.c++ | |
push: | |
- match: '>' | |
scope: punctuation.section.generic.end.c++ | |
pop: true | |
- include: expressions-minus-generic-type-function-call | |
block: | |
- match: '\{' | |
scope: punctuation.section.block.begin.c++ | |
push: | |
- meta_scope: meta.block.c++ | |
- match: (?=^\s*#\s*(elif|else|endif)\b) | |
pop: true | |
- match: '\}' | |
scope: punctuation.section.block.end.c++ | |
pop: true | |
- include: statements | |
function-call: | |
- match: (?={{path_lookahead}}\s*\() | |
push: | |
- meta_scope: meta.function-call.c++ | |
- include: scope:source.c#c99 | |
- match: '(?:(::)\s*)?{{identifier}}\s*(::)\s*' | |
scope: variable.function.c++ | |
captures: | |
1: punctuation.accessor.c++ | |
2: punctuation.accessor.c++ | |
- match: '(?:(::)\s*)?{{identifier}}' | |
scope: variable.function.c++ | |
captures: | |
1: punctuation.accessor.c++ | |
- match: '\(' | |
scope: meta.group.c++ punctuation.section.group.begin.c++ | |
set: | |
- meta_content_scope: meta.function-call.c++ meta.group.c++ | |
- match: '\)' | |
scope: meta.function-call.c++ meta.group.c++ punctuation.section.group.end.c++ | |
pop: true | |
- include: expressions | |
members-inside-function-call: | |
- meta_content_scope: meta.method-call.c++ meta.group.c++ | |
- match: \) | |
scope: meta.method-call.c++ meta.group.c++ punctuation.section.group.end.c++ | |
pop: true | |
- include: expressions | |
members-after-accessor-junction: | |
# After we've seen an accessor (dot or arrow), this context decides what | |
# kind of entity we're accessing. | |
- include: comments | |
- match: \btemplate\b | |
scope: meta.method-call.c++ storage.type.template.c++ | |
# Guaranteed to be a template member function call after we match this | |
set: | |
- meta_content_scope: meta.method-call.c++ | |
- include: comments | |
- match: '{{identifier}}' | |
scope: variable.function.member.c++ | |
set: | |
- meta_content_scope: meta.method-call.c++ | |
- match: \( | |
scope: meta.group.c++ punctuation.section.group.begin.c++ | |
set: members-inside-function-call | |
- include: comments | |
- include: angle-brackets | |
- match: (?=\S) # safety pop | |
pop: true | |
- match: (?=\S) # safety pop | |
pop: true | |
# Operator overloading | |
- match: '({{operator_method_name}})\s*(\()' | |
captures: | |
0: meta.method-call.c++ | |
1: variable.function.member.c++ | |
2: meta.group.c++ punctuation.section.group.begin.c++ | |
set: members-inside-function-call | |
# Non-templated member function call | |
- match: (~?{{identifier}})\s*(\() | |
captures: | |
0: meta.method-call.c++ | |
1: variable.function.member.c++ | |
2: meta.group.c++ punctuation.section.group.begin.c++ | |
set: members-inside-function-call | |
# Templated member function call | |
- match: (~?{{identifier}})\s*(?={{generic_lookahead}}) | |
captures: | |
1: variable.function.member.c++ | |
set: | |
- meta_scope: meta.method-call.c++ | |
- match: < | |
scope: punctuation.section.generic.begin.c++ | |
set: | |
- meta_content_scope: meta.method-call.c++ | |
- match: '>' | |
scope: punctuation.section.generic.end.c++ | |
set: | |
- meta_content_scope: meta.method-call.c++ | |
- include: comments | |
- match: \( | |
scope: punctuation.section.group.begin.c++ | |
set: members-inside-function-call | |
- match: (?=\S) # safety pop | |
pop: true | |
- include: expressions | |
# Explicit base-class access | |
- match: ({{identifier}})\s*(::) | |
captures: | |
1: variable.other.base-class.c++ | |
2: punctuation.accessor.double-colon.c++ | |
set: members-after-accessor-junction # reset | |
# Just a regular member variable | |
- match: '{{identifier}}' | |
scope: variable.other.readwrite.member.c++ | |
pop: true | |
members-dot: | |
- include: scope:source.c#access-illegal | |
# No lookahead required because members-dot goes after operators in the | |
# early-expressions-after-generic-type context. This means triple dots | |
# (i.e. "..." or "variadic") is attempted first. | |
- match: \. | |
scope: punctuation.accessor.dot.c++ | |
push: members-after-accessor-junction | |
members-arrow: | |
# This needs to be before operators in the | |
# early-expressions-after-generic-type context because otherwise the "->" | |
# from the C language will match. | |
- match: -> | |
scope: punctuation.accessor.arrow.c++ | |
push: members-after-accessor-junction | |
typedef: | |
- match: \btypedef\b | |
scope: storage.type.c++ | |
push: | |
- match: ({{identifier}})?\s*(?=;) | |
captures: | |
1: entity.name.type.typedef.c++ | |
pop: true | |
- match: \b(struct)\s+({{identifier}})\b | |
captures: | |
1: storage.type.c++ | |
- include: expressions-minus-generic-type | |
parens: | |
- match: \( | |
scope: punctuation.section.group.begin.c++ | |
push: | |
- meta_scope: meta.group.c++ | |
- match: \) | |
scope: punctuation.section.group.end.c++ | |
pop: true | |
- include: expressions | |
brackets: | |
- match: \[ | |
scope: punctuation.section.brackets.begin.c++ | |
push: | |
- meta_scope: meta.brackets.c++ | |
- match: \] | |
scope: punctuation.section.brackets.end.c++ | |
pop: true | |
- include: expressions | |
function-trailing-return-type: | |
- match: '{{non_angle_brackets}}' | |
pop: true | |
- include: angle-brackets | |
- include: types | |
- include: modifiers-parens | |
- include: modifiers | |
- include: identifiers | |
- match: \*|& | |
scope: keyword.operator.c++ | |
- include: function-trailing-return-type-parens | |
- match: '(?=\S)' | |
pop: true | |
function-trailing-return-type-parens: | |
- match: \( | |
scope: punctuation.section.group.begin.c++ | |
push: | |
- meta_scope: meta.group.c++ | |
- match: \) | |
scope: punctuation.section.group.end.c++ | |
pop: true | |
- include: function-trailing-return-type | |
## Detection of function and data structure definitions at the global level | |
global-modifier: | |
- include: comments | |
- include: modifiers-parens | |
- include: modifiers | |
# Constructors and destructors don't have a type | |
- match: '(?={{path_lookahead}}\s*::\s*{{identifier}}\s*(\(|$))' | |
set: | |
- meta_content_scope: meta.function.c++ entity.name.function.constructor.c++ | |
- include: identifiers | |
- match: '(?=[^\w\s])' | |
set: function-definition-params | |
- match: '(?={{path_lookahead}}\s*::\s*~{{identifier}}\s*(\(|$))' | |
set: | |
- meta_content_scope: meta.function.c++ entity.name.function.destructor.c++ | |
- include: identifiers | |
- match: '~{{identifier}}' | |
- match: '(?=[^\w\s])' | |
set: function-definition-params | |
# If we see a path ending in :: before a newline, we don't know if it is | |
# a constructor or destructor, or a long return type, so we are just going | |
# to treat it like a regular function. Most likely it is a constructor, | |
# since it doesn't seem most developers would create such a long typename. | |
- match: '(?={{path_lookahead}}\s*::\s*$)' | |
set: | |
- meta_content_scope: meta.function.c++ entity.name.function.c++ | |
- include: identifiers | |
- match: '~{{identifier}}' | |
- match: '(?=[^\w\s])' | |
set: function-definition-params | |
- include: unique-strings | |
- match: '(?=\S)' | |
set: global-type | |
global-type: | |
- include: comments | |
- match: \*|& | |
scope: keyword.operator.c++ | |
- match: '(?=\b({{control_keywords}}|{{operator_keywords}}|{{casts}}|{{memory_operators}}|{{other_keywords}}|operator)\b)' | |
pop: true | |
- match: '(?=\s)' | |
set: global-maybe-function | |
# If a class/struct/enum followed by a name that is not a macro or declspec | |
# then this is likely a return type of a function. This is uncommon. | |
- match: |- | |
(?x: | |
({{before_tag}}) | |
\s+ | |
(?= | |
(?![[:upper:][:digit:]_]+\b|__declspec|{{before_tag}}) | |
{{path_lookahead}} | |
(\s+{{identifier}}\s*\(|\s*[*&]) | |
) | |
) | |
captures: | |
1: storage.type.c++ | |
set: | |
- include: identifiers | |
- match: '' | |
set: global-maybe-function | |
# The previous match handles return types of struct/enum/etc from a func, | |
# there this one exits the context to allow matching an actual struct/class | |
- match: '(?=\b({{before_tag}})\b)' | |
set: data-structures | |
- match: '(?=\b({{casts}})\b\s*<)' | |
pop: true | |
- match: '{{non_angle_brackets}}' | |
pop: true | |
- include: angle-brackets | |
- include: types | |
# Allow a macro call | |
- match: '({{identifier}})\s*(\()(?=[^\)]+\))' | |
captures: | |
1: variable.function.c++ | |
2: meta.group.c++ punctuation.section.group.begin.c++ | |
push: | |
- meta_scope: meta.function-call.c++ | |
- meta_content_scope: meta.group.c++ | |
- match: '\)' | |
scope: meta.group.c++ punctuation.section.group.end.c++ | |
pop: true | |
- include: expressions | |
- match: '(?={{path_lookahead}}\s*\()' | |
set: | |
- include: function-call | |
- match: '' | |
pop: true | |
- include: variables | |
- include: constants | |
- include: identifiers | |
- match: (?=\W) | |
pop: true | |
global-maybe-function: | |
- include: comments | |
# Consume pointer info, macros and any type info that was offset by macros | |
- match: \*|& | |
scope: keyword.operator.c++ | |
- match: '(?=\b({{control_keywords}}|{{operator_keywords}}|{{casts}}|{{memory_operators}}|{{other_keywords}})\b)' | |
pop: true | |
- match: '\b({{type_qualifier}})\b' | |
scope: storage.modifier.c++ | |
- match: '{{non_angle_brackets}}' | |
pop: true | |
- include: angle-brackets | |
- include: types | |
- include: modifiers-parens | |
- include: modifiers | |
# All uppercase identifier just before a newline is most likely a macro | |
- match: '[[:upper:][:digit:]_]+\s*$' | |
# Operator overloading | |
- match: '(?=({{path_lookahead}}\s*(?:{{generic_lookahead}})?::\s*)?{{operator_method_name}}\s*(\(|$))' | |
set: | |
- meta_content_scope: meta.function.c++ entity.name.function.c++ | |
- include: identifiers | |
- match: '(?=\s*(\(|$))' | |
set: function-definition-params | |
# Identifier that is not the function name - likely a macro or type | |
- match: '(?={{path_lookahead}}([ \t]+|[*&])(?!\s*(<|::|\(|$)))' | |
push: | |
- include: identifiers | |
- match: '' | |
pop: true | |
# Real function definition | |
- match: '(?={{path_lookahead}}({{generic_lookahead}}({{path_lookahead}})?)\s*(\(|$))' | |
set: [function-definition-params, global-function-identifier-generic] | |
- match: '(?={{path_lookahead}}\s*(\(|$))' | |
set: [function-definition-params, global-function-identifier] | |
- match: '(?={{path_lookahead}}\s*::\s*$)' | |
set: [function-definition-params, global-function-identifier] | |
- match: '(?=\S)' | |
pop: true | |
global-function-identifier-generic: | |
- include: angle-brackets | |
- match: '::' | |
scope: punctuation.accessor.c++ | |
- match: '(?={{identifier}}<.*>\s*\()' | |
push: | |
- meta_content_scope: entity.name.function.c++ | |
- include: identifiers | |
- match: '(?=<)' | |
pop: true | |
- match: '(?={{identifier}}\s*\()' | |
push: | |
- meta_content_scope: entity.name.function.c++ | |
- include: identifiers | |
- match: '' | |
pop: true | |
- match: '(?=\()' | |
pop: true | |
global-function-identifier: | |
- meta_content_scope: entity.name.function.c++ | |
- include: identifiers | |
- match: '(?=\S)' | |
pop: true | |
function-definition-params: | |
- meta_content_scope: meta.function.c++ | |
- include: comments | |
- match: '(?=\()' | |
set: | |
- match: \( | |
scope: meta.function.parameters.c++ meta.group.c++ punctuation.section.group.begin.c++ | |
set: | |
- meta_content_scope: meta.function.parameters.c++ meta.group.c++ | |
- match : \) | |
scope: punctuation.section.group.end.c++ | |
set: function-definition-continue | |
- match: '\bvoid\b' | |
scope: storage.type.c++ | |
- match: '{{identifier}}(?=\s*(\[|,|\)|=))' | |
scope: variable.parameter.c++ | |
- match: '=' | |
scope: keyword.operator.assignment.c++ | |
push: | |
- match: '(?=,|\))' | |
pop: true | |
- include: expressions-minus-generic-type | |
- include: scope:source.c#preprocessor-line-continuation | |
- include: expressions-minus-generic-type | |
- include: scope:source.c#preprocessor-line-continuation | |
- match: (?=\S) | |
pop: true | |
function-definition-continue: | |
- meta_content_scope: meta.function.c++ | |
- include: comments | |
- match: '(?=;)' | |
pop: true | |
- match: '->' | |
scope: punctuation.separator.c++ | |
set: function-definition-trailing-return | |
- include: function-specifiers | |
- match: '=' | |
scope: keyword.operator.assignment.c++ | |
- match: '&' | |
scope: keyword.operator.c++ | |
- match: \b0\b | |
scope: constant.numeric.c++ | |
- match: \b(default|delete)\b | |
scope: storage.modifier.c++ | |
- match: '(?=\{)' | |
set: function-definition-body | |
- match: '(?=\S)' | |
pop: true | |
function-definition-trailing-return: | |
- include: comments | |
- match: '(?=;)' | |
pop: true | |
- match: '(?=\{)' | |
set: function-definition-body | |
- include: function-specifiers | |
- include: function-trailing-return-type | |
function-definition-body: | |
- meta_content_scope: meta.function.c++ meta.block.c++ | |
- match: '\{' | |
scope: punctuation.section.block.begin.c++ | |
set: | |
- meta_content_scope: meta.function.c++ meta.block.c++ | |
- match: '\}' | |
scope: meta.function.c++ meta.block.c++ punctuation.section.block.end.c++ | |
pop: true | |
- match: (?=^\s*#\s*(elif|else|endif)\b) | |
pop: true | |
- match: '(?=({{before_tag}})([^(;]+$|.*\{))' | |
push: data-structures | |
- include: statements | |
## Data structures including classes, structs, unions and enums | |
data-structures: | |
- match: '\bclass\b' | |
scope: storage.type.c++ | |
set: data-structures-class-definition | |
# Detect variable type definitions using struct/enum/union followed by a tag | |
- match: '\b({{before_tag}})(?=\s+{{path_lookahead}}\s+{{path_lookahead}}\s*[=;\[])' | |
scope: storage.type.c++ | |
- match: '\bstruct\b' | |
scope: storage.type.c++ | |
set: data-structures-struct-definition | |
- match: '\benum(\s+(class|struct))?\b' | |
scope: storage.type.c++ | |
set: data-structures-enum-definition | |
- match: '\bunion\b' | |
scope: storage.type.c++ | |
set: data-structures-union-definition | |
- match: '(?=\S)' | |
pop: true | |
preprocessor-workaround-eat-macro-before-identifier: | |
# Handle macros so they aren't matched as the class name | |
- match: ({{macro_identifier}})(?=\s+~?{{identifier}}) | |
captures: | |
1: meta.assumed-macro.c | |
data-structures-class-definition: | |
- meta_scope: meta.class.c++ | |
- include: data-structures-definition-common-begin | |
- match: '{{identifier}}(?={{data_structures_forward_decl_lookahead}})' | |
scope: entity.name.class.forward-decl.c++ | |
set: data-structures-class-definition-after-identifier | |
- match: '{{identifier}}' | |
scope: entity.name.class.c++ | |
set: data-structures-class-definition-after-identifier | |
- match: '(?=[:{])' | |
set: data-structures-class-definition-after-identifier | |
- match: '(?=;)' | |
pop: true | |
data-structures-class-definition-after-identifier: | |
- meta_content_scope: meta.class.c++ | |
- include: data-structures-definition-common-begin | |
# No matching of identifiers since they should all be macros at this point | |
- include: data-structures-definition-common-end | |
- match: '\{' | |
scope: meta.block.c++ punctuation.section.block.begin.c++ | |
set: | |
- meta_content_scope: meta.class.c++ meta.block.c++ | |
- match: '\}' | |
scope: meta.class.c++ meta.block.c++ punctuation.section.block.end.c++ | |
pop: true | |
- include: data-structures-body | |
data-structures-struct-definition: | |
- meta_scope: meta.struct.c++ | |
- include: data-structures-definition-common-begin | |
- match: '{{identifier}}(?={{data_structures_forward_decl_lookahead}})' | |
scope: entity.name.struct.forward-decl.c++ | |
set: data-structures-struct-definition-after-identifier | |
- match: '{{identifier}}' | |
scope: entity.name.struct.c++ | |
set: data-structures-struct-definition-after-identifier | |
- match: '(?=[:{])' | |
set: data-structures-struct-definition-after-identifier | |
- match: '(?=;)' | |
pop: true | |
data-structures-struct-definition-after-identifier: | |
- meta_content_scope: meta.struct.c++ | |
- include: data-structures-definition-common-begin | |
# No matching of identifiers since they should all be macros at this point | |
- include: data-structures-definition-common-end | |
- match: '\{' | |
scope: meta.block.c++ punctuation.section.block.begin.c++ | |
set: | |
- meta_content_scope: meta.struct.c++ meta.block.c++ | |
- match: '\}' | |
scope: meta.struct.c++ meta.block.c++ punctuation.section.block.end.c++ | |
pop: true | |
- include: data-structures-body | |
data-structures-enum-definition: | |
- meta_scope: meta.enum.c++ | |
- include: data-structures-definition-common-begin | |
- match: '{{identifier}}(?={{data_structures_forward_decl_lookahead}})' | |
scope: entity.name.enum.forward-decl.c++ | |
set: data-structures-enum-definition-after-identifier | |
- match: '{{identifier}}' | |
scope: entity.name.enum.c++ | |
set: data-structures-enum-definition-after-identifier | |
- match: '(?=[:{])' | |
set: data-structures-enum-definition-after-identifier | |
- match: '(?=;)' | |
pop: true | |
data-structures-enum-definition-after-identifier: | |
- meta_content_scope: meta.enum.c++ | |
- include: data-structures-definition-common-begin | |
# No matching of identifiers since they should all be macros at this point | |
- include: data-structures-definition-common-end | |
- match: '\{' | |
scope: meta.block.c++ punctuation.section.block.begin.c++ | |
set: | |
- meta_content_scope: meta.enum.c++ meta.block.c++ | |
# Enums don't support methods so we have a simplified body | |
- match: '\}' | |
scope: meta.enum.c++ meta.block.c++ punctuation.section.block.end.c++ | |
pop: true | |
- include: statements | |
data-structures-union-definition: | |
- meta_scope: meta.union.c++ | |
- include: data-structures-definition-common-begin | |
- match: '{{identifier}}(?={{data_structures_forward_decl_lookahead}})' | |
scope: entity.name.union.forward-decl.c++ | |
set: data-structures-union-definition-after-identifier | |
- match: '{{identifier}}' | |
scope: entity.name.union.c++ | |
set: data-structures-union-definition-after-identifier | |
- match: '(?=[{])' | |
set: data-structures-union-definition-after-identifier | |
- match: '(?=;)' | |
pop: true | |
data-structures-union-definition-after-identifier: | |
- meta_content_scope: meta.union.c++ | |
- include: data-structures-definition-common-begin | |
# No matching of identifiers since they should all be macros at this point | |
# Unions don't support base classes | |
- include: angle-brackets | |
- match: '\{' | |
scope: meta.block.c++ punctuation.section.block.begin.c++ | |
set: | |
- meta_content_scope: meta.union.c++ meta.block.c++ | |
- match: '\}' | |
scope: meta.union.c++ meta.block.c++ punctuation.section.block.end.c++ | |
pop: true | |
- include: data-structures-body | |
- match: '(?=;)' | |
pop: true | |
data-structures-definition-common-begin: | |
- include: comments | |
- match: '(?=\b(?:{{before_tag}}|{{control_keywords}})\b)' | |
pop: true | |
- include: preprocessor-other | |
- include: modifiers-parens | |
- include: modifiers | |
- include: preprocessor-workaround-eat-macro-before-identifier | |
data-structures-definition-common-end: | |
- include: angle-brackets | |
- match: \bfinal\b | |
scope: storage.modifier.c++ | |
- match: ':' | |
scope: punctuation.separator.c++ | |
push: | |
- include: comments | |
- include: preprocessor-other | |
- include: modifiers-parens | |
- include: modifiers | |
- match: '\b(virtual|{{visibility_modifiers}})\b' | |
scope: storage.modifier.c++ | |
- match: (?={{path_lookahead}}) | |
push: | |
- meta_scope: entity.other.inherited-class.c++ | |
- include: identifiers | |
- match: '' | |
pop: true | |
- include: angle-brackets | |
- match: ',' | |
scope: punctuation.separator.c++ | |
- match: (?=\{|;) | |
pop: true | |
- match: '(?=;)' | |
pop: true | |
data-structures-body: | |
- include: preprocessor-data-structures | |
- match: '(?=\btemplate\b)' | |
push: | |
- include: template | |
- match: (?=\S) | |
set: data-structures-modifier | |
- include: typedef | |
- match: \b({{visibility_modifiers}})\s*(:)(?!:) | |
captures: | |
1: storage.modifier.c++ | |
2: punctuation.section.class.c++ | |
- match: '^\s*(?=(?:~?\w+|::))' | |
push: data-structures-modifier | |
- include: expressions-minus-generic-type | |
data-structures-modifier: | |
- match: '\bfriend\b' | |
scope: storage.modifier.c++ | |
push: | |
- match: (?=;) | |
pop: true | |
- match: '\{' | |
scope: punctuation.section.block.begin.c++ | |
set: | |
- meta_scope: meta.block.c++ | |
- match: '\}' | |
scope: punctuation.section.block.end.c++ | |
pop: true | |
- include: statements | |
- match: '\b({{before_tag}})\b' | |
scope: storage.type.c++ | |
- include: expressions-minus-function-call | |
- include: comments | |
- include: modifiers-parens | |
- include: modifiers | |
- match: '\bstatic_assert(?=\s*\()' | |
scope: meta.static-assert.c++ keyword.operator.word.c++ | |
push: | |
- match: '\(' | |
scope: meta.group.c++ punctuation.section.group.begin.c++ | |
set: | |
- meta_content_scope: meta.function-call.c++ meta.group.c++ | |
- match: '\)' | |
scope: meta.function-call.c++ meta.group.c++ punctuation.section.group.end.c++ | |
pop: true | |
- include: expressions | |
# Destructor | |
- match: '(?:{{identifier}}\s*(::)\s*)?~{{identifier}}(?=\s*(\(|$))' | |
scope: meta.method.destructor.c++ entity.name.function.destructor.c++ | |
captures: | |
1: punctuation.accessor.c++ | |
set: method-definition-params | |
# It's a macro, not a constructor if there is no type in the first param | |
- match: '({{identifier}})\s*(\()(?=\s*(?!void){{identifier}}\s*[),])' | |
captures: | |
1: variable.function.c++ | |
2: meta.group.c++ punctuation.section.group.begin.c++ | |
push: | |
- meta_scope: meta.function-call.c++ | |
- meta_content_scope: meta.group.c++ | |
- match: '\)' | |
scope: meta.group.c++ punctuation.section.group.end.c++ | |
pop: true | |
- include: expressions | |
# Constructor | |
- include: preprocessor-workaround-eat-macro-before-identifier | |
- match: '((?!{{before_tag}}|template){{identifier}})(?=\s*\()' | |
scope: meta.method.constructor.c++ entity.name.function.constructor.c++ | |
set: method-definition-params | |
# Long form constructor | |
- match: '({{identifier}}\s*(::)\s*{{identifier}})(?=\s*\()' | |
captures: | |
1: meta.method.constructor.c++ entity.name.function.constructor.c++ | |
2: punctuation.accessor.c++ | |
push: method-definition-params | |
- match: '(?=\S)' | |
set: data-structures-type | |
data-structures-type: | |
- include: comments | |
- match: \*|& | |
scope: keyword.operator.c++ | |
# Cast methods | |
- match: '(operator)\s+({{identifier}})(?=\s*(\(|$))' | |
captures: | |
1: keyword.control.c++ | |
2: meta.method.c++ entity.name.function.c++ | |
set: method-definition-params | |
- match: '(?=\b({{control_keywords}}|{{operator_keywords}}|{{casts}}|{{memory_operators}}|{{other_keywords}}|operator)\b)' | |
pop: true | |
- match: '(?=\s)' | |
set: data-structures-maybe-method | |
# If a class/struct/enum followed by a name that is not a macro or declspec | |
# then this is likely a return type of a function. This is uncommon. | |
- match: |- | |
(?x: | |
({{before_tag}}) | |
\s+ | |
(?= | |
(?![[:upper:][:digit:]_]+\b|__declspec|{{before_tag}}) | |
{{path_lookahead}} | |
(\s+{{identifier}}\s*\(|\s*[*&]) | |
) | |
) | |
captures: | |
1: storage.type.c++ | |
set: | |
- include: identifiers | |
- match: '' | |
set: data-structures-maybe-method | |
# The previous match handles return types of struct/enum/etc from a func, | |
# there this one exits the context to allow matching an actual struct/class | |
- match: '(?=\b({{before_tag}})\b)' | |
set: data-structures | |
- match: '(?=\b({{casts}})\b\s*<)' | |
pop: true | |
- match: '{{non_angle_brackets}}' | |
pop: true | |
- include: angle-brackets | |
- include: types | |
- include: variables | |
- include: constants | |
- include: identifiers | |
- match: (?=[&*]) | |
set: data-structures-maybe-method | |
- match: (?=\W) | |
pop: true | |
data-structures-maybe-method: | |
- include: comments | |
# Consume pointer info, macros and any type info that was offset by macros | |
- match: \*|& | |
scope: keyword.operator.c++ | |
- match: '(?=\b({{control_keywords}}|{{operator_keywords}}|{{casts}}|{{memory_operators}}|{{other_keywords}})\b)' | |
pop: true | |
- match: '\b({{type_qualifier}})\b' | |
scope: storage.modifier.c++ | |
- match: '{{non_angle_brackets}}' | |
pop: true | |
- include: angle-brackets | |
- include: types | |
- include: modifiers-parens | |
- include: modifiers | |
# Operator overloading | |
- match: '{{operator_method_name}}(?=\s*(\(|$))' | |
scope: meta.method.c++ entity.name.function.c++ | |
set: method-definition-params | |
# Identifier that is not the function name - likely a macro or type | |
- match: '(?={{path_lookahead}}([ \t]+|[*&])(?!\s*(<|::|\()))' | |
push: | |
- include: identifiers | |
- match: '' | |
pop: true | |
# Real function definition | |
- match: '(?={{path_lookahead}}({{generic_lookahead}})\s*(\())' | |
set: [method-definition-params, data-structures-function-identifier-generic] | |
- match: '(?={{path_lookahead}}\s*(\())' | |
set: [method-definition-params, data-structures-function-identifier] | |
- match: '(?={{path_lookahead}}\s*::\s*$)' | |
set: [method-definition-params, data-structures-function-identifier] | |
- match: '(?=\S)' | |
pop: true | |
data-structures-function-identifier-generic: | |
- include: angle-brackets | |
- match: '(?={{identifier}})' | |
push: | |
- meta_content_scope: entity.name.function.c++ | |
- include: identifiers | |
- match: '(?=<)' | |
pop: true | |
- match: '(?=\()' | |
pop: true | |
data-structures-function-identifier: | |
- meta_content_scope: entity.name.function.c++ | |
- include: identifiers | |
- match: '(?=\S)' | |
pop: true | |
method-definition-params: | |
- meta_content_scope: meta.method.c++ | |
- include: comments | |
- match: '(?=\()' | |
set: | |
- match: \( | |
scope: meta.method.parameters.c++ meta.group.c++ punctuation.section.group.begin.c++ | |
set: | |
- meta_content_scope: meta.method.parameters.c++ meta.group.c++ | |
- match : \) | |
scope: punctuation.section.group.end.c++ | |
set: method-definition-continue | |
- match: '\bvoid\b' | |
scope: storage.type.c++ | |
- match: '{{identifier}}(?=\s*(\[|,|\)|=))' | |
scope: variable.parameter.c++ | |
- match: '=' | |
scope: keyword.operator.assignment.c++ | |
push: | |
- match: '(?=,|\))' | |
pop: true | |
- include: expressions-minus-generic-type | |
- include: expressions-minus-generic-type | |
- match: '(?=\S)' | |
pop: true | |
method-definition-continue: | |
- meta_content_scope: meta.method.c++ | |
- include: comments | |
- match: '(?=;)' | |
pop: true | |
- match: '->' | |
scope: punctuation.separator.c++ | |
set: method-definition-trailing-return | |
- include: function-specifiers | |
- match: '=' | |
scope: keyword.operator.assignment.c++ | |
- match: '&' | |
scope: keyword.operator.c++ | |
- match: \b0\b | |
scope: constant.numeric.c++ | |
- match: \b(default|delete)\b | |
scope: storage.modifier.c++ | |
- match: '(?=:)' | |
set: | |
- match: ':' | |
scope: punctuation.separator.initializer-list.c++ | |
set: | |
- meta_scope: meta.method.constructor.initializer-list.c++ | |
- match: '{{identifier}}' | |
scope: variable.other.readwrite.member.c++ | |
push: | |
- match: \( | |
scope: meta.group.c++ punctuation.section.group.begin.c++ | |
set: | |
- meta_content_scope: meta.group.c++ | |
- match: \) | |
scope: meta.group.c++ punctuation.section.group.end.c++ | |
pop: true | |
- include: expressions | |
- match: \{ | |
scope: meta.group.c++ punctuation.section.group.begin.c++ | |
set: | |
- meta_content_scope: meta.group.c++ | |
- match: \} | |
scope: meta.group.c++ punctuation.section.group.end.c++ | |
pop: true | |
- include: expressions | |
- include: comments | |
- match: (?=\{|;) | |
set: method-definition-continue | |
- include: expressions | |
- match: '(?=\{)' | |
set: method-definition-body | |
- match: '(?=\S)' | |
pop: true | |
method-definition-trailing-return: | |
- include: comments | |
- match: '(?=;)' | |
pop: true | |
- match: '(?=\{)' | |
set: method-definition-body | |
- include: function-specifiers | |
- include: function-trailing-return-type | |
method-definition-body: | |
- meta_content_scope: meta.method.c++ meta.block.c++ | |
- match: '\{' | |
scope: punctuation.section.block.begin.c++ | |
set: | |
- meta_content_scope: meta.method.c++ meta.block.c++ | |
- match: '\}' | |
scope: meta.method.c++ meta.block.c++ punctuation.section.block.end.c++ | |
pop: true | |
- match: (?=^\s*#\s*(elif|else|endif)\b) | |
pop: true | |
- match: '(?=({{before_tag}})([^(;]+$|.*\{))' | |
push: data-structures | |
- include: statements | |
## Preprocessor for data-structures | |
preprocessor-data-structures: | |
- include: preprocessor-rule-enabled-data-structures | |
- include: preprocessor-rule-disabled-data-structures | |
- include: preprocessor-practical-workarounds | |
preprocessor-rule-disabled-data-structures: | |
- match: ^\s*((#if)\s+(0))\b | |
captures: | |
1: meta.preprocessor.c++ | |
2: keyword.control.import.c++ | |
3: constant.numeric.preprocessor.c++ | |
push: | |
- match: ^\s*(#\s*endif)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.c++ | |
pop: true | |
- match: ^\s*(#\s*else)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.else.c++ | |
push: | |
- match: (?=^\s*#\s*endif\b) | |
pop: true | |
- include: negated-block | |
- include: data-structures-body | |
- match: "" | |
push: | |
- meta_scope: comment.block.preprocessor.if-branch.c++ | |
- match: (?=^\s*#\s*(else|endif)\b) | |
pop: true | |
- include: scope:source.c#preprocessor-disabled | |
preprocessor-rule-enabled-data-structures: | |
- match: ^\s*((#if)\s+(0*1))\b | |
captures: | |
1: meta.preprocessor.c++ | |
2: keyword.control.import.c++ | |
3: constant.numeric.preprocessor.c++ | |
push: | |
- match: ^\s*(#\s*endif)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.c++ | |
pop: true | |
- match: ^\s*(#\s*else)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.else.c++ | |
push: | |
- meta_content_scope: comment.block.preprocessor.else-branch.c++ | |
- match: (?=^\s*#\s*endif\b) | |
pop: true | |
- include: scope:source.c#preprocessor-disabled | |
- match: "" | |
push: | |
- match: (?=^\s*#\s*(else|endif)\b) | |
pop: true | |
- include: negated-block | |
- include: data-structures-body | |
## Preprocessor for global | |
preprocessor-global: | |
- include: preprocessor-rule-enabled-global | |
- include: preprocessor-rule-disabled-global | |
- include: preprocessor-rule-other-global | |
preprocessor-statements: | |
- include: preprocessor-rule-enabled-statements | |
- include: preprocessor-rule-disabled-statements | |
- include: preprocessor-rule-other-statements | |
preprocessor-expressions: | |
- include: scope:source.c#incomplete-inc | |
- include: preprocessor-macro-define | |
- include: scope:source.c#pragma-mark | |
- include: preprocessor-other | |
preprocessor-rule-disabled-global: | |
- match: ^\s*((#if)\s+(0))\b | |
captures: | |
1: meta.preprocessor.c++ | |
2: keyword.control.import.c++ | |
3: constant.numeric.preprocessor.c++ | |
push: | |
- match: ^\s*(#\s*endif)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.c++ | |
pop: true | |
- match: ^\s*(#\s*else)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.else.c++ | |
push: | |
- match: (?=^\s*#\s*endif\b) | |
pop: true | |
- include: preprocessor-global | |
- include: negated-block | |
- include: global | |
- match: "" | |
push: | |
- meta_scope: comment.block.preprocessor.if-branch.c++ | |
- match: (?=^\s*#\s*(else|endif)\b) | |
pop: true | |
- include: scope:source.c#preprocessor-disabled | |
preprocessor-rule-enabled-global: | |
- match: ^\s*((#if)\s+(0*1))\b | |
captures: | |
1: meta.preprocessor.c++ | |
2: keyword.control.import.c++ | |
3: constant.numeric.preprocessor.c++ | |
push: | |
- match: ^\s*(#\s*endif)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.c++ | |
pop: true | |
- match: ^\s*(#\s*else)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.else.c++ | |
push: | |
- meta_content_scope: comment.block.preprocessor.else-branch.c++ | |
- match: (?=^\s*#\s*endif\b) | |
pop: true | |
- include: scope:source.c#preprocessor-disabled | |
- match: "" | |
push: | |
- match: (?=^\s*#\s*(else|endif)\b) | |
pop: true | |
- include: preprocessor-global | |
- include: negated-block | |
- include: global | |
preprocessor-rule-other-global: | |
- match: ^\s*(#\s*(?:if|ifdef|ifndef))\b | |
captures: | |
1: keyword.control.import.c++ | |
push: | |
- meta_scope: meta.preprocessor.c++ | |
- include: scope:source.c#preprocessor-line-continuation | |
- include: scope:source.c#preprocessor-comments | |
- match: \bdefined\b | |
scope: keyword.control.c++ | |
# Enter a new scope where all elif/else branches have their | |
# contexts popped by a subsequent elif/else/endif. This ensures that | |
# preprocessor branches don't push multiple meta.block scopes on | |
# the stack, thus messing up the "global" context's detection of | |
# functions. | |
- match: $\n | |
set: preprocessor-if-branch-global | |
# These gymnastics here ensure that we are properly handling scope even | |
# when the preprocessor is used to create different scope beginnings, such | |
# as a different if/while condition | |
preprocessor-if-branch-global: | |
- match: ^\s*(#\s*endif)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.c++ | |
pop: true | |
- match: (?=^\s*#\s*(elif|else)\b) | |
push: preprocessor-elif-else-branch-global | |
- match: \{ | |
scope: punctuation.section.block.begin.c++ | |
set: preprocessor-block-if-branch-global | |
- include: preprocessor-global | |
- include: negated-block | |
- include: global | |
preprocessor-block-if-branch-global: | |
- meta_scope: meta.block.c++ | |
- match: ^\s*(#\s*endif)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.c++ | |
set: preprocessor-block-finish-global | |
- match: (?=^\s*#\s*(elif|else)\b) | |
push: preprocessor-elif-else-branch-global | |
- match: \} | |
scope: punctuation.section.block.end.c++ | |
set: preprocessor-if-branch-global | |
- include: statements | |
preprocessor-block-finish-global: | |
- meta_scope: meta.block.c++ | |
- match: ^\s*(#\s*(?:if|ifdef|ifndef))\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.c++ | |
set: preprocessor-block-finish-if-branch-global | |
- match: \} | |
scope: punctuation.section.block.end.c++ | |
pop: true | |
- include: statements | |
preprocessor-block-finish-if-branch-global: | |
- match: ^\s*(#\s*endif)\b | |
captures: | |
1: keyword.control.import.c++ | |
pop: true | |
- match: \} | |
scope: punctuation.section.block.end.c++ | |
set: preprocessor-if-branch-global | |
- include: statements | |
preprocessor-elif-else-branch-global: | |
- match: (?=^\s*#\s*(endif)\b) | |
pop: true | |
- include: preprocessor-global | |
- include: negated-block | |
- include: global | |
## Preprocessor for statements | |
preprocessor-rule-disabled-statements: | |
- match: ^\s*((#if)\s+(0))\b | |
captures: | |
1: meta.preprocessor.c++ | |
2: keyword.control.import.c++ | |
3: constant.numeric.preprocessor.c++ | |
push: | |
- match: ^\s*(#\s*endif)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.c++ | |
pop: true | |
- match: ^\s*(#\s*else)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.else.c++ | |
push: | |
- match: (?=^\s*#\s*endif\b) | |
pop: true | |
- include: negated-block | |
- include: statements | |
- match: "" | |
push: | |
- meta_scope: comment.block.preprocessor.if-branch.c++ | |
- match: (?=^\s*#\s*(else|endif)\b) | |
pop: true | |
- include: scope:source.c#preprocessor-disabled | |
preprocessor-rule-enabled-statements: | |
- match: ^\s*((#if)\s+(0*1))\b | |
captures: | |
1: meta.preprocessor.c++ | |
2: keyword.control.import.c++ | |
3: constant.numeric.preprocessor.c++ | |
push: | |
- match: ^\s*(#\s*endif)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.c++ | |
pop: true | |
- match: ^\s*(#\s*else)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.else.c++ | |
push: | |
- meta_content_scope: comment.block.preprocessor.else-branch.c++ | |
- match: (?=^\s*#\s*endif\b) | |
pop: true | |
- include: scope:source.c#preprocessor-disabled | |
- match: "" | |
push: | |
- match: (?=^\s*#\s*(else|endif)\b) | |
pop: true | |
- include: negated-block | |
- include: statements | |
preprocessor-rule-other-statements: | |
- match: ^\s*(#\s*(?:if|ifdef|ifndef))\b | |
captures: | |
1: keyword.control.import.c++ | |
push: | |
- meta_scope: meta.preprocessor.c++ | |
- include: scope:source.c#preprocessor-line-continuation | |
- include: scope:source.c#preprocessor-comments | |
- match: \bdefined\b | |
scope: keyword.control.c++ | |
# Enter a new scope where all elif/else branches have their | |
# contexts popped by a subsequent elif/else/endif. This ensures that | |
# preprocessor branches don't push multiple meta.block scopes on | |
# the stack, thus messing up the "global" context's detection of | |
# functions. | |
- match: $\n | |
set: preprocessor-if-branch-statements | |
# These gymnastics here ensure that we are properly handling scope even | |
# when the preprocessor is used to create different scope beginnings, such | |
# as a different if/while condition | |
preprocessor-if-branch-statements: | |
- match: ^\s*(#\s*endif)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.c++ | |
pop: true | |
- match: (?=^\s*#\s*(elif|else)\b) | |
push: preprocessor-elif-else-branch-statements | |
- match: \{ | |
scope: punctuation.section.block.begin.c++ | |
set: preprocessor-block-if-branch-statements | |
- match: (?=(?!{{non_func_keywords}}){{path_lookahead}}\s*\() | |
set: preprocessor-if-branch-function-call | |
- include: negated-block | |
- include: statements | |
preprocessor-if-branch-function-call: | |
- meta_content_scope: meta.function-call.c++ | |
- include: scope:source.c#c99 | |
- match: '(?:(::)\s*)?{{identifier}}\s*(::)\s*' | |
scope: variable.function.c++ | |
captures: | |
1: punctuation.accessor.c++ | |
2: punctuation.accessor.c++ | |
- match: '(?:(::)\s*)?{{identifier}}' | |
scope: variable.function.c++ | |
captures: | |
1: punctuation.accessor.c++ | |
- match: '\(' | |
scope: meta.group.c++ punctuation.section.group.begin.c++ | |
set: preprocessor-if-branch-function-call-arguments | |
preprocessor-if-branch-function-call-arguments: | |
- meta_content_scope: meta.function-call.c++ meta.group.c++ | |
- match : \) | |
scope: meta.function-call.c++ meta.group.c++ punctuation.section.group.end.c++ | |
set: preprocessor-if-branch-statements | |
- match: ^\s*(#\s*(?:elif|else))\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.c++ | |
set: preprocessor-if-branch-statements | |
- match: ^\s*(#\s*endif)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.c++ | |
set: preprocessor-if-branch-function-call-arguments-finish | |
- include: expressions | |
preprocessor-if-branch-function-call-arguments-finish: | |
- meta_content_scope: meta.function-call.c++ meta.group.c++ | |
- match: \) | |
scope: meta.function-call.c++ meta.group.c++ punctuation.section.group.end.c++ | |
pop: true | |
- include: expressions | |
preprocessor-block-if-branch-statements: | |
- meta_scope: meta.block.c++ | |
- match: ^\s*(#\s*endif)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.c++ | |
set: preprocessor-block-finish-statements | |
- match: (?=^\s*#\s*(elif|else)\b) | |
push: preprocessor-elif-else-branch-statements | |
- match: \} | |
scope: punctuation.section.block.end.c++ | |
set: preprocessor-if-branch-statements | |
- include: statements | |
preprocessor-block-finish-statements: | |
- meta_scope: meta.block.c++ | |
- match: ^\s*(#\s*(?:if|ifdef|ifndef))\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.c++ | |
set: preprocessor-block-finish-if-branch-statements | |
- match: \} | |
scope: punctuation.section.block.end.c++ | |
pop: true | |
- include: statements | |
preprocessor-block-finish-if-branch-statements: | |
- match: ^\s*(#\s*endif)\b | |
captures: | |
1: keyword.control.import.c++ | |
pop: true | |
- match: \} | |
scope: meta.block.c++ punctuation.section.block.end.c++ | |
set: preprocessor-if-branch-statements | |
- include: statements | |
preprocessor-elif-else-branch-statements: | |
- match: (?=^\s*#\s*endif\b) | |
pop: true | |
- include: negated-block | |
- include: statements | |
## Preprocessor other | |
negated-block: | |
- match: '\}' | |
scope: punctuation.section.block.end.c++ | |
push: | |
- match: '\{' | |
scope: punctuation.section.block.begin.c++ | |
pop: true | |
- match: (?=^\s*#\s*(elif|else|endif)\b) | |
pop: true | |
- include: statements | |
preprocessor-macro-define: | |
- match: ^\s*(\#\s*define)\b | |
captures: | |
1: meta.preprocessor.macro.c++ keyword.control.import.define.c++ | |
push: | |
- meta_content_scope: meta.preprocessor.macro.c++ | |
- include: scope:source.c#preprocessor-line-continuation | |
- include: scope:source.c#preprocessor-line-ending | |
- include: scope:source.c#preprocessor-comments | |
- match: '({{identifier}})(?=\()' | |
scope: entity.name.function.preprocessor.c++ | |
set: | |
- match: '\(' | |
scope: punctuation.section.group.begin.c++ | |
set: preprocessor-macro-params | |
- match: '{{identifier}}' | |
scope: entity.name.constant.preprocessor.c++ | |
set: preprocessor-macro-definition | |
preprocessor-macro-params: | |
- meta_scope: meta.preprocessor.macro.parameters.c++ meta.group.c++ | |
- match: '{{identifier}}' | |
scope: variable.parameter.c++ | |
- match: \) | |
scope: punctuation.section.group.end.c++ | |
set: preprocessor-macro-definition | |
- match: ',' | |
scope: punctuation.separator.c++ | |
push: | |
- match: '{{identifier}}' | |
scope: variable.parameter.c++ | |
pop: true | |
- include: scope:source.c#preprocessor-line-continuation | |
- include: scope:source.c#preprocessor-comments | |
- match: '\.\.\.' | |
scope: keyword.operator.variadic.c++ | |
- match: '(?=\))' | |
pop: true | |
- match: (/\*).*(\*/) | |
scope: comment.block.c++ | |
captures: | |
1: punctuation.definition.comment.c++ | |
2: punctuation.definition.comment.c++ | |
- match: '\S+' | |
scope: invalid.illegal.unexpected-character.c++ | |
- include: scope:source.c#preprocessor-line-continuation | |
- include: scope:source.c#preprocessor-comments | |
- match: '\.\.\.' | |
scope: keyword.operator.variadic.c++ | |
- match: (/\*).*(\*/) | |
scope: comment.block.c++ | |
captures: | |
1: punctuation.definition.comment.c++ | |
2: punctuation.definition.comment.c++ | |
- match: $\n | |
scope: invalid.illegal.unexpected-end-of-line.c++ | |
preprocessor-macro-definition: | |
- meta_content_scope: meta.preprocessor.macro.c++ | |
- include: scope:source.c#preprocessor-line-continuation | |
- include: scope:source.c#preprocessor-line-ending | |
- include: scope:source.c#preprocessor-comments | |
# Don't define blocks in define statements | |
- match: '\{' | |
scope: punctuation.section.block.begin.c++ | |
- match: '\}' | |
scope: punctuation.section.block.end.c++ | |
- include: expressions | |
preprocessor-practical-workarounds: | |
- include: preprocessor-convention-ignore-uppercase-ident-lines | |
- include: scope:source.c#preprocessor-convention-ignore-uppercase-calls-without-semicolon | |
preprocessor-convention-ignore-uppercase-ident-lines: | |
- match: ^(\s*{{macro_identifier}})+\s*$ | |
scope: meta.assumed-macro.c++ | |
push: | |
# It's possible that we are dealing with a function return type on its own line, and the | |
# name of the function is on the subsequent line. | |
- match: '(?={{path_lookahead}}({{generic_lookahead}}({{path_lookahead}})?)\s*\()' | |
set: [function-definition-params, global-function-identifier-generic] | |
- match: '(?={{path_lookahead}}\s*\()' | |
set: [function-definition-params, global-function-identifier] | |
- match: ^ | |
pop: true | |
preprocessor-other: | |
- match: ^\s*(#\s*(?:if|ifdef|ifndef|elif|else|line|pragma|undef))\b | |
captures: | |
1: keyword.control.import.c++ | |
push: | |
- meta_scope: meta.preprocessor.c++ | |
- include: scope:source.c#preprocessor-line-continuation | |
- include: scope:source.c#preprocessor-line-ending | |
- include: scope:source.c#preprocessor-comments | |
- match: \bdefined\b | |
scope: keyword.control.c++ | |
- match: ^\s*(#\s*endif)\b | |
captures: | |
1: meta.preprocessor.c++ keyword.control.import.c++ | |
- match: ^\s*(#\s*(?:error|warning))\b | |
captures: | |
1: keyword.control.import.error.c++ | |
push: | |
- meta_scope: meta.preprocessor.diagnostic.c++ | |
- include: scope:source.c#preprocessor-line-continuation | |
- include: scope:source.c#preprocessor-line-ending | |
- include: scope:source.c#preprocessor-comments | |
- include: strings | |
- match: '\S+' | |
scope: string.unquoted.c++ | |
- match: ^\s*(#\s*(?:include|include_next|import))\b | |
captures: | |
1: keyword.control.import.include.c++ | |
push: | |
- meta_scope: meta.preprocessor.include.c++ | |
- include: scope:source.c#preprocessor-line-continuation | |
- include: scope:source.c#preprocessor-line-ending | |
- include: scope:source.c#preprocessor-comments | |
- match: '"' | |
scope: punctuation.definition.string.begin.c++ | |
push: | |
- meta_scope: string.quoted.double.include.c++ | |
- match: '"' | |
scope: punctuation.definition.string.end.c++ | |
pop: true | |
- match: < | |
scope: punctuation.definition.string.begin.c++ | |
push: | |
- meta_scope: string.quoted.other.lt-gt.include.c++ | |
- match: '>' | |
scope: punctuation.definition.string.end.c++ | |
pop: true | |
- include: preprocessor-practical-workarounds |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment