diff --git a/book/src/themes.md b/book/src/themes.md index 46d0a2d3c..3ef064d6d 100644 --- a/book/src/themes.md +++ b/book/src/themes.md @@ -174,6 +174,7 @@ We use a similar set of scopes as - `documentation` - Line documentation comments (e.g. `///` in Rust) - `block` - Block comments (e.g. (`/* */`) - `documentation` - Block documentation comments (e.g. `/** */` in Rust) + - `unused` - Unused variables and patterns, e.g. `_` and `_foo` - `variable` - Variables - `builtin` - Reserved language variables (`self`, `this`, `super`, etc.) diff --git a/languages.toml b/languages.toml index 6ea02d55b..78c5561fb 100644 --- a/languages.toml +++ b/languages.toml @@ -2080,14 +2080,14 @@ scope = "source.gleam" injection-regex = "gleam" file-types = ["gleam"] roots = ["gleam.toml"] -comment-token = "//" +comment-tokens = ["//", "///", "////"] indent = { tab-width = 2, unit = " " } language-servers = [ "gleam" ] auto-format = true [[grammar]] name = "gleam" -source = { git = "https://github.com/gleam-lang/tree-sitter-gleam", rev = "6ece453acf8b14568c10f629f8cd25d3dde3794f" } +source = { git = "https://github.com/gleam-lang/tree-sitter-gleam", rev = "ee93c639dc82148d716919df336ad612fd33538e" } [[language]] name = "quarto" diff --git a/runtime/queries/gleam/highlights.scm b/runtime/queries/gleam/highlights.scm index 961afc344..cc2c93e7c 100644 --- a/runtime/queries/gleam/highlights.scm +++ b/runtime/queries/gleam/highlights.scm @@ -1,11 +1,12 @@ ; Variables (identifier) @variable -(discard) @comment.unused +(discard) @comment.unused ; `_` pattern +(hole) @comment.unused ; `_`, `_foo` unused variable ; Comments -(module_comment) @comment -(statement_comment) @comment -(comment) @comment +(module_comment) @comment.line.documentation +(statement_comment) @comment.line.documentation +(comment) @comment.line ; Constants (constant @@ -23,7 +24,10 @@ field: (label) @function) (#is-not? local)) +; ========= ; Functions +; ========= + (unqualified_import (identifier) @function) (unqualified_import "type" (type_identifier) @type) (unqualified_import (type_identifier) @constructor) @@ -41,6 +45,10 @@ right: (identifier) @function) (#is-not? local)) +; ========= +; Misc +; ========= + ; "Properties" ; Assumed to be intended to refer to a name for a field; something that comes ; before ":" or after "." @@ -56,27 +64,55 @@ (attribute_value (identifier) @constant) +; ========= +; Types +; ========= + +(type_hole) @comment.unused + ; Type names (remote_type_identifier) @type (type_identifier) @type +; Generic types +[ + ; in `pub type Dict(key, value)` this is `key` and `value` + (type_parameter) + ; in `pub fn size(dict: Dict(key, value)) -> Int` this is `key` and `value` + (type_var) +] @type + ; Data constructors (constructor_name) @constructor +; built-ins +((constructor_name) @constant.builtin + (#any-of? @constant.builtin "False" "True")) +((constructor_name) @constant.builtin + (#any-of? @constant.builtin "Nil")) +((constructor_name) @type.enum.variant.builtin + (#any-of? @type.enum.variant.builtin "Ok" "Error" "Some" "None")) + +; ========= ; Literals +; ========= + (string) @string +(escape_sequence) @constant.character.escape ((escape_sequence) @warning (#eq? @warning "\\e")) ; deprecated escape sequence -(escape_sequence) @constant.character.escape (bit_string_segment_option) @function.builtin (integer) @constant.numeric.integer (float) @constant.numeric.float ; Reserved identifiers ((identifier) @error - (#any-of? @error "auto" "delegate" "derive" "else" "implement" "macro" "test" "echo")) + (#any-of? @error "auto" "delegate" "derive" "else" "implement" "macro" "test")) +; ========= ; Keywords +; ========= + [ (visibility_modifier) ; "pub" (opacity_modifier) ; "opaque" @@ -94,15 +130,32 @@ "todo" "type" "use" + "echo" ] @keyword +; ========= ; Operators +; ========= + (binary_expression operator: _ @operator) (boolean_negation "!" @operator) (integer_negation "-" @operator) +[ + "->" + "-" + "=" + ".." + "<-" + ; OR clause in patterns + "|" +] @operator + +; ========== ; Punctuation +; ========== + [ "(" ")" @@ -113,15 +166,23 @@ "<<" ">>" ] @punctuation.bracket + +(tuple_type "#" @punctuation.bracket) +(tuple "#" @punctuation.bracket) +(tuple_pattern "#" @punctuation.bracket) + +[ + "," + ":" +] @punctuation.delimiter + +; the `/` in `import gleam/list` +(import (module "/" @punctuation.delimiter)) + [ "." - "," - ;; Controversial -- maybe some are operators? - ":" - "#" - "=" - "->" - ".." - "-" - "<-" -] @punctuation.delimiter +] @punctuation + +; affects e.g. `replace` in `string.replace("+", "-")` +; without this, it would be highlighted as a field instead of function +(function_call (field_access (label) @function)) diff --git a/runtime/queries/gleam/injections.scm b/runtime/queries/gleam/injections.scm index ac82a3e5f..22039b627 100644 --- a/runtime/queries/gleam/injections.scm +++ b/runtime/queries/gleam/injections.scm @@ -1,3 +1,7 @@ ((comment) @injection.content (#set! injection.language "comment")) +; Inject markdown into documentation comments +((doc_comment_content) @injection.content + (#set! injection.language "markdown") + (#set! injection.combined))