Skip to content

Commit cc2d6c4

Browse files
authored
Merge pull request #72 from hildjj/from-mem
from mem
2 parents cc5f1a3 + 0561c7a commit cc2d6c4

File tree

8 files changed

+712
-671
lines changed

8 files changed

+712
-671
lines changed

client/client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ let client: LanguageClient = undefined;
1313
export function activate(context: ExtensionContext): void {
1414
// The server is implemented in node
1515
const serverModule
16-
= context.asAbsolutePath(path.join("out", "server", "server.js"));
16+
= context.asAbsolutePath(path.join("out", "server.js"));
1717

1818
// The debug options for the server
1919
const debugOptions = { execArgv: ["--nolazy", "--inspect=6009"] };

client/preview.ts

Lines changed: 90 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import * as fromMem from "@peggyjs/from-mem";
12
import * as path from "path";
23
import * as peggy from "peggy";
3-
import * as util from "node-inspect-extracted";
44
import {
55
ExtensionContext,
66
OutputChannel,
@@ -12,6 +12,7 @@ import {
1212
} from "vscode";
1313
import { MemFS } from "../vendor/vscode-extension-samples/fileSystemProvider";
1414
import { debounce } from "../common/debounce";
15+
import { fileURLToPath } from "url";
1516

1617
const PEGGY_INPUT_SCHEME = "peggyjsin";
1718

@@ -22,60 +23,98 @@ interface GrammarConfig {
2223
grammar_uri: Uri;
2324
input_uri: Uri;
2425
timeout?: NodeJS.Timeout;
25-
grammar_text?: string;
26-
parser?: any;
2726
}
2827

2928
async function executeAndDisplayResults(
3029
output: OutputChannel,
3130
config: GrammarConfig
3231
): Promise<void> {
3332
output.show(true);
34-
let out = `// ${config.name} ${config.start_rule ? `(${config.start_rule})` : ""}\n`;
33+
let out = `// ${config.name}${config.start_rule ? ` (${config.start_rule})` : ""}\n`;
34+
35+
const [grammar_document, input_document] = [
36+
await workspace.openTextDocument(config.grammar_uri),
37+
await workspace.openTextDocument(config.input_uri),
38+
];
39+
40+
// Never leave it dirty; it's saved in memory anyway.
41+
// Don't bother to wait for the promise.
42+
input_document.save();
43+
const input = input_document.getText();
44+
const filename = fileURLToPath(grammar_document.uri.toString());
3545

3646
try {
37-
const [grammar_document, input_document] = [
38-
await workspace.openTextDocument(config.grammar_uri),
39-
await workspace.openTextDocument(config.input_uri),
40-
];
41-
42-
// Never leave it dirty; it's saved in memory anyway.
43-
// Don't bother to wait for the promise.
44-
input_document.save();
4547
const grammar_text = grammar_document.getText();
4648

47-
if (grammar_text !== config.grammar_text) {
48-
config.parser = peggy.generate(
49-
grammar_text,
50-
config.start_rule
51-
? {
52-
allowedStartRules: [config.start_rule],
53-
}
54-
: undefined
55-
);
56-
config.grammar_text = grammar_text;
49+
const format = await fromMem.guessModuleType(filename);
50+
const pbo: peggy.SourceBuildOptions<"source"> = {
51+
output: "source",
52+
format,
53+
};
54+
if (config.start_rule) {
55+
pbo.allowedStartRules = [config.start_rule];
5756
}
57+
const parserSource = peggy.generate(grammar_text, pbo);
5858

59-
const input = input_document.getText();
60-
const result = config.parser.parse(
61-
input,
62-
config.start_rule ? { startRule: config.start_rule } : undefined
63-
);
59+
const consoleOutput: fromMem.ConsoleOutErr = {};
60+
const parseOpts: PEG.ParserOptions = {
61+
grammarSource: config.name,
62+
};
63+
if (config.start_rule) {
64+
parseOpts.startRule = config.start_rule;
65+
}
6466

65-
out += util.inspect(result, {
66-
depth: Infinity,
67-
colors: false,
68-
maxArrayLength: Infinity,
69-
maxStringLength: Infinity,
70-
breakLength: 40,
71-
sorted: true,
67+
const result = await fromMem(parserSource, {
68+
filename,
69+
format,
70+
consoleOutput,
71+
exec: `
72+
const util = await import("node:util");
73+
try {
74+
const res = IMPORTED.parse(...arg);
75+
return util.inspect(res, {
76+
depth: Infinity,
77+
colors: false,
78+
maxArrayLength: Infinity,
79+
maxStringLength: Infinity,
80+
breakLength: 40,
81+
sorted: true,
82+
});
83+
} catch (er) {
84+
if (typeof er.format === "function") {
85+
er.message = er.format([{
86+
source: arg[1].grammarSource,
87+
text: arg[0],
88+
}]);
89+
}
90+
throw er;
91+
}
92+
`,
93+
arg: [input, parseOpts],
94+
colorMode: false,
7295
});
96+
97+
consoleOutput.capture?.();
98+
if (consoleOutput.out) {
99+
consoleOutput.out = consoleOutput.out.trimEnd();
100+
out += "\n" + consoleOutput.out.replace(/^/gm, "// stdout: ") + "\n";
101+
}
102+
if (consoleOutput.err) {
103+
consoleOutput.err = consoleOutput.err.trimEnd();
104+
out += "\n" + consoleOutput.err.replace(/^/gm, "// stderr: ") + "\n";
105+
}
73106
out += "\n";
74-
} catch (error) {
107+
out += result;
108+
out += "\n";
109+
} catch(error) {
75110
out += error.toString();
111+
}
112+
if (!out.endsWith("\n")) {
76113
out += "\n";
77114
}
78-
// Replace once, since addLine causes issues with trailing spaces.
115+
116+
// Replace once. Causes trailing spaces to be deleted in input doc,
117+
// seemingly.
79118
output.replace(out);
80119
}
81120

@@ -93,10 +132,10 @@ export function activate(context: ExtensionContext): void {
93132
.replace(/^[(][^)]+[)]__/, "");
94133
}
95134

96-
function trackGrammar(
135+
async function trackGrammar(
97136
grammar_document_uri: Uri,
98137
start_rule?: string
99-
): GrammarConfig {
138+
): Promise<GrammarConfig> {
100139
const grammar_name = grammarNameFromUri(grammar_document_uri);
101140
const key = `${grammar_name}:${start_rule || "*"}`;
102141

@@ -109,11 +148,10 @@ export function activate(context: ExtensionContext): void {
109148
);
110149

111150
if (!is_input_document_open) {
112-
workspace.fs.writeFile(input_document_uri, Buffer.from("")).then(() => {
113-
window.showTextDocument(input_document_uri, {
114-
viewColumn: ViewColumn.Beside,
115-
preserveFocus: true,
116-
});
151+
await workspace.fs.writeFile(input_document_uri, Buffer.from(""));
152+
await window.showTextDocument(input_document_uri, {
153+
viewColumn: ViewColumn.Beside,
154+
preserveFocus: false,
117155
});
118156
}
119157
const config = {
@@ -135,7 +173,7 @@ export function activate(context: ExtensionContext): void {
135173
config.grammar_uri.toString() === document_uri_string
136174
|| config.input_uri.toString() === document_uri_string
137175
) {
138-
await executeAndDisplayResults(peggy_output, config);
176+
debounceExecution(peggy_output, config);
139177
}
140178
}
141179
});
@@ -154,19 +192,22 @@ export function activate(context: ExtensionContext): void {
154192
documents_changed,
155193
documents_closed,
156194
peggy_output,
157-
commands.registerTextEditorCommand("editor.peggyLive", editor => {
158-
const grammar_config = trackGrammar(editor.document.uri);
195+
commands.registerTextEditorCommand("editor.peggyLive", async editor => {
196+
const grammar_config = await trackGrammar(editor.document.uri);
159197
debounceExecution(peggy_output, grammar_config);
160198
}),
161-
commands.registerTextEditorCommand("editor.peggyLiveFromRule", editor => {
199+
commands.registerTextEditorCommand("editor.peggyLiveFromRule", async editor => {
162200
const word_range = editor.document.getWordRangeAtPosition(
163201
editor.selection.start,
164-
/[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*/
202+
/[\p{ID_Start}][\p{ID_Continue}]*/u
165203
);
166204

167205
if (word_range !== null) {
168206
const rule_name = editor.document.getText(word_range);
169-
const grammar_config = trackGrammar(editor.document.uri, rule_name);
207+
const grammar_config = await trackGrammar(
208+
editor.document.uri,
209+
rule_name
210+
);
170211

171212
debounceExecution(peggy_output, grammar_config);
172213
}

common/debounce.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@ export function debounce<T extends (...args: any[]) => any>(
88
): (...args: Parameters<T>) => void {
99
let timeout: NodeJS.Timeout = undefined;
1010

11-
return (...args: Parameters<T>) => {
11+
return (...args: Parameters<T>): void => {
1212
if (timeout) {
1313
clearTimeout(timeout);
1414
}
15-
timeout = setTimeout(() => fn(...args), wait);
15+
timeout = setTimeout(() => {
16+
timeout = undefined;
17+
fn(...args);
18+
}, wait);
1619
};
1720
}

0 commit comments

Comments
 (0)