scaffold: VSCode/VSCodium extension wrapping testium lsp
A thin LSP client that spawns `testium lsp` and forwards messages to
VSCode. All language intelligence lives in the testium repo, so this
extension only needs republishing for editor-side UX changes.
- package.json: declares the .tum language, registers the LSP client,
exposes testium.serverPath and testium.trace.server settings.
- src/extension.ts: vscode-languageclient setup over stdio, surfaces a
user-visible error if `testium lsp` can't start.
- syntaxes/tum.tmLanguage.json: TextMate grammar embedding source.yaml
plus tum-specific tokens for $(name), <| python |>, {% jinja %},
{{ jinja }}.
- language-configuration.json: comment char, bracket pairs, auto-close
for $(/), <|/|>, {%/%}, {{/}}.
- README.md: install (incl. testium[lsp] extra), settings, packaging
via vsce, publish to both VS Marketplace and Open VSX (the latter
is what VSCodium / Cursor / Gitpod use — same .vsix artifact).
Works identically on VSCode and VSCodium — no Microsoft-proprietary
API surface used.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
node_modules/
|
||||||
|
out/
|
||||||
|
*.vsix
|
||||||
|
.vscode-test/
|
||||||
|
*.tsbuildinfo
|
||||||
12
.vscodeignore
Normal file
12
.vscodeignore
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
.vscode/**
|
||||||
|
.vscode-test/**
|
||||||
|
src/**
|
||||||
|
.gitignore
|
||||||
|
.git
|
||||||
|
tsconfig.json
|
||||||
|
node_modules/.cache/**
|
||||||
|
**/*.map
|
||||||
|
**/*.ts
|
||||||
|
!out/**/*.js
|
||||||
|
.github/**
|
||||||
|
.editorconfig
|
||||||
95
README.md
95
README.md
@@ -0,0 +1,95 @@
|
|||||||
|
# Testium Assist
|
||||||
|
|
||||||
|
Language support for [testium](https://git.beafrancois.fr/v-and-v/testium) `.tum`
|
||||||
|
test scripts: syntax highlighting, completion, hover, and (later)
|
||||||
|
diagnostics.
|
||||||
|
|
||||||
|
Works the same on **VSCode** and **VSCodium** — the extension uses
|
||||||
|
only the standard VSCode API and `vscode-languageclient`, no
|
||||||
|
Microsoft-proprietary surface.
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
The extension is a thin LSP client that spawns the language server
|
||||||
|
shipped with testium itself (`testium lsp`). All the language
|
||||||
|
intelligence (item types, parameter completion, schema awareness)
|
||||||
|
lives in the testium repo — every new item type or parameter you add
|
||||||
|
upstream becomes available in the editor on the next testium upgrade,
|
||||||
|
without re-publishing this extension.
|
||||||
|
|
||||||
|
Two static parts live here, because they need to run *before* the LSP
|
||||||
|
has a chance to start:
|
||||||
|
|
||||||
|
- **Syntax highlighting** — a TextMate grammar under `syntaxes/`
|
||||||
|
delegates to the base YAML grammar and adds tokens for testium's
|
||||||
|
`$(name)`, `<| python expr |>`, and Jinja `{% … %}` / `{{ … }}`
|
||||||
|
constructs.
|
||||||
|
- **Editor configuration** — comment character, bracket pairs,
|
||||||
|
auto-close pairs for `$( )`, `<| |>`, `{% %}`, `{{ }}`.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- VSCode ≥ 1.80 (or any recent VSCodium build).
|
||||||
|
- A working `testium` installation with the `lsp` extra:
|
||||||
|
```sh
|
||||||
|
pip install 'testium[lsp]'
|
||||||
|
```
|
||||||
|
Or, when developing testium from source:
|
||||||
|
```sh
|
||||||
|
pip install -e /path/to/testium/src[lsp]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Settings
|
||||||
|
|
||||||
|
| Setting | Default | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `testium.serverPath` | `testium` | Path to the `testium` executable. Set this to your venv's `bin/testium` if `testium` isn't on `$PATH`. |
|
||||||
|
| `testium.trace.server` | `off` | LSP trace level surfaced in the **Testium LSP** output channel. |
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install
|
||||||
|
npm run compile # one-shot build
|
||||||
|
npm run watch # rebuild on save
|
||||||
|
```
|
||||||
|
|
||||||
|
Press **F5** in VSCode to launch a development host with the extension
|
||||||
|
loaded. Open any `.tum` file; the **Testium LSP** output channel shows
|
||||||
|
the language-server traffic when `testium.trace.server` is set to
|
||||||
|
`messages` or `verbose`.
|
||||||
|
|
||||||
|
## Packaging
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npx vsce package # produces testium-assist-<v>.vsix
|
||||||
|
```
|
||||||
|
|
||||||
|
To install locally without publishing:
|
||||||
|
- **Code/Codium UI** — `Extensions: Install from VSIX…` from the
|
||||||
|
command palette, pick the `.vsix`.
|
||||||
|
- **CLI** — `code --install-extension testium-assist-<v>.vsix` (or
|
||||||
|
`codium --install-extension …`).
|
||||||
|
|
||||||
|
## Publishing
|
||||||
|
|
||||||
|
The extension targets two registries:
|
||||||
|
|
||||||
|
- **VS Marketplace** (used by VSCode) — `npx vsce publish`. Requires a
|
||||||
|
Microsoft publisher account.
|
||||||
|
- **Open VSX** (used by VSCodium, Cursor, Gitpod, Theia, Eclipse Che) —
|
||||||
|
`npx ovsx publish`. Free and open.
|
||||||
|
|
||||||
|
Both consume the same `.vsix` artifact. A GitHub Actions workflow that
|
||||||
|
runs both on tag push is the typical setup.
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
This is the MVP: completion of test item type names at the start of a
|
||||||
|
new step. Hover, parameter completion, outline and diagnostics will
|
||||||
|
follow as the testium LSP server gains those features — no extension
|
||||||
|
re-publish needed.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
EUPL-1.2 — same as testium.
|
||||||
|
|||||||
38
language-configuration.json
Normal file
38
language-configuration.json
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"comments": {
|
||||||
|
"lineComment": "#"
|
||||||
|
},
|
||||||
|
"brackets": [
|
||||||
|
["{", "}"],
|
||||||
|
["[", "]"],
|
||||||
|
["(", ")"]
|
||||||
|
],
|
||||||
|
"autoClosingPairs": [
|
||||||
|
{ "open": "{", "close": "}" },
|
||||||
|
{ "open": "[", "close": "]" },
|
||||||
|
{ "open": "(", "close": ")" },
|
||||||
|
{ "open": "\"", "close": "\"", "notIn": ["string"] },
|
||||||
|
{ "open": "'", "close": "'", "notIn": ["string"] },
|
||||||
|
{ "open": "$(", "close": ")" },
|
||||||
|
{ "open": "<|", "close": "|>" },
|
||||||
|
{ "open": "{%", "close": "%}" },
|
||||||
|
{ "open": "{{", "close": "}}" }
|
||||||
|
],
|
||||||
|
"surroundingPairs": [
|
||||||
|
["{", "}"],
|
||||||
|
["[", "]"],
|
||||||
|
["(", ")"],
|
||||||
|
["\"", "\""],
|
||||||
|
["'", "'"]
|
||||||
|
],
|
||||||
|
"indentationRules": {
|
||||||
|
"increaseIndentPattern": "^.*:\\s*$",
|
||||||
|
"decreaseIndentPattern": "^\\s+[}\\]].*$"
|
||||||
|
},
|
||||||
|
"onEnterRules": [
|
||||||
|
{
|
||||||
|
"beforeText": "^\\s*-\\s+[^:]*:\\s*$",
|
||||||
|
"action": { "indent": "indent" }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
128
package-lock.json
generated
Normal file
128
package-lock.json
generated
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
{
|
||||||
|
"name": "testium-assist",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "testium-assist",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"license": "EUPL-1.2",
|
||||||
|
"dependencies": {
|
||||||
|
"vscode-languageclient": "^9.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20",
|
||||||
|
"@types/vscode": "^1.80.0",
|
||||||
|
"typescript": "^5.4.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"vscode": "^1.80.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/node": {
|
||||||
|
"version": "20.19.41",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.41.tgz",
|
||||||
|
"integrity": "sha512-ECymXOukMnOoVkC2bb1Vc/w/836DXncOg5m8Xj1RH7xSHZJWNYY6Zh7EH477vcnD5egKNNfy2RpNOmuChhFPgQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"undici-types": "~6.21.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/vscode": {
|
||||||
|
"version": "1.120.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.120.0.tgz",
|
||||||
|
"integrity": "sha512-feaT4Rst+FkTch5zz/ZbNCxoIvo55YU80Be2kiL7OJcod4+CUYf2lUBPdIJzozNnSEMq1VRTGrWEcCGFB3fBmA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/balanced-match": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||||
|
},
|
||||||
|
"node_modules/brace-expansion": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==",
|
||||||
|
"dependencies": {
|
||||||
|
"balanced-match": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/minimatch": {
|
||||||
|
"version": "5.1.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz",
|
||||||
|
"integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/semver": {
|
||||||
|
"version": "7.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz",
|
||||||
|
"integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==",
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/typescript": {
|
||||||
|
"version": "5.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||||
|
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"tsc": "bin/tsc",
|
||||||
|
"tsserver": "bin/tsserver"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.17"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/undici-types": {
|
||||||
|
"version": "6.21.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||||
|
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/vscode-jsonrpc": {
|
||||||
|
"version": "8.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz",
|
||||||
|
"integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vscode-languageclient": {
|
||||||
|
"version": "9.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-9.0.1.tgz",
|
||||||
|
"integrity": "sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA==",
|
||||||
|
"dependencies": {
|
||||||
|
"minimatch": "^5.1.0",
|
||||||
|
"semver": "^7.3.7",
|
||||||
|
"vscode-languageserver-protocol": "3.17.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"vscode": "^1.82.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vscode-languageserver-protocol": {
|
||||||
|
"version": "3.17.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz",
|
||||||
|
"integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==",
|
||||||
|
"dependencies": {
|
||||||
|
"vscode-jsonrpc": "8.2.0",
|
||||||
|
"vscode-languageserver-types": "3.17.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vscode-languageserver-types": {
|
||||||
|
"version": "3.17.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz",
|
||||||
|
"integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
69
package.json
Normal file
69
package.json
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
"name": "testium-assist",
|
||||||
|
"displayName": "Testium Assist",
|
||||||
|
"description": "Language support for testium .tum test scripts. Completion, hover and diagnostics powered by the testium LSP server (`testium lsp`).",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"publisher": "testium",
|
||||||
|
"license": "EUPL-1.2",
|
||||||
|
"engines": {
|
||||||
|
"vscode": "^1.80.0"
|
||||||
|
},
|
||||||
|
"categories": [
|
||||||
|
"Programming Languages"
|
||||||
|
],
|
||||||
|
"main": "./out/extension.js",
|
||||||
|
"activationEvents": [
|
||||||
|
"onLanguage:tum"
|
||||||
|
],
|
||||||
|
"contributes": {
|
||||||
|
"languages": [
|
||||||
|
{
|
||||||
|
"id": "tum",
|
||||||
|
"aliases": [
|
||||||
|
"Testium TUM",
|
||||||
|
"tum"
|
||||||
|
],
|
||||||
|
"extensions": [
|
||||||
|
".tum"
|
||||||
|
],
|
||||||
|
"configuration": "./language-configuration.json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"grammars": [
|
||||||
|
{
|
||||||
|
"language": "tum",
|
||||||
|
"scopeName": "source.tum",
|
||||||
|
"path": "./syntaxes/tum.tmLanguage.json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configuration": {
|
||||||
|
"title": "Testium Assist",
|
||||||
|
"properties": {
|
||||||
|
"testium.serverPath": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "testium",
|
||||||
|
"description": "Path to the testium executable used to start the language server (`<path> lsp`). Defaults to looking up `testium` on $PATH."
|
||||||
|
},
|
||||||
|
"testium.trace.server": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["off", "messages", "verbose"],
|
||||||
|
"default": "off",
|
||||||
|
"description": "Trace the LSP communication between VSCode and the testium server in the Output panel."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"compile": "tsc -p .",
|
||||||
|
"watch": "tsc -p . --watch",
|
||||||
|
"vscode:prepublish": "npm run compile"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"vscode-languageclient": "^9.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20",
|
||||||
|
"@types/vscode": "^1.80.0",
|
||||||
|
"typescript": "^5.4.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
71
src/extension.ts
Normal file
71
src/extension.ts
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Testium Assist — VSCode language client for .tum files.
|
||||||
|
*
|
||||||
|
* This extension is a thin LSP client: it spawns `testium lsp` and forwards
|
||||||
|
* LSP messages between VSCode and the server. All the language intelligence
|
||||||
|
* (completion, hover, diagnostics, …) lives in the testium repository itself
|
||||||
|
* (`src/testium/lsp/`), which keeps this extension shippable independently
|
||||||
|
* of testium's feature evolution.
|
||||||
|
*
|
||||||
|
* The user can override the testium executable through the
|
||||||
|
* `testium.serverPath` setting (useful when working with a virtualenv or a
|
||||||
|
* source checkout).
|
||||||
|
*/
|
||||||
|
import * as vscode from "vscode";
|
||||||
|
import {
|
||||||
|
LanguageClient,
|
||||||
|
LanguageClientOptions,
|
||||||
|
ServerOptions,
|
||||||
|
TransportKind,
|
||||||
|
} from "vscode-languageclient/node";
|
||||||
|
|
||||||
|
let client: LanguageClient | undefined;
|
||||||
|
|
||||||
|
export async function activate(context: vscode.ExtensionContext): Promise<void> {
|
||||||
|
const config = vscode.workspace.getConfiguration("testium");
|
||||||
|
const serverPath = config.get<string>("serverPath", "testium");
|
||||||
|
|
||||||
|
const serverOptions: ServerOptions = {
|
||||||
|
run: { command: serverPath, args: ["lsp"], transport: TransportKind.stdio },
|
||||||
|
debug: {
|
||||||
|
command: serverPath,
|
||||||
|
args: ["lsp"],
|
||||||
|
transport: TransportKind.stdio,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const clientOptions: LanguageClientOptions = {
|
||||||
|
documentSelector: [
|
||||||
|
{ scheme: "file", language: "tum" },
|
||||||
|
],
|
||||||
|
// Echo the user-visible setting into the client so the LSP trace shows up
|
||||||
|
// in the Output panel under "Testium LSP".
|
||||||
|
traceOutputChannel: vscode.window.createOutputChannel("Testium LSP"),
|
||||||
|
};
|
||||||
|
|
||||||
|
client = new LanguageClient(
|
||||||
|
"testiumLsp",
|
||||||
|
"Testium LSP",
|
||||||
|
serverOptions,
|
||||||
|
clientOptions,
|
||||||
|
);
|
||||||
|
|
||||||
|
// start() throws if the executable can't be found; we surface that as a
|
||||||
|
// user-visible message instead of a silent failure in the dev console.
|
||||||
|
try {
|
||||||
|
await client.start();
|
||||||
|
} catch (err) {
|
||||||
|
const msg = err instanceof Error ? err.message : String(err);
|
||||||
|
vscode.window.showErrorMessage(
|
||||||
|
`Testium Assist: failed to start the language server (${serverPath} lsp). ${msg}`,
|
||||||
|
);
|
||||||
|
client = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deactivate(): Promise<void> {
|
||||||
|
if (client) {
|
||||||
|
await client.stop();
|
||||||
|
client = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
81
syntaxes/tum.tmLanguage.json
Normal file
81
syntaxes/tum.tmLanguage.json
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
|
||||||
|
"name": "Testium TUM",
|
||||||
|
"scopeName": "source.tum",
|
||||||
|
"patterns": [
|
||||||
|
{ "include": "#tum-tokens" },
|
||||||
|
{ "include": "source.yaml" }
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"tum-tokens": {
|
||||||
|
"patterns": [
|
||||||
|
{ "include": "#globaldict-reference" },
|
||||||
|
{ "include": "#eval-expression" },
|
||||||
|
{ "include": "#jinja-statement" },
|
||||||
|
{ "include": "#jinja-expression" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"globaldict-reference": {
|
||||||
|
"name": "variable.other.tum.globaldict",
|
||||||
|
"begin": "\\$\\(",
|
||||||
|
"end": "\\)",
|
||||||
|
"beginCaptures": {
|
||||||
|
"0": { "name": "punctuation.definition.variable.begin.tum" }
|
||||||
|
},
|
||||||
|
"endCaptures": {
|
||||||
|
"0": { "name": "punctuation.definition.variable.end.tum" }
|
||||||
|
},
|
||||||
|
"patterns": [
|
||||||
|
{ "name": "entity.name.variable.tum", "match": "[A-Za-z_][A-Za-z0-9_]*" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"eval-expression": {
|
||||||
|
"name": "meta.embedded.expression.tum",
|
||||||
|
"begin": "<\\|",
|
||||||
|
"end": "\\|>",
|
||||||
|
"beginCaptures": {
|
||||||
|
"0": { "name": "punctuation.definition.expression.begin.tum" }
|
||||||
|
},
|
||||||
|
"endCaptures": {
|
||||||
|
"0": { "name": "punctuation.definition.expression.end.tum" }
|
||||||
|
},
|
||||||
|
"patterns": [
|
||||||
|
{ "include": "source.python" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"jinja-statement": {
|
||||||
|
"name": "meta.embedded.block.jinja.tum",
|
||||||
|
"begin": "\\{%-?",
|
||||||
|
"end": "-?%\\}",
|
||||||
|
"beginCaptures": {
|
||||||
|
"0": { "name": "punctuation.definition.template-statement.begin.tum" }
|
||||||
|
},
|
||||||
|
"endCaptures": {
|
||||||
|
"0": { "name": "punctuation.definition.template-statement.end.tum" }
|
||||||
|
},
|
||||||
|
"patterns": [
|
||||||
|
{ "name": "keyword.control.jinja.tum",
|
||||||
|
"match": "\\b(for|endfor|if|elif|else|endif|set|include|extends|block|endblock|macro|endmacro|in|and|or|not|is|with|without|context)\\b" },
|
||||||
|
{ "name": "string.quoted.double.jinja.tum", "match": "\"(?:[^\"\\\\]|\\\\.)*\"" },
|
||||||
|
{ "name": "string.quoted.single.jinja.tum", "match": "'(?:[^'\\\\]|\\\\.)*'" },
|
||||||
|
{ "name": "constant.numeric.jinja.tum", "match": "\\b[0-9]+(?:\\.[0-9]+)?\\b" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"jinja-expression": {
|
||||||
|
"name": "meta.embedded.expression.jinja.tum",
|
||||||
|
"begin": "\\{\\{-?",
|
||||||
|
"end": "-?\\}\\}",
|
||||||
|
"beginCaptures": {
|
||||||
|
"0": { "name": "punctuation.definition.template-expression.begin.tum" }
|
||||||
|
},
|
||||||
|
"endCaptures": {
|
||||||
|
"0": { "name": "punctuation.definition.template-expression.end.tum" }
|
||||||
|
},
|
||||||
|
"patterns": [
|
||||||
|
{ "name": "string.quoted.double.jinja.tum", "match": "\"(?:[^\"\\\\]|\\\\.)*\"" },
|
||||||
|
{ "name": "string.quoted.single.jinja.tum", "match": "'(?:[^'\\\\]|\\\\.)*'" },
|
||||||
|
{ "name": "variable.other.jinja.tum", "match": "[A-Za-z_][A-Za-z0-9_]*" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
tsconfig.json
Normal file
15
tsconfig.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "ES2022",
|
||||||
|
"lib": ["ES2022"],
|
||||||
|
"outDir": "out",
|
||||||
|
"rootDir": "src",
|
||||||
|
"sourceMap": true,
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", ".vscode-test"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user