├── .gitattributes ├── .github └── workflows │ └── publish.yml ├── .vscode └── launch.json ├── LICENSE ├── README.md ├── kage-file-dark-theme.png ├── kage-file-light-theme.png ├── kage.png ├── package.json ├── syntaxes ├── kage.tmLanguage.json ├── language-configuration.json └── snippets.json └── themes ├── kage-dark.json └── kage-light.json /.gitattributes: -------------------------------------------------------------------------------- 1 | *.vim linguist-detectable=false 2 | *.snippets linguist-detectable=false 3 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | release: 4 | types: 5 | - published 6 | workflow_dispatch: 7 | 8 | jobs: 9 | release: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | - uses: actions/setup-node@v1 15 | with: 16 | node-version: 14 17 | registry-url: https://registry.npmjs.org/ 18 | 19 | - name: Install npm 20 | run: npm i 21 | 22 | - name: Install vsce 23 | run: npm i -g vsce 24 | 25 | - name: Publish extension 26 | run: vsce publish -p ${{ secrets.VSCE_PAT }} 27 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Extension", 6 | "type": "extensionHost", 7 | "request": "launch", 8 | "args": [ 9 | "--extensionDevelopmentPath=${workspaceFolder}" 10 | ] 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This repository is licensed under: 2 | 3 | CC0 1.0 Universal 4 | https://creativecommons.org/publicdomain/zero/1.0 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## ebitengine-kage-support Ebitengine Kage support for Visual Studio Code 2 | 3 | Basic syntax and snippet support for the Ebitengine Kage shading language. 4 | 5 |
6 | 7 | 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. 8 | 9 | ### Installation 10 | 11 | [![](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) 12 | 13 |
Manual installation
14 | 15 | Install `vsce` from `npm`. 16 | 17 | ``` 18 | npm install --global vsce 19 | ``` 20 | 21 | Package extension in `.vsix` archive. 22 | 23 | ``` 24 | vsce package 25 | ``` 26 | 27 | Run this command to install package from `.vsix`, replace `ebitengine-kage.vsix` with your path. 28 | 29 | ``` 30 | code --install-extension ebitengine-kage.vsix 31 | ``` 32 | 33 |
34 | 35 | ### Other editors 36 | [![](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/packages/Ebitengine%20Kage)
37 | [![](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) 38 | 39 | ### Features 40 | 41 | - [Basic syntax highlighting](#basic-syntax-highlighting) 42 | - [Quick start](#quick-start) 43 | - [Short documentation](#short-documentation) 44 | - [List of all built-in functions](#list-of-all-built-in-functions) 45 | 46 | ### Basic syntax highlighting 47 | 48 | back This plugin provides basic Kage language support for Ebitengine. It includes keywords, types, literals and snippets. 49 | 50 | ![feature-syntax](https://user-images.githubusercontent.com/19890545/187960786-0a9292f7-3143-414e-bf5f-e44db90f458c.png) 51 | 52 | ### Quick start 53 | 54 | back To quickly start writing a shader, you can type "fragment" or "package". 55 | 56 | ![feature-quickstart](https://user-images.githubusercontent.com/19890545/177755034-58f14b63-f92d-4bba-8e7e-3e740cd81e60.png) 57 | 58 | ### Short documentation 59 | 60 | back The plugin provides a short help for each feature in Kage. 61 | 62 | ![feature-description](https://user-images.githubusercontent.com/19890545/177755312-77153cff-16a7-46ce-b962-c002fc92c2ff.png) 63 | 64 | ### List of all built-in functions 65 | 66 | back You can see a list of all built-in functions by typing "kage". 67 | 68 | ![feature-help](https://user-images.githubusercontent.com/19890545/177755430-0f020abf-abcc-4b02-8138-410695e09fbd.png) 69 | 70 | ## Known Issues 71 | 72 | The plugin will highlight complex numbers despite the fact that, at the moment, Kage does not support them. 73 | -------------------------------------------------------------------------------- /kage-file-dark-theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sedyh/ebitengine-kage-vscode/dbc847a86df716a076769c562366aa1b53c108ad/kage-file-dark-theme.png -------------------------------------------------------------------------------- /kage-file-light-theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sedyh/ebitengine-kage-vscode/dbc847a86df716a076769c562366aa1b53c108ad/kage-file-light-theme.png -------------------------------------------------------------------------------- /kage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sedyh/ebitengine-kage-vscode/dbc847a86df716a076769c562366aa1b53c108ad/kage.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ebitengine-kage", 3 | "publisher": "sedyh", 4 | "displayName": "ebitengine-kage", 5 | "description": "Language for writing shaders on Ebitengine", 6 | "version": "0.1.6", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/sedyh/ebitengine-kage-support.git" 10 | }, 11 | "engines": { 12 | "vscode": "^1.68.0" 13 | }, 14 | "categories": [ 15 | "Programming Languages" 16 | ], 17 | "license": "See LICENSE file", 18 | "icon": "kage.png", 19 | "contributes": { 20 | "languages": [{ 21 | "id": "kage", 22 | "aliases": ["Kage"], 23 | "extensions": [".kage",".go.kage",".kage.go"], 24 | "configuration": "./syntaxes/language-configuration.json", 25 | "icon": { 26 | "dark": "kage-file-dark-theme.png", 27 | "light": "kage-file-light-theme.png" 28 | } 29 | }], 30 | "grammars": [{ 31 | "language": "kage", 32 | "scopeName": "source.kage", 33 | "path": "./syntaxes/kage.tmLanguage.json" 34 | }], 35 | "snippets": [ 36 | { 37 | "language": "kage", 38 | "path": "./syntaxes/snippets.json" 39 | } 40 | ] 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /syntaxes/kage.tmLanguage.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", 3 | "name": "kage", 4 | "patterns": [ 5 | { "include": "#keywords" }, 6 | { "include": "#types" }, 7 | { "include": "#builtins" }, 8 | { "include": "#functions" }, 9 | { "include": "#numbers" }, 10 | { "include": "#swizzling" }, 11 | { "include": "#comments" } 12 | ], 13 | "repository": { 14 | "keywords": { 15 | "patterns": [ 16 | { 17 | "name": "keyword.control.kage", 18 | "match": "\\b(package|var|func|if|for|return|true|false|nil)\\b" 19 | } 20 | ] 21 | }, 22 | "types": { 23 | "patterns": [ 24 | { 25 | "name": "constant.language.kage", 26 | "match": "\\b(bool|int|float|vec2|vec3|vec4|mat2|mat3|mat4)\\b" 27 | } 28 | ] 29 | }, 30 | "builtins": { 31 | "patterns": [ 32 | { 33 | "name": "entity.name.tag.kage", 34 | "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" 35 | } 36 | ] 37 | }, 38 | "functions": { 39 | "patterns": [ 40 | { 41 | "name": "entity.name.function.kage", 42 | "match": "(?<=func )([a-zA-Z][a-zA-Z0-9]+)(?=\\()" 43 | }, 44 | { 45 | "name": "support.function.kage", 46 | "match": "[a-zA-Z][a-zA-Z0-9]+(?=\\(.*\\))" 47 | } 48 | ] 49 | }, 50 | "numbers": { 51 | "patterns": [ 52 | { 53 | "name": "constant.numeric.kage", 54 | "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}" 55 | } 56 | ] 57 | }, 58 | "swizzling": { 59 | "patterns": [ 60 | { 61 | "name": "support.other.r.kage", 62 | "match": "(?<=\\.)r(?=([rgba][rgba][rgba][^rgbaxyzwstpq])?)|(?<=\\.[rgba])r(?=([rgba][rgba][^rgbaxyzwstpq])?)|(?<=\\.[rgba][rgba])r(?=([rgba][^rgbaxyzwstpq])?)|(?<=\\.[rgba][rgba][rgba])r(?=([^rgbaxyzwstpq])?)" 63 | }, 64 | { 65 | "name": "support.other.g.kage", 66 | "match": "(?<=\\.)g(?=([rgba][rgba][rgba][^rgbaxyzwstpq])?)|(?<=\\.[rgba])g(?=([rgba][rgba][^rgbaxyzwstpq])?)|(?<=\\.[rgba][rgba])g(?=([rgba][^rgbaxyzwstpq])?)|(?<=\\.[rgba][rgba][rgba])g(?=([^rgbaxyzwstpq])?)" 67 | }, 68 | { 69 | "name": "support.other.b.kage", 70 | "match": "(?<=\\.)b(?=([rgba][rgba][rgba][^rgbaxyzwstpq])?)|(?<=\\.[rgba])b(?=([rgba][rgba][^rgbaxyzwstpq])?)|(?<=\\.[rgba][rgba])b(?=([rgba][^rgbaxyzwstpq])?)|(?<=\\.[rgba][rgba][rgba])b(?=([^rgbaxyzwstpq])?)" 71 | }, 72 | { 73 | "name": "support.other.a.kage", 74 | "match": "(?<=\\.)a(?=([rgba][rgba][rgba][^rgbaxyzwstpq])?)|(?<=\\.[rgba])a(?=([rgba][rgba][^rgbaxyzwstpq])?)|(?<=\\.[rgba][rgba])a(?=([rgba][^rgbaxyzwstpq])?)|(?<=\\.[rgba][rgba][rgba])a(?=([^rgbaxyzwstpq])?)" 75 | }, 76 | { 77 | "name": "support.other.x.kage", 78 | "match": "(?<=\\.)x(?=([xyzw][xyzw][xyzw][^xyzwxyzwstpq])?)|(?<=\\.[xyzw])x(?=([xyzw][xyzw][^xyzwxyzwstpq])?)|(?<=\\.[xyzw][xyzw])x(?=([xyzw][^xyzwxyzwstpq])?)|(?<=\\.[xyzw][xyzw][xyzw])x(?=([^xyzwxyzwstpq])?)" 79 | }, 80 | { 81 | "name": "support.other.y.kage", 82 | "match": "(?<=\\.)y(?=([xyzw][xyzw][xyzw][^xyzwxyzwstpq])?)|(?<=\\.[xyzw])y(?=([xyzw][xyzw][^xyzwxyzwstpq])?)|(?<=\\.[xyzw][xyzw])y(?=([xyzw][^xyzwxyzwstpq])?)|(?<=\\.[xyzw][xyzw][xyzw])y(?=([^xyzwxyzwstpq])?)" 83 | }, 84 | { 85 | "name": "support.other.z.kage", 86 | "match": "(?<=\\.)z(?=([xyzw][xyzw][xyzw][^xyzwxyzwstpq])?)|(?<=\\.[xyzw])z(?=([xyzw][xyzw][^xyzwxyzwstpq])?)|(?<=\\.[xyzw][xyzw])z(?=([xyzw][^xyzwxyzwstpq])?)|(?<=\\.[xyzw][xyzw][xyzw])z(?=([^xyzwxyzwstpq])?)" 87 | }, 88 | { 89 | "name": "support.other.w.kage", 90 | "match": "(?<=\\.)w(?=([xyzw][xyzw][xyzw][^xyzwxyzwstpq])?)|(?<=\\.[xyzw])w(?=([xyzw][xyzw][^xyzwxyzwstpq])?)|(?<=\\.[xyzw][xyzw])w(?=([xyzw][^xyzwxyzwstpq])?)|(?<=\\.[xyzw][xyzw][xyzw])w(?=([^xyzwxyzwstpq])?)" 91 | }, 92 | { 93 | "name": "support.other.s.kage", 94 | "match": "(?<=\\.)s(?=([stpq][stpq][stpq][^stpqstpqstpq])?)|(?<=\\.[stpq])s(?=([stpq][stpq][^stpqstpqstpq])?)|(?<=\\.[stpq][stpq])s(?=([stpq][^stpqstpqstpq])?)|(?<=\\.[stpq][stpq][stpq])s(?=([^stpqstpqstpq])?)" 95 | }, 96 | { 97 | "name": "support.other.t.kage", 98 | "match": "(?<=\\.)t(?=([stpq][stpq][stpq][^stpqstpqstpq])?)|(?<=\\.[stpq])t(?=([stpq][stpq][^stpqstpqstpq])?)|(?<=\\.[stpq][stpq])t(?=([stpq][^stpqstpqstpq])?)|(?<=\\.[stpq][stpq][stpq])t(?=([^stpqstpqstpq])?)" 99 | }, 100 | { 101 | "name": "support.other.p.kage", 102 | "match": "(?<=\\.)p(?=([stpq][stpq][stpq][^stpqstpqstpq])?)|(?<=\\.[stpq])p(?=([stpq][stpq][^stpqstpqstpq])?)|(?<=\\.[stpq][stpq])p(?=([stpq][^stpqstpqstpq])?)|(?<=\\.[stpq][stpq][stpq])p(?=([^stpqstpqstpq])?)" 103 | }, 104 | { 105 | "name": "support.other.q.kage", 106 | "match": "(?<=\\.)q(?=([stpq][stpq][stpq][^stpqstpqstpq])?)|(?<=\\.[stpq])q(?=([stpq][stpq][^stpqstpqstpq])?)|(?<=\\.[stpq][stpq])q(?=([stpq][^stpqstpqstpq])?)|(?<=\\.[stpq][stpq][stpq])q(?=([^stpqstpqstpq])?)" 107 | } 108 | ] 109 | }, 110 | "comments": { 111 | "patterns": [ 112 | { 113 | "name": "comment.line.double-slash.kage", 114 | "match": "//.*" 115 | }, 116 | { 117 | "name": "comment.block.kage", 118 | "begin": "/\\*(?!\\*)", 119 | "end": "\\*/", 120 | "patterns": [ 121 | { 122 | "include": "#comments" 123 | } 124 | ] 125 | }, 126 | { 127 | "name": "comment.block.documentation.kage", 128 | "begin": "/\\*\\*", 129 | "end": "\\*/", 130 | "patterns": [ 131 | { 132 | "include": "#comments" 133 | } 134 | ] 135 | } 136 | ] 137 | } 138 | }, 139 | "scopeName": "source.kage" 140 | } 141 | -------------------------------------------------------------------------------- /syntaxes/language-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | // symbol used for single line comment. Remove this entry if your language does not support line comments 4 | "lineComment": "//", 5 | // symbols used for start and end a block comment. Remove this entry if your language does not support block comments 6 | "blockComment": [ "/*", "*/" ] 7 | }, 8 | // symbols used as brackets 9 | "brackets": [ 10 | ["{", "}"], 11 | ["[", "]"], 12 | ["(", ")"] 13 | ], 14 | // symbols that are auto closed when typing 15 | "autoClosingPairs": [ 16 | ["{", "}"], 17 | ["[", "]"], 18 | ["(", ")"], 19 | ["\"", "\""], 20 | ["'", "'"] 21 | ], 22 | // symbols that can be used to surround a selection 23 | "surroundingPairs": [ 24 | ["{", "}"], 25 | ["[", "]"], 26 | ["(", ")"], 27 | ["\"", "\""], 28 | ["'", "'"] 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /syntaxes/snippets.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": { 3 | "prefix": ["fragment", "package", "kage"], 4 | "body": [ 5 | "package main", "", 6 | "func Fragment(pos vec4, tex vec2, col vec4) vec4 {", 7 | "\t$0", 8 | "\treturn vec4(0.5, 0.0, 0.0, 1.0)", 9 | "}" 10 | ], 11 | "description": [ 12 | "The basis for the shader", "", 13 | "pos: destination pixel position, xy is in range 0..N", 14 | "tex: source texture texel position, xy is in range 0..1", 15 | "col: supplemental color information given from vertices, rgba is in range 0..1", 16 | "Returns: current position color", 17 | "Documentation: https://ebitengine.org/en/documents/shader.html" 18 | ] 19 | }, 20 | "imageColorNAtPixel": { 21 | "prefix": ["imageColorNAtPixel", "kage"], 22 | "body": [ 23 | "func imageColor${1|0,1,2,3|}AtPixel(pixelCoords vec2) vec4 {", 24 | "\tsizeInPixels := imageSrcTextureSize()", 25 | "\toffsetInTexels, _ := imageSrcRegionOnTexture()", 26 | "\tadjustedTexelCoords := pixelCoords/sizeInPixels + offsetInTexels", 27 | "\treturn imageSrc$1At(adjustedTexelCoords)", 28 | "}" 29 | ], 30 | "description": [ 31 | "Usage imageColorNAtPixel(pos vec2) vec2", "N is 0 to 3", "", 32 | "For users who are not familiar with texels, it is recommended to use this helper function", 33 | "instead of the standard ones to access an image's color at the given pixel coordinates", 34 | "Returns: image's color at the given pixel pos, xy in range 0..N", 35 | "Documentation: https://github.com/tinne26/kage-desk/blob/main/docs/tutorials/intro/07_images.md" 36 | ] 37 | }, 38 | "imageColorNAtUnit": { 39 | "prefix": ["imageColorNAtUnit", "kage"], 40 | "body": [ 41 | "func imageColor${1|0,1,2,3|}AtUnit(unitCoords vec2) vec4 {", 42 | "\toffsetInTexels, sizeInTexels := imageSrcRegionOnTexture()", 43 | "\tadjustedTexelCoords := unitCoords*sizeInTexels + offsetInTexels", 44 | "\treturn imageSrc$1At(adjustedTexelCoords)", 45 | "}" 46 | ], 47 | "description": [ 48 | "Usage imageColorNAtUnit(pos vec2) vec2", "N is 0 to 3", "", 49 | "For users who are not familiar with texels, it is recommended to use this helper function", 50 | "instead of the standard ones to access an image's color at the given pixel coordinates", 51 | "Returns: image's color at the given pixel pos, xy in range 0..1", 52 | "Documentation: https://github.com/tinne26/kage-desk/blob/main/docs/tutorials/intro/07_images.md" 53 | ] 54 | }, 55 | "imageSrcNAt": { 56 | "prefix": ["imageSrcNAt", "kage"], 57 | "body": ["imageSrc${1|0,1,2,3|}At($0)"], 58 | "description": [ 59 | "Usage imageSrcNAt(pos vec2) vec2", "N is 0 to 3", "", 60 | "Returns: color value as vec4 at the given position pos in texels of the source image N", 61 | "Documentation: https://ebitengine.org/en/documents/shader.html" 62 | ] 63 | }, 64 | "imageSrcNUnsafeAt": { 65 | "prefix": ["imageSrcNUnsafeAt", "kage"], 66 | "body": ["imageSrc${1|0,1,2,3|}UnsafeAt($0)"], 67 | "description": [ 68 | "Usage imageSrcNUnsafeAt(pos vec2) vec2", "N is 0 to 3", "", 69 | "Returns: color value as vec4 at the given position pos in texels of the source image N, but without boundary checks", 70 | "Documentation: https://ebitengine.org/en/documents/shader.html" 71 | ] 72 | }, 73 | "imageSrcTextureSize": { 74 | "prefix": ["imageSrcTextureSize", "kage"], 75 | "body": ["imageSrcTextureSize()"], 76 | "description": [ 77 | "Usage imageSrcTextureSize() vec2", "", 78 | "Returns: source image's texture size in pixels", 79 | "Documentation: https://ebitengine.org/en/documents/shader.html" 80 | ] 81 | }, 82 | "imageDstTextureSize": { 83 | "prefix": ["imageDstTextureSize", "kage"], 84 | "body": ["imageDstTextureSize()"], 85 | "description": [ 86 | "Usage imageDstTextureSize() vec2", "", 87 | "Returns: destination image's texture size in pixels", 88 | "Documentation: https://ebitengine.org/en/documents/shader.html" 89 | ] 90 | }, 91 | "imageSrcRegionOnTexture": { 92 | "prefix": ["imageSrcRegionOnTexture", "kage"], 93 | "body": ["imageSrcRegionOnTexture()"], 94 | "description": [ 95 | "Usage imageSrcRegionOnTexture() (vec2, vec2)", "", 96 | "Returns: source image's origin position and the size on the texture in texels", 97 | "Documentation: https://ebitengine.org/en/documents/shader.html" 98 | ] 99 | }, 100 | "imageDstRegionOnTexture": { 101 | "prefix": ["imageDstRegionOnTexture", "kage"], 102 | "body": ["imageDstRegionOnTexture()"], 103 | "description": [ 104 | "Usage imageDstRegionOnTexture() (vec2, vec2)", "", 105 | "Returns: destination image's origin position and the size on the texture in texels", 106 | "Documentation: https://ebitengine.org/en/documents/shader.html" 107 | ] 108 | }, 109 | "vec2": { 110 | "prefix": ["vec2"], 111 | "body": ["vec2(0, 0)"], 112 | "description": [ 113 | "Usage: vec2(x, y) or vec2(x)", "", 114 | "Documentation: https://ebitengine.org/en/documents/shader.html" 115 | ] 116 | }, 117 | "vec3": { 118 | "prefix": ["vec3"], 119 | "body": ["vec3(0, 0, 0)"], 120 | "description": [ 121 | "Usage: vec3(x, y, z) or vec3(x)", "", 122 | "Documentation: https://ebitengine.org/en/documents/shader.html" 123 | ] 124 | }, 125 | "vec4": { 126 | "prefix": ["vec4"], 127 | "body": ["vec4(0, 0, 0, 0)"], 128 | "description": [ 129 | "Usage: vec4(x, y, z, w) or vec4(x)", "", 130 | "Documentation: https://ebitengine.org/en/documents/shader.html" 131 | ] 132 | }, 133 | "mat2": { 134 | "prefix": ["mat2"], 135 | "body": [ 136 | "mat2(", 137 | "\t0, 0", 138 | "\t0, 0,", 139 | ")" 140 | ], 141 | "description": [ 142 | "Usage: mat2(", 143 | " a, b,", 144 | " c, d,", 145 | ")", 146 | "Documentation: https://ebitengine.org/en/documents/shader.html" 147 | ] 148 | }, 149 | "mat3": { 150 | "prefix": ["mat3"], 151 | "body": [ 152 | "mat3(", 153 | "\t0, 0, 0,", 154 | "\t0, 0, 0,", 155 | "\t0, 0, 0,", 156 | ")" 157 | ], 158 | "description": [ 159 | "Usage: mat3(", 160 | " a, b, c,", 161 | " d, e, f,", 162 | " g, h, i,", 163 | ")", 164 | "Documentation: https://ebitengine.org/en/documents/shader.html" 165 | ] 166 | }, 167 | "mat4": { 168 | "prefix": ["mat4"], 169 | "body": [ 170 | "mat4(", 171 | "\t0, 0, 0, 0,", 172 | "\t0, 0, 0, 0,", 173 | "\t0, 0, 0, 0,", 174 | "\t0, 0, 0, 0,", 175 | ")" 176 | ], 177 | "description": [ 178 | "Usage mat4(", 179 | " a, b, c, d,", 180 | " e, f, g, h,", 181 | " i, j, k, l", 182 | " m, n, o, p,", 183 | ")", 184 | "Documentation: https://ebitengine.org/en/documents/shader.html" 185 | ] 186 | }, 187 | "sin": { 188 | "prefix": ["sin", "kage"], 189 | "body": ["sin($0)"], 190 | "description": [ 191 | "Usage sin(x T)", "T is float or vec", "", 192 | "Calculates: trigonometric sine of angle x in radians", 193 | "Returns: sin(x)", 194 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/sin.xhtml" 195 | ] 196 | }, 197 | "cos": { 198 | "prefix": ["cos", "kage"], 199 | "body": ["cos($0)"], 200 | "description": [ 201 | "Usage cos(x T)", "T is float or vec", "", 202 | "Calculates: trigonometric cosine of angle x in radians", 203 | "Returns: cos(x)", 204 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/cos.xhtml" 205 | ] 206 | }, 207 | "tan": { 208 | "prefix": ["tan", "kage"], 209 | "body": ["tan($0)"], 210 | "description": [ 211 | "Usage tan(x T)", "T is float or vec", "", 212 | "Calculates: trigonometric tangent of angle x in radians", 213 | "Returns: tan(x)", 214 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/tan.xhtml" 215 | ] 216 | }, 217 | "asin": { 218 | "prefix": ["asin", "kage"], 219 | "body": ["asin($0)"], 220 | "description": [ 221 | "Usage asin(x T)", "T is float or vec", "", 222 | "Calculates: angle in radians whose trigonometric sine is x", 223 | "Returns: asin(x)", 224 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/asin.xhtml" 225 | ] 226 | }, 227 | "acos": { 228 | "prefix": ["acos", "kage"], 229 | "body": ["acos($0)"], 230 | "description": [ 231 | "Usage acos(x T)", "T is float or vec", "", 232 | "Calculates: angle in radians whose trigonometric cosine is x", 233 | "Returns: acos(x)", 234 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/acos.xhtml" 235 | ] 236 | }, 237 | "atan": { 238 | "prefix": ["atan", "kage"], 239 | "body": ["atan($0)"], 240 | "description": [ 241 | "Usage atan(x T)", "T is float or vec", "", 242 | "Calculates: angle in radians whose trigonometric tangent is x", 243 | "Returns: atan(x)", 244 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/atan.xhtml" 245 | ] 246 | }, 247 | "atan2": { 248 | "prefix": ["atan2", "kage"], 249 | "body": ["atan2($0)"], 250 | "description": [ 251 | "Usage atan2(x, y T)", "T is float or vec", "", 252 | "Calculates: angle in radians whose trigonometric tangent is y/x that properly accounts for all 4 quadrants and zero values", 253 | "Returns: atan(y/x T) with additional checks", 254 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/atan.xhtml" 255 | ] 256 | }, 257 | "pow": { 258 | "prefix": ["pow", "kage"], 259 | "body": ["pow($0)"], 260 | "description": [ 261 | "Usage pow(x, y T)", "T is float or vec", "", 262 | "Calculates: value of x raised to the y power", 263 | "Returns: xʸ", 264 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/pow.xhtml" 265 | ] 266 | }, 267 | "exp": { 268 | "prefix": ["exp", "kage"], 269 | "body": ["exp($0)"], 270 | "description": [ 271 | "Usage exp(x T)", "T is float or vec", "", 272 | "Calculates: natural exponentiation of the x", 273 | "Returns: eˣ", 274 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/exp.xhtml" 275 | ] 276 | }, 277 | "log": { 278 | "prefix": ["log", "kage"], 279 | "body": ["log($0)"], 280 | "description": [ 281 | "Usage log(x T)", "T is float or vec", "", 282 | "Calculates: natural logarithm of x, i.e. the value y which satisfies x=e^y", 283 | "Returns: logₑx", 284 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/log.xhtml" 285 | ] 286 | }, 287 | "exp2": { 288 | "prefix": ["exp2", "kage"], 289 | "body": ["exp2($0)"], 290 | "description": [ 291 | "Usage exp2(x T)", "T is float or vec", "", 292 | "Calculates: 2 raised to the power of the x", 293 | "Returns: 2ˣ", 294 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/exp2.xhtml" 295 | ] 296 | }, 297 | "log2": { 298 | "prefix": ["log2", "kage"], 299 | "body": ["log2($0)"], 300 | "description": [ 301 | "Usage log2(x T)", "T is float or vec", "", 302 | "Calculates: base 2 logarithm of x, i.e. the value y which satisfies x=2^y", 303 | "Returns: log₂(x)", 304 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/log2.xhtml" 305 | ] 306 | }, 307 | "sqrt": { 308 | "prefix": ["sqrt", "kage"], 309 | "body": ["sqrt($0)"], 310 | "description": [ 311 | "Usage sqrt(x T)", "T is float or vec", "", 312 | "Calculates: square root of the x", 313 | "Returns: √x", 314 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/log2.xhtml" 315 | ] 316 | }, 317 | "inversesqrt": { 318 | "prefix": ["inversesqrt", "kage"], 319 | "body": ["inversesqrt($0)"], 320 | "description": [ 321 | "Usage inversesqrt(x T)", "T is float or vec", "", 322 | "Calculates: inverse of the square root of the x", 323 | "Returns: 1/√x", 324 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/inversesqrt.xhtml" 325 | ] 326 | }, 327 | "abs": { 328 | "prefix": ["abs", "kage"], 329 | "body": ["abs($0)"], 330 | "description": [ 331 | "Usage abs(x T)", "T is float or vec", "", 332 | "Calculates: absolute value of the x", 333 | "Returns: |x|", 334 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/abs.xhtml" 335 | ] 336 | }, 337 | "sign": { 338 | "prefix": ["sign", "kage"], 339 | "body": ["sign($0)"], 340 | "description": [ 341 | "Usage sign(x T)", "T is float or vec", "", 342 | "Calculates: sign of the x", 343 | "Returns: -1 if x < 0 else 1", 344 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/sign.xhtml" 345 | ] 346 | }, 347 | "floor": { 348 | "prefix": ["floor", "kage"], 349 | "body": ["floor($0)"], 350 | "description": [ 351 | "Usage floor(x T)", "T is float or vec", "", 352 | "Calculates: nearest integer less than or equal to the x", 353 | "Returns: floor(x), i.e. 5.95 -> 5", 354 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/floor.xhtml" 355 | ] 356 | }, 357 | "ceil": { 358 | "prefix": ["ceil", "kage"], 359 | "body": ["ceil($0)"], 360 | "description": [ 361 | "Usage ceil(x T)", "T is float or vec", "", 362 | "Calculates: nearest integer that is greater than or equal to the x", 363 | "Returns: ceil(x), i.e. 5.001 -> 6", 364 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/ceil.xhtml" 365 | ] 366 | }, 367 | "fract": { 368 | "prefix": ["fract", "kage"], 369 | "body": ["fract($0)"], 370 | "description": [ 371 | "Usage fract(x T)", "T is float or vec", "", 372 | "Calculates: fractional part of the x", 373 | "Returns: x - floor(x), i.e. 5.95 -> 0.95", 374 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/fract.xhtml" 375 | ] 376 | }, 377 | "mod": { 378 | "prefix": ["mod", "kage"], 379 | "body": ["mod($0)"], 380 | "description": [ 381 | "Usage mod(x, y T)", "T is float or vec", "", 382 | "Calculates: value of x modulo y", 383 | "Returns: x - y*floor(x/y)", 384 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/mod.xhtml" 385 | ] 386 | }, 387 | "min": { 388 | "prefix": ["min", "kage"], 389 | "body": ["min($0)"], 390 | "description": [ 391 | "Usage min(x, y T)", "T is float or vec", "", 392 | "Calculates: lesser among x and y", 393 | "Returns: y if y < x else x", 394 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/min.xhtml" 395 | ] 396 | }, 397 | "max": { 398 | "prefix": ["max", "kage"], 399 | "body": ["max($0)"], 400 | "description": [ 401 | "Usage max(x, y T)", "T is float or vec", "", 402 | "Calculates: greater among x and y", 403 | "Returns: y if y > x else x", 404 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/max.xhtml" 405 | ] 406 | }, 407 | "clamp": { 408 | "prefix": ["clamp", "kage"], 409 | "body": ["clamp($0)"], 410 | "description": [ 411 | "Usage clamp(x, min, max T)", "T is float or vec", "", 412 | "Calculates: constrained value that lies between min and max", 413 | "Returns: min(max(x, min), max)", 414 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/clamp.xhtml" 415 | ] 416 | }, 417 | "mix": { 418 | "prefix": ["mix", "kage"], 419 | "body": ["mix($0)"], 420 | "description": [ 421 | "Usage mix(x, y, a T)", "T is float or vec", "", 422 | "Calculates: linear interpolation between x and y", 423 | "Returns: x*(1-a) + y*a", 424 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/mix.xhtml" 425 | ] 426 | }, 427 | "step": { 428 | "prefix": ["step", "kage"], 429 | "body": ["step($0)"], 430 | "description": [ 431 | "Usage step(edge, x T)", "T is float or vec", "", 432 | "Calculates: step function by comparing x with the edge", 433 | "Returns: 0 if x < edge else 1", 434 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/step.xhtml" 435 | ] 436 | }, 437 | "smoothstep": { 438 | "prefix": ["smoothstep", "kage"], 439 | "body": ["smoothstep($0)"], 440 | "description": [ 441 | "Usage smoothstep(start, end, x T)", "T is float or vec", "", 442 | "Calculates: Hermite interpolation between two values", 443 | "Returns: 0 if x <= start, 1 if x >= end, else interpolate", 444 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/smoothstep.xhtml" 445 | ] 446 | }, 447 | "length": { 448 | "prefix": ["length", "kage"], 449 | "body": ["length($0)"], 450 | "description": [ 451 | "Usage length(x T)", "T is vec", "", 452 | "Calculates: length of a vector", 453 | "Returns: √(x₀² + x₁² + ...)", 454 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/length.xhtml" 455 | ] 456 | }, 457 | "distance": { 458 | "prefix": ["distance", "kage"], 459 | "body": ["distance($0)"], 460 | "description": [ 461 | "Usage length(a, b T)", "T is vec", "", 462 | "Calculates: distance between two points", 463 | "Returns: length(a-b)", 464 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/distance.xhtml" 465 | ] 466 | }, 467 | "dot": { 468 | "prefix": ["dot", "kage"], 469 | "body": ["dot($0)"], 470 | "description": [ 471 | "Usage dot(a, b T)", "T is vec", "", 472 | "Calculates: dot product of two vectors", 473 | "Returns: x₀*y₀ + x₁*y₁ + ...", 474 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/dot.xhtml" 475 | ] 476 | }, 477 | "cross": { 478 | "prefix": ["cross", "kage"], 479 | "body": ["cross($0)"], 480 | "description": [ 481 | "Usage cross(a, b T)", "T is vec", "", 482 | "Calculates: cross product of two vectors", 483 | "Returns: x × y", 484 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/cross.xhtml" 485 | ] 486 | }, 487 | "normalize": { 488 | "prefix": ["normalize", "kage"], 489 | "body": ["normalize($0)"], 490 | "description": [ 491 | "Usage normalize(x T)", "T is vec", "", 492 | "Calculates: unit vector in the same direction as the original vector", 493 | "Returns: [x₀/length(x), x₁/length(x), ...]", 494 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/normalize.xhtml" 495 | ] 496 | }, 497 | "faceforward": { 498 | "prefix": ["faceforward", "kage"], 499 | "body": ["faceforward($0)"], 500 | "description": [ 501 | "Usage faceforward(n, i, nref T)", "T is vec", "", 502 | "Calculates: vector to point away from a surface as defined by its normal, i.e. conditionally flips a vector n if two vectors i and nref are pointing in the same direction", 503 | "Returns: n if dot(nref, i) < 0 else -n", 504 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/faceforward.xhtml" 505 | ] 506 | }, 507 | "reflect": { 508 | "prefix": ["reflect", "kage"], 509 | "body": ["reflect($0)"], 510 | "description": [ 511 | "Usage reflect(i, n T)", "T is vec", "", 512 | "Calculates: reflection direction for a given incident vector i and normalized surface normal n", 513 | "Returns: i - 2*dot(n, i)*n", 514 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/reflect.xhtml" 515 | ] 516 | }, 517 | "refract": { 518 | "prefix": ["refract", "kage"], 519 | "body": ["refract($0)"], 520 | "description": [ 521 | "Usage length(a, b T)", "T is vec", "", 522 | "Calculates: refraction direction for an incident vector i and normalized surface normal n using the ratio of indices of refraction eta", 523 | "Returns: eta*i - (eta*dot(n, i)+sqrt(1.0-eta*eta*(1.0-dot(n, i)*dot(n, i))))*n", 524 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/refract.xhtml" 525 | ] 526 | }, 527 | "transpose": { 528 | "prefix": ["transpose", "kage"], 529 | "body": ["transpose($0)"], 530 | "description": [ 531 | "Usage transpose(x T)", "T is mat", "", 532 | "Calculates: transpose of the matrix", 533 | "Returns: a matrix flipped along its diagonal", 534 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/transpose.xhtml" 535 | ] 536 | }, 537 | "dfdx": { 538 | "prefix": ["dfdx", "kage"], 539 | "body": ["dfdx($0)"], 540 | "description": [ 541 | "Usage dfdx(x T)", "T is float or vec", "", 542 | "Calculates: rate that a value changes between the current x and the neighboring x₀", 543 | "Returns: (x₀ - x) / pixelwidth", 544 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/dFdx.xhtml" 545 | ] 546 | }, 547 | "dfdy": { 548 | "prefix": ["dfdy", "kage"], 549 | "body": ["dfdy($0)"], 550 | "description": [ 551 | "Usage dfdy(x T)", "T is float or vec", "", 552 | "Calculates: rate that a value changes between the current y and the neighboring y₀", 553 | "Returns: (y₀ - y) / pixelwidth", 554 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/dFdx.xhtml" 555 | ] 556 | }, 557 | "fwidth": { 558 | "prefix": ["fwidth", "kage"], 559 | "body": ["fwidth($0)"], 560 | "description": [ 561 | "Usage fwidth(v T)", "T is vec", "", 562 | "Calculates: sum of the absolute value of derivatives in x and y of vector v", 563 | "Returns: abs(dfdx(v.x)) + abs(dfdy(v.x))", 564 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/fwidth.xhtml" 565 | ] 566 | }, 567 | "cap": { 568 | "prefix": ["cap"], 569 | "body": ["cap($0)"], 570 | "description": [ 571 | "Usage cap(x T)", "T is array", "", 572 | "Returns: capacity of the array", 573 | "Documentation: https://ebitengine.org/en/documents/shader.html" 574 | ] 575 | }, 576 | "len": { 577 | "prefix": ["len"], 578 | "body": ["len($0)"], 579 | "description": [ 580 | "Usage len(x T)", "T is array", "", 581 | "Calculates: length of the array", 582 | "Documentation: https://ebitengine.org/en/documents/shader.html" 583 | ] 584 | }, 585 | "discard": { 586 | "prefix": ["discard", "kage"], 587 | "body": ["discard()$0"], 588 | "description": [ 589 | "Usage discard()", "", 590 | "Stop outputting the current fragment", 591 | "Documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/distance.xhtml" 592 | ] 593 | }, 594 | "swizzling-rgba": { 595 | "prefix": [".rgba"], 596 | "body": [".rgba$0"], 597 | "description": "Read and write multiple vec components at the same time" 598 | }, 599 | "swizzling-xyzw": { 600 | "prefix": [".xyzw"], 601 | "body": [".xyzw$0"], 602 | "description": "Read and write multiple vec components at the same time" 603 | }, 604 | "swizzling-stpq": { 605 | "prefix": [".stpq"], 606 | "body": [".stpq$0"], 607 | "description": "Read and write multiple vec components at the same time" 608 | } 609 | } 610 | -------------------------------------------------------------------------------- /themes/kage-dark.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "vscode://schemas/color-theme", 3 | "name": "Dark (Ebitengine Kage)", 4 | "tokenColors": [ 5 | { 6 | "name": "kage-keywords", 7 | "scope": [ 8 | "keyword.control.kage", 9 | ], 10 | "settings": { 11 | "foreground": "#C586C0" 12 | } 13 | }, 14 | { 15 | "name": "kage-types", 16 | "scope": "constant.language.kage", 17 | "settings": { 18 | "foreground": "#569cd6" 19 | } 20 | }, 21 | { 22 | "name": "kage-builtins", 23 | "scope": [ 24 | "entity.name.tag.kage", 25 | ], 26 | "settings": { 27 | "foreground": "#569cd6" 28 | } 29 | }, 30 | { 31 | "name": "kage-functions", 32 | "scope": [ 33 | "entity.name.function.kage", 34 | "support.function.kage", 35 | ], 36 | "settings": { 37 | "foreground": "#DCDCAA" 38 | } 39 | }, 40 | { 41 | "name": "kage-numbers", 42 | "scope": [ 43 | "constant.numeric.kage" 44 | ], 45 | "settings": { 46 | "foreground": "#b5cea8" 47 | }, 48 | }, 49 | { 50 | "name": "kage-swizzling-rxs", 51 | "scope": [ 52 | "support.other.r.kage", 53 | "support.other.x.kage", 54 | "support.other.s.kage" 55 | ], 56 | "settings": { 57 | "foreground": "#a87171" 58 | }, 59 | }, 60 | { 61 | "name": "kage-swizzling-qyt", 62 | "scope": [ 63 | "support.other.g.kage", 64 | "support.other.y.kage", 65 | "support.other.t.kage" 66 | ], 67 | "settings": { 68 | "foreground": "#75ac8a" 69 | }, 70 | }, 71 | { 72 | "name": "kage-swizzling-bzp", 73 | "scope": [ 74 | "support.other.b.kage", 75 | "support.other.z.kage", 76 | "support.other.p.kage" 77 | ], 78 | "settings": { 79 | "foreground": "#717ea3" 80 | }, 81 | }, 82 | { 83 | "name": "kage-swizzling-awq", 84 | "scope": [ 85 | "support.other.a.kage", 86 | "support.other.w.kage", 87 | "support.other.q.kage" 88 | ], 89 | "settings": { 90 | "foreground": "#a19b78" 91 | }, 92 | }, 93 | { 94 | "name": "kage-comment", 95 | "scope": [ 96 | "comment", 97 | ], 98 | "settings": { 99 | "foreground": "#6A9955" 100 | } 101 | }, 102 | ] 103 | } 104 | -------------------------------------------------------------------------------- /themes/kage-light.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "vscode://schemas/color-theme", 3 | "name": "Light (Ebitengine Kage)", 4 | "tokenColors": [ 5 | { 6 | "name": "kage-keywords", 7 | "scope": [ 8 | "keyword.control.kage", 9 | ], 10 | "settings": { 11 | "foreground": "#AF00DB" 12 | } 13 | }, 14 | { 15 | "name": "kage-types", 16 | "scope": "constant.language.kage", 17 | "settings": { 18 | "foreground": "#0000ff" 19 | } 20 | }, 21 | { 22 | "name": "kage-builtins", 23 | "scope": [ 24 | "entity.name.tag.kage", 25 | ], 26 | "settings": { 27 | "foreground": "#800000" 28 | } 29 | }, 30 | { 31 | "name": "kage-functions", 32 | "scope": [ 33 | "entity.name.function.kage", 34 | "support.function.kage", 35 | ], 36 | "settings": { 37 | "foreground": "#795E26" 38 | } 39 | }, 40 | { 41 | "name": "kage-numbers", 42 | "scope": [ 43 | "constant.numeric.kage" 44 | ], 45 | "settings": { 46 | "foreground": "#098658" 47 | }, 48 | }, 49 | { 50 | "name": "kage-swizzling-rxs", 51 | "scope": [ 52 | "support.other.r.kage", 53 | "support.other.x.kage", 54 | "support.other.s.kage" 55 | ], 56 | "settings": { 57 | "foreground": "#a55252" 58 | }, 59 | }, 60 | { 61 | "name": "kage-swizzling-qyt", 62 | "scope": [ 63 | "support.other.g.kage", 64 | "support.other.y.kage", 65 | "support.other.t.kage" 66 | ], 67 | "settings": { 68 | "foreground": "#50aa73" 69 | }, 70 | }, 71 | { 72 | "name": "kage-swizzling-bzp", 73 | "scope": [ 74 | "support.other.b.kage", 75 | "support.other.z.kage", 76 | "support.other.p.kage" 77 | ], 78 | "settings": { 79 | "foreground": "#5267a1" 80 | }, 81 | }, 82 | { 83 | "name": "kage-swizzling-awq", 84 | "scope": [ 85 | "support.other.a.kage", 86 | "support.other.w.kage", 87 | "support.other.q.kage" 88 | ], 89 | "settings": { 90 | "foreground": "#a19759" 91 | }, 92 | }, 93 | { 94 | "name": "kage-comment", 95 | "scope": [ 96 | "comment", 97 | ], 98 | "settings": { 99 | "foreground": "#6A9955" 100 | } 101 | }, 102 | ] 103 | } 104 | --------------------------------------------------------------------------------