mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 17:36:19 +04:00
Add kotlin language (#1689)
* Add kotlin language Queries taken from https://github.com/nvim-treesitter/nvim-treesitter/blob/master/queries/kotlin seem to work well enough for my needs though I don't use kotlin heavily. * Update lang-support doc * Updates the kotlin highlight query to use helixs scopes * Updates the queries from PR feedback * Adds 'shallow = true' to gitmodules * Removes kotlin locals.scm * Remove blank line Co-authored-by: Ivan Tham <pickfire@riseup.net> Co-authored-by: Ivan Tham <pickfire@riseup.net>
This commit is contained in:
parent
40eb1268c7
commit
f83843ceba
5
.gitmodules
vendored
5
.gitmodules
vendored
@ -229,3 +229,8 @@
|
|||||||
[submodule "helix-syntax/languages/tree-sitter-erlang"]
|
[submodule "helix-syntax/languages/tree-sitter-erlang"]
|
||||||
path = helix-syntax/languages/tree-sitter-erlang
|
path = helix-syntax/languages/tree-sitter-erlang
|
||||||
url = https://github.com/the-mikedavis/tree-sitter-erlang
|
url = https://github.com/the-mikedavis/tree-sitter-erlang
|
||||||
|
shallow = true
|
||||||
|
[submodule "helix-syntax/languages/tree-sitter-kotlin"]
|
||||||
|
path = helix-syntax/languages/tree-sitter-kotlin
|
||||||
|
url = https://github.com/fwcd/tree-sitter-kotlin.git
|
||||||
|
shallow = true
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
| javascript | ✓ | | ✓ | `typescript-language-server` |
|
| javascript | ✓ | | ✓ | `typescript-language-server` |
|
||||||
| json | ✓ | | ✓ | |
|
| json | ✓ | | ✓ | |
|
||||||
| julia | ✓ | | | `julia` |
|
| julia | ✓ | | | `julia` |
|
||||||
|
| kotlin | ✓ | | | `kotlin-language-server` |
|
||||||
| latex | ✓ | | | |
|
| latex | ✓ | | | |
|
||||||
| lean | ✓ | | | `lean` |
|
| lean | ✓ | | | `lean` |
|
||||||
| ledger | ✓ | | | |
|
| ledger | ✓ | | | |
|
||||||
|
1
helix-syntax/languages/tree-sitter-kotlin
Submodule
1
helix-syntax/languages/tree-sitter-kotlin
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit a4f71eb9b8c9b19ded3e0e9470be4b1b77c2b569
|
@ -741,3 +741,12 @@ file-types = ["erl", "hrl", "app", "rebar.config"]
|
|||||||
roots = ["rebar.config"]
|
roots = ["rebar.config"]
|
||||||
comment-token = "%%"
|
comment-token = "%%"
|
||||||
indent = { tab-width = 4, unit = " " }
|
indent = { tab-width = 4, unit = " " }
|
||||||
|
|
||||||
|
[[language]]
|
||||||
|
name = "kotlin"
|
||||||
|
scope = "source.kotlin"
|
||||||
|
file-types = ["kt", "kts"]
|
||||||
|
roots = ["settings.gradle", "settings.gradle.kts"]
|
||||||
|
comment-token = "//"
|
||||||
|
indent = { tab-width = 4, unit = " " }
|
||||||
|
language-server = { command = "kotlin-language-server" }
|
||||||
|
17
runtime/queries/kotlin/folds.scm
Normal file
17
runtime/queries/kotlin/folds.scm
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
[
|
||||||
|
(import_list)
|
||||||
|
|
||||||
|
(when_expression)
|
||||||
|
(control_structure_body)
|
||||||
|
|
||||||
|
(lambda_literal)
|
||||||
|
(function_body)
|
||||||
|
(primary_constructor)
|
||||||
|
(secondary_constructor)
|
||||||
|
(anonymous_initializer)
|
||||||
|
|
||||||
|
(class_body)
|
||||||
|
(enum_class_body)
|
||||||
|
|
||||||
|
(interpolated_expression)
|
||||||
|
] @fold
|
295
runtime/queries/kotlin/highlights.scm
Normal file
295
runtime/queries/kotlin/highlights.scm
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
;;; Operators & Punctuation
|
||||||
|
|
||||||
|
(multi_line_string_literal
|
||||||
|
"$" @punctuation
|
||||||
|
(interpolated_identifier) @none)
|
||||||
|
(multi_line_string_literal
|
||||||
|
"${" @punctuation
|
||||||
|
(interpolated_expression) @none
|
||||||
|
"}" @punctuation.)
|
||||||
|
|
||||||
|
; NOTE: `interpolated_identifier`s can be highlighted in any way
|
||||||
|
(line_string_literal
|
||||||
|
"$" @punctuation
|
||||||
|
(interpolated_identifier) @none)
|
||||||
|
(line_string_literal
|
||||||
|
"${" @punctuation
|
||||||
|
(interpolated_expression) @none
|
||||||
|
"}" @punctuation)
|
||||||
|
|
||||||
|
[
|
||||||
|
"."
|
||||||
|
","
|
||||||
|
";"
|
||||||
|
":"
|
||||||
|
"::"
|
||||||
|
] @punctuation.delimiter
|
||||||
|
|
||||||
|
[
|
||||||
|
"(" ")"
|
||||||
|
"[" "]"
|
||||||
|
"{" "}"
|
||||||
|
] @punctuation.bracket
|
||||||
|
|
||||||
|
[
|
||||||
|
"!"
|
||||||
|
"!="
|
||||||
|
"!=="
|
||||||
|
"="
|
||||||
|
"=="
|
||||||
|
"==="
|
||||||
|
">"
|
||||||
|
">="
|
||||||
|
"<"
|
||||||
|
"<="
|
||||||
|
"||"
|
||||||
|
"&&"
|
||||||
|
"+"
|
||||||
|
"++"
|
||||||
|
"+="
|
||||||
|
"-"
|
||||||
|
"--"
|
||||||
|
"-="
|
||||||
|
"*"
|
||||||
|
"*="
|
||||||
|
"/"
|
||||||
|
"/="
|
||||||
|
"%"
|
||||||
|
"%="
|
||||||
|
"?."
|
||||||
|
"?:"
|
||||||
|
"!!"
|
||||||
|
"is"
|
||||||
|
"!is"
|
||||||
|
"in"
|
||||||
|
"!in"
|
||||||
|
"as"
|
||||||
|
"as?"
|
||||||
|
".."
|
||||||
|
"->"
|
||||||
|
] @operator
|
||||||
|
|
||||||
|
;;; Keywords
|
||||||
|
|
||||||
|
(type_alias "typealias" @keyword)
|
||||||
|
[
|
||||||
|
(class_modifier)
|
||||||
|
(member_modifier)
|
||||||
|
(function_modifier)
|
||||||
|
(property_modifier)
|
||||||
|
(platform_modifier)
|
||||||
|
(variance_modifier)
|
||||||
|
(parameter_modifier)
|
||||||
|
(visibility_modifier)
|
||||||
|
(reification_modifier)
|
||||||
|
(inheritance_modifier)
|
||||||
|
]@keyword
|
||||||
|
|
||||||
|
[
|
||||||
|
"val"
|
||||||
|
"var"
|
||||||
|
"enum"
|
||||||
|
"class"
|
||||||
|
"object"
|
||||||
|
"interface"
|
||||||
|
; "typeof" ; NOTE: It is reserved for future use
|
||||||
|
] @keyword
|
||||||
|
|
||||||
|
("fun") @keyword.function
|
||||||
|
|
||||||
|
(jump_expression) @keyword.control.return
|
||||||
|
|
||||||
|
[
|
||||||
|
"if"
|
||||||
|
"else"
|
||||||
|
"when"
|
||||||
|
] @keyword.control.conditional
|
||||||
|
|
||||||
|
[
|
||||||
|
"for"
|
||||||
|
"do"
|
||||||
|
"while"
|
||||||
|
] @keyword.control.repeat
|
||||||
|
|
||||||
|
[
|
||||||
|
"try"
|
||||||
|
"catch"
|
||||||
|
"throw"
|
||||||
|
"finally"
|
||||||
|
] @keyword.control.exception
|
||||||
|
|
||||||
|
(annotation
|
||||||
|
"@" @attribute (use_site_target)? @attribute)
|
||||||
|
(annotation
|
||||||
|
(user_type
|
||||||
|
(type_identifier) @attribute))
|
||||||
|
(annotation
|
||||||
|
(constructor_invocation
|
||||||
|
(user_type
|
||||||
|
(type_identifier) @attribute)))
|
||||||
|
|
||||||
|
(file_annotation
|
||||||
|
"@" @attribute "file" @attribute ":" @attribute)
|
||||||
|
(file_annotation
|
||||||
|
(user_type
|
||||||
|
(type_identifier) @attribute))
|
||||||
|
(file_annotation
|
||||||
|
(constructor_invocation
|
||||||
|
(user_type
|
||||||
|
(type_identifier) @attribute)))
|
||||||
|
|
||||||
|
;;; Literals
|
||||||
|
; NOTE: Escapes not allowed in multi-line strings
|
||||||
|
(line_string_literal (character_escape_seq) @constant.character.escape)
|
||||||
|
|
||||||
|
[
|
||||||
|
(line_string_literal)
|
||||||
|
(multi_line_string_literal)
|
||||||
|
] @string
|
||||||
|
|
||||||
|
(character_literal) @constant.character
|
||||||
|
|
||||||
|
[
|
||||||
|
"null" ; should be highlighted the same as booleans
|
||||||
|
(boolean_literal)
|
||||||
|
] @constant.builtin.boolean
|
||||||
|
|
||||||
|
(real_literal) @constant.numeric.float
|
||||||
|
[
|
||||||
|
(integer_literal)
|
||||||
|
(long_literal)
|
||||||
|
(hex_literal)
|
||||||
|
(bin_literal)
|
||||||
|
(unsigned_literal)
|
||||||
|
] @constant.numeric.integer
|
||||||
|
|
||||||
|
[
|
||||||
|
(comment)
|
||||||
|
(shebang_line)
|
||||||
|
] @comment
|
||||||
|
|
||||||
|
;;; Function calls
|
||||||
|
|
||||||
|
(call_expression
|
||||||
|
. (simple_identifier) @function.builtin
|
||||||
|
(#match? @function.builtin "^(arrayOf|arrayOfNulls|byteArrayOf|shortArrayOf|intArrayOf|longArrayOf|ubyteArrayOf|ushortArrayOf|uintArrayOf|ulongArrayOf|floatArrayOf|doubleArrayOf|booleanArrayOf|charArrayOf|emptyArray|mapOf|setOf|listOf|emptyMap|emptySet|emptyList|mutableMapOf|mutableSetOf|mutableListOf|print|println|error|TODO|run|runCatching|repeat|lazy|lazyOf|enumValues|enumValueOf|assert|check|checkNotNull|require|requireNotNull|with|suspend|synchronized)$"))
|
||||||
|
|
||||||
|
; object.function() or object.property.function()
|
||||||
|
(call_expression
|
||||||
|
(navigation_expression
|
||||||
|
(navigation_suffix
|
||||||
|
(simple_identifier) @function) . ))
|
||||||
|
|
||||||
|
; function()
|
||||||
|
(call_expression
|
||||||
|
. (simple_identifier) @function)
|
||||||
|
|
||||||
|
;;; Function definitions
|
||||||
|
|
||||||
|
; lambda parameters
|
||||||
|
(lambda_literal
|
||||||
|
(lambda_parameters
|
||||||
|
(variable_declaration
|
||||||
|
(simple_identifier) @variable.parameter)))
|
||||||
|
|
||||||
|
(parameter_with_optional_type
|
||||||
|
(simple_identifier) @variable.parameter)
|
||||||
|
|
||||||
|
(parameter
|
||||||
|
(simple_identifier) @variable.parameter)
|
||||||
|
|
||||||
|
(anonymous_initializer
|
||||||
|
("init") @constructor)
|
||||||
|
|
||||||
|
(constructor_invocation
|
||||||
|
(user_type
|
||||||
|
(type_identifier) @constructor))
|
||||||
|
|
||||||
|
(secondary_constructor
|
||||||
|
("constructor") @constructor)
|
||||||
|
(primary_constructor) @constructor
|
||||||
|
|
||||||
|
(getter
|
||||||
|
("get") @function.builtin)
|
||||||
|
(setter
|
||||||
|
("set") @function.builtin)
|
||||||
|
|
||||||
|
(function_declaration
|
||||||
|
. (simple_identifier) @function)
|
||||||
|
|
||||||
|
; TODO: Seperate labeled returns/breaks/continue/super/this
|
||||||
|
; Must be implemented in the parser first
|
||||||
|
(label) @label
|
||||||
|
|
||||||
|
(import_header
|
||||||
|
(identifier
|
||||||
|
(simple_identifier) @function @_import .)
|
||||||
|
(import_alias
|
||||||
|
(type_identifier) @function)?
|
||||||
|
(#match? @_import "^[a-z]"))
|
||||||
|
|
||||||
|
; The last `simple_identifier` in a `import_header` will always either be a function
|
||||||
|
; or a type. Classes can appear anywhere in the import path, unlike functions
|
||||||
|
(import_header
|
||||||
|
(identifier
|
||||||
|
(simple_identifier) @type @_import)
|
||||||
|
(import_alias
|
||||||
|
(type_identifier) @type)?
|
||||||
|
(#match? @_import "^[A-Z]"))
|
||||||
|
|
||||||
|
(import_header
|
||||||
|
"import" @keyword.control.import)
|
||||||
|
|
||||||
|
(package_header
|
||||||
|
. (identifier)) @namespace
|
||||||
|
|
||||||
|
((type_identifier) @type.builtin
|
||||||
|
(#match? @function.builtin "^(Byte|Short|Int|Long|UByte|UShort|UInt|ULong|Float|Double|Boolean|Char|String|Array|ByteArray|ShortArray|IntArray|LongArray|UByteArray|UShortArray|UIntArray|ULongArray|FloatArray|DoubleArray|BooleanArray|CharArray|Map|Set|List|EmptyMap|EmptySet|EmptyList|MutableMap|MutableSet|MutableList)$"))
|
||||||
|
|
||||||
|
(type_identifier) @type
|
||||||
|
|
||||||
|
(enum_entry
|
||||||
|
(simple_identifier) @constant)
|
||||||
|
|
||||||
|
(_
|
||||||
|
(navigation_suffix
|
||||||
|
(simple_identifier) @constant
|
||||||
|
(#match? @constant "^[A-Z][A-Z0-9_]*$")))
|
||||||
|
|
||||||
|
; SCREAMING CASE identifiers are assumed to be constants
|
||||||
|
((simple_identifier) @constant
|
||||||
|
(#match? @constant "^[A-Z][A-Z0-9_]*$"))
|
||||||
|
|
||||||
|
; id_1.id_2.id_3: `id_2` and `id_3` are assumed as object properties
|
||||||
|
(_
|
||||||
|
(navigation_suffix
|
||||||
|
(simple_identifier) @variable.other.member))
|
||||||
|
|
||||||
|
(class_body
|
||||||
|
(property_declaration
|
||||||
|
(variable_declaration
|
||||||
|
(simple_identifier) @variable.other.member)))
|
||||||
|
|
||||||
|
(class_parameter
|
||||||
|
(simple_identifier) @variable.other.member)
|
||||||
|
|
||||||
|
; `super` keyword inside classes
|
||||||
|
(super_expression) @variable.builtin
|
||||||
|
|
||||||
|
; `this` this keyword inside classes
|
||||||
|
(this_expression) @variable.builtin
|
||||||
|
|
||||||
|
;;; Identifiers
|
||||||
|
; `field` keyword inside property getter/setter
|
||||||
|
; FIXME: This will highlight the keyword outside of getters and setters
|
||||||
|
; since tree-sitter does not allow us to check for arbitrary nestation
|
||||||
|
((simple_identifier) @variable.builtin
|
||||||
|
(#eq? @variable.builtin "field"))
|
||||||
|
|
||||||
|
; `it` keyword inside lambdas
|
||||||
|
; FIXME: This will highlight the keyword outside of lambdas since tree-sitter
|
||||||
|
; does not allow us to check for arbitrary nestation
|
||||||
|
((simple_identifier) @variable.builtin
|
||||||
|
(#eq? @variable.builtin "it"))
|
||||||
|
|
||||||
|
(simple_identifier) @variable
|
36
runtime/queries/kotlin/injections.scm
Normal file
36
runtime/queries/kotlin/injections.scm
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
((comment) @injection.content
|
||||||
|
(#set! injection.language "comment"))
|
||||||
|
|
||||||
|
; There are 3 ways to define a regex
|
||||||
|
; - "[abc]?".toRegex()
|
||||||
|
((call_expression
|
||||||
|
(navigation_expression
|
||||||
|
([(line_string_literal) (multi_line_string_literal)] @injection.content)
|
||||||
|
(navigation_suffix
|
||||||
|
((simple_identifier) @_function
|
||||||
|
(#eq? @_function "toRegex")))))
|
||||||
|
(#set! injection.language "regex"))
|
||||||
|
|
||||||
|
; - Regex("[abc]?")
|
||||||
|
((call_expression
|
||||||
|
((simple_identifier) @_function
|
||||||
|
(#eq? @_function "Regex"))
|
||||||
|
(call_suffix
|
||||||
|
(value_arguments
|
||||||
|
(value_argument
|
||||||
|
[ (line_string_literal) (multi_line_string_literal) ] @injection.content))))
|
||||||
|
(#set! injection.language "regex"))
|
||||||
|
|
||||||
|
; - Regex.fromLiteral("[abc]?")
|
||||||
|
((call_expression
|
||||||
|
(navigation_expression
|
||||||
|
((simple_identifier) @_class
|
||||||
|
(#eq? @_class "Regex"))
|
||||||
|
(navigation_suffix
|
||||||
|
((simple_identifier) @_function
|
||||||
|
(#eq? @_function "fromLiteral"))))
|
||||||
|
(call_suffix
|
||||||
|
(value_arguments
|
||||||
|
(value_argument
|
||||||
|
[ (line_string_literal) (multi_line_string_literal) ] @injection.content))))
|
||||||
|
(#set! injection.language "regex"))
|
Loading…
Reference in New Issue
Block a user