1+ import * as fromMem from "@peggyjs/from-mem" ;
12import * as path from "path" ;
23import * as peggy from "peggy" ;
3- import * as util from "node-inspect-extracted" ;
44import {
55 ExtensionContext ,
66 OutputChannel ,
@@ -12,6 +12,7 @@ import {
1212} from "vscode" ;
1313import { MemFS } from "../vendor/vscode-extension-samples/fileSystemProvider" ;
1414import { debounce } from "../common/debounce" ;
15+ import { fileURLToPath } from "url" ;
1516
1617const 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
2928async 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 - z A - Z \xA0 - \uFFFF ] [ _ $ a - z A - Z 0 - 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 }
0 commit comments