Root cause: CSS zoom on document.documentElement caused stale CodeMirror
measurements. Two issues:
1. Race condition: zoom was applied in useEffect (parent), but CodeMirror
was created in useEffect (child) — child effects run first, so CM
measured at zoom=1 before zoom was actually applied.
2. No re-measure on zoom change: CSS zoom changes don't trigger
ResizeObserver on descendant elements, so CodeMirror never updated
its cached scaleX/scaleY, line heights, or character widths.
Fix:
- Apply zoom synchronously during useState init (before child effects)
- Dispatch 'laputa-zoom-change' event when zoom changes
- Listen for this event in useCodeMirror and call view.requestMeasure()
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Long lines now wrap to the next visual line instead of scrolling
horizontally off-screen, matching expected behavior.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds line numbers, current line highlight, and syntax highlighting
(YAML frontmatter keys/values, --- delimiters, markdown headings).
Extracted useCodeMirror hook and frontmatterHighlight extension.
Preserves wikilink autocomplete, Cmd+S save, and Escape dismiss.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>