Unnamed repository; edit this file 'description' to name the repository.
Add support for Teal language (#12081)
Co-authored-by: Michael Davis <[email protected]>
barsoosayque 2024-12-05
parent 07e7e75 · commit cd972ae
-rw-r--r--book/src/generated/lang-support.md1
-rw-r--r--languages.toml15
-rw-r--r--runtime/queries/teal/folds.scm15
-rw-r--r--runtime/queries/teal/highlights.scm170
-rw-r--r--runtime/queries/teal/locals.scm25
5 files changed, 226 insertions, 0 deletions
diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md
index 08122563..4d9c24e6 100644
--- a/book/src/generated/lang-support.md
+++ b/book/src/generated/lang-support.md
@@ -208,6 +208,7 @@
| tact | ✓ | ✓ | ✓ | |
| task | ✓ | | | |
| tcl | ✓ | | ✓ | |
+| teal | ✓ | | | |
| templ | ✓ | | | `templ` |
| textproto | ✓ | ✓ | ✓ | |
| tfvars | ✓ | | ✓ | `terraform-ls` |
diff --git a/languages.toml b/languages.toml
index 2fab0053..812b145f 100644
--- a/languages.toml
+++ b/languages.toml
@@ -123,6 +123,7 @@ tinymist = { command = "tinymist" }
pkgbuild-language-server = { command = "pkgbuild-language-server" }
helm_ls = { command = "helm_ls", args = ["serve"] }
ember-language-server = { command = "ember-language-server", args = ["--stdio"] }
+teal-language-server = { command = "teal-language-server" }
[language-server.ansible-language-server]
command = "ansible-language-server"
@@ -1297,6 +1298,20 @@ language-servers = [ "lua-language-server" ]
name = "lua"
source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-lua", rev = "88e446476a1e97a8724dff7a23e2d709855077f2" }
+[[grammar]]
+name = "teal"
+source = { git = "https://github.com/euclidianAce/tree-sitter-teal", rev = "3db655924b2ff1c54fdf6371b5425ea6b5dccefe" }
+
+[[language]]
+name = "teal"
+scope = "source.tl"
+injection-regex = "teal"
+file-types = ["tl"]
+comment-tokens = "--"
+block-comment-tokens = { start = "--[[", end = "--]]" }
+roots = [ "tlconfig.lua" ]
+language-servers = [ "teal-lsp" ]
+
[[language]]
name = "svelte"
scope = "source.svelte"
diff --git a/runtime/queries/teal/folds.scm b/runtime/queries/teal/folds.scm
new file mode 100644
index 00000000..e756719a
--- /dev/null
+++ b/runtime/queries/teal/folds.scm
@@ -0,0 +1,15 @@
+[
+(do_statement)
+(numeric_for_statement)
+(generic_for_statement)
+(while_statement)
+(repeat_statement)
+(if_statement)
+(function_statement)
+(record_declaration)
+(interface_declaration)
+(enum_declaration)
+(anon_function)
+(table_constructor)
+] @fold
+
diff --git a/runtime/queries/teal/highlights.scm b/runtime/queries/teal/highlights.scm
new file mode 100644
index 00000000..0aa41b19
--- /dev/null
+++ b/runtime/queries/teal/highlights.scm
@@ -0,0 +1,170 @@
+
+;; Primitives
+(boolean) @constant.builtin.boolean
+(comment) @comment
+(shebang_comment) @comment
+(identifier) @variable
+((identifier) @variable.builtin
+ (#eq? @variable.builtin "self"))
+(nil) @constant.builtin
+(number) @constant.numeric
+(string) @string
+(table_constructor ["{" "}"] @constructor)
+(varargs "..." @constant.builtin)
+[ "," "." ":" ";" ] @punctuation.delimiter
+
+(escape_sequence) @constant.character.escape
+(format_specifier) @constant.character.escape
+
+;; Basic statements/Keywords
+[ "if" "then" "elseif" "else" ] @keyword.control.conditional
+[ "for" "while" "repeat" "until" "do" ] @keyword.control.repeat
+[ "end" ] @keyword
+[ "in" ] @keyword.operator
+[ "local" ] @keyword.storage.type
+[ (break) (goto) ] @keyword.control
+[ "return" ] @keyword.control.return
+(label) @label
+
+;; Global isn't a real keyword, but it gets special treatment in these places
+(var_declaration "global" @keyword.storage.type)
+(type_declaration "global" @keyword.storage.type)
+(function_statement "global" @keyword.storage.type)
+(record_declaration "global" @keyword.storage.type)
+(interface_declaration "global" @keyword.storage.type)
+(enum_declaration "global" @keyword.storage.type)
+
+(macroexp_statement "macroexp" @keyword)
+
+;; Ops
+(bin_op (op) @operator)
+(unary_op (op) @operator)
+[ "=" "as" ] @operator
+
+;; Functions
+(function_statement
+ "function" @keyword.function
+ . name: (_) @function)
+(anon_function
+ "function" @keyword.function)
+(function_body "end" @keyword.function)
+
+(arg name: (identifier) @variable.parameter)
+
+(function_signature
+ (arguments
+ . (arg name: (identifier) @variable.builtin))
+ (#eq? @variable.builtin "self"))
+
+(typeargs
+ "<" @punctuation.bracket
+ . (_) @type.parameter
+ . ("," . (_) @type.parameter)*
+ . ">" @punctuation.bracket)
+
+(function_call
+ (identifier) @function . (arguments))
+(function_call
+ (index (_) key: (identifier) @function) . (arguments))
+(function_call
+ (method_index (_) key: (identifier) @function) . (arguments))
+
+;; Types
+
+; Contextual keywords in record bodies
+(record_declaration
+ . [ "record" ] @keyword.storage.type
+ name: (identifier) @type)
+(anon_record . "record" @keyword.storage.type)
+(record_body
+ (record_declaration
+ . [ "record" ] @keyword.storage.type
+ . name: (identifier) @type))
+(record_body
+ (enum_declaration
+ . [ "enum" ] @keyword.storage.type
+ . name: (identifier) @type.enum))
+(record_body
+ (interface_declaration
+ . [ "interface" ] @keyword.storage.type
+ . name: (identifier) @type))
+(record_body
+ (typedef
+ . "type" @keyword.storage.type
+ . name: (identifier) @type . "="))
+(record_body
+ (macroexp_declaration
+ . [ "macroexp" ] @keyword.storage.type))
+(record_body (metamethod "metamethod" @keyword.storage.modifier))
+(record_body (userdata) @keyword.storage.modifier)
+
+; Contextual keywords in interface bodies
+(interface_declaration
+ . [ "interface" ] @keyword.storage.type
+ name: (identifier) @type)
+(anon_interface . "interface" @keyword.storage.type)
+(interface_body
+ (record_declaration
+ . [ "record" ] @keyword.storage.type
+ . name: (identifier) @type))
+(interface_body
+ (enum_declaration
+ . [ "enum" ] @keyword.storage.type
+ . name: (identifier) @type.enum))
+(interface_body
+ (interface_declaration
+ . [ "interface" ] @keyword.storage.type
+ . name: (identifier) @type))
+(interface_body
+ (typedef
+ . "type" @keyword.storage.type
+ . name: (identifier) @type . "="))
+(interface_body
+ (macroexp_declaration
+ . [ "macroexp" ] @keyword.storage.type))
+(interface_body (metamethod "metamethod" @keyword.storage.modifier))
+(interface_body (userdata) @keyword.storage.modifier)
+
+(enum_declaration
+ "enum" @keyword.storage.type
+ name: (identifier) @type.enum)
+
+(type_declaration "type" @keyword.storage.type)
+(type_declaration (identifier) @type)
+(simple_type) @type
+(type_index) @type
+(type_union "|" @operator)
+(function_type "function" @type)
+
+;; The rest of it
+(var_declaration
+ declarators: (var_declarators
+ (var name: (identifier) @variable)))
+(var_declaration
+ declarators: (var_declarators
+ (var
+ "<" @punctuation.bracket
+ . attribute: (attribute) @attribute
+ . ">" @punctuation.bracket)))
+[ "(" ")" "[" "]" "{" "}" ] @punctuation.bracket
+
+;; Only highlight format specifiers in calls to string.format
+;; string.format('...')
+;(function_call
+; called_object: (index
+; (identifier) @base
+; key: (identifier) @entry)
+; arguments: (arguments .
+; (string (format_specifier) @string.escape))
+;
+; (#eq? @base "string")
+; (#eq? @entry "format"))
+
+;; ('...'):format()
+;(function_call
+; called_object: (method_index
+; (string (format_specifier) @string.escape)
+; key: (identifier) @func-name)
+; (#eq? @func-name "format"))
+
+
diff --git a/runtime/queries/teal/locals.scm b/runtime/queries/teal/locals.scm
new file mode 100644
index 00000000..879aa71c
--- /dev/null
+++ b/runtime/queries/teal/locals.scm
@@ -0,0 +1,25 @@
+
+(var_declaration
+ declarators: (var_declarators
+ (var (identifier)) @local.definition))
+
+(var_assignment
+ variables: (assignment_variables
+ (var (identifier) @local.definition)))
+
+(arg name: (identifier) @local.definition)
+
+(anon_function) @local.scope
+((function_statement
+ (function_name) @local.definition) @local.scope)
+
+(program) @local.scope
+(if_statement) @local.scope
+(generic_for_statement (for_body) @local.scope)
+(numeric_for_statement (for_body) @local.scope)
+(repeat_statement) @local.scope
+(while_statement (while_body) @local.scope)
+(do_statement) @local.scope
+
+(identifier) @local.reference
+