@coldsmirk/inkstone-monaco 0.19.2 → 0.20.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 +2 -1
- package/dist/index.d.ts +25 -5
- package/dist/index.js +174 -15
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -15,7 +15,8 @@ Part of [inkstone](https://github.com/coldsmirk/inkstone). For a drop-in React c
|
|
|
15
15
|
- **Embedded-editor fix** — 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. The tooltip layer positions against the editor's container — give that container `position: relative`.
|
|
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
|
-
- **`registerShikiHighlighting(monaco, highlighter)`** — wire `@coldsmirk/inkstone-core`'s shared Shiki highlighter onto a monaco module, once per distinct module:
|
|
18
|
+
- **`registerShikiHighlighting(monaco, highlighter)`** — wire `@coldsmirk/inkstone-core`'s shared Shiki highlighter onto a monaco module, 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 installs a Shiki tokens provider for it, 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 installs the grammars loaded since. A failed registration is restored and retried on the next call.
|
|
19
|
+
- **`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`), installs its tokens provider once under the grammar's canonical name (an alias like `ts` collapses), 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.
|
|
19
20
|
- **`installDesignTokens()`** — defines the VS Code design tokens monaco-editor 0.56's chrome reads and the standalone editor never does ([microsoft/monaco-editor#5408](https://github.com/microsoft/monaco-editor/issues/5408)): `--vscode-cornerRadius-{small,medium,large,xLarge}` and `--vscode-shadow-{md,lg,xl}`, on `.monaco-editor` (the context menu's shadow root and a host's `overflowWidgetsDomNode` inherit them). Without them the context menu, completion, hover, and find widgets ship square and shadowless. 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.
|
|
20
21
|
- **`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" }`.
|
|
21
22
|
- **`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.
|
package/dist/index.d.ts
CHANGED
|
@@ -248,12 +248,32 @@ declare function replaceInEditor(target: editor.ICodeEditor | null, search: stri
|
|
|
248
248
|
//#endregion
|
|
249
249
|
//#region src/shiki-bridge.d.ts
|
|
250
250
|
/**
|
|
251
|
-
* Register the shared Shiki highlighter's languages, themes, and
|
|
252
|
-
* once per distinct module, whichever caller gets there first
|
|
253
|
-
*
|
|
254
|
-
*
|
|
251
|
+
* Register the shared Shiki highlighter's languages, themes, and tokenizers on a monaco module —
|
|
252
|
+
* once per distinct module, whichever caller gets there first — and, on a module already
|
|
253
|
+
* bridged, install the tokenizer of any grammar loaded since. Language services are unaffected:
|
|
254
|
+
* Shiki replaces syntax highlighting only. The module is recorded only after every registration
|
|
255
|
+
* succeeds, so a transient failure can retry on a later call.
|
|
256
|
+
*
|
|
257
|
+
* Monaco's own `setTheme` is patched to route the Shiki theme ids through the highlighter, so
|
|
258
|
+
* the tokenizers paint in the theme the editor shows; Monaco's built-in themes (vs/vs-dark) and
|
|
259
|
+
* caller-defined themes keep Monaco's original path. `create` is patched so its `theme` option
|
|
260
|
+
* reaches that patch. The shape is `@shikijs/monaco`'s, kept here because that package
|
|
261
|
+
* installs tokenizers only for the grammars loaded at the moment it is called, and re-calling
|
|
262
|
+
* it for a grammar loaded later resets the editor's theme to the first one.
|
|
263
|
+
*
|
|
264
|
+
* A grammar loaded into the highlighter *after* this call is not tokenized until it is
|
|
265
|
+
* registered — pass it to {@link registerShikiLanguage} (or call this again).
|
|
255
266
|
*/
|
|
256
267
|
declare function registerShikiHighlighting(monaco: MonacoModule, highlighter: HighlighterCore): void;
|
|
268
|
+
/**
|
|
269
|
+
* Install the tokenizer of one grammar the highlighter has loaded since the module was bridged
|
|
270
|
+
* — the lazy path: an app that loads grammars as files are opened registers each here, after
|
|
271
|
+
* its `loadLanguage`, and before a model names it. `language` may be an alias (`ts`); it
|
|
272
|
+
* collapses to the grammar's canonical name. Bridges the module first where nothing has, and
|
|
273
|
+
* is nothing for a grammar already registered. Throws when the highlighter has not loaded the
|
|
274
|
+
* grammar: there is nothing to tokenize with.
|
|
275
|
+
*/
|
|
276
|
+
declare function registerShikiLanguage(monaco: MonacoModule, highlighter: HighlighterCore, language: string): void;
|
|
257
277
|
//#endregion
|
|
258
278
|
//#region src/streaming.d.ts
|
|
259
279
|
/**
|
|
@@ -377,4 +397,4 @@ declare class StreamingEditorController {
|
|
|
377
397
|
discard(): void;
|
|
378
398
|
}
|
|
379
399
|
//#endregion
|
|
380
|
-
export { type AutoImportCompletionOptions, DEFAULT_MONACO_OPTIONS, type HoverDeadBandTargetEditor, type JsxTagClosingTargetEditor, type JsxTagClosingTargetModel, type KeybindingTargetEditor, type MonacoBuiltInLanguage, type MonacoHostOptions, type MonacoLanguage, type MonacoModule, type MonacoUiLocale, type StreamTargetEditor, StreamingEditorController, type SwallowedKeybindings, disabledKeybindings, ensureMonacoHost, installAutoImportCompletions, installDesignTokens, installDisabledKeybindings, installHoverDeadBandFix, installJsxTagClosing, modelValueMatches, monacoLanguages, reconcileModelValue, registerShikiHighlighting, replaceInEditor };
|
|
400
|
+
export { type AutoImportCompletionOptions, DEFAULT_MONACO_OPTIONS, type HoverDeadBandTargetEditor, type JsxTagClosingTargetEditor, type JsxTagClosingTargetModel, type KeybindingTargetEditor, type MonacoBuiltInLanguage, type MonacoHostOptions, type MonacoLanguage, type MonacoModule, type MonacoUiLocale, type StreamTargetEditor, StreamingEditorController, type SwallowedKeybindings, disabledKeybindings, ensureMonacoHost, installAutoImportCompletions, installDesignTokens, installDisabledKeybindings, installHoverDeadBandFix, installJsxTagClosing, modelValueMatches, monacoLanguages, reconcileModelValue, registerShikiHighlighting, registerShikiLanguage, replaceInEditor };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CODE_FONT_FAMILY, inkstoneRadius, inkstoneShadow } from "@coldsmirk/inkstone-core";
|
|
2
|
-
import {
|
|
2
|
+
import { EncodedTokenMetadata, INITIAL } from "@shikijs/vscode-textmate";
|
|
3
3
|
//#region src/auto-imports.ts
|
|
4
4
|
const MISSING_LOOKUP_REJECTION$1 = "Missing requestHandler or method: getAutoImportCompletionsAtPosition";
|
|
5
5
|
const MODE_BOOTING_REJECTIONS$1 = /* @__PURE__ */ new Set(["TypeScript not registered!", "JavaScript not registered!"]);
|
|
@@ -546,36 +546,195 @@ function replaceInEditor(target, search, replaceWith, all) {
|
|
|
546
546
|
//#endregion
|
|
547
547
|
//#region src/shiki-bridge.ts
|
|
548
548
|
const SHIKI_REGISTRY_KEY = Symbol.for("coldsmirk.inkstone.monaco.shikiRegistry");
|
|
549
|
-
function
|
|
549
|
+
function bridges() {
|
|
550
550
|
const host = globalThis;
|
|
551
551
|
const existing = host[SHIKI_REGISTRY_KEY];
|
|
552
552
|
if (existing) return existing;
|
|
553
|
-
const created = /* @__PURE__ */ new
|
|
553
|
+
const created = /* @__PURE__ */ new WeakMap();
|
|
554
554
|
host[SHIKI_REGISTRY_KEY] = created;
|
|
555
555
|
return created;
|
|
556
556
|
}
|
|
557
|
+
const TOKENIZE_MAX_LINE_LENGTH = 2e4;
|
|
558
|
+
const TOKENIZE_TIME_LIMIT_MS = 500;
|
|
559
|
+
const ITALIC = 1;
|
|
560
|
+
const BOLD = 2;
|
|
561
|
+
const UNDERLINE = 4;
|
|
562
|
+
const STRIKETHROUGH = 8;
|
|
563
|
+
const RE_FONT_STYLE_SPLIT = /[\s,]+/;
|
|
564
|
+
const FONT_STYLES = [
|
|
565
|
+
"italic",
|
|
566
|
+
"bold",
|
|
567
|
+
"underline",
|
|
568
|
+
"strikethrough"
|
|
569
|
+
];
|
|
570
|
+
const FONT_STYLE_ALIASES = { "line-through": "strikethrough" };
|
|
571
|
+
function normalizeColor(color) {
|
|
572
|
+
if (!color) return;
|
|
573
|
+
let normalized = (color.startsWith("#") ? color.slice(1) : color).toLowerCase();
|
|
574
|
+
if (normalized.length === 3 || normalized.length === 4) normalized = [...normalized].map((digit) => digit + digit).join("");
|
|
575
|
+
return normalized;
|
|
576
|
+
}
|
|
577
|
+
function normalizeFontStyleString(fontStyle) {
|
|
578
|
+
if (!fontStyle) return "";
|
|
579
|
+
const styles = new Set(fontStyle.split(RE_FONT_STYLE_SPLIT).map((style) => style.trim().toLowerCase()).map((style) => FONT_STYLE_ALIASES[style] ?? style).filter(Boolean));
|
|
580
|
+
return FONT_STYLES.filter((style) => styles.has(style)).join(" ");
|
|
581
|
+
}
|
|
582
|
+
function normalizeFontStyleBits(fontStyle) {
|
|
583
|
+
if (fontStyle <= 0) return "";
|
|
584
|
+
const styles = [];
|
|
585
|
+
if (fontStyle & ITALIC) styles.push("italic");
|
|
586
|
+
if (fontStyle & BOLD) styles.push("bold");
|
|
587
|
+
if (fontStyle & UNDERLINE) styles.push("underline");
|
|
588
|
+
if (fontStyle & STRIKETHROUGH) styles.push("strikethrough");
|
|
589
|
+
return styles.join(" ");
|
|
590
|
+
}
|
|
591
|
+
function colorStyleKey(color, fontStyle) {
|
|
592
|
+
return fontStyle ? `${color}|${fontStyle}` : color;
|
|
593
|
+
}
|
|
594
|
+
function monacoThemeOf(theme) {
|
|
595
|
+
const rules = [];
|
|
596
|
+
const tokenSettings = theme.settings ?? theme.tokenColors ?? [];
|
|
597
|
+
for (const { scope, settings } of tokenSettings) {
|
|
598
|
+
const { foreground, background, fontStyle } = settings ?? {};
|
|
599
|
+
if (!foreground && !background && !fontStyle) continue;
|
|
600
|
+
const scopes = Array.isArray(scope) ? scope : scope ? [scope] : [];
|
|
601
|
+
const normalizedFontStyle = normalizeFontStyleString(fontStyle);
|
|
602
|
+
const normalizedForeground = normalizeColor(foreground);
|
|
603
|
+
const normalizedBackground = normalizeColor(background);
|
|
604
|
+
for (const token of scopes) rules.push({
|
|
605
|
+
token,
|
|
606
|
+
foreground: normalizedForeground,
|
|
607
|
+
background: normalizedBackground,
|
|
608
|
+
fontStyle: normalizedFontStyle
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
const colors = Object.fromEntries(Object.entries(theme.colors ?? {}).map(([key, value]) => [key, `#${normalizeColor(value) ?? ""}`]));
|
|
612
|
+
return {
|
|
613
|
+
base: theme.type === "light" ? "vs" : "vs-dark",
|
|
614
|
+
inherit: false,
|
|
615
|
+
colors,
|
|
616
|
+
rules
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
function adoptTheme(bridge, themeName) {
|
|
620
|
+
const { colorMap } = bridge.highlighter.setTheme(themeName);
|
|
621
|
+
const theme = bridge.themes.get(themeName);
|
|
622
|
+
bridge.colorMap.length = colorMap.length;
|
|
623
|
+
for (const [index, color] of colorMap.entries()) bridge.colorMap[index] = color;
|
|
624
|
+
bridge.scopeOf.clear();
|
|
625
|
+
const rules = theme?.rules ?? [];
|
|
626
|
+
for (const rule of rules) {
|
|
627
|
+
const color = normalizeColor(rule.foreground);
|
|
628
|
+
if (!color) continue;
|
|
629
|
+
const key = colorStyleKey(color, normalizeFontStyleString(rule.fontStyle));
|
|
630
|
+
if (!bridge.scopeOf.has(key)) bridge.scopeOf.set(key, rule.token);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
var TokenizerState = class TokenizerState {
|
|
634
|
+
ruleStack;
|
|
635
|
+
constructor(ruleStack) {
|
|
636
|
+
this.ruleStack = ruleStack;
|
|
637
|
+
}
|
|
638
|
+
clone() {
|
|
639
|
+
return new TokenizerState(this.ruleStack);
|
|
640
|
+
}
|
|
641
|
+
equals(other) {
|
|
642
|
+
return other instanceof TokenizerState && other.ruleStack === this.ruleStack;
|
|
643
|
+
}
|
|
644
|
+
};
|
|
645
|
+
function tokensProvider(bridge, lang) {
|
|
646
|
+
return {
|
|
647
|
+
getInitialState() {
|
|
648
|
+
return new TokenizerState(INITIAL);
|
|
649
|
+
},
|
|
650
|
+
tokenize(line, state) {
|
|
651
|
+
if (line.length >= TOKENIZE_MAX_LINE_LENGTH) return {
|
|
652
|
+
endState: state,
|
|
653
|
+
tokens: [{
|
|
654
|
+
startIndex: 0,
|
|
655
|
+
scopes: ""
|
|
656
|
+
}]
|
|
657
|
+
};
|
|
658
|
+
const ruleStack = state instanceof TokenizerState ? state.ruleStack : INITIAL;
|
|
659
|
+
const result = bridge.highlighter.getLanguage(lang).tokenizeLine2(line, ruleStack, TOKENIZE_TIME_LIMIT_MS);
|
|
660
|
+
if (result.stoppedEarly) console.warn(`inkstone: time limit reached when tokenizing a line: ${line.slice(0, 100)}`);
|
|
661
|
+
const tokens = [];
|
|
662
|
+
for (let index = 0; index < result.tokens.length; index += 2) {
|
|
663
|
+
const startIndex = result.tokens[index] ?? 0;
|
|
664
|
+
const metadata = result.tokens[index + 1] ?? 0;
|
|
665
|
+
const color = normalizeColor(bridge.colorMap[EncodedTokenMetadata.getForeground(metadata)]);
|
|
666
|
+
const fontStyle = normalizeFontStyleBits(EncodedTokenMetadata.getFontStyle(metadata));
|
|
667
|
+
const scopes = color ? bridge.scopeOf.get(colorStyleKey(color, fontStyle)) ?? "" : "";
|
|
668
|
+
tokens.push({
|
|
669
|
+
startIndex,
|
|
670
|
+
scopes
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
return {
|
|
674
|
+
endState: new TokenizerState(result.ruleStack),
|
|
675
|
+
tokens
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
function install(monaco, bridge, canonical) {
|
|
681
|
+
if (bridge.registered.has(canonical)) return;
|
|
682
|
+
if (monaco.languages.getLanguages().every((language) => language.id !== canonical)) monaco.languages.register({ id: canonical });
|
|
683
|
+
monaco.languages.setTokensProvider(canonical, tokensProvider(bridge, canonical));
|
|
684
|
+
bridge.registered.add(canonical);
|
|
685
|
+
}
|
|
686
|
+
function canonicalLanguages(highlighter) {
|
|
687
|
+
return new Set(highlighter.getLoadedLanguages().map((id) => highlighter.getLanguage(id).name));
|
|
688
|
+
}
|
|
557
689
|
function registerShikiHighlighting(monaco, highlighter) {
|
|
558
|
-
const registry =
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
690
|
+
const registry = bridges();
|
|
691
|
+
const bridged = registry.get(monaco);
|
|
692
|
+
if (bridged) {
|
|
693
|
+
for (const canonical of canonicalLanguages(highlighter)) install(monaco, bridged, canonical);
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
const bridge = {
|
|
697
|
+
highlighter,
|
|
698
|
+
themes: /* @__PURE__ */ new Map(),
|
|
699
|
+
colorMap: [],
|
|
700
|
+
scopeOf: /* @__PURE__ */ new Map(),
|
|
701
|
+
registered: /* @__PURE__ */ new Set()
|
|
702
|
+
};
|
|
564
703
|
const originalCreate = monaco.editor.create;
|
|
565
704
|
const originalSetTheme = monaco.editor.setTheme;
|
|
566
705
|
try {
|
|
567
|
-
|
|
568
|
-
|
|
706
|
+
for (const themeId of highlighter.getLoadedThemes()) {
|
|
707
|
+
const theme = monacoThemeOf(highlighter.getTheme(themeId));
|
|
708
|
+
bridge.themes.set(themeId, theme);
|
|
709
|
+
monaco.editor.defineTheme(themeId, theme);
|
|
710
|
+
}
|
|
569
711
|
monaco.editor.setTheme = (themeName) => {
|
|
570
|
-
if (
|
|
571
|
-
|
|
712
|
+
if (bridge.themes.has(themeName)) adoptTheme(bridge, themeName);
|
|
713
|
+
originalSetTheme.call(monaco.editor, themeName);
|
|
572
714
|
};
|
|
715
|
+
monaco.editor.create = (element, options, override) => {
|
|
716
|
+
if (options?.theme) monaco.editor.setTheme(options.theme);
|
|
717
|
+
return originalCreate.call(monaco.editor, element, options, override);
|
|
718
|
+
};
|
|
719
|
+
const [firstTheme] = highlighter.getLoadedThemes();
|
|
720
|
+
if (firstTheme !== void 0) monaco.editor.setTheme(firstTheme);
|
|
721
|
+
for (const canonical of canonicalLanguages(highlighter)) install(monaco, bridge, canonical);
|
|
573
722
|
} catch (error) {
|
|
574
723
|
monaco.editor.create = originalCreate;
|
|
575
724
|
monaco.editor.setTheme = originalSetTheme;
|
|
576
725
|
throw error;
|
|
577
726
|
}
|
|
578
|
-
registry.
|
|
727
|
+
registry.set(monaco, bridge);
|
|
728
|
+
}
|
|
729
|
+
function registerShikiLanguage(monaco, highlighter, language) {
|
|
730
|
+
const registry = bridges();
|
|
731
|
+
let bridge = registry.get(monaco);
|
|
732
|
+
if (!bridge) {
|
|
733
|
+
registerShikiHighlighting(monaco, highlighter);
|
|
734
|
+
bridge = registry.get(monaco);
|
|
735
|
+
}
|
|
736
|
+
if (!bridge) throw new Error("inkstone: the Shiki bridge is not installed on this monaco module");
|
|
737
|
+
install(monaco, bridge, highlighter.getLanguage(language).name);
|
|
579
738
|
}
|
|
580
739
|
//#endregion
|
|
581
740
|
//#region src/streaming.ts
|
|
@@ -687,4 +846,4 @@ var StreamingEditorController = class {
|
|
|
687
846
|
}
|
|
688
847
|
};
|
|
689
848
|
//#endregion
|
|
690
|
-
export { DEFAULT_MONACO_OPTIONS, StreamingEditorController, disabledKeybindings, ensureMonacoHost, installAutoImportCompletions, installDesignTokens, installDisabledKeybindings, installHoverDeadBandFix, installJsxTagClosing, modelValueMatches, monacoLanguages, reconcileModelValue, registerShikiHighlighting, replaceInEditor };
|
|
849
|
+
export { DEFAULT_MONACO_OPTIONS, StreamingEditorController, disabledKeybindings, ensureMonacoHost, installAutoImportCompletions, installDesignTokens, installDisabledKeybindings, installHoverDeadBandFix, installJsxTagClosing, modelValueMatches, monacoLanguages, reconcileModelValue, registerShikiHighlighting, registerShikiLanguage, replaceInEditor };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coldsmirk/inkstone-monaco",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.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",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"dist"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@shikijs/
|
|
43
|
-
"@coldsmirk/inkstone-core": "^0.
|
|
42
|
+
"@shikijs/vscode-textmate": "^10.0.2",
|
|
43
|
+
"@coldsmirk/inkstone-core": "^0.20.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"monaco-editor": "^0.56.0",
|