Skip to content

Find in the markdown preview and in any diff - #82

Merged
afitzgerald merged 2 commits into
mainfrom
alan/md-find
Sep 7, 2026
Merged

afitzgerald merged 2 commits into
mainfrom
alan/md-find

Conversation

@afitzgerald

Copy link
Copy Markdown
Owner

What

⌘F / Ctrl+F (rebindable, in the Edit menu) dispatches on whatever the diff pane is showing:

  • Rendered markdown preview — the one view with no editor behind it, so it gets its own find bar: case-insensitive substring search, n/m counter, Enter / ⇧Enter to cycle with wrap, Esc to close. Matches are painted with the CSS Custom Highlight API (Ranges, no DOM mutation), so the rendered document and its diff tinting stay exactly as rendered, and clearing is one delete() per highlight. Re-runs whenever the pane re-renders (mode switch, file switch, live edit) since the old Ranges point at nodes that are gone.
  • Any diff / conflict editor — hands over to Monaco's own find widget. The global keydown handler swallows the key before Monaco sees it, so the handover is explicit.

Mermaid fix (separate commit)

Several of mermaid's bundled deps ship classic UMD wrappers that test typeof define === 'function' && define.amd first. Monaco's AMD loader already owns a global define by the time markdown.ts lazy-loads renderer/mermaid.js, so they registered as anonymous modules and the bundle died with Can only have one anonymous define call per script file — every mermaid fence fell back to raw source in the shipped app, not just in tests. The bundle is now wrapped in (function(define){ … })().

UI test harness

Three things kept node test/ui.test.js from running at all:

  • the navigator.platform pin (which gives the suite Mod = Ctrl semantics) was defined on the instance, where current Chromium makes it non-configurable — it threw Cannot redefine property and silently never applied. Now on Navigator.prototype.
  • #diff-count renders "2 differences (+2 −2)", but two assertions still compared against the bare "2 differences".
  • the Chromium path fell back to a sandbox-only location; it now uses Playwright's own downloaded browser when that path is absent (DIFFIER_CHROMIUM still overrides).

Known limitation

Markdown matches don't span inline element boundaries — a query crossing **bold** won't hit. Flagged in a ponytail: comment; needs a concatenated-text offset map if it ever matters.

Testing

yarn typecheck, yarn test, and node test/ui.test.js all pass (7 new UI assertions cover the Monaco handover, the bar opening + focus, the counter, Enter/⇧Enter wrap, the no-match state, and Esc clearing the highlights).

Several of mermaid's bundled dependencies ship classic UMD wrappers whose
first branch is `typeof define === 'function' && define.amd`. Monaco's AMD
loader has already installed a global `define` by the time markdown.ts
lazy-loads renderer/mermaid.js, so those deps registered as anonymous
modules and the whole bundle died with "Can only have one anonymous define
call per script file" — every mermaid fence fell back to raw source, in the
shipped app as well as the UI test.

Wrap the bundle in `(function(define){ … })()` so `define` is undefined
inside it and the UMD wrappers take their CommonJS branch instead.
Mod+F (rebindable, in the Edit menu) dispatches on the active pane: the
rendered markdown preview is the one view with no editor behind it, so it
gets its own find bar — case-insensitive substring search painted with the
CSS Custom Highlight API, which leaves the rendered document and its diff
tinting untouched. Every editor view hands over to Monaco's own find widget
instead; the global keydown handler swallows the key before Monaco sees it,
so the handover has to be explicit.

Also fixes three things in the UI test that kept it from running:

- the navigator.platform pin (Mod = Ctrl semantics) was defined on the
  instance, where current Chromium makes it non-configurable — it threw and
  silently never applied. Define it on Navigator.prototype.
- #diff-count renders "2 differences (+2 -2)"; two assertions still
  compared against the bare "2 differences".
- the Chromium path fell back to a sandbox-only location, so the suite
  couldn't launch on a dev machine. Use Playwright's own browser when that
  path is absent.
@afitzgerald
afitzgerald merged commit 11181b5 into main Sep 7, 2026
1 check passed
@afitzgerald
afitzgerald deleted the alan/md-find branch September 7, 2026 18:34
afitzgerald added a commit that referenced this pull request Sep 30, 2026
Find in the markdown preview and in any diff
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant