mirror of
https://github.com/fmtlib/fmt.git
synced 2024-11-30 13:50:05 +00:00
2062 lines
71 KiB
Plaintext
2062 lines
71 KiB
Plaintext
|
%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
|