Add markdown preview type and per result preview visibility control
What
The preview pane can now render formatted markdown with syntax-highlighted code blocks. Plugins opt in by setting Result.Preview.ContentType to Markdown and providing a markdown description.
A new Result.PreviewVisibility lets plugins control whether the preview pane shows:
- Optional (default) - respects the user's Always Preview setting and preference from the preview toggle
- Always - forces the pane open so users see the preview without manual toggling
- Never - hides the pane for results with nothing useful to preview
And PreviewContentType controls how the preview is rendered:
- ImageWithText (default) - the classic preview: image above, plain text below
- Markdown - formatted markdown with headings, links, and syntax-highlighted code blocks
Existing plugins are unaffected as all defaults match current behavior.
Why
Plugins that produce rich text (AI assistants, documentation/snippet/note search, dictionary-style lookups) currently have to cram everything into plain SubTitle/Description text. This lets them opt into a proper rendered preview per result without affecting any existing plugin: every current result keeps the default text behavior.
The visibility controls exist so plugins can make sure users see the preview when it matters, without relying on them to manually toggle it or change settings. Results that exist primarily for their rendered content (like markdown) always show their preview; results with nothing useful to preview can hide it.
Details
Markdown rendering — Built on MdXaml (already a dependency) with code blocks highlighted through AvalonEdit (the one new package). A CodeHighlightTheme setting under Settings > Theme lets users pick a syntax theme or use Auto to match the app colour scheme. Bundled themes include VS Code Dark+, VS Code Light, One Dark, and Catppuccin Macchiato.
JSON-RPC — Both contentType and previewVisibility are added as keys on the result object (with contentType nested in preview):
{ "preview": { "contentType": "markdown", "description": "**hello**" }, "previewVisibility": "always" }
Themed horizontal scrollbars — Code blocks need horizontal scrolling, so horizontal scrollbar styles were added to Base.xaml and every built-in theme. Minimum thickness is 5px since horizontal bars are harder to click and have no scrollwheel alternative.
New dependency — AvalonEdit 6.3.0.90.
Tests
Full suite passes (256/256), including new coverage: pane gating rules (MainViewModelPreviewTest), markdown control behavior (PreviewMarkdownScrollViewerTest, PreviewMarkdownStyleTest), and JSON-RPC contentType deserialization (JsonRPCPluginTest).
Demo
Slightly outdated but still a good demonstration
📹
TODO
- Update https://github.com/Flow-Launcher/flow-launcher.github.io theme builder with the new changes
- Update documentation on markdown usage
Summary by cubic
Adds a markdown preview pane with syntax-highlighted code, per-result preview visibility (optional/never/always), and a Code Highlight Theme setting with Auto that follows the app theme. The pane won’t open without a selected result; existing results default to imageWithText.
Summary of changes
- Changed
- Preview visibility: single toggle preference
_previewPreferenceFromToggle; results can force show/hide viaPreviewVisibility; forced previews restore on reopen; internal preview is no longer auto-hidden on window hide; toggle always affects the current result; no selection keeps the pane hidden; fixed startup so preview doesn’t show beforeResetPreviewAsyncruns. - Preview flow:
UpdatePreviewAsyncdelegates toShowPreviewAsync; all preview calls awaited with try/catch;Resetcloses external before opening internal; navigation still respects plugin visibility. - Input/UX: only code‑block navigation keys are captured; while a code block is focused the window key handler is skipped; hyperlinks open with improved error handling; preview height bound to the result list.
- Styling: themed horizontal scrollbars with overrideable
HorizontalScrollBarStyle/HorizontalThumbStyle; explicit code‑block scrollbar template avoids last‑line overlap; subtler thumbs; hyperlink underlines persist on hover/focus; preview and code‑block scrollbars themed across built‑in themes. - Naming/strings: default preview type renamed to
imageWithText;PreviewVisibility.DefaulttoOptional; tooltips and README updated;Result.Previewnow a new instance per result and cloning deep‑copies to avoid shared state.
- Preview visibility: single toggle preference
- Added
Result.Preview.ContentType(imageWithText,markdown) andResult.PreviewVisibility(optional,never,always) with JSON‑RPC wire values.PreviewMarkdownScrollViewerusingMdXaml+AvalonEdit, per‑editor themed colorizer, language aliases, themed code‑block scrollbars, andIsCodeBlockFocused.Settings.CodeHighlightTheme(default "Auto") with a Theme dropdown; Auto tracks light/dark and updates on theme change and startup. Dependency:AvalonEdit6.3.0.90.
- Removed
- Old hidden preview content type (use
PreviewVisibility.Never),HidePreviewPane/ForcePreviewPanewrappers, and theIsSafeSchemehelper (allow only http/https). - Automatic hide of the internal preview on window hide.
- Old hidden preview content type (use
- Memory
- Small increase from
AvalonEdit, per‑editor colorizers, and style resources; editors are created on demand.
- Small increase from
- Security
- Low risk: markdown renders to a FlowDocument (no scripts/autonavigation); links restricted to http/https; code blocks are read‑only.
- Unit tests
- Added:
MainViewModelPreviewTest,PreviewMarkdownScrollViewerTest,PreviewMarkdownStyleTest,CodeHighlightThemeTest, andJsonRPCPluginTest. Tests cover toggle behavior, startup/reset edge cases, no‑selection guard, restore on reopen, JSON‑RPC content types, and theme auto‑resolve.
- Added:
Release Note
You can preview markdown with clickable links and highlighted code, choose a code theme, and plugins can auto‑show or hide previews for their results.