@coldsmirk/inkstone-codemirror 0.27.3 → 0.28.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 CHANGED
@@ -13,7 +13,7 @@ Part of [inkstone](https://github.com/coldsmirk/inkstone). For a drop-in React c
13
13
  - **MiniJinja** — `language: "minijinja"` for standalone templates, or `minijinja-<host>` mixed variants (`minijinja-html`, `-xml`, `-json`, `-yaml`, `-css`, `-scss`, `-sass`, `-less`, `-markdown`; the SQL family — `-sql` plus every dialect id: `-mysql`, `-pgsql`, `-sqlite`, `-mssql`, `-mariadb`, `-plsql`, `-cassandra`, `-hive`, `-sparksql`, `-gql`, `-gpsql`, `-esper`; and the config/deploy hosts `-toml`, `-ini`, `-env`, `-shell`, `-dockerfile`, `-nginx`) that overlay MiniJinja tooling on the host grammar. A parser adapter supports MiniJinja whitespace control, dotted namespace assignments, and comma-separated `set` assignments beyond the upstream Jinja grammar; a linter flags non-MiniJinja tags, and autocomplete is restricted to MiniJinja's real tags / filters / tests / functions.
14
14
  - **Context completion** — `normalizeContext({ schema })` (JSON Schema) or `normalizeContext({ sample })` (representative value) builds an `EditorContext`; dispatch it with `setMinijinjaContext` to make `{{ }}` / `{% if %}` / `{% for %}` complete the render context's variables and walk member access (`user.address.city`). `minijinjaContextField`, `resolveMembers`, and `typeAtPath` expose the underlying pieces.
15
15
  - **SQL schema completion** — dispatch `setSqlSchema.of({ tables })` for dialect-aware table and column completion in the Lezer-backed `sql`, `mysql`, `pgsql`, `sqlite`, `mssql`, `mariadb`, `plsql`, and `cassandra` languages plus their `minijinja-*` variants. Legacy stream-mode SQL languages do not consume schemas. Install `sqlSchemaField` in your static extensions to dispatch the schema before the lazy grammar arrives.
16
- - **Catppuccin theming** — `defaultThemeExtensions(dark, height?, width?, fontSize?, lineHeight?)`, the latte/macchiato flavor pair plus chrome polish (completion tooltip, icons, hover/lint tooltips, search panel) and sizing. The polish paints the host surface a consumer configured through `@coldsmirk/inkstone-core`'s `configureEditorSurface` (background and gutter, current line, line numbers, tooltip and panel chrome) and reads the host's `--inkstone-radius-*` / `--inkstone-shadow-*` tokens for corners and elevation, each falling back to its own look; `mergeTheme(dark)` / `installDiffChrome(root)` / `diffChromeColor(dark)` / `installDiffControlKeyboardSupport(container)` extend it to `@codemirror/merge`'s diff surfaces (see the `merge-chrome` module docs for the assembly). This is the identity `@coldsmirk/inkstone-react`'s components ship by default.
16
+ - **Catppuccin theming** — `defaultThemeExtensions(dark, height?, width?, fontSize?, lineHeight?)`, the latte/macchiato flavor pair plus chrome polish (completion tooltip, icons, hover/lint tooltips, search panel) and sizing. The polish paints the roles a consumer configured through `@coldsmirk/inkstone-core`'s `configureEditorSurface` — background and gutter, the current line and its number, caret, selection, scrollbars, the tooltip and panel chrome and its text, the accent, and the diagnostic severities, which color every mark `@codemirror/lint` draws (squiggle, point, gutter marker, message bar) — and reads the host's `--inkstone-radius-*` / `--inkstone-shadow-*` tokens for corners and elevation, each falling back to its own look; `mergeTheme(dark)` / `installDiffChrome(root)` / `diffChromeColor(dark)` / `installDiffControlKeyboardSupport(container)` extend it to `@codemirror/merge`'s diff surfaces (see the `merge-chrome` module docs for the assembly). This is the identity `@coldsmirk/inkstone-react`'s components ship by default.
17
17
  - **`searchPhrasesZhCn`** — an opt-in `EditorState.phrases` table localizing the search panel to Simplified Chinese.
18
18
 
19
19
  ## Install
package/dist/index.d.ts CHANGED
@@ -554,7 +554,8 @@ declare const searchPhrasesZhCn: Extension;
554
554
  * Chrome for the surfaces `@codemirror/merge` owns, in catppuccin: deletions read red on the
555
555
  * original side, insertions green on the modified side (the package scopes sides through the
556
556
  * cm-merge-a / cm-merge-b classes it places on each editor root), and the collapsed-lines bar
557
- * drops its hardcoded grays for flavor colors. Regular theme precedence — it beats the merge
557
+ * drops its hardcoded grays for the chrome's own: a host's muted text and selection plane
558
+ * (`configureEditorSurface`), else the flavor's. Regular theme precedence — it beats the merge
558
559
  * package's baseTheme by CodeMirror's theme-over-base contract, and a caller theme layered
559
560
  * after it still overrides it.
560
561
  */
@@ -562,7 +563,8 @@ declare function mergeTheme(dark: boolean): Extension;
562
563
  /**
563
564
  * The foreground the injected diff chrome inherits: set it as the diff container's `color` so
564
565
  * the revert buttons between the editors — which sit outside both editors' theme scopes —
565
- * follow the flavor (and flip with `dark`). The editors paint their own flavor colors over it.
566
+ * follow the chrome's muted text (a host's, else the flavor's) and flip with `dark`. The
567
+ * editors paint their own colors over it.
566
568
  */
567
569
  declare function diffChromeColor(dark: boolean): string;
568
570
  /**
package/dist/index.js CHANGED
@@ -401,9 +401,14 @@ function toCssSize(value) {
401
401
  function alphaOf(color, alphaValue) {
402
402
  return `rgba(${color.rgb.r}, ${color.rgb.g}, ${color.rgb.b}, ${alphaValue})`;
403
403
  }
404
+ function fade(color, percent) {
405
+ return `color-mix(in srgb, ${color} ${percent}%, transparent)`;
406
+ }
404
407
  function completionIconMask(body) {
405
- const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" stroke="#000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">${body}</svg>`;
406
- return `url("data:image/svg+xml,${encodeURIComponent(svg)}")`;
408
+ return svgImage("viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"#000\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"", body);
409
+ }
410
+ function svgImage(attributes, body) {
411
+ return `url("data:image/svg+xml,${encodeURIComponent(`<svg xmlns="http://www.w3.org/2000/svg" ${attributes}>${body}</svg>`)}")`;
407
412
  }
408
413
  const COMPLETION_ICON_FALLBACK = completionIconMask("<circle cx=\"8\" cy=\"8\" r=\"2.5\"/>");
409
414
  const COMPLETION_ICONS = {
@@ -428,29 +433,83 @@ function completionIconRules() {
428
433
  };
429
434
  return rules;
430
435
  }
436
+ const SEVERITIES = [
437
+ "error",
438
+ "warning",
439
+ "info",
440
+ "hint"
441
+ ];
442
+ function squiggle(color) {
443
+ return svgImage("width=\"6\" height=\"3\"", `<path d="m0 2.5 l2 -1.5 l1 0 l2 1.5 l1 0" stroke="${color}" fill="none" stroke-width=".7"/>`);
444
+ }
445
+ const LINT_MARKER_SHAPES = {
446
+ error: "<circle cx=\"20\" cy=\"20\" r=\"15\"/>",
447
+ warning: "<path d=\"M20 6L37 35L3 35Z\"/>",
448
+ info: "<path d=\"M5 5L35 5L35 35L5 35Z\"/>"
449
+ };
450
+ const HINT_MARK_SHAPE = "<circle cx=\"20\" cy=\"20\" r=\"9\"/>";
451
+ function lintMarker(shape, color) {
452
+ return svgImage(`viewBox="0 0 40 40" fill="${color}" fill-opacity=".35" stroke="${color}" stroke-width="6" stroke-linejoin="round"`, shape);
453
+ }
454
+ function diagnosticRules(palette) {
455
+ const rules = {};
456
+ for (const severity of SEVERITIES) {
457
+ const color = palette[severity];
458
+ const shape = LINT_MARKER_SHAPES[severity];
459
+ rules[`.cm-diagnostic-${severity}`] = { borderLeft: "none" };
460
+ rules[`.cm-diagnostic-${severity}::before`] = { backgroundImage: lintMarker(shape ?? HINT_MARK_SHAPE, color) };
461
+ rules[`.cm-lintRange-${severity}`] = { backgroundImage: squiggle(color) };
462
+ rules[`.cm-lintPoint-${severity}:after`] = { borderBottomColor: color };
463
+ if (shape !== void 0) rules[`.cm-lint-marker-${severity}`] = { content: lintMarker(shape, color) };
464
+ }
465
+ return rules;
466
+ }
431
467
  function chromeTheme(dark) {
432
468
  const { colors } = dark ? flavors.macchiato : flavors.latte;
433
469
  const surface = getEditorSurface(dark) ?? {};
434
470
  const hairline = `1px solid ${surface.widgetBorder ?? alphaOf(colors.overlay0, .35)}`;
471
+ const controlFill = surface.widgetSelection ?? colors.surface1.hex;
472
+ const foreground = surface.widgetForeground ?? colors.text.hex;
473
+ const muted = surface.widgetForegroundMuted ?? colors.overlay1.hex;
474
+ const label = surface.widgetForegroundMuted ?? colors.subtext0.hex;
475
+ const accent = surface.accent ?? colors.blue.hex;
476
+ const selection = surface.selection ?? alphaOf(colors.blue, dark ? .35 : .25);
477
+ const blurredSelection = surface.selection === void 0 ? alphaOf(colors.blue, dark ? .2 : .14) : fade(surface.selection, 50);
435
478
  const frame = {
436
479
  border: hairline,
437
480
  borderRadius: inkstoneRadius("large", "8px"),
438
481
  boxShadow: inkstoneShadow("large", dark ? "0 8px 24px rgba(0, 0, 0, 0.5)" : "0 8px 24px rgba(0, 0, 0, 0.12)"),
439
- color: colors.text.hex,
482
+ color: foreground,
440
483
  ...surface.widget !== void 0 && { backgroundColor: surface.widget }
441
484
  };
442
485
  const gutters = {
443
486
  ...surface.background !== void 0 && { backgroundColor: surface.background },
444
487
  ...surface.lineNumber !== void 0 && { color: surface.lineNumber }
445
488
  };
489
+ const caret = surface.cursor === void 0 ? {} : {
490
+ ".cm-content": { caretColor: surface.cursor },
491
+ ".cm-cursor, .cm-dropCursor": { borderLeftColor: surface.cursor }
492
+ };
493
+ const tooltipArrow = surface.widget === void 0 ? {} : {
494
+ ".cm-tooltip .cm-tooltip-arrow:before": {
495
+ borderTopColor: surface.widgetBorder ?? "transparent",
496
+ borderBottomColor: surface.widgetBorder ?? "transparent"
497
+ },
498
+ ".cm-tooltip .cm-tooltip-arrow:after": {
499
+ borderTopColor: surface.widget,
500
+ borderBottomColor: surface.widget
501
+ }
502
+ };
446
503
  return EditorView.theme({
447
504
  "&": {
448
505
  colorScheme: dark ? "dark" : "light",
449
506
  ...surface.background !== void 0 && { backgroundColor: surface.background }
450
507
  },
451
508
  ...Object.keys(gutters).length > 0 && { ".cm-gutters": gutters },
509
+ ...caret,
452
510
  ".cm-scroller": { fontFamily: CODE_FONT_FAMILY },
453
511
  ".cm-tooltip": frame,
512
+ ...tooltipArrow,
454
513
  ".cm-tooltip.cm-tooltip-autocomplete": {
455
514
  ...frame,
456
515
  paddingBlock: "4px",
@@ -466,7 +525,10 @@ function chromeTheme(dark) {
466
525
  borderRadius: inkstoneRadius("medium", "5px"),
467
526
  lineHeight: "1.45"
468
527
  },
469
- ...surface.widgetSelection !== void 0 && { "& > ul > li[aria-selected]": { backgroundColor: surface.widgetSelection } }
528
+ "& > ul > li[aria-selected]": {
529
+ color: foreground,
530
+ ...surface.widgetSelection !== void 0 && { backgroundColor: surface.widgetSelection }
531
+ }
470
532
  },
471
533
  ".cm-completionLabel": {
472
534
  minWidth: "0",
@@ -476,20 +538,20 @@ function chromeTheme(dark) {
476
538
  ".cm-completionMatchedText": {
477
539
  textDecoration: "none",
478
540
  fontWeight: "600",
479
- color: colors.blue.hex
541
+ color: accent
480
542
  },
481
543
  ".cm-completionDetail": {
482
544
  marginLeft: "auto",
483
545
  paddingLeft: "12px",
484
546
  fontStyle: "normal",
485
547
  fontSize: "85%",
486
- color: colors.overlay1.hex
548
+ color: muted
487
549
  },
488
550
  ".cm-completionIcon": {
489
551
  width: "14px",
490
552
  paddingRight: "8px",
491
553
  opacity: "1",
492
- color: colors.overlay1.hex
554
+ color: muted
493
555
  },
494
556
  ".cm-completionIcon:after": {
495
557
  content: "''",
@@ -513,7 +575,7 @@ function chromeTheme(dark) {
513
575
  ".cm-completionIcon-constant": { color: colors.sky.hex },
514
576
  ".cm-completionIcon-property": { color: colors.teal.hex },
515
577
  ".cm-completionIcon-namespace": { color: colors.sapphire.hex },
516
- ".cm-completionIcon-text": { color: colors.overlay1.hex },
578
+ ".cm-completionIcon-text": { color: muted },
517
579
  ".cm-completionIcon-class, .cm-completionIcon-type, .cm-completionIcon-interface, .cm-completionIcon-enum": { color: colors.yellow.hex },
518
580
  ".cm-tooltip.cm-completionInfo": {
519
581
  ...frame,
@@ -525,39 +587,70 @@ function chromeTheme(dark) {
525
587
  maxWidth: "26em",
526
588
  overflowWrap: "anywhere"
527
589
  },
590
+ ".cm-gutter-lint .cm-gutterElement": { padding: "calc((1lh - 1em) / 2) .2em 0" },
528
591
  ".cm-diagnostic": {
592
+ display: "grid",
593
+ gridTemplateColumns: "0.9em minmax(0, 1fr)",
594
+ columnGap: "0.6em",
595
+ rowGap: "4px",
529
596
  margin: "0",
530
597
  padding: "3px 8px",
531
- borderLeftWidth: "3px",
532
598
  borderRadius: inkstoneRadius("medium", "5px"),
533
599
  lineHeight: "1.45"
534
600
  },
535
- ".cm-diagnostic-error": { borderLeftColor: colors.red.hex },
536
- ".cm-diagnostic-warning": { borderLeftColor: colors.yellow.hex },
537
- ".cm-diagnostic-info": { borderLeftColor: colors.overlay1.hex },
538
- ".cm-diagnostic-hint": { borderLeftColor: colors.blue.hex },
601
+ ".cm-diagnostic::before": {
602
+ content: "''",
603
+ gridColumn: "1",
604
+ gridRow: "1",
605
+ height: "1lh",
606
+ backgroundPosition: "center",
607
+ backgroundSize: "0.9em",
608
+ backgroundRepeat: "no-repeat"
609
+ },
610
+ ".cm-diagnostic > *": { gridColumn: "2" },
611
+ ...diagnosticRules({
612
+ error: surface.error ?? colors.red.hex,
613
+ warning: surface.warning ?? colors.peach.hex,
614
+ info: surface.info ?? colors.blue.hex,
615
+ hint: surface.hint ?? colors.overlay1.hex
616
+ }),
539
617
  ".cm-diagnosticAction": {
540
- padding: "2px 6px",
541
- backgroundColor: colors.surface1.hex,
542
- color: colors.text.hex,
618
+ justifySelf: "start",
619
+ margin: "0",
620
+ padding: "1px 6px",
621
+ color: foreground,
622
+ backgroundColor: "transparent",
623
+ border: hairline,
543
624
  borderRadius: inkstoneRadius("small", "4px")
544
625
  },
626
+ ".cm-diagnosticAction:hover, .cm-diagnosticAction:active": { backgroundColor: controlFill },
545
627
  ".cm-diagnosticSource": {
546
628
  fontSize: "85%",
547
- color: colors.overlay1.hex,
629
+ color: muted,
548
630
  opacity: "1"
549
631
  },
632
+ ".cm-panel.cm-panel-lint ul [aria-selected], .cm-panel.cm-panel-lint ul:focus [aria-selected]": {
633
+ backgroundColor: controlFill,
634
+ color: foreground
635
+ },
636
+ ".cm-panel.cm-panel-lint [name=close]": { color: muted },
550
637
  "&.cm-focused": { outline: "none" },
551
638
  ".cm-activeLine": { backgroundColor: surface.lineHighlight ?? alphaOf(colors.overlay0, .12) },
552
- ".cm-activeLineGutter": { backgroundColor: surface.lineHighlight ?? alphaOf(colors.overlay0, .12) },
553
- "&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": { backgroundColor: alphaOf(colors.blue, dark ? .35 : .25) },
554
- ".cm-selectionBackground": { backgroundColor: alphaOf(colors.blue, dark ? .2 : .14) },
555
- ".cm-content ::selection": { backgroundColor: alphaOf(colors.blue, dark ? .35 : .25) },
639
+ ".cm-activeLineGutter": {
640
+ backgroundColor: surface.lineHighlight ?? alphaOf(colors.overlay0, .12),
641
+ ...surface.lineNumberActive !== void 0 && { color: surface.lineNumberActive }
642
+ },
643
+ "&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": { backgroundColor: selection },
644
+ ".cm-selectionBackground": { backgroundColor: blurredSelection },
645
+ ".cm-content ::selection": { backgroundColor: selection },
556
646
  ".cm-scroller, .cm-tooltip-autocomplete > ul, .cm-tooltip.cm-completionInfo": {
557
647
  scrollbarWidth: "thin",
558
- scrollbarColor: `${alphaOf(colors.overlay0, .55)} transparent`
648
+ scrollbarColor: `${surface.scrollbar ?? alphaOf(colors.overlay0, .55)} transparent`
649
+ },
650
+ ".cm-panels": {
651
+ color: foreground,
652
+ ...surface.widget !== void 0 && { backgroundColor: surface.widget }
559
653
  },
560
- ...surface.widget !== void 0 && { ".cm-panels": { backgroundColor: surface.widget } },
561
654
  ".cm-panels.cm-panels-top": { borderBottom: hairline },
562
655
  ".cm-panels.cm-panels-bottom": { borderTop: hairline },
563
656
  ".cm-panel.cm-search, .cm-panel.cm-gotoLine": {
@@ -582,7 +675,7 @@ function chromeTheme(dark) {
582
675
  gap: "6px",
583
676
  margin: "0",
584
677
  fontSize: "12.5px",
585
- color: colors.subtext0.hex,
678
+ color: label,
586
679
  cursor: "pointer",
587
680
  userSelect: "none"
588
681
  },
@@ -590,7 +683,7 @@ function chromeTheme(dark) {
590
683
  margin: "0",
591
684
  width: "14px",
592
685
  height: "14px",
593
- accentColor: colors.blue.hex
686
+ accentColor: accent
594
687
  },
595
688
  ".cm-panel.cm-search button[name=close]": {
596
689
  position: "absolute",
@@ -605,15 +698,15 @@ function chromeTheme(dark) {
605
698
  justifyContent: "center",
606
699
  fontSize: "16px",
607
700
  lineHeight: "1",
608
- color: colors.overlay1.hex,
701
+ color: muted,
609
702
  background: "transparent",
610
703
  border: "none",
611
704
  borderRadius: inkstoneRadius("medium", "6px"),
612
705
  cursor: "pointer"
613
706
  },
614
707
  ".cm-panel.cm-search button[name=close]:hover": {
615
- backgroundColor: colors.surface0.hex,
616
- color: colors.text.hex
708
+ backgroundColor: controlFill,
709
+ color: foreground
617
710
  },
618
711
  ".cm-panel .cm-textfield": {
619
712
  boxSizing: "border-box",
@@ -623,15 +716,16 @@ function chromeTheme(dark) {
623
716
  margin: "0",
624
717
  padding: "0 10px",
625
718
  fontSize: "12.5px",
626
- color: colors.text.hex,
719
+ color: foreground,
627
720
  backgroundColor: surface.background ?? colors.base.hex,
628
721
  border: hairline,
629
722
  borderRadius: inkstoneRadius("medium", "6px")
630
723
  },
724
+ ".cm-panel .cm-textfield::placeholder": { color: muted },
631
725
  ".cm-panel .cm-textfield:focus": {
632
726
  outline: "none",
633
- borderColor: alphaOf(colors.blue, .6),
634
- boxShadow: `0 0 0 2px ${alphaOf(colors.blue, .2)}`
727
+ borderColor: fade(accent, 60),
728
+ boxShadow: `0 0 0 2px ${fade(accent, 20)}`
635
729
  },
636
730
  ".cm-panel .cm-button": {
637
731
  boxSizing: "border-box",
@@ -639,17 +733,16 @@ function chromeTheme(dark) {
639
733
  margin: "0",
640
734
  padding: "0 12px",
641
735
  fontSize: "12.5px",
642
- color: colors.text.hex,
736
+ color: foreground,
643
737
  backgroundImage: "none",
644
- backgroundColor: colors.surface0.hex,
738
+ backgroundColor: "transparent",
645
739
  border: hairline,
646
740
  borderRadius: inkstoneRadius("medium", "6px"),
647
741
  cursor: "pointer"
648
742
  },
649
- ".cm-panel .cm-button:hover": { backgroundColor: colors.surface1.hex },
650
- ".cm-panel .cm-button:active": {
743
+ ".cm-panel .cm-button:hover, .cm-panel .cm-button:active": {
651
744
  backgroundImage: "none",
652
- backgroundColor: colors.surface1.hex
745
+ backgroundColor: controlFill
653
746
  }
654
747
  }, { dark });
655
748
  }
@@ -675,6 +768,8 @@ function defaultThemeExtensions(dark, height, width, fontSize, lineHeight) {
675
768
  //#region src/merge-chrome.ts
676
769
  function mergeTheme(dark) {
677
770
  const { colors } = dark ? flavors.macchiato : flavors.latte;
771
+ const surface = getEditorSurface(dark) ?? {};
772
+ const band = surface.widgetSelection ?? colors.surface0.hex;
678
773
  const removed = colors.red;
679
774
  const added = colors.green;
680
775
  const underline = (color) => `linear-gradient(${alphaOf(color, .5)}, ${alphaOf(color, .5)}) bottom/100% 2px no-repeat`;
@@ -686,13 +781,13 @@ function mergeTheme(dark) {
686
781
  "&.cm-merge-a .cm-changedLineGutter": { background: removed.hex },
687
782
  "&.cm-merge-b .cm-changedLineGutter": { background: added.hex },
688
783
  ".cm-collapsedLines": {
689
- color: colors.subtext0.hex,
690
- background: `linear-gradient(to bottom, transparent 0, ${colors.surface0.hex} 30%, ${colors.surface0.hex} 70%, transparent 100%)`
784
+ color: surface.widgetForegroundMuted ?? colors.subtext0.hex,
785
+ background: `linear-gradient(to bottom, transparent 0, ${band} 30%, ${band} 70%, transparent 100%)`
691
786
  }
692
787
  }, { dark });
693
788
  }
694
789
  function diffChromeColor(dark) {
695
- return (dark ? flavors.macchiato : flavors.latte).colors.overlay1.hex;
790
+ return getEditorSurface(dark)?.widgetForegroundMuted ?? (dark ? flavors.macchiato : flavors.latte).colors.overlay1.hex;
696
791
  }
697
792
  const DIFF_CHROME_STYLE_SELECTOR = "style[data-inkstone=\"codemirror-diff\"]";
698
793
  function installDiffChrome(root) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coldsmirk/inkstone-codemirror",
3
- "version": "0.27.3",
3
+ "version": "0.28.0",
4
4
  "description": "Framework-agnostic CodeMirror 6 plumbing: a controlled editor host (create-once, external-value reconcile, in-place theme swap), the standard document extension bundle, and the editors' catppuccin theming.",
5
5
  "keywords": [
6
6
  "codemirror",
@@ -62,7 +62,7 @@
62
62
  "@codemirror/lint": "^6.9.7",
63
63
  "@codemirror/merge": "^6.12.2",
64
64
  "@lezer/common": "^1.5.2",
65
- "@coldsmirk/inkstone-core": "^0.27.3"
65
+ "@coldsmirk/inkstone-core": "^0.28.0"
66
66
  },
67
67
  "devDependencies": {
68
68
  "@codemirror/autocomplete": "^6.20.3",