%YAML 1.2 --- # http://www.sublimetext.com/docs/3/syntax.html name: Objective-C++ file_extensions: - mm - M - h scope: source.objc++ 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' coroutine_keywords: co_(?:await|return|yield) control_keywords: 'break|case|catch|continue|default|do|else|for|goto|if|_Pragma|return|switch|throw|try|while|{{coroutine_keywords}}' 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: '[^(){}&;*^%=<>-]*' regular_plus: '[^(){}&;*^%=<>-]+' paren_open: (?:\( paren_close: '\))?' generic_open: (?:{{regular_plus}}(?:< generic_close: '>)?)?' balance_parentheses: '{{regular}}{{paren_open}}{{regular}}{{paren_close}}{{regular}}' generic_lookahead: <{{generic_open}}{{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' contexts: main: - include: preprocessor-global - include: global ## Common context layout global: - include: preprocessor-expressions - match: '(?=\btemplate\b)' push: - include: template - match: (?=\S) set: global-modifier - include: using-namespace - include: namespace - include: keywords-angle-brackets - match: '(?={{path_lookahead}}\s*<)' push: global-modifier - include: objc-structures # 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.objc++ push: - include: comments - include: strings - match: '\{' scope: punctuation.section.block.begin.objc++ set: - meta_scope: meta.extern-c.objc++ - match: '^\s*(#\s*ifdef)\s*__cplusplus\s*' scope: meta.preprocessor.objc++ captures: 1: keyword.control.import.objc++ set: - match: '\}' scope: punctuation.section.block.end.objc++ pop: true - include: preprocessor-global - include: global - match: '\}' scope: punctuation.section.block.end.objc++ 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: preprocessor-expressions - 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: comments - include: case-default - include: using-namespace - include: typedef - include: using-alias - 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: block - include: variables - include: constants - match: ',' scope: punctuation.separator.objc++ - match: '\)|\}' scope: invalid.illegal.stray-bracket-end.objc++ - include: bracketed-content - include: brackets 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: scope:source.c++#identifiers - match: ';' scope: punctuation.terminator.objc++ late-expressions: - include: late-expressions-before-function-call - include: function-call - include: scope:source.c++#identifiers - match: ';' scope: punctuation.terminator.objc++ late-expressions-before-function-call: - include: scope:source.c++#unique-late-expressions - include: modifiers-parens - include: modifiers - include: types expressions-minus-function-call: - include: early-expressions - include: late-expressions-before-function-call - include: scope:source.c++#identifiers - match: ';' scope: punctuation.terminator.objc++ comments: - include: scope:source.c#comments operators: - include: scope:source.c#operators modifiers: - include: scope:source.objc#unique-modifiers - include: scope:source.c++#unique-modifiers - include: scope:source.c#modifiers variables: - include: scope:source.objc#unique-variables - include: scope:source.c++#unique-variables - include: scope:source.c#variables constants: - include: scope:source.objc#unique-constants - match: '(?=\bNS\w+\b)' push: scope:source.objc#ns-identifiers - include: scope:source.c++#unique-constants - include: scope:source.c#constants keywords: - include: scope:source.objc#unique-keywords - include: scope:source.c++#unique-keywords - include: scope:source.c#keywords types: - include: scope:source.objc#unique-types - match: '(?=\bNS\w+\b)' push: scope:source.objc#ns-identifiers - include: scope:source.c++#unique-types - include: types-parens - include: scope:source.c#types strings: - include: scope:source.objc#unique-strings - include: scope:source.c++#unique-strings - include: scope:source.c#strings numbers: - include: scope:source.c++#numbers ########################################## # Directly from Objective-C.sublime-syntax ########################################## bracketed-content: - match: '(\[)\s*(?={{identifier}}\s+[^\s,])' captures: 1: punctuation.section.scope.begin.objc++ push: - meta_scope: meta.bracketed.objc++ - match: '\]' scope: punctuation.section.scope.end.objc++ pop: true - match: \s*(NSPredicate)\s+(predicateWithFormat(:)) captures: 1: support.class.cocoa.objc++ 2: support.function.any-method.objc++ 3: punctuation.separator.arguments.objc++ push: - meta_scope: meta.function-call.predicate.objc++ - include: scope:source.objc#ns-predicate - include: expressions - match: '\s+(\w+)(?=\s*\])' captures: 1: support.function.any-method.objc++ - match: '\s+(\w+(:))' captures: 1: support.function.any-method.objc++ 2: punctuation.separator.arguments.objc++ push: - meta_scope: meta.function-call.objc++ - match: '(?=\])' pop: true - match: \b\w+(:) scope: support.function.any-method.name-of-parameter.objc++ captures: 1: punctuation.separator.arguments.objc++ - include: expressions - include: expressions objc-structures: - match: '((@)(interface|protocol))(?!.+;)\s+([[:alpha:]_][[:alnum:]_]*)\s*((:)(?:\s*)([[:alpha:]][[:alnum:]]*))?(\s|\n)?' captures: 1: storage.type.objc++ 2: punctuation.definition.storage.type.objc++ 4: entity.name.type.objc++ 6: punctuation.definition.entity.other.inherited-class.objc++ 7: entity.other.inherited-class.objc++ 8: meta.divider.objc++ 9: meta.inherited-class.objc++ push: - meta_scope: meta.interface-or-protocol.objc++ - meta_content_scope: meta.scope.interface.objc++ - match: ((@)end)\b captures: 1: storage.type.objc++ 2: punctuation.definition.storage.type.objc++ pop: true - include: preprocessor-objc-structures - include: objc-structure-body - match: '((@)(implementation))\s+([[:alpha:]_][[:alnum:]_]*)\s*(?::\s*([[:alpha:]][[:alnum:]]*))?' captures: 1: storage.type.objc++ 2: punctuation.definition.storage.type.objc++ 4: entity.name.type.objc++ 5: entity.other.inherited-class.objc++ push: - meta_scope: meta.implementation.objc++ - meta_content_scope: meta.scope.implementation.objc++ - match: ((@)end)\b captures: 1: storage.type.objc++ 2: punctuation.definition.storage.type.objc++ pop: true - include: preprocessor-objc-structures - include: objc-structure-body objc-structure-body: - include: scope:source.objc#properties - include: scope:source.objc#protocol_list - include: method - include: expressions method: - match: ^(-|\+)\s* push: - meta_scope: meta.function.objc++ - match: '\{' scope: punctuation.section.block.begin.objc++ set: - meta_scope: meta.block.objc++ - match: (?=^\s*#\s*(elif|else|endif)\b) pop: true - match: (?=@end\b) pop: true - match: '\}' scope: punctuation.section.block.end.objc++ pop: true - include: statements - match: '(?=#|@end|;)' pop: true - match: '\(' scope: meta.return-type.objc++ punctuation.definition.type.objc++ push: - meta_scope: meta.return-type.objc++ - match: (\))\s*(\w+\b) captures: 1: punctuation.definition.type.objc++ 2: entity.name.function.objc++ pop: true - include: scope:source.objc#protocol_list - include: scope:source.objc#protocol_type_qualifier - include: expressions - match: \b\w+(?=:) scope: entity.name.function.name-of-parameter.objc++ - match: ((:))\s*(\() captures: 1: entity.name.function.name-of-parameter.objc++ 2: punctuation.separator.arguments.objc++ 3: punctuation.definition.type.objc++ push: - meta_scope: meta.argument-type.objc++ - match: (\))\s*(\w+\b)? captures: 1: punctuation.definition.type.objc++ 2: variable.parameter.function.objc++ pop: true - include: scope:source.objc#protocol_list - include: scope:source.objc#protocol_type_qualifier - include: expressions - include: comments - match: '(,)\s+(\.\.\.)\s*' captures: 1: punctuation.separator.objc++ 2: keyword.operator.variadic.objc++ push: - include: scope:source.c#function-call - match: '(?=\S)' pop: true ## Preprocessor for objc-structures preprocessor-objc-structures: - include: preprocessor-rule-enabled-objc-structures - include: preprocessor-rule-disabled-objc-structures preprocessor-rule-disabled-objc-structures: - match: ^\s*((#if)\s+(0))\b captures: 1: meta.preprocessor.objc++ 2: keyword.control.import.objc++ 3: constant.numeric.integer.decimal.objc++ push: - match: ^\s*(#\s*endif)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.objc++ pop: true - match: ^\s*(#\s*else)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.else.objc++ push: - match: (?=^\s*#\s*endif\b) pop: true - include: negated-block - include: objc-structure-body - match: "" push: - meta_scope: comment.block.preprocessor.if-branch.objc++ - match: (?=^\s*#\s*(else|endif)\b) pop: true - include: scope:source.c#preprocessor-disabled preprocessor-rule-enabled-objc-structures: - match: ^\s*((#if)\s+(0*1))\b captures: 1: meta.preprocessor.objc++ 2: keyword.control.import.objc++ 3: constant.numeric.integer.decimal.objc++ push: - match: ^\s*(#\s*endif)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.objc++ pop: true - match: ^\s*(#\s*else)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.else.objc++ push: - meta_content_scope: comment.block.preprocessor.else-branch.objc++ - 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: objc-structure-body ################################## # Directly from C++.sublime-syntax ################################## case-default: - match: '\b(default|case)\b' scope: keyword.control.objc++ push: - match: (?=[);,]) pop: true - match: ':' scope: punctuation.separator.objc++ pop: true - include: expressions modifiers-parens: - match: '\b(alignas)\b\s*(\()' captures: 1: storage.modifier.objc++ 2: meta.group.objc++ punctuation.section.group.begin.objc++ push: - meta_content_scope: meta.group.objc++ - match: '\)' scope: meta.group.objc++ punctuation.section.group.end.objc++ pop: true - include: expressions - match: \b(__attribute__)\s*(\(\() captures: 1: storage.modifier.objc++ 2: meta.group.objc++ punctuation.section.group.begin.objc++ push : - meta_scope: meta.attribute.objc++ - meta_content_scope: meta.group.objc++ - include: parens - include: strings - match: \)\) scope: meta.group.objc++ punctuation.section.group.end.objc++ pop: true - match: \b(__declspec)(\() captures: 1: storage.modifier.objc++ 2: meta.group.objc++ punctuation.section.group.begin.objc++ push: - meta_content_scope: meta.group.objc++ - match: '\)' scope: meta.group.objc++ punctuation.section.group.end.objc++ pop: true - match: '\b(align|allocate|code_seg|deprecated|property|uuid)\b\s*(\()' captures: 1: storage.modifier.objc++ 2: meta.group.objc++ punctuation.section.group.begin.objc++ push: - meta_content_scope: meta.group.objc++ - match: '\)' scope: meta.group.objc++ punctuation.section.group.end.objc++ pop: true - include: numbers - include: strings - match: \b(get|put)\b scope: variable.parameter.objc++ - match: ',' scope: punctuation.separator.objc++ - match: '=' scope: keyword.operator.assignment.objc++ - match: '\b(appdomain|deprecated|dllimport|dllexport|jintrinsic|naked|noalias|noinline|noreturn|nothrow|novtable|process|restrict|safebuffers|selectany|thread)\b' scope: constant.other.objc++ types-parens: - match: '\b(decltype)\b\s*(\()' captures: 1: storage.type.objc++ 2: meta.group.objc++ punctuation.section.group.begin.objc++ push: - meta_content_scope: meta.group.objc++ - match: '\)' scope: meta.group.objc++ punctuation.section.group.end.objc++ pop: true - include: expressions keywords-angle-brackets: - match: \b({{casts}})\b\s* scope: keyword.operator.word.cast.objc++ push: - match: '>' scope: punctuation.section.generic.end.objc++ pop: true - match: '<' scope: punctuation.section.generic.begin.objc++ 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.objc++ 2: meta.group.objc++ punctuation.section.group.begin.objc++ push: - meta_content_scope: meta.group.objc++ - match: '\)' scope: meta.group.objc++ punctuation.section.group.end.objc++ pop: true - include: expressions using-namespace: - match: '\b(using)\s+(namespace)\b' captures: 1: keyword.control.objc++ 2: keyword.control.objc++ push: - include: scope:source.c++#identifiers - match: '' pop: true namespace: - match: '\b(namespace)\s+(?=({{path_lookahead}})?(?!\s*[;,]))' scope: meta.namespace.objc++ captures: 1: keyword.control.objc++ push: - meta_content_scope: meta.namespace.objc++ entity.name.namespace.objc++ - include: scope:source.c++#identifiers - match: '' set: - meta_scope: meta.namespace.objc++ - include: comments - match: '=' scope: keyword.operator.alias.objc++ - match: '(?=;)' pop: true - match: '\}' scope: meta.block.objc++ punctuation.section.block.end.objc++ pop: true - match: '\{' scope: punctuation.section.block.begin.objc++ push: - meta_scope: meta.block.objc++ - 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.objc++ push: - meta_scope: meta.template.objc++ # 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.objc++ set: - meta_content_scope: meta.template.objc++ - match: '>' scope: meta.template.objc++ punctuation.section.generic.end.objc++ pop: true - match: \.{3} scope: keyword.operator.variadic.objc++ - match: \b(typename|{{before_tag}})\b scope: storage.type.objc++ - include: template # include template here for nested templates - include: template-common - match: (?=\S) set: - meta_content_scope: meta.template.objc++ - match: \b({{before_tag}})\b scope: storage.type.objc++ - include: template-common generic-type: - match: '(?=(?!template){{path_lookahead}}\s*{{generic_lookahead}}\s*(\(|\{))' push: - meta_scope: meta.function-call.objc++ - match: \btemplate\b scope: storage.type.template.objc++ - match: (?:(::)\s*)?({{identifier}})\s*(<) captures: 1: punctuation.accessor.double-colon.objc++ 2: variable.function.objc++ 3: punctuation.section.generic.begin.objc++ push: - match: '>' scope: punctuation.section.generic.end.objc++ pop: true - include: expressions-minus-generic-type-function-call - match: (?:(::)\s*)?({{identifier}})\s*(\() captures: 1: punctuation.accessor.double-colon.objc++ 2: variable.function.objc++ 3: punctuation.section.group.begin.objc++ set: - meta_scope: meta.function-call.objc++ - meta_content_scope: meta.group.objc++ - match: '\)' scope: meta.group.objc++ punctuation.section.group.end.objc++ pop: true - include: expressions - match: (?:(::)\s*)?({{identifier}})\s*(\{) captures: 1: punctuation.accessor.double-colon.objc++ 2: variable.function.objc++ 3: punctuation.section.group.begin.objc++ set: - meta_scope: meta.function-call.objc++ - meta_content_scope: meta.group.objc++ - match: '\}' scope: meta.group.objc++ punctuation.section.group.end.objc++ pop: true - include: expressions - include: scope:source.c++#identifiers - include: angle-brackets - match: '\(' scope: meta.group.objc++ punctuation.section.group.begin.objc++ set: - meta_scope: meta.function-call.objc++ - meta_content_scope: meta.group.objc++ - match: '\)' scope: meta.group.objc++ punctuation.section.group.end.objc++ pop: true - include: expressions - match: '\{' scope: meta.group.objc++ punctuation.section.group.begin.objc++ set: - meta_scope: meta.function-call.objc++ - meta_content_scope: meta.group.objc++ - match: '\}' scope: meta.group.objc++ punctuation.section.group.end.objc++ pop: true - include: expressions - match: '(?=(?!template){{path_lookahead}}\s*{{generic_lookahead}})' push: - include: scope:source.c++#identifiers - match: '<' scope: punctuation.section.generic.begin.objc++ set: - match: '>' scope: punctuation.section.generic.end.objc++ pop: true - include: expressions-minus-generic-type-function-call angle-brackets: - match: '<(?!<)' scope: punctuation.section.generic.begin.objc++ push: - match: '>' scope: punctuation.section.generic.end.objc++ pop: true - include: expressions-minus-generic-type-function-call block: - match: '\{' scope: punctuation.section.block.begin.objc++ push: - meta_scope: meta.block.objc++ - match: (?=^\s*#\s*(elif|else|endif)\b) pop: true - match: '\}' scope: punctuation.section.block.end.objc++ pop: true - include: statements function-call: - match: (?={{path_lookahead}}\s*(\(|\{)) push: - meta_scope: meta.function-call.objc++ - include: scope:source.c#c99 - match: '(?:(::)\s*)?{{identifier}}\s*(::)\s*' captures: 1: punctuation.accessor.double-colon.objc++ 2: punctuation.accessor.double-colon.objc++ - match: '(?:(::)\s*)?({{identifier}})' captures: 1: punctuation.accessor.double-colon.objc++ 2: variable.function.objc++ - match: '\(' scope: meta.group.objc++ punctuation.section.group.begin.objc++ set: - meta_scope: meta.function-call.objc++ - meta_content_scope: meta.group.objc++ - match: '\)' scope: meta.group.objc++ punctuation.section.group.end.objc++ pop: true - include: expressions - match: '\{' scope: meta.group.objc++ punctuation.section.group.begin.objc++ set: - meta_content_scope: meta.function-call.objc++ meta.group.objc++ - match: '\}' scope: meta.function-call.objc++ meta.group.objc++ punctuation.section.group.end.objc++ pop: true - include: expressions members-inside-function-call: - meta_content_scope: meta.method-call.objc++ meta.group.objc++ - match: \) scope: meta.method-call.objc++ meta.group.objc++ punctuation.section.group.end.objc++ 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.objc++ storage.type.template.objc++ # Guaranteed to be a template member function call after we match this set: - meta_content_scope: meta.method-call.objc++ - include: comments - match: '{{identifier}}' scope: variable.function.member.objc++ set: - meta_content_scope: meta.method-call.objc++ - match: \( scope: meta.group.objc++ punctuation.section.group.begin.objc++ set: members-inside-function-call - include: comments - include: angle-brackets - match: (?=\S) # safety pop pop: true - match: (?=\S) # safety pop pop: true # Non-templated member function call - match: (~?{{identifier}})\s*(\() captures: 0: meta.method-call.objc++ 1: variable.function.member.objc++ 2: meta.group.objc++ punctuation.section.group.begin.objc++ set: members-inside-function-call # Templated member function call - match: (~?{{identifier}})\s*(?={{generic_lookahead}}) captures: 1: variable.function.member.objc++ set: - meta_scope: meta.method-call.objc++ - match: < scope: punctuation.section.generic.begin.objc++ set: - meta_content_scope: meta.method-call.objc++ - match: '>' scope: punctuation.section.generic.end.objc++ set: - meta_content_scope: meta.method-call.objc++ - include: comments - match: \( scope: punctuation.section.group.begin.objc++ 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.objc++ 2: punctuation.accessor.double-colon.objc++ set: members-after-accessor-junction # reset # Just a regular member variable - match: '{{identifier}}' scope: variable.other.readwrite.member.objc++ 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.objc++ 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.objc++ push: members-after-accessor-junction using-alias: # consume keyword if followed by typename - match: '\b(using)\b(?=\s+typename\b)' captures: 1: keyword.control.objc++ - match: '\b(using)\b\s+({{identifier}})(?!\s*(<|::))' captures: 1: keyword.control.objc++ 2: entity.name.type.using.objc++ typedef: - match: \btypedef\b scope: storage.type.objc++ push: - match: ({{identifier}})?\s*(?=;) captures: 1: entity.name.type.typedef.objc++ pop: true - match: \b(struct)\s+({{identifier}})\b captures: 1: storage.type.objc++ - include: expressions-minus-generic-type parens: - match: \( scope: punctuation.section.group.begin.objc++ push: - meta_scope: meta.group.objc++ - match: \) scope: punctuation.section.group.end.objc++ pop: true - include: expressions brackets: - match: \[ scope: punctuation.section.brackets.begin.objc++ push: - meta_scope: meta.brackets.objc++ - match: \] scope: punctuation.section.brackets.end.objc++ 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: scope:source.c++#identifiers - match: \*|& scope: keyword.operator.objc++ - include: function-trailing-return-type-parens - match: '(?=\S)' pop: true function-trailing-return-type-parens: - match: \( scope: meta.group.objc++ punctuation.section.group.begin.objc++ push: - meta_scope: meta.group.objc++ - match: \) scope: punctuation.section.group.end.objc++ 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*(?:{{generic_lookahead}})?\s*::\s*{{identifier}}\s*\()' set: - meta_content_scope: meta.function.objc++ meta.toc-list.full-identifier.objc++ - include: scope:source.c++#identifier-path-generic - match: '(?:(::)\s*)?({{identifier}})' captures: 1: punctuation.accessor.double-colon.objc++ 2: entity.name.function.constructor.objc++ - match: '(?=[^\w\s])' set: function-definition-params - match: '(?={{path_lookahead}}\s*(?:{{generic_lookahead}})?\s*::\s*~{{identifier}}\s*(\(|$))' set: - meta_content_scope: meta.function.objc++ meta.toc-list.full-identifier.objc++ - include: scope:source.c++#identifier-path-generic - match: '(?:(::)\s*)?(~{{identifier}})' captures: 1: punctuation.accessor.double-colon.objc++ 2: entity.name.function.destructor.objc++ - 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*(?:{{generic_lookahead}})?::\s*$)' set: - meta_content_scope: meta.function.objc++ meta.toc-list.full-identifier.objc++ - include: scope:source.c++#identifier-path-generic - match: '(::)\s*$' captures: 1: punctuation.accessor.double-colon.objc++ - match: '(?:(::)\s*)?(~?{{identifier}})(?=\s*\()' captures: 1: punctuation.accessor.double-colon.objc++ 2: entity.name.function.objc++ - match: '(?=[^\w\s])' set: function-definition-params - include: scope:source.c++#unique-strings - match: '(?=\S)' set: global-type global-type: - include: comments - match: \*|& scope: keyword.operator.objc++ - 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.objc++ set: - include: scope:source.c++#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.objc++ 2: meta.group.objc++ punctuation.section.group.begin.objc++ push: - meta_scope: meta.function-call.objc++ - meta_content_scope: meta.group.objc++ - match: '\)' scope: meta.group.objc++ punctuation.section.group.end.objc++ pop: true - include: expressions - match: '(?={{path_lookahead}}\s*\()' set: - include: function-call - match: '' pop: true - include: variables - include: constants - include: scope:source.c++#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.objc++ - match: '(?=\b({{control_keywords}}|{{operator_keywords}}|{{casts}}|{{memory_operators}}|{{other_keywords}})\b)' pop: true - match: '\b({{type_qualifier}})\b' scope: storage.modifier.objc++ - 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.objc++ meta.toc-list.full-identifier.objc++ - include: scope:source.c++#identifier-path-generic - match: '(?:(::)\s*)?({{operator_method_name}})(?=\s*\()' captures: 1: punctuation.accessor.double-colon.objc++ 2: entity.name.function.objc++ - 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: scope:source.c++#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: - meta_content_scope: meta.toc-list.full-identifier.objc++ - include: scope:source.c++#identifier-path-generic - match: '(?:(::)\s*)?({{identifier}})(?=\s*(<.*>)?\s*\()' captures: 1: punctuation.accessor.double-colon.objc++ 2: entity.name.function.objc++ - match: '(?=\()' pop: true global-function-identifier: - meta_content_scope: meta.toc-list.full-identifier.objc++ - match: '(?:(::)\s*)?({{identifier}})(?!\s*(::))' captures: 1: punctuation.accessor.double-colon.c++ 2: entity.name.function.c++ - include: scope:source.c++#identifiers - match: '(?=\S)' pop: true function-definition-params: - meta_content_scope: meta.function.objc++ - include: comments - match: '(?=\()' set: - match: \( scope: meta.function.parameters.objc++ meta.group.objc++ punctuation.section.group.begin.objc++ set: - meta_content_scope: meta.function.parameters.objc++ meta.group.objc++ - match : \) scope: punctuation.section.group.end.objc++ set: function-definition-continue - match: '\bvoid\b' scope: storage.type.objc++ - match: '{{identifier}}(?=\s*(\[|,|\)|=))' scope: variable.parameter.objc++ - match: '=' scope: keyword.operator.assignment.objc++ 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.objc++ - include: comments - match: '(?=;)' pop: true - match: '->' scope: punctuation.separator.objc++ set: function-definition-trailing-return - include: scope:source.c++#function-specifiers - match: '=' scope: keyword.operator.assignment.objc++ - match: '&' scope: keyword.operator.objc++ - match: \b0\b scope: constant.numeric.integer.decimal.objc++ - match: \b(default|delete)\b scope: storage.modifier.objc++ - match: '(?=\{)' set: function-definition-body - match: '(?=\S)' pop: true function-definition-trailing-return: - include: comments - match: '(?=;)' pop: true - match: '(?=\{)' set: function-definition-body - include: scope:source.c++#function-specifiers - include: function-trailing-return-type function-definition-body: - meta_content_scope: meta.function.objc++ meta.block.objc++ - match: '\{' scope: punctuation.section.block.begin.objc++ set: - meta_content_scope: meta.function.objc++ meta.block.objc++ - match: '\}' scope: meta.function.objc++ meta.block.objc++ punctuation.section.block.end.objc++ 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.objc++ 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.objc++ - match: '\bstruct\b' scope: storage.type.objc++ set: data-structures-struct-definition - match: '\benum(\s+(class|struct))?\b' scope: storage.type.objc++ set: data-structures-enum-definition - match: '\bunion\b' scope: storage.type.objc++ 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.objc++ - include: data-structures-definition-common-begin - match: '{{identifier}}(?={{data_structures_forward_decl_lookahead}})' scope: entity.name.class.forward-decl.objc++ set: data-structures-class-definition-after-identifier - match: '(?={{path_lookahead}})' set: - meta_scope: meta.class.objc++ - match: '{{identifier}}(?!\s*::)' scope: entity.name.class.objc++ set: data-structures-class-definition-after-identifier - include: scope:source.c++#identifiers - match: data-structures-class-definition-after-identifier - match: '(?=[^\w\s])' 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.objc++ - 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.objc++ punctuation.section.block.begin.objc++ set: - meta_content_scope: meta.class.objc++ meta.block.objc++ - match: '\}' scope: meta.class.objc++ meta.block.objc++ punctuation.section.block.end.objc++ pop: true - include: data-structures-body data-structures-struct-definition: - meta_scope: meta.struct.objc++ - include: data-structures-definition-common-begin - match: '{{identifier}}(?={{data_structures_forward_decl_lookahead}})' scope: entity.name.struct.forward-decl.objc++ set: data-structures-struct-definition-after-identifier - match: '(?={{path_lookahead}})' set: - meta_scope: meta.struct.objc++ - match: '{{identifier}}(?!\s*::)' scope: entity.name.struct.objc++ set: data-structures-struct-definition-after-identifier - include: scope:source.c++#identifiers - match: data-structures-struct-definition-after-identifier - match: '(?=[^\w\s])' 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.objc++ - 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.objc++ punctuation.section.block.begin.objc++ set: - meta_content_scope: meta.struct.objc++ meta.block.objc++ - match: '\}' scope: meta.struct.objc++ meta.block.objc++ punctuation.section.block.end.objc++ pop: true - include: data-structures-body data-structures-enum-definition: - meta_scope: meta.enum.objc++ - include: data-structures-definition-common-begin - match: '{{identifier}}(?={{data_structures_forward_decl_lookahead}})' scope: entity.name.enum.forward-decl.objc++ set: data-structures-enum-definition-after-identifier - match: '(?={{path_lookahead}})' set: - meta_scope: meta.enum.objc++ - match: '{{identifier}}(?!\s*::)' scope: entity.name.enum.objc++ set: data-structures-enum-definition-after-identifier - include: scope:source.c++#identifiers - match: data-structures-enum-definition-after-identifier - match: '(?=[^\w\s])' 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.objc++ - 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.objc++ punctuation.section.block.begin.objc++ set: - meta_content_scope: meta.enum.objc++ meta.block.objc++ # Enums don't support methods so we have a simplified body - match: '\}' scope: meta.enum.objc++ meta.block.objc++ punctuation.section.block.end.objc++ pop: true - include: statements data-structures-union-definition: - meta_scope: meta.union.objc++ - include: data-structures-definition-common-begin - match: '{{identifier}}(?={{data_structures_forward_decl_lookahead}})' scope: entity.name.union.forward-decl.objc++ set: data-structures-union-definition-after-identifier - match: '(?={{path_lookahead}})' set: - meta_scope: meta.union.objc++ - match: '{{identifier}}(?!\s*::)' scope: entity.name.union.objc++ set: data-structures-union-definition-after-identifier - include: scope:source.c++#identifiers - match: data-structures-union-definition-after-identifier - match: '(?=[^\w\s])' 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.objc++ - 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.objc++ punctuation.section.block.begin.objc++ set: - meta_content_scope: meta.union.objc++ meta.block.objc++ - match: '\}' scope: meta.union.objc++ meta.block.objc++ punctuation.section.block.end.objc++ 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: scope:source.c++#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.objc++ push: - include: comments - include: preprocessor-other - include: modifiers-parens - include: modifiers - match: '\b(virtual|{{visibility_modifiers}})\b' scope: storage.modifier.objc++ - match: (?={{path_lookahead}}) push: - meta_scope: entity.other.inherited-class.objc++ - include: scope:source.c++#identifiers - match: '' pop: true - include: angle-brackets - match: ',' scope: punctuation.separator.objc++ - 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.objc++ 2: punctuation.section.class.objc++ - match: '^\s*(?=(?:~?\w+|::))' push: data-structures-modifier - include: preprocessor-expressions - include: expressions-minus-generic-type data-structures-modifier-friend: - match: (?=;) pop: true - match: '\{' scope: punctuation.section.block.begin.objc++ set: - meta_scope: meta.block.objc++ - match: '\}' scope: punctuation.section.block.end.objc++ pop: true - include: statements - include: expressions-minus-function-call data-structures-modifier: - match: '\bfriend\b' scope: storage.modifier.objc++ push: - include: comments - match: '\b({{before_tag}})\b' scope: storage.type.objc++ set: data-structures-modifier-friend - match: '(?=\S)(?=[^;]+;)' set: data-structures-modifier-friend - match: '(?=\S)' pop: true - include: comments - include: modifiers-parens - include: modifiers - match: '\bstatic_assert(?=\s*\()' scope: meta.static-assert.objc++ keyword.operator.word.objc++ push: - match: '\(' scope: meta.group.objc++ punctuation.section.group.begin.objc++ set: - meta_content_scope: meta.function-call.objc++ meta.group.objc++ - match: '\)' scope: meta.function-call.objc++ meta.group.objc++ punctuation.section.group.end.objc++ pop: true - include: expressions # Destructor - match: '(?:{{identifier}}\s*(::)\s*)?~{{identifier}}(?=\s*(\(|$))' scope: meta.method.destructor.objc++ entity.name.function.destructor.objc++ captures: 1: punctuation.accessor.objc++ 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.objc++ 2: meta.group.objc++ punctuation.section.group.begin.objc++ push: - meta_scope: meta.function-call.objc++ - meta_content_scope: meta.group.objc++ - match: '\)' scope: meta.group.objc++ punctuation.section.group.end.objc++ pop: true - include: expressions # Constructor - include: scope:source.c++#preprocessor-workaround-eat-macro-before-identifier - match: '((?!{{before_tag}}|template){{identifier}})(?=\s*\()' scope: meta.method.constructor.objc++ entity.name.function.constructor.objc++ set: method-definition-params # Long form constructor - match: '({{identifier}}\s*(::)\s*{{identifier}})(?=\s*\()' captures: 1: meta.method.constructor.objc++ entity.name.function.constructor.objc++ 2: punctuation.accessor.objc++ push: method-definition-params - match: '(?=\S)' set: data-structures-type data-structures-type: - include: comments - match: \*|& scope: keyword.operator.objc++ # Cast methods - match: '(operator)\s+({{identifier}})(?=\s*(\(|$))' captures: 1: keyword.control.objc++ 2: meta.method.objc++ entity.name.function.objc++ 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.objc++ set: - include: scope:source.c++#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: scope:source.c++#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.objc++ - match: '(?=\b({{control_keywords}}|{{operator_keywords}}|{{casts}}|{{memory_operators}}|{{other_keywords}})\b)' pop: true - match: '\b({{type_qualifier}})\b' scope: storage.modifier.objc++ - 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.objc++ entity.name.function.objc++ set: method-definition-params # Identifier that is not the function name - likely a macro or type - match: '(?={{path_lookahead}}([ \t]+|[*&])(?!\s*(<|::|\()))' push: - include: scope:source.c++#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.objc++ - include: scope:source.c++#identifiers - match: '(?=<)' pop: true - match: '(?=\()' pop: true data-structures-function-identifier: - meta_content_scope: entity.name.function.objc++ - include: scope:source.c++#identifiers - match: '(?=\S)' pop: true method-definition-params: - meta_content_scope: meta.method.objc++ - include: comments - match: '(?=\()' set: - match: \( scope: meta.method.parameters.objc++ meta.group.objc++ punctuation.section.group.begin.objc++ set: - meta_content_scope: meta.method.parameters.objc++ meta.group.objc++ - match : \) scope: punctuation.section.group.end.objc++ set: method-definition-continue - match: '\bvoid\b' scope: storage.type.objc++ - match: '{{identifier}}(?=\s*(\[|,|\)|=))' scope: variable.parameter.objc++ - match: '=' scope: keyword.operator.assignment.objc++ 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.objc++ - include: comments - match: '(?=;)' pop: true - match: '->' scope: punctuation.separator.objc++ set: method-definition-trailing-return - include: scope:source.c++#function-specifiers - match: '=' scope: keyword.operator.assignment.objc++ - match: '&' scope: keyword.operator.objc++ - match: \b0\b scope: constant.numeric.integer.decimal.objc++ - match: \b(default|delete)\b scope: storage.modifier.objc++ - match: '(?=:)' set: - match: ':' scope: punctuation.separator.initializer-list.objc++ set: - meta_scope: meta.method.constructor.initializer-list.objc++ - match: '{{identifier}}' scope: variable.other.readwrite.member.objc++ push: - match: \( scope: meta.group.objc++ punctuation.section.group.begin.objc++ set: - meta_content_scope: meta.group.objc++ - match: \) scope: meta.group.objc++ punctuation.section.group.end.objc++ pop: true - include: expressions - match: \{ scope: meta.group.objc++ punctuation.section.group.begin.objc++ set: - meta_content_scope: meta.group.objc++ - match: \} scope: meta.group.objc++ punctuation.section.group.end.objc++ 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: scope:source.c++#function-specifiers - include: function-trailing-return-type method-definition-body: - meta_content_scope: meta.method.objc++ meta.block.objc++ - match: '\{' scope: punctuation.section.block.begin.objc++ set: - meta_content_scope: meta.method.objc++ meta.block.objc++ - match: '\}' scope: meta.method.objc++ meta.block.objc++ punctuation.section.block.end.objc++ 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: scope:source.c++#preprocessor-practical-workarounds preprocessor-rule-disabled-data-structures: - match: ^\s*((#if)\s+(0))\b captures: 1: meta.preprocessor.objc++ 2: keyword.control.import.objc++ 3: constant.numeric.integer.decimal.objc++ push: - match: ^\s*(#\s*endif)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.objc++ pop: true - match: ^\s*(#\s*else)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.else.objc++ push: - match: (?=^\s*#\s*endif\b) pop: true - include: negated-block - include: data-structures-body - match: "" push: - meta_scope: comment.block.preprocessor.if-branch.objc++ - 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.objc++ 2: keyword.control.import.objc++ 3: constant.numeric.integer.decimal.objc++ push: - match: ^\s*(#\s*endif)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.objc++ pop: true - match: ^\s*(#\s*else)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.else.objc++ push: - meta_content_scope: comment.block.preprocessor.else-branch.objc++ - 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.objc++ 2: keyword.control.import.objc++ 3: constant.numeric.integer.decimal.objc++ push: - match: ^\s*(#\s*endif)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.objc++ pop: true - match: ^\s*(#\s*else)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.else.objc++ 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.objc++ - 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.objc++ 2: keyword.control.import.objc++ 3: constant.numeric.integer.decimal.objc++ push: - match: ^\s*(#\s*endif)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.objc++ pop: true - match: ^\s*(#\s*else)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.else.objc++ push: - meta_content_scope: comment.block.preprocessor.else-branch.objc++ - 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.objc++ push: - meta_scope: meta.preprocessor.objc++ - include: scope:source.c#preprocessor-line-continuation - include: scope:source.c#preprocessor-comments - match: \bdefined\b scope: keyword.control.objc++ # 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.objc++ keyword.control.import.objc++ pop: true - match: (?=^\s*#\s*(elif|else)\b) push: preprocessor-elif-else-branch-global - match: \{ scope: punctuation.section.block.begin.objc++ set: preprocessor-block-if-branch-global - include: preprocessor-global - include: negated-block - include: global preprocessor-block-if-branch-global: - meta_scope: meta.block.objc++ - match: ^\s*(#\s*endif)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.objc++ set: preprocessor-block-finish-global - match: (?=^\s*#\s*(elif|else)\b) push: preprocessor-elif-else-branch-global - match: \} scope: punctuation.section.block.end.objc++ set: preprocessor-if-branch-global - include: statements preprocessor-block-finish-global: - meta_scope: meta.block.objc++ - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b captures: 1: meta.preprocessor.objc++ keyword.control.import.objc++ set: preprocessor-block-finish-if-branch-global - match: \} scope: punctuation.section.block.end.objc++ pop: true - include: statements preprocessor-block-finish-if-branch-global: - match: ^\s*(#\s*endif)\b captures: 1: keyword.control.import.objc++ pop: true - match: \} scope: punctuation.section.block.end.objc++ 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.objc++ 2: keyword.control.import.objc++ 3: constant.numeric.integer.decimal.objc++ push: - match: ^\s*(#\s*endif)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.objc++ pop: true - match: ^\s*(#\s*else)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.else.objc++ push: - match: (?=^\s*#\s*endif\b) pop: true - include: negated-block - include: statements - match: "" push: - meta_scope: comment.block.preprocessor.if-branch.objc++ - 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.objc++ 2: keyword.control.import.objc++ 3: constant.numeric.integer.decimal.objc++ push: - match: ^\s*(#\s*endif)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.objc++ pop: true - match: ^\s*(#\s*else)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.else.objc++ push: - meta_content_scope: comment.block.preprocessor.else-branch.objc++ - 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.objc++ push: - meta_scope: meta.preprocessor.objc++ - include: scope:source.c#preprocessor-line-continuation - include: scope:source.c#preprocessor-comments - match: \bdefined\b scope: keyword.control.objc++ # 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.objc++ keyword.control.import.objc++ pop: true - match: (?=^\s*#\s*(elif|else)\b) push: preprocessor-elif-else-branch-statements - match: \{ scope: punctuation.section.block.begin.objc++ 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.objc++ - include: scope:source.c#c99 - match: '(?:(::)\s*)?{{identifier}}\s*(::)\s*' scope: variable.function.objc++ captures: 1: punctuation.accessor.objc++ 2: punctuation.accessor.objc++ - match: '(?:(::)\s*)?{{identifier}}' scope: variable.function.objc++ captures: 1: punctuation.accessor.objc++ - match: '\(' scope: meta.group.objc++ punctuation.section.group.begin.objc++ set: preprocessor-if-branch-function-call-arguments preprocessor-if-branch-function-call-arguments: - meta_content_scope: meta.function-call.objc++ meta.group.objc++ - match : \) scope: meta.function-call.objc++ meta.group.objc++ punctuation.section.group.end.objc++ set: preprocessor-if-branch-statements - match: ^\s*(#\s*(?:elif|else))\b captures: 1: meta.preprocessor.objc++ keyword.control.import.objc++ set: preprocessor-if-branch-statements - match: ^\s*(#\s*endif)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.objc++ set: preprocessor-if-branch-function-call-arguments-finish - include: expressions preprocessor-if-branch-function-call-arguments-finish: - meta_content_scope: meta.function-call.objc++ meta.group.objc++ - match: \) scope: meta.function-call.objc++ meta.group.objc++ punctuation.section.group.end.objc++ pop: true - include: expressions preprocessor-block-if-branch-statements: - meta_scope: meta.block.objc++ - match: ^\s*(#\s*endif)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.objc++ set: preprocessor-block-finish-statements - match: (?=^\s*#\s*(elif|else)\b) push: preprocessor-elif-else-branch-statements - match: \} scope: punctuation.section.block.end.objc++ set: preprocessor-if-branch-statements - include: statements preprocessor-block-finish-statements: - meta_scope: meta.block.objc++ - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b captures: 1: meta.preprocessor.objc++ keyword.control.import.objc++ set: preprocessor-block-finish-if-branch-statements - match: \} scope: punctuation.section.block.end.objc++ pop: true - include: statements preprocessor-block-finish-if-branch-statements: - match: ^\s*(#\s*endif)\b captures: 1: keyword.control.import.objc++ pop: true - match: \} scope: meta.block.objc++ punctuation.section.block.end.objc++ 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.objc++ push: - match: '\{' scope: punctuation.section.block.begin.objc++ 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.objc++ keyword.control.import.define.objc++ push: - meta_content_scope: meta.preprocessor.macro.objc++ - 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.objc++ set: - match: '\(' scope: punctuation.section.group.begin.objc++ set: preprocessor-macro-params - match: '{{identifier}}' scope: entity.name.constant.preprocessor.objc++ set: preprocessor-macro-definition preprocessor-macro-params: - meta_scope: meta.preprocessor.macro.parameters.objc++ meta.group.objc++ - match: '{{identifier}}' scope: variable.parameter.objc++ - match: \) scope: punctuation.section.group.end.objc++ set: preprocessor-macro-definition - match: ',' scope: punctuation.separator.objc++ push: - match: '{{identifier}}' scope: variable.parameter.objc++ pop: true - include: scope:source.c#preprocessor-line-continuation - include: scope:source.c#preprocessor-comments - match: '\.\.\.' scope: keyword.operator.variadic.objc++ - match: '(?=\))' pop: true - match: (/\*).*(\*/) scope: comment.block.objc++ captures: 1: punctuation.definition.comment.objc++ 2: punctuation.definition.comment.objc++ - match: '\S+' scope: invalid.illegal.unexpected-character.objc++ - include: scope:source.c#preprocessor-line-continuation - include: scope:source.c#preprocessor-comments - match: '\.\.\.' scope: keyword.operator.variadic.objc++ - match: (/\*).*(\*/) scope: comment.block.objc++ captures: 1: punctuation.definition.comment.objc++ 2: punctuation.definition.comment.objc++ - match: $\n scope: invalid.illegal.unexpected-end-of-line.objc++ preprocessor-macro-definition: - meta_content_scope: meta.preprocessor.macro.objc++ - 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.objc++ - match: '\}' scope: punctuation.section.block.end.objc++ # Captures the namespace macro idiom - match: '\b(namespace)\s+(?={{path_lookahead}}\s*\{)' scope: meta.namespace.objc++ captures: 1: keyword.control.objc++ push: - meta_content_scope: meta.namespace.objc++ entity.name.namespace.objc++ - include: scope:source.c++#identifiers - match: '(?=\S)' pop: true - include: expressions preprocessor-other: - match: ^\s*(#\s*(?:if|ifdef|ifndef|elif|else|line|pragma|undef))\b captures: 1: keyword.control.import.objc++ push: - meta_scope: meta.preprocessor.objc++ - 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.objc++ - match: ^\s*(#\s*endif)\b captures: 1: meta.preprocessor.objc++ keyword.control.import.objc++ - match: ^\s*(#\s*(?:error|warning))\b captures: 1: keyword.control.import.error.objc++ push: - meta_scope: meta.preprocessor.diagnostic.objc++ - 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.objc++ - match: ^\s*(#\s*(?:include|include_next))\b captures: 1: keyword.control.import.include.objc++ push: - meta_scope: meta.preprocessor.include.objc++ - include: preprocessor-other-include-common - match: ^\s*(#\s*import)\b captures: 1: keyword.control.import.import.objc++ push: - meta_scope: meta.preprocessor.import.objc++ - include: preprocessor-other-include-common - include: scope:source.c++#preprocessor-practical-workarounds preprocessor-other-include-common: - 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.objc++ push: - meta_scope: string.quoted.double.include.objc++ - match: '"' scope: punctuation.definition.string.end.objc++ pop: true - match: < scope: punctuation.definition.string.begin.objc++ push: - meta_scope: string.quoted.other.lt-gt.include.objc++ - match: ">" scope: punctuation.definition.string.end.objc++ pop: true