aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNovus Nota2024-02-04 01:09:11 +0000
committerGitHub2024-02-04 01:09:11 +0000
commitd1054de3ced44903c7bdcf5886d8481eb40a948f (patch)
treec02d4845b68072a94f1daff489043f9d3f7394f8
parent3f380722fbb2fd676ccc0a9dbbea4ddc4871c6ea (diff)
feat: Add `Tact` language support (#9512)
Re-submitting
-rw-r--r--book/src/generated/lang-support.md1
-rw-r--r--languages.toml19
-rw-r--r--runtime/queries/tact/highlights.scm298
-rw-r--r--runtime/queries/tact/indents.scm38
-rw-r--r--runtime/queries/tact/injections.scm5
-rw-r--r--runtime/queries/tact/locals.scm35
-rw-r--r--runtime/queries/tact/textobjects.scm58
7 files changed, 454 insertions, 0 deletions
diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md
index a78dd793..e7d29cc7 100644
--- a/book/src/generated/lang-support.md
+++ b/book/src/generated/lang-support.md
@@ -162,6 +162,7 @@
| swift | ✓ | | | `sourcekit-lsp` |
| t32 | ✓ | | | |
| tablegen | ✓ | ✓ | ✓ | |
+| tact | ✓ | ✓ | ✓ | |
| task | ✓ | | | |
| templ | ✓ | | | `templ` |
| tfvars | ✓ | | ✓ | `terraform-ls` |
diff --git a/languages.toml b/languages.toml
index 1f26f168..e601c20d 100644
--- a/languages.toml
+++ b/languages.toml
@@ -3042,3 +3042,22 @@ indent = { tab-width = 2, unit = " " }
[[grammar]]
name = "hocon"
source = { git = "https://github.com/antosha417/tree-sitter-hocon", rev = "c390f10519ae69fdb03b3e5764f5592fb6924bcc" }
+
+[[language]]
+name = "tact"
+scope = "source.tact"
+injection-regex = "tact"
+file-types = ["tact"]
+comment-token = "//"
+indent = { tab-width = 4, unit = " " }
+
+[language.auto-pairs]
+'"' = '"'
+'{' = '}'
+'(' = ')'
+'<' = '>'
+
+[[grammar]]
+name = "tact"
+source = { git = "https://github.com/tact-lang/tree-sitter-tact", rev = "ec57ab29c86d632639726631fb2bb178d23e1c91" }
+
diff --git a/runtime/queries/tact/highlights.scm b/runtime/queries/tact/highlights.scm
new file mode 100644
index 00000000..53bf985b
--- /dev/null
+++ b/runtime/queries/tact/highlights.scm
@@ -0,0 +1,298 @@
+; See: https://docs.helix-editor.com/master/themes.html#syntax-highlighting
+; -------------------------------------------------------------------------
+
+; attribute
+; ---------
+
+[
+ "@name"
+ "@interface"
+] @attribute
+
+; comment.line
+; ------------
+
+((comment) @comment.line
+ (#match? @comment.line "^//"))
+
+; comment.block
+; -------------
+
+(comment) @comment.block
+
+; function.builtin
+; ----------------
+
+((identifier) @function.builtin
+ (#any-of? @function.builtin
+ "send" "sender" "require" "now"
+ "myBalance" "myAddress" "newAddress"
+ "contractAddress" "contractAddressExt"
+ "emit" "cell" "ton"
+ "beginString" "beginComment" "beginTailString" "beginStringFromBuilder" "beginCell" "emptyCell"
+ "randomInt" "random"
+ "checkSignature" "checkDataSignature" "sha256"
+ "min" "max" "abs" "pow"
+ "throw" "dump" "getConfigParam"
+ "nativeThrowWhen" "nativeThrowUnless" "nativeReserve"
+ "nativeRandomize" "nativeRandomizeLt" "nativePrepareRandom" "nativeRandom" "nativeRandomInterval")
+ (#is-not? local))
+
+; function.method
+; ---------------
+
+(method_call_expression
+ name: (identifier) @function.method)
+
+; function
+; --------
+
+(func_identifier) @function
+
+(native_function
+ name: (identifier) @function)
+
+(static_function
+ name: (identifier) @function)
+
+(static_call_expression
+ name: (identifier) @function)
+
+(init_function
+ "init" @function.method)
+
+(receive_function
+ "receive" @function.method)
+
+(bounced_function
+ "bounced" @function.method)
+
+(external_function
+ "external" @function.method)
+
+(function
+ name: (identifier) @function.method)
+
+; keyword.control.conditional
+; ---------------------------
+
+[
+ "if" "else"
+] @keyword.control.conditional
+
+; keyword.control.repeat
+; ----------------------
+
+[
+ "while" "repeat" "do" "until"
+] @keyword.control.repeat
+
+; keyword.control.import
+; ----------------------
+
+"import" @keyword.control.import
+
+; keyword.control.return
+; ----------------------
+
+"return" @keyword.control.return
+
+; keyword.operator
+; ----------------
+
+"initOf" @keyword.operator
+
+; keyword.directive
+; -----------------
+
+"primitive" @keyword.directive
+
+; keyword.function
+; ----------------
+
+[
+ "fun"
+ "native"
+] @keyword.function
+
+; keyword.storage.type
+; --------------------
+
+[
+ "contract" "trait" "struct" "message" "with"
+ "const" "let"
+] @keyword.storage.type
+
+; keyword.storage.modifier
+; ------------------------
+
+[
+ "get" "mutates" "extends" "virtual" "override" "inline" "abstract"
+] @keyword.storage.modifier
+
+; keyword
+; -------
+
+[
+ "with"
+ ; "public" ; -- not used, but declared in grammar.ohm
+ ; "extend" ; -- not used, but declared in grammar.ohm
+] @keyword
+
+; constant.builtin.boolean
+; ------------------------
+
+(boolean) @constant.builtin.boolean
+
+; constant.builtin
+; ----------------
+
+((identifier) @constant.builtin
+ (#any-of? @constant.builtin
+ "SendPayGasSeparately"
+ "SendIgnoreErrors"
+ "SendDestroyIfZero"
+ "SendRemainingValue"
+ "SendRemainingBalance")
+ (#is-not? local))
+
+(null) @constant.builtin
+
+; constant.numeric.integer
+; ------------------------
+
+(integer) @constant.numeric.integer
+
+; constant
+; --------
+
+(constant
+ name: (identifier) @constant)
+
+; string.special.path
+; -------------------
+
+(import_statement
+ library: (string) @string.special.path)
+
+; string
+; ------
+
+(string) @string
+
+; type.builtin
+; ------------
+
+(tlb_serialization
+ "as" @keyword
+ type: (identifier) @type.builtin
+ (#any-of? @type.builtin
+ "int8" "int16" "int32" "int64" "int128" "int256" "int257"
+ "uint8" "uint16" "uint32" "uint64" "uint128" "uint256"
+ "coins" "remaining" "bytes32" "bytes64"))
+
+((type_identifier) @type.builtin
+ (#any-of? @type.builtin
+ "Address" "Bool" "Builder" "Cell" "Int" "Slice" "String" "StringBuilder"))
+
+(map_type
+ "map" @type.builtin
+ "<" @punctuation.bracket
+ ">" @punctuation.bracket)
+
+(bounced_type
+ "bounced" @type.builtin
+ "<" @punctuation.bracket
+ ">" @punctuation.bracket)
+
+((identifier) @type.builtin
+ (#eq? @type.builtin "SendParameters")
+ (#is-not? local))
+
+; type
+; ----
+
+(type_identifier) @type
+
+; constructor
+; -----------
+
+(instance_expression
+ name: (identifier) @constructor)
+
+(initOf
+ name: (identifier) @constructor)
+
+; operator
+; --------
+
+[
+ "-" "-="
+ "+" "+="
+ "*" "*="
+ "/" "/="
+ "%" "%="
+ "=" "=="
+ "!" "!=" "!!"
+ "<" "<=" "<<"
+ ">" ">=" ">>"
+ "&" "|"
+ "&&" "||"
+] @operator
+
+; punctuation.bracket
+; -------------------
+
+[
+ "(" ")"
+ "{" "}"
+] @punctuation.bracket
+
+; punctuation.delimiter
+; ---------------------
+
+[
+ ";"
+ ","
+ "."
+ ":"
+ "?"
+] @punctuation.delimiter
+
+; variable.other.member
+; ---------------------
+
+(field
+ name: (identifier) @variable.other.member)
+
+(contract_body
+ (constant
+ name: (identifier) @variable.other.member))
+
+(trait_body
+ (constant
+ name: (identifier) @variable.other.member))
+
+(field_access_expression
+ name: (identifier) @variable.other.member)
+
+(lvalue (_) (_) @variable.other.member)
+
+(instance_argument
+ name: (identifier) @variable.other.member)
+
+; variable.parameter
+; ------------------
+
+(parameter
+ name: (identifier) @variable.parameter)
+
+; variable.builtin
+; ----------------
+
+(self) @variable.builtin
+
+; variable
+; --------
+
+(identifier) @variable
diff --git a/runtime/queries/tact/indents.scm b/runtime/queries/tact/indents.scm
new file mode 100644
index 00000000..62c532b2
--- /dev/null
+++ b/runtime/queries/tact/indents.scm
@@ -0,0 +1,38 @@
+; indent
+; ------
+
+[
+ ; (..., ...)
+ (parameter_list)
+ (argument_list)
+
+ ; {..., ...}
+ (instance_argument_list)
+
+ ; {...; ...}
+ (message_body)
+ (struct_body)
+ (contract_body)
+ (trait_body)
+ (function_body)
+ (block_statement)
+
+ ; misc.
+ (binary_expression)
+ (return_statement)
+] @indent
+
+; outdent
+; -------
+
+[
+ "}"
+ ")"
+ ">"
+] @outdent
+
+; indent.always
+; outdent.always
+; align
+; extend
+; extend.prevent-once \ No newline at end of file
diff --git a/runtime/queries/tact/injections.scm b/runtime/queries/tact/injections.scm
new file mode 100644
index 00000000..e61db3a5
--- /dev/null
+++ b/runtime/queries/tact/injections.scm
@@ -0,0 +1,5 @@
+; See: https://docs.helix-editor.com/guides/injection.html
+
+((comment) @injection.content
+ (#set! injection.language "comment")
+ (#match? @injection.content "^//")) \ No newline at end of file
diff --git a/runtime/queries/tact/locals.scm b/runtime/queries/tact/locals.scm
new file mode 100644
index 00000000..f1b3e8de
--- /dev/null
+++ b/runtime/queries/tact/locals.scm
@@ -0,0 +1,35 @@
+; See: https://tree-sitter.github.io/tree-sitter/syntax-highlighting#local-variables
+
+; Scopes @local.scope
+; -------------------------
+
+[
+ (static_function)
+ (init_function)
+ (bounced_function)
+ (receive_function)
+ (external_function)
+ (function)
+ (block_statement)
+] @local.scope
+
+; Definitions @local.definition
+; ------------------------------
+
+(let_statement
+ name: (identifier) @local.definition)
+
+(parameter
+ name: (identifier) @local.definition)
+
+(constant
+ name: (identifier) @local.definition)
+
+; References @local.reference
+; -----------------------------
+
+(self) @local.reference
+
+(value_expression (identifier) @local.reference)
+
+(lvalue (identifier) @local.reference)
diff --git a/runtime/queries/tact/textobjects.scm b/runtime/queries/tact/textobjects.scm
new file mode 100644
index 00000000..54d07014
--- /dev/null
+++ b/runtime/queries/tact/textobjects.scm
@@ -0,0 +1,58 @@
+; function.inside & around
+; ------------------------
+
+(static_function
+ body: (_) @function.inside) @function.around
+
+(init_function
+ body: (_) @function.inside) @function.around
+
+(bounced_function
+ body: (_) @function.inside) @function.around
+
+(receive_function
+ body: (_) @function.inside) @function.around
+
+(external_function
+ body: (_) @function.inside) @function.around
+
+(function
+ body: (_) @function.inside) @function.around
+
+; class.inside & around
+; ---------------------
+
+(struct
+ body: (_) @class.inside) @class.around
+
+(message
+ body: (_) @class.inside) @class.around
+
+(contract
+ body: (_) @class.inside) @class.around
+
+; NOTE: Marked as @definition.interface in tags, as it's semantically correct
+(trait
+ body: (_) @class.inside) @class.around
+
+; parameter.inside & around
+; -------------------------
+
+(parameter_list
+ ((_) @parameter.inside . ","? @parameter.around) @parameter.around)
+
+(argument_list
+ ((_) @parameter.inside . ","? @parameter.around) @parameter.around)
+
+(instance_argument_list
+ ((_) @parameter.inside . ","? @parameter.around) @parameter.around)
+
+; comment.inside
+; --------------
+
+(comment) @comment.inside
+
+; comment.around
+; --------------
+
+(comment)+ @comment.around \ No newline at end of file