diff --git a/README.md b/README.md index 70226d0..2829fa9 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,14 @@ See the [Marketplace](https://marketplace.visualstudio.com/items?itemName=PeggyJ merely informative ones. Some grammar compiler passes will give informative messages about optimizations. Those may be more annoying to you than helpful, depending on your approach to grammar writing. +- `peggyLanguageServer.debounceMS` [default: *200*] Amount of time to wait + after a file has changed before running. Longer times use less CPU but are + less responsive. +- `peggyLanguageServer.filePattern` [default: *%s/%s.js*] Convert a grammar + name to a JS file to output, using this first `%s` as the directory and the + second `%s` as the unsuffixed name of the grammar. This is useful in a per- + workspace configuration file so that `import` and `require` work from the + correct output directory. ## Syntax Highlighting @@ -59,6 +67,10 @@ of all of the rules in the Outline view. Live edit and test your Grammars, optionally starting at the rule under cursor. +![Live Preview Menu](/images/LivePreviewMenu.png) + +![Live Preview](/images/LivePreview.png) + ## Problem Matchers Report problems of your code in the Problems view when `peggy` is run in a task. diff --git a/client/preview.ts b/client/preview.ts index d6025a4..0d67b61 100644 --- a/client/preview.ts +++ b/client/preview.ts @@ -3,8 +3,10 @@ import * as peggy from "peggy"; import { ExtensionContext, OutputChannel, + Selection, Tab, TabInputText, + TextEditorRevealType, Uri, ViewColumn, commands, @@ -13,11 +15,12 @@ import { } from "vscode"; import { MemFS } from "../vendor/vscode-extension-samples/fileSystemProvider"; import { debouncePromise } from "../common/debounce"; -import { fileURLToPath } from "url"; import fromMem from "@peggyjs/from-mem"; +import { format as uformat } from "node:util"; const PEGGY_INPUT_SCHEME = "peggyjsin"; const ID = "peggyLanguageServer"; +let filePattern = "%s/%s.js"; interface GrammarConfig { name: string; @@ -57,7 +60,12 @@ async function executeAndDisplayResults( const input = input_document.getText(); const fs = await import("node:fs"); fs.writeFileSync("/tmp/u.txt", JSON.stringify(config)); - const filename = fileURLToPath(grammar_document.uri.toString()); + const parsedFilename = path.parse(grammar_document.uri.fsPath); + const filename = path.resolve(uformat( + filePattern, + parsedFilename.dir, + parsedFilename.name + )); try { const grammar_text = grammar_document.getText(); @@ -227,12 +235,16 @@ export function activate(context: ExtensionContext): void { } }); + const initialConfig = workspace.getConfiguration(ID); + debounceExecution.wait = initialConfig.get("debounceMS"); + filePattern = initialConfig.get("filePattern"); const configChanged = workspace.onDidChangeConfiguration(e => { if (e.affectsConfiguration(ID)) { - debounceExecution.wait = workspace.getConfiguration(ID).get("debounceMS"); + const config = workspace.getConfiguration(ID); + debounceExecution.wait = config.get("debounceMS"); + filePattern = config.get("filePattern"); } }); - debounceExecution.wait = workspace.getConfiguration(ID).get("debounceMS"); context.subscriptions.push( configChanged, @@ -253,13 +265,19 @@ export function activate(context: ExtensionContext): void { ); if (word_range !== null) { + editor.selection = new Selection(word_range.start, word_range.end); const rule_name = editor.document.getText(word_range); const grammar_config = await trackGrammar( editor.document.uri, rule_name ); - return debounceExecution(peggy_output, grammar_config); + return debounceExecution(peggy_output, grammar_config).then(() => { + editor.revealRange( + word_range, + TextEditorRevealType.InCenterIfOutsideViewport + ); + }); } return null; diff --git a/images/LivePreview.png b/images/LivePreview.png new file mode 100644 index 0000000..209f287 Binary files /dev/null and b/images/LivePreview.png differ diff --git a/images/LivePreviewMenu.png b/images/LivePreviewMenu.png new file mode 100644 index 0000000..e9350cc Binary files /dev/null and b/images/LivePreviewMenu.png differ diff --git a/package.json b/package.json index fe9ade0..3707324 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,13 @@ "peggyLanguageServer.debounceMS": { "description": "Time, in milliseconds, to debounce typing", "type": "integer", - "default": 200 + "default": 200, + "minimum": 0 + }, + "peggyLanguageServer.filePattern": { + "markdownDescription": "Convert a grammar name to a JS file to output, using this first `%s` as the directory and the second `%s` as the unsuffixed name of the grammar.", + "type": "string", + "default": "%s/%s.js" } } }, @@ -188,7 +194,7 @@ "eslint-plugin-mocha": "11.1.0", "npm-run-all": "^4.1.5", "rimraf": "^6.0.1", - "typescript": "^5.8.3", + "typescript": "^5.9.2", "typescript-eslint": "8.38.0" }, "dependencies": { @@ -204,7 +210,7 @@ "c8": "10.1.3" } }, - "packageManager": "pnpm@10.13.1", + "packageManager": "pnpm@10.14.0", "engines": { "vscode": ">=1.102.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 58707a8..b6c3642 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -70,11 +70,11 @@ importers: specifier: ^6.0.1 version: 6.0.1 typescript: - specifier: ^5.8.3 - version: 5.8.3 + specifier: ^5.9.2 + version: 5.9.2 typescript-eslint: specifier: 8.38.0 - version: 8.38.0(eslint@9.32.0)(typescript@5.8.3) + version: 8.38.0(eslint@9.32.0)(typescript@5.9.2) packages: @@ -116,8 +116,8 @@ packages: resolution: {integrity: sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA==} engines: {node: '>=20.0.0'} - '@azure/msal-browser@4.16.0': - resolution: {integrity: sha512-yF8gqyq7tVnYftnrWaNaxWpqhGQXoXpDfwBtL7UCGlIbDMQ1PUJF/T2xCL6NyDNHoO70qp1xU8GjjYTyNIefkw==} + '@azure/msal-browser@4.18.0': + resolution: {integrity: sha512-esQwdtHHVkFJhcKWnysnCTchiKsy3dmNZGs8AckD9PO3t8Lp5VtY0xcrbCBC0JbttG/5w2/xukUQOsMpoUFKrg==} engines: {node: '>=0.8.0'} '@azure/msal-common@15.9.0': @@ -2535,8 +2535,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + typescript@5.9.2: + resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} engines: {node: '>=14.17'} hasBin: true @@ -2553,8 +2553,8 @@ packages: undici-types@7.8.0: resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} - undici@7.12.0: - resolution: {integrity: sha512-GrKEsc3ughskmGA9jevVlIOPMiiAHJ4OFUtaAH+NhfTUSiZ1wMPIQqQvAJUrJspFXJt3EBWgpAeoHEDVT1IBug==} + undici@7.13.0: + resolution: {integrity: sha512-l+zSMssRqrzDcb3fjMkjjLGmuiiK2pMIcV++mJaAc9vhjSGpvM7h43QgP+OAMb1GImHmbPyG2tBXeuyG5iY4gA==} engines: {node: '>=20.18.1'} unicorn-magic@0.1.0: @@ -2786,7 +2786,7 @@ snapshots: '@azure/core-tracing': 1.3.0 '@azure/core-util': 1.13.0 '@azure/logger': 1.3.0 - '@azure/msal-browser': 4.16.0 + '@azure/msal-browser': 4.18.0 '@azure/msal-node': 3.6.4 open: 10.2.0 tslib: 2.8.1 @@ -2800,7 +2800,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@azure/msal-browser@4.16.0': + '@azure/msal-browser@4.18.0': dependencies: '@azure/msal-common': 15.9.0 @@ -3187,41 +3187,41 @@ snapshots: '@types/vscode@1.102.0': {} - '@typescript-eslint/eslint-plugin@8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0)(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.9.2))(eslint@9.32.0)(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.38.0(eslint@9.32.0)(typescript@5.8.3) + '@typescript-eslint/parser': 8.38.0(eslint@9.32.0)(typescript@5.9.2) '@typescript-eslint/scope-manager': 8.38.0 - '@typescript-eslint/type-utils': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0)(typescript@5.8.3) + '@typescript-eslint/type-utils': 8.38.0(eslint@9.32.0)(typescript@5.9.2) + '@typescript-eslint/utils': 8.38.0(eslint@9.32.0)(typescript@5.9.2) '@typescript-eslint/visitor-keys': 8.38.0 eslint: 9.32.0 graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3)': + '@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.9.2)': dependencies: '@typescript-eslint/scope-manager': 8.38.0 '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.9.2) '@typescript-eslint/visitor-keys': 8.38.0 debug: 4.4.1(supports-color@8.1.1) eslint: 9.32.0 - typescript: 5.8.3 + typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.38.0(typescript@5.8.3)': + '@typescript-eslint/project-service@8.38.0(typescript@5.9.2)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.9.2) '@typescript-eslint/types': 8.38.0 debug: 4.4.1(supports-color@8.1.1) - typescript: 5.8.3 + typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -3230,28 +3230,28 @@ snapshots: '@typescript-eslint/types': 8.38.0 '@typescript-eslint/visitor-keys': 8.38.0 - '@typescript-eslint/tsconfig-utils@8.38.0(typescript@5.8.3)': + '@typescript-eslint/tsconfig-utils@8.38.0(typescript@5.9.2)': dependencies: - typescript: 5.8.3 + typescript: 5.9.2 - '@typescript-eslint/type-utils@8.38.0(eslint@9.32.0)(typescript@5.8.3)': + '@typescript-eslint/type-utils@8.38.0(eslint@9.32.0)(typescript@5.9.2)': dependencies: '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0)(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.9.2) + '@typescript-eslint/utils': 8.38.0(eslint@9.32.0)(typescript@5.9.2) debug: 4.4.1(supports-color@8.1.1) eslint: 9.32.0 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 transitivePeerDependencies: - supports-color '@typescript-eslint/types@8.38.0': {} - '@typescript-eslint/typescript-estree@8.38.0(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.38.0(typescript@5.9.2)': dependencies: - '@typescript-eslint/project-service': 8.38.0(typescript@5.8.3) - '@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.8.3) + '@typescript-eslint/project-service': 8.38.0(typescript@5.9.2) + '@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.9.2) '@typescript-eslint/types': 8.38.0 '@typescript-eslint/visitor-keys': 8.38.0 debug: 4.4.1(supports-color@8.1.1) @@ -3259,19 +3259,19 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.2 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.38.0(eslint@9.32.0)(typescript@5.8.3)': + '@typescript-eslint/utils@8.38.0(eslint@9.32.0)(typescript@5.9.2)': dependencies: '@eslint-community/eslint-utils': 4.7.0(eslint@9.32.0) '@typescript-eslint/scope-manager': 8.38.0 '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.9.2) eslint: 9.32.0 - typescript: 5.8.3 + typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -3591,7 +3591,7 @@ snapshots: parse5: 7.3.0 parse5-htmlparser2-tree-adapter: 7.1.0 parse5-parser-stream: 7.1.2 - undici: 7.12.0 + undici: 7.13.0 whatwg-mimetype: 4.0.0 chokidar@3.6.0: @@ -5645,9 +5645,9 @@ snapshots: dependencies: is-number: 7.0.0 - ts-api-utils@2.1.0(typescript@5.8.3): + ts-api-utils@2.1.0(typescript@5.9.2): dependencies: - typescript: 5.8.3 + typescript: 5.9.2 tslib@2.8.1: {} @@ -5703,18 +5703,18 @@ snapshots: tunnel: 0.0.6 underscore: 1.13.7 - typescript-eslint@8.38.0(eslint@9.32.0)(typescript@5.8.3): + typescript-eslint@8.38.0(eslint@9.32.0)(typescript@5.9.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0)(typescript@5.8.3) - '@typescript-eslint/parser': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0)(typescript@5.8.3) + '@typescript-eslint/eslint-plugin': 8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.9.2))(eslint@9.32.0)(typescript@5.9.2) + '@typescript-eslint/parser': 8.38.0(eslint@9.32.0)(typescript@5.9.2) + '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.9.2) + '@typescript-eslint/utils': 8.38.0(eslint@9.32.0)(typescript@5.9.2) eslint: 9.32.0 - typescript: 5.8.3 + typescript: 5.9.2 transitivePeerDependencies: - supports-color - typescript@5.8.3: {} + typescript@5.9.2: {} uc.micro@2.1.0: {} @@ -5729,7 +5729,7 @@ snapshots: undici-types@7.8.0: {} - undici@7.12.0: {} + undici@7.13.0: {} unicorn-magic@0.1.0: {}