diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..a035b56
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+*.vim linguist-detectable=false
+*.snippets linguist-detectable=false
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..f675aa1
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,13 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Extension",
+ "type": "extensionHost",
+ "request": "launch",
+ "args": [
+ "--extensionDevelopmentPath=${workspaceFolder}"
+ ]
+ }
+ ]
+}
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..28eb83b
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,4 @@
+This repository is licensed under:
+
+CC0 1.0 Universal
+https://creativecommons.org/publicdomain/zero/1.0
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..10514ef
--- /dev/null
+++ b/README.md
@@ -0,0 +1,72 @@
+## Ebitengine Kage support for Visual Studio Code
+
+Basic syntax and snippet support for the Ebitengine Kage shading language.
+
+
+
+Ebitengine adopts an original shading language 'Kage'. This has a compatible syntax with Go, but the details are different. Kage has high portability. Ebitengine uses graphics libraries like OpenGL or Metal and this depends on environments, but Kage is compiled on the fly so that this works equally everywhere.
+
+### Installation
+
+[![](https://img.shields.io/badge/get%20it%20from-555555?style=for-the-badge&logo=visualstudiocode&logoColor=72a9d4)![](https://img.shields.io/badge/marketplace-72a9d4?style=for-the-badge)](https://marketplace.visualstudio.com/items?itemName=sedyh.ebitengine-kage)
+
+Manual installation
+
+ Install `vsce` from `npm`.
+
+ ```
+ npm install --global vsce
+ ```
+
+ Package extension in `.vsix` archive.
+
+ ```
+ vsce package
+ ```
+
+ Run this command to install package from `.vsix`, replace `ebitengine-kage.vsix` with your path.
+
+ ```
+ code --install-extension ebitengine-kage.vsix
+ ```
+
+
+
+### Other editors
+[![](https://img.shields.io/badge/source-555555?style=for-the-badge&logo=sublimetext&logoColor=ba9759)](https://github.com/sedyh/ebitengine-kage-sublime)[![](https://img.shields.io/badge/download-ba9759?style=for-the-badge)](https://packagecontrol.io)
+[![](https://img.shields.io/badge/source-555555?style=for-the-badge&logo=vim&logoColor=60b371)](https://github.com/sedyh/ebitengine-kage-vim)[![](https://img.shields.io/badge/download-60b371?style=for-the-badge)](https://www.vim.org/scripts/script.php?script_id=6021)
+
+### Features
+
+- [Basic syntax highlighting](#basic-syntax-highlighting)
+- [Quick start](#quick-start)
+- [Short documentation](#short-documentation)
+- [List of all built-in functions](#list-of-all-built-in-functions)
+
+### Basic syntax highlighting
+
+ This plugin provides basic Kage language support for Ebitengine. It includes keywords, types, literals and snippets.
+
+![feature-syntax](https://user-images.githubusercontent.com/19890545/177754828-9ab585c9-56be-4304-92e5-dafa0b10ba97.png)
+
+### Quick start
+
+ To quickly start writing a shader, you can type "fragment" or "package".
+
+![feature-quickstart](https://user-images.githubusercontent.com/19890545/177755034-58f14b63-f92d-4bba-8e7e-3e740cd81e60.png)
+
+### Short documentation
+
+ The plugin provides a short help for each feature in Kage.
+
+![feature-description](https://user-images.githubusercontent.com/19890545/177755312-77153cff-16a7-46ce-b962-c002fc92c2ff.png)
+
+### List of all built-in functions
+
+ You can see a list of all built-in functions by typing "kage".
+
+![feature-help](https://user-images.githubusercontent.com/19890545/177755430-0f020abf-abcc-4b02-8138-410695e09fbd.png)
+
+## Known Issues
+
+The plugin will highlight complex numbers despite the fact that, at the moment, Kage does not support them.
diff --git a/kage-file-dark-theme.png b/kage-file-dark-theme.png
new file mode 100644
index 0000000..958b9ef
Binary files /dev/null and b/kage-file-dark-theme.png differ
diff --git a/kage-file-light-theme.png b/kage-file-light-theme.png
new file mode 100644
index 0000000..046a56d
Binary files /dev/null and b/kage-file-light-theme.png differ
diff --git a/kage.png b/kage.png
new file mode 100644
index 0000000..7586000
Binary files /dev/null and b/kage.png differ
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..235e711
--- /dev/null
+++ b/package.json
@@ -0,0 +1,42 @@
+{
+ "name": "ebitengine-kage",
+ "publisher": "sedyh",
+ "displayName": "ebitengine-kage",
+ "description": "Language for writing shaders on Ebitengine",
+ "version": "0.1.1",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/sedyh/ebitengine-kage-support.git"
+ },
+ "engines": {
+ "vscode": "^1.68.0"
+ },
+ "categories": [
+ "Programming Languages"
+ ],
+ "license": "See LICENSE file",
+ "icon": "kage.png",
+ "contributes": {
+ "languages": [{
+ "id": "kage",
+ "aliases": ["kage", "kage"],
+ "extensions": [".kage",".go.kage",".kage.go"],
+ "configuration": "./syntaxes/language-configuration.json",
+ "icon": {
+ "light": "kage-file-light-theme.png",
+ "dark": "kage-file-dark-theme.png"
+ }
+ }],
+ "grammars": [{
+ "language": "kage",
+ "scopeName": "source.kage",
+ "path": "./syntaxes/kage.tmLanguage.json"
+ }],
+ "snippets": [
+ {
+ "language": "kage",
+ "path": "./syntaxes/snippets.json"
+ }
+ ]
+ }
+}
diff --git a/syntaxes/kage.tmLanguage.json b/syntaxes/kage.tmLanguage.json
new file mode 100644
index 0000000..60b3309
--- /dev/null
+++ b/syntaxes/kage.tmLanguage.json
@@ -0,0 +1,87 @@
+{
+ "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
+ "name": "kage",
+ "patterns": [
+ { "include": "#keywords" },
+ { "include": "#types" },
+ { "include": "#builtins" },
+ { "include": "#functions" },
+ { "include": "#numbers" },
+ { "include": "#comments" }
+ ],
+ "repository": {
+ "keywords": {
+ "patterns": [
+ {
+ "name": "keyword.control.kage",
+ "match": "\\b(package|var|func|if|for|return|true|false|nil)\\b"
+ }
+ ]
+ },
+ "types": {
+ "patterns": [
+ {
+ "name": "constant.language.kage",
+ "match": "\\b(bool|int|float|vec2|vec3|vec4|mat2|mat3|mat4)\\b"
+ }
+ ]
+ },
+ "builtins": {
+ "patterns": [
+ {
+ "name": "entity.name.tag.kage",
+ "match": "\\b(sin|cos|tan|asin|acos|atan|atan2|pow|exp|log|exp2|log2|sqrt|inversesqrt|abs|sign|floor|ceil|fract|mod|min|max|clamp|mix|step|smoothstep|length|distance|dot|bcross|normalize|faceforward|reflect|refract|transpose|dfdx|dfdy|fwidth)\\b"
+ }
+ ]
+ },
+ "functions": {
+ "patterns": [
+ {
+ "name": "entity.name.function.kage",
+ "match": "(?<=func )([a-zA-Z][a-zA-Z0-9]+)(?=\\()"
+ },
+ {
+ "name": "support.function.kage",
+ "match": "[a-zA-Z][a-zA-Z0-9]+(?=\\(.*\\))"
+ }
+ ]
+ },
+ "numbers": {
+ "patterns": [
+ {
+ "name": "constant.numeric.kage",
+ "match": "(((\\.\\d+|0[xXbBoO][\\dbBxXaAbBcCdDeEfF_]*|(?<=[^\\w])\\d+)\\.{0,1}[\\dbBxXaAbBcCdDeEfF_]*([eEpP][-+]{0,1}\\d+))|((\\.\\d+|0[xXbBoO][\\dbBxXaAbBcCdDeEfF_]*|(?<=[^\\w])\\d+)\\.{0,1}[\\dbBxXaAbBcCdDeEfF_]*))i{0,1}"
+ }
+ ]
+ },
+ "comments": {
+ "patterns": [
+ {
+ "name": "comment.line.double-slash.kage",
+ "match": "//.*"
+ },
+ {
+ "name": "comment.block.kage",
+ "begin": "/\\*(?!\\*)",
+ "end": "\\*/",
+ "patterns": [
+ {
+ "include": "#comments"
+ }
+ ]
+ },
+ {
+ "name": "comment.block.documentation.kage",
+ "begin": "/\\*\\*",
+ "end": "\\*/",
+ "patterns": [
+ {
+ "include": "#comments"
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "scopeName": "source.kage"
+}
diff --git a/syntaxes/language-configuration.json b/syntaxes/language-configuration.json
new file mode 100644
index 0000000..6b619d0
--- /dev/null
+++ b/syntaxes/language-configuration.json
@@ -0,0 +1,30 @@
+{
+ "comments": {
+ // symbol used for single line comment. Remove this entry if your language does not support line comments
+ "lineComment": "//",
+ // symbols used for start and end a block comment. Remove this entry if your language does not support block comments
+ "blockComment": [ "/*", "*/" ]
+ },
+ // symbols used as brackets
+ "brackets": [
+ ["{", "}"],
+ ["[", "]"],
+ ["(", ")"]
+ ],
+ // symbols that are auto closed when typing
+ "autoClosingPairs": [
+ ["{", "}"],
+ ["[", "]"],
+ ["(", ")"],
+ ["\"", "\""],
+ ["'", "'"]
+ ],
+ // symbols that can be used to surround a selection
+ "surroundingPairs": [
+ ["{", "}"],
+ ["[", "]"],
+ ["(", ")"],
+ ["\"", "\""],
+ ["'", "'"]
+ ]
+}
diff --git a/syntaxes/snippets.json b/syntaxes/snippets.json
new file mode 100644
index 0000000..0544413
--- /dev/null
+++ b/syntaxes/snippets.json
@@ -0,0 +1,227 @@
+{
+ "main": {
+ "prefix": ["fragment", "package"],
+ "body": ["package main", "", "func Fragment(pos vec4, tex vec2, col vec4) vec4 {", "\t$0", "\treturn vec4(0.5, 0.0, 0.0, 1.0)", "}"],
+ "description": "The basis for the shader"
+ },
+ "vec2": {
+ "prefix": ["vec2"],
+ "body": ["vec2(0, 0)"],
+ "description": "Usage vec2(x, y) or vec2(x)"
+ },
+ "vec3": {
+ "prefix": ["vec3"],
+ "body": ["vec3(0, 0, 0)"],
+ "description": "Usage vec3(x, y, z) or vec3(x)"
+ },
+ "vec4": {
+ "prefix": ["vec4"],
+ "body": ["vec4(0, 0, 0, 0)"],
+ "description": "Usage vec4(x, y, z, w) or vec4(x)"
+ },
+ "mat2": {
+ "prefix": ["mat2"],
+ "body": ["mat2(", "\t0, 0", "\t0, 0,", ")"],
+ "description": "Usage mat2(\n a, b,\n c, d\n)"
+ },
+ "mat3": {
+ "prefix": ["mat3"],
+ "body": ["mat3(", "\t0, 0, 0,", "\t0, 0, 0,", "\t0, 0, 0,", ")"],
+ "description": "Usage mat3(\n a, b, c,\n d, e, f,\n g, h, i\n)"
+ },
+ "mat4": {
+ "prefix": ["mat4"],
+ "body": ["mat4(", "\t0, 0, 0, 0,", "\t0, 0, 0, 0,", "\t0, 0, 0, 0,", "\t0, 0, 0, 0,", ")"],
+ "description": "Usage mat4(\n a, b, c, d,\n e, f, g, h,\n i, j, k, l\n)"
+ },
+ "sin": {
+ "prefix": ["sin", "kage"],
+ "body": ["sin($0)"],
+ "description": "Usage sin(x T)\n\nT is float or vec"
+ },
+ "cos": {
+ "prefix": ["cos", "kage"],
+ "body": ["cos($0)"],
+ "description": "Usage cos(x T)\n\nT is float or vec"
+ },
+ "tan": {
+ "prefix": ["tan", "kage"],
+ "body": ["tan($0)"],
+ "description": "Usage tan(x T)\n\nT is float or vec"
+ },
+ "asin": {
+ "prefix": ["asin", "kage"],
+ "body": ["asin($0)"],
+ "description": "Usage asin(x T)\n\nT is float or vec"
+ },
+ "acos": {
+ "prefix": ["acos", "kage"],
+ "body": ["acos($0)"],
+ "description": "Usage acos(x T)\n\nT is float or vec"
+ },
+ "atan": {
+ "prefix": ["atan", "kage"],
+ "body": ["atan($0)"],
+ "description": "Usage atan(y_over_x T)\n\nT is float or vec"
+ },
+ "atan2": {
+ "prefix": ["atan2", "kage"],
+ "body": ["atan2($0)"],
+ "description": "Usage atan2(x, y T)\n\nT is float or vec"
+ },
+ "pow": {
+ "prefix": ["pow", "kage"],
+ "body": ["pow($0)"],
+ "description": "Usage pow(x, y T)\n\nT is float or vec"
+ },
+ "exp": {
+ "prefix": ["exp", "kage"],
+ "body": ["exp($0)"],
+ "description": "Usage exp(x T)\n\nT is float or vec"
+ },
+ "log": {
+ "prefix": ["log", "kage"],
+ "body": ["log($0)"],
+ "description": "Usage log(x T)\n\nT is float or vec"
+ },
+ "exp2": {
+ "prefix": ["exp2", "kage"],
+ "body": ["exp2($0)"],
+ "description": "Usage exp2(x T)\n\nT is float or vec"
+ },
+ "log2": {
+ "prefix": ["log2", "kage"],
+ "body": ["log2($0)"],
+ "description": "Usage log2(x T)\n\nT is float or vec"
+ },
+ "sqrt": {
+ "prefix": ["sqrt", "kage"],
+ "body": ["sqrt($0)"],
+ "description": "Usage sqrt(x T)\n\nT is float or vec"
+ },
+ "inversesqrt": {
+ "prefix": ["inversesqrt", "kage"],
+ "body": ["inversesqrt($0)"],
+ "description": "Usage inversesqrt(x T)\n\nT is float or vec"
+ },
+ "abs": {
+ "prefix": ["abs", "kage"],
+ "body": ["abs($0)"],
+ "description": "Usage abs(x T)\n\nT is float or vec"
+ },
+ "sign": {
+ "prefix": ["sign", "kage"],
+ "body": ["sign($0)"],
+ "description": "Usage sign(x T)\n\nT is float or vec"
+ },
+ "floor": {
+ "prefix": ["floor", "kage"],
+ "body": ["floor($0)"],
+ "description": "Usage floor(x T)\n\nT is float or vec"
+ },
+ "ceil": {
+ "prefix": ["ceil", "kage"],
+ "body": ["ceil($0)"],
+ "description": "Usage ceil(x T)\n\nT is float or vec"
+ },
+ "fract": {
+ "prefix": ["fract", "kage"],
+ "body": ["fract($0)"],
+ "description": "Usage fract(x T)\n\nT is float or vec"
+ },
+ "mod": {
+ "prefix": ["mod", "kage"],
+ "body": ["mod($0)"],
+ "description": "Usage mod(x, y T)\n\nT is float or vec"
+ },
+ "min": {
+ "prefix": ["min", "kage"],
+ "body": ["min($0)"],
+ "description": "Usage min(x, y T)\n\nT is float or vec"
+ },
+ "max": {
+ "prefix": ["max", "kage"],
+ "body": ["max($0)"],
+ "description": "Usage max(x, y T)\n\nT is float or vec"
+ },
+ "clamp": {
+ "prefix": ["clamp", "kage"],
+ "body": ["clamp($0)"],
+ "description": "Usage clap(x, min, max T)\n\nT is float or vec"
+ },
+ "mix": {
+ "prefix": ["mix", "kage"],
+ "body": ["mix($0)"],
+ "description": "Usage mix(x, y, a T)\n\nT is float or vec"
+ },
+ "step": {
+ "prefix": ["step", "kage"],
+ "body": ["step($0)"],
+ "description": "Usage step(edge, x T)\n\nT is float or vec"
+ },
+ "smoothstep": {
+ "prefix": ["smoothstep", "kage"],
+ "body": ["smoothstep($0)"],
+ "description": "Usage smoothstep(edge0, edge1, x T)\n\nT is float or vec"
+ },
+ "length": {
+ "prefix": ["length", "kage"],
+ "body": ["length($0)"],
+ "description": "Usage length(x T)\n\nT is float or vec"
+ },
+ "distance": {
+ "prefix": ["distance", "kage"],
+ "body": ["distance($0)"],
+ "description": "Usage distance(p0, p1 T)\n\nT is float or vec"
+ },
+ "dot": {
+ "prefix": ["dot", "kage"],
+ "body": ["dot($0)"],
+ "description": "Usage dot(x, y T)\n\nT is float or vec"
+ },
+ "cross": {
+ "prefix": ["cross", "kage"],
+ "body": ["cross($0)"],
+ "description": "Usage cross(x, y vec3)"
+ },
+ "normalize": {
+ "prefix": ["normalize", "kage"],
+ "body": ["normalize($0)"],
+ "description": "Usage normalize(x T)\n\nT is float or vec"
+ },
+ "faceforward": {
+ "prefix": ["faceforward", "kage"],
+ "body": ["faceforward($0)"],
+ "description": "Usage faceforward(n, i, nref T)\n\nT is float or vec"
+ },
+ "reflect": {
+ "prefix": ["reflect", "kage"],
+ "body": ["reflect($0)"],
+ "description": "Usage reflect(i, n T)\n\nT is float or vec"
+ },
+ "refract": {
+ "prefix": ["refract", "kage"],
+ "body": ["refract($0)"],
+ "description": "Usage refract(i, n T, eta float)\n\nT is float or vec"
+ },
+ "transpose": {
+ "prefix": ["transpose", "kage"],
+ "body": ["transpose($0)"],
+ "description": "Usage transpose(x T)\n\nT is mat"
+ },
+ "dfdx": {
+ "prefix": ["dfdx", "kage"],
+ "body": ["dfdx($0)"],
+ "description": "Usage dfdx(x T)\n\nT is float or vec"
+ },
+ "dfdy": {
+ "prefix": ["dfdy", "kage"],
+ "body": ["dfdy($0)"],
+ "description": "Usage dfdy(x T)\n\nT is float or vec"
+ },
+ "fwidth": {
+ "prefix": ["fwidth", "kage"],
+ "body": ["fwidth($0)"],
+ "description": "Usage fwidth(x T)\n\nT is float or vec"
+ }
+}