Skip to content

Commit cb28dc2

Browse files
wtfbbqhaxbug-ops
authored andcommitted
fix(config): polish file pattern extension mapping
Add direct unit coverage for extract_extension_from_pattern edge cases, including empty input, no-dot patterns, dotfiles, and multi-dot filenames. Tighten the parser to reject dotfile basenames so hidden files like .gitignore do not get treated as language extensions. Update the translator initialization test to assert against build_effective_extension_map(), which matches the runtime code path introduced by the earlier file_patterns fix. Document the resulting C/C++ language detection behavior change in CHANGELOG.md.
1 parent 152e28f commit cb28dc2

3 files changed

Lines changed: 32 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## [Unreleased]
9+
### Changed
10+
11+
- **C/C++ file pattern language detection** - When `lsp_servers[].file_patterns` include simple extensions such as `**/*.c` or `**/*.h`, mcpls now derives extension-to-language mappings from those patterns and overlays them onto the workspace extension map. This changes the default behavior for matching C/C++ files to prefer the configured LSP server language instead of falling back to built-in mappings or `plaintext`.
912

1013
## [0.3.5] - 2026-03-17
1114

crates/mcpls-core/src/bridge/translator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2776,7 +2776,7 @@ mod tests {
27762776
lsp_servers: vec![],
27772777
};
27782778

2779-
let extension_map = config.workspace.build_extension_map();
2779+
let extension_map = config.build_effective_extension_map();
27802780
assert_eq!(extension_map.get("nu"), Some(&"nushell".to_string()));
27812781
assert_eq!(extension_map.get("rs"), Some(&"rust".to_string()));
27822782

crates/mcpls-core/src/config/mod.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ impl WorkspaceConfig {
121121
/// Supports common patterns such as `**/*.rs` and `*.h`.
122122
/// Returns `None` for patterns without a simple trailing extension.
123123
fn extract_extension_from_pattern(pattern: &str) -> Option<String> {
124+
let basename = pattern.rsplit('/').next().unwrap_or(pattern);
125+
if basename.starts_with('.') {
126+
return None;
127+
}
128+
124129
let (_, ext) = pattern.rsplit_once('.')?;
125130
if ext.is_empty() {
126131
return None;
@@ -696,6 +701,29 @@ mod tests {
696701
assert_eq!(map.get("unknown"), None);
697702
}
698703

704+
#[test]
705+
fn test_extract_extension_from_pattern_empty_string() {
706+
assert_eq!(extract_extension_from_pattern(""), None);
707+
}
708+
709+
#[test]
710+
fn test_extract_extension_from_pattern_without_dot() {
711+
assert_eq!(extract_extension_from_pattern("**/*"), None);
712+
}
713+
714+
#[test]
715+
fn test_extract_extension_from_pattern_dotfile() {
716+
assert_eq!(extract_extension_from_pattern(".gitignore"), None);
717+
}
718+
719+
#[test]
720+
fn test_extract_extension_from_pattern_multi_dot_extension() {
721+
assert_eq!(
722+
extract_extension_from_pattern("foo.tar.gz"),
723+
Some("gz".to_string())
724+
);
725+
}
726+
699727
#[test]
700728
fn test_build_effective_extension_map_overrides_with_file_patterns() {
701729
let config = ServerConfig {

0 commit comments

Comments
 (0)