From f0aa0114409506cc739159ee9574f9f2887ebf42 Mon Sep 17 00:00:00 2001 From: Chris Dragan Date: Wed, 31 Dec 2025 18:36:55 +0100 Subject: [PATCH] feat: add Kos parser Add parser, queries and tests for the Kos programming language. --- SUPPORTED_LANGUAGES.md | 1 + lua/nvim-treesitter/parsers.lua | 8 ++ plugin/filetypes.lua | 1 + runtime/queries/kos/folds.scm | 19 ++++ runtime/queries/kos/highlights.scm | 132 ++++++++++++++++++++++++++++ runtime/queries/kos/injections.scm | 6 ++ runtime/queries/kos/locals.scm | 41 +++++++++ tests/query/highlights/kos/test.kos | 103 ++++++++++++++++++++++ 8 files changed, 311 insertions(+) create mode 100644 runtime/queries/kos/folds.scm create mode 100644 runtime/queries/kos/highlights.scm create mode 100644 runtime/queries/kos/injections.scm create mode 100644 runtime/queries/kos/locals.scm create mode 100644 tests/query/highlights/kos/test.kos diff --git a/SUPPORTED_LANGUAGES.md b/SUPPORTED_LANGUAGES.md index a487c7cca..153483006 100644 --- a/SUPPORTED_LANGUAGES.md +++ b/SUPPORTED_LANGUAGES.md @@ -157,6 +157,7 @@ jsx (queries only)[^jsx] | unstable | `HFIJ ` | @steelsojka [kconfig](https://github.com/tree-sitter-grammars/tree-sitter-kconfig) | unstable | `HFIJL` | @amaanq [kdl](https://github.com/tree-sitter-grammars/tree-sitter-kdl) | unstable | `HFIJL` | @amaanq [kitty](https://github.com/OXY2DEV/tree-sitter-kitty) | unstable | `H  J ` | @OXY2DEV +[kos](https://github.com/kos-lang/tree-sitter-kos) | unstable | `HF JL` | @cdragan [kotlin](https://github.com/fwcd/tree-sitter-kotlin) | unstable | `HF JL` | @SalBakraa [koto](https://github.com/koto-lang/tree-sitter-koto) | unstable | `HF JL` | @irh [kusto](https://github.com/Willem-J-an/tree-sitter-kusto) | unstable | `H  J ` | @Willem-J-an diff --git a/lua/nvim-treesitter/parsers.lua b/lua/nvim-treesitter/parsers.lua index 9ce38664d..e52784058 100644 --- a/lua/nvim-treesitter/parsers.lua +++ b/lua/nvim-treesitter/parsers.lua @@ -1187,6 +1187,14 @@ return { maintainers = { '@OXY2DEV' }, tier = 2, }, + kos = { + install_info = { + revision = 'e4cec3a376c051199faea0ae27d0787b93fd2b0f', + url = 'https://github.com/kos-lang/tree-sitter-kos', + }, + maintainers = { '@cdragan' }, + tier = 2, + }, kotlin = { install_info = { revision = '57fb4560ba8641865bc0baa6b3f413b236112c4c', diff --git a/plugin/filetypes.lua b/plugin/filetypes.lua index 7759c1f5c..d23d52977 100644 --- a/plugin/filetypes.lua +++ b/plugin/filetypes.lua @@ -25,6 +25,7 @@ local filetypes = { janet_simple = { 'janet' }, javascript = { 'javascriptreact', 'ecma', 'ecmascript', 'jsx', 'js' }, json = { 'jsonc' }, + kos = { 'kos' }, glimmer_javascript = { 'javascript.glimmer' }, latex = { 'tex' }, linkerscript = { 'ld' }, diff --git a/runtime/queries/kos/folds.scm b/runtime/queries/kos/folds.scm new file mode 100644 index 000000000..ca51a5406 --- /dev/null +++ b/runtime/queries/kos/folds.scm @@ -0,0 +1,19 @@ +[ + (function_decl) + (constructor_literal) + (function_literal) + (class_decl) + (class_literal) + (do_statement) + (if_statement) + (try_statement) + (defer_statement) + (with_statement) + (switch_statement) + (switch_case) + (default_case) + (loop_statement) + (repeat_statement) + (while_statement) + (for_statement) +] @fold diff --git a/runtime/queries/kos/highlights.scm b/runtime/queries/kos/highlights.scm new file mode 100644 index 000000000..59a26e146 --- /dev/null +++ b/runtime/queries/kos/highlights.scm @@ -0,0 +1,132 @@ +(comment) @comment +(number) @number +(identifier) @variable +(property_identifier) @property +(string_literal) @string +(string_literal_begin) @string +(string_literal_continuation) @string +(string_literal_end) @string + +[ + "case" + "default" + "else" + "if" + "switch" +] @keyword.conditional + +[ + "import" +] @keyword.import + +[ + "for" + "loop" + "repeat" + "while" +] @keyword.repeat + +(for_statement + "in" @keyword.repeat) + +[ + "class" +] @keyword.type + +[ + "return" + "yield" +] @keyword.return + +[ + "catch" + "defer" + "throw" + "try" +] @keyword.exception + +[ + "constructor" + "fun" + "=>" +] @keyword.function + +[ + "_" + (line) + "assert" + ;"async" + (break_statement) + "const" + (continue_statement) + "do" + "extends" + (fallthrough_statement) + ;"get" + ;"match" + "public" + ;"set" + ;"static" + "var" + "with" +] @keyword + +[ + (this) + (super) +] @variable.builtin + +[ + (false) + (true) +] @boolean + +[ + (void) +] @constant.builtin + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +[ + ";" + ":" + "." + "," +] @punctuation.delimiter + +[ + (arithmetic_assignment_operator) + (comparison_operator) + (bitwise_operator) + (additive_operator) + (multiplicative_operator) + (logical_operator) + (unary_operator) + "->" + "..." + "=" + "?" +] @operator + +(conditional_expression + [ + "?" + ":" + ] @keyword.conditional.ternary) + +(class_member + (function_decl + name: (identifier) @function.method)) + +(function_decl + name: (identifier) @function) + +(class_decl + name: (identifier) @type) diff --git a/runtime/queries/kos/injections.scm b/runtime/queries/kos/injections.scm new file mode 100644 index 000000000..2677f272b --- /dev/null +++ b/runtime/queries/kos/injections.scm @@ -0,0 +1,6 @@ +(((comment) @_jsdoc_comment + (#lua-match? @_jsdoc_comment "^/[*][*][^*].*[*]/$")) @injection.content + (#set! injection.language "jsdoc")) + +((comment) @injection.content + (#set! injection.language "comment")) diff --git a/runtime/queries/kos/locals.scm b/runtime/queries/kos/locals.scm new file mode 100644 index 000000000..a853f6671 --- /dev/null +++ b/runtime/queries/kos/locals.scm @@ -0,0 +1,41 @@ +; Scopes +;------- +(compound_statement) @local.scope + +(for_statement) @local.scope + +(function_decl) @local.scope + +(constructor_literal) @local.scope + +(function_literal) @local.scope + +(with_statement) @local.scope + +(catch_clause) @local.scope + +; Definitions +;------------ +(variable_decl + variable: (identifier) @local.definition.var) + +(parameter + parameter: (identifier) @local.definition.var) + +(import + module: (identifier) @local.definition.import) + +(import + symbol: (identifier) @local.definition.import) + +(function_decl + name: (identifier) @local.definition.function + (#set! definition.var.scope parent)) + +(class_decl + name: (identifier) @local.definition.class + (#set! definition.var.scope parent)) + +; References +;------------ +(identifier) @local.reference diff --git a/tests/query/highlights/kos/test.kos b/tests/query/highlights/kos/test.kos new file mode 100644 index 000000000..cbc684d24 --- /dev/null +++ b/tests/query/highlights/kos/test.kos @@ -0,0 +1,103 @@ +#!/usr/bin/env kos +# ^ comment +public var item = 1; +# ^ keyword +# ^ keyword +# ^ variable +# ^ operator +# ^ number +# ^ punctuation.delimiter + +fun name(arg1, +# ^ keyword.function +# ^ function +# ^ punctuation.bracket +# ^ variable +# ^ punctuation.delimiter + arg2 = "default", +# ^ variable +# ^ operator +# ^ string +# ^ punctuation.delimiter + arg3...) +# ^ variable +# ^ operator +# ^ punctuation.bracket +{ +# <- punctuation.bracket + arg1 += 1 + # ^ variable + # ^ operator + # ^ number + arg1 -= 2 + # ^ variable + # ^ operator + # ^ number + arg1 *= 3 + # ^ variable + # ^ operator + # ^ number + arg1 /= 4 + # ^ variable + # ^ operator + # ^ number + arg1 %= 5 + # ^ variable + # ^ operator + # ^ number + arg1 |= 6 + # ^ variable + # ^ operator + # ^ number + arg1 &= 7 + # ^ variable + # ^ operator + # ^ number + arg1 ^= 8 + # ^ variable + # ^ operator + # ^ number + arg1 <<= 9 + # ^ variable + # ^ operator + # ^ number + arg1 >>= 10 + # ^ variable + # ^ operator + # ^ number + arg1 >>>= 11 + # ^ variable + # ^ operator + # ^ number + arg1.prop[arg1](arg1)[void] = true + # ^ variable + # ^ punctuation.delimiter + # ^ property + # ^ punctuation.bracket + # ^ variable + # ^ punctuation.bracket + # ^ punctuation.bracket + # ^ variable + # ^ punctuation.bracket + # ^ punctuation.bracket + # ^ constant.builtin + # ^ operator + # ^ boolean + arg1 = 1 * (arg1 + 2) / arg1 - 3 % arg1 + # ^ variable + # ^ operator + # ^ number + # ^ operator + # ^ punctuation.bracket + # ^ variable + # ^ operator + # ^ number + # ^ punctuation.bracket + # ^ operator + # ^ variable + # ^ operator + # ^ number + # ^ operator + # ^ variable +} +# <- punctuation.bracket