diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index c09d934e5..dad557d96 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -30,7 +30,7 @@ | common-lisp | ✓ | | ✓ | `cl-lsp` | | cpon | ✓ | | ✓ | | | cpp | ✓ | ✓ | ✓ | `clangd` | -| crystal | ✓ | ✓ | | `crystalline` | +| crystal | ✓ | ✓ | ✓ | `crystalline`, `ameba-ls` | | css | ✓ | | ✓ | `vscode-css-language-server` | | csv | ✓ | | | | | cue | ✓ | | | `cuelsp` | diff --git a/languages.toml b/languages.toml index 91c5da666..6ea02d55b 100644 --- a/languages.toml +++ b/languages.toml @@ -9,6 +9,7 @@ ada-gpr-language-server = {command = "ada_language_server", args = ["--language- ada-language-server = { command = "ada_language_server" } als = { command = "als" } amber-lsp = { command = "amber-lsp" } +ameba-ls = { command = "ameba-ls" } angular = {command = "ngserver", args = ["--stdio", "--tsProbeLocations", ".", "--ngProbeLocations", ".",]} asm-lsp = { command = "asm-lsp" } awk-language-server = { command = "awk-language-server" } @@ -647,10 +648,13 @@ file-types = ["cr"] roots = ["shard.yml", "shard.lock"] comment-token = "#" indent = { tab-width = 2, unit = " " } -grammar = "ruby" -language-servers = [ "crystalline" ] +language-servers = [ "crystalline", "ameba-ls" ] formatter = { command = "crystal", args = ["tool", "format", "-"] } +[[grammar]] +name = "crystal" +source = { git = "https://github.com/crystal-lang-tools/tree-sitter-crystal", rev = "76afc1f53518a2b68b51a5abcde01d268a9cb47c" } + [[language]] name = "c-sharp" scope = "source.csharp" diff --git a/runtime/queries/crystal/highlights.scm b/runtime/queries/crystal/highlights.scm index 571542863..0845479bc 100644 --- a/runtime/queries/crystal/highlights.scm +++ b/runtime/queries/crystal/highlights.scm @@ -1 +1,300 @@ -; inherits: ruby +[ + "," + ";" + "." + ":" + "*" + "**" +] @punctuation.delimiter + +[ + "alias" + "alignof" + "annotation" + "asm" + "begin" + "case" + "def" + "do" + "end" + "extend" + "forall" + "fun" + "in" + "include" + "instance_alignof" + "instance_sizeof" + "macro" + "of" + "offsetof" + "out" + "pointerof" + "select" + "sizeof" + "then" + "type" + "typeof" + "uninitialized" + "verbatim" + "when" + "with" +] @keyword + +[ + "else" + "elsif" + "if" + "unless" +] @keyword.control.conditional + +[ + "for" + "until" + "while" +] @keyword.control.repeat + +["require"] @keyword.control.import + +[ + "break" + "next" + "return" + "yield" +] @keyword.control.return + +[ + "ensure" + "rescue" +] @keyword.control.exception + +[ + "class" + "enum" + "lib" + "module" + "struct" + "union" +] @keyword.storage.type + +(conditional + [ + "?" + ":" + ] @keyword.control.conditional) + +[ + (private) + (protected) + "abstract" +] @keyword + +(pseudo_constant) @constant.builtin + +; literals +(char + ["'" (literal_content)] @string) + +(char + (escape_sequence) @constant.character.escape) + +(string + ["\"" (literal_content)] @string) + +(string + (escape_sequence) @constant.character.escape) + +(symbol + [ + ":" + ":\"" + "\"" + (literal_content) + ] @string.special.symbol) + +(symbol + (escape_sequence) @constant.character.escape) + +(command + ["`" (literal_content)] @string.special) + +(command + (escape_sequence) @constant.character.escape) + +(regex + "/" @punctuation.bracket) + +(regex + (literal_content) @string.regexp) + +(regex_modifier) @string.special.symbol + +(heredoc_body + (literal_content) @string) + +(heredoc_body + (escape_sequence) @constant.character.escape) + +[ + (heredoc_start) + (heredoc_end) +] @string.symbol + +(integer) @constant.numeric.integer +(float) @constant.numeric.float + +[ + (true) + (false) + (nil) + (self) +] @variable.builtin + +( + (comment)+ @comment.block.documentation + . + [ + (class_def) + (struct_def) + (method_def) + (abstract_method_def) + (macro_def) + (module_def) + (enum_def) + (annotation_def) + (lib_def) + (type_def) + (c_struct_def) + (union_def) + (alias) + (const_assign) + ] +) + +(comment) @comment + +; Operators and punctuation +[ + "=" + "=>" + "->" + "&" + (operator) +] @operator + +[ + "(" + ")" + "[" + "@[" + "]" + "{" + "}" +] @punctuation.bracket + +(index_call + method: (operator) @punctuation.bracket + [ + "]" + "]?" + ] @punctuation.bracket) + +(block + "|" @punctuation.bracket) + +[ + "{%" + "%}" + "{{" + "}}" +] @keyword.directive + +(interpolation + "#{" @punctuation.special + "}" @punctuation.special) + +; TODO: {splat,double_splat,block,fun}_param + rescue param + +; Types + +(nilable_constant + "?" @type) + +(nilable_type + "?" @type) + +(union_type + "|" @operator) + +(annotation + (constant) @attribute) + +(identifier) @variable +(param name: (identifier) @variable.parameter) + +(method_def + name: (identifier) @function.method) + +(macro_def + name: (identifier) @function.method) + +(abstract_method_def + name: (identifier) @function.method) + +(fun_def + name: (identifier) @function.method + real_name: (identifier)? @function.method) + +(macro_var) @variable + +[ + (class_var) + (instance_var) +] @variable.other.member + +(named_expr + name: (identifier) @variable.other.member + ":" @variable.other.member) + +(named_type + name: (identifier) @variable.other.member) + +(underscore) @variable.special + +; function calls + +(call + method: (_) @keyword + arguments: (argument_list + [ + (type_declaration + var: (_) @function.method) + (assign + lhs: (_) @function.method) + (_) @function.method + ]) + (#match? @keyword "^(class_)?(getter|setter|property)[?!]?$")) + +(call + method: (_) @keyword + (#match? @keyword "^(record|is_a\\?|as|as\\?|responds_to\\?|nil\\?|\\!)$")) + +(call + method: (_) @function.method) + +(implicit_object_call + method: (_) @function.method) + +(method_proc + method: (_) @function.method) + +(assign_call + method: (_) @function.method) + +((identifier) @variable.builtin + (#match? @variable.builtin "^(previous_def|super)$")) + +[ + (constant) + (generic_instance_type) + (generic_type) +] @type diff --git a/runtime/queries/crystal/indents.scm b/runtime/queries/crystal/indents.scm new file mode 100644 index 000000000..75d61953c --- /dev/null +++ b/runtime/queries/crystal/indents.scm @@ -0,0 +1,29 @@ +[ + (param_list) + (array) + (block) + (call) + (class_def) + (struct_def) + (module_def) + (enum_def) + (lib_def) + (fun_def) + (method_def) + (case) + (select) + (elsif) + (if) + (unless) + (hash) + (tuple) +] @indent + +[ + ")" + "}" + "]" + "end" + "when" + "in" +] @outdent diff --git a/runtime/queries/crystal/injections.scm b/runtime/queries/crystal/injections.scm index 571542863..1be5e4975 100644 --- a/runtime/queries/crystal/injections.scm +++ b/runtime/queries/crystal/injections.scm @@ -1 +1,11 @@ -; inherits: ruby +((heredoc_body + (literal_content) @injection.content + (heredoc_end) @name + (#set! injection.language "sql")) + (#eq? @name "SQL")) + +((heredoc_body + (literal_content) @injection.content + (heredoc_end) @name + (#set! injection.language "html")) + (#eq? @name "HTML")) diff --git a/runtime/queries/crystal/locals.scm b/runtime/queries/crystal/locals.scm index 571542863..b44fd3a07 100644 --- a/runtime/queries/crystal/locals.scm +++ b/runtime/queries/crystal/locals.scm @@ -1 +1,14 @@ -; inherits: ruby +((method_def) @local.scope + (#set! local.scope-inherits false)) +((fun_def) @local.scope + (#set! local.scope-inherits false)) + +(block) @local.scope + +(param + name: (identifier) @local.definition.variable.parameter) + +(assign + lhs: (identifier) @local.definition.variable) + +(identifier) @local.reference diff --git a/runtime/queries/crystal/tags.scm b/runtime/queries/crystal/tags.scm new file mode 100644 index 000000000..33fbefc93 --- /dev/null +++ b/runtime/queries/crystal/tags.scm @@ -0,0 +1 @@ +;; diff --git a/runtime/queries/crystal/textobjects.scm b/runtime/queries/crystal/textobjects.scm index 571542863..f05574fcb 100644 --- a/runtime/queries/crystal/textobjects.scm +++ b/runtime/queries/crystal/textobjects.scm @@ -1 +1,38 @@ -; inherits: ruby +(class_def + name: (_) + (_) @class.inside) @class.around + +(struct_def + name: (_) + (_) @class.inside) @class.around + +(module_def + name: (_) + (_) @class.inside) @class.around + +(lib_def + name: (_) + (_) @class.inside) @class.around + +(enum_def + name: (_) + (_) @class.inside) @class.around + +(block + params: (_) @parameter.inside) @parameter.around + +(method_def + params: (_) @parameter.inside) @parameter.around + +(method_def + name: (_) + (_) @function.inside) @function.around + +(block + (_) @function.inside) @function.around + +(comment) @comment.inside +(comment)+ @comment.around + +(array + (_) @entry.around)