"Live Preview is the decoration engine's first job: render the look over the source, and reveal the raw markup where the cursor is."
Job One — Render the Look Over the Source
Live Preview is the most visible of the three jobs and, mechanically, the most direct: walk the Markdown syntax, and for each construct attach mark decorations that render its look, plus replace decorations where a markup token should disappear from view. A **fire** gets a mark that renders bold and replace decorations that hide its asterisks; a # heading gets marks that enlarge the text and dim the hash. Nothing is inserted or deleted — the source is exactly the Markdown you typed, wearing a rendered coat.
The Active-Line Reveal
The behavior that makes it feel alive is the active-line reveal. On lines your cursor isn't on, the markup is rendered (bold looks bold, the # is dimmed). On the line your cursor is on, the raw markup snaps back so you can edit it precisely — the text styling stays put; the hidden markup tokens return. The decoration set is recomputed with the cursor's line excluded from the "render" treatment. Read a clean document; edit exact source; the boundary follows your attention.
function buildLivePreview(state) {
const cursorLine = state.doc.lineAt(state.selection.main.head).number;
const marks = [];
for (const node of parseMarkdown(state.doc)) {
if (node.line === cursorLine) { marks.push(revealTokens(node)); continue; } // active line: styling stays, hidden markup tokens return
marks.push(renderMark(node)); // render the look everywhere else
}
return Decoration.set(marks, true);
}
Marks and Replacements, No Mutation
Every bit of Live Preview is decorations over unchanged source — marks that style, replace decorations that hide a token from view while it stays in the text. That's why it can coexist with everything else: turn it off and the document is byte-identical Markdown; turn it on and you've added a layer, not a model. It's also why this is the same engine as the next two jobs — voice underline and CMD+K are the same 'compute ranges, attach decorations' shape, just with different ranges and, for CMD+K, a widget instead of a mark. Job one is the gentle introduction to a mechanism the whole soul layer rides.