Skip to content

Add bidirectional scroll sync (preview to editor)#261

Merged
schuyler merged 2 commits intomainfrom
claude/issue-254-KywFB
Jan 8, 2026
Merged

Add bidirectional scroll sync (preview to editor)#261
schuyler merged 2 commits intomainfrom
claude/issue-254-KywFB

Conversation

@schuyler
Copy link
Copy Markdown
Owner

@schuyler schuyler commented Jan 8, 2026

Summary

Implements preview→editor scroll synchronization to complement the existing editor→preview sync (Issue #39). When the user scrolls the preview pane, the editor now automatically scrolls to the corresponding position.

Changes:

  • Add syncScrollersReverse method mirroring the existing syncScrollers algorithm
  • Add previewBoundsDidChange: handler to trigger reverse sync on preview scroll
  • Add shouldHandlePreviewBoundsChange flag for loop prevention
  • Register NSViewBoundsDidChangeNotification for preview scroll view
  • Add 8 unit tests for the new functionality

Implementation details:

  • Uses same reference point matching algorithm (headers/images) as editor→preview
  • Real-time sync during scrolling via NSViewBoundsDidChangeNotification
  • Two-flag system prevents infinite sync loops
  • Controlled by existing editorSyncScrolling preference (no new toggle)

Related Issue

Related to #258

Manual Testing Plan

Prerequisites

  • Build and run MacDown 3000
  • Ensure editorSyncScrolling preference is enabled (default)

Key Test Scenarios

  1. Basic sync: Scroll preview pane → verify editor follows
  2. Bidirectional: Alternate scrolling between panes → verify no loops
  3. Header matching: Position headers at various scroll positions → verify alignment
  4. Edge cases: Test top/bottom of document, empty documents, documents without headers
  5. Preference toggle: Disable editorSyncScrolling → verify sync stops in both directions

Review Notes

  • Architecture (Groucho): Uses symmetric design mirroring existing scroll sync
  • Code review (Chico): Implementation approved, minor style fix applied
  • Documentation (Harpo): Updated test coverage plan and xcuitest docs
  • Testing (Zeppo): Comprehensive 14-scenario manual testing plan provided

claude added 2 commits January 8, 2026 18:36
Implements preview→editor scroll synchronization to complement the existing
editor→preview sync. When the user scrolls the preview pane, the editor
now scrolls to the corresponding position using the same reference point
matching algorithm.

Changes:
- Add shouldHandlePreviewBoundsChange property for loop prevention
- Register NSViewBoundsDidChangeNotification for preview scroll view
- Add previewBoundsDidChange: handler to trigger reverse sync
- Implement syncScrollersReverse method mirroring syncScrollers algorithm
- Update syncScrollers to set preview flag before scrolling
- Add 8 unit tests for reverse sync functionality

The implementation uses the same header/image reference point matching
with tapering at document edges for smooth scrolling behavior.

Related to #258
- Fix spacing in if statement for consistency (line 1271)
- Update test_coverage_improvement_plan.md with Issue #258 tests
- Update xcuitest.md with bidirectional scroll sync reference

Related to #258
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 8, 2026

Code Coverage Report

Current Coverage: 51.70%

Coverage Details (Summary)
Name                                                                                                                                   Coverage            
-------------------------------------------------------------------------------------------------------------------------------------- ------------------- 
MASPreferences.bundle                                                                                                                  0.00% (0/0)         
MacDown 3000.app                                                                                                                       58.04% (7343/12652) 
    /Users/runner/work/macdown3000/macdown3000/Dependency/peg-markdown-highlight/HGMarkdownHighlighter.m                               81.75% (457/559)    
        styleparsing_error_callback                                                                                                    90.00% (9/10)       
        -[HGMarkdownHighlighter init]                                                                                                  92.86% (13/14)      
        -[HGMarkdownHighlighter initWithTextView:]                                                                                     83.33% (5/6)        
        -[HGMarkdownHighlighter initWithTextView:waitInterval:]                                                                        83.33% (5/6)        
        -[HGMarkdownHighlighter initWithTextView:waitInterval:styles:]                                                                 83.33% (5/6)        
        -[HGMarkdownHighlighter parseText:]                                                                                            100.00% (9/9)       
        -[HGMarkdownHighlighter convertOffsets:text:]                                                                                  26.19% (11/42)      
        -[HGMarkdownHighlighter requestParsing]                                                                                        100.00% (15/15)     
        __39-[HGMarkdownHighlighter requestParsing]_block_invoke                                                                       100.00% (12/12)     
        __39-[HGMarkdownHighlighter requestParsing]_block_invoke.55                                                                    100.00% (3/3)       
        __39-[HGMarkdownHighlighter requestParsing]_block_invoke.67                                                                    100.00% (4/4)       
        -[HGMarkdownHighlighter getClearFontTraitMask:]                                                                                88.89% (16/18)      
        -[HGMarkdownHighlighter clearHighlightingForRange:]                                                                            100.00% (31/31)     
        __51-[HGMarkdownHighlighter clearHighlightingForRange:]_block_invoke                                                           100.00% (8/8)       
        -[HGMarkdownHighlighter readClearTextStylesFromTextView]                                                                       100.00% (17/17)     
        -[HGMarkdownHighlighter applyHighlighting:withRange:]                                                                          74.67% (56/75)      
        __53-[HGMarkdownHighlighter applyHighlighting:withRange:]_block_invoke                                                         92.31% (12/13)      
        -[HGMarkdownHighlighter applyVisibleRangeHighlighting]                                                                         100.00% (16/16)     
        -[HGMarkdownHighlighter clearHighlighting]                                                                                     100.00% (3/3)       
        -[HGMarkdownHighlighter cacheElementList:]                                                                                     100.00% (6/6)       
        -[HGMarkdownHighlighter clearElementsCache]                                                                                    100.00% (2/2)       
        -[HGMarkdownHighlighter textViewTextDidChange:]                                                                                0.00% (0/11)        
        __47-[HGMarkdownHighlighter textViewTextDidChange:]_block_invoke                                                               0.00% (0/3)         
        -[HGMarkdownHighlighter textViewDidScroll:]                                                                                    27.27% (3/11)       
        __43-[HGMarkdownHighlighter textViewDidScroll:]_block_invoke                                                                   0.00% (0/6)         
        __43-[HGMarkdownHighlighter textViewDidScroll:]_block_invoke_2                                                                 0.00% (0/3)         
        -[HGMarkdownHighlighter getDefaultStyles]                                                                                      100.00% (27/27)     
        -[HGMarkdownHighlighter applyStyleDependenciesToTargetTextView]                                                                92.86% (13/14)      
        -[HGMarkdownHighlighter setStyles:]                                                                                            100.00% (8/8)       
        -[HGMarkdownHighlighter getDefaultSelectedTextAttributes]                                                                      100.00% (7/7)       
        -[HGMarkdownHighlighter handleStyleParsingError:]                                                                              100.00% (12/12)     
        -[HGMarkdownHighlighter applyStylesFromStylesheet:withErrorHandler:]                                                           86.05% (74/86)      
        -[HGMarkdownHighlighter setTargetTextView:]                                                                                    100.00% (7/7)       
        -[HGMarkdownHighlighter parseAndHighlightNow]                                                                                  100.00% (3/3)       
        -[HGMarkdownHighlighter highlightNow]                                                                                          100.00% (3/3)       
        -[HGMarkdownHighlighter activate]                                                                                              100.00% (24/24)     
        -[HGMarkdownHighlighter deactivate]                                                                                            100.00% (18/18)     
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Extension/NSColor+HTML.m                                                   94.05% (332/353)    
        +[NSColor(HTML) colorWithHexString:]                                                                                           94.12% (16/17)      
        +[NSColor(HTML) colorWithHTMLName:]                                                                                            89.13% (164/184)    
        __35+[NSColor(HTML) colorWithHTMLName:]_block_invoke                                                                           100.00% (152/152)   
    /Users/runner/work/macdown3000/macdown3000/Dependency/peg-markdown-highlight/HGMarkdownHighlightingStyle.m                         87.69% (57/65)      
        +[HGMarkdownHighlightingStyle colorFromARGBColor:]                                                                             100.00% (6/6)       
        -[HGMarkdownHighlightingStyle initWithType:attributesToAdd:toRemove:fontTraitsToAdd:]                                          88.89% (8/9)        
        -[HGMarkdownHighlightingStyle initWithStyleAttributes:baseFont:]                                                               86.00% (43/50)      

... (2401 more lines truncated)

📊 **Full coverage report available in workflow artifacts**

@schuyler schuyler merged commit e00cbd1 into main Jan 8, 2026
9 checks 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.

2 participants