diff --git a/developer/src/kmc/src/util/NodeCompilerCallbacks.ts b/developer/src/kmc/src/util/NodeCompilerCallbacks.ts
index fd5f29d2122..de80ba62f27 100644
--- a/developer/src/kmc/src/util/NodeCompilerCallbacks.ts
+++ b/developer/src/kmc/src/util/NodeCompilerCallbacks.ts
@@ -193,6 +193,11 @@ export class NodeCompilerCallbacks implements CompilerCallbacks {
this.printMessage(event);
}
+ /** Bottleneck for output */
+ protected writeString(str: string) {
+ process.stdout.write(str);
+ }
+
private printMessage(event: CompilerEvent) {
if(this.options.logFormat == 'tsv') {
this.printTsvMessage(event);
@@ -202,7 +207,7 @@ export class NodeCompilerCallbacks implements CompilerCallbacks {
}
private printTsvMessage(event: CompilerEvent) {
- process.stdout.write([
+ this.writeString([
CompilerError.formatFilename(event.filename, {fullPath:true, forwardSlashes:false}),
CompilerError.formatLine(event.line),
CompilerError.formatSeverity(event.code),
@@ -214,7 +219,7 @@ export class NodeCompilerCallbacks implements CompilerCallbacks {
private printFormattedMessage(event: CompilerEvent) {
const severityColor = severityColors[CompilerError.severity(event.code)] ?? color.reset;
const messageColor = this.messageSpecialColor(event) ?? color.reset;
- process.stdout.write(
+ this.writeString(
(
event.filename
? color.cyan(CompilerError.formatFilename(event.filename)) +
@@ -228,7 +233,7 @@ export class NodeCompilerCallbacks implements CompilerCallbacks {
if(event.code == InfrastructureMessages.INFO_ProjectBuiltSuccessfully) {
// Special case: we'll add a blank line after project builds
- process.stdout.write('\n');
+ this.writeString('\n');
}
}
diff --git a/developer/src/vscode-plugin/app/App.tsx b/developer/src/vscode-plugin/app/App.tsx
index f109b9973be..db87a86beb5 100644
--- a/developer/src/vscode-plugin/app/App.tsx
+++ b/developer/src/vscode-plugin/app/App.tsx
@@ -7,6 +7,20 @@ function count() : number {
return (++a);
}
+let kmxplus = null;
+let text = null;
+
+window.addEventListener('message', event => {
+ const message = event.data;
+ switch (message.command) {
+ case 'update':
+ kmxplus = message.kmxplus;
+ text = message.text;
+ break;
+ }
+});
+
+
function App() {
return (
diff --git a/developer/src/vscode-plugin/src/extensionCallbacks.mts b/developer/src/vscode-plugin/src/extensionCallbacks.mts
new file mode 100644
index 00000000000..e0c0fa7c6b9
--- /dev/null
+++ b/developer/src/vscode-plugin/src/extensionCallbacks.mts
@@ -0,0 +1,25 @@
+/*
+ * Keyman is copyright (C) SIL Global. MIT License.
+ */
+
+import * as process from 'node:process';
+import { CompilerCallbackOptions } from "@keymanapp/developer-utils";
+import { NodeCompilerCallbacks } from "@keymanapp/kmc/build/src/util/NodeCompilerCallbacks.js";
+
+export class ExtensionCallbacks extends NodeCompilerCallbacks {
+ /**
+ * @param options options to pass to NodeCompilerCallbacks
+ * @param msg callback to write to the console
+ */
+ constructor(options: CompilerCallbackOptions, private msg?: (m: string)=>void) {
+ super(options);
+ }
+
+ protected writeString(str: string) {
+ if (this.msg) {
+ this.msg(str);
+ } else {
+ process.stdout.write(str);
+ }
+ }
+}
diff --git a/developer/src/vscode-plugin/src/kmcLdmlCompilerManager.mts b/developer/src/vscode-plugin/src/kmcLdmlCompilerManager.mts
index 0fc0c813199..7ffd930d926 100644
--- a/developer/src/vscode-plugin/src/kmcLdmlCompilerManager.mts
+++ b/developer/src/vscode-plugin/src/kmcLdmlCompilerManager.mts
@@ -2,19 +2,59 @@
* Keyman is copyright (C) SIL Global. MIT License.
*/
-// import { NodeCompilerCallbacks } from "@keymanapp/kmc";
import { LDMLCompilerManager } from "./ldmlCompilerManager.js";
-
+import { CompilerCallbackOptions, CompilerCallbacks, defaultCompilerOptions } from "@keymanapp/developer-utils";
+import { LdmlCompilerOptions, LdmlKeyboardCompiler } from "@keymanapp/kmc-ldml";
+import { ExtensionCallbacks } from "./extensionCallbacks.mjs";
+import { KMXPlus } from "@keymanapp/common-types";
/**
* TODO-LDML-EDITOR: should use vscode.workspace.fs.readFile which can read from remote workspaces.
+ *
+ * TODO-LDML-EDITOR: naming can be improved.
*/
export class KmcLdmlManager implements LDMLCompilerManager {
+ calloptions?: CompilerCallbackOptions;
+ callbacks?: CompilerCallbacks;
+ compoptions?: LdmlCompilerOptions;
+
async init(): Promise
{
+ if (this.callbacks) {
+ return; // already initted
+ }
console.log("Initting KmcLdmlManager…");
- // new NodeCompilerCallbacks({
- // });
+ this.calloptions = {
+ logLevel: "debug"
+ };
+ this.callbacks = new ExtensionCallbacks(this.calloptions); // TODO-EPIC-LDML: capture output
console.log("KmcLdmlManager okay!");
+ console.log('Initted');
+ }
+
+ async compile(filename: string): Promise {
+ if (!this.callbacks) {
+ throw Error(`Must call init() first.`);
+ }
+ const k = new LdmlKeyboardCompiler();
+ this.compoptions = {
+ ...defaultCompilerOptions,
+ readerOptions: {
+ // TODO-EPIC-LDML: need to use global path
+ importsPath: "/Users/srl295/src/cldr/keyboards/import/",
+ }
+ };
+ await k.init(this.callbacks, this.compoptions);
+ const source = await k.load(filename);
+ console.log(`loaded ${filename}`);
+ if (!source) {
+ throw Error(`Could not load ${filename}`);
+ }
+ const compiled = await k.compile(source);
+ if (!compiled) {
+ throw Error(`Could not compile ${filename}`);
+ }
+ console.log(`compiled ${filename}`);
+ return compiled;
}
};
diff --git a/developer/src/vscode-plugin/src/ldmlCompilerManager.ts b/developer/src/vscode-plugin/src/ldmlCompilerManager.ts
index 05a0dfb070a..2cc81a44159 100644
--- a/developer/src/vscode-plugin/src/ldmlCompilerManager.ts
+++ b/developer/src/vscode-plugin/src/ldmlCompilerManager.ts
@@ -7,8 +7,10 @@
* This is abstract because the ES module needs to be loaded asynchronously.
*/
export interface LDMLCompilerManager {
- /** validate that everything loaded properly */
+ /** validate that everything loaded properly. idempotent */
init() : Promise;
+ /** Compile a file. Returns KMXPlus file. */
+ compile(filename: string) : Promise;
};
/** load concrete instance from module */
diff --git a/developer/src/vscode-plugin/src/ldmleditor.ts b/developer/src/vscode-plugin/src/ldmleditor.ts
index 11fc4b58db1..8d3d7bff686 100644
--- a/developer/src/vscode-plugin/src/ldmleditor.ts
+++ b/developer/src/vscode-plugin/src/ldmleditor.ts
@@ -6,7 +6,7 @@
import * as vscode from 'vscode';
import * as crypto from 'crypto';
-import { getLDMLCompilerManager } from './ldmlCompilerManager';
+import { getLDMLCompilerManager, LDMLCompilerManager } from './ldmlCompilerManager';
interface LdmlDocumentDelegate {
getFileData(): Promise;
@@ -41,8 +41,17 @@ class LdmlDocument implements vscode.CustomDocument {
}
export class LdmlEditorProvider implements vscode.CustomTextEditorProvider {
+ private compiler? : LDMLCompilerManager;
private static readonly viewType = 'keyman.ldml'; // sync w/ package.json
+ private async getCompiler() : Promise {
+ if (!this.compiler) {
+ this.compiler = await getLDMLCompilerManager();
+ }
+ await this.compiler.init();
+ return this.compiler;
+ }
+
constructor(private readonly context: vscode.ExtensionContext) { }
static register(context: vscode.ExtensionContext): vscode.Disposable {
const provider = new LdmlEditorProvider(context);
@@ -96,8 +105,10 @@ export class LdmlEditorProvider implements vscode.CustomTextEditorProvider {
}
async resolveCustomTextEditor(document: vscode.TextDocument, webviewPanel: vscode.WebviewPanel, token: vscode.CancellationToken): Promise {
+ // make sure we have a compiler
+ const compiler = await this.getCompiler();
// temporary - testing linkage
- await (await getLDMLCompilerManager()).init();
+ const kmxPlus = await compiler.compile(document.fileName);
webviewPanel.webview.options = {
enableScripts: true,
@@ -142,6 +153,7 @@ export class LdmlEditorProvider implements vscode.CustomTextEditorProvider {
webviewPanel.webview.postMessage({
type: 'update',
text: document.getText(),
+ kmxPlus,
});
}