Skip to content

0.8.34

Choose a tag to compare

@github-actions github-actions released this 06 Sep 06:39
· 9 commits to develop since this release

Features

  • New commands "Copy Current Source Path" and "Copy Current Source Relative Path" — Copy the Markdown file that the focused preview is actually rendering, as a full filesystem path/URI or as a workspace-relative path. Following a link inside the preview leaves the preview and the editor resource it was opened from out of sync (the drift behind the stale breadcrumb in #2235), so VS Code's built-in Copy Path / Copy Relative Path can copy a different file than the one on screen — most visibly with "markdown-preview-enhanced.previewMode": "Previews Only", where the preview is the tab and no text editor is open. The commands read the source of the focused preview panel only and never guess: with no preview focused, with two previews active, or before a preview has rendered, they warn instead of copying, as does asking for a relative path outside the workspace. file: sources are copied as filesystem paths (Windows drive letters and UNC spellings preserved), while remote and virtual sources keep their scheme and authority. By @HappyOnigiri

Performance

All of the following ship with crossnote 0.9.34.

  • Cheaper preview updates while editing — every preview refresh used to copy the full rendered HTML (multi-MB on large documents) into a React state variable, re-rendering the entire preview component tree on each debounced keystroke; nothing ever read that value, so the copy is gone and updates skip the redundant re-render.
  • Prism syntax highlighting and KaTeX formulas are cached across preview updates — every refresh used to re-highlight every code block and re-render every formula from scratch, so editing a code- or math-heavy note re-processed all of its unchanged blocks on each keystroke. Both renderers now keep a bounded, content-keyed cache (Prism: 200 blocks up to 64 KB; KaTeX: 1000 formulas up to 16 KB, keyed on the KaTeX configuration so config changes still take effect) with byte-identical output. On a 195 KB document with 240 code blocks and 360 formulas, a typical edit-keystroke render drops from ~540 ms to ~460 ms.
  • The in-preview editor and the sidebar TOC do less repeated work per render — the editor's jump-to-line effect no longer accumulates a new decoration collection on every preview update (it reuses one), its minimap is disabled and it no longer scrolls past the last line; the sidebar TOC reuses a single markdown-it instance per notebook instead of building a fresh 18-plugin instance for every render.

Bug fixes

  • "Open In-preview Editor" works offline — right-clicking the preview and choosing Edit Markdown → Open In-preview Editor mounted the editor shell but loaded the monaco editor itself at runtime from cdn.jsdelivr.net, so offline or firewalled setups sat on "Loading editor..." forever and the menu item looked like it did nothing (#2164 reported by @CVStratACGrant). The editor is now bundled locally (monaco-editor upgraded 0.43.0 → 0.55.1) and opens instantly with zero network requests (crossnote 0.9.34).
  • "Open In-preview Editor" no longer silently does nothing — the menu item attached the editor to the first .final-line element on the page and gave up when none was visibly usable: while a render was in flight, the hidden preview copy also held a .final-line element, so a click there portaled the editor into an invisible element that the next render deleted, and in zen mode (or a file with no source map) no anchor existed at all. The lookup is now scoped to the real preview container, and when no anchor exists a fresh one is appended at the end of the preview so the editor always opens; the menu item is hidden in zen mode, where the in-preview editor cannot be shown (crossnote 0.9.34).
  • Fix the preview's file watcher deleting a freshly recreated Markdown file (data loss) — when Git removed and then recreated a Markdown file during a branch checkout, the watcher's delayed deletion notification could delete the freshly recreated replacement, surfacing as unstaged deletions in git status. The underlying deleteNote(path, alreadyDeleted) call had its flag wired backwards: true — which the watcher passes for every deletion event — guaranteed an unlink() ran instead of skipping it. The watcher no longer deletes a file that exists at the path; internal bookkeeping still runs when a note really is gone (crossnote#481 reported by @Josh-Cena; fixed in crossnote 0.9.34).