mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-11 11:15:24 +03:00
Add C and C++ grammars
This commit is contained in:
parent
bd822c2599
commit
e13793034a
1
packages/language-c/.envrc
Normal file
1
packages/language-c/.envrc
Normal file
@ -0,0 +1 @@
|
||||
source "/Users/andrew/Code/JavaScript/emsdk/emsdk_env.sh"
|
1
packages/language-c/.tool-versions
Normal file
1
packages/language-c/.tool-versions
Normal file
@ -0,0 +1 @@
|
||||
nodejs 18.14.0
|
13
packages/language-c/grammars/modern-tree-sitter-c.cson
Normal file
13
packages/language-c/grammars/modern-tree-sitter-c.cson
Normal file
@ -0,0 +1,13 @@
|
||||
name: 'C'
|
||||
scopeName: 'source.c'
|
||||
type: 'tree-sitter-2'
|
||||
parser: 'tree-sitter-c'
|
||||
|
||||
injectionRegex: '^(c|C)$'
|
||||
|
||||
treeSitter:
|
||||
grammar: 'tree-sitter-c/tree-sitter-c.wasm'
|
||||
syntaxQuery: 'tree-sitter-c/highlights.scm'
|
||||
localsQuery: 'tree-sitter-c/locals.scm'
|
||||
foldsQuery: 'tree-sitter-c/folds.scm'
|
||||
indentsQuery: 'tree-sitter-c/indents.scm'
|
13
packages/language-c/grammars/modern-tree-sitter-cpp.cson
Normal file
13
packages/language-c/grammars/modern-tree-sitter-cpp.cson
Normal file
@ -0,0 +1,13 @@
|
||||
name: 'C++'
|
||||
scopeName: 'source.cpp'
|
||||
type: 'tree-sitter-2'
|
||||
parser: 'tree-sitter-cpp'
|
||||
|
||||
injectionRegex: '^(cpp|CPP|cc|CC)$'
|
||||
|
||||
treeSitter:
|
||||
grammar: 'tree-sitter-cpp/tree-sitter-cpp.wasm'
|
||||
syntaxQuery: 'tree-sitter-cpp/highlights.scm'
|
||||
localsQuery: 'tree-sitter-cpp/locals.scm'
|
||||
foldsQuery: 'tree-sitter-cpp/folds.scm'
|
||||
indentsQuery: 'tree-sitter-cpp/indents.scm'
|
24
packages/language-c/grammars/tree-sitter-c/folds.scm
Normal file
24
packages/language-c/grammars/tree-sitter-c/folds.scm
Normal file
@ -0,0 +1,24 @@
|
||||
; When we've got
|
||||
;
|
||||
; if (foo) {
|
||||
; // something
|
||||
; } else {
|
||||
; // something else
|
||||
; }
|
||||
;
|
||||
; we want the folds to work a little differently so that collapsing the `if`
|
||||
; fold doesn't interfere with our ability to collapse the `else` fold.
|
||||
(if_statement
|
||||
consequence: (compound_statement) @fold
|
||||
(#set! adjustToEndOfPreviousRow true))
|
||||
|
||||
[
|
||||
(field_declaration_list)
|
||||
(enumerator_list)
|
||||
(compound_statement)
|
||||
] @fold
|
||||
|
||||
; Divided folds for preprocessor statements because they can't reliably be
|
||||
; expressed with simple folds.
|
||||
["#ifndef" "#ifdef" "#elif" "#else" "#if"] @fold.start
|
||||
["#elif" "#else" "#endif"] @fold.end
|
310
packages/language-c/grammars/tree-sitter-c/highlights.scm
Normal file
310
packages/language-c/grammars/tree-sitter-c/highlights.scm
Normal file
@ -0,0 +1,310 @@
|
||||
; PREPROCESSOR
|
||||
; ============
|
||||
|
||||
[
|
||||
"#if"
|
||||
"#ifdef"
|
||||
"#ifndef"
|
||||
"#endif"
|
||||
"#elif"
|
||||
"#else"
|
||||
] @keyword.control.directive.conditional.c
|
||||
|
||||
"#define" @keyword.control.directive.define.c
|
||||
"#include" @keyword.control.directive.include.c
|
||||
|
||||
; This will match if the more specific rules above haven't matched. The
|
||||
; anonymous nodes will match under ideal conditions, but might not be present
|
||||
; if the parser is flummoxed.
|
||||
((preproc_directive) @keyword.control.directive.c
|
||||
(#set! shy true))
|
||||
|
||||
((preproc_ifdef
|
||||
(identifier) @entity.name.function.preprocessor.c
|
||||
(#match? @entity.name.function.preprocessor.c "[a-zA-Z_$][\\w$]*")))
|
||||
|
||||
(preproc_function_def
|
||||
(identifier) @entity.name.function.preprocessor.c
|
||||
(#set! final true))
|
||||
|
||||
(system_lib_string) @string.quoted.other.lt-gt.include.c
|
||||
((system_lib_string) @punctuation.definition.string.begin.c
|
||||
(#set! endAfterFirstMatchOf "^<"))
|
||||
((system_lib_string) @punctuation.definition.string.end.c
|
||||
(#set! startBeforeFirstMatchOf ">$"))
|
||||
|
||||
|
||||
; TYPES
|
||||
; =====
|
||||
|
||||
; WORKAROUND: If we're in an error state, don't trust the parser's designation
|
||||
; of `type_identifier`. Someone's probably just typing on a new line.
|
||||
(ERROR
|
||||
(type_identifier) @_IGNORE_
|
||||
(#set! final true))
|
||||
|
||||
(primitive_type) @storage.type.builtin.c
|
||||
(type_identifier) @storage.type.other.c
|
||||
|
||||
[
|
||||
"enum"
|
||||
"long"
|
||||
"short"
|
||||
"signed"
|
||||
"struct"
|
||||
"typedef"
|
||||
"union"
|
||||
"unsigned"
|
||||
] @storage.type.c
|
||||
|
||||
[
|
||||
"const"
|
||||
"extern"
|
||||
"inline"
|
||||
"register"
|
||||
"restrict"
|
||||
"static"
|
||||
"volatile"
|
||||
] @storage.modifier.c
|
||||
|
||||
((primitive_type) @support.type.stdint.c
|
||||
(#match? @support.type.stdint.c "^(int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|int_least8_t|int_least16_t|int_least32_t|int_least64_t|uint_least8_t|uint_least16_t|uint_least32_t|uint_least64_t|int_fast8_t|int_fast16_t|int_fast32_t|int_fast64_t|uint_fast8_t|uint_fast16_t|uint_fast32_t|uint_fast64_t|intptr_t|uintptr_t|intmax_t|intmax_t|uintmax_t|uintmax_t)$"))
|
||||
|
||||
|
||||
; CAVEAT: tree-sitter-c doesn't identify placeholders like `%c` in strings.
|
||||
; Candidate for an injection grammar.
|
||||
(string_literal "\"") @string.quoted.double.c
|
||||
|
||||
(string_literal
|
||||
"\"" @punctuation.definition.string.begin.c
|
||||
(#set! onlyIfFirst true))
|
||||
|
||||
(string_literal
|
||||
"\"" @punctuation.definition.string.end.c
|
||||
(#set! onlyIfLast true))
|
||||
|
||||
(char_literal "'") @string.quoted.single.c
|
||||
|
||||
(char_literal
|
||||
"'" @punctuation.definition.string.begin.c
|
||||
(#set! onlyIfFirst true))
|
||||
|
||||
(char_literal
|
||||
"'" @punctuation.definition.string.end.c
|
||||
(#set! onlyIfLast true))
|
||||
|
||||
(string_literal (escape_sequence) @constant.character.escape.c)
|
||||
(char_literal (escape_sequence) @constant.character.escape.c)
|
||||
|
||||
; VARIABLES
|
||||
; =========
|
||||
|
||||
; Declarations and assignments
|
||||
; ----------------------------
|
||||
|
||||
(declaration
|
||||
(identifier) @variable.declaration.c)
|
||||
|
||||
(field_declaration
|
||||
(field_identifier) @variable.declaration.c)
|
||||
|
||||
(field_declaration
|
||||
(pointer_declarator
|
||||
(field_identifier) @variable.declaration.c))
|
||||
|
||||
(field_declaration
|
||||
(array_declarator
|
||||
(field_identifier) @variable.declaration.c))
|
||||
|
||||
(init_declarator
|
||||
(identifier) @variable.declaration.c)
|
||||
|
||||
(init_declarator
|
||||
(pointer_declarator
|
||||
(identifier) @variable.declaration.c))
|
||||
|
||||
(assignment_expression
|
||||
left: (identifier) @variable.other.assignment.c)
|
||||
|
||||
|
||||
; Function parameters
|
||||
; -------------------
|
||||
|
||||
(preproc_params
|
||||
(identifier) @variable.parameter.preprocessor.c)
|
||||
|
||||
; The "foo" in `const char foo` within a parameter list.
|
||||
(parameter_declaration
|
||||
declarator: (identifier) @variable.parameter.c)
|
||||
|
||||
; The "foo" in `const char *foo` within a parameter list.
|
||||
(parameter_declaration
|
||||
declarator: (pointer_declarator
|
||||
declarator: (identifier) @variable.parameter.c))
|
||||
|
||||
; The "foo" in `const char foo[]` within a parameter list.
|
||||
(parameter_declaration
|
||||
declarator: (array_declarator
|
||||
declarator: (identifier) @variable.parameter.c))
|
||||
|
||||
; The "argv" in `char* argv[]` within a parameter list.
|
||||
(parameter_declaration
|
||||
declarator: (pointer_declarator
|
||||
declarator: (array_declarator
|
||||
declarator: (identifier) @variable.parameter.c)))
|
||||
|
||||
; The "size" in `finfo->size`.
|
||||
(field_expression
|
||||
"->"
|
||||
field: (field_identifier) @variable.other.member.c)
|
||||
|
||||
|
||||
; FUNCTIONS
|
||||
; =========
|
||||
|
||||
(function_declarator
|
||||
(identifier) @entity.name.function.c)
|
||||
|
||||
(call_expression
|
||||
(identifier) @support.function.c99.c
|
||||
; Regex copied from the TM grammar.
|
||||
(#match? @support.function.c99.c "^(_Exit|(?:nearbyint|nextafter|nexttoward|netoward|nan)[fl]?|a(?:cos|sin)h?[fl]?|abort|abs|asctime|assert|atan(?:[h2]?[fl]?)?|atexit|ato[ifl]|atoll|bsearch|btowc|cabs[fl]?|cacos|cacos[fl]|cacosh[fl]?|calloc|carg[fl]?|casinh?[fl]?|catanh?[fl]?|cbrt[fl]?|ccosh?[fl]?|ceil[fl]?|cexp[fl]?|cimag[fl]?|clearerr|clock|clog[fl]?|conj[fl]?|copysign[fl]?|cosh?[fl]?|cpow[fl]?|cproj[fl]?|creal[fl]?|csinh?[fl]?|csqrt[fl]?|ctanh?[fl]?|ctime|difftime|div|erfc?[fl]?|exit|fabs[fl]?|exp(?:2[fl]?|[fl]|m1[fl]?)?|fclose|fdim[fl]?|fe[gs]et(?:env|exceptflag|round)|feclearexcept|feholdexcept|feof|feraiseexcept|ferror|fetestexcept|feupdateenv|fflush|fgetpos|fgetw?[sc]|floor[fl]?|fmax?[fl]?|fmin[fl]?|fmod[fl]?|fopen|fpclassify|fprintf|fputw?[sc]|fread|free|freopen|frexp[fl]?|fscanf|fseek|fsetpos|ftell|fwide|fwprintf|fwrite|fwscanf|genv|get[sc]|getchar|gmtime|gwc|gwchar|hypot[fl]?|ilogb[fl]?|imaxabs|imaxdiv|isalnum|isalpha|isblank|iscntrl|isdigit|isfinite|isgraph|isgreater|isgreaterequal|isinf|isless(?:equal|greater)?|isw?lower|isnan|isnormal|isw?print|isw?punct|isw?space|isunordered|isw?upper|iswalnum|iswalpha|iswblank|iswcntrl|iswctype|iswdigit|iswgraph|isw?xdigit|labs|ldexp[fl]?|ldiv|lgamma[fl]?|llabs|lldiv|llrint[fl]?|llround[fl]?|localeconv|localtime|log[2b]?[fl]?|log1[p0][fl]?|longjmp|lrint[fl]?|lround[fl]?|malloc|mbr?len|mbr?towc|mbsinit|mbsrtowcs|mbstowcs|memchr|memcmp|memcpy|memmove|memset|mktime|modf[fl]?|perror|pow[fl]?|printf|puts|putw?c(?:har)?|qsort|raise|rand|remainder[fl]?|realloc|remove|remquo[fl]?|rename|rewind|rint[fl]?|round[fl]?|scalbl?n[fl]?|scanf|setbuf|setjmp|setlocale|setvbuf|signal|signbit|sinh?[fl]?|snprintf|sprintf|sqrt[fl]?|srand|sscanf|strcat|strchr|strcmp|strcoll|strcpy|strcspn|strerror|strftime|strlen|strncat|strncmp|strncpy|strpbrk|strrchr|strspn|strstr|strto[kdf]|strtoimax|strtol[dl]?|strtoull?|strtoumax|strxfrm|swprintf|swscanf|system|tan|tan[fl]|tanh[fl]?|tgamma[fl]?|time|tmpfile|tmpnam|tolower|toupper|trunc[fl]?|ungetw?c|va_arg|va_copy|va_end|va_start|vfw?printf|vfw?scanf|vprintf|vscanf|vsnprintf|vsprintf|vsscanf|vswprintf|vswscanf|vwprintf|vwscanf|wcrtomb|wcscat|wcschr|wcscmp|wcscoll|wcscpy|wcscspn|wcsftime|wcslen|wcsncat|wcsncmp|wcsncpy|wcspbrk|wcsrchr|wcsrtombs|wcsspn|wcsstr|wcsto[dkf]|wcstoimax|wcstol[dl]?|wcstombs|wcstoull?|wcstoumax|wcsxfrm|wctom?b|wmem(?:set|chr|cpy|cmp|move)|wprintf|wscanf)$")
|
||||
(#set! final true))
|
||||
|
||||
; The "foo" in `thing->troz->foo(...)`.
|
||||
(call_expression
|
||||
(field_expression
|
||||
field: (field_identifier) @support.function.other.c)
|
||||
(#set! final true))
|
||||
|
||||
(call_expression
|
||||
(identifier) @support.function.other.c
|
||||
(#set! final true))
|
||||
|
||||
; NUMBERS
|
||||
; =======
|
||||
|
||||
(number_literal) @constant.numeric.c
|
||||
|
||||
|
||||
; CONSTANTS
|
||||
; =========
|
||||
|
||||
[
|
||||
(null)
|
||||
(true)
|
||||
(false)
|
||||
] @constant.language._TYPE_.c
|
||||
|
||||
((identifier) @constant.c
|
||||
(#match? @constant.c "[_A-Z][_A-Z0-9]*$"))
|
||||
|
||||
|
||||
; COMMENTS
|
||||
; ========
|
||||
|
||||
; Match // comments.
|
||||
((comment) @comment.line.double-slash.c
|
||||
(#match? @comment.line.double-slash.c "^\\s*//"))
|
||||
|
||||
((comment) @punctuation.definition.comment.c
|
||||
(#match? @comment.line.double-slash.c "^\\s*//")
|
||||
(#set! startAndEndAroundFirstMatchOf "//"))
|
||||
|
||||
; Match /* */ comments.
|
||||
((comment) @comment.block.c
|
||||
(#match? @comment.block.c "^/\\*"))
|
||||
|
||||
((comment) @punctuation.definition.comment.begin.c
|
||||
(#match? @punctuation.definition.comment.begin.c "^/\\*")
|
||||
(#set! startAndEndAroundFirstMatchOf "^/\\*"))
|
||||
|
||||
((comment) @punctuation.definition.comment.end.c
|
||||
(#match? @punctuation.definition.comment.end.c "\\*/$")
|
||||
(#set! startAndEndAroundFirstMatchOf "\\*/$"))
|
||||
|
||||
|
||||
[
|
||||
"break"
|
||||
"case"
|
||||
"continue"
|
||||
"default"
|
||||
"do"
|
||||
"else"
|
||||
"for"
|
||||
"goto"
|
||||
"if"
|
||||
"return"
|
||||
"switch"
|
||||
"while"
|
||||
] @keyword.control._TYPE_.c
|
||||
|
||||
; OPERATORS
|
||||
; =========
|
||||
|
||||
(pointer_declarator "*" @keyword.operator.pointer.c)
|
||||
(abstract_pointer_declarator "*" @keyword.operator.pointer.c)
|
||||
(pointer_expression "*" @keyword.operator.pointer.c)
|
||||
|
||||
"sizeof" @keyword.operator.sizeof.c
|
||||
(pointer_expression "&" @keyword.operator.pointer.c)
|
||||
|
||||
"=" @keyword.operator.assignment.c
|
||||
|
||||
[
|
||||
"%="
|
||||
"+="
|
||||
"-="
|
||||
"*="
|
||||
"/="
|
||||
"&="
|
||||
"^="
|
||||
"<<="
|
||||
">>="
|
||||
"|="
|
||||
] @keyword.operator.assignment.compound.c
|
||||
|
||||
|
||||
(binary_expression
|
||||
["==" "!=" ">" "<" ">=" "<="] @keyword.operator.comparison.c)
|
||||
|
||||
(binary_expression
|
||||
["&" "|" "^" "~" "<<" ">>"]
|
||||
@keyword.operator.bitwise.c)
|
||||
|
||||
"++" @keyword.operator.increment.c
|
||||
"--" @keyword.operator.decrement.c
|
||||
|
||||
(binary_expression ["+" "-" "*" "/" "%"] @keyword.operator.arithmetic.c)
|
||||
(unary_expression ["+" "-" "!"] @keyword.operator.unary.c)
|
||||
|
||||
(conditional_expression
|
||||
["?" ":"] @keyword.operator.ternary.c)
|
||||
|
||||
|
||||
["||" "&&"] @keyword.operator.logical.c
|
||||
|
||||
(field_expression "." @keyword.operator.accessor.dot.c)
|
||||
(preproc_params "..." @keyword.operator.ellipsis.c)
|
||||
|
||||
; PUNCTUATION
|
||||
; ===========
|
||||
|
||||
";" @punctuation.terminator.statement.c
|
||||
|
||||
"," @punctuation.separator.comma.c
|
||||
"->" @punctuation.separator.pointer-access.c
|
||||
|
||||
"{" @punctuation.definition.begin.brace.curly.c
|
||||
"}" @punctuation.definition.end.brace.curly.c
|
||||
"(" @punctuation.definition.begin.brace.round.c
|
||||
")" @punctuation.definition.end.brace.round.c
|
||||
"[" @punctuation.definition.begin.brace.square.c
|
||||
"]" @punctuation.definition.end.brace.square.c
|
||||
|
||||
; TODO:
|
||||
;
|
||||
; * TM-style grammar has a lot of `mac-classic` scopes. I doubt they'd be
|
||||
; present if this wasn't converted from a TextMate grammar, so I'm leaving
|
||||
; them out for now.
|
||||
;
|
20
packages/language-c/grammars/tree-sitter-c/indents.scm
Normal file
20
packages/language-c/grammars/tree-sitter-c/indents.scm
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
|
||||
["{" "(" "["] @indent
|
||||
|
||||
["}" ")" "]"] @dedent
|
||||
|
||||
; `switch` statements have a couple schools of thought, indentation-wise, and
|
||||
; we might have to make this configurable somehow.
|
||||
(switch_statement
|
||||
body: (compound_statement "}" @match
|
||||
(#set! onlyIfLast true))
|
||||
(#set! matchIndentOf parent.startPosition))
|
||||
|
||||
; 'case' and 'default' need to be indented one level more than their containing
|
||||
; `switch`.
|
||||
(["case" "default"] @match
|
||||
(#set! matchIndentOf parent.parent.startPosition)
|
||||
(#set! offsetIndent 1))
|
||||
|
||||
["case" "default"] @indent
|
1
packages/language-c/grammars/tree-sitter-c/locals.scm
Normal file
1
packages/language-c/grammars/tree-sitter-c/locals.scm
Normal file
@ -0,0 +1 @@
|
||||
;
|
BIN
packages/language-c/grammars/tree-sitter-c/tree-sitter-c.wasm
Executable file
BIN
packages/language-c/grammars/tree-sitter-c/tree-sitter-c.wasm
Executable file
Binary file not shown.
24
packages/language-c/grammars/tree-sitter-cpp/folds.scm
Normal file
24
packages/language-c/grammars/tree-sitter-cpp/folds.scm
Normal file
@ -0,0 +1,24 @@
|
||||
; When we've got
|
||||
;
|
||||
; if (foo) {
|
||||
; // something
|
||||
; } else {
|
||||
; // something else
|
||||
; }
|
||||
;
|
||||
; we want the folds to work a little differently so that collapsing the `if`
|
||||
; fold doesn't interfere with our ability to collapse the `else` fold.
|
||||
(if_statement
|
||||
consequence: (compound_statement) @fold
|
||||
(#set! adjustToEndOfPreviousRow true))
|
||||
|
||||
[
|
||||
(field_declaration_list)
|
||||
(enumerator_list)
|
||||
(compound_statement)
|
||||
] @fold
|
||||
|
||||
; Divided folds for preprocessor statements because they can't reliably be
|
||||
; expressed with simple folds.
|
||||
["#ifndef" "#ifdef" "#elif" "#else" "#if"] @fold.start
|
||||
["#elif" "#else" "#endif"] @fold.end
|
384
packages/language-c/grammars/tree-sitter-cpp/highlights.scm
Normal file
384
packages/language-c/grammars/tree-sitter-cpp/highlights.scm
Normal file
@ -0,0 +1,384 @@
|
||||
; PREPROCESSOR
|
||||
; ============
|
||||
|
||||
[
|
||||
"#if"
|
||||
"#ifdef"
|
||||
"#ifndef"
|
||||
"#endif"
|
||||
"#elif"
|
||||
"#else"
|
||||
] @keyword.control.directive.conditional.cpp
|
||||
|
||||
"#define" @keyword.control.directive.define.cpp
|
||||
"#include" @keyword.control.directive.include.cpp
|
||||
|
||||
; This will match if the more specific rules above haven't matched. The
|
||||
; anonymous nodes will match under ideal conditions, but might not be present
|
||||
; if the parser is flummoxed.
|
||||
((preproc_directive) @keyword.control.directive.c
|
||||
(#set! shy true))
|
||||
|
||||
((preproc_ifdef
|
||||
(identifier) @entity.name.function.preprocessor.c
|
||||
(#match? @entity.name.function.preprocessor.c "[a-zA-Z_$][\\w$]*")))
|
||||
|
||||
(preproc_function_def
|
||||
(identifier) @entity.name.function.preprocessor.c
|
||||
(#set! final true))
|
||||
|
||||
(preproc_function_def
|
||||
(identifier) @entity.name.function.preprocessor.cpp
|
||||
(#set! final true)
|
||||
)
|
||||
|
||||
(system_lib_string) @string.quoted.other.lt-gt.include.c
|
||||
((system_lib_string) @punctuation.definition.string.begin.c
|
||||
(#set! endAfterFirstMatchOf "^<"))
|
||||
((system_lib_string) @punctuation.definition.string.end.c
|
||||
(#set! startBeforeFirstMatchOf ">$"))
|
||||
|
||||
|
||||
; TYPES
|
||||
; =====
|
||||
|
||||
; WORKAROUND: If we're in an error state, don't trust the parser's designation
|
||||
; of `type_identifier`. Someone's probably just typing on a new line.
|
||||
(ERROR
|
||||
(type_identifier) @_IGNORE_
|
||||
(#set! final true))
|
||||
|
||||
|
||||
(primitive_type) @storage.type.builtin.cpp
|
||||
|
||||
(class_specifier
|
||||
(type_identifier) @entity.name.class.cpp
|
||||
(#set! final true))
|
||||
|
||||
(type_identifier) @storage.type.other.cpp
|
||||
; (struct_specifier) @storage.type.cpp
|
||||
|
||||
[
|
||||
"enum"
|
||||
"long"
|
||||
"short"
|
||||
"signed"
|
||||
"struct"
|
||||
"typedef"
|
||||
"union"
|
||||
"unsigned"
|
||||
|
||||
"template"
|
||||
] @storage.type.cpp
|
||||
|
||||
[
|
||||
"const"
|
||||
"extern"
|
||||
"inline"
|
||||
"register"
|
||||
"restrict"
|
||||
"static"
|
||||
"volatile"
|
||||
|
||||
"private"
|
||||
"protected"
|
||||
"public"
|
||||
|
||||
"friend"
|
||||
"explicit"
|
||||
"virtual"
|
||||
"override"
|
||||
"final"
|
||||
"noexcept"
|
||||
] @storage.modifier.cpp
|
||||
|
||||
(
|
||||
(primitive_type) @support.type.stdint.cpp
|
||||
(#match? @support.type.stdint.cpp "^(int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|int_least8_t|int_least16_t|int_least32_t|int_least64_t|uint_least8_t|uint_least16_t|uint_least32_t|uint_least64_t|int_fast8_t|int_fast16_t|int_fast32_t|int_fast64_t|uint_fast8_t|uint_fast16_t|uint_fast32_t|uint_fast64_t|intptr_t|uintptr_t|intmax_t|intmax_t|uintmax_t|uintmax_t)$")
|
||||
)
|
||||
|
||||
"typename" @storage.modifier.typename.cpp
|
||||
|
||||
|
||||
; FUNCTIONS
|
||||
; =========
|
||||
|
||||
(function_declarator
|
||||
(identifier) @entity.name.function.cpp)
|
||||
|
||||
(function_declarator
|
||||
(field_identifier) @entity.name.function.method.cpp)
|
||||
|
||||
(call_expression
|
||||
(identifier) @support.function.c99.cpp
|
||||
; Regex copied from the TM grammar.
|
||||
(#match? @support.function.c99.cpp "^(_Exit|(?:nearbyint|nextafter|nexttoward|netoward|nan)[fl]?|a(?:cos|sin)h?[fl]?|abort|abs|asctime|assert|atan(?:[h2]?[fl]?)?|atexit|ato[ifl]|atoll|bsearch|btowc|cabs[fl]?|cacos|cacos[fl]|cacosh[fl]?|calloc|carg[fl]?|casinh?[fl]?|catanh?[fl]?|cbrt[fl]?|ccosh?[fl]?|ceil[fl]?|cexp[fl]?|cimag[fl]?|clearerr|clock|clog[fl]?|conj[fl]?|copysign[fl]?|cosh?[fl]?|cpow[fl]?|cproj[fl]?|creal[fl]?|csinh?[fl]?|csqrt[fl]?|ctanh?[fl]?|ctime|difftime|div|erfc?[fl]?|exit|fabs[fl]?|exp(?:2[fl]?|[fl]|m1[fl]?)?|fclose|fdim[fl]?|fe[gs]et(?:env|exceptflag|round)|feclearexcept|feholdexcept|feof|feraiseexcept|ferror|fetestexcept|feupdateenv|fflush|fgetpos|fgetw?[sc]|floor[fl]?|fmax?[fl]?|fmin[fl]?|fmod[fl]?|fopen|fpclassify|fprintf|fputw?[sc]|fread|free|freopen|frexp[fl]?|fscanf|fseek|fsetpos|ftell|fwide|fwprintf|fwrite|fwscanf|genv|get[sc]|getchar|gmtime|gwc|gwchar|hypot[fl]?|ilogb[fl]?|imaxabs|imaxdiv|isalnum|isalpha|isblank|iscntrl|isdigit|isfinite|isgraph|isgreater|isgreaterequal|isinf|isless(?:equal|greater)?|isw?lower|isnan|isnormal|isw?print|isw?punct|isw?space|isunordered|isw?upper|iswalnum|iswalpha|iswblank|iswcntrl|iswctype|iswdigit|iswgraph|isw?xdigit|labs|ldexp[fl]?|ldiv|lgamma[fl]?|llabs|lldiv|llrint[fl]?|llround[fl]?|localeconv|localtime|log[2b]?[fl]?|log1[p0][fl]?|longjmp|lrint[fl]?|lround[fl]?|malloc|mbr?len|mbr?towc|mbsinit|mbsrtowcs|mbstowcs|memchr|memcmp|memcpy|memmove|memset|mktime|modf[fl]?|perror|pow[fl]?|printf|puts|putw?c(?:har)?|qsort|raise|rand|remainder[fl]?|realloc|remove|remquo[fl]?|rename|rewind|rint[fl]?|round[fl]?|scalbl?n[fl]?|scanf|setbuf|setjmp|setlocale|setvbuf|signal|signbit|sinh?[fl]?|snprintf|sprintf|sqrt[fl]?|srand|sscanf|strcat|strchr|strcmp|strcoll|strcpy|strcspn|strerror|strftime|strlen|strncat|strncmp|strncpy|strpbrk|strrchr|strspn|strstr|strto[kdf]|strtoimax|strtol[dl]?|strtoull?|strtoumax|strxfrm|swprintf|swscanf|system|tan|tan[fl]|tanh[fl]?|tgamma[fl]?|time|tmpfile|tmpnam|tolower|toupper|trunc[fl]?|ungetw?c|va_arg|va_copy|va_end|va_start|vfw?printf|vfw?scanf|vprintf|vscanf|vsnprintf|vsprintf|vsscanf|vswprintf|vswscanf|vwprintf|vwscanf|wcrtomb|wcscat|wcschr|wcscmp|wcscoll|wcscpy|wcscspn|wcsftime|wcslen|wcsncat|wcsncmp|wcsncpy|wcspbrk|wcsrchr|wcsrtombs|wcsspn|wcsstr|wcsto[dkf]|wcstoimax|wcstol[dl]?|wcstombs|wcstoull?|wcstoumax|wcsxfrm|wctom?b|wmem(?:set|chr|cpy|cmp|move)|wprintf|wscanf)$")
|
||||
(#set! final true))
|
||||
|
||||
; The "foo" in `thing->troz->foo(...)`.
|
||||
(call_expression
|
||||
(field_expression
|
||||
field: (field_identifier) @support.function.other.cpp)
|
||||
(#set! final true))
|
||||
|
||||
(call_expression
|
||||
(identifier) @support.function.other.cpp
|
||||
(#set! final true))
|
||||
|
||||
|
||||
; STRINGS
|
||||
; =======
|
||||
|
||||
; CAVEAT: tree-sitter-c doesn't identify placeholders like `%c` in strings.
|
||||
; Candidate for an injection grammar.
|
||||
(string_literal "\"") @string.quoted.double.cpp
|
||||
|
||||
(string_literal
|
||||
"\"" @punctuation.definition.string.begin.cpp
|
||||
(#set! onlyIfFirst true))
|
||||
|
||||
(string_literal
|
||||
"\"" @punctuation.definition.string.end.cpp
|
||||
(#set! onlyIfLast true))
|
||||
|
||||
(char_literal "'") @string.quoted.single.cpp
|
||||
|
||||
(char_literal
|
||||
"'" @punctuation.definition.string.begin.cpp
|
||||
(#set! onlyIfFirst true))
|
||||
|
||||
(char_literal
|
||||
"'" @punctuation.definition.string.end.cpp
|
||||
(#set! onlyIfLast true))
|
||||
|
||||
(string_literal (escape_sequence) @constant.character.escape.cpp)
|
||||
(char_literal (escape_sequence) @constant.character.escape.cpp)
|
||||
|
||||
; VARIABLES
|
||||
; =========
|
||||
|
||||
(this) @variable.language.this.cpp
|
||||
|
||||
; Declarations and assignments
|
||||
; ----------------------------
|
||||
|
||||
(declaration
|
||||
(identifier) @variable.declaration.cpp)
|
||||
|
||||
(field_declaration
|
||||
(field_identifier) @variable.declaration.cpp)
|
||||
|
||||
(field_declaration
|
||||
(pointer_declarator
|
||||
(field_identifier) @variable.declaration.cpp))
|
||||
|
||||
(field_declaration
|
||||
(array_declarator
|
||||
(field_identifier) @variable.declaration.cpp))
|
||||
|
||||
(init_declarator
|
||||
(identifier) @variable.declaration.cpp)
|
||||
|
||||
(init_declarator
|
||||
(pointer_declarator
|
||||
(identifier) @variable.declaration.cpp))
|
||||
|
||||
(assignment_expression
|
||||
left: (identifier) @variable.other.assignment.cpp)
|
||||
|
||||
; Function parameters
|
||||
; -------------------
|
||||
|
||||
(preproc_params
|
||||
(identifier) @variable.parameter.preprocessor.cpp)
|
||||
|
||||
(parameter_declaration
|
||||
declarator: (identifier) @variable.parameter.cpp)
|
||||
|
||||
(parameter_declaration
|
||||
declarator: (pointer_declarator
|
||||
declarator: (identifier) @variable.parameter.cpp))
|
||||
|
||||
; The "foo" in `const char foo[]` within a parameter list.
|
||||
(parameter_declaration
|
||||
declarator: (array_declarator
|
||||
declarator: (identifier) @variable.parameter.cpp))
|
||||
|
||||
; The "argv" in `char* argv[]` within a parameter list.
|
||||
(parameter_declaration
|
||||
declarator: (pointer_declarator
|
||||
declarator: (array_declarator
|
||||
declarator: (identifier) @variable.parameter.cpp)))
|
||||
|
||||
; The "size" in `finfo->size`.
|
||||
(field_expression
|
||||
"->"
|
||||
field: (field_identifier) @variable.other.member.cpp)
|
||||
|
||||
; Common naming idiom for C++ instanced vars: "fMemberName"
|
||||
; ((identifier) @variable.other.readwrite.member.cpp
|
||||
; (#match? @variable.other.readwrite.member.cpp "^(f|m)[A-Z]\\w*$"))
|
||||
|
||||
|
||||
|
||||
; NUMBERS
|
||||
; =======
|
||||
|
||||
(number_literal) @constant.numeric.cpp
|
||||
|
||||
; CONSTANTS
|
||||
; =========
|
||||
|
||||
[
|
||||
(null)
|
||||
(true)
|
||||
(false)
|
||||
(nullptr)
|
||||
] @constant.language._TYPE_.cpp
|
||||
|
||||
((identifier) @constant.cpp
|
||||
(#match? @constant.cpp "[_A-Z][_A-Z0-9]*$"))
|
||||
|
||||
|
||||
; COMMENTS
|
||||
; ========
|
||||
|
||||
; Match // comments.
|
||||
((comment) @comment.line.double-slash.cpp
|
||||
(#match? @comment.line.double-slash.cpp "^\\s*//"))
|
||||
|
||||
((comment) @punctuation.definition.comment.cpp
|
||||
(#match? @comment.line.double-slash.cpp "^\\s*//")
|
||||
(#set! startAndEndAroundFirstMatchOf "//"))
|
||||
|
||||
; Match /* */ comments.
|
||||
((comment) @comment.block.cpp
|
||||
(#match? @comment.block.cpp "^/\\*"))
|
||||
|
||||
((comment) @punctuation.definition.comment.begin.cpp
|
||||
(#match? @punctuation.definition.comment.begin.cpp "^/\\*")
|
||||
(#set! startAndEndAroundFirstMatchOf "^/\\*"))
|
||||
|
||||
((comment) @punctuation.definition.comment.end.cpp
|
||||
(#match? @punctuation.definition.comment.end.cpp "\\*/$")
|
||||
(#set! startAndEndAroundFirstMatchOf "\\*/$"))
|
||||
|
||||
|
||||
; KEYWORDS
|
||||
; ========
|
||||
|
||||
[
|
||||
"break"
|
||||
"case"
|
||||
"continue"
|
||||
"default"
|
||||
"do"
|
||||
"else"
|
||||
"for"
|
||||
"goto"
|
||||
"if"
|
||||
"return"
|
||||
"switch"
|
||||
"while"
|
||||
|
||||
"new"
|
||||
"delete"
|
||||
] @keyword.control._TYPE_.cpp
|
||||
|
||||
[
|
||||
"catch"
|
||||
"operator"
|
||||
"try"
|
||||
"throw"
|
||||
"using"
|
||||
"namespace"
|
||||
] @keyword.control._TYPE_.cpp
|
||||
|
||||
; OPERATORS
|
||||
; =========
|
||||
|
||||
(pointer_declarator "*" @keyword.operator.pointer.cpp)
|
||||
(abstract_pointer_declarator "*" @keyword.operator.pointer.cpp)
|
||||
(pointer_expression "*" @keyword.operator.pointer.cpp)
|
||||
|
||||
|
||||
"sizeof" @keyword.operator.sizeof.cpp
|
||||
(pointer_expression "&" @keyword.operator.pointer.c)
|
||||
|
||||
|
||||
"=" @keyword.operator.assignment.cpp
|
||||
|
||||
[
|
||||
"%="
|
||||
"+="
|
||||
"-="
|
||||
"*="
|
||||
"/="
|
||||
"&="
|
||||
"^="
|
||||
"<<="
|
||||
">>="
|
||||
"|="
|
||||
] @keyword.operator.assignment.compound.cpp
|
||||
|
||||
(binary_expression
|
||||
["==" "!=" ">" "<" ">=" "<="] @keyword.operator.comparison.cpp)
|
||||
|
||||
|
||||
["&&" "||"] @keyword.operator.logical.cpp
|
||||
|
||||
"++" @keyword.operator.increment.cpp
|
||||
"--" @keyword.operator.decrement.cpp
|
||||
|
||||
(binary_expression
|
||||
["&" "|" "^" "~" "<<" ">>"]
|
||||
@keyword.operator.bitwise.cpp)
|
||||
|
||||
(binary_expression
|
||||
["<" ">"] @keyword.operator.comparison.cpp)
|
||||
|
||||
(binary_expression
|
||||
["+" "-" "*" "/" "%"] @keyword.operator.arithmetic.cpp)
|
||||
|
||||
(unary_expression
|
||||
["+" "-" "!"] @keyword.operator.unary.cpp)
|
||||
|
||||
(conditional_expression
|
||||
["?" ":"] @keyword.operator.ternary.cpp)
|
||||
|
||||
(qualified_identifier
|
||||
"::" @keyword.operator.accessor.namespace.cpp)
|
||||
|
||||
(field_expression "." @keyword.operator.accessor.dot.cpp)
|
||||
(preproc_params "..." @keyword.operator.ellipsis.cpp)
|
||||
|
||||
; PUNCTUATION
|
||||
; ===========
|
||||
|
||||
";" @punctuation.terminator.statement.cpp
|
||||
|
||||
"," @punctuation.separator.comma.cpp
|
||||
"->" @punctuation.separator.pointer-access.cpp
|
||||
|
||||
"{" @punctuation.definition.begin.brace.curly.cpp
|
||||
"}" @punctuation.definition.end.brace.curly.cpp
|
||||
"(" @punctuation.definition.begin.brace.round.cpp
|
||||
")" @punctuation.definition.end.brace.round.cpp
|
||||
"[" @punctuation.definition.begin.brace.square.cpp
|
||||
"]" @punctuation.definition.end.brace.square.cpp
|
||||
|
||||
; TODO:
|
||||
;
|
||||
; * TM-style grammar has a lot of `mac-classic` scopes. I doubt they'd be
|
||||
; present if this wasn't converted from a TextMate grammar, so I'm leaving
|
||||
; them out for now.
|
||||
;
|
||||
|
||||
; (
|
||||
; (compound_statement) @invalid.illegal
|
||||
; )
|
||||
|
||||
|
||||
(compound_statement
|
||||
(compound_statement) @invalid.illegal
|
||||
)
|
32
packages/language-c/grammars/tree-sitter-cpp/indents.scm
Normal file
32
packages/language-c/grammars/tree-sitter-cpp/indents.scm
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
|
||||
["{" "(" "["] @indent
|
||||
|
||||
["}" ")" "]"] @dedent
|
||||
|
||||
|
||||
; With access specifiers like…
|
||||
;
|
||||
; class Foo {
|
||||
; public:
|
||||
; void bar() {}
|
||||
; }
|
||||
;
|
||||
; …prevailing style is to dedent the specifier so it matches the indentation of
|
||||
; the line above.
|
||||
(access_specifier) @dedent @indent
|
||||
|
||||
; `switch` statements have a couple schools of thought, indentation-wise, and
|
||||
; we might have to make this configurable somehow.
|
||||
(switch_statement
|
||||
body: (compound_statement "}" @match
|
||||
(#set! onlyIfLast true))
|
||||
(#set! matchIndentOf parent.startPosition))
|
||||
|
||||
; 'case' and 'default' need to be indented one level more than their containing
|
||||
; `switch`.
|
||||
(["case" "default"] @match
|
||||
(#set! matchIndentOf parent.parent.startPosition)
|
||||
(#set! offsetIndent 1))
|
||||
|
||||
["case" "default"] @indent
|
1
packages/language-c/grammars/tree-sitter-cpp/locals.scm
Normal file
1
packages/language-c/grammars/tree-sitter-cpp/locals.scm
Normal file
@ -0,0 +1 @@
|
||||
;
|
BIN
packages/language-c/grammars/tree-sitter-cpp/tree-sitter-cpp.wasm
Executable file
BIN
packages/language-c/grammars/tree-sitter-cpp/tree-sitter-cpp.wasm
Executable file
Binary file not shown.
Loading…
Reference in New Issue
Block a user