@coldsmirk/inkstone-core 0.28.1 → 0.29.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 +32 -29
- package/dist/index.js +26 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Part of [inkstone](https://github.com/coldsmirk/inkstone). The editor layers ([`
|
|
|
10
10
|
- **`configureHighlighter(config)`** — extend or replace the default grammar / theme set, and choose the regex engine, once, before any editor mounts. `DEFAULT_HIGHLIGHTER_LANGS` is exported so extension is additive. `engine` takes the engine itself, a promise of one, or a factory called once when the highlighter is first built — configuration stays synchronous while the engine may be async to make: the strict JavaScript engine by default, `createJavaScriptRegexEngine({ forgiving: true })` for grammars the strict one refuses, or `onigurumaEngine`.
|
|
11
11
|
- **`onigurumaEngine`** — the Oniguruma engine on its WASM, inlined into a chunk of your own bundle (about 600 KB, nothing fetched from anywhere else) and instantiated once, in about 20 ms. Which engine: the JavaScript one translates each grammar's patterns into JavaScript at the first tokenization, on the main thread, and pays for it on whole files — a TypeScript file's first sixty lines cost it about 170 ms, against Oniguruma's 20. Colouring fenced snippets, keep the default; reading whole files in an editor (`@coldsmirk/inkstone-monaco`'s Shiki bridge, `<MonacoEditor>`), pass `onigurumaEngine` as the factory. `onigurumaEngine(wasm)` takes the WASM from elsewhere in any form Shiki's `createOnigurumaEngine` accepts, such as a `fetch("/onig.wasm")`.
|
|
12
12
|
- **`shikiThemeId(dark)`** plus the `INKSTONE_LIGHT_THEME` / `INKSTONE_DARK_THEME` constants — the theme names to pass wherever a Shiki theme id is expected.
|
|
13
|
-
- **`
|
|
13
|
+
- **`configureEditorColors(config)`** — set every color the editors paint that is not syntax (a VS Code theme's `colors`, beside its `tokenColors`) in your design language, once, before any editor mounts. Per scheme, CSS color literals for the editor (`background` — content, gutter and the fields of its chrome — `lineHighlight`, `lineNumber`, `lineNumberActive`, `cursor`, `selection`, `scrollbar`), its floating chrome — completion, hover, parameter hints, the find widget and search panels, the context menu — (`widget`, `widgetBorder`, `widgetSelection`, `widgetForeground`, `widgetForegroundMuted`), the `accent` that rings a focused field and marks what a completion matched, and the diagnostic severities `error`, `warning`, `info` and `hint`, named as CodeMirror's `Diagnostic.severity` names them. The catppuccin pair keeps its syntax palette — token colors, the editor's default text, the completion-kind icons that mirror them — and gets these baked into its theme colors — Monaco, static rendering, and CodeMirror's chrome all read the same values — so an editor sits inside the app instead of bringing a second dark. A role or scheme left out keeps the flavor's own color, a later call replaces the schemes it names, and values must be hex colors (`#rrggbb`, `#rrggbbaa`) — Monaco parses theme colors as hex and paints red for anything else, so a `var()` reference or an `rgb(…)` is refused up front. Keep `lineHighlight` translucent: CodeMirror draws selections behind the content, so an opaque active line would hide them. `selection` shows at half its alpha while the editor is unfocused, in both engines; `scrollbar` has no hover state (CodeMirror's `scrollbar-color` has none, so Monaco's slider keeps it too). `getEditorColors(dark)` reads what was configured, and `withEditorColors(theme, colors)` applies a set of them to a Shiki theme of your own.
|
|
14
14
|
- **`CODE_FONT_FAMILY`** — the shared code font stack both editor engines render with: the page's `--inkstone-font-family-code` CSS token when defined, else the platform's native monospace.
|
|
15
15
|
- **`inkstoneRadius(size, fallback)` / `inkstoneShadow(size, fallback)`** — `var()` references to the host's `--inkstone-radius-{small,medium,large,xlarge}` and `--inkstone-shadow-{medium,large,xlarge}` tokens. Set them once on your root and both engines' chrome follows: the Monaco host maps them onto VS Code's `--vscode-cornerRadius-*` / `--vscode-shadow-*` design tokens (which the standalone editor never defines), CodeMirror's polish reads them directly; unset, each engine keeps the look it ships with.
|
|
16
16
|
|
|
@@ -25,7 +25,7 @@ pnpm add @coldsmirk/inkstone-core
|
|
|
25
25
|
## Quick start
|
|
26
26
|
|
|
27
27
|
```ts
|
|
28
|
-
import {
|
|
28
|
+
import { configureEditorColors, configureHighlighter, DEFAULT_HIGHLIGHTER_LANGS, getHighlighter, onigurumaEngine, shikiThemeId } from "@coldsmirk/inkstone-core";
|
|
29
29
|
import yaml from "@shikijs/langs/yaml";
|
|
30
30
|
|
|
31
31
|
// Optional: add grammars/themes beyond the defaults — once, before any editor mounts — and,
|
|
@@ -33,7 +33,7 @@ import yaml from "@shikijs/langs/yaml";
|
|
|
33
33
|
configureHighlighter({ langs: [...DEFAULT_HIGHLIGHTER_LANGS, yaml], engine: onigurumaEngine });
|
|
34
34
|
|
|
35
35
|
// Optional: paint the editors' chrome in your own tokens (syntax colors stay catppuccin's).
|
|
36
|
-
|
|
36
|
+
configureEditorColors({
|
|
37
37
|
light: { background: "#f7f7fa", lineHighlight: "#16171a0a", widget: "#ffffff", widgetBorder: "#ced4da", accent: "#228be6", error: "#e03131" },
|
|
38
38
|
dark: { background: "#1d1b22", lineHighlight: "#ffffff0a", widget: "#302e38", widgetBorder: "#423f4b", accent: "#4dabf7", error: "#ff6b6b" }
|
|
39
39
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -8,19 +8,20 @@ import { Awaitable, HighlighterCore, HighlighterCore as HighlighterCore$1, Langu
|
|
|
8
8
|
*/
|
|
9
9
|
declare const CODE_FONT_FAMILY = "var(--inkstone-font-family-code, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace)";
|
|
10
10
|
//#endregion
|
|
11
|
-
//#region src/
|
|
12
|
-
/**
|
|
13
|
-
* The colors an editor paints that are not its syntax
|
|
14
|
-
* them. A host that configures these keeps
|
|
15
|
-
* editor's own chrome — background, gutter,
|
|
16
|
-
* completion / hover / find widgets and the
|
|
17
|
-
* sits inside the app instead of bringing a
|
|
11
|
+
//#region src/editor-colors.d.ts
|
|
12
|
+
/**
|
|
13
|
+
* The colors an editor paints that are not its syntax — a VS Code theme's `colors` beside its
|
|
14
|
+
* `tokenColors` — as a host's design language names them. A host that configures these keeps
|
|
15
|
+
* the catppuccin flavors' syntax palette and gets the editor's own chrome — background, gutter,
|
|
16
|
+
* current line, caret and selection, the floating completion / hover / find widgets and the
|
|
17
|
+
* signals on them — in its own tokens, so an editor sits inside the app instead of bringing a
|
|
18
|
+
* second dark.
|
|
18
19
|
*
|
|
19
20
|
* Every value is a hex color (`#rrggbb`, `#rrggbbaa`): Monaco parses its theme colors itself,
|
|
20
21
|
* as hex only, and cannot follow a custom property. An omitted role keeps the flavor's own
|
|
21
22
|
* color.
|
|
22
23
|
*/
|
|
23
|
-
interface
|
|
24
|
+
interface EditorColors {
|
|
24
25
|
/**
|
|
25
26
|
* The editor's own background: the content area and the gutter, and the fields inside
|
|
26
27
|
* floating chrome.
|
|
@@ -102,12 +103,20 @@ interface EditorSurface {
|
|
|
102
103
|
hint?: string;
|
|
103
104
|
}
|
|
104
105
|
/**
|
|
105
|
-
*
|
|
106
|
+
* The editor colors of each color scheme; an omitted scheme keeps the flavor's own.
|
|
106
107
|
*/
|
|
107
|
-
interface
|
|
108
|
-
light?:
|
|
109
|
-
dark?:
|
|
108
|
+
interface EditorColorsConfig {
|
|
109
|
+
light?: EditorColors;
|
|
110
|
+
dark?: EditorColors;
|
|
110
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* A flavor with its editor colors repainted from `colors`: the token colors (the syntax
|
|
114
|
+
* palette) are untouched, only the theme colors behind each configured role change. Returns
|
|
115
|
+
* the theme itself when there is nothing to apply.
|
|
116
|
+
*/
|
|
117
|
+
declare function withEditorColors(theme: ThemeRegistration, colors: EditorColors | undefined): ThemeRegistration;
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region src/host-tokens.d.ts
|
|
111
120
|
/**
|
|
112
121
|
* The corner-radius sizes both editors read from the host: `--inkstone-radius-<size>`. Monaco
|
|
113
122
|
* maps them onto VS Code's own `--vscode-cornerRadius-*` design tokens (which the standalone
|
|
@@ -130,12 +139,6 @@ type ShadowSize = "medium" | "large" | "xlarge";
|
|
|
130
139
|
* A `var()` reference to the host's `--inkstone-shadow-<size>` token with the given fallback.
|
|
131
140
|
*/
|
|
132
141
|
declare function inkstoneShadow(size: ShadowSize, fallback: string): string;
|
|
133
|
-
/**
|
|
134
|
-
* A flavor with its surfaces repainted from `surface`: the token colors (the syntax palette)
|
|
135
|
-
* are untouched, only the theme colors behind each configured role change. Returns the theme
|
|
136
|
-
* itself when there is nothing to apply.
|
|
137
|
-
*/
|
|
138
|
-
declare function surfacedTheme(theme: ThemeRegistration, surface: EditorSurface | undefined): ThemeRegistration;
|
|
139
142
|
//#endregion
|
|
140
143
|
//#region src/shiki.d.ts
|
|
141
144
|
/**
|
|
@@ -202,23 +205,23 @@ declare function onigurumaEngine(wasm?: LoadWasmOptions): Promise<RegexEngine>;
|
|
|
202
205
|
*/
|
|
203
206
|
declare function configureHighlighter(options: HighlighterConfig): void;
|
|
204
207
|
/**
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
*
|
|
208
|
+
* Paint the editors in the host's own colors, once, before the first {@link getHighlighter}
|
|
209
|
+
* call — the catppuccin pair is registered with these colors baked in (Monaco reads them from
|
|
210
|
+
* the theme, static rendering too), and CodeMirror's chrome reads them at mount. A scheme left
|
|
211
|
+
* out keeps the flavor's own colors; a role left out keeps that role's flavor color; a later
|
|
212
|
+
* call replaces the schemes it names. Process-global like the highlighter itself, for the same
|
|
213
|
+
* reason: one palette across every editor and rendered block.
|
|
211
214
|
*
|
|
212
215
|
* Every value must be a hex color (`#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`) — Monaco parses
|
|
213
216
|
* theme colors as hex and paints red for anything else, a custom property reference or an
|
|
214
217
|
* `rgb(…)` alike, so those are refused here instead of failing on screen.
|
|
215
218
|
*/
|
|
216
|
-
declare function
|
|
219
|
+
declare function configureEditorColors(config: EditorColorsConfig): void;
|
|
217
220
|
/**
|
|
218
|
-
* The
|
|
219
|
-
* undefined when the flavor's own
|
|
221
|
+
* The editor colors configured for a color scheme through {@link configureEditorColors}, or
|
|
222
|
+
* undefined when the flavor's own colors stand.
|
|
220
223
|
*/
|
|
221
|
-
declare function
|
|
224
|
+
declare function getEditorColors(dark: boolean): EditorColors | undefined;
|
|
222
225
|
/**
|
|
223
226
|
* The shared Shiki highlighter, built lazily on first call.
|
|
224
227
|
*
|
|
@@ -239,4 +242,4 @@ declare function getHighlighter(): Promise<HighlighterCore$1>;
|
|
|
239
242
|
*/
|
|
240
243
|
declare function shikiThemeId(dark: boolean): string;
|
|
241
244
|
//#endregion
|
|
242
|
-
export { CODE_FONT_FAMILY, DEFAULT_HIGHLIGHTER_LANGS, type
|
|
245
|
+
export { CODE_FONT_FAMILY, DEFAULT_HIGHLIGHTER_LANGS, type EditorColors, type EditorColorsConfig, type HighlighterConfig, type HighlighterCore, INKSTONE_DARK_THEME, INKSTONE_LIGHT_THEME, type RadiusSize, type ShadowSize, configureEditorColors, configureHighlighter, getEditorColors, getHighlighter, inkstoneRadius, inkstoneShadow, onigurumaEngine, shikiThemeId, withEditorColors };
|
package/dist/index.js
CHANGED
|
@@ -10,14 +10,8 @@ import { createOnigurumaEngine } from "shiki/engine/oniguruma";
|
|
|
10
10
|
//#region src/code-font.ts
|
|
11
11
|
const CODE_FONT_FAMILY = "var(--inkstone-font-family-code, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace)";
|
|
12
12
|
//#endregion
|
|
13
|
-
//#region src/
|
|
14
|
-
|
|
15
|
-
return `var(--inkstone-radius-${size}, ${fallback})`;
|
|
16
|
-
}
|
|
17
|
-
function inkstoneShadow(size, fallback) {
|
|
18
|
-
return `var(--inkstone-shadow-${size}, ${fallback})`;
|
|
19
|
-
}
|
|
20
|
-
const SURFACE_COLORS = {
|
|
13
|
+
//#region src/editor-colors.ts
|
|
14
|
+
const EDITOR_COLOR_KEYS = {
|
|
21
15
|
background: [
|
|
22
16
|
"editor.background",
|
|
23
17
|
"editorGutter.background",
|
|
@@ -120,22 +114,30 @@ const SURFACE_COLORS = {
|
|
|
120
114
|
],
|
|
121
115
|
hint: ["editorHint.foreground"]
|
|
122
116
|
};
|
|
123
|
-
function
|
|
124
|
-
const roles = Object.entries(
|
|
125
|
-
const
|
|
117
|
+
function withEditorColors(theme, colors) {
|
|
118
|
+
const roles = Object.entries(EDITOR_COLOR_KEYS);
|
|
119
|
+
const themeColors = { ...theme.colors };
|
|
126
120
|
let changed = false;
|
|
127
121
|
for (const [role, keys] of roles) {
|
|
128
|
-
const value =
|
|
122
|
+
const value = colors?.[role];
|
|
129
123
|
if (value === void 0) continue;
|
|
130
|
-
for (const key of keys)
|
|
124
|
+
for (const key of keys) themeColors[key] = value;
|
|
131
125
|
changed = true;
|
|
132
126
|
}
|
|
133
127
|
return changed ? {
|
|
134
128
|
...theme,
|
|
135
|
-
colors
|
|
129
|
+
colors: themeColors
|
|
136
130
|
} : theme;
|
|
137
131
|
}
|
|
138
132
|
//#endregion
|
|
133
|
+
//#region src/host-tokens.ts
|
|
134
|
+
function inkstoneRadius(size, fallback) {
|
|
135
|
+
return `var(--inkstone-radius-${size}, ${fallback})`;
|
|
136
|
+
}
|
|
137
|
+
function inkstoneShadow(size, fallback) {
|
|
138
|
+
return `var(--inkstone-shadow-${size}, ${fallback})`;
|
|
139
|
+
}
|
|
140
|
+
//#endregion
|
|
139
141
|
//#region src/shiki.ts
|
|
140
142
|
const INKSTONE_LIGHT_THEME = "catppuccin-latte";
|
|
141
143
|
const INKSTONE_DARK_THEME = "catppuccin-macchiato";
|
|
@@ -180,19 +182,19 @@ function configureHighlighter(options) {
|
|
|
180
182
|
};
|
|
181
183
|
}
|
|
182
184
|
const HEX_COLOR = /^#(?:[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/i;
|
|
183
|
-
function
|
|
185
|
+
function configureEditorColors(config) {
|
|
184
186
|
const registry = getHighlighterRegistry();
|
|
185
|
-
assertConfigurable(registry, "
|
|
186
|
-
for (const [scheme,
|
|
187
|
-
const roles = Object.entries(
|
|
188
|
-
for (const [role, value] of roles) if (typeof value === "string" && !HEX_COLOR.test(value)) throw new Error(`
|
|
187
|
+
assertConfigurable(registry, "configureEditorColors");
|
|
188
|
+
for (const [scheme, colors] of Object.entries(config)) {
|
|
189
|
+
const roles = Object.entries(colors ?? {});
|
|
190
|
+
for (const [role, value] of roles) if (typeof value === "string" && !HEX_COLOR.test(value)) throw new Error(`configureEditorColors: ${scheme}.${role} must be a hex color, which is all Monaco parses (${value})`);
|
|
189
191
|
}
|
|
190
192
|
registry.surfaces = {
|
|
191
193
|
...registry.surfaces,
|
|
192
|
-
...
|
|
194
|
+
...config
|
|
193
195
|
};
|
|
194
196
|
}
|
|
195
|
-
function
|
|
197
|
+
function getEditorColors(dark) {
|
|
196
198
|
const { surfaces } = getHighlighterRegistry();
|
|
197
199
|
return dark ? surfaces.dark : surfaces.light;
|
|
198
200
|
}
|
|
@@ -202,8 +204,8 @@ function getHighlighter() {
|
|
|
202
204
|
if (existing) return existing;
|
|
203
205
|
const attempt = createHighlighterCore({
|
|
204
206
|
themes: [
|
|
205
|
-
|
|
206
|
-
|
|
207
|
+
withEditorColors(catppuccinLatte, registry.surfaces.light),
|
|
208
|
+
withEditorColors(catppuccinMacchiato, registry.surfaces.dark),
|
|
207
209
|
...registry.config.themes ?? []
|
|
208
210
|
],
|
|
209
211
|
langs: registry.config.langs ?? [...DEFAULT_HIGHLIGHTER_LANGS],
|
|
@@ -219,4 +221,4 @@ function shikiThemeId(dark) {
|
|
|
219
221
|
return dark ? INKSTONE_DARK_THEME : INKSTONE_LIGHT_THEME;
|
|
220
222
|
}
|
|
221
223
|
//#endregion
|
|
222
|
-
export { CODE_FONT_FAMILY, DEFAULT_HIGHLIGHTER_LANGS, INKSTONE_DARK_THEME, INKSTONE_LIGHT_THEME,
|
|
224
|
+
export { CODE_FONT_FAMILY, DEFAULT_HIGHLIGHTER_LANGS, INKSTONE_DARK_THEME, INKSTONE_LIGHT_THEME, configureEditorColors, configureHighlighter, getEditorColors, getHighlighter, inkstoneRadius, inkstoneShadow, onigurumaEngine, shikiThemeId, withEditorColors };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coldsmirk/inkstone-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.0",
|
|
4
4
|
"description": "Shared Shiki highlighter service for the inkstone editor toolkit: one fine-grained singleton (catppuccin themes, the JS regex engine by default or Oniguruma on request) reused by Monaco, static rendering, and markdown surfaces.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"shiki",
|