Add compact JSON formatter with format-on-paste (§03A)

This commit is contained in:
2026-06-07 18:45:17 +03:00
parent a62e2c6128
commit 9f7bf27b7a
6 changed files with 148 additions and 0 deletions
+9
View File
@@ -23,6 +23,7 @@ import * as monaco from 'monaco-editor/esm/vs/editor/edcore.main';
import 'monaco-editor/esm/vs/language/json/monaco.contribution';
import '../infrastructure/monaco-env'; // side-effect: wire workers before create
import { configureVegaLiteJson } from '../infrastructure/monaco-schema';
import { configureJsonFormatter, installFormatOnPaste } from '../infrastructure/monaco-format';
import { openModal } from '../modals/ModalCoordinator';
import { useAppStore } from '../stores/AppStore';
import { confirm } from '../stores/ConfirmStore';
@@ -134,6 +135,8 @@ function EditorSettings() {
// Register the bundled Vega-Lite schema once: resolves `$schema` locally (no
// network warning) and powers validation, autocomplete, and hover docs.
configureVegaLiteJson();
// Register the compact JSON formatter once (Format Document + format-on-paste, §03A).
configureJsonFormatter();
function EditorToolbar() {
const activeId = useSnippetStore((s) => s.activeSnippetId);
@@ -267,6 +270,11 @@ export function SpecEditor() {
}
});
// Pasting reindents the whole spec to keep it consistently formatted (§03A).
// The reformat fires onDidChangeModelContent above, so the draft buffer picks
// up the formatted text. No-op on the read-only published view / invalid JSON.
const pasteSub = installFormatOnPaste(editor);
// Cmd/Ctrl+S is owned globally by the EventRouter (docs/architecture/04 →
// "bind listeners in exactly one place"), which publishes before the
// interactive-context gate so it works while the editor has focus. Monaco
@@ -274,6 +282,7 @@ export function SpecEditor() {
return () => {
sub.dispose();
pasteSub.dispose();
editor.dispose();
editorRef.current = null;
};