feat(editor): intellisense registry seam for the pro completion engine
This commit is contained in:
parent
5b82299793
commit
55bc03d281
|
|
@ -2,6 +2,7 @@ import Editor from '@monaco-editor/react';
|
|||
import { useEditorStore } from '../../store/useEditorStore';
|
||||
import { useSimulatorStore } from '../../store/useSimulatorStore';
|
||||
import { registerRetroAsm, LANGUAGE_ID as RETRO_ASM_ID } from './retroAsmLanguage';
|
||||
import { attachIntellisenseMonaco } from '../../lib/intellisenseRegistry';
|
||||
|
||||
function getLanguage(filename: string): string {
|
||||
const ext = filename.split('.').pop()?.toLowerCase() ?? '';
|
||||
|
|
@ -62,6 +63,10 @@ export const CodeEditor = () => {
|
|||
// Register the 8080/Z80 assembly language once so Monaco knows how
|
||||
// to tokenize .s / .asm files when they're opened.
|
||||
registerRetroAsm(monaco);
|
||||
// Hand the monaco instance to the intellisense seam. Inert in OSS;
|
||||
// with the pro overlay loaded it registers the completion engine
|
||||
// (idempotent per monaco instance, so per-file remounts are fine).
|
||||
attachIntellisenseMonaco(monaco);
|
||||
}}
|
||||
onChange={(value) => {
|
||||
if (activeFileId) setFileContent(activeFileId, value || '');
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* Intellisense registry.
|
||||
*
|
||||
* Seam between the OSS editor and the pro overlay's code-completion engine
|
||||
* (the private `velxio-intellisense` package). OSS ships no completion
|
||||
* engine of its own, so without an overlay this registry is inert and the
|
||||
* editor behaves exactly as before.
|
||||
*
|
||||
* Two-sided handshake, because arrival order is not guaranteed:
|
||||
*
|
||||
* - CodeEditor's `beforeMount` calls `attachIntellisenseMonaco(monaco)`
|
||||
* every time an editor instance is created (which happens on every
|
||||
* file switch — the editor is keyed by file id).
|
||||
* - The overlay calls `installIntellisenseImpl(impl)` from `mountPro()`,
|
||||
* which lands via an async `import('@pro/index')` and may resolve
|
||||
* before or after the first editor mounted.
|
||||
*
|
||||
* Whichever side arrives last triggers the install. The impl itself is
|
||||
* responsible for being idempotent per monaco instance (the package guards
|
||||
* with a WeakSet), so replaying it on every mount is safe and cheap.
|
||||
*/
|
||||
|
||||
type IntellisenseImpl = (monaco: unknown) => void;
|
||||
|
||||
let _impl: IntellisenseImpl | null = null;
|
||||
let _monaco: unknown = null;
|
||||
|
||||
export function installIntellisenseImpl(impl: IntellisenseImpl | null): void {
|
||||
_impl = impl;
|
||||
if (_impl && _monaco) run(_impl, _monaco);
|
||||
}
|
||||
|
||||
export function attachIntellisenseMonaco(monaco: unknown): void {
|
||||
_monaco = monaco;
|
||||
if (_impl) run(_impl, monaco);
|
||||
}
|
||||
|
||||
function run(impl: IntellisenseImpl, monaco: unknown): void {
|
||||
try {
|
||||
impl(monaco);
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('[oss] intellisense impl threw:', err);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue