Skip to content

Feat/markdown anchor sync plan#216

Merged
saeedvaziry merged 81 commits intomuxy-app:mainfrom
helipillo:feat/markdown-anchor-sync-plan
Apr 25, 2026
Merged

Feat/markdown anchor sync plan#216
saeedvaziry merged 81 commits intomuxy-app:mainfrom
helipillo:feat/markdown-anchor-sync-plan

Conversation

@helipillo
Copy link
Copy Markdown
Contributor

@helipillo helipillo commented Apr 23, 2026

Summary

Changes

Added markdown (full, split, code view).
Added initial mermaid.js support for diagram rendering.
Anchor scroll sync for more accurate scrolling

How to use:

cmd + P => open a .md file and 🪄

Testing

  • [ x] scripts/checks.sh passes
  • [ x] Tested manually on macOS
  • [x ] Trust me bro

Screenshots

Screenshot 2026-04-20 at 23 24 01 Screenshot 2026-04-20 at 23 27 39

- Add MarkdownTabState and MarkdownTabView for markdown file handling
- Add Mermaid diagram rendering with native and JS fallback support
- Add EditorMarkdownViewMode for code/preview/split views
- Add markdown file detection and auto-preview mode
- Add comprehensive Mermaid normalizer tests
@helipillo helipillo marked this pull request as draft April 23, 2026 21:30
@helipillo
Copy link
Copy Markdown
Contributor Author

Closes #196

@helipillo helipillo marked this pull request as ready for review April 24, 2026 05:54
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a Markdown viewing experience to Muxy tabs (preview/code/split), including Mermaid diagram rendering and anchor-based scroll syncing between the editor and preview.

Changes:

  • Introduces a Markdown renderer (Marked + Highlight.js) with Mermaid.js diagram support and DOM sanitization.
  • Implements anchor parsing + editor/preview coordination to sync scroll positions in split view.
  • Updates the editor UI/state to support Markdown view modes and scroll-sync controls, with accompanying unit tests.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
Tests/MuxyTests/Models/ViewportStateTests.swift Updates expectations for document height now that padding is included.
Tests/MuxyTests/Models/MermaidCodeBlockNormalizerTests.swift Adds tests for Mermaid code block normalization and HTML template contracts.
Tests/MuxyTests/Models/MarkdownSyncCoordinatorTests.swift Adds tests for editor↔preview sync and relayout behavior.
Tests/MuxyTests/Models/MarkdownEditorAnchorMapperTests.swift Adds tests for mapping editor scroll position to an active anchor/progress snapshot.
Tests/MuxyTests/Models/MarkdownAnchorParserTests.swift Adds tests for parsing Markdown into stable, inclusive anchor ranges.
Tests/MuxyTests/Models/EditorTabStateTests.swift Ensures Markdown tabs default to preview mode with scroll sync enabled.
Muxy/Views/Markdown/MarkdownTabView.swift Adds WKWebView-based Markdown preview plumbing, scroll observation, and sync-point reporting.
Muxy/Views/Markdown/MarkdownPreviewAnchorGeometryBridge.swift Adds JS bridge to measure DOM anchor geometry and report it to Swift for more accurate sync.
Muxy/Views/Editor/EditorPane.swift Adds Markdown view mode switching (code/preview/split) and integrates preview into the editor pane.
Muxy/Views/Editor/CodeEditorRepresentable.swift Adds editor-side anchor snapshotting + scroll metric publishing and drives preview refresh/sync.
Muxy/Models/ViewportState.swift Adjusts line height calculation and includes document vertical padding in total height.
Muxy/Models/MermaidCodeBlockNormalizer.swift Normalizes Mermaid labels by converting in-label newlines to <br/>.
Muxy/Models/MarkdownSyncCoordinator.swift Coordinates which side is the scroll driver and suppresses echo updates.
Muxy/Models/MarkdownSyncAnchor.swift Defines anchor kinds and the anchor model used for syncing.
Muxy/Models/MarkdownRenderer.swift Provides the HTML/JS/CSS template for Markdown rendering, sanitization, and Mermaid rendering.
Muxy/Models/MarkdownPreviewAnchorGeometry.swift Adds a model for preview DOM anchor geometry snapshots.
Muxy/Models/MarkdownEditorAnchorSyncSnapshot.swift Adds a model representing the editor’s active anchor + local progress.
Muxy/Models/MarkdownEditorAnchorMapper.swift Implements logic to choose an active anchor and compute progress for a focused editor line.
Muxy/Models/MarkdownAnchorParser.swift Implements a Swift-side Markdown block parser for building sync anchors.
Muxy/Models/EditorTabState.swift Adds Markdown state (view mode, scroll sync, driver tracking, caches) to editor tabs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Muxy/Models/MarkdownRenderer.swift Outdated
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>\(title)</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-..." crossorigin="anonymous"></script>
Comment on lines +559 to +563
guard message.name == MarkdownWebBridge.scrollHandlerName,
scrollSyncEnabled,
!isNavigationInFlight,
let payload = message.body as? [String: Any],
let scrollTopNumber = payload["scrollTop"] as? NSNumber
Comment on lines +302 to +306
const root = document.documentElement;
if (!root) return;
root.classList.toggle('muxy-hide-content-scrollbar', \(
hideScrollbar
));
Comment on lines +293 to +294
textView.setSelectedRange(NSRange(location: 0, length: 0))
textView.scrollRangeToVisible(NSRange(location: 0, length: 0))
}

func previewDidRelayout() -> Output {
Output()
Comment thread Muxy/Models/EditorTabState.swift Outdated

guard abs(targetY - currentY) > 0.1 else { return }

markdownScrollDriver = .editor
Comment on lines +68 to +72
if bracketDepth > 0,
ch.isNewline
{
output.append("<br/>")
cursor = next
Comment on lines +71 to +77
let markdown = """
```mermaid
graph TD
A[Hello\\nWorld] --> B
```
"""

Comment on lines +97 to +101
let markdown = """
# Title

Paragraph

Comment on lines +12 to +17
let line = lines[index]
let trimmed = line.trimmingCharacters(in: .whitespaces)

if trimmed.isEmpty {
index += 1
continue
@saeedvaziry saeedvaziry merged commit 73fd31a into muxy-app:main Apr 25, 2026
1 check passed
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.

3 participants