├── .gitattributes ├── .gitignore ├── src ├── lsp │ ├── README.md │ ├── LICENSE │ └── index.ts ├── main.zig ├── theme.ts ├── workers │ ├── runner.ts │ ├── zig.ts │ └── zls.ts ├── utils.ts ├── zls.zig └── editor.ts ├── vite.config.js ├── README.md ├── zig.patch ├── package.json ├── .github └── workflows │ └── deploy.yml ├── index.html ├── LICENSE └── style ├── reset.css ├── zig-theme.css ├── zigtools-theme.css └── style.css /.gitattributes: -------------------------------------------------------------------------------- 1 | *.zig text=auto eol=lf 2 | *.zon text=auto eol=lf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .env 4 | repos 5 | .zig-cache 6 | zig-out 7 | -------------------------------------------------------------------------------- /src/lsp/README.md: -------------------------------------------------------------------------------- 1 | Rewritten version of https://github.com/FurqanSoftware/codemirror-languageserver 2 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | export default defineConfig({ 3 | plugins: [], 4 | }); -------------------------------------------------------------------------------- /src/main.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void { 4 | try std.fs.File.stdout().writeAll("Hello, World!\n"); 5 | } 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Zigtools Playground 2 | 3 | Run and explore Zig in your browser, with compiler and LSP support built in. 4 | 5 | ## Installation 6 | 7 | You can either: 8 | 9 | - Use it online: https://playground.zigtools.org/ 10 | - Run it locally: 11 | 12 | Requires Zig `0.15.1`. Will automatically fetch Zig along with ZLS, compiling both for webassembly. 13 | 14 | ```bash 15 | zig build 16 | npm install 17 | npm run dev 18 | ``` 19 | 20 | Enjoy! 21 | -------------------------------------------------------------------------------- /zig.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/dev.zig b/src/dev.zig 2 | index f4be5a36..ae4e914b 100644 3 | --- a/src/dev.zig 4 | +++ b/src/dev.zig 5 | @@ -150,12 +150,13 @@ pub const Env = enum { 6 | else => Env.sema.supports(feature), 7 | }, 8 | .wasm => switch (feature) { 9 | - .stdio_listen, 10 | - .incremental, 11 | .wasm_backend, 12 | .wasm_linker, 13 | + .build_exe_command, 14 | + .sema, 15 | + .ast_gen, 16 | => true, 17 | - else => Env.sema.supports(feature), 18 | + else => false, 19 | }, 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "playground", 3 | "type": "module", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "preview": "vite preview" 8 | }, 9 | "dependencies": { 10 | "@andrewbranch/untar.js": "^1.0.3", 11 | "@bjorn3/browser_wasi_shim": "^0.4.1", 12 | "@codemirror/autocomplete": "^6.4.2", 13 | "@codemirror/commands": "^6.2.2", 14 | "@codemirror/language": "^6.6.0", 15 | "@codemirror/lint": "^6.2.0", 16 | "@codemirror/state": "^6.2.0", 17 | "@codemirror/view": "^6.9.3", 18 | "codemirror": "^6.0.1", 19 | "vscode-languageserver-protocol": "^3.17.3" 20 | }, 21 | "devDependencies": { 22 | "typescript": "~5.7.2", 23 | "vite": "^6.3.1" 24 | }, 25 | "browserslist": [ 26 | "since 2017-06" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /src/theme.ts: -------------------------------------------------------------------------------- 1 | import { EditorView } from "@codemirror/view"; 2 | 3 | export const editorTheme = EditorView.theme( 4 | { 5 | "&": { 6 | backgroundColor: "var(--code-background-color)", 7 | color: "var(--code-text-color)", 8 | }, 9 | ".cm-gutter": { backgroundColor: "var(--code-background-color)" }, 10 | ".cm-gutterElement": { 11 | backgroundColor: "var(--code-background-color)", 12 | color: "var(--code-text-color)", 13 | }, 14 | ".cm-activeLine": { backgroundColor: "transparent" }, 15 | "&.cm-focused .cm-matchingBracket": { 16 | backgroundColor: "#FFFFFF30", 17 | }, 18 | ".cm-content": { caretColor: "var(--code-text-color)" }, 19 | ".cm-cursor, .cm-dropCursor": { borderLeftColor: "var(--code-text-color)" }, 20 | ".cm-tooltip": { 21 | backgroundColor: "var(--tooltip-background)", 22 | color: "var(--tooltip-text)", 23 | } 24 | }, 25 | {} 26 | ); 27 | 28 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | 3 | on: 4 | push: 5 | branches: ["main"] 6 | pull_request: 7 | workflow_dispatch: 8 | 9 | permissions: 10 | contents: read 11 | pages: write 12 | id-token: write 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | 21 | - uses: actions/setup-node@v4 22 | with: 23 | node-version: 22 24 | 25 | - uses: mlugg/setup-zig@v2 26 | 27 | - name: Install binaryen 28 | run: | 29 | sudo apt-get update 30 | sudo apt-get install binaryen 31 | 32 | - run: | 33 | zig build -Drelease -Dwasm-opt 34 | npm ci 35 | npm run build 36 | 37 | - uses: actions/upload-pages-artifact@v3 38 | with: 39 | path: "dist/" 40 | 41 | - uses: actions/deploy-pages@v4 42 | if: github.ref == 'refs/heads/main' 43 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 |(method: string, params: P): Promise (method: string, params: P) {
221 | await this.sendMessage({
222 | jsonrpc: "2.0",
223 | method,
224 | params,
225 | });
226 | }
227 |
228 | public handleMessage(message: JsonRpcMessage) {
229 | if (message.method === "workspace/configuration") {
230 | const configParams = message.params as LSP.ConfigurationParams;
231 | let resp: unknown[] = [];
232 |
233 | for (const item of configParams.items) {
234 | if (item.section === "zls.prefer_ast_check_as_child_process") {
235 | resp.push(false);
236 | } else {
237 | resp.push(null);
238 | }
239 | }
240 |
241 | this.sendMessage({
242 | jsonrpc: "2.0",
243 | id: message.id,
244 | result: resp,
245 | })
246 |
247 | return;
248 | }
249 |
250 | if (message.id !== undefined && message.method === undefined) {
251 | const req = this.outboundRequests.get(message.id);
252 | if (req) {
253 | if (message.error) req.reject(message.error);
254 | else req.resolve(message.result);
255 | } else {
256 | console.error("Got non-answer");
257 | }
258 | }
259 |
260 | for (const plugin of this.plugins)
261 | plugin.handleMessage(message);
262 | }
263 |
264 | public createPlugin(docUri: string, langId: string, allowHtmlContent: boolean) {
265 | let plugin: LspPlugin | null = null;
266 |
267 | const decorations = StateField.define