Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 142 additions & 23 deletions packages/language-csharp/grammars/tree-sitter-c-sharp/highlights.scm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
"params"
"partial"
"static"
"async"
"readonly"
"unchecked"
"unmanaged"
] @storage.modifier._TYPE_.cs
Expand Down Expand Up @@ -63,10 +65,45 @@
(raw_string_literal) @string.quoted.triple.cs
(verbatim_string_literal) @string.quoted.double.verbatim.cs

; Double-quoted interpolated string expressions. We want to match `$""` and
; `$"x"` but not `$"""`. Also, `$`/`$@`/`@$` are all valid sigils!
((interpolated_string_expression) @string.quoted.double.interpolated.cs
(#match? @string.quoted.double.interpolated.cs "^(\\$|\\$@|@\\$)\"[^\"]"))
((interpolated_string_expression) @string.quoted.double.interpolated.cs
(#eq? @string.quoted.double.interpolated.cs "$\"\""))

; Triple-quoted interpolation strings.
(interpolated_string_expression (interpolation_quote)) @string.quoted.triple.interpolated.cs

; Delimiters for triple-quoted interpolation strings.
(interpolated_string_expression
(interpolation_quote) @punctuation.definition.string.begin.cs
(#is? test.firstOfType))
(interpolated_string_expression
(interpolation_quote) @punctuation.definition.string.end.cs
(#is? test.lastOfType))

; The sigil in an interpolation string.
(interpolation_start) @punctuation.definition.string.begin.cs

(escape_sequence) @constant.character.escape.cs

; TODO: Interpolations.
; Interpolations within strings.
(interpolated_string_expression
(interpolation) @meta.embedded.block.cs
(#match? @meta.embedded.block.cs "\\n")
(#set! capture.final))

(interpolated_string_expression
(interpolation) @meta.embedded.line.cs)

(interpolation
(interpolation_brace) @punctuation.section.embedded.begin.cs
(#is? test.firstOfType))

(interpolation
(interpolation_brace) @punctuation.section.embedded.end.cs
(#is? test.lastOfType))

; COMMENTS

Expand Down Expand Up @@ -112,38 +149,85 @@
(local_function_statement
name: (identifier) @entity.name.function.cs)

(attribute name: _ @entity.other.attribute-name.cs)

(property_declaration name: _ @entity.name.property.cs)

; SUPPORT

(invocation_expression
function: (identifier) @support.other.function.cs)

; All kinds of Foo in `new Foo()`, `new Foo<int>`, new `Foo.Foo()`, etc.
(object_creation_expression
type: (identifier) @support.class.instance.cs
(#set! capture.final))

; Mark `type:` fields within an object creation…
(object_creation_expression
type: _ @_IGNORE_
(#set! type_instantiation true)
(#set! capture.final))

; …then scope all identifiers within (except generic type arguments).
((identifier) @support.class.instance.cs
(#is-not? test.descendantOfType "type_argument_list")
(#is? test.descendantOfNodeWithData "type_instantiation"))

; TYPES

; Builtin types like `string`.
(predefined_type) @support.storage.type.builtin.cs

(type_argument_list
(identifier) @support.storage.type.cs)

(generic_name (identifier) @support.storage.type.cs)
; Catch and mark all `type:` fields on things that aren't object creation
; expressions.
(_ type: (_) @_IGNORE_
(#set! type_annotation true))

; Type coercion.
(as_expression
right: (identifier) @support.storage.type.cs)
right: (_) @_IGNORE_
(#set! type_annotation true))

; Type checking/binding.
(is_expression
right: (identifier) @support.storage.type.cs)
right: (_) @_IGNORE_
(#set! type_annotation true))

; e.g., `value is Foo.Bar`.
(is_pattern_expression
pattern: _ @_IGNORE_
(#set! type_annotation true))

; Generally, anything with a `returns:` field should be highlighted like a type.
(_
returns: (_) @_IGNORE_
(#set! type_annotation true))

(class_declaration
(base_list) @_IGNORE_
(#set! type_annotation true))

; Scope all identifiers as types when they match those marked nodes…
((identifier)
@support.storage.type.cs
(#is? test.rangeWithData "type_annotation")
(#set! capture.final))

(_ type: (identifier) @support.storage.type.cs)
; or when they descend from those marked nodes.
((identifier)
@support.storage.type.cs
(#is? test.descendantOfNodeWithData "type_annotation")
(#set! capture.final))

; TODO: This might be overbroad.
(base_list (identifier) @support.storage.type.cs)
; (base_list (identifier) @support.storage.type.cs)

; Generally, anything with a `returns:` field should be highlighted like a type.
(_
returns: (identifier) @support.storage.type.cs
(#set! capture.shy))

(_
returns: (qualified_name
name: (identifier) @support.storage.type.cs))

; VARIABLES

Expand All @@ -158,6 +242,8 @@
(assignment_expression
left: (identifier) @variable.other.assignment.cs)

(declaration_pattern name: (identifier) @variable.other.assignment.cs)

(type_parameter_list
(type_parameter
name: (identifier) @support.storage.type.parameter.cs))
Expand All @@ -168,9 +254,29 @@
(enum_member_declaration
(identifier) @variable.other.property.cs)

; The `EndsWith` in 'someString.EndsWith("foo")'.
(invocation_expression
(member_access_expression
name: (identifier) @support.other.function.method.cs))
(#set! capture.final)

(invocation_expression
(generic_name
(identifier) @support.other.function.cs))

; The `Sort` in "Array.Sort<Foo>".
(invocation_expression
(member_access_expression
name: (generic_name (identifier) @support.other.function.method.cs))
(#set! capture.final))

; The "X" in `ptr->X`.
(member_access_expression
name: (identifier) @variable.other.property.cs)
name: (identifier) @variable.other.property.cs
; This way it won't apply if we've already scoped it as a method call.
(#set! capture.shy))

(catch_declaration name: _ @variable.other.assignment.cs)

; KEYWORDS

Expand Down Expand Up @@ -212,6 +318,8 @@
"unsafe"
"with"
"stackalloc"
"try"
"switch"
] @keyword.control._TYPE_.cs

(
Expand All @@ -237,6 +345,8 @@
"?" @keyword.operator.optional.cs
".." @keyword.operator.range.cs

["new"] @keyword.operator._TYPE_.cs

(prefix_unary_expression
["&" "^" "+" "-"] @keyword.operator.unary.cs)

Expand Down Expand Up @@ -299,6 +409,25 @@
">>>="
] @keyword.operator.bitwise.compound.cs

((type_parameter_list
"<" @punctuation.definition.parameters.begin.bracket.angle.cs
">" @punctuation.definition.parameters.end.bracket.angle.cs)
(#set! capture.final))

((type_argument_list
"<" @punctuation.definition.parameters.begin.bracket.angle.cs
">" @punctuation.definition.parameters.end.bracket.angle.cs)
(#set! capture.final))

[
"=="
"!="
">="
"<="
">"
"<"
] @keyword.operator.comparison.cs

(destructor_declaration "~" @keyword.operator.destructor.cs)

; PUNCTUATION
Expand All @@ -323,13 +452,3 @@
(#set! capture.shy))
(")" @punctuation.definition.end.bracket.round.cs
(#set! capture.shy))

(type_parameter_list
"<" @punctuation.definition.parameters.begin.bracket.angle.cs
">" @punctuation.definition.parameters.end.bracket.angle.cs
)

(type_argument_list
"<" @punctuation.definition.parameters.begin.bracket.angle.cs
">" @punctuation.definition.parameters.end.bracket.angle.cs
)
25 changes: 25 additions & 0 deletions packages/language-csharp/spec/fixtures/sample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,34 @@ static void Main(string[] args) {
Car myCar = new Car();
// ^^^ support.storage.type.cs
// ^^^^^ variable.other.assignment.cs
// ^^^ keyword.operator.new.cs

myCar.honk();

Console.WriteLine(myCar.brand + " " + myCar.modelName);
// ^^^^^^^^^ support.other.function.method.cs

Array.Sort<int>(myNumbers);
// ^^^^ support.other.function.method.cs
// ^^^ support.storage.type.builtin.cs

Console.WriteLine($"Doing {noun}...");
// ^^^^^^^^^^^^^^^^^^ string.quoted.double.interpolated.cs
// ^ punctuation.section.embedded.begin.cs
// ^ punctuation.section.embedded.end.cs

string json = $$"""
{
"name": {{name.toUpperCase("foo")}}
}
""";
// ^^^ punctuation.definition.string.end.cs

}
}

static readonly string[] signinMethods = {
// ^^^^^^^^ storage.modifier.readonly.cs
"Credentials",
"QR Code"
};
2 changes: 2 additions & 0 deletions packages/language-html/grammars/modern-tree-sitter-html.cson
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ parser: 'tree-sitter-html'

injectionRegex: '(HTML|html|Html)$'

firstLineRegex: "<(?:!DOCTYPE\\s*)?html|-\\*-(?:\\s*(?=[^:;\\s]+\\s*-\\*-)|(?:.*?[;\\s]|(?<=-\\*-))mode\\s*:\\s*)html(?=[\\s;]|(?<![-*])-\\*-).*?-\\*-|(?:(?:\\s|^)vi(?:m[<=>]?\\d+|m)?|\\sex)(?=:(?=\\s*set?\\s[^\\n:]+:)|:(?!\\s*set?\\s))(?:(?:\\s|\\s*:\\s*)\\w*(?:\\s*=(?:[^\\n\\\\\\s]|\\\\.)*)?)*[\\s:](?:filetype|ft|syntax)\\s*=x?html(?=\\s|:|$)"

treeSitter:
parserSource: 'github:tree-sitter/tree-sitter-html#v0.23.0'
grammar: 'tree-sitter-html/tree-sitter-html.wasm'
Expand Down
2 changes: 1 addition & 1 deletion packages/symbol-provider-ctags/lib/ctags-provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ class CtagsProvider {
}

getLanguage(editor) {
if (['.cson', '.gyp'].includes(path.extname(this.path))) {
if (['.cson', '.gyp'].includes(path.extname(this.getPath()))) {
return 'Cson';
}

Expand Down
Loading
Loading