Skip to content

feat(format): add smart format toggle with treesitter detection#158

Merged
YousefHadder merged 3 commits intomainfrom
feat/smart-format-toggle-150
Dec 11, 2025
Merged

feat(format): add smart format toggle with treesitter detection#158
YousefHadder merged 3 commits intomainfrom
feat/smart-format-toggle-150

Conversation

@YousefHadder
Copy link
Copy Markdown
Owner

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

  • Treesitter-based format detection: Detects strong_emphasis, emphasis, strikethrough, and code_span nodes
  • Smart toggle: Removes formatting from entire range when cursor is inside formatted text
  • Nested formatting support: Adding italic to bold text produces ***text*** instead of corrupting formatting
  • Visual mode enhancement: Detects if selection is inside a formatted range and removes the containing formatting
  • Cursor position preservation: Cursor stays on the same logical character after adding/removing formatting

Code Quality

  • Added strip_all_formatting() helper to reduce ~40 lines of code duplication
  • Added get_any_format_at_cursor() for optimized single-pass format detection (reduces 4 parser calls to 1)
  • Added ESC constant for consistency
  • Added LuaCATS annotations for all public functions
  • Graceful fallback when treesitter is unavailable

Tests

  • 16 new tests for treesitter integration
  • Tests for cursor position preservation
  • Tests for nested formatting scenarios
  • Tests for visual mode smart toggle
  • All 108 tests pass

Behavior Examples

Before Action After
Some **bold text** here (cursor on 'bold') Toggle bold Some bold text here
Some text here (cursor on 'text') Toggle bold Some **text** here
**bold** (cursor on 'bold') Toggle italic ***bold***
Visual select 'bold text' inside **bold text** Toggle bold bold text

Closes #150

- 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
Copilot AI review requested due to automatic review settings December 11, 2025 14:57
Copy link
Copy Markdown
Contributor

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

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 optimized get_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'
Copy link
Copy Markdown
Contributor

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

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

- 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
@YousefHadder YousefHadder force-pushed the feat/smart-format-toggle-150 branch from 93b1db3 to 13d65bf Compare December 11, 2025 17:06
@YousefHadder YousefHadder merged commit ef2ba09 into main Dec 11, 2025
15 checks passed
@YousefHadder YousefHadder deleted the feat/smart-format-toggle-150 branch December 11, 2025 17:09
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.

[FEATURE] format actions should toggle the state of current format range

2 participants