Conversation
651ba39 to
8bbe8bc
Compare
🔍 Multi-Reviewer Code Review — PR #507 (Re-review)CodeMirror 6 Side-by-Side Diff Editor
Previous Findings — Status🔴 #1 — Fire-and-forget
|
60b10f9 to
29535bf
Compare
Integrates CodeMirror 6 as an alternative diff viewer alongside the existing table-based DiffView. Each file in a diff now shows Table/Editor toggle buttons in the file header. Components: - CodeMirror 6 bundle (660KB minified) with C#, JS, CSS, HTML, JSON, XML, Python, Markdown language support - Custom dark theme matching PolyPilot's color palette - MergeView for side-by-side diff with collapsed unchanged regions - Line numbers, bracket matching, fold gutters, Ctrl+F search - DiffParser.ReconstructOriginal/Modified for extracting both sides Also fixes pre-existing ChangeModelAsync test compilation errors (missing named parameter for reasoningEffort). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Use @codemirror/legacy-modes pre-built csharp export instead of custom clike config (simpler, maintained upstream) - Add shell/bash/zsh syntax highlighting - Move CodeMirror DOM styles to global app.css (Blazor scoped CSS can't reach CodeMirror's dynamically created elements) - Hide merge-view revert buttons (read-only view) - Add merge-spacer gutter styling Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace async void SetViewMode with sync method + _pendingEditorInit set. CodeMirror initialization now happens in OnAfterRenderAsync (guaranteed DOM availability) instead of Task.Delay(50) (race-prone). - Add 4 edge case tests: deleted file, empty hunks, multi-hunk, context-only diffs for ReconstructOriginal/ReconstructModified. - Tests: 3136/3136 pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…-hunk gaps - #1 (CRITICAL): Snapshot CM instance IDs before clearing dictionaries in OnParametersSet, preventing InvalidOperationException from enumerator invalidation and ensuring all JS instances are properly disposed - #2 (CRITICAL): Add generation counter to InitCodeMirrorForFile; stale completions (from a previous diff) are detected and disposed immediately - #3: Double-init guard — skip InitCodeMirrorForFile if _cmInstances already contains an entry for the fileIdx - #4: DisposeCmInstance replaced with snapshot-then-remove pattern; _pendingEditorInit cleared on Table toggle to prevent stale inits - #5: ReconstructOriginal/Modified now insert blank placeholder lines for inter-hunk gaps to preserve correct line numbering in CM MergeView - #6: Add SRI integrity hash (sha384) to codemirror-bundle.js script tag - #7: Replace O(n²) Files.IndexOf(file) with indexed for loop - #8: All catch blocks now log to Console.Error with [DiffView] prefix - NEW-1: Post-loop Clear() race eliminated — DisposeJsInstancesByIdAsync works on snapshotted arrays, never touches _cmInstances dictionary - Added _disposed guard to DisposeAsync for safe double-dispose Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add thorough test coverage for the CodeMirror diff editor feature: - Inter-hunk gap placeholder tests: verify ReconstructOriginal/Modified insert correct blank lines between distant hunks (review fix #5) - PairLines side-by-side pairing: context-only, matched pairs, uneven remove/add counts, pure additions/deletions, mixed interleaving, empty hunks, multiple independent change blocks - Multi-file mixed types: new + deleted + modified + renamed in one diff - Edge cases: CRLF handling, empty added/removed lines, hunk headers with and without function names, line number sequencing, insertions causing offset, multiple hunks resetting line numbers - ShouldRenderDiffView integration: Read/view tool filtering, null tool - IsPlainTextViewTool case insensitivity - Reconstruction round-trip integrity: single-line, multi-hunk gaps with exact line counts, gap adjustment for added lines - Real-world patterns: binary file notices, index lines, three-hunk diffs, hunk headers without comma Total DiffParser tests: 67 (28 existing + 39 new), all passing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
30d2560 to
48ea3a5
Compare
ShouldRenderDiffView already validates the content is a parseable unified diff. The extra Parse + Count > 0 guard in the render body was always true when _hasDiffOutput was set, making the else branch (fallback <pre>) dead code. DiffView internally parses via OnParametersSet, so the removed call was a wasted parse per render. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CodeMirror 6 Diff Editor
Adds a side-by-side diff editor using CodeMirror 6, integrated into the existing DiffView component.
Features
Technical Details
codemirror-src/via esbuild (reproducible)DiffParser.ReconstructOriginal/ReconstructModifiedextract both sides from parsed diffsChangeModelAsynctest compilation errors (missing named param)Verified