diff --git a/extension.toml b/extension.toml index 5c3551b..be830dd 100644 --- a/extension.toml +++ b/extension.toml @@ -8,7 +8,7 @@ repository = "https://github.com/h2000/zed-roc" [grammars.roc] repository = "https://github.com/faldor20/tree-sitter-roc" -commit = "6ea64b6434a45472bd87b0772fd84a017de0a557" +commit = "40e52f343f1b1f270d6ecb2ca898ca9b8cba6936" [language_servers.roc] language = "Roc" diff --git a/languages/roc/highlights.scm b/languages/roc/highlights.scm index 53c8787..07c1209 100644 --- a/languages/roc/highlights.scm +++ b/languages/roc/highlights.scm @@ -1,63 +1,208 @@ -;;----comments---- +;; Highlight names (like `@comment.block.documentation`) are arbitrary. +;; However, some text editors encourage a standard set in their themes. +;; For consistency and quality, these queries assign the highlight names that Helix uses: +;; see https://docs.helix-editor.com/themes.html#scopes + + +; Initialli this was at the end, but that ruined everything +(identifier) @variable + + +;; +;; Higher-priorty queries +;; + + + +((module) @namespace.roc-special.builtin + (#match? @namespace.roc-special.builtin "^(Bool|Box|Decode|Dict|Encode|Hash|Inspect|List|Num|Result|Set|Str)")) +; TODO(bugfix): `Set` yields an ERROR in `expect Set.from_list(paths_as_str) == Set.from_list(["nested-dir/a", "nested-dir/child"])` + + + +(ability_chain "&" @operator.roc-special.in-typedef) + + + +(parenthesized_type ["(" ")"] @punctuation.bracket.roc-special.in-typedef) +(record_type ["{" "}"] @punctuation.bracket.roc-special.in-typedef) +(tags_type ["[" "]"] @punctuation.bracket.roc-special.in-typedef) +(tuple_type ["(" ")"] @punctuation.bracket.roc-special.in-typedef) + +(function_type "," @punctuation.delimiter.roc-special.in-typedef) +(record_type "," @punctuation.delimiter.roc-special.in-typedef) +(tuple_type "," @punctuation.delimiter.roc-special.in-typedef) + + +(record_field_type (field_name) @variable.other.member.roc-special.in-typedef) + + + +;; +;; Normal-priorty queries +;; + + + +; N/A +; @attribute + + + +; N/A +; @comment + +; N/A +; @comment.block + +(doc_comment) @comment.block.documentation + +(line_comment) @comment.line + + + +; N/A +; @constant + +; N/A +; @constant.builtin + +(variable_expr (module) @ignoreme.module "." (identifier) @constant.builtin.boolean + (#eq? @constant.builtin.boolean "false") (#eq? @ignoreme.module "Bool")) +(variable_expr (module) @ignoreme.module "." (identifier) @constant.builtin.boolean + (#eq? @constant.builtin.boolean "true") (#eq? @ignoreme.module "Bool")) + +(char) @constant.character + +(escape_char) @constant.character.escape + +; N/A +; @constant.numeric + +[ + (iint) + (int) + (natural) + (uint) + (xint) +] @constant.numeric.integer [ - (line_comment) - (doc_comment) @comment.block.documentation -] @comment + (decimal) + (float) +] @constant.numeric.float -;;----typedefs----- -;; opinion: typedefs cross into documentation and should be -;; highlighted differently from normal code -(opaque_type_def (_ (concrete_type) @type.definition)) -(function_type (arrow) @punctuation.delimiter.structural.typedef) +[ + (opaque_tag) + (tag) +] @constructor -(parenthesized_type ["(" ")"] @punctuation.bracket.typedef) -(tuple_type ["(" ")"] @punctuation.bracket.typedef) -(record_type ["{" "}"] @punctuation.bracket.typedef) -(tags_type ["[" "]"] @punctuation.bracket.typedef) -(function_type "," @punctuation.delimiter.typedef) -(tuple_type "," @punctuation.delimiter.typedef) -(record_type "," @punctuation.delimiter.typedef) -(record_field_type ":" @punctuation.delimiter.typedef) +; This line should find it's place. Let us be patient with that. +(value_declaration (decl_left (identifier_pattern (identifier) @variable.parameter))) -(record_field_type (field_name) @variable.other.enum.typedef) -(ability_chain "&" @operator.typedef) +(annotation_type_def (annotation_pre_colon (identifier) @function) + (function_type)) +(bin_op_expr (operator "|>") (variable_expr (identifier) @function)) +(function_call_pnc_expr caller: (field_access_expr (identifier) @function .)) +(function_call_pnc_expr caller: (variable_expr (identifier) @function)) +(value_declaration (decl_left (identifier_pattern (identifier) @function)) + (expr_body (anon_fun_expr))) -(where_implements _ - (where) @type.keyword - (identifier) @type.parameter - (implements) @type.keyword - (ability_chain) @type.parameter) +[ + "dbg" +] @function.builtin +; N/A +; @function.macro -((concrete_type) @type.builtin - (#match? @type.builtin "^(Bool|Str|Num|List|Result|Dict|Set|Dec)")) -((concrete_type) @type.builtin - (#match? @type.builtin "^[IU](8|16|32|64|128)")) -((concrete_type) @type.builtin - (#match? @type.builtin "^F(32|64)")) +; N/A +; @function.method -(bound_variable) @type.parameter -(tags_type (apply_type(concrete_type) @type.enum.variant)) +; N/A +; @function.method.private + +; N/A +; @function.special -(concrete_type) @type -;;-----Punctuation---- + +; N/A +; @keyword + [ -"?" -(arrow) -(back_arrow) -(backslash) -] @punctuation.delimiter.structural -(bang_expr "!" @punctuation.delimiter.structural) + "app" + (as) + "as" + "expect" + "exposing" + (implements) + "module" + "package" + "platform" + (to) +] @keyword.control + [ - "," - ":" -] @punctuation.delimiter + "else" + "if" + (is) + "then" + (when) +] @keyword.control.conditional + +; N/A +; @keyword.control.exception + +[ + "import" +] @keyword.control.import + +; TODO: Implement this for `for` and `while`. +; @keyword.control.repeat +; TODO: Also implement this for `return`. +(suffix_operator "?" @keyword.control.return) + +; N/A +; @keyword.directive + +; N/A +; @keyword.function + +; TODO: Implement this for `and`, `or`, and any others. +; @keyword.operator + +; N/A +; @keyword.storage.modifier + +; TODO: Implement this for `var`. +; @keyword.storage.type + + + +; N/A +; @label + + + +[ + "=" + "." + "&" + ; "|" ; TODO: This conflicts with the `"|" @punctuation.bracket` query, so improve both. + "<-" + ".." + (wildcard_pattern) + (operator) +] @operator + + + +; N/A +; @punctuation [ "(" @@ -66,154 +211,131 @@ "}" "[" "]" - (interpolation_char) + "|" ; TODO: This conflicts with the `"|" @operator` query, so improve both. ] @punctuation.bracket [ - "|" - "&" - ".." - (operator) - (wildcard_pattern) -] @operator + "," + ":" + (arrow) + (fat_arrow) +] @punctuation.delimiter [ - "if" - "then" - "else" -] @keyword.control.conditional + (interpolation_char) +] @punctuation.special -[ -(implements) -(when) -(is) -"as" -(to) -] @keyword.control.roc -;----headers----- -[ - "app" - "expect" - "module" - "package" - "import" - ] @keyword.control +; N/A +; @special -;---annotations---- +; TODO: Differentiate between values, functions, and types. +(app_header (provides_list ((identifier) @special.roc-special.provided))) -(annotation_type_def - (annotation_pre_colon - (identifier)@function ) - (function_type)) +(app_header (packages_list ((platform_ref) @special.roc-special.package))) -(annotation_type_def - (annotation_pre_colon - (identifier)@parameter.definition )) +; TODO: Differentiate between values, functions, and types. +(import_expr (exposing ((ident) @special.roc-special.exposed))) -;----decleration types---- -(value_declaration(decl_left - (identifier_pattern - (identifier)@function.definition))(expr_body(anon_fun_expr))) -(value_declaration(decl_left - (identifier_pattern - (identifier) @parameter.definition))) +(multiline_string) @string +(string) @string -(backpassing_expr assignee: (identifier_pattern (identifier) @parameter.definition)) +; N/A +; @string.regexp -;----tags---- +; N/A +; @string.special -(tag)@constructor -(opaque_tag)@constructor +; N/A +; @string.special.path -;-----builtins---- +; N/A +; @string.special.symbol + +(app_header (packages_list (platform_ref ((package_uri) @string.special.url)))) -(variable_expr - (module)@module - (identifier)@constant.builtin.boolean - (#eq? @constant.builtin.boolean "true" ) - (#eq? @module "Bool" ) - ) -(variable_expr - (module)@module - (identifier)@constant.builtin.boolean - (#eq? @constant.builtin.boolean "false" ) - (#eq? @module "Bool" ) - ) -[ -"dbg" -] @constant.builtin -;----function invocations ---- -(function_call_expr - caller: (variable_expr - (identifier)@function)) -(function_call_expr - caller: (field_access_expr (identifier)@function .)) -(bin_op_expr (operator "|>")@operator(variable_expr(identifier)@function)) -;----function arguments---- +; N/A (We use `@constructor` and `@type.enum.variant` for "tags".) +; @tag -(argument_patterns(identifier_pattern - (identifier)@variable.parameter)) -(argument_patterns(_(identifier_pattern(identifier)@variable.parameter))) -(argument_patterns(_(_(identifier_pattern(identifier)@variable.parameter)))) -(argument_patterns(_(_(_(identifier_pattern(identifier)@variable.parameter))))) -(argument_patterns(_(_(_(_(identifier_pattern(identifier)@variable.parameter)))))) -(argument_patterns(_(_(_(_(_(identifier_pattern(identifier)@variable.parameter))))))) +; N/A +; @tag.builtin -; pattern captures -(when_is_branch pattern: (_ (identifier_pattern (identifier) @variable.parameter))) -(range_pattern (identifier) @variable.parameter) -;;----records---- +; Note: See the lower-priority queries below for a `@type` query. -(field_name)@variable.other.member -(record_field_pattern (_(identifier) @variable)) +((concrete_type) @type.builtin + (#match? @type.builtin "^(Bool|Box|Dec|Decode|Dict|Encode|Hash|Inspect|Int|List|Num|Result|Set|Str)")) +((concrete_type) @type.builtin + (#match? @type.builtin "^[IU](8|16|32|64|128)")) +((concrete_type) @type.builtin + (#match? @type.builtin "^(Dec|F(32|64))")) +; Opinion: Type defs cross into documentation +; and should be highlighted differently from normal code. +(opaque_type_def (_ (concrete_type) @type.definition)) +; N/A +; @type.enum -;matches the second identifier and all subsequent ones -(field_access_expr (identifier) @variable.other.member) +(tag_type) @type.enum.variant -;highlight module members as records instead of free variables -; avoids highlighting them as out-of-scope vars +(bound_variable) @type.parameter +(where_implements _ (where) (identifier) @type.parameter + (implements) (ability_chain) @type.parameter) + +(inferred) @type.roc-special.inferred + + + +; Note: See the lower-priority queries below for a `@variable` query. +(record_field_pattern (_ (identifier) @variable)) + +; N/A +; @variable.builtin + +; N/A +; @variable.other + +(field_name) @variable.other.member +; Note: This query matches the second identifier and all subsequent ones. +(field_access_expr (identifier) @variable.other.member) +; Note: This query highlights module members as records instead of free variables, +; which avoids highlighting them as out-of-scope vars. (variable_expr (module) (identifier) @variable.other.member) -;-----consts----- -[ - (int) - (uint) - (iint) - (xint) - (natural) -] @constant.numeric.integer -[ - (decimal) - (float) -] @constant.numeric.float +; N/A +; @variable.other.member.private -(string)@string -(multiline_string)@string -(char) @constant.character -(escape_char)@constant.character.escape - -;---keep most generic types at bottom for helix--- -;; #any-of? not working in the tree-sitter for helix 23.10 -((module) @namespace.builtin (#eq? @namespace.builtin "Bool")) -((module) @namespace.builtin (#eq? @namespace.builtin "Str")) -((module) @namespace.builtin (#eq? @namespace.builtin "Num")) -((module) @namespace.builtin (#eq? @namespace.builtin "List")) -((module) @namespace.builtin (#eq? @namespace.builtin "Result")) -((module) @namespace.builtin (#eq? @namespace.builtin "Dict")) -((module) @namespace.builtin (#eq? @namespace.builtin "Set")) -(module)@namespace -(module)@module - -(identifier)@variable +; (value_declaration (identifier_pattern (identifier) @variable.other.member)) +; (value_declaration (_ (identifier_pattern (identifier) @variable.other.member))) + +(argument_patterns (identifier_pattern (identifier) @variable.parameter)) +(argument_patterns (_ (identifier_pattern (identifier) @variable.parameter))) +(argument_patterns (_ (_ (identifier_pattern (identifier) @variable.parameter)))) +(argument_patterns (_ (_ (_ (identifier_pattern (identifier) @variable.parameter))))) +(argument_patterns (_ (_ (_ (_ (identifier_pattern (identifier) @variable.parameter)))))) +(argument_patterns (_ (_ (_ (_ (_ (identifier_pattern (identifier) @variable.parameter))))))) +(spread_pattern (identifier) @variable.parameter) +(when_is_branch pattern: (_ (identifier_pattern (identifier) @variable.parameter))) + + + +;; +;; Lower-priorty queries +;; + + + +(module) @namespace + +(concrete_type) @type +; this naughtly one was ruining everything +; (identifier) @variable diff --git a/languages/roc/injections.scm b/languages/roc/injections.scm index 47a8dde..64e55c2 100644 --- a/languages/roc/injections.scm +++ b/languages/roc/injections.scm @@ -1,5 +1,5 @@ ;injection from function calls -(function_call_expr +(function_call_pnc_expr (variable_expr (identifier) @injection.language) (const [(multiline_string) (string)] @injection.content) (#any-of? @injection.language diff --git a/languages/roc/locals.scm b/languages/roc/locals.scm index 4d25923..1f6d0d7 100644 --- a/languages/roc/locals.scm +++ b/languages/roc/locals.scm @@ -1,4 +1,6 @@ (expr_body) @local.scope +(file) @local.scope +(provides_list (identifier)@local.reference) (value_declaration(decl_left @@ -24,7 +26,7 @@ (alias_type_def(apply_type(concrete_type)@local.definition)) (when_is_branch pattern: (_ (identifier_pattern (identifier) @local.definition))) -(range_pattern (identifier) @local.definition) +(spread_pattern (identifier) @local.definition) (identifier)@local.reference (tag_expr(tag))@local.reference diff --git a/languages/roc/tags.scm b/languages/roc/tags.scm index 4876067..97cf189 100644 --- a/languages/roc/tags.scm +++ b/languages/roc/tags.scm @@ -1,9 +1,9 @@ ; Function calls -(function_call_expr +(function_call_pnc_expr caller: (variable_expr (identifier)@name ))@reference.call -(function_call_expr +(function_call_pnc_expr caller: (field_access_expr (identifier)@name .))@reference.call ; Function definitions diff --git a/languages/roc/textobjects.scm b/languages/roc/textobjects.scm index 0e053f7..51797c4 100644 --- a/languages/roc/textobjects.scm +++ b/languages/roc/textobjects.scm @@ -10,13 +10,13 @@ ((_) @parameter.inside . ","? @parameter.around) @parameter.around(#not-eq? @parameter.inside "->") ) -(function_call_expr +(function_call_pnc_expr . (_) (parenthesized_expr (expr_body) @parameter.inside) @parameter.around ) -(function_call_expr +(function_call_pnc_expr . (_) ((_) @parameter.inside) @parameter.around )