Added
- Git-style intelligent configuration merging
- User and project configs can now intelligently combine instead of simply overriding
disablearray uses union semantics - user can add to project disablesenablearray uses replace semantics - project can enforce specific rules- When a rule appears in both
enableanddisable,enablewins (project can override user) - Configuration hierarchy is now explicit and follows Git's pattern:
- Default (0) < UserConfig (1) < PyprojectToml (2) < ProjectConfig (3) < CLI (4)
- Renamed config sources for clarity:
ConfigSource::RumdlToml→UserConfig(global user config)ConfigSource::RumdlToml→ProjectConfig(project-level config files)- Removed
Markdownlintsource (now usesProjectConfig)
- New API methods:
SourcedValue::merge_union()- additive merging for disable arraysSourcedValue::merge_override()- replacement merging for enable arrays
- Example use cases:
- User disables MD013 globally → Project enables MD013 → MD013 is enabled ✓
- Project disables MD001, MD003 → User disables MD013 → All three are disabled ✓
- 17 comprehensive tests covering merge semantics, precedence, and conflict resolution
- Matches configuration pattern used by git, eslint, prettier, and other modern tools
Performance
-
Major memory optimizations eliminating string allocations
- Converted
LineInfoto use byte ranges instead of owned strings (50-80% memory reduction) - Eliminates N string allocations where N = number of lines in document
- Added zero-copy
content(&self, source: &str) -> &strmethod for on-demand access - Converted
LineIndexto borrow&'a strinstead of cloning (eliminates one full document copy per lint operation) - Converted
ParsedLink/ParsedImageto useCow<'a, str>(60-80% reduction in heap allocations for link/image parsing) - Zero-cost when borrowing, minimal overhead when owning - most data borrowed directly from source
- Converted
-
Eliminated O(n²) complexity in multiple rules
- Fixed quadratic bottlenecks in MD027 (Multiple spaces after blockquote symbol)
- Fixed quadratic bottlenecks in MD020 (No space inside hashes on closed atx style heading)
- Fixed quadratic bottlenecks in MD046 (Code block style)
- All three rules now use pre-computed context data with O(1) lookups
-
Optimized CLI commands
rumdl confignow executes in ~18ms (eliminated duplicate rule instantiation)- Removed duplicate instantiation of ~50 rule objects between main.rs and formatter.rs
- Cleaner architecture with single source of truth for rule instances
Fixed
-
Config loading: User config now always loaded as base layer (#131)
- Fixed LSP server ignoring user config when finding project-level config files
- User configuration is now always loaded first (unless
--no-configis used) - Project configs merge on top of user config, CLI flags have highest priority
- Configuration hierarchy now consistent between CLI and LSP:
- User/global config (
~/.config/rumdl/rumdl.toml) - base layer - Project config (discovered or explicit) - overrides user config
- CLI flags - highest priority
- User/global config (
- Matches pattern used by git, eslint, prettier, and other tools
- Added regression test verifying user config preserved with explicit project config
-
MD035: Frontmatter delimiter false positives (#40)
- Fixed incorrect flagging of YAML/TOML frontmatter delimiters (
---/+++) as horizontal rules - Rule now correctly skips frontmatter in three places:
most_prevalent_hr_style()- don't count frontmatter HRs for prevalencecheck()- don't flag frontmatter delimiters as violationsfix()- don't replace frontmatter delimiters when fixing
- Uses pre-computed
LineInfo.in_front_matterfield for efficient detection
- Fixed incorrect flagging of YAML/TOML frontmatter delimiters (
Changed
-
Architecture: Consistent use of pre-computed context data
- MD035 now uses pre-computed
LineInfo.in_front_matterinstead of function calls - All rules now consistently use
ctx.line_indexfor line-based operations - Eliminates redundant function calls and O(n) scans
- More efficient with O(1) field access patterns
- MD035 now uses pre-computed
-
Test infrastructure improvements
- Implemented dynamic fixture downloading for performance tests
- Test downloads now happen on-demand instead of being checked into repository
- Better handling of large test files for performance benchmarking
-
Test quality improvements
- Corrected ESM block test assertions to match actual MDX behavior
- ESM blocks only exist at TOP of MDX files and end at first non-ESM line
- Tests now assert correct behavior rather than documenting implementation quirks
- Fixed MD033 test assertions to properly validate HTML inline rules
Breaking Changes
For library users only (CLI users unaffected):
LineInfo.contentfield is no longer public - use newcontent(source: &str)method instead- Since
LineInfowas primarily internal API, impact should be minimal
Downloads
| File | Platform | Checksum |
|---|---|---|
| rumdl-v0.0.176-x86_64-unknown-linux-gnu.tar.gz | Linux x86_64 | checksum |
| rumdl-v0.0.176-x86_64-unknown-linux-musl.tar.gz | Linux x86_64 (musl) | checksum |
| rumdl-v0.0.176-aarch64-unknown-linux-gnu.tar.gz | Linux ARM64 | checksum |
| rumdl-v0.0.176-aarch64-unknown-linux-musl.tar.gz | Linux ARM64 (musl) | checksum |
| rumdl-v0.0.176-x86_64-apple-darwin.tar.gz | macOS x86_64 | checksum |
| rumdl-v0.0.176-aarch64-apple-darwin.tar.gz | macOS ARM64 (Apple Silicon) | checksum |
| rumdl-v0.0.176-x86_64-pc-windows-msvc.zip | Windows x86_64 | checksum |
Installation
Using uv (Recommended)
uv tool install rumdlUsing pip
pip install rumdlUsing pipx
pipx install rumdlDirect Download
Download the appropriate binary for your platform from the table above, extract it, and add it to your PATH.