Improve the CodeMirror live-preview editor's list support:
- Bullets render as a • glyph (widget) instead of a literal -/*/+, with the
raw marker revealed on the cursor's line for editing. Ordered markers keep
their digits.
- List indentation (and the glyph) only apply once the marker is followed by
a space, so a marker mid-typing no longer indents then un-indents.
- New listKeymap.ts supplies Enter/Backspace/Tab/Shift-Tab for list items,
replacing @codemirror/lang-markdown's addKeymap (which turns lists "loose",
inserting a blank line between items — the "new item two lines below" bug):
- Enter: tight continuation with the next marker + trailing space,
auto-incrementing ordered lists; exits the list on an empty item.
- Tab/Shift-Tab: nest/outdent aligned to the parent's content column, with
ordered-list renumbering (reset to 1 on indent, continue parent on
outdent). Falls through to the default indent outside a list.
Headless tests cover the decoration builder and every list command (168
passing).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The depth styling used a single border-left with `double` for levels 2-3,
so level 2 rendered as two hairlines thinner than the level-1 solid bar,
level 3 as thicker lines, and levels past 3 had no class at all (depth was
capped at 3). A single border can only ever be one bar.
Pass the nesting depth to CSS as an inline `--quote-depth` variable and
paint the bars with a repeating gradient clipped (via background-size) to
exactly that many 3px bars. Every level now adds one more equal-width bar,
at any depth, with a dark-theme bar color.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address the "recognized but marker left raw" cases from the audit, plus
code syntax colors:
- Headings: hide the optional closing `##` sequence, not just the opening.
- Escapes / hard breaks (new escapeDecoration.ts): hide the backslash of
`\x` escapes and the `\` hard-line-break form, so the escaped character
renders literally.
- Reference links: hide the `[ref]` label (no URL child) and mute the
`[ref]: url` definition line via cm-link-def.
- Fenced code: hide the language label (CodeInfo) off-block so no stray
`js` floats above the box.
- Code syntax colors: add a scoped tok-* palette (light + data-theme dark)
so classHighlighter output is actually colored.
- Nested blockquotes: cm-quote-{depth} by `>` count per line, with
progressive indent/bar instead of flat styling.
Extends the headless builder tests with a case per fix (146 passing).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The cm-hr line decoration that draws the rule was applied unconditionally,
so placing the cursor on a horizontal rule showed both the rule and the raw
"---". Only style the line (and hide its glyphs) when the cursor is on a
different line; on the rule's own line, emit nothing so the raw "---" shows
for editing — matching how headings/blockquotes reveal their markers.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`.cm-hr` is a line decoration on a `.cm-line`, and it used `margin: 1em 0`
for the rule's vertical spacing. A vertical margin on a line is not part of
the box CodeMirror measures for its height map, so each `---` added ~32px of
height that CM6 didn't account for — shifting the caret/click mapping for
every line below the rule downward, compounding with each additional rule.
This read as "clicking anywhere puts the cursor a couple lines too low."
Use padding (which is inside the measured box) for the spacing and draw the
rule with a centered pseudo-element instead of a top border.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reserve the CodeMirror scroller's scrollbar gutter with
`scrollbar-gutter: stable` so content no longer shifts left when a
document first grows tall enough to need a vertical scrollbar.
Add a non-passive wheel listener to the tile tab strip so a vertical
mouse wheel scrolls it horizontally while the pointer is over it
(trackpad horizontal gestures still work via the dominant axis).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pressing Enter after a code fence left the new line outside the block
background until the closing ``` was typed. The per-line loop decremented
endLine whenever node.to sat at a line start — but @lezer/markdown only
puts node.to at a line start for an *unterminated* block (the newline just
typed), never for a closed one (whose node ends on the closing-fence line).
So the decrement only ever dropped the active editing line. Remove it: the
loop now paints every line the node spans, keeping the cursor's line — and
the closing ``` — inside the block, while closed blocks still stop at the
fence line and never paint the blank line after.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>