Skip to content

Fix smart quote substitution causing unwanted characters#289

Merged
schuyler merged 2 commits intomainfrom
claude/resolve-issue-285-d4w7g
Jan 24, 2026
Merged

Fix smart quote substitution causing unwanted characters#289
schuyler merged 2 commits intomainfrom
claude/resolve-issue-285-d4w7g

Conversation

@schuyler
Copy link
Copy Markdown
Owner

@schuyler schuyler commented Jan 24, 2026

Summary

Fixes the smart quote substitution bug where typing a closing quotation mark would insert extra unwanted characters, and using undo (Cmd+Z) would make it worse.

Root cause: The custom matching-pair autocomplete code was conflicting with macOS's built-in smart quote substitution. When smart quotes were enabled, the custom code tried to "mimic" smart quotes but only handled opening quotes, not closing quotes.

Fix: When smart quote substitution is enabled and the user types " or ', the custom code now returns early and defers to macOS's native smart quote handling. This eliminates the conflict.

Related Issue

Related to #285

Changes

  • NSTextView+Autocomplete.m: Added early return for quote characters when smart quotes are enabled
  • MPSmartQuoteTests.m: New test file with 11 test cases covering the fix
  • test_coverage_improvement_plan.md: Updated to include new test file

Manual Testing Plan

Setup

  1. Build the application from this branch
  2. Launch MacDown 3000
  3. Enable smart quotes: Edit > Substitutions > Smart Quotes
  4. Create a new document

Key Test Scenarios

Scenario Steps Expected Result
Basic smart quotes Type "hello" Opening and closing typographic quotes, no extra characters
Undo behavior Type "test", then Cmd+Z repeatedly Clean undo, no character corruption
Multiple quotes Type She said "hello" and "goodbye" All quote pairs work correctly
Single quotes Type It's a 'test' Apostrophes and single quotes handled correctly
Smart quotes OFF Disable smart quotes, type " Matching pair "" inserted (regression test)
Brackets still work With smart quotes ON, type (, [, { Matching pairs still inserted

Edge Cases

  • Quote at document start
  • Quote at end of line
  • Rapid quote typing
  • Different locale quote styles (German „...", French «...»)

When smart quote substitution is enabled, defer handling of quote
characters to macOS instead of using custom matching-pair logic.
This prevents the conflict that was causing extra characters to be
inserted and corrupting the undo stack.

Related to #285
- Fix header comment in MPSmartQuoteTests.m to use 'MacDown 3000'
- Update test_coverage_improvement_plan.md to include new test file

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

github-actions bot commented Jan 24, 2026

Code Coverage Report

Current Coverage: 53.19%

Coverage Details (Summary)
Name                                                                                                                                   Coverage            
-------------------------------------------------------------------------------------------------------------------------------------- ------------------- 
MASPreferences.bundle                                                                                                                  0.00% (0/0)         
MacDown 3000.app                                                                                                                       59.46% (7706/12960) 
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Preferences/MPHtmlPreferencesViewController.m                              0.00% (0/87)        
        MPPrismDefaultThemeName                                                                                                        0.00% (0/2)         
        -[MPHtmlPreferencesViewController viewIdentifier]                                                                              0.00% (0/3)         
        -[MPHtmlPreferencesViewController toolbarItemImage]                                                                            0.00% (0/3)         
        -[MPHtmlPreferencesViewController toolbarItemLabel]                                                                            0.00% (0/2)         
        -[MPHtmlPreferencesViewController viewWillAppear]                                                                              0.00% (0/4)         
        -[MPHtmlPreferencesViewController changeStylesheet:]                                                                           0.00% (0/7)         
        -[MPHtmlPreferencesViewController changeHighlightingTheme:]                                                                    0.00% (0/7)         
        -[MPHtmlPreferencesViewController invokeStylesheetFunction:]                                                                   0.00% (0/23)        
        -[MPHtmlPreferencesViewController loadStylesheets]                                                                             0.00% (0/13)        
        -[MPHtmlPreferencesViewController loadHighlightingThemes]                                                                      0.00% (0/23)        
    /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)      
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Utility/FileURLInlining.m                                                  22.92% (22/96)      
        +[FileURLInlining inlineFromIterable:]                                                                                         0.00% (0/11)        
        +[FileURLInlining withURL:]                                                                                                    0.00% (0/4)         
        -[FileURLInlining inlineContent]                                                                                               0.00% (0/9)         
        -[FileURLInlining initWithURL:]                                                                                                0.00% (0/7)         
        -[FileURLInlining imageContent]                                                                                                0.00% (0/12)        
        +[FileURLInlining mimeTypeForFilePath:]                                                                                        100.00% (22/22)     
        -[FileURLInlining clippingContent]                                                                                             0.00% (0/4)         
        +[FileURLInlining isTextClippingAtPath:]                                                                                       0.00% (0/12)        
        +[FileURLInlining textContentFromClipping:]                                                                                    0.00% (0/15)        
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Extension/hoedown_html_patch.c                                             86.47% (115/133)    
        hoedown_patch_reset_checkbox_index                                                                                             100.00% (3/3)       
        hoedown_patch_get_checkbox_index                                                                                               0.00% (0/3)         
        hoedown_patch_render_blockcode                                                                                                 89.09% (49/55)      
        hoedown_patch_render_listitem                                                                                                  100.00% (44/44)     
        hoedown_patch_render_toc_header                                                                                                67.86% (19/28)      
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Application/MPMainController.m                                             42.91% (106/247)    
        MPOpenBundledFile                                                                                                              96.67% (29/30)      
        __MPOpenBundledFile_block_invoke                                                                                               85.71% (6/7)        
        treat                                                                                                                          20.00% (6/30)       
        __treat_block_invoke                                                                                                           0.00% (0/3)         
        -[MPMainController applicationDidFinishLaunching:]                                                                             100.00% (6/6)       
        -[MPMainController openUrlSchemeAppleEvent:withReplyEvent:]                                                                    0.00% (0/45)        
        __59-[MPMainController openUrlSchemeAppleEvent:withReplyEvent:]_block_invoke                                                   0.00% (0/7)         
        -[MPMainController valueForKey:fromQueryItems:]                                                                                0.00% (0/5)         
        -[MPMainController preferences]                                                                                                100.00% (3/3)       
        -[MPMainController preferencesWindowController]                                                                                0.00% (0/18)        

... (2490 more lines truncated)

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

@schuyler schuyler merged commit 8923392 into main Jan 24, 2026
10 checks passed
schuyler pushed a commit that referenced this pull request Jan 24, 2026
Comprehensive testing plan covering all changes since v3000.0.3:
- Smart quote substitution fix (#289)
- Editor jumping when typing at end of long documents (#288)
- New document window positioning (#286)
- Graphviz/Mermaid button positioning in Compilation Settings (#280)
- Adjacent shortcut-style links rendering (#275)

Includes regression testing checklist for core functionality.
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