chore: import upstream snapshot with attribution
CI / Deep Native Runtime Cases (1/6) (push) Has been skipped
CI / Native Preflight (push) Failing after 1s
CI / Native Runtime Cases (1/2) (push) Failing after 0s
CI / Native Runtime Cases (2/2) (push) Failing after 1s
CI / Native Metadata Reports (push) Failing after 0s
CI / Native Direct Backend Artifacts (push) Failing after 0s
CI / Native Sanitizer Smoke (push) Failing after 1s
CI / Command Contract Snapshots (push) Failing after 1s
CI / Deep Conformance Suite (push) Has been skipped
CI / Graph Build Perf (push) Failing after 1s
CI / Deep Native Preflight (push) Has been skipped
CI / Deep Native Runtime Cases (2/6) (push) Has been skipped
CI / Deep Native Runtime Cases (3/6) (push) Has been skipped
CI / Conformance Suite (push) Failing after 1s
CI / Workspace Checks (push) Failing after 0s
CI / Deep Native Runtime Cases (5/6) (push) Has been skipped
CI / Deep Native Runtime Cases (6/6) (push) Has been skipped
CI / Deep Native Runtime Cases (4/6) (push) Has been skipped
CI / Deep Graph Build Perf (push) Has been skipped
CI / Deep Native Runtime Cases (1/6) (push) Has been skipped
CI / Native Preflight (push) Failing after 1s
CI / Native Runtime Cases (1/2) (push) Failing after 0s
CI / Native Runtime Cases (2/2) (push) Failing after 1s
CI / Native Metadata Reports (push) Failing after 0s
CI / Native Direct Backend Artifacts (push) Failing after 0s
CI / Native Sanitizer Smoke (push) Failing after 1s
CI / Command Contract Snapshots (push) Failing after 1s
CI / Deep Conformance Suite (push) Has been skipped
CI / Graph Build Perf (push) Failing after 1s
CI / Deep Native Preflight (push) Has been skipped
CI / Deep Native Runtime Cases (2/6) (push) Has been skipped
CI / Deep Native Runtime Cases (3/6) (push) Has been skipped
CI / Conformance Suite (push) Failing after 1s
CI / Workspace Checks (push) Failing after 0s
CI / Deep Native Runtime Cases (5/6) (push) Has been skipped
CI / Deep Native Runtime Cases (6/6) (push) Has been skipped
CI / Deep Native Runtime Cases (4/6) (push) Has been skipped
CI / Deep Graph Build Perf (push) Has been skipped
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
dist/**
|
||||
examples/**
|
||||
node_modules/**
|
||||
src/**
|
||||
tests/**
|
||||
.git/**
|
||||
.zero/**
|
||||
package-lock.json
|
||||
tsconfig.json
|
||||
@@ -0,0 +1,9 @@
|
||||
# Zero Language Extension
|
||||
|
||||
Syntax highlighting and basic editor configuration for Zero `.0` projection files in VS Code and Cursor. The repository also ships `pnpm run zls -- --self-test`, which exercises diagnostics, hovers, completions, symbols, fix plans, and editor metadata from `zero inspect`, `zero size`, `zero mem`, and `zero doc`.
|
||||
|
||||
Install into Cursor from the repository root:
|
||||
|
||||
```sh
|
||||
pnpm run extension:install:cursor
|
||||
```
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"comments": {
|
||||
"lineComment": "//",
|
||||
"blockComment": ["/*", "*/"]
|
||||
},
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"],
|
||||
["<", ">"]
|
||||
],
|
||||
"autoClosingPairs": [
|
||||
{
|
||||
"open": "{",
|
||||
"close": "}"
|
||||
},
|
||||
{
|
||||
"open": "[",
|
||||
"close": "]"
|
||||
},
|
||||
{
|
||||
"open": "(",
|
||||
"close": ")"
|
||||
},
|
||||
{
|
||||
"open": "<",
|
||||
"close": ">"
|
||||
},
|
||||
{
|
||||
"open": "\"",
|
||||
"close": "\"",
|
||||
"notIn": ["string", "comment"]
|
||||
}
|
||||
],
|
||||
"surroundingPairs": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"],
|
||||
["<", ">"],
|
||||
["\"", "\""]
|
||||
],
|
||||
"folding": {
|
||||
"markers": {
|
||||
"start": "^\\s*//\\s*#region\\b",
|
||||
"end": "^\\s*//\\s*#endregion\\b"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "zero-lang",
|
||||
"displayName": "Zero Language",
|
||||
"description": "Syntax highlighting for the Zero programming language.",
|
||||
"publisher": "zero-lang",
|
||||
"version": "0.3.4",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"categories": [
|
||||
"Programming Languages"
|
||||
],
|
||||
"scripts": {
|
||||
"install:cursor": "node scripts/install-cursor-extension.mjs",
|
||||
"test": "node --test tests/*.test.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=24",
|
||||
"vscode": "^1.100.0"
|
||||
},
|
||||
"contributes": {
|
||||
"languages": [
|
||||
{
|
||||
"id": "zero",
|
||||
"aliases": [
|
||||
"Zero",
|
||||
"zero"
|
||||
],
|
||||
"extensions": [
|
||||
".0"
|
||||
],
|
||||
"configuration": "./language-configuration/zero.json"
|
||||
}
|
||||
],
|
||||
"grammars": [
|
||||
{
|
||||
"language": "zero",
|
||||
"scopeName": "source.zero",
|
||||
"path": "./syntaxes/zero.tmLanguage.json"
|
||||
}
|
||||
],
|
||||
"snippets": [
|
||||
{
|
||||
"language": "zero",
|
||||
"path": "./snippets/zero.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env node
|
||||
import { cp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
||||
import { homedir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
|
||||
const manifest = JSON.parse(await readFile("package.json", "utf8"));
|
||||
const extensionId = `${manifest.publisher}.${manifest.name}-${manifest.version}`;
|
||||
const extensionDir = join(homedir(), ".cursor", "extensions", extensionId);
|
||||
|
||||
await rm(extensionDir, { force: true, recursive: true });
|
||||
await mkdir(join(extensionDir, "language-configuration"), { recursive: true });
|
||||
await mkdir(join(extensionDir, "syntaxes"), { recursive: true });
|
||||
await mkdir(join(extensionDir, "snippets"), { recursive: true });
|
||||
|
||||
await cp("package.json", join(extensionDir, "package.json"));
|
||||
await cp("README.md", join(extensionDir, "README.md"));
|
||||
await cp("language-configuration/zero.json", join(extensionDir, "language-configuration", "zero.json"));
|
||||
await cp("syntaxes/zero.tmLanguage.json", join(extensionDir, "syntaxes", "zero.tmLanguage.json"));
|
||||
await cp("snippets/zero.json", join(extensionDir, "snippets", "zero.json"));
|
||||
await writeFile(join(extensionDir, ".installed-by-zero"), new Date().toISOString());
|
||||
|
||||
console.log(`Installed ${manifest.publisher}.${manifest.name} to ${extensionDir}`);
|
||||
console.log("Reload the Cursor window for syntax highlighting to activate.");
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"main": {
|
||||
"prefix": "main",
|
||||
"body": [
|
||||
"pub fn main(world: World) -> Void raises {",
|
||||
" check world.out.write(\"$1\\\\n\")",
|
||||
"}"
|
||||
],
|
||||
"description": "Zero main entrypoint"
|
||||
},
|
||||
"type": {
|
||||
"prefix": "type",
|
||||
"body": [
|
||||
"type ${1:Name} {",
|
||||
" ${2:field}: ${3:i32},",
|
||||
"}"
|
||||
],
|
||||
"description": "Zero type declaration"
|
||||
},
|
||||
"function": {
|
||||
"prefix": "fn",
|
||||
"body": [
|
||||
"fn ${1:name}(${2:param}: ${3:i32}) -> ${4:i32} {",
|
||||
" return ${2:param}",
|
||||
"}"
|
||||
],
|
||||
"description": "Zero function declaration"
|
||||
},
|
||||
"test": {
|
||||
"prefix": "test",
|
||||
"body": [
|
||||
"test \"${1:behavior}\" {",
|
||||
" expect(${2:true})",
|
||||
"}"
|
||||
],
|
||||
"description": "Zero test block"
|
||||
},
|
||||
"if": {
|
||||
"prefix": "if",
|
||||
"body": [
|
||||
"if $1 {",
|
||||
" $2",
|
||||
"}"
|
||||
],
|
||||
"description": "Zero if statement"
|
||||
},
|
||||
"while": {
|
||||
"prefix": "while",
|
||||
"body": [
|
||||
"while $1 {",
|
||||
" $2",
|
||||
"}"
|
||||
],
|
||||
"description": "Zero while loop"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
|
||||
"name": "Zero",
|
||||
"scopeName": "source.zero",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#comments"
|
||||
},
|
||||
{
|
||||
"include": "#strings"
|
||||
},
|
||||
{
|
||||
"include": "#chars"
|
||||
},
|
||||
{
|
||||
"include": "#numbers"
|
||||
},
|
||||
{
|
||||
"include": "#keywords"
|
||||
},
|
||||
{
|
||||
"include": "#types"
|
||||
},
|
||||
{
|
||||
"include": "#functions"
|
||||
},
|
||||
{
|
||||
"include": "#operators"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"comments": {
|
||||
"patterns": [
|
||||
{
|
||||
"name": "comment.line.double-slash.zero",
|
||||
"match": "//.*$"
|
||||
},
|
||||
{
|
||||
"name": "comment.block.zero",
|
||||
"begin": "/\\*",
|
||||
"end": "\\*/"
|
||||
}
|
||||
]
|
||||
},
|
||||
"strings": {
|
||||
"patterns": [
|
||||
{
|
||||
"name": "string.quoted.double.zero",
|
||||
"begin": "\"",
|
||||
"end": "\"",
|
||||
"patterns": [
|
||||
{
|
||||
"name": "constant.character.escape.zero",
|
||||
"match": "\\\\(?:[nrt0\"\\\\]|x[0-9A-Fa-f]{2}|u\\{[0-9A-Fa-f]+\\})"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"chars": {
|
||||
"patterns": [
|
||||
{
|
||||
"name": "constant.character.zero",
|
||||
"match": "'(?:[^'\\\\\\n]|\\\\(?:[nrt0'\"\\\\]|x[0-9A-Fa-f]{2}))'"
|
||||
}
|
||||
]
|
||||
},
|
||||
"numbers": {
|
||||
"patterns": [
|
||||
{
|
||||
"name": "constant.numeric.zero",
|
||||
"match": "\\b(?:[0-9]+\\.[0-9]+(?:[eE][+-]?[0-9]+)?|0x[0-9A-Fa-f_]+|0b[01_]+|0o[0-7_]+|[0-9][0-9_]*(?:_[A-Za-z][A-Za-z0-9_]*)?)\\b"
|
||||
}
|
||||
]
|
||||
},
|
||||
"keywords": {
|
||||
"patterns": [
|
||||
{
|
||||
"name": "keyword.control.zero",
|
||||
"match": "\\b(?:break|check|continue|defer|else|for|if|match|raise|raises|rescue|return|while)\\b"
|
||||
},
|
||||
{
|
||||
"name": "keyword.declaration.zero",
|
||||
"match": "\\b(?:alias|choice|const|enum|export|extern|fn|interface|let|meta|mut|packed|pub|static|test|type|use|var)\\b"
|
||||
},
|
||||
{
|
||||
"name": "constant.language.zero",
|
||||
"match": "\\b(?:false|null|true)\\b"
|
||||
}
|
||||
]
|
||||
},
|
||||
"types": {
|
||||
"patterns": [
|
||||
{
|
||||
"name": "support.type.primitive.zero",
|
||||
"match": "\\b(?:Bool|Void|Type|char|usize|isize|u[0-9]+|i[0-9]+|f(?:16|32|64)|c_(?:int|long|size|char)|World|Alloc|Fs|Net|Env|Args|Clock|Rand|Proc|Sync)\\b"
|
||||
},
|
||||
{
|
||||
"name": "support.type.container.zero",
|
||||
"match": "\\b(?:Maybe|Span|owned|ref|mutref|Vec|String)\\b"
|
||||
}
|
||||
]
|
||||
},
|
||||
"functions": {
|
||||
"patterns": [
|
||||
{
|
||||
"name": "entity.name.function.zero",
|
||||
"match": "(?<=\\bfn\\s+)[A-Za-z_][A-Za-z0-9_]*"
|
||||
},
|
||||
{
|
||||
"name": "entity.name.function.method.zero",
|
||||
"match": "\\b[A-Za-z_][A-Za-z0-9_]*(?=\\s*\\()"
|
||||
}
|
||||
]
|
||||
},
|
||||
"operators": {
|
||||
"patterns": [
|
||||
{
|
||||
"name": "keyword.operator.zero",
|
||||
"match": "\\b(?:as)\\b|->|=>|\\+%|\\+\\||==|!=|<=|>=|&&|\\|\\||[=+\\-*/%<>.:]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { describe, it } from "node:test";
|
||||
|
||||
describe("VS Code extension manifest", () => {
|
||||
it("contributes Zero language support for .0 files", async () => {
|
||||
const manifest = JSON.parse(await readFile("package.json", "utf8"));
|
||||
const language = manifest.contributes?.languages?.find((entry) => entry.id === "zero");
|
||||
const grammar = manifest.contributes?.grammars?.find((entry) => entry.language === "zero");
|
||||
const snippets = manifest.contributes?.snippets?.find((entry) => entry.language === "zero");
|
||||
|
||||
assert.ok(language);
|
||||
assert.deepEqual(language.extensions, [".0"]);
|
||||
assert.equal(language.configuration, "./language-configuration/zero.json");
|
||||
|
||||
assert.ok(grammar);
|
||||
assert.equal(grammar.scopeName, "source.zero");
|
||||
assert.equal(grammar.path, "./syntaxes/zero.tmLanguage.json");
|
||||
|
||||
assert.ok(snippets);
|
||||
assert.equal(snippets.path, "./snippets/zero.json");
|
||||
});
|
||||
|
||||
it("ships snippets for main, type, fn, and test", async () => {
|
||||
const snippets = JSON.parse(await readFile("snippets/zero.json", "utf8"));
|
||||
assert.ok(snippets.main);
|
||||
assert.ok(snippets.type);
|
||||
assert.ok(snippets.function);
|
||||
assert.ok(snippets.test);
|
||||
});
|
||||
|
||||
it("highlights core Zero keywords and types", async () => {
|
||||
const grammar = JSON.parse(await readFile("syntaxes/zero.tmLanguage.json", "utf8"));
|
||||
const matches = Object.values(grammar.repository)
|
||||
.flatMap((entry) => entry.patterns)
|
||||
.map((pattern) => pattern.match ?? "")
|
||||
.join("\n");
|
||||
|
||||
assert.match(matches, /fn/);
|
||||
assert.match(matches, /raises/);
|
||||
assert.match(matches, /type/);
|
||||
assert.match(matches, /World/);
|
||||
assert.doesNotMatch(matches, /Vercel|Request|Response/);
|
||||
|
||||
const declarationKeywords = grammar.repository.keywords.patterns.find(
|
||||
(pattern) => pattern.name === "keyword.declaration.zero"
|
||||
)?.match;
|
||||
assert.match(declarationKeywords, /\|mut\|/);
|
||||
});
|
||||
|
||||
it("highlights comments, strings, and numbers", async () => {
|
||||
const grammar = JSON.parse(await readFile("syntaxes/zero.tmLanguage.json", "utf8"));
|
||||
assert.equal(grammar.repository.comments.patterns[0].name, "comment.line.double-slash.zero");
|
||||
assert.equal(grammar.repository.comments.patterns[1].name, "comment.block.zero");
|
||||
assert.equal(grammar.repository.strings.patterns[0].name, "string.quoted.double.zero");
|
||||
assert.equal(grammar.repository.numbers.patterns[0].name, "constant.numeric.zero");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user