Skip to content
QuireKit MSFE
Developer docs
v0.0.0 · Experimental

Custom code blocks

Customize toolbars, language loading and styles while retaining native code editing.

Complete toolbar example

The example adds a language selector to a fence. Changing language edits only its header field, preserving the body and fence spelling. Locked mode disables the selector; undo restores the previous language.

Preparing the editor…

Choose the customization layer

GoalEntry point
Fonts, surfaces and spacingEditorView.theme() and syntax highlighting
Language, copy or menu controlsCodeBlock.extend({ addNodeView() {} })
TypeScript, JSON and other grammarscodeLanguages creation option
Mermaid, ECharts or flow DSL outputSemantic extension plus block projection; see Diagrams

The CodeBlock NodeView sits before the fence with placement: 'before'. It does not replace the complete code body and provides no editable contentDOM.

Replace one preset feature

ts

Do not install both StarterKit's original owner and a derived owner with the same name. Alternatively disable the preset entry and install exactly one replacement.

Available fields and actions

The component receives nodeView: MsfeNodeViewProps<CodeBlockAttributes>. The persisted field is currently language. Call nodeView.updateAttributes({ language: 'json' }). Admitted language tokens contain at most 40 letters, digits, underscores or + # . -; newlines and arbitrary header injection are rejected.

With an applicable selection, editor.commands.setCodeLanguage('typescript') updates a confirmed fence. Check failure results. Field validity does not imply that a matching highlighter was installed.

Copying is a read action: the host should read confirmed CodeText ranges while preserving indentation and line breaks. NodeView getRange() supplies coordinates, not an already-extracted code body. Use anchors for actions spanning a dialog.

Lazy language loading

code-block/languages.ts supplies TypeScript, JavaScript and JSON through @quirekit/cm-lang-javascript and @quirekit/cm-lang-json. Pass the registry as codeLanguages when creating the editor.

Names and aliases match exactly, case-insensitively. load(signal) returns LanguageSupport. Unknown languages remain plain text; no package path is guessed or downloaded. Dynamic imports cannot truly abort, so host resources must respect cancellation and discard obsolete results.

Closed fences without a body line

CodeBlock shows an input placeholder when the opening and closing fence are on adjacent lines. Clicking it or activating it with Enter / Space inserts one real line through a normal editor command, preserves quote/list prefixes, and moves the caret into the body. Rendering, scrolling and mode changes do not modify Markdown. Existing empty body lines need no placeholder. Read-only mode disables activation; materializing the line supports undo and redo.

Set CodeBlock.configure({ emptyLine: false }) to disable it; emptyLineLabel supplies the accessible hint. MD Editor accepts features.codeBlock: ProseCodeBlock.configure({ emptyLine: false }) and localizes the default hint. Source mode shows the actual fences and newlines without an input placeholder.

MD Editor provides the lazy mdCodeLanguages catalog by default: TypeScript, JavaScript / JSX, TSX, JSON, CSS, HTML, Python, Bash and Markdown. Supplying codeLanguages replaces the catalog; [] disables it. Custom themes and grammar packages must share the same @lezer/highlight version: different tag identities can leave parsed tokens without colors.

Styling and active source

Style semantic classes such as .msfe-code-line, .msfe-code-start, .msfe-code-body-start, .msfe-code-end and .msfe-code-indented; use HighlightStyle for code tokens. Let the runtime handle source-token reveal and line layout. Do not hide arbitrary .cm-line elements or move the body into another editable region.

Selecting a fence reveals active source. Composition, cross-block drag selection, copying and history remain native. Report geometry changes through the component measurement entry; see Projection layers.

Verification

Cover language changes and undo, empty/unknown languages, long code, unclosed fences, both fence characters, readonly mode, Tab indentation and theme changes. See Rendering API for exact language and component contracts.

MSFE · QuireKitYour Markdown source stays yours.