Add namespaces to custom #set! predicates

Predicates were getting pretty chaotic. With the namespace, it's now clearer
where a predicate may be defined and what its purpose is. It also helps resolve
ambiguity — e.g., both folds and highlights can have an `endAt` predicate, so
now they're disambiguated as `fold.endAt` and `adjust.endAt`, respectively.

Namespaces:

* `highlight` for highlight-specific settings (of which there is presently only
   one)
* `test` for scope tests (currently used by highlights and indents)
* `adjust` for scope adjustments (highlights)
* `indent` for indent settings
* `fold` for fold settings

Right now, only the `test` namespace will be used by more than one kind of query
file, but I could imagine that changing in the future.

For now, tests and adjustments still work without the prepended namespace, but
I imagine I'll take that out even before we ship this feature experimentally.
Much easier to make big changes like this before anyone depends on them.

This also draws a much clearer line between `#set!` predicates with special
meaning in Pulsar… and those which are being used to set arbitrary data for
later use. For instance, if you see `(#set! isOnLeftSideOfAssignment true)`, you
know it must just be arbitrary data.
This commit is contained in:
Andrew Dupont 2023-04-29 14:58:42 -07:00
parent 0237ddceba
commit 1c90032276
30 changed files with 553 additions and 496 deletions

View File

@ -17,7 +17,7 @@
; 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))
(#set! test.shy true))
((preproc_ifdef
(identifier) @entity.name.function.preprocessor.c
@ -25,13 +25,13 @@
(preproc_function_def
(identifier) @entity.name.function.preprocessor.c
(#set! final true))
(#set! test.final true))
(system_lib_string) @string.quoted.other.lt-gt.include.c
((system_lib_string) @punctuation.definition.string.begin.c
(#set! endAfterFirstMatchOf "^<"))
(#set! adjust.endAfterFirstMatchOf "^<"))
((system_lib_string) @punctuation.definition.string.end.c
(#set! startBeforeFirstMatchOf ">$"))
(#set! adjust.startBeforeFirstMatchOf ">$"))
; TYPES
@ -41,7 +41,7 @@
; of `type_identifier`. Someone's probably just typing on a new line.
(ERROR
(type_identifier) @_IGNORE_
(#set! final true))
(#set! test.final true))
(primitive_type) @storage.type.builtin.c
(type_identifier) @storage.type.other.c
@ -77,21 +77,21 @@
(string_literal
"\"" @punctuation.definition.string.begin.c
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
(string_literal
"\"" @punctuation.definition.string.end.c
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
(char_literal "'") @string.quoted.single.c
(char_literal
"'" @punctuation.definition.string.begin.c
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
(char_literal
"'" @punctuation.definition.string.end.c
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
(string_literal (escape_sequence) @constant.character.escape.c)
(char_literal (escape_sequence) @constant.character.escape.c)
@ -171,17 +171,17 @@
(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))
(#set! test.final true))
; The "foo" in `thing->troz->foo(...)`.
(call_expression
(field_expression
field: (field_identifier) @support.other.function.c)
(#set! final true))
(#set! test.final true))
(call_expression
(identifier) @support.other.function.c
(#set! final true))
(#set! test.final true))
; NUMBERS
; =======
@ -211,7 +211,7 @@
((comment) @punctuation.definition.comment.c
(#match? @comment.line.double-slash.c "^\\s*//")
(#set! startAndEndAroundFirstMatchOf "//"))
(#set! adjust.startAndEndAroundFirstMatchOf "//"))
; Match /* */ comments.
((comment) @comment.block.c
@ -219,11 +219,11 @@
((comment) @punctuation.definition.comment.begin.c
(#match? @punctuation.definition.comment.begin.c "^/\\*")
(#set! startAndEndAroundFirstMatchOf "^/\\*"))
(#set! adjust.startAndEndAroundFirstMatchOf "^/\\*"))
((comment) @punctuation.definition.comment.end.c
(#match? @punctuation.definition.comment.end.c "\\*/$")
(#set! startAndEndAroundFirstMatchOf "\\*/$"))
(#set! adjust.startAndEndAroundFirstMatchOf "\\*/$"))
[
@ -300,18 +300,18 @@
(parameter_list
"(" @punctuation.definition.parameters.begin.bracket.round.c
")" @punctuation.definition.parameters.end.bracket.round.c
(#set! final true))
(#set! test.final true))
(parenthesized_expression
"(" @punctuation.definition.expression.begin.bracket.round.c
")" @punctuation.definition.expression.end.bracket.round.c
(#set! final true))
(#set! test.final true))
(if_statement
condition: (parenthesized_expression
"(" @punctuation.definition.expression.begin.bracket.round.c
")" @punctuation.definition.expression.end.bracket.round.c
(#set! final true)))
(#set! test.final true)))
"{" @punctuation.definition.block.begin.bracket.curly.c
"}" @punctuation.definition.block.end.bracket.curly.c

View File

@ -8,13 +8,13 @@
; we might have to make this configurable somehow.
(switch_statement
body: (compound_statement "}" @match
(#set! onlyIfLast true))
(#set! matchIndentOf parent.startPosition))
(#set! test.onlyIfLast true))
(#set! indent.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))
(#set! indent.matchIndentOf parent.parent.startPosition)
(#set! indent.offsetIndent 1))
["case" "default"] @indent

View File

@ -17,7 +17,7 @@
; 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))
(#set! test.shy true))
((preproc_ifdef
(identifier) @entity.name.function.preprocessor.c
@ -25,18 +25,18 @@
(preproc_function_def
(identifier) @entity.name.function.preprocessor.c
(#set! final true))
(#set! test.final true))
(preproc_function_def
(identifier) @entity.name.function.preprocessor.cpp
(#set! final true)
(#set! test.final true)
)
(system_lib_string) @string.quoted.other.lt-gt.include.c
((system_lib_string) @punctuation.definition.string.begin.c
(#set! endAfterFirstMatchOf "^<"))
(#set! adjust.endAfterFirstMatchOf "^<"))
((system_lib_string) @punctuation.definition.string.end.c
(#set! startBeforeFirstMatchOf ">$"))
(#set! adjust.startBeforeFirstMatchOf ">$"))
; TYPES
@ -46,14 +46,14 @@
; of `type_identifier`. Someone's probably just typing on a new line.
(ERROR
(type_identifier) @_IGNORE_
(#set! final true))
(#set! test.final true))
(primitive_type) @storage.type.builtin.cpp
(class_specifier
(type_identifier) @entity.name.class.cpp
(#set! final true))
(#set! test.final true))
(type_identifier) @storage.type.other.cpp
; (struct_specifier) @storage.type.cpp
@ -113,17 +113,17 @@
(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))
(#set! test.final true))
; The "foo" in `thing->troz->foo(...)`.
(call_expression
(field_expression
field: (field_identifier) @support.other.function.cpp)
(#set! final true))
(#set! test.final true))
(call_expression
(identifier) @support.other.function.cpp
(#set! final true))
(#set! test.final true))
; STRINGS
@ -135,21 +135,21 @@
(string_literal
"\"" @punctuation.definition.string.begin.cpp
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
(string_literal
"\"" @punctuation.definition.string.end.cpp
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
(char_literal "'") @string.quoted.single.cpp
(char_literal
"'" @punctuation.definition.string.begin.cpp
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
(char_literal
"'" @punctuation.definition.string.end.cpp
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
(string_literal (escape_sequence) @constant.character.escape.cpp)
(char_literal (escape_sequence) @constant.character.escape.cpp)
@ -254,7 +254,7 @@
((comment) @punctuation.definition.comment.cpp
(#match? @comment.line.double-slash.cpp "^\\s*//")
(#set! startAndEndAroundFirstMatchOf "//"))
(#set! adjust.startAndEndAroundFirstMatchOf "//"))
; Match /* */ comments.
((comment) @comment.block.cpp
@ -262,11 +262,11 @@
((comment) @punctuation.definition.comment.begin.cpp
(#match? @punctuation.definition.comment.begin.cpp "^/\\*")
(#set! startAndEndAroundFirstMatchOf "^/\\*"))
(#set! adjust.startAndEndAroundFirstMatchOf "^/\\*"))
((comment) @punctuation.definition.comment.end.cpp
(#match? @punctuation.definition.comment.end.cpp "\\*/$")
(#set! startAndEndAroundFirstMatchOf "\\*/$"))
(#set! adjust.startAndEndAroundFirstMatchOf "\\*/$"))
; KEYWORDS
@ -369,18 +369,18 @@
(parameter_list
"(" @punctuation.definition.parameters.begin.bracket.round.cpp
")" @punctuation.definition.parameters.end.bracket.round.cpp
(#set! final true))
(#set! test.final true))
(parenthesized_expression
"(" @punctuation.definition.expression.begin.bracket.round.cpp
")" @punctuation.definition.expression.end.bracket.round.cpp
(#set! final true))
(#set! test.final true))
(if_statement
condition: (condition_clause
"(" @punctuation.definition.expression.begin.bracket.round.cpp
")" @punctuation.definition.expression.end.bracket.round.cpp
(#set! final true)))
(#set! test.final true)))
"{" @punctuation.definition.block.begin.bracket.curly.cpp
"}" @punctuation.definition.block.end.bracket.curly.cpp

View File

@ -20,13 +20,13 @@
; we might have to make this configurable somehow.
(switch_statement
body: (compound_statement "}" @match
(#set! onlyIfLast true))
(#set! matchIndentOf parent.startPosition))
(#set! test.onlyIfLast true))
(#set! indent.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))
(#set! indent.matchIndentOf parent.parent.startPosition)
(#set! indent.offsetIndent 1))
["case" "default"] @indent

View File

@ -8,15 +8,15 @@
(descendant_selector
(tag_name) @_IGNORE_
(#set! final true))
(#set! test.final true))
(ERROR
(attribute_name) @_IGNORE_
(#set! final true))
(#set! test.final true))
((ERROR
(attribute_name) @invalid.illegal)
(#set! final true))
(#set! test.final true))
; WORKAROUND:
;
@ -35,14 +35,14 @@
; Scope the entire `::after` range as one unit.
((pseudo_element_selector)
@entity.other.attribute-name.pseudo-element.css
(#set! startAt lastChild.previousSibling.startPosition)
(#set! endAt lastChild.endPosition))
(#set! adjust.startAt lastChild.previousSibling.startPosition)
(#set! adjust.endAt lastChild.endPosition))
; Claim this range and block it from being scoped as a tag name.
(pseudo_element_selector
(tag_name) @_IGNORE_
(#set! onlyIfLast true)
(#set! final true))
(#set! test.onlyIfLast true)
(#set! test.final true))
; COMMENTS
; ========
@ -51,9 +51,9 @@
; Scope the block-comment delimiters (`/*` and `*/`).
((comment) @punctuation.definition.comment.begin.css
(#set! startAndEndAroundFirstMatchOf "^/\\*"))
(#set! adjust.startAndEndAroundFirstMatchOf "^/\\*"))
((comment) @punctuation.definition.comment.end.css
(#set! startAndEndAroundFirstMatchOf "\\*/$"))
(#set! adjust.startAndEndAroundFirstMatchOf "\\*/$"))
; SELECTORS
@ -88,18 +88,18 @@
; The '.foo' in `.foo`.
((class_selector) @entity.other.attribute-name.class.css
(#set! startAt lastChild.previousSibling.startPosition))
(#set! adjust.startAt lastChild.previousSibling.startPosition))
; Pseudo-classes without arguments: the ":first-of-type" in `li:first-of-type`.
((pseudo_class_selector (class_name) (arguments) .) @entity.other.attribute-name.pseudo-class.css
(#set! startAt lastChild.previousSibling.previousSibling.startPosition)
(#set! endAt lastChild.previousSibling.endPosition)
(#set! final true))
(#set! adjust.startAt lastChild.previousSibling.previousSibling.startPosition)
(#set! adjust.endAt lastChild.previousSibling.endPosition)
(#set! test.final true))
; Pseudo-classes with arguments: the ":nth-of-type" in `li:nth-of-type(2n-1)`.
((pseudo_class_selector (class_name) .) @entity.other.attribute-name.pseudo-class.css
(#set! startAt lastChild.previousSibling.startPosition)
(#set! endAt lastChild.endPosition))
(#set! adjust.startAt lastChild.previousSibling.startPosition)
(#set! adjust.endAt lastChild.endPosition))
(arguments
"(" @punctuation.definition.arguments.begin.bracket.round.css
@ -120,7 +120,7 @@
(declaration
(property_name) @variable.other.assignment.css
(#match? @variable.other.assignment.css "^--" )
(#set! final true))
(#set! test.final true))
; PROPERTIES
; ==========
@ -146,10 +146,10 @@
(#match? @string.quoted.single.css "'$"))
((string_value) @puncutation.definition.string.begin.css
(#set! startAndEndAroundFirstMatchOf "^[\"']"))
(#set! adjust.startAndEndAroundFirstMatchOf "^[\"']"))
((string_value) @puncutation.definition.string.end.css
(#set! startAndEndAroundFirstMatchOf "[\"']$"))
(#set! adjust.startAndEndAroundFirstMatchOf "[\"']$"))
; Property value constants
@ -233,7 +233,7 @@
; The parser is permissive and supports at-rule keywords that don't currently
; exist, so we'll set a fallback scope for those.
((at_keyword) @keyword.control.at-rule.other.css
(#set! shy true))
(#set! test.shy true))
[(to) (from)] @keyword.control._TYPE_.css
(important) @keyword.control.important.css
@ -262,12 +262,12 @@
[":" "::"] @punctuation.definition.entity.css)
(":" @punctuation.separator.key-value.css
(#set! shy true))
(#set! test.shy true))
; SECTIONS
; ========
(rule_set (block) @meta.block.inside-selector.css)
((block) @meta.block.css
(#set! shy true))
(#set! test.shy true))
(selectors) @meta.selector.css

View File

@ -8,11 +8,11 @@
((comment) @comment.line.double-slash.go
(#match? @comment.line.double-slash.go "^\/\/")
(#set! final true))
(#set! test.final true))
((comment) @punctuation.definition.comment.go
(#match? @punctuation.definition.comment.go "^\/\/")
(#set! startAndEndAroundFirstMatchOf "^\/\/"))
(#set! adjust.startAndEndAroundFirstMatchOf "^\/\/"))
((comment) @comment.block.go
@ -20,11 +20,11 @@
((comment) @punctuation.definition.comment.begin.go
(#match? @punctuation.definition.comment.begin.go "^\\/\\*")
(#set! startAndEndAroundFirstMatchOf "^\\/\\*"))
(#set! adjust.startAndEndAroundFirstMatchOf "^\\/\\*"))
((comment) @punctuation.definition.comment.end.go
(#match? @punctuation.definition.comment.end.go "\\*\\/$")
(#set! startAndEndAroundFirstMatchOf "\\*\\/$"))
(#set! adjust.startAndEndAroundFirstMatchOf "\\*\\/$"))
; TYPES
@ -33,7 +33,7 @@
(type_declaration
(type_spec
name: (type_identifier) @entity.name.type.go)
(#set! final true))
(#set! test.final true))
(type_identifier) @storage.type.other.go
@ -83,7 +83,7 @@
(call_expression
(identifier) @support.function.builtin.go
(#match? @support.function.builtin.go "^(?:append|cap|close|complex|copy|delete|imag|len|make|new|panic|print|println|real|recover)$")
(#set! final true))
(#set! test.final true))
(call_expression
(identifier) @support.other.function.go)
@ -111,7 +111,7 @@
(package_clause
(package_identifier) @entity.name.package.go
(#set! final true))
(#set! test.final true))
(package_identifier) @support.object.package.go
@ -121,11 +121,11 @@
((interpreted_string_literal "\"") @string.quoted.double.go)
(interpreted_string_literal
"\"" @punctuation.definition.string.begin.go
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
(interpreted_string_literal
"\"" @punctuation.definition.string.end.go
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
(escape_sequence) @constant.character.escape.go
@ -134,10 +134,10 @@
(raw_string_literal) @string.quoted.raw.go
((raw_string_literal)
@punctuation.definition.string.begin.go
(#set! startAndEndAroundFirstMatchOf "^`"))
(#set! adjust.startAndEndAroundFirstMatchOf "^`"))
((raw_string_literal)
@punctuation.definition.string.end.go
(#set! startAndEndAroundFirstMatchOf "`$"))
(#set! adjust.startAndEndAroundFirstMatchOf "`$"))
; NUMBERS
@ -257,13 +257,13 @@
(parameter_list
"(" @punctuation.definition.parameters.begin.bracket.round.go
")" @punctuation.definition.parameters.end.bracket.round.go
(#set! final true))
(#set! test.final true))
(composite_literal
body: (literal_value
"{" @punctuation.definition.struct.begin.bracket.curly.go
"}" @punctuation.definition.struct.end.bracket.curly.go
(#set! final true)))
(#set! test.final true)))
"{" @punctuation.definition.begin.bracket.curly.go
"}" @punctuation.definition.end.bracket.curly.go
@ -277,7 +277,7 @@
(function_declaration
(block) @meta.block.function.go
(#set! final true))
(#set! test.final true))
(block) @meta.block.go

View File

@ -1,23 +1,10 @@
; (
; (comment_directive) @comment.block
; )
(comment_directive) @comment.block
(output_directive
["<%=" "%>"] @keyword.control.directive.output
)
["<%=" "%>"] @keyword.control.directive.output)
(
(directive
["<%" "<%_"] @keyword.control.directive
["_%>" "%>"] @keyword.control.directive
)
(#set! final true)
)
; (
;
; (#set! onlyIfNotChildOfType comment_directive)
; )
((directive
["<%" "<%_"] @keyword.control.directive
["_%>" "%>"] @keyword.control.directive)
(#set! test.final true))

View File

@ -1,10 +1,8 @@
(
(directive
((directive
"%>" @_IGNORE_
(#match! @_IGNORE_ "^$")
) @_IGNORE_
(#set! final true)
)
(#set! test.final true))
(comment_directive) @comment.block.erb @meta.embedded
@ -18,5 +16,3 @@
["<%="] @keyword.directive.begin.erb
["%>" "-%>"] @keyword.directive.end.erb
) @meta.embedded
; ["<%" "<%-"] @keyword.directiv

View File

@ -27,10 +27,10 @@
(comment) @comment.block.html
((comment) @punctuation.definition.comment.begin.html
(#set! startAndEndAroundFirstMatchOf "^<!--"))
(#set! adjust.startAndEndAroundFirstMatchOf "^<!--"))
((comment) @punctuation.definition.comment.end.html
(#set! startAndEndAroundFirstMatchOf "-->$"))
(#set! adjust.startAndEndAroundFirstMatchOf "-->$"))
; SUPPORT
@ -39,32 +39,32 @@
(start_tag
(tag_name) @entity.name.tag.structure._TEXT_.html
(#match? @entity.name.tag.structure._TEXT_.html "^(body|head|html|BODY|HEAD|HTML)$")
(#set! final true))
(#set! test.final true))
(end_tag
(tag_name) @entity.name.tag.structure._TEXT_.html
(#match? @entity.name.tag.structure._TEXT_.html "^(body|head|html|BODY|HEAD|HTML)$")
(#set! final true))
(#set! test.final true))
(start_tag
(tag_name) @entity.name.tag.block._TEXT_.html
(#match? @entity.name.tag.block._TEXT_.html "^(address|blockquote|dd|div|section|article|aside|header|footer|nav|menu|dl|dt|fieldset|form|frame|frameset|h1|h2|h3|h4|h5|h6|iframe|noframes|object|ol|p|ul|applet|center|dir|hr|pre|ADDRESS|BLOCKQUOTE|DD|DIV|SECTION|ARTICLE|ASIDE|HEADER|FOOTER|NAV|MENU|DL|DT|FIELDSET|FORM|FRAME|FRAMESET|H1|H2|H3|H4|H5|H6|IFRAME|NOFRAMES|OBJECT|OL|P|UL|APPLET|CENTER|DIR|HR|PRE)$")
(#set! final true))
(#set! test.final true))
(end_tag
(tag_name) @entity.name.tag.block._TEXT_.html
(#match? @entity.name.tag.block._TEXT_.html "^(address|blockquote|dd|div|section|article|aside|header|footer|nav|menu|dl|dt|fieldset|form|frame|frameset|h1|h2|h3|h4|h5|h6|iframe|noframes|object|ol|p|ul|applet|center|dir|hr|pre|ADDRESS|BLOCKQUOTE|DD|DIV|SECTION|ARTICLE|ASIDE|HEADER|FOOTER|NAV|MENU|DL|DT|FIELDSET|FORM|FRAME|FRAMESET|H1|H2|H3|H4|H5|H6|IFRAME|NOFRAMES|OBJECT|OL|P|UL|APPLET|CENTER|DIR|HR|PRE)$")
(#set! final true))
(#set! test.final true))
(start_tag
(tag_name) @entity.name.tag.inline._TEXT_.html
(#match? @entity.name.tag.inline._TEXT_.html "^(a|abbr|acronym|area|b|base|basefont|bdo|big|br|button|caption|cite|code|col|colgroup|del|dfn|em|font|head|html|i|img|input|ins|isindex|kbd|label|legend|li|link|map|meta|noscript|optgroup|option|param|q|s|samp|script|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|title|tr|tt|u|var|A|ABBR|ACRONYM|AREA|B|BASE|BASEFONT|BDO|BIG|BR|BUTTON|CAPTION|CITE|CODE|COL|COLGROUP|DEL|DFN|EM|FONT|HEAD|HTML|I|IMG|INPUT|INS|ISINDEX|KBD|LABEL|LEGEND|LI|LINK|MAP|META|NOSCRIPT|OPTGROUP|OPTION|PARAM|Q|S|SAMP|SCRIPT|SELECT|SMALL|SPAN|STRIKE|STRONG|STYLE|SUB|SUP|TABLE|TBODY|TD|TEXTAREA|TFOOT|TH|THEAD|TITLE|TR|TT|U|VAR)$")
(#set! final true))
(#set! test.final true))
(end_tag
(tag_name) @entity.name.tag.inline._TEXT_.html
(#match? @entity.name.tag.inline._TEXT_.html "^(a|abbr|acronym|area|b|base|basefont|bdo|big|br|button|caption|cite|code|col|colgroup|del|dfn|em|font|head|html|i|img|input|ins|isindex|kbd|label|legend|li|link|map|meta|noscript|optgroup|option|param|q|s|samp|script|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|title|tr|tt|u|var|A|ABBR|ACRONYM|AREA|B|BASE|BASEFONT|BDO|BIG|BR|BUTTON|CAPTION|CITE|CODE|COL|COLGROUP|DEL|DFN|EM|FONT|HEAD|HTML|I|IMG|INPUT|INS|ISINDEX|KBD|LABEL|LEGEND|LI|LINK|MAP|META|NOSCRIPT|OPTGROUP|OPTION|PARAM|Q|S|SAMP|SCRIPT|SELECT|SMALL|SPAN|STRIKE|STRONG|STYLE|SUB|SUP|TABLE|TBODY|TD|TEXTAREA|TFOOT|TH|THEAD|TITLE|TR|TT|U|VAR)$")
(#set! final true))
(#set! test.final true))
; ELEMENTS
@ -109,10 +109,10 @@
; Single- and double-quotes around attribute values.
((quoted_attribute_value ["\"" "'"] @punctuation.definition.string.begin.html)
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
((quoted_attribute_value ["\"" "'"] @punctuation.definition.string.end.html)
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
; If this matches, the value is double-quoted.
(quoted_attribute_value "\"") @string.quoted.double.html
@ -123,7 +123,7 @@
; Prevent quoted attribute values from having `string.unquoted` applied.
(quoted_attribute_value
(attribute_value) @_IGNORE_
(#set! final true))
(#set! test.final true))
; The "foo" in `<div class=foo>`.
; Because of the preceding rule, if this matches and passes all tests, the

View File

@ -6,31 +6,25 @@
((comment) @punctuation.definition.comment.java
(#match? @punctuation.definition.comment.java "^//")
(#set! startAndEndAroundFirstMatchOf "^//"))
(#set! adjust.startAndEndAroundFirstMatchOf "^//"))
((comment) @comment.block.documentation.javadoc.java
(#match? @comment.block.documentation.javadoc.java "^/\\*\\*")
(#set! final true)
(#set! invalidateOnChange true))
; ((comment) @punctuation.definition.comment.begin.java
; (#match? @punctuation.definition.comment.begin.java "^/\\*\\*")
; (#set! startAndEndAroundFirstMatchOf "^/\\*\\*")
; (#set! final true))
(#set! test.final true)
(#set! highlight.invalidateOnChange true))
((comment) @comment.block.java
(#match? @comment.block.java "^/\\*")
(#set! invalidateOnChange true))
(#set! highlight.invalidateOnChange true))
((comment) @punctuation.definition.comment.begin.java
(#match? @punctuation.definition.comment.begin.java "^/\\*")
(#set! startAndEndAroundFirstMatchOf "^/\\*"))
(#match? @punctuation.definition.comment.begin.java "^/\\*\\*?")
(#set! adjust.startAndEndAroundFirstMatchOf "^/\\*"))
((comment) @punctuation.definition.comment.end.java
(#match? @punctuation.definition.comment.end.java "\\*/$")
(#set! startAndEndAroundFirstMatchOf "\\*/$"))
(#set! adjust.startAndEndAroundFirstMatchOf "\\*/$"))
; OBJECTS
; =======
@ -42,7 +36,7 @@
(superclass
"extends" @storage.modifier.extends.java
(type_identifier) @entity.other.inherited-class.java
(#set! final true))
(#set! test.final true))
(class_declaration body: (_) @meta.class.body.java)
@ -71,14 +65,14 @@
(extends_interfaces
(interface_type_list
(type_identifier) @entity.other.inherited-class.java)
(#set! final true))
(#set! test.final true))
(super_interfaces "implements" @storage.modifier.implements.java)
(super_interfaces
(interface_type_list
(type_identifier) @entity.other.inherited-class.java)
(#set! final true))
(#set! test.final true))
(static_initializer "static" @storage.modifier.static.java)
@ -91,14 +85,14 @@
; Cover both the '@' and the 'Foo' in `@Foo`.
((marker_annotation) @storage.type.annotation.java @support.type.annotation.java
(#set! endAt firstChild.nextSibling.endPosition))
(#set! adjust.endAt firstChild.nextSibling.endPosition))
(annotation
"@" @punctuation.definition.annotation.java) @meta.declaration.annotation.java
; Cover both the '@' and the 'Foo' in `@Foo`.
((annotation) @storage.type.annotation.java @support.type.annotation.java
(#set! endAt firstChild.nextSibling.endPosition))
(#set! adjust.endAt firstChild.nextSibling.endPosition))
(element_value_pair key: (_) @variable.other.annotation.element.java)
@ -107,21 +101,21 @@
(object_creation_expression (type_identifier)
@support.other.class.java
(#set! final true))
(#set! test.final true))
; WORKAROUND: This matches often when the user is typing, so we shouldn't
; highlight it until we know for sure what it is.
(ERROR
(type_identifier) @_IGNORE_
(#set! final true))
(#set! test.final true))
; WORKAROUND: A chain like `System.out.println` shouldn't match at all until
; it's out of an ERROR state; this should catch all references no matter how
; long the chain is.
(scoped_type_identifier
(type_identifier) @_IGNORE
(#set! onlyIfDescendantOfType ERROR)
(#set! final true))
(#set! test.onlyIfDescendantOfType ERROR)
(#set! test.final true))
(type_identifier) @storage.type.java
(type_parameter (identifier) @storage.type.java)
@ -188,22 +182,22 @@
(field_access (identifier) @constant.other.java
(#match? @constant.other.java "^[A-Z][A-Z0-9_\\$]+$")
(#set! final true))
(#set! test.final true))
(field_access
object: (identifier) @support.other.class.java
(#match? @support.other.class.java "^[A-Z]")
(#set! final true))
(#set! test.final true))
(field_access
field: (identifier) @support.other.class.java
(#match? @support.other.class.java "^[A-Z]")
(#set! final true))
(#set! test.final true))
(method_invocation (identifier) @constant.other.java
(#match? @constant.other.java "^[A-Z][A-Z0-9_\\$]+$")
(#set! final true))
(#set! test.final true))
; VARIABLES
@ -248,17 +242,17 @@
(character_literal) @string.quoted.single.java
((character_literal) @punctuation.definition.string.begin.java
(#set! startAndEndAroundFirstMatchOf "^'"))
(#set! adjust.startAndEndAroundFirstMatchOf "^'"))
((character_literal) @punctuation.definition.string.end.java
(#set! startAndEndAroundFirstMatchOf "'$"))
(#set! adjust.startAndEndAroundFirstMatchOf "'$"))
(string_literal) @string.quoted.double.java
((string_literal) @punctuation.definition.string.begin.java
(#set! startAndEndAroundFirstMatchOf "^\""))
(#set! adjust.startAndEndAroundFirstMatchOf "^\""))
((string_literal) @punctuation.definition.string.end.java
(#set! startAndEndAroundFirstMatchOf "\"$"))
(#set! adjust.startAndEndAroundFirstMatchOf "\"$"))
; CAVEAT: Parser doesn't recognize escape sequences in strings.
@ -380,17 +374,17 @@
condition: (parenthesized_expression
"(" @punctuation.definition.expression.begin.bracket.round.java
")" @punctuation.definition.expression.end.bracket.round.java
(#set! final true)))
(#set! test.final true)))
(formal_parameters
"(" @punctuation.definition.parameters.begin.bracket.round.java
")" @punctuation.definition.parameters.end.bracket.round.java
(#set! final true))
(#set! test.final true))
(argument_list
"(" @punctuation.definition.arguments.begin.bracket.round.java
")" @punctuation.definition.arguments.end.bracket.round.java
(#set! final true))
(#set! test.final true))
"{" @punctuation.definition.block.begin.bracket.curly.java

View File

@ -1,14 +1,14 @@
; The closing brace of a switch statement's body should match the indentation of the line where the switch statement starts.
(switch_statement
body: (switch_block "}" @match
(#set! onlyIfLast true))
(#set! matchIndentOf parent.parent.startPosition))
(#set! test.onlyIfLast true))
(#set! indent.matchIndentOf parent.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))
(#set! indent.matchIndentOf parent.parent.startPosition)
(#set! indent.offsetIndent 1))
[
"{"

View File

@ -9,7 +9,7 @@
] @fold
((arguments) @fold
(#set! adjustToEndOfPreviousRow true))
(#set! fold.adjustToEndOfPreviousRow true))
; When we've got
@ -24,15 +24,15 @@
; fold doesn't interfere with our ability to collapse the `else` fold.
((if_statement
consequence: (statement_block) @fold)
(#set! adjustToEndOfPreviousRow true))
(#set! fold.adjustToEndOfPreviousRow true))
(else_clause (statement_block) @fold)
(statement_block) @fold
((comment) @fold
(#set! endAt endPosition)
(#set! adjustEndColumn 0))
(#set! fold.endAt endPosition)
(#set! fold.adjustEndColumn 0))
; When you have…
@ -48,8 +48,8 @@
;
(jsx_element
(jsx_opening_element ">" @fold)
(#set! endAt parent.parent.lastChild.startPosition)
(#set! adjustToEndOfPreviousRow true)
(#set! fold.endAt parent.parent.lastChild.startPosition)
(#set! fold.adjustToEndOfPreviousRow true)
)
; When you have…
@ -66,8 +66,8 @@
;
(jsx_element
(jsx_opening_element) @fold
(#set! endAt lastChild.previousSibling.endPosition))
(#set! fold.endAt lastChild.previousSibling.endPosition))
((jsx_self_closing_element) @fold
; Exclude both the slash and angle bracket `/>` from the fold.
(#set! endAt lastChild.previousSibling.startPosition))
(#set! fold.endAt lastChild.previousSibling.startPosition))

View File

@ -7,33 +7,33 @@
(string
"'" @punctuation.definition.string.begin.js
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
(string
"'" @punctuation.definition.string.end.js
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
; Double-quoted.
(string "\"") @string.quoted.double.js
(string
"\"" @punctuation.definition.string.begin.js
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
(string
"\"" @punctuation.definition.string.end.js
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
; Template string (backticks).
(template_string) @string.quoted.template.js
(template_string
"`" @punctuation.definition.string.begin.js
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
(template_string
"`" @punctuation.definition.string.end.js
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
; Interpolations inside of template strings.
(template_substitution
@ -140,7 +140,7 @@
(pair_pattern
key: (_) @entity.other.attribute-name.js
value: (identifier) @variable.other.assignment.loop.js)
(#set! final true)))
(#set! test.final true)))
; The "error" in `} catch (error) {`
(catch_clause
@ -219,7 +219,7 @@
(assignment_expression
left: (member_expression
property: (property_identifier) @entity.name.function.definition.js
(#set! final true))
(#set! test.final true))
right: [(arrow_function) (function)])
; Function variable assignment:
@ -260,7 +260,7 @@
(#eq? @support.object.builtin.js "Array")
property: (property_identifier) @support.function.builtin.js
(#match? @support.function.builtin.js "^(from|isArray|of)$")
(#set! final true))
(#set! test.final true))
; Date methods.
(member_expression
@ -268,7 +268,7 @@
(#eq? @support.object.builtin.js "Date")
property: (property_identifier) @support.function.builtin.js
(#match? @support.function.builtin.js "^(now|parse|UTC)$")
(#set! final true))
(#set! test.final true))
; JSON methods.
(member_expression
@ -276,7 +276,7 @@
(#eq? @support.object.builtin.js "JSON")
property: (property_identifier) @support.function.builtin.js
(#match? @support.function.builtin.js "^(parse|stringify)$")
(#set! final true))
(#set! test.final true))
; Math methods.
(member_expression
@ -284,7 +284,7 @@
(#eq? @support.object.builtin.js "Math")
property: (property_identifier) @support.function.builtin.js
(#match? @support.function.builtin.js "^(abs|acos|acosh|asin|asinh|atan|atanh|atan2|cbrt|ceil|clz32|cos|cosh|exp|expm1|floor|fround|hypot|imul|log|log1p|log10|log2|max|min|pow|random|round|sign|sin|sinh|sqrt|tan|tanh|trunc)$")
(#set! final true))
(#set! test.final true))
; Object methods.
(member_expression
@ -292,7 +292,7 @@
(#eq? @support.object.builtin.js "Object")
property: (property_identifier) @support.function.builtin.js
(#match? @support.function.builtin.js "^(assign|create|defineProperty|defineProperties|entries|freeze|fromEntries|getOwnPropertyDescriptor|getOwnPropertyDescriptors|getOwnPropertyNames|getOwnPropertySymbols|getPrototypeOf|is|isExtensible|isFrozen|isSealed|keys|preventExtensions|seal|setPrototypeOf|values)$")
(#set! final true))
(#set! test.final true))
; Reflect methods.
(member_expression
@ -300,7 +300,7 @@
(#eq? @support.object.builtin.js "Reflect")
property: (property_identifier) @support.function.builtin.js
(#match? @support.function.builtin.js "^(apply|construct|defineProperty|deleteProperty|get|getOwnPropertyDescriptor|getPrototypeOf|has|isExtensible|ownKeys|preventExtensions|set|setPrototypeOf)$")
(#set! final true))
(#set! test.final true))
; Intl.X instantiations.
(new_expression
@ -309,25 +309,25 @@
(#eq? @support.object.builtin.js "Intl")
property: (property_identifier) @support.class.builtin.js
(#match? @support.class.builtin.js "^(Collator|DateTimeFormat|DisplayNames|ListFormat|Locale|NumberFormat|PluralRules|Segmenter)$"))
(#set! final true))
(#set! test.final true))
; Built-in class instantiations.
(new_expression
constructor: (identifier) @support.class.builtin.instance.js
(#match? @support.class.builtin.instance.js "^(AggregateError|Array|ArrayBuffer|BigInt64Array|BigUint64Array|Boolean|DataView|Date|Error|EvalError|FinalizationRegistry|Float32Array|Float64Array|Function|ImageCapture|Int8Array|Int16Array|Int32Array|Map|Number|Object|Promise|RangeError|ReferenceError|RegExp|Set|String|SyntaxError|TypeError|Uint8Array|Uint8ClampedArray|Uint16Array|Uint32Array|URIError|URL|WeakMap|WeakRef|WeakSet|XMLHttpRequest)$")
(#set! final true))
(#set! test.final true))
; Built-in constructors that can be invoked without `new`.
(call_expression
(identifier) @support.function.builtin.js
(#match? @support.function.builtin.js "^(AggregateError|Array|ArrayBuffer|Boolean|BigInt|Error|EvalError|Function|Number|Object|Proxy|RangeError|String|Symbol|SyntaxError|URIError)$")
(#set! final true))
(#set! test.final true))
; Built-in functions.
(call_expression
(identifier) @support.function.builtin.js
(#match? @support.function.builtin.js "^(decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt)$")
(#set! final true))
(#set! test.final true))
; Built-in `console` functions.
@ -336,7 +336,7 @@
(#eq? @support.class.builtin.console.js "console")
property: (property_identifier) @support.function.builtin.console.js
(#match? @support.function.builtin.console.js "^(assert|clear|count(Reset)?|debug|dir(xml)?|error|group(End)?info|log|profile(End)?|table|time(End|Log|Stamp)?|trace|warn)$")
(#set! final true))
(#set! test.final true))
; Static methods of `Promise`.
(member_expression
@ -344,7 +344,7 @@
(#eq? @support.class.builtin.js "Promise")
property: (property_identifier) @support.function.builtin.js
(#match? @support.function.builtin.js "^(all|allSettled|any|race|resolve|reject)$")
(#set! final true))
(#set! test.final true))
; All “well-known” symbols (as they are referred to in the spec).
(member_expression
@ -352,7 +352,7 @@
property: (property_identifier) @support.property.builtin.js
(#eq? @support.class.builtin.js "Symbol")
(#match? @support.property.builtin.js "^(asyncIterator|hasInstance|isConcatSpreadable|iterator|match|matchAll|replace|search|split|species|toPrimitive|toStringTag|unscopables)$")
(#set! final true))
(#set! test.final true))
; Static methods of `Symbol`.
(member_expression
@ -360,28 +360,28 @@
(#eq? @support.class.builtin.js "Symbol")
property: (property_identifier) @support.function.builtin.js
(#match? @support.function.builtin.js "^(for|keyFor)$")
(#set! final true))
(#set! test.final true))
; Other built-in objects.
((identifier) @support.class.builtin.js
(#match? @support.class.builtin.js "^(Symbol)$")
(#set! final true))
(#set! test.final true))
; Deprecated built-in functions.
(call_expression
(identifier) @invalid.deprecated.function.js
(#match? @invalid.deprecated.function.js "^(escape|unescape)$")
(#set! final true))
(#set! test.final true))
; Built-in DOM classes.
((identifier) @support.class.builtin.js
(#match? @support.class.builtin.js "^(Document|Element|HTMLElement|HTMLDocument|HTML(Select|BR|HR|LI|Div|Map|Mod|Pre|Area|Base|Body|Data|Font|Form|Head|Html|Link|Menu|Meta|Slot|Span|Time|Audio|DList|Embed|Image|Input|Label|Media|Meter|OList|Param|Quote|Style|Table|Title|Track|UList|Video|Anchor|Button|Canvas|Dialog|IFrame|Legend|Object|Option|Output|Script|Source|Content|Details|Heading|Marquee|Picture|Unknown|DataList|FieldSet|FrameSet|MenuItem|OptGroup|Progress|TableCol|TableRow|Template|TextArea|Paragraph|TableCell|Options|TableCaption|TableSection|FormControls))$")
(#set! final true))
(#set! test.final true))
; Deprecated built-in DOM classes.
((identifier) @invalid.deprecated.class.js
(#match? @invalid.deprecated.class.js "^(HTMLShadowElement)$")
(#set! final true))
(#set! test.final true))
; Built-in DOM methods on `document`.
(call_expression
@ -390,7 +390,7 @@
(#eq? @support.object.builtin.js "document")
property: (property_identifier) @support.function.method.builtin.js
(#match? @support.function.method.builtin.js "^(adoptNode|append|caretPositionFromPoint|caretRangeFromPoint|createAttribute(?:NS)?|createCDATASection|createComment|createDocumentFragment|createElement(?:NS)?|createEvent|createNodeIterator|createProcessingInstruction|createRange|createTextNode|createTreeWalker|elementFromPoint|elementsFromPoint|exitFullscreen|exitPictureInPicture|exitPointerLock|getAnimations|getElementById|getElementsByClassName|getElementsByTagName(?:NS)?|getSelection|hasStorageAccess|importNode|prepend|querySelector|querySelectorAll|releaseCapture|replaceChildren|requestStorageAccess|createExpression|createNSResolver|evaluate|getElementsByName|hasFocus|write|writeln|open|close)$")
(#set! final true)))
(#set! test.final true)))
; Built-in DOM methods on nodes. These will show up as builtins on _any_ class, but
; they're distinctive enough that we're OK with that possibility.
@ -398,7 +398,7 @@
function: (member_expression
property: (property_identifier) @support.function.method.builtin.js
(#match? @support.function.method.builtin.js "^(addEventListener|appendChild|cloneNode|compareDocumentPosition|contains|getElementsByClassName|getElementsByTagName(?:NS)?|getRootNode|hasChildNodes|insertBefore|isDefaultNamespace|isEqualNode|isSameNode|lookupPrefix|lookupNamespaceURI|normalize|querySelector|querySelectorAll|removeChild|replaceChild|removeEventListener)$")
(#set! final true)))
(#set! test.final true)))
; FUNCTION CALLS
@ -412,7 +412,7 @@
(call_expression
function: (member_expression
property: (property_identifier) @support.other.function.method.js
(#set! final true)))
(#set! test.final true)))
; OBJECTS
@ -523,7 +523,7 @@
((comment) @punctuation.definition.comment.js
(#match? @punctuation.definition.comment.js "^\/\/")
(#set! startAndEndAroundFirstMatchOf "^\/\/"))
(#set! adjust.startAndEndAroundFirstMatchOf "^\/\/"))
; Block comments. `/* */`
((comment) @comment.block.js
@ -532,15 +532,15 @@
((comment) @punctuation.definition.comment.begin.js
(#match? @punctuation.definition.comment.begin.js "^/\\*")
(#set! startAndEndAroundFirstMatchOf "^/\\*"))
(#set! adjust.startAndEndAroundFirstMatchOf "^/\\*"))
((comment) @punctuation.definition.comment.end.js
(#match? @punctuation.definition.comment.end.js "\\*/$")
(#set! startAndEndAroundFirstMatchOf "\\*/$"))
(#set! adjust.startAndEndAroundFirstMatchOf "\\*/$"))
(hash_bang_line) @comment.line.shebang.js
((hash_bang_line) @punctuation.definition.comment.js
(#set! endAfterFirstMatchOf "^#!"))
(#set! adjust.endAfterFirstMatchOf "^#!"))
; KEYWORDS
@ -611,23 +611,23 @@
((identifier) @support.object.builtin._TEXT_.js
(#match? @support.object.builtin._TEXT_.js "^(arguments|module|window|document)$")
(#is-not? local)
(#set! final true))
(#set! test.final true))
((identifier) @support.object.builtin.filename.js
(#eq? @support.object.builtin.filename.js "__filename")
(#is-not? local)
(#set! final true))
(#set! test.final true))
((identifier) @support.object.builtin.dirname.js
(#eq? @support.object.builtin.dirname.js "__dirname")
(#is-not? local)
(#set! final true))
(#set! test.final true))
((identifier) @support.function.builtin.require.js
(#eq? @support.function.builtin.require.js "require")
(#is-not? local)
(#set! final true))
(#set! test.final true))
[
(null)
@ -641,7 +641,7 @@
((identifier) @constant.language.infinity.js
(#eq? @constant.language.infinity.js "Infinity")
(#set! final true))
(#set! test.final true))
(arrow_function
"=>" @punctuation.function.arrow.js)
@ -649,7 +649,7 @@
; Things that `LOOK_LIKE_CONSTANTS`.
([(property_identifier) (identifier)] @constant.other.js
(#match? @constant.other.js "^[A-Z_][A-Z0-9_]*$")
(#set! shy true))
(#set! test.shy true))
; TODO: What do we do with computed object keys?
;
@ -673,11 +673,11 @@
(regex) @string.regexp.js
(regex
"/" @punctuation.definition.string.begin.js
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
(regex
"/" @punctuation.definition.string.end.js
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
(regex_flags) @keyword.other.js
@ -697,7 +697,7 @@
; The "Foo" in `</Foo>`.
(jsx_closing_element
"/" @punctuation.definition.tag.end.js
(#set! final true)
(#set! test.final true)
name: (identifier) @entity.name.tag.js)
; The "bar" in `<Foo bar={true} />`.
@ -707,7 +707,7 @@
; All JSX expressions/interpolations within braces.
((jsx_expression) @meta.embedded.block.jsx.js
(#match? @meta.embedded.block.jsx.js "\\n")
(#set! final true))
(#set! test.final true))
(jsx_expression) @meta.embedded.line.jsx.js
@ -721,14 +721,14 @@
(jsx_self_closing_element
"<" @punctuation.definition.tag.begin.js
(#set! final true))
(#set! test.final true))
((jsx_self_closing_element
; The "/>" in `<Foo />`, extended to cover both anonymous nodes at once.
"/") @punctuation.definition.tag.end.js
(#set! startAt lastChild.previousSibling.startPosition)
(#set! endAt lastChild.endPosition)
(#set! final true))
(#set! adjust.startAt lastChild.previousSibling.startPosition)
(#set! adjust.endAt lastChild.endPosition)
(#set! test.final true))
; OPERATORS
@ -800,7 +800,7 @@
(#set! prohibitsOptionalChaining true))
((optional_chain) @invalid.illegal.optional-chain.js
(#set! onlyIfDescendantOfNodeWithData prohibitsOptionalChaining))
(#set! test.onlyIfDescendantOfNodeWithData prohibitsOptionalChaining))
; PUNCTUATION
@ -809,37 +809,37 @@
(formal_parameters
"(" @punctuation.definition.parameters.begin.bracket.round.js
")"@punctuation.definition.parameters.end.bracket.round.js
(#set! final true))
(#set! test.final true))
(object
"{" @punctuation.definition.object.begin.bracket.curly.js
"}" @punctuation.definition.object.end.bracket.curly.js
(#set! final true))
(#set! test.final true))
(arguments
"(" @punctuation.definition.arguments.begin.bracket.round.js
")" @punctuation.definition.arguments.end.bracket.round.js
(#set! final true))
(#set! test.final true))
(computed_property_name
"[" @punctuation.definition.computed-property.begin.bracket.square.js
"]" @punctuation.definition.computed-property.end.bracket.square.js
(#set! final true))
(#set! test.final true))
(subscript_expression
"[" @punctuation.definition.subscript.begin.bracket.square.js
"]" @punctuation.definition.subscript.end.bracket.square.js
(#set! final true))
(#set! test.final true))
(array
"[" @punctuation.definition.array.begin.bracket.square.js
"]" @punctuation.definition.array.end.bracket.square.js
(#set! final true))
(#set! test.final true))
(array_pattern
"[" @punctuation.definition.array.begin.bracket.square.js
"]" @punctuation.definition.array.end.bracket.square.js
(#set! final true))
(#set! test.final true))
"{" @punctuation.definition.block.begin.bracket.curly.js
"}" @punctuation.definition.block.end.bracket.curly.js
@ -850,15 +850,15 @@
(array
"," @punctuation.separator.array.comma.js
(#set! final true))
(#set! test.final true))
(array_pattern
"," @punctuation.separator.array.comma.js
(#set! final true))
(#set! test.final true))
(pair
":" @punctuation.separator.key-value.colon.js
(#set! final true))
(#set! test.final true))
";" @punctuation.terminator.statement.js
"," @punctuation.separator.comma.js
@ -870,23 +870,23 @@
; The interiors of functions (useful for snippets and commands).
(method_definition
body: (statement_block) @meta.block.function.js
(#set! final true))
(#set! test.final true))
(function_declaration
body: (statement_block) @meta.block.function.js
(#set! final true))
(#set! test.final true))
(generator_function_declaration
body: (statement_block) @meta.block.function.js
(#set! final true))
(#set! test.final true))
(function
body: (statement_block) @meta.block.function.js
(#set! final true))
(#set! test.final true))
(generator_function
body: (statement_block) @meta.block.function.js
(#set! final true))
(#set! test.final true))
; The interior of a class body (useful for snippets and commands).
(class_body) @meta.block.class.js
@ -896,13 +896,13 @@
; The inside of a parameter definition list.
((formal_parameters) @meta.parameters.js
(#set! startAt firstChild.endPosition)
(#set! endAt lastChild.startPosition))
(#set! adjust.startAt firstChild.endPosition)
(#set! adjust.endAt lastChild.startPosition))
; The inside of an object literal.
((object) @meta.object.js
(#set! startAt firstChild.endPosition)
(#set! endAt lastChild.startPosition))
(#set! adjust.startAt firstChild.endPosition)
(#set! adjust.endAt lastChild.startPosition))
; MISC
@ -933,4 +933,4 @@
; TODO: Any identifier not yet scoped might as well be scoped as a variable,
; but that's an opinionated choice. We might want to make this configurable.
; ((identifier) @variable.other.other.js
; (#set! shy true))
; (#set! test.shy true))

View File

@ -1,10 +1,13 @@
; ((template_string) @ignore
; (#set! test.onlyIfNotOnStartingOrEndingRow true))
; STATEMENT BLOCKS
; ================
; More accurate indentation matching for all blocks delimited by braces.
(statement_block "}" @match
(#set! matchIndentOf parent.firstChild.startPosition))
(#set! indent.matchIndentOf parent.firstChild.startPosition))
; SWITCH STATEMENTS
@ -14,14 +17,14 @@
; of the line where the switch statement starts.
(switch_statement
body: (switch_body "}" @match
(#set! onlyIfLast true))
(#set! matchIndentOf parent.startPosition))
(#set! test.onlyIfLast true))
(#set! indent.matchIndentOf parent.startPosition))
; 'case' and 'default' need to be indented one level more than their containing
; `switch`. TODO: Might need to make this configurable.
(["case" "default"] @match
(#set! matchIndentOf parent.parent.startPosition)
(#set! offsetIndent 1))
(#set! indent.matchIndentOf parent.parent.startPosition)
(#set! indent.offsetIndent 1))
; ONE-LINE CONDITIONALS
@ -30,18 +33,18 @@
; An `if` statement without an opening brace should indent the next line…
(if_statement
condition: (parenthesized_expression ")" @indent
(#set! onlyIfLastTextOnRow true)))
(#set! test.onlyIfLastTextOnRow true)))
; (as should a braceless `else`…)
("else" @indent
(#set! onlyIfLastTextOnRow true))
(#set! test.onlyIfLastTextOnRow true))
; …and keep that indent level if the user types a comment before the
; consequence…
(if_statement
consequence: (empty_statement) @match
(#set! onlyIfNotStartsOnSameRowAs parent.startPosition)
(#set! matchIndentOf parent.startPosition)
(#set! offsetIndent 1))
(#set! test.onlyIfNotStartsOnSameRowAs parent.startPosition)
(#set! indent.matchIndentOf parent.startPosition)
(#set! indent.offsetIndent 1))
; …and keep that indent level after the user starts typing…
(if_statement
@ -57,8 +60,8 @@
; When an opening curly brace is unpaired, it might get interpreted as part
; of an `expression_statement`, for some reason.
(#not-match? @match "^\\s*{")
(#set! matchIndentOf parent.startPosition)
(#set! offsetIndent 1))
(#set! indent.matchIndentOf parent.startPosition)
(#set! indent.offsetIndent 1))
; …but dedent after exactly one statement.
(if_statement
@ -84,7 +87,7 @@
(throw_statement)
(debugger_statement)
] @dedent.next
(#set! onlyIfNotStartsOnSameRowAs parent.startPosition))
(#set! test.onlyIfNotStartsOnSameRowAs parent.startPosition))
; HANGING INDENT ON SPLIT LINES
@ -95,13 +98,13 @@
; Any of these at the end of a line indicate the next line should be indented…
(["||" "&&" "?"] @indent
(#set! onlyIfLastTextOnRow true))
(#set! test.onlyIfLastTextOnRow true))
; …and the line after that should be dedented.
(binary_expression
["||" "&&"]
right: (_) @dedent.next
(#set! onlyIfNotStartsOnSameRowAs parent.startPosition))
(#set! test.onlyIfNotStartsOnSameRowAs parent.startPosition))
; let foo = this.longTernaryCondition() ?
; consequenceWhichIsItselfRatherLong :
@ -110,14 +113,27 @@
; …followed by a dedent.
(ternary_expression
alternative: (_) @dedent.next
(#set! onlyIfNotStartsOnSameRowAs parent.startPosition))
(#set! test.onlyIfNotStartsOnSameRowAs parent.startPosition))
; DEDENT-NEXT IN LIMITED SCENARIOS
; ================================
; Catches unusual hanging-indent scenarios when calling a method, such as:
;
; return this.veryLongMethodNameWithSeveralArgumentsThat(are, too,
; short, forEach, toHave, itsOwn, line);
;
; (arguments ")" @dedent.next
; (#set! test.onlyIfNotStartsOnSameRowAs parent.firstChild.startPosition)
; (#set! test.onlyIfNotFirstTextOnRow true))
; GENERAL
; =======
; Weed out `}`s that should not signal dedents.
(template_substitution "}" @_IGNORE_ (#set! final true))
(template_substitution "}" @_IGNORE_ (#set! test.final true))
[
"{"

View File

@ -1,31 +1,31 @@
; Highlight this comment even if it's not “valid” JSDoc.
((ERROR) @comment.block.documentation.js.jsdoc
(#set! onlyIfRoot true))
(#set! test.onlyIfRoot true))
((ERROR) @punctuation.definition.begin.comment.js.jsdoc
(#set! onlyIfRoot true)
(#set! startAndEndAroundFirstMatchOf "^/\\*\\*"))
(#set! test.onlyIfRoot true)
(#set! adjust.startAndEndAroundFirstMatchOf "^/\\*\\*"))
((ERROR) @punctuation.definition.end.comment.js.jsdoc
(#set! onlyIfRoot true)
(#set! startAndEndAroundFirstMatchOf "(?:\\*)?\\*/$"))
(#set! test.onlyIfRoot true)
(#set! adjust.startAndEndAroundFirstMatchOf "(?:\\*)?\\*/$"))
(document) @comment.block.documentation.js.jsdoc
((document) @punctuation.definition.begin.comment.js.jsdoc
(#set! startAndEndAroundFirstMatchOf "^/\\*\\*"))
(#set! adjust.startAndEndAroundFirstMatchOf "^/\\*\\*"))
((document) @punctuation.definition.end.comment.js.jsdoc
(#set! startAndEndAroundFirstMatchOf "(?:\\*)?\\*/$"))
(#set! adjust.startAndEndAroundFirstMatchOf "(?:\\*)?\\*/$"))
(tag_name) @storage.type.class.jsdoc
((tag (type)) @entity.other.type.instance.jsdoc
; Join the type with its surrounding braces.
(#set! startAt firstChild.nextSibling.startPosition)
(#set! endAt firstChild.nextSibling.nextSibling.nextSibling.endPosition))
(#set! adjust.startAt firstChild.nextSibling.startPosition)
(#set! adjust.endAt firstChild.nextSibling.nextSibling.nextSibling.endPosition))
"{" @punctuation.definition.begin.bracket.curly.jsdoc
"}" @punctuation.definition.end.bracket.curly.jsdoc

View File

@ -27,18 +27,18 @@
] @keyword.operator.quantifier.regexp
((lookahead_assertion) @keyword.operator.lookahead.regexp
(#set! startAndEndAroundFirstMatchOf "\\?="))
(#set! adjust.startAndEndAroundFirstMatchOf "\\?="))
((lookahead_assertion) @keyword.operator.lookahead.negated.regexp
(#set! startAndEndAroundFirstMatchOf "\\?!"))
(#set! adjust.startAndEndAroundFirstMatchOf "\\?!"))
((non_capturing_group) @keyword.operator.group.non-capturing.regexp
(#set! startAndEndAroundFirstMatchOf "\\?:"))
(#set! adjust.startAndEndAroundFirstMatchOf "\\?:"))
(anonymous_capturing_group
"(" @punctuation.definition.group.begin.bracket.round.regexp
")" @punctuation.definition.group.end.bracket.round.regexp
(#set! final true))
(#set! test.final true))
"|" @keyword.operator.or.regexp
["*" "+"] @keyword.operator.quantifier.regexp

View File

@ -3,11 +3,11 @@
(string
"\"" @punctuation.definition.string.begin.json
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
(string
"\"" @punctuation.definition.string.end.json
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
(string) @string.quoted.double.json
@ -33,11 +33,11 @@
(object
"," @punctuation.separator.object.comma.json
(#set! final true))
(#set! test.final true))
(array
"," @punctuation.separator.array.comma.json
(#set! final true))
(#set! test.final true))
"," @punctuation.separator.comma.json
":" @punctuation.separator.key-value.colon.json

View File

@ -22,14 +22,14 @@
((identifier) @support.type.exception.python
(#match? @support.type.exception.python "^(BaseException|Exception|TypeError|StopAsyncIteration|StopIteration|ImportError|ModuleNotFoundError|OSError|ConnectionError|BrokenPipeError|ConnectionAbortedError|ConnectionRefusedError|ConnectionResetError|BlockingIOError|ChildProcessError|FileExistsError|FileNotFoundError|IsADirectoryError|NotADirectoryError|InterruptedError|PermissionError|ProcessLookupError|TimeoutError|EOFError|RuntimeError|RecursionError|NotImplementedError|NameError|UnboundLocalError|AttributeError|SyntaxError|IndentationError|TabError|LookupError|IndexError|KeyError|ValueError|UnicodeError|UnicodeEncodeError|UnicodeDecodeError|UnicodeTranslateError|AssertionError|ArithmeticError|FloatingPointError|OverflowError|ZeroDivisionError|SystemError|ReferenceError|BufferError|MemoryError|Warning|UserWarning|DeprecationWarning|PendingDeprecationWarning|SyntaxWarning|RuntimeWarning|FutureWarning|ImportWarning|UnicodeWarning|BytesWarning|ResourceWarning|GeneratorExit|SystemExit|KeyboardInterrupt)$")
(#set! final true))
(#set! test.final true))
; These methods have magic interpretation by python and are generally called
; indirectly through syntactic constructs.
((identifier) @support.function.magic.python
(#match? @support.function.magic.python "^__(abs|add|and|bool|bytes|call|cmp|coerce|complex|contains|del|delattr|delete|delitem|delslice|dir|div|divmod|enter|eq|exit|float|floordiv|format|ge|get|getattr|getattribute|getitem|getslice|gt|hash|hex|iadd|iand|idiv|ifloordiv|ilshift|imatmul|imod|imul|index|init|instancecheck|int|invert|ior|ipow|irshift|isub|iter|itruediv|ixor|le|len|length_hint|long|lshift|lt|matmul|missing|mod|mul|ne|neg|next|new|nonzero|oct|or|pos|pow|radd|rand|rdiv|rdivmod|repr|reversed|rfloordiv|rlshift|rmatmul|rmod|rmul|ror|round|rpow|rrshift|rshift|rsub|rtruediv|rxor|set|setattr|setitem|setslice|str|sub|subclasscheck|truediv|unicode|xor)__$")
(#set! onlyIfDescendantOfType call)
(#set! final true))
(#set! test.onlyIfDescendantOfType call)
(#set! test.final true))
; Magic variables which a class/module may have.
((identifier) @support.variable.magic.python
@ -38,30 +38,30 @@
(call
function: (identifier) @support.type.constructor.python
(#match? @support.type.constructor.python "^[A-Z][a-z_]+")
(#set! final true))
(#set! test.final true))
(call
function: (attribute
attribute: (identifier) @support.type.constructor.python)
(#match? @support.type.constructor.python "^[A-Z][a-z_]+")
(#set! final true))
(#set! test.final true))
(call
(identifier) @support.function.builtin.python
(#match? @support.function.builtin.python "^(__import__|abs|all|any|ascii|bin|bool|bytearray|bytes|callable|chr|classmethod|compile|complex|delattr|dict|dir|divmod|enumerate|eval|exec|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|property|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|vars|zip|file|long|raw_input|reduce|reload|unichr|unicode|xrange|apply|buffer|coerce|intern|execfile)$")
(#set! final true))
(#set! test.final true))
; `NotImplemented` is a constant, but is not recognized as such by the parser.
((identifier) @constant.language.not-implemented.python
(#eq? @constant.language.not-implemented.python "NotImplemented")
(#set! final true))
(#set! test.final true))
; `Ellipsis` is also a constant, and though there don't seem to be any use
; cases for using it directly instead of `...`, we should at least mark it as a
; constant because that's how it'll be interpreted by Python.
((identifier) @constant.language.ellipsis.python
(#eq? @constant.language.ellipsis.python "Ellipsis")
(#set! final true))
(#set! test.final true))
; CLASSES
@ -107,19 +107,19 @@
; The "@" and "foo" together in a decorator with arguments, like `@foo(True)`.
((decorator "@" (call function: (identifier))) @support.other.function.decorator.python
(#set! endAt firstNamedChild.firstNamedChild.endPosition))
(#set! adjust.endAt firstNamedChild.firstNamedChild.endPosition))
; Claim the "foo" in `@foo(True)` so it doesn't get scoped like an ordinary
; function call.
(decorator
(call
function: (identifier) @_IGNORE_
(#set! final true)))
(#set! test.final true)))
(call
function: (attribute
attribute: (identifier) @support.other.function.python)
(#set! final true))
(#set! test.final true))
(call
function: (identifier) @support.other.function.python)
@ -161,7 +161,7 @@
(comment) @comment.line.number-sign.python
((comment) @punctuation.definition.comment.python
(#set! endAfterFirstMatchOf "^#"))
(#set! adjust.endAfterFirstMatchOf "^#"))
; DICTIONARIES
; ============
@ -208,15 +208,15 @@
(string
_ @punctuation.definition.string.begin.python
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
(string
_ @punctuation.definition.string.end.python
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
(string prefix: _ @storage.type.string.python
(#match? @storage.type.string.python "^[bBfFrRuU]+")
(#set! endAfterFirstMatchOf "^[bBfFrRuU]+"))
(#set! adjust.endAfterFirstMatchOf "^[bBfFrRuU]+"))
; CONSTANTS
@ -302,11 +302,11 @@
; `self` and `cls` are just conventions, but they are _strong_ conventions.
((identifier) @variable.language.self.python
(#eq? @variable.language.self.python "self")
(#set! final true))
(#set! test.final true))
((identifier) @variable.language.cls.python
(#eq? @variable.language.cls.python "cls")
(#set! final true))
(#set! test.final true))
(keyword_argument
name: (identifier) @variable.parameter.function.python)
@ -336,7 +336,7 @@
; =========
(list_splat_pattern "*" @keyword.operator.splat.python
(#set! final true))
(#set! test.final true))
"=" @keyword.operator.assignment.python
@ -389,7 +389,7 @@
(call
(identifier) @keyword.other._TEXT_.python
(#match? @keyword.other._TEXT_.python "^(exec|print)$")
(#set! final true))
(#set! test.final true))
(print_statement "print" @keyword.other.print.python)
@ -412,42 +412,42 @@
(function_definition
":" @punctuation.definition.function.colon.python
(#set! final true))
(#set! test.final true))
(dictionary (pair ":" @puncutation.separator.key-value.python))
(parameters
"(" @punctuation.definition.parameters.begin.bracket.round.python
")" @punctuation.definition.parameters.end.bracket.round.python
(#set! final true))
(#set! test.final true))
(parameters
"," @punctuation.separator.parameters.comma.python
(#set! final true))
(#set! test.final true))
(argument_list
"(" @punctuation.definition.arguments.begin.bracket.round.python
")" @punctuation.definition.arguments.end.bracket.round.python
(#set! final true))
(#set! test.final true))
(argument_list
"," @punctuation.separator.arguments.comma.python
(#set! final true))
(#set! test.final true))
(tuple
"(" @punctuation.definition.tuple.begin.bracket.round.python
")" @punctuation.definition.tuple.end.bracket.round.python
(#set! final true))
(#set! test.final true))
(tuple
"," @punctuation.separator.tuple.comma.python
(#set! final true))
(#set! test.final true))
(dictionary
"{" @punctuation.definition.dictionary.begin.bracket.curly.python
"}" @punctuation.definition.dictionary.end.bracket.curly.python
(#set! final true))
(#set! test.final true))
(dictionary
"," @punctuation.separator.dictionary.comma.python
(#set! final true))
(#set! test.final true))

View File

@ -1,9 +1,9 @@
(dictionary
(pair ":" @_IGNORE_
(#set! final true)))
(#set! test.final true)))
((lambda ":" @_IGNORE_)
(#set! final true))
(#set! test.final true))
":" @indent

View File

@ -27,18 +27,18 @@
] @keyword.operator.quantifier.regexp
((lookahead_assertion) @keyword.operator.lookahead.regexp
(#set! startAndEndAroundFirstMatchOf "\\?="))
(#set! adjust.startAndEndAroundFirstMatchOf "\\?="))
((lookahead_assertion) @keyword.operator.lookahead.negated.regexp
(#set! startAndEndAroundFirstMatchOf "\\?!"))
(#set! adjust.startAndEndAroundFirstMatchOf "\\?!"))
((non_capturing_group) @keyword.operator.group.non-capturing.regexp
(#set! startAndEndAroundFirstMatchOf "\\?:"))
(#set! adjust.startAndEndAroundFirstMatchOf "\\?:"))
(anonymous_capturing_group
"(" @punctuation.definition.group.begin.bracket.round.regexp
")" @punctuation.definition.group.end.bracket.round.regexp
(#set! final true))
(#set! test.final true))
"|" @keyword.operator.or.regexp
["*" "+"] @keyword.operator.quantifier.regexp

View File

@ -3,13 +3,13 @@
(line_comment) @comment.line.double-slash.rust
((line_comment) @punctuation.definition.comment.rust
(#set! endAfterFirstMatchOf "^//"))
(#set! adjust.endAfterFirstMatchOf "^//"))
(block_comment) @comment.block.rust
((block_comment) @punctuation.definition.begin.comment.rust
(#set! endAfterFirstMatchOf "^/\\*"))
(#set! adjust.endAfterFirstMatchOf "^/\\*"))
((block_comment) @punctuation.definition.end.comment.rust
(#set! startBeforeFirstMatchOf "\\*/$"))
(#set! adjust.startBeforeFirstMatchOf "\\*/$"))
; FUNCTIONS
@ -33,7 +33,7 @@
; Wrap the "foo" and "!" of `foo!()`.
((macro_invocation) @support.other.function.rust
(#set! endAt firstChild.nextSibling.endPosition))
(#set! adjust.endAt firstChild.nextSibling.endPosition))
(call_expression
function: (identifier) @support.other.function.rust)
@ -120,7 +120,7 @@
((identifier) @constant.other.rust
(#match? @constant.other.rust "^[A-Z_][A-Z\\d_]+$")
(#set! final true))
(#set! test.final true))
(boolean_literal) @constant.language.boolean._TEXT_.rust
(escape_sequence) @constant.character.escape.rust

View File

@ -9,11 +9,11 @@
; Why isn't this a keyword in the parser?
((command_name) @keyword.control.return.shell
(#eq? @keyword.control.return.shell "return")
(#set! final true))
(#set! test.final true))
((command_name) @support.function.builtin.shell
(#match? @support.function.builtin.shell "^(?:alias|bg|bind|break|builtin|caller|cd|command|compgen|complete|dirs|disown|echo|enable|eval|exec|exit|false|fc|fg|getopts|hash|help|history|jobs|kill|let|logout|popd|printf|pushd|pwd|read|readonly|set|shift|shopt|source|suspend|test|times|trap|true|type|ulimit|umask|unalias|unset|wait)$")
(#set! final true))
(#set! test.final true))
(command_name) @support.other.function.shell
@ -49,13 +49,13 @@
((simple_expansion) @variable.other.positional.shell
(#match? @variable.other.positional.shell "^\\$\\d+$")
(#set! final true))
(#set! test.final true))
((simple_expansion) @variable.other.normal.shell)
; Prevent the "foo" in $foo from matching the following rule.
(simple_expansion (variable_name) @_IGNORE_
(#set! final true))
(#set! test.final true))
(variable_name) @variable.other.shell
@ -64,9 +64,9 @@
(string "\"") @string.quoted.double.shell
(string "\"" @punctuation.definition.string.begin.shell
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
(string "\"" @punctuation.definition.string.end.shell
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
(raw_string) @string.quoted.single.shell
(string

View File

@ -35,18 +35,18 @@
((comment) @punctuation.definition.comment.ts.tsx
(#match? @comment.line.double-slash.ts.tsx "^//")
(#set! startAndEndAroundFirstMatchOf "^//"))
(#set! adjust.startAndEndAroundFirstMatchOf "^//"))
((comment) @comment.block.ts.tsx
(#match? @comment.block.ts.tsx "^/\\*"))
((comment) @punctuation.definition.comment.begin.ts.tsx
(#match? @punctuation.definition.comment.begin.ts.tsx "^/\\*")
(#set! startAndEndAroundFirstMatchOf "^/\\*"))
(#set! adjust.startAndEndAroundFirstMatchOf "^/\\*"))
((comment) @punctuation.definition.comment.end.ts.tsx
(#match? @punctuation.definition.comment.end.ts.tsx "\\*/$")
(#set! startAndEndAroundFirstMatchOf "\\*/$"))
(#set! adjust.startAndEndAroundFirstMatchOf "\\*/$"))
; PROPERTIES
@ -54,7 +54,7 @@
((property_identifier) @constant.other.property.ts.tsx
(#match? @constant.other.property.ts.tsx "^[\$A-Z_]+$")
(#set! final true))
(#set! test.final true))
; (property_identifier) @variable.other.object.property.ts.tsx
@ -128,10 +128,10 @@
; (type_annotation)
((type_identifier) @storage.type.ts.tsx @support.type.ts.tsx
(#set! onlyIfDescendantOfType type_annotation))
(#set! test.onlyIfDescendantOfType type_annotation))
((type_identifier) @storage.type.ts.tsx @support.type.ts.tsx
(#set! onlyIfDescendantOfType type_arguments))
(#set! test.onlyIfDescendantOfType type_arguments))
; OBJECTS
; =======
@ -190,7 +190,7 @@
(assignment_expression
left: (member_expression
property: (property_identifier) @entity.name.function.definition.ts.tsx
(#set! final true))
(#set! test.final true))
right: [(arrow_function) (function)])
; Function variable assignment:
@ -233,7 +233,7 @@
(required_parameter
pattern: (object_pattern
(shorthand_property_identifier_pattern) @variable.parameter.destructuring.ts)
(#set! final true))
(#set! test.final true))
(update_expression
argument: (identifier) @variable.other.assignment.js)
@ -321,7 +321,7 @@
(pair_pattern
key: (_) @entity.other.attribute-name.ts.tsx
value: (identifier) @variable.other.assignment.loop.ts.tsx)
(#set! final true)))
(#set! test.final true)))
; The "error" in `} catch (error) {`
(catch_clause
@ -343,27 +343,27 @@
((string "\"") @string.quoted.double.ts.tsx)
((string
"\"" @punctuation.definition.string.begin.ts.tsx)
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
((string
"\"" @punctuation.definition.string.end.ts.tsx)
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
((string "'") @string.quoted.single.ts.tsx)
((string
"'" @punctuation.definition.string.begin.ts.tsx)
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
((string
"'" @punctuation.definition.string.end.ts.tsx)
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
(template_string) @string.quoted.template.ts.tsx
((template_string "`" @punctuation.definition.string.begin.ts.tsx)
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
((template_string "`" @punctuation.definition.string.end.ts.tsx)
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
; Interpolations inside of template strings.
(template_substitution
@ -511,7 +511,7 @@
; The "Foo" in `</Foo>`.
(jsx_closing_element
"/" @punctuation.definition.tag.end.ts.tsx
(#set! final true)
(#set! test.final true)
name: (identifier) @entity.name.tag.ts.tsx)
; The "bar" in `<Foo bar={true} />`.
@ -521,17 +521,17 @@
; All JSX expressions/interpolations within braces.
((jsx_expression) @meta.embedded.block.ts.tsx
(#match? @meta.embedded.block.ts.tsx "\\n")
(#set! final true))
(#set! test.final true))
(jsx_expression) @meta.embedded.line.ts.tsx
(jsx_self_closing_element
"<" @punctuation.definition.tag.begin.ts.tsx
(#set! final true))
(#set! test.final true))
((jsx_self_closing_element
; The "/>" in `<Foo />`, extended to cover both anonymous nodes at once.
"/") @punctuation.definition.tag.end.ts.tsx
(#set! startAt lastChild.previousSibling.startPosition)
(#set! endAt lastChild.endPosition)
(#set! final true))
(#set! adjust.startAt lastChild.previousSibling.startPosition)
(#set! adjust.endAt lastChild.endPosition)
(#set! test.final true))

View File

@ -1,14 +1,14 @@
; The closing brace of a switch statement's body should match the indentation of the line where the switch statement starts.
(switch_statement
body: (switch_body "}" @match
(#set! onlyIfLast true))
(#set! matchIndentOf parent.parent.startPosition))
(#set! test.onlyIfLast true))
(#set! indent.matchIndentOf parent.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))
(#set! indent.matchIndentOf parent.parent.startPosition)
(#set! indent.offsetIndent 1))
[
"{"

View File

@ -35,18 +35,18 @@
((comment) @punctuation.definition.comment.ts
(#match? @comment.line.double-slash.ts "^//")
(#set! startAndEndAroundFirstMatchOf "^//"))
(#set! adjust.startAndEndAroundFirstMatchOf "^//"))
((comment) @comment.block.ts
(#match? @comment.block.ts "^/\\*"))
((comment) @punctuation.definition.comment.begin.ts
(#match? @punctuation.definition.comment.begin.ts "^/\\*")
(#set! startAndEndAroundFirstMatchOf "^/\\*"))
(#set! adjust.startAndEndAroundFirstMatchOf "^/\\*"))
((comment) @punctuation.definition.comment.end.ts
(#match? @punctuation.definition.comment.end.ts "\\*/$")
(#set! startAndEndAroundFirstMatchOf "\\*/$"))
(#set! adjust.startAndEndAroundFirstMatchOf "\\*/$"))
; PROPERTIES
@ -54,7 +54,7 @@
((property_identifier) @constant.other.property.ts
(#match? @constant.other.property.ts "^[\$A-Z_]+$")
(#set! final true))
(#set! test.final true))
; (property_identifier) @variable.other.object.property.ts
@ -128,10 +128,10 @@
; (type_annotation)
((type_identifier) @storage.type.ts @support.type.ts
(#set! onlyIfDescendantOfType type_annotation))
(#set! test.onlyIfDescendantOfType type_annotation))
((type_identifier) @storage.type.ts @support.type.ts
(#set! onlyIfDescendantOfType type_arguments))
(#set! test.onlyIfDescendantOfType type_arguments))
; OBJECTS
; =======
@ -197,7 +197,7 @@
(assignment_expression
left: (member_expression
property: (property_identifier) @entity.name.function.definition.ts
(#set! final true))
(#set! test.final true))
right: [(arrow_function) (function)])
; Function variable assignment:
@ -240,7 +240,7 @@
(required_parameter
pattern: (object_pattern
(shorthand_property_identifier_pattern) @variable.parameter.destructuring.ts)
(#set! final true))
(#set! test.final true))
["var" "const" "let"] @storage.type._TYPE_.ts
@ -319,7 +319,7 @@
(pair_pattern
key: (_) @entity.other.attribute-name.ts
value: (identifier) @variable.other.assignment.loop.ts)
(#set! final true)))
(#set! test.final true)))
; The "error" in `} catch (error) {`
(catch_clause
@ -341,27 +341,27 @@
((string "\"") @string.quoted.double.ts)
((string
"\"" @punctuation.definition.string.begin.ts)
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
((string
"\"" @punctuation.definition.string.end.ts)
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
((string "'") @string.quoted.single.ts)
((string
"'" @punctuation.definition.string.begin.ts)
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
((string
"'" @punctuation.definition.string.end.ts)
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
(template_string) @string.quoted.template.ts
((template_string "`" @punctuation.definition.string.begin.ts)
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
((template_string "`" @punctuation.definition.string.end.ts)
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
; Interpolations inside of template strings.
(template_substitution
@ -471,13 +471,13 @@
(ternary_expression
["?" ":"] @keyword.operator.ternary.ts
(#set! final true))
(#set! test.final true))
; TODO: Ternary doesn't highlight properly; presumably fixed in
; https://github.com/tree-sitter/tree-sitter-typescript/pull/215, but needs
; update to v0.20.2.
((ternary_expression) @keyword.operator.ternary.ts
(#set! startAndEndAroundFirstMatchOf "\\?"))
(#set! adjust.startAndEndAroundFirstMatchOf "\\?"))
(public_field_definition "?" @keyword.operator.optional-type.ts)

View File

@ -1,26 +1,15 @@
; The closing brace of a switch statement's body should match the indentation of the line where the switch statement starts.
(switch_statement
body: (switch_body "}" @match
(#set! onlyIfLast true))
(#set! matchIndentOf parent.parent.startPosition))
(#set! test.onlyIfLast true))
(#set! indent.matchIndentOf parent.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))
[
"{"
"("
"["
] @indent
[
"}"
")"
"]"
] @dedent
(#set! indent.matchIndentOf parent.parent.startPosition)
(#set! indent.offsetIndent 1))
["{" "(" "["] @indent
["}" ")" "]"] @dedent
["case" "default"] @indent

View File

@ -135,10 +135,10 @@ describe('ScopeResolver', () => {
});
describe('adjustments', () => {
it('adjusts ranges with (#set! startAt)', async () => {
it('adjusts ranges with (#set! adjust.startAt)', async () => {
await grammar.setQueryForTest('highlightsQuery', `
((try_statement) @try.plus.brace
(#set! endAt
(#set! adjust.endAt
firstChild.nextSibling.firstChild.endPosition))
`);
@ -158,11 +158,11 @@ describe('ScopeResolver', () => {
.toBe('try {');
});
it('adjusts ranges with (#set! endAt)', async () => {
it('adjusts ranges with (#set! adjust.endAt)', async () => {
await grammar.setQueryForTest('highlightsQuery', `
((object) @object.interior
(#set! startAt firstChild.endPosition)
(#set! endAt lastChild.startPosition))
(#set! adjust.startAt firstChild.endPosition)
(#set! adjust.endAt lastChild.startPosition))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -183,12 +183,12 @@ describe('ScopeResolver', () => {
).toBe(`from: 'x', to: 'y'`);
});
it('adjusts ranges with (#set! offset(Start|End))', async () => {
it('adjusts ranges with (#set! adjust.offset(Start|End))', async () => {
// Same result as the previous test, but with a different technique.
await grammar.setQueryForTest('highlightsQuery', `
((object) @object.interior
(#set! offsetStart 1)
(#set! offsetEnd -1))
(#set! adjust.offsetStart 1)
(#set! adjust.offsetEnd -1))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -211,13 +211,13 @@ describe('ScopeResolver', () => {
it('prevents adjustments outside the original capture', async () => {
await grammar.setQueryForTest('highlightsQuery', `
((comment) @too-early
(#set! startAt previousSibling.startPosition))
(#set! adjust.startAt previousSibling.startPosition))
((comment) @too-late
(#set! endAt nextSibling.endPosition))
(#set! adjust.endAt nextSibling.endPosition))
((comment) @offset-too-early
(#set! offsetStart -10))
(#set! adjust.offsetStart -10))
((comment) @offset-too-late
(#set! offsetEnd 10))
(#set! adjust.offsetEnd 10))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -241,10 +241,10 @@ describe('ScopeResolver', () => {
}
});
it("adjusts a range around a regex match with `startAndEndAroundFirstMatchOf`", async () => {
it("adjusts a range around a regex match with `adjust.startAndEndAroundFirstMatchOf`", async () => {
await grammar.setQueryForTest('highlightsQuery', `
((comment) @todo
(#set! startAndEndAroundFirstMatchOf "\\\\sTODO(?=:)"))
(#set! adjust.startAndEndAroundFirstMatchOf "\\\\sTODO(?=:)"))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -276,12 +276,12 @@ describe('ScopeResolver', () => {
describe('tests', () => {
it('rejects scopes for ranges that have already been claimed by another capture with (#set! final true)', async () => {
it('rejects scopes for ranges that have already been claimed by another capture with (#set! test.final true)', async () => {
await grammar.setQueryForTest('highlightsQuery', `
(comment) @comment
(string) @string0
((string) @string1
(#set! final true))
(#set! test.final true))
(string) @string2
"=" @operator
@ -312,11 +312,47 @@ describe('ScopeResolver', () => {
}
});
it('rejects scopes for ranges that have already been claimed if set with (#set! shy true)', async () => {
it('rejects scopes for ranges that have already been claimed by another capture with (#set! test.final true)', async () => {
await grammar.setQueryForTest('highlightsQuery', `
(comment) @comment
(string) @string0
((string) @string1
(#set! test.final true))
(string) @string2
"=" @operator
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
buffer.setLanguageMode(languageMode);
buffer.setText(dedent`
// this is a comment
const foo = "ahaha";
`);
await languageMode.ready;
let { scopeResolver, captures } = await getAllCaptures(grammar, languageMode);
for (let capture of captures) {
let { node, name } = capture;
let result = scopeResolver.store(capture);
if (name === 'string0') {
expect(!!result).toBe(true);
}
if (name === 'string1') {
expect(!!result).toBe(true);
}
if (name === 'string2') {
expect(!!result).toBe(false);
}
}
});
it('rejects scopes for ranges that have already been claimed if set with (#set! test.shy true)', async () => {
await grammar.setQueryForTest('highlightsQuery', `
(comment) @comment
(string "\\"") @string.double
((string) @string.other (#set! shy true))
((string) @string.other (#set! test.shy true))
"=" @operator
`);
@ -347,9 +383,9 @@ describe('ScopeResolver', () => {
it('rejects scopes for ranges that fail onlyIfFirst or onlyIfLast', async () => {
await grammar.setQueryForTest('highlightsQuery', `
((string_fragment) @impossible.first
(#set! onlyIfFirst true))
(#set! test.onlyIfFirst true))
((string_fragment) @impossible.last
(#set! onlyIfLast true))
(#set! test.onlyIfLast true))
((string) "'" @punctuation.first
(#onlyIfFirst true))
((string) "'" @punctuation.last
@ -386,14 +422,14 @@ describe('ScopeResolver', () => {
it('supports onlyIfFirstOfType and onlyIfLastOfType', async () => {
await grammar.setQueryForTest('highlightsQuery', `
(formal_parameters (identifier) @first-param
(#set! onlyIfFirstOfType identifier))
(#set! test.onlyIfFirstOfType identifier))
(formal_parameters (identifier) @last-param
(#set! onlyIfLastOfType identifier))
(#set! test.onlyIfLastOfType identifier))
(formal_parameters "," @first-comma
(#set! onlyIfFirstOfType ","))
(#set! test.onlyIfFirstOfType ","))
(formal_parameters "," @last-comma
(#set! onlyIfLastOfType ","))
(#set! test.onlyIfLastOfType ","))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -421,7 +457,7 @@ describe('ScopeResolver', () => {
it('supports onlyIfLastTextOnRow', async () => {
await grammar.setQueryForTest('highlightsQuery', `
("||" @hanging-logical-operator
(#set! onlyIfLastTextOnRow true))
(#set! test.onlyIfLastTextOnRow true))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -452,7 +488,7 @@ describe('ScopeResolver', () => {
it('supports onlyIfFirstTextOnRow', async () => {
await grammar.setQueryForTest('highlightsQuery', `
("||" @hanging-logical-operator
(#set! onlyIfFirstTextOnRow true))
(#set! test.onlyIfFirstTextOnRow true))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -483,7 +519,7 @@ describe('ScopeResolver', () => {
it('supports onlyIfDescendantOfType', async () => {
await grammar.setQueryForTest('highlightsQuery', `
("," @comma-inside-function
(#set! onlyIfDescendantOfType function_declaration))
(#set! test.onlyIfDescendantOfType function_declaration))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -505,7 +541,7 @@ describe('ScopeResolver', () => {
it('supports onlyIfAncestorOfType', async () => {
await grammar.setQueryForTest('highlightsQuery', `
((function_declaration) @function-with-semicolons
(#set! onlyIfAncestorOfType ";"))
(#set! test.onlyIfAncestorOfType ";"))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -531,7 +567,7 @@ describe('ScopeResolver', () => {
(#set! isSpecialFunction true))
("," @special-comma
(#set! onlyIfDescendantOfNodeWithData isSpecialFunction))
(#set! test.onlyIfDescendantOfNodeWithData isSpecialFunction))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -558,7 +594,7 @@ describe('ScopeResolver', () => {
(#set! isSpecialFunction "troz"))
("," @special-comma
(#set! onlyIfDescendantOfNodeWithData "isSpecialFunction troz"))
(#set! test.onlyIfDescendantOfNodeWithData "isSpecialFunction troz"))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -585,7 +621,7 @@ describe('ScopeResolver', () => {
(#set! isSpecialFunction "troz"))
("," @special-comma
(#set! onlyIfDescendantOfNodeWithData "isSpecialFunction zort"))
(#set! test.onlyIfDescendantOfNodeWithData "isSpecialFunction zort"))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -605,7 +641,7 @@ describe('ScopeResolver', () => {
it('supports onlyIfType', async () => {
await grammar.setQueryForTest('highlightsQuery', `
(formal_parameters _ @function-comma
(#set! onlyIfType ","))
(#set! test.onlyIfType ","))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -626,7 +662,7 @@ describe('ScopeResolver', () => {
it('supports onlyIfHasError', async () => {
await grammar.setQueryForTest('highlightsQuery', `
((statement_block) @messed-up-statement-block
(#set! onlyIfHasError true))
(#set! test.onlyIfHasError true))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -649,7 +685,7 @@ describe('ScopeResolver', () => {
it('supports onlyIfRoot', async () => {
await grammar.setQueryForTest('highlightsQuery', `
((_) @is-root
(#set! onlyIfRoot true))
(#set! test.onlyIfRoot true))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -673,7 +709,7 @@ describe('ScopeResolver', () => {
it('supports onlyIfLastTextOnRow', async () => {
await grammar.setQueryForTest('highlightsQuery', `
("||" @orphaned-operator
(#set! onlyIfLastTextOnRow true))
(#set! test.onlyIfLastTextOnRow true))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -700,7 +736,7 @@ describe('ScopeResolver', () => {
await grammar.setQueryForTest('highlightsQuery', `
((true) @_IGNORE_ (#set! isTrue true))
([ (true) (false) ] @optimistic-boolean
(#set! onlyIfRangeWithData isTrue))
(#set! test.onlyIfRangeWithData isTrue))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -726,7 +762,7 @@ describe('ScopeResolver', () => {
await grammar.setQueryForTest('highlightsQuery', `
((true) @_IGNORE_ (#set! isTrue "exactly"))
([ (true) (false) ] @optimistic-boolean
(#set! onlyIfRangeWithData "isTrue exactly"))
(#set! test.onlyIfRangeWithData "isTrue exactly"))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -752,7 +788,7 @@ describe('ScopeResolver', () => {
await grammar.setQueryForTest('highlightsQuery', `
((true) @_IGNORE_ (#set! isTrue "perhaps"))
([ (true) (false) ] @optimistic-boolean
(#set! onlyIfRangeWithData "isTrue exactly"))
(#set! test.onlyIfRangeWithData "isTrue exactly"))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -774,7 +810,7 @@ describe('ScopeResolver', () => {
it('supports onlyIfStartsOnSameRowAs', async () => {
await grammar.setQueryForTest('highlightsQuery', `
((false) @non-hanging-false
(#set! onlyIfStartsOnSameRowAs parent.startPosition))
(#set! test.onlyIfStartsOnSameRowAs parent.startPosition))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -801,7 +837,7 @@ describe('ScopeResolver', () => {
it('supports onlyIfEndsOnSameRowAs', async () => {
await grammar.setQueryForTest('highlightsQuery', `
((true) @non-hanging-true
(#set! onlyIfEndsOnSameRowAs parent.endPosition))
(#set! test.onlyIfEndsOnSameRowAs parent.endPosition))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer });
@ -830,7 +866,7 @@ describe('ScopeResolver', () => {
await grammar.setQueryForTest('highlightsQuery', `
([(true) (false)] @boolean
(#set! onlyIfConfig core.careAboutBooleans))
(#set! test.onlyIfConfig core.careAboutBooleans))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer, config: atom.config });
@ -857,7 +893,7 @@ describe('ScopeResolver', () => {
await grammar.setQueryForTest('highlightsQuery', `
([(true) (false)] @boolean
(#set! onlyIfConfig "core.careAboutBooleans true"))
(#set! test.onlyIfConfig "core.careAboutBooleans true"))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer, config: atom.config });
@ -884,7 +920,7 @@ describe('ScopeResolver', () => {
await grammar.setQueryForTest('highlightsQuery', `
([(true) (false)] @boolean
(#set! onlyIfConfig "core.careAboutBooleans 0"))
(#set! test.onlyIfConfig "core.careAboutBooleans 0"))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer, config: atom.config });
@ -911,7 +947,7 @@ describe('ScopeResolver', () => {
await grammar.setQueryForTest('highlightsQuery', `
([(true) (false)] @boolean
(#set! onlyIfConfig "core.careAboutBooleans something"))
(#set! test.onlyIfConfig "core.careAboutBooleans something"))
`);
const languageMode = new WASMTreeSitterLanguageMode({ grammar, buffer, config: atom.config });
@ -937,13 +973,13 @@ describe('ScopeResolver', () => {
jasmine.useRealClock();
await grammar.setQueryForTest('highlightsQuery', `
((escape_sequence) @regex-escape
(#set! onlyIfInjection true))
(#set! test.onlyIfInjection true))
`);
let regexGrammar = new WASMTreeSitterGrammar(atom.grammars, jsRegexGrammarPath, jsRegexConfig);
await regexGrammar.setQueryForTest('highlightsQuery', `
((control_escape) @regex-escape
(#set! onlyIfInjection true))
(#set! test.onlyIfInjection true))
`);
atom.grammars.addGrammar(regexGrammar);

View File

@ -292,17 +292,17 @@ describe('WASMTreeSitterLanguageMode', () => {
]);
});
it('updates the range of the current node in the tree when invalidateOnChange is set', async () => {
it('updates the range of the current node in the tree when highlight.invalidateOnChange is set', async () => {
jasmine.useRealClock();
const grammar = new WASMTreeSitterGrammar(atom.grammars, jsGrammarPath, jsConfig);
await grammar.setQueryForTest('highlightsQuery', `
((template_string) @lorem
(#match? @lorem "lorem")
(#set! invalidateOnChange true))
(#set! highlight.invalidateOnChange true))
((template_string) @ipsum
(#not-match? @ipsum "lorem")
(#set! invalidateOnChange true))
(#set! highlight.invalidateOnChange true))
`);
buffer.setText(dedent`\`
@ -498,13 +498,13 @@ describe('WASMTreeSitterLanguageMode', () => {
((identifier) @constant
(#match? @constant "^[A-Z_]+$")
(#set! final true))
(#set! test.final true))
((identifier) @constructor
(#match? @constructor "^[A-Z]"))
((identifier) @variable
(#set! shy true))
(#set! test.shy true))
`);
buffer.setText(`exports.object = Class(SOME_CONSTANT, x)`);
@ -650,10 +650,10 @@ describe('WASMTreeSitterLanguageMode', () => {
(call_expression
(member_expression
(property_identifier) @method)
(#set! final true))
(#set! test.final true))
((property_identifier) @property
(#set! final true))
(#set! test.final true))
(call_expression (identifier) @function)
`);
@ -1130,7 +1130,7 @@ describe('WASMTreeSitterLanguageMode', () => {
let jsdocGrammar = atom.grammars.grammarForScopeName('source.jsdoc');
await jsdocGrammar.setQueryForTest('highlightsQuery', `
((ERROR) @comment.block.js
(#set! onlyIfRoot true))
(#set! test.onlyIfRoot true))
(document) @comment.block.js
(tag_name) @storage.type.class.jsdoc
@ -1204,18 +1204,18 @@ describe('WASMTreeSitterLanguageMode', () => {
await rustGrammar.setQueryForTest('highlightsQuery', `
(macro_invocation
macro: (identifier) @macro
(#set! final true))
(#set! test.final true))
(call_expression
(field_expression
(field_identifier) @function)
(#set! final true))
(#set! test.final true))
((field_identifier) @property
(#set! final true))
(#set! test.final true))
((identifier) @variable
(#set! shy true))
(#set! test.shy true))
`);
atom.grammars.addGrammar(rustGrammar);
@ -1691,27 +1691,13 @@ describe('WASMTreeSitterLanguageMode', () => {
((if_statement
consequence: (statement_block) @fold)
(#set! offsetEnd -1))
(#set! fold.offsetEnd -1))
(else_clause (statement_block) @fold)
(statement_block) @fold
`);
// {
// parser: 'tree-sitter-javascript',
// folds: [
// {
// start: { type: '{', index: 0 },
// end: { type: '}', index: -1 }
// },
// {
// start: { type: '(', index: 0 },
// end: { type: ')', index: -1 }
// }
// ]
// });
buffer.setText(dedent`
if (a) {
b
@ -1759,16 +1745,16 @@ describe('WASMTreeSitterLanguageMode', () => {
await grammar.setQueryForTest('foldsQuery', `
(jsx_element
(jsx_opening_element ">" @fold)
(#set! endAt parent.parent.lastChild.startPosition)
(#set! offsetEnd -1)
(#set! fold.endAt parent.parent.lastChild.startPosition)
(#set! fold.offsetEnd -1)
)
(jsx_element
(jsx_opening_element) @fold
(#set! endAt lastChild.previousSibling.endPosition))
(#set! fold.endAt lastChild.previousSibling.endPosition))
((jsx_self_closing_element) @fold
(#set! endAt lastChild.previousSibling.startPosition))
(#set! fold.endAt lastChild.previousSibling.startPosition))
`);
buffer.setText(dedent`
@ -1817,8 +1803,8 @@ describe('WASMTreeSitterLanguageMode', () => {
await grammar.setQueryForTest('foldsQuery', `
((comment) @fold
(#set! endAt endPosition)
(#set! adjustEndColumn 0))
(#set! fold.endAt endPosition)
(#set! fold.adjustEndColumn 0))
`);
buffer.setText(dedent`
@ -1987,16 +1973,16 @@ describe('WASMTreeSitterLanguageMode', () => {
await grammar.setQueryForTest('foldsQuery', `
((if
alternative: [(elsif) (else)]) @fold
(#set! endAt firstNamedChild.nextNamedSibling.nextNamedSibling.startPosition)
(#set! offsetEnd -1))
(#set! fold.endAt firstNamedChild.nextNamedSibling.nextNamedSibling.startPosition)
(#set! fold.offsetEnd -1))
((elsif
consequence: [(then) (elsif)]) @fold
(#set! endAt firstNamedChild.nextNamedSibling.nextNamedSibling.startPosition)
(#set! offsetEnd -1))
(#set! fold.endAt firstNamedChild.nextNamedSibling.nextNamedSibling.startPosition)
(#set! fold.offsetEnd -1))
((else) @fold
(#set! endAt endPosition))
(#set! fold.endAt endPosition))
(if) @fold
`);
@ -2124,7 +2110,7 @@ describe('WASMTreeSitterLanguageMode', () => {
(dictionary)
(string)
] @fold (#set! endAt endPosition))
] @fold (#set! fold.endAt endPosition))
`);
@ -2171,8 +2157,8 @@ describe('WASMTreeSitterLanguageMode', () => {
await jsGrammar.setQueryForTest('foldsQuery', `
(template_string) @fold
((arguments) @fold
(#set! adjustEndColumn 0)
(#set! offsetEnd -1))
(#set! fold.adjustEndColumn 0)
(#set! fold.offsetEnd -1))
`);
jsGrammar.addInjectionPoint(HTML_TEMPLATE_LITERAL_INJECTION_POINT);
@ -2376,7 +2362,7 @@ describe('WASMTreeSitterLanguageMode', () => {
await grammar.setQueryForTest('highlightsQuery', `
(comment) @comment.block
((comment) @punctuation.definition.comment.begin
(#set! startAndEndAroundFirstMatchOf "^/\\\\*"))
(#set! adjust.startAndEndAroundFirstMatchOf "^/\\\\*"))
`);
buffer.setText('\n/* lorem ipsum dolor sit amet */');
@ -2427,7 +2413,7 @@ describe('WASMTreeSitterLanguageMode', () => {
await jsGrammar.setQueryForTest('highlightsQuery', `
((regex) @gadfly
(#set! startAndEndAroundFirstMatchOf "lor\\\\?em"))
(#set! adjust.startAndEndAroundFirstMatchOf "lor\\\\?em"))
(regex) @regex-outer
(regex_pattern) @regex-inner
`);
@ -2489,7 +2475,7 @@ describe('WASMTreeSitterLanguageMode', () => {
await jsGrammar.setQueryForTest('highlightsQuery', `
((regex_pattern) @gadfly
(#set! startAndEndAroundFirstMatchOf "lor\\\\?em"))
(#set! adjust.startAndEndAroundFirstMatchOf "lor\\\\?em"))
(regex) @regex-outer
(regex_pattern) @regex-inner
`);
@ -2784,11 +2770,11 @@ describe('WASMTreeSitterLanguageMode', () => {
await jsGrammar.setQueryForTest('highlightsQuery', `
((regex) @keyword.operator.optional
(#set! startAndEndAroundFirstMatchOf "\\\\?"))
(#set! adjust.startAndEndAroundFirstMatchOf "\\\\?"))
(regex) @string.regexp.js
((comment) @comment.block.js)
((comment) @punctuation.definition.comment.begin.js
(#set! endAfterFirstMatchOf "^/\\\\*"))
(#set! adjust.endAfterFirstMatchOf "^/\\\\*"))
`);
atom.grammars.addGrammar(jsGrammar);
@ -2848,7 +2834,7 @@ describe('WASMTreeSitterLanguageMode', () => {
await jsGrammar.setQueryForTest('highlightsQuery', `
((regex) @keyword.operator.optional
(#set! startAndEndAroundFirstMatchOf "\\\\?"))
(#set! adjust.startAndEndAroundFirstMatchOf "\\\\?"))
((regex_pattern) @string.regexp.js)
`);
@ -3149,14 +3135,14 @@ describe('WASMTreeSitterLanguageMode', () => {
(call_expression
(member_expression
(property_identifier) @method)
(#set! final true))
(#set! test.final true))
(call_expression
(identifier) @function
(#set! final true))
(#set! test.final true))
((property_identifier) @property
(#set! final true))
(#set! test.final true))
(identifier) @variable
`);
@ -3313,8 +3299,8 @@ describe('WASMTreeSitterLanguageMode', () => {
await grammar.setQueryForTest('indentsQuery', `
(template_string
"\`" @match
(#set! onlyIfLast true)
(#set! matchIndentOf parent.firstChild.startPosition))
(#set! test.onlyIfLast true)
(#set! indent.matchIndentOf parent.firstChild.startPosition))
`);
buffer.setText(dedent`
@ -3349,8 +3335,8 @@ describe('WASMTreeSitterLanguageMode', () => {
await grammar.setQueryForTest('indentsQuery', `
(template_string
"\`" @dedent @match
(#set! onlyIfLast true)
(#set! matchIndentOf parent.firstChild.startPosition))
(#set! test.onlyIfLast true)
(#set! indent.matchIndentOf parent.firstChild.startPosition))
`);
buffer.setText(dedent`
@ -3610,7 +3596,7 @@ describe('WASMTreeSitterLanguageMode', () => {
["{"] @indent
["}"] @dedent
((comment) @indent
(#set! onlyIfDescendantOfType class_body))
(#set! test.onlyIfDescendantOfType class_body))
`);
let emptyClassText = dedent`
@ -3660,7 +3646,7 @@ describe('WASMTreeSitterLanguageMode', () => {
["{"] @indent
["}"] @dedent
((comment) @indent
(#set! onlyIfDescendantOfType class_body))
(#set! test.onlyIfDescendantOfType class_body))
`);
let emptyClassText = dedent`

View File

@ -124,7 +124,7 @@ class ScopeResolver {
shouldInvalidateOnChange(capture) {
return capture.setProperties &&
('invalidateOnChange' in capture.setProperties);
('highlight.invalidateOnChange' in capture.setProperties);
}
// We want to index scope data on buffer position, but each `Point` (or
@ -178,7 +178,7 @@ class ScopeResolver {
let { setProperties: props = {} } = capture;
let keys = Object.keys(props);
if (keys.length === 0) { return false; }
return keys.some(k => k in ScopeResolver.ADJUSTMENTS);
return keys.some(k => this.capturePropertyIsAdjustment(k));
}
rangeExceedsBoundsOfCapture(range, capture) {
@ -186,6 +186,42 @@ class ScopeResolver {
range.endIndex > capture.node.endIndex;
}
normalizeAdjustmentProperty(prop) {
if (prop.startsWith('adjust.')) {
prop = prop.replace(/^adjust\./, '');
}
return prop;
}
capturePropertyIsAdjustment(prop) {
prop = this.normalizeAdjustmentProperty(prop);
return prop in ScopeResolver.ADJUSTMENTS;
}
applyAdjustment(prop, ...args) {
prop = this.normalizeAdjustmentProperty(prop);
return ScopeResolver.ADJUSTMENTS[prop](...args);
}
normalizeTestProperty(prop) {
if (prop.startsWith('test.')) {
prop = prop.replace(/^test\./, '');
}
return prop;
}
capturePropertyIsTest(prop) {
prop = this.normalizeTestProperty(prop);
return prop in ScopeResolver.TESTS;
}
applyTest(prop, ...args) {
// console.log('testing prop:', prop);
prop = this.normalizeTestProperty(prop);
// console.log('now prop:', prop);
return ScopeResolver.TESTS[prop](...args);
}
// Given a capture and possible predicate data, determines the buffer range
// that this capture wants to cover.
determineCaptureRange(capture) {
@ -204,14 +240,13 @@ class ScopeResolver {
};
for (let key in props) {
if (key in ScopeResolver.ADJUSTMENTS) {
if (this.capturePropertyIsAdjustment(key)) {
let value = props[key];
// Transform the range successively. Later adjustments can optionally
// act on earlier adjustments, or they can ignore the current position
// and inspect the original node instead.
range = ScopeResolver.ADJUSTMENTS[key](
capture.node, value, props, range, this);
range = this.applyAdjustment(key, capture.node, value, props, range, this);
// If any single adjustment returns `null`, we shouldn't store this
// capture.
@ -233,13 +268,12 @@ class ScopeResolver {
// document.
test(capture, existingData) {
let { node, setProperties: props = {} } = capture;
if (existingData?.final) { return false; }
if (existingData?.final || existingData?.['test.final']) { return false; }
for (let key in props) {
if (!(key in ScopeResolver.TESTS)) { continue; }
let test = ScopeResolver.TESTS[key];
if (!this.capturePropertyIsTest(key)) { continue; }
let value = props[key];
if (!test(node, value, props, existingData, this)) {
if (!this.applyTest(key, node, value, props, existingData, this)) {
return false;
}
}
@ -364,7 +398,9 @@ ScopeResolver.interpolateName = (name, node) => {
!node.text.includes(' ')) {
name = name.replace('_TEXT_', node.text);
}
name = name.replace('_TYPE_', node.type);
if (name.includes('_TYPE_')) {
name = name.replace('_TYPE_', node.type);
}
return name;
};
@ -391,7 +427,8 @@ ScopeResolver.TESTS = {
// all other captures for that same range are ignored, whether they try to
// define `final` or not.
final(node, value, props, existingData) {
return !(existingData && existingData.final);
let final = existingData?.final || existingData?.['test.final'];
return !(existingData && final);
},
// Passes only if no earlier capture has occurred for the exact same range.

View File

@ -1215,7 +1215,7 @@ class WASMTreeSitterLanguageMode {
let { node, name, setProperties: props = {} } = capture;
// Ignore “phantom” nodes that aren't present in the buffer.
if (node.text === '' && !props.allowEmpty) {
if (node.text === '' && !props['indent.allowEmpty']) {
continue;
}
@ -1316,7 +1316,7 @@ class WASMTreeSitterLanguageMode {
let { text } = node;
// Ignore “phantom” nodes that aren't present in the buffer.
if (text === '' && !props.allowEmpty) { continue; }
if (text === '' && !props['indent.allowEmpty']) { continue; }
// Ignore anything that isn't actually on the row.
if (node.endPosition.row < row) { continue; }
@ -1339,8 +1339,8 @@ class WASMTreeSitterLanguageMode {
// logic for `suggestedIndentForEditedBufferRow`.
//
// If a capture is confident it knows what it's doing, it can opt out
// of this behavior with `(#set! force true)`.
if (!props.force && !currentRowText.startsWith(text)) { continue; }
// of this behavior with `(#set! indent.force true)`.
if (!props['indent.force'] && !currentRowText.startsWith(text)) { continue; }
// The '@match' capture short-circuits a lot of this logic by pointing
// us to a different node and asking us to match the indentation of
@ -1607,9 +1607,9 @@ class WASMTreeSitterLanguageMode {
//
// If the capture is confident it knows what it's doing, and is using
// some other mechanism to ensure the adjustment will happen exactly
// once, it can bypass this behavior with `(#set! force true)`.
// once, it can bypass this behavior with `(#set! indent.force true)`.
//
if (!props.force && node.text !== lineText) { continue; }
if (!props['indent.force'] && node.text !== lineText) { continue; }
// `@match` is authoritative; honor the first one we see and ignore other
// captures.
@ -1664,21 +1664,21 @@ class WASMTreeSitterLanguageMode {
// A `@match` capture must specify
//
// (#set! matchIndentOf foo)
// (#set! indent.matchIndentOf foo)
//
// where "foo" is a node descriptor. It may optionally specify
//
// (#set! offsetIndent X)
// (#set! indent.offsetIndent X)
//
// where "X" is a number, positive or negative.
//
let { matchIndentOf, offsetIndent = "0" } = props;
if (!matchIndentOf) { return undefined; }
if (!props['indent.matchIndentOf']) { return undefined; }
let offsetIndent = props['indent.offsetIndent'] ?? "0";
offsetIndent = Number(offsetIndent);
if (isNaN(offsetIndent)) { offsetIndent = 0; }
// Follow a node descriptor to a target node.
let targetPosition = resolveNodePosition(node, props.matchIndentOf);
let targetPosition = resolveNodePosition(node, props['indent.matchIndentOf']);
// That node must start on a row earlier than ours.
let targetRow = targetPosition?.row;
@ -1843,7 +1843,7 @@ class WASMTreeSitterLanguageMode {
// * A “simple” fold is one with a capture name of `@fold` in a folds query. It
// can be described with only one capture. It starts at the end of the row
// that the captured node starts on, and ends at a configurable position
// controlled by the `endAt` adjustment (which defaults to
// controlled by the `fold.endAt` adjustment (which defaults to
// `lastChild.startPosition`).
//
// Simple folds should be used whenever you're able to predict the end of a
@ -2072,21 +2072,37 @@ class FoldResolver {
}
}
normalizeFoldProperty(prop) {
if (prop.startsWith('fold.')) {
prop = prop.replace(/^fold./, '');
}
return prop;
}
capturePropertyIsFoldAdjustment(prop) {
prop = this.normalizeFoldProperty(prop);
return prop in FoldResolver.ADJUSTMENTS;
}
applyFoldAdjustment(prop, ...args) {
prop = this.normalizeFoldProperty(prop);
return FoldResolver.ADJUSTMENTS[prop](...args);
}
resolveRangeForSimpleFold(capture) {
let { node, setProperties: props } = capture;
if (node.type === 'ERROR') { return null; }
let start = new Point(node.startPosition.row, Infinity);
let end = node.endPosition;
let defaultOptions = { endAt: 'lastChild.startPosition' };
let defaultOptions = { 'fold.endAt': 'lastChild.startPosition' };
let options = { ...defaultOptions, ...props };
try {
for (let key in options) {
if (!FoldResolver.ADJUSTMENTS[key]) { continue; }
if (!this.capturePropertyIsFoldAdjustment(key)) { continue; }
let value = options[key];
end = FoldResolver.ADJUSTMENTS[key](
end, node, value, props, this.layer);
end = this.applyFoldAdjustment(key, end, node, value, props, this.layer);
}
end = Point.fromObject(end, true);