@coldsmirk/inkstone-monaco 0.30.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/index.d.ts +21 -20
- package/dist/index.js +12 -10
- package/dist/vite.d.ts +2 -3
- package/dist/workers/ts.worker.js +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -12,15 +12,15 @@ Part of [inkstone](https://github.com/coldsmirk/inkstone). For a drop-in React c
|
|
|
12
12
|
- **`disabledKeybindings` / `installDisabledKeybindings`** — swallow the find/replace chords and the command palette's F1 for editors that opt in. Monaco's standalone keybinding service is page-global and its rules are permanent, so the install registers each chord once per monaco module's service (duplicate copies of this package share the ledger; independent monaco bundles register their own) and scopes it with a per-capability context key created on the opted-in editor; the chord table is held to the installed `monaco-editor` by an upgrade-tripwire test.
|
|
13
13
|
- **`installJsxTagClosing`** — VS Code's auto-closing JSX tags: a typed `>` that completes an opening tag inserts the matching closing tag and keeps the caret between the pair. Parser-backed: the bundled TS worker subclasses monaco's stock worker to expose `getJsxClosingTagAtPosition` — a language-service call monaco never proxied (VS Code ships the feature in its TypeScript extension, outside the editor core) — so generics, comparisons, arrow functions, and already-closed elements never trigger. Only a *typed* `>` triggers: the gates require one bare single-character insertion into a **writable** TypeScript/JavaScript model whose path ends in `.tsx` / `.jsx`, and the reply lands only while the caret still sits right after that `>` — so `replaceInEditor` replacements, `StreamingEditorController` appends (the stream holds the editor read-only), and other programmatic writes never earn a closing tag, and the insert arrives as its own undo step (one undo removes just the closing tag). A `getWorker` override that routes the `typescript` label to a worker without the subclass is detected on its first lookup and the install disarms silently. Multi-cursor typing and the diff editor's panes are deliberately out of scope. `<MonacoEditor>` installs it automatically.
|
|
14
14
|
- **`dropMonacoWorkerFallbacks()`** (from **`@coldsmirk/inkstone-monaco/vite`**) — a Vite plugin that removes monaco's built-in worker fallbacks at build time. Monaco's language workerManagers statically reference their workers as `new Worker(new URL(...))` fallbacks that never run under `ensureMonacoHost` (the environment check prefers `getWorker`), yet bundlers emit a chunk per reference — including a ~7MB TypeScript worker duplicate that is never fetched. The plugin rewrites the fallbacks into located throws so the duplicates are never emitted; if a monaco bump reshapes the pattern it warns and leaves the file untouched (the dead chunk returns, nothing breaks).
|
|
15
|
-
- **Embedded-editor fixes** — works around [microsoft/monaco-editor#5177](https://github.com/microsoft/monaco-editor/issues/5177) (find-widget button tooltips landing on top of the buttons they describe) with a `width: max-content` hover-layer style tagged `data-inkstone="monaco-hover-geometry"`; deleted the moment upstream fixes it.
|
|
15
|
+
- **Embedded-editor fixes** — works around [microsoft/monaco-editor#5177](https://github.com/microsoft/monaco-editor/issues/5177) (find-widget button tooltips landing on top of the buttons they describe) with a `width: max-content` hover-layer style tagged `data-inkstone="monaco-hover-geometry"`; deleted the moment upstream fixes it. And 0.57 draws an editor's context menu under `fixedOverflowWidgets` (inkstone's default) in a shadow root hosted in the node the editor was created in, which no theme color reaches — a transparent menu, its items over the code ([microsoft/monaco-editor#5511](https://github.com/microsoft/monaco-editor/issues/5511)); the host makes that node a `.monaco-component`, the class Monaco writes its theme's colors on, so the menu inherits them, and `<MonacoEditor>` keeps the class in the `className` it renders.
|
|
16
16
|
- **`StreamingEditorController`** — stream generated text into an editor without routing every token through app state: `begin()` / `append(chunk)` / `end()` / `discard()`, `attach(editor)` / `detach(editor)` with buffered replay for late-mounting editors (and for a model swapped onto the attached editor mid-stream, including after the final chunk), and `isStreaming()` for the onChange guard. The stream locks every editor it touches read-only and `end()` / `discard()` restore each one's own setting — by handle, so an editor detached mid-stream is restored too; `discard()` puts every displaced document back into the model it came from, and `end()` does the same for every model except the one keeping the streamed text. Full-buffer writes and restorations preserve each model's UTF-8 BOM. Editors and models the app disposed mid-stream are skipped, never touched — teardown can race the stream without wedging it.
|
|
17
17
|
- **`replaceInEditor(editor, old, new, all)`** — exact find-and-replace on an editor handle via `executeEdits`, preserving undo/cursor/folds; returns whether the edit landed (`false` = no editor / empty search / no match / a read-only editor refused it — e.g. one locked by a stream in progress), so a tool-call handler knows to fall back to a state write.
|
|
18
18
|
- **`registerShikiHighlighting(monaco, highlighter)`** — wire `@coldsmirk/inkstone-core`'s shared Shiki highlighter onto a monaco module (one from `ensureMonacoHost`), once per distinct module: defines the highlighter's themes as Monaco themes, registers each loaded grammar's canonical name as a Monaco language where Monaco has none and its Shiki tokenization in Monaco's registry — over Monaco's own, JSON's included (its mode's tokenizer is turned off through its configuration, its other features left on) — and patches `setTheme` so the Shiki theme ids route through the highlighter while non-Shiki ids (vs/vs-dark, caller-defined) keep Monaco's original path. Called again on a bridged module, it registers the grammars loaded since. A failed registration is restored and retried on the next call.
|
|
19
19
|
- **Tokenization off the page's thread** — VS Code's design, through the same door in Monaco: each model an editor shows is tokenized whole in a worker of its own, built from what the shared highlighter was built from (`highlighterSources`), the tokens and the state each line ends in sent back as they are made and moved past the edits the worker has not yet seen. The page's thread tokenizes only what Monaco still asks of it before the worker reaches it — a model's first lines in view, the lines an edit touches — and of those only a line it can afford: one of 1,000 characters or more, or one the grammar does not finish in 50 ms, is drawn in the default color until the worker's tokens arrive, the line after it read from the state before it (a minified line costs the grammar about 10 ms per 1,000 characters, 370 over 10,000, and one in view would hold the page that long). The worker bounds a line as VS Code does, at 20,000 characters and 500 ms. Where the page passes a line over in the lines it paints first, its own states for the lines after it stand — Monaco keeps a state it computed over one sent later — so an edit there is drawn from them until the worker's tokens arrive. A highlighter inkstone did not build, or a host that routes no worker for `textmate`, leaves every model to Monaco's own pass on the page's thread, under the same bound.
|
|
20
20
|
- **Which regex engine** — the worker builds the engine kind the shared highlighter was configured with: Oniguruma wherever an engine was configured, the strict JavaScript engine where none was, so the page and the worker tokenize alike. The JavaScript engine translates each grammar's patterns at the first tokenization — in the worker for a model, and on the page for the lines it tokenizes itself (a TypeScript file's first sixty lines: about 170 ms) — so an app that opens files in Monaco should configure `onigurumaEngine` from `@coldsmirk/inkstone-core` (`configureHighlighter({ engine: onigurumaEngine })`, before the first `getHighlighter()`): its WASM is inlined into your bundle and compiles the same lines in about 20 ms.
|
|
21
21
|
- **`registerShikiLanguage(monaco, highlighter, language)`** — the lazy path: an app that loads grammars as files are opened calls this after each `highlighter.loadLanguage(...)` and before a model names the language. Registers the language where Monaco lacks it (`toml`, `shellscript`), its tokenization once under the grammar's canonical name (an alias like `ts` collapses), the models of a grammar shiki has built again since (a language it embeds lazily arrived) tokenized again under the new one, and leaves the theme the editor shows alone — the one thing re-running `@shikijs/monaco`'s `shikiToMonaco` cannot promise, which is why the bridge is inkstone's own. Throws for a grammar the highlighter has not loaded.
|
|
22
|
-
- **`installDesignTokens()`** — defines the VS Code design tokens monaco-editor
|
|
23
|
-
- **`DEFAULT_MONACO_OPTIONS`** — the inkstone construction-option baseline (no minimap, 14px/1.6 type on the shared `--inkstone-font-family-code` token, embedded-friendly find widget, tuned completion, thin scrollbars). Spread it to extend: `{ ...DEFAULT_MONACO_OPTIONS, wordWrap: "on" }`.
|
|
22
|
+
- **`installDesignTokens()`** — defines the VS Code design tokens monaco-editor's chrome has read since 0.56 and the standalone editor still never does ([microsoft/monaco-editor#5408](https://github.com/microsoft/monaco-editor/issues/5408)): `--vscode-cornerRadius-{small,medium,large,xLarge,circle}` and `--vscode-shadow-{md,lg,xl}`, on `.monaco-editor` (a host's `overflowWidgetsDomNode` carries the class) and on `.monaco-component` — every context view, the class Monaco writes its own theme colors on: an element's tooltip and, since 0.57 under `fixedOverflowWidgets`, the editor's context menu stand in the node the editor was created in, outside `.monaco-editor`. Without them the context menu, completion, hover, and find widgets ship square and shadowless. 0.57 also took the completion list off `--vscode-shadow-lg` for a literal `0 2px 8px` shadow; it is put back on the token, so it wears the host's shadow as the hover and the context menu do. Each resolves through the host's `--inkstone-radius-*` / `--inkstone-shadow-*` token first (see `@coldsmirk/inkstone-core`), then a fallback scale in the spirit of 0.55's look. It also keeps an input box's focus ring single: the standalone editor outlines both the `.monaco-inputbox` container (its `synthetic-focus` ring, which follows the box's radius) and the inner `<input>` (square, 1px inside), and the inner ring's corners poke out as soon as the box has corners — the container's ring is the one ring. `ensureMonacoHost` installs it; idempotent.
|
|
23
|
+
- **`DEFAULT_MONACO_OPTIONS`** — the inkstone construction-option baseline (no minimap, 14px/1.6 type on the shared `--inkstone-font-family-code` token, embedded-friendly find widget, tuned completion, thin scrollbars). Spread it to extend: `{ ...DEFAULT_MONACO_OPTIONS, wordWrap: "on" }`. Left out on purpose: `fullwidthCharacterWidth: "twoCells"`, which centers each full-width character — CJK text among it — in exactly two cells of a monospace font, so it lines up with the grid the way a terminal draws it. It draws every such character as a span of its own, which costs on text dense with them (a Chinese JSON body, a document of prose), so it is a host's to turn on where the alignment matters more.
|
|
24
24
|
- **`reconcileModelValue` / `modelValueMatches`** — the controlled-value reconcile: diff an external value against a live model (normalized to the model's EOL) and apply one minimal `applyEdits` replace that never lands on the undo stack or moves a caret outside the changed region.
|
|
25
25
|
|
|
26
26
|
## Install
|
package/dist/index.d.ts
CHANGED
|
@@ -51,7 +51,7 @@ type MonacoModule = typeof monacoEditor;
|
|
|
51
51
|
* (both are idempotent), instead of replaying one transient failure — a chunk 404 after a
|
|
52
52
|
* redeploy, a flaky network — for the rest of the session.
|
|
53
53
|
*/
|
|
54
|
-
declare function ensureMonacoHost(options?: MonacoHostOptions): Promise<MonacoModule>;
|
|
54
|
+
export declare function ensureMonacoHost(options?: MonacoHostOptions): Promise<MonacoModule>;
|
|
55
55
|
//#endregion
|
|
56
56
|
//#region src/auto-imports.d.ts
|
|
57
57
|
/**
|
|
@@ -75,18 +75,19 @@ interface AutoImportCompletionOptions {
|
|
|
75
75
|
* subclass (a `getWorker` override) is detected on the first answer and the install disarms
|
|
76
76
|
* silently. Install once per app; repeated calls return the first install's disposable.
|
|
77
77
|
*/
|
|
78
|
-
declare function installAutoImportCompletions(monaco: MonacoModule, options: AutoImportCompletionOptions): monacoEditor.IDisposable;
|
|
78
|
+
export declare function installAutoImportCompletions(monaco: MonacoModule, options: AutoImportCompletionOptions): monacoEditor.IDisposable;
|
|
79
79
|
//#endregion
|
|
80
80
|
//#region src/design-tokens.d.ts
|
|
81
81
|
/**
|
|
82
82
|
* Define the VS Code design tokens Monaco's chrome reads but the standalone editor lacks —
|
|
83
|
-
* corner radii and widget shadows —
|
|
84
|
-
* `--inkstone-radius-*` / `--inkstone-shadow-*` tokens with inkstone's
|
|
85
|
-
* input box's focus ring single now that the box has corners (see
|
|
83
|
+
* corner radii and widget shadows — where Monaco writes its theme's colors, resolved
|
|
84
|
+
* through the host's `--inkstone-radius-*` / `--inkstone-shadow-*` tokens with inkstone's
|
|
85
|
+
* fallbacks; keep an input box's focus ring single now that the box has corners (see
|
|
86
|
+
* `INPUTBOX_FOCUS_RULE`), and the completion list on the shadow token (`SUGGEST_SHADOW_RULE`).
|
|
86
87
|
* Installed by `ensureMonacoHost`; idempotent, so a host that brings monaco up on its own can
|
|
87
88
|
* call it too.
|
|
88
89
|
*/
|
|
89
|
-
declare function installDesignTokens(): void;
|
|
90
|
+
export declare function installDesignTokens(): void;
|
|
90
91
|
//#endregion
|
|
91
92
|
//#region src/hover-dead-band.d.ts
|
|
92
93
|
/**
|
|
@@ -103,7 +104,7 @@ interface HoverDeadBandTargetEditor {
|
|
|
103
104
|
* on every editor; a monaco whose hover controller no longer matches the pinned shape is
|
|
104
105
|
* left untouched. Dispose to restore the stock test.
|
|
105
106
|
*/
|
|
106
|
-
declare function installHoverDeadBandFix(editorInstance: HoverDeadBandTargetEditor): monacoEditor.IDisposable;
|
|
107
|
+
export declare function installHoverDeadBandFix(editorInstance: HoverDeadBandTargetEditor): monacoEditor.IDisposable;
|
|
107
108
|
//#endregion
|
|
108
109
|
//#region src/jsx-tag-closing.d.ts
|
|
109
110
|
/**
|
|
@@ -149,7 +150,7 @@ interface JsxTagClosingTargetEditor {
|
|
|
149
150
|
* detected on its first answer and the install disarms silently. Listener lifetime follows
|
|
150
151
|
* the editor; dispose the returned subscription to detach earlier.
|
|
151
152
|
*/
|
|
152
|
-
declare function installJsxTagClosing(monaco: MonacoModule, editorInstance: JsxTagClosingTargetEditor): monacoEditor.IDisposable;
|
|
153
|
+
export declare function installJsxTagClosing(monaco: MonacoModule, editorInstance: JsxTagClosingTargetEditor): monacoEditor.IDisposable;
|
|
153
154
|
//#endregion
|
|
154
155
|
//#region src/keybindings.d.ts
|
|
155
156
|
/**
|
|
@@ -164,13 +165,13 @@ interface SwallowedKeybindings {
|
|
|
164
165
|
* The keybindings `disableFind` / `disableCommandPalette` swallow: the find/replace widget's
|
|
165
166
|
* entries (Ctrl/Cmd+F to find; Ctrl+H and Cmd+Alt+F, the per-platform replace bindings) and
|
|
166
167
|
* the command palette's F1 — Monaco never binds Ctrl+Shift+P (a VS Code binding). Sourced
|
|
167
|
-
* from monaco-editor 0.
|
|
168
|
+
* from monaco-editor 0.57.0 (`findController.js`, `standaloneCommandsQuickAccess.js`).
|
|
168
169
|
*
|
|
169
170
|
* Both replace chords are swallowed on every platform rather than branching: `CtrlCmd` already
|
|
170
171
|
* resolves per platform, and the off-platform chord (Ctrl+Alt+F on Windows, Cmd+H on macOS, where
|
|
171
172
|
* the OS takes the key before the page sees it) is one Monaco never bound.
|
|
172
173
|
*/
|
|
173
|
-
declare function disabledKeybindings(monaco: MonacoModule, disableFind: boolean, disableCommandPalette: boolean): SwallowedKeybindings[];
|
|
174
|
+
export declare function disabledKeybindings(monaco: MonacoModule, disableFind: boolean, disableCommandPalette: boolean): SwallowedKeybindings[];
|
|
174
175
|
/**
|
|
175
176
|
* The slice of a standalone editor the install touches — a structural type, so the install is
|
|
176
177
|
* testable without evaluating the monaco module (which jsdom cannot do).
|
|
@@ -185,7 +186,7 @@ interface KeybindingTargetEditor {
|
|
|
185
186
|
* the page-global service only the first time any editor of that monaco module asks for it —
|
|
186
187
|
* monaco offers no way to unregister one.
|
|
187
188
|
*/
|
|
188
|
-
declare function installDisabledKeybindings(monaco: MonacoModule, editorInstance: KeybindingTargetEditor, groups: readonly SwallowedKeybindings[]): void;
|
|
189
|
+
export declare function installDisabledKeybindings(monaco: MonacoModule, editorInstance: KeybindingTargetEditor, groups: readonly SwallowedKeybindings[]): void;
|
|
189
190
|
//#endregion
|
|
190
191
|
//#region src/languages.d.ts
|
|
191
192
|
/**
|
|
@@ -209,7 +210,7 @@ type MonacoBuiltInLanguage = (typeof BUILT_IN_LANGUAGES)[number];
|
|
|
209
210
|
/**
|
|
210
211
|
* Every built-in Monaco language id, sorted.
|
|
211
212
|
*/
|
|
212
|
-
declare const monacoLanguages: readonly MonacoBuiltInLanguage[];
|
|
213
|
+
export declare const monacoLanguages: readonly MonacoBuiltInLanguage[];
|
|
213
214
|
/**
|
|
214
215
|
* The `<MonacoEditor language>` type. Monaco also accepts any custom-registered id (e.g. a
|
|
215
216
|
* language wired through `getWorker` such as monaco-yaml), so the type stays open: the union
|
|
@@ -224,7 +225,7 @@ type MonacoLanguage = MonacoBuiltInLanguage | (string & Record<never, never>);
|
|
|
224
225
|
* tuned for API-assisted editing, thin scrollbars, and an embedded-friendly find widget.
|
|
225
226
|
* Spread these to extend rather than replace: `options={{ ...DEFAULT_MONACO_OPTIONS, wordWrap: "on" }}`.
|
|
226
227
|
*/
|
|
227
|
-
declare const DEFAULT_MONACO_OPTIONS: editor.IStandaloneEditorConstructionOptions;
|
|
228
|
+
export declare const DEFAULT_MONACO_OPTIONS: editor.IStandaloneEditorConstructionOptions;
|
|
228
229
|
//#endregion
|
|
229
230
|
//#region src/reconcile.d.ts
|
|
230
231
|
/**
|
|
@@ -232,11 +233,11 @@ declare const DEFAULT_MONACO_OPTIONS: editor.IStandaloneEditorConstructionOption
|
|
|
232
233
|
* documents already match. Fires the model's content-change event synchronously when it
|
|
233
234
|
* edits — callers that must not re-enter their change callback silence it around this call.
|
|
234
235
|
*/
|
|
235
|
-
declare function reconcileModelValue(model: editor.ITextModel, externalValue: string): void;
|
|
236
|
+
export declare function reconcileModelValue(model: editor.ITextModel, externalValue: string): void;
|
|
236
237
|
/**
|
|
237
238
|
* Whether an external value already matches the model after applying its EOL convention.
|
|
238
239
|
*/
|
|
239
|
-
declare function modelValueMatches(model: editor.ITextModel, externalValue: string): boolean;
|
|
240
|
+
export declare function modelValueMatches(model: editor.ITextModel, externalValue: string): boolean;
|
|
240
241
|
//#endregion
|
|
241
242
|
//#region src/replace.d.ts
|
|
242
243
|
/**
|
|
@@ -246,7 +247,7 @@ declare function modelValueMatches(model: editor.ITextModel, externalValue: stri
|
|
|
246
247
|
* because it is read-only — e.g. locked by a stream in progress; the caller falls back to a
|
|
247
248
|
* state write).
|
|
248
249
|
*/
|
|
249
|
-
declare function replaceInEditor(target: editor.ICodeEditor | null, search: string, replaceWith: string, all: boolean): boolean;
|
|
250
|
+
export declare function replaceInEditor(target: editor.ICodeEditor | null, search: string, replaceWith: string, all: boolean): boolean;
|
|
250
251
|
//#endregion
|
|
251
252
|
//#region src/shiki-bridge.d.ts
|
|
252
253
|
/**
|
|
@@ -275,7 +276,7 @@ declare function replaceInEditor(target: editor.ICodeEditor | null, search: stri
|
|
|
275
276
|
* A grammar loaded into the highlighter *after* this call is not tokenized until it is
|
|
276
277
|
* registered — pass it to {@link registerShikiLanguage} (or call this again).
|
|
277
278
|
*/
|
|
278
|
-
declare function registerShikiHighlighting(monaco: MonacoModule, highlighter: HighlighterCore): void;
|
|
279
|
+
export declare function registerShikiHighlighting(monaco: MonacoModule, highlighter: HighlighterCore): void;
|
|
279
280
|
/**
|
|
280
281
|
* Register the tokenization of one grammar the highlighter has loaded since the module was
|
|
281
282
|
* bridged — the lazy path: an app that loads grammars as files are opened registers each here,
|
|
@@ -285,7 +286,7 @@ declare function registerShikiHighlighting(monaco: MonacoModule, highlighter: Hi
|
|
|
285
286
|
* a language it embeds lazily arrived, has its models tokenized again under the new one. Throws
|
|
286
287
|
* when the highlighter has not loaded the grammar: there is nothing to tokenize with.
|
|
287
288
|
*/
|
|
288
|
-
declare function registerShikiLanguage(monaco: MonacoModule, highlighter: HighlighterCore, language: string): void;
|
|
289
|
+
export declare function registerShikiLanguage(monaco: MonacoModule, highlighter: HighlighterCore, language: string): void;
|
|
289
290
|
//#endregion
|
|
290
291
|
//#region src/streaming.d.ts
|
|
291
292
|
/**
|
|
@@ -308,7 +309,7 @@ type StreamTargetEditor = editor.ICodeEditor;
|
|
|
308
309
|
* accumulate in a buffer that is replayed on {@link attach}, so the final document is
|
|
309
310
|
* complete even if the editor never mounts.
|
|
310
311
|
*/
|
|
311
|
-
declare class StreamingEditorController {
|
|
312
|
+
export declare class StreamingEditorController {
|
|
312
313
|
private editor;
|
|
313
314
|
private writing;
|
|
314
315
|
private buffer;
|
|
@@ -409,4 +410,4 @@ declare class StreamingEditorController {
|
|
|
409
410
|
discard(): void;
|
|
410
411
|
}
|
|
411
412
|
//#endregion
|
|
412
|
-
export {
|
|
413
|
+
export type { AutoImportCompletionOptions, HoverDeadBandTargetEditor, JsxTagClosingTargetEditor, JsxTagClosingTargetModel, KeybindingTargetEditor, MonacoBuiltInLanguage, MonacoHostOptions, MonacoLanguage, MonacoModule, MonacoUiLocale, StreamTargetEditor, SwallowedKeybindings };
|
package/dist/index.js
CHANGED
|
@@ -131,16 +131,18 @@ const DESIGN_TOKENS = [
|
|
|
131
131
|
`--vscode-cornerRadius-medium: ${inkstoneRadius("medium", "4px")}`,
|
|
132
132
|
`--vscode-cornerRadius-large: ${inkstoneRadius("large", "6px")}`,
|
|
133
133
|
`--vscode-cornerRadius-xLarge: ${inkstoneRadius("xlarge", "8px")}`,
|
|
134
|
+
"--vscode-cornerRadius-circle: 9999px",
|
|
134
135
|
`--vscode-shadow-md: ${inkstoneShadow("medium", "0 1px 4px var(--vscode-widget-shadow)")}`,
|
|
135
136
|
`--vscode-shadow-lg: ${inkstoneShadow("large", "0 2px 8px var(--vscode-widget-shadow)")}`,
|
|
136
137
|
`--vscode-shadow-xl: ${inkstoneShadow("xlarge", "0 4px 16px var(--vscode-widget-shadow)")}`
|
|
137
138
|
];
|
|
138
139
|
const INPUTBOX_FOCUS_RULE = ".monaco-editor .monaco-inputbox > .ibwrapper > .input:focus { outline: none; }";
|
|
140
|
+
const SUGGEST_SHADOW_RULE = ".monaco-editor:not(.hc-black):not(.hc-light) .suggest-widget { box-shadow: var(--vscode-shadow-lg); }";
|
|
139
141
|
function installDesignTokens() {
|
|
140
142
|
if (document.querySelector(DESIGN_TOKENS_STYLE_SELECTOR)) return;
|
|
141
143
|
const style = document.createElement("style");
|
|
142
144
|
style.dataset.inkstone = "monaco-design-tokens";
|
|
143
|
-
style.textContent = `.monaco-editor { ${DESIGN_TOKENS.join("; ")}; }\n${INPUTBOX_FOCUS_RULE}`;
|
|
145
|
+
style.textContent = `.monaco-editor, .monaco-diff-editor, .monaco-component { ${DESIGN_TOKENS.join("; ")}; }\n${INPUTBOX_FOCUS_RULE}\n${SUGGEST_SHADOW_RULE}`;
|
|
144
146
|
document.head.append(style);
|
|
145
147
|
}
|
|
146
148
|
//#endregion
|
|
@@ -181,6 +183,14 @@ function localizeActionDescriptions(editorInstance) {
|
|
|
181
183
|
}
|
|
182
184
|
}
|
|
183
185
|
//#endregion
|
|
186
|
+
//#region src/context-menu-fix.ts
|
|
187
|
+
const COMPONENT_CLASS = "monaco-component";
|
|
188
|
+
function installContextMenuThemeFix(monaco) {
|
|
189
|
+
monaco.editor.onDidCreateEditor((editorInstance) => {
|
|
190
|
+
editorInstance.getContainerDomNode().classList.add(COMPONENT_CLASS);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
//#endregion
|
|
184
194
|
//#region src/geometry-fixes.ts
|
|
185
195
|
const HOVER_GEOMETRY_STYLE_SELECTOR = "style[data-inkstone=\"monaco-hover-geometry\"]";
|
|
186
196
|
function installHoverGeometryFix() {
|
|
@@ -198,14 +208,6 @@ function installSuggestGeometryFix() {
|
|
|
198
208
|
style.textContent = ".monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > span.readMore.codicon.codicon-suggest-more-info::before { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }";
|
|
199
209
|
document.head.append(style);
|
|
200
210
|
}
|
|
201
|
-
const QUICK_INPUT_GEOMETRY_STYLE_SELECTOR = "style[data-inkstone=\"monaco-quick-input-geometry\"]";
|
|
202
|
-
function installQuickInputGeometryFix() {
|
|
203
|
-
if (document.querySelector(QUICK_INPUT_GEOMETRY_STYLE_SELECTOR)) return;
|
|
204
|
-
const style = document.createElement("style");
|
|
205
|
-
style.dataset.inkstone = "monaco-quick-input-geometry";
|
|
206
|
-
style.textContent = ".monaco-editor .quick-input-list { position: relative; }";
|
|
207
|
-
document.head.append(style);
|
|
208
|
-
}
|
|
209
211
|
const HOVER_FOCUS_STYLE_SELECTOR = "style[data-inkstone=\"monaco-hover-focus\"]";
|
|
210
212
|
function installHoverFocusFix() {
|
|
211
213
|
if (document.querySelector(HOVER_FOCUS_STYLE_SELECTOR)) return;
|
|
@@ -313,11 +315,11 @@ function ensureMonacoHost(options = {}) {
|
|
|
313
315
|
installDesignTokens();
|
|
314
316
|
installHoverGeometryFix();
|
|
315
317
|
installSuggestGeometryFix();
|
|
316
|
-
installQuickInputGeometryFix();
|
|
317
318
|
installHoverFocusFix();
|
|
318
319
|
const monaco = await import("monaco-editor");
|
|
319
320
|
rememberInternals(monaco, await loadMonacoInternals());
|
|
320
321
|
globalThis.MonacoEnvironment = { getWorker: (workerId, label) => getWorker?.(workerId, label) ?? builtinGetWorker(label) };
|
|
322
|
+
installContextMenuThemeFix(monaco);
|
|
321
323
|
if (locale === "zh-cn") monaco.editor.onDidCreateEditor(localizeActionDescriptions);
|
|
322
324
|
return monaco;
|
|
323
325
|
} catch (error) {
|
package/dist/vite.d.ts
CHANGED
|
@@ -17,6 +17,5 @@ import { Plugin } from "vite";
|
|
|
17
17
|
* time and leaves the file untouched — the duplicate chunk returns (dead weight, nothing
|
|
18
18
|
* breaks) until the pattern catches up.
|
|
19
19
|
*/
|
|
20
|
-
declare function dropMonacoWorkerFallbacks(): Plugin;
|
|
21
|
-
//#endregion
|
|
22
|
-
export { dropMonacoWorkerFallbacks };
|
|
20
|
+
export declare function dropMonacoWorkerFallbacks(): Plugin;
|
|
21
|
+
//#endregion
|
|
@@ -63,7 +63,7 @@ class JsxTypeScriptWorker extends TypeScriptWorker {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
// Monaco's worker handshake is two-staged (`internal/common/initialize.js`, 0.
|
|
66
|
+
// Monaco's worker handshake is two-staged (`internal/common/initialize.js`, 0.57): a first
|
|
67
67
|
// message merely triggers `initialize`, whose own handler then reads the *second* message as
|
|
68
68
|
// createData. The stock entry import above installed the stage-one handler for its own
|
|
69
69
|
// factory; this assignment must *replace* it with one building the subclass — calling
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coldsmirk/inkstone-monaco",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0",
|
|
4
4
|
"description": "Framework-agnostic Monaco assembly: lazy offline host (all language workers bundled, no CDN), opt-in Simplified-Chinese UI via monaco's official NLS catalog, a streaming editor controller for AI-typed content, and the shared Shiki highlighting bridge.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"monaco",
|
|
@@ -40,15 +40,15 @@
|
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@shikijs/vscode-textmate": "^10.0.2",
|
|
43
|
-
"shiki": "^4.
|
|
44
|
-
"@coldsmirk/inkstone-core": "^0.
|
|
43
|
+
"shiki": "^4.5.0",
|
|
44
|
+
"@coldsmirk/inkstone-core": "^0.31.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"monaco-editor": "^0.
|
|
48
|
-
"vite": "^8.
|
|
47
|
+
"monaco-editor": "^0.57.0",
|
|
48
|
+
"vite": "^8.3.4"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"monaco-editor": "^0.
|
|
51
|
+
"monaco-editor": "^0.57.0",
|
|
52
52
|
"vite": ">=6"
|
|
53
53
|
},
|
|
54
54
|
"peerDependenciesMeta": {
|