feat(format): add smart format toggle with treesitter detection#158
Merged
YousefHadder merged 3 commits intomainfrom Dec 11, 2025
Merged
feat(format): add smart format toggle with treesitter detection#158YousefHadder merged 3 commits intomainfrom
YousefHadder merged 3 commits intomainfrom
Conversation
- Use treesitter to detect if cursor is inside formatted range - Remove formatting from entire range when toggling same format type - Add nested formatting support (e.g., italic to bold word) - Preserve cursor position after adding/removing formatting - Smart visual mode: detect containing formatted range - Add strip_all_formatting() helper to reduce code duplication - Add get_any_format_at_cursor() for optimized format detection - Add ESC constant for consistency - Add LuaCATS annotations for all public functions - Add 16 new tests for treesitter integration Closes #150
Contributor
There was a problem hiding this comment.
Pull request overview
This PR implements smart format toggling with treesitter-based detection for Markdown formatting operations. The key improvement is that when toggling a format (bold, italic, strikethrough, code), the plugin now detects if the cursor is inside an existing formatted range of the same type and removes the entire formatted range instead of adding nested markers. This provides a more intuitive editing experience and supports nested formatting (e.g., adding italic to bold text produces ***text***).
Key Changes
- Treesitter integration: New functions to detect formatted ranges using treesitter's markdown_inline parser for precise node detection
- Smart toggle behavior: Toggle operations now remove formatting from the entire containing range when cursor is inside formatted text of the same type
- Code quality improvements: Extracted
strip_all_formatting()helper to eliminate ~40 lines of duplicated code, and added optimizedget_any_format_at_cursor()to reduce parser calls from 4 to 1
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| lua/markdown-plus/format/init.lua | Adds treesitter-based format detection functions, smart toggle logic for both normal and visual modes, cursor position preservation, ESC constant, and LuaCATS annotations for all new functions |
| spec/markdown-plus/format_spec.lua | Adds comprehensive test coverage (79 new tests) for new helper functions, treesitter integration, cursor position preservation, and nested formatting scenarios |
- Add @Class markdown-plus.format.NodeInfo type definition - Use NodeInfo type for return and parameter annotations - Clarify end_col comment about 0-indexed vs 1-indexed - Update outdated comment 'Exit visual mode and clear the selection'
bfa3f46 to
8824d5f
Compare
- Fix end_col type annotation: 'exclusive' -> 'inclusive' (matches string.sub usage) - Clarify end_col conversion comment: 0-indexed exclusive becomes 1-indexed inclusive - Strengthen test assertion: verify actual formatting removal instead of just non-nil
93b1db3 to
13d65bf
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements smart format toggle using treesitter to detect if cursor is inside an existing formatted range. When toggling the same format type, removes formatting from the entire range instead of adding more markers.
Changes
New Features
strong_emphasis,emphasis,strikethrough, andcode_spannodes***text***instead of corrupting formattingCode Quality
strip_all_formatting()helper to reduce ~40 lines of code duplicationget_any_format_at_cursor()for optimized single-pass format detection (reduces 4 parser calls to 1)ESCconstant for consistencyTests
Behavior Examples
Some **bold text** here(cursor on 'bold')Some bold text hereSome text here(cursor on 'text')Some **text** here**bold**(cursor on 'bold')***bold*****bold text**bold textCloses #150