feat(loader): support multi-barreled file extensions

This commit is contained in:
WillLillis 2024-11-02 23:43:34 -04:00 committed by Amaan Qureshi
parent 7b90dbf189
commit 05b6871a02
2 changed files with 123 additions and 5 deletions

View file

@ -522,11 +522,15 @@ impl Loader {
.and_then(|n| n.to_str())
.and_then(|file_name| self.language_configuration_ids_by_file_type.get(file_name))
.or_else(|| {
path.extension()
.and_then(|extension| extension.to_str())
.and_then(|extension| {
self.language_configuration_ids_by_file_type.get(extension)
})
let mut path = path.to_owned();
let mut extensions = Vec::with_capacity(2);
while let Some(extension) = path.extension() {
extensions.push(extension.to_str()?.to_string());
path = PathBuf::from(path.file_stem()?.to_os_string());
}
extensions.reverse();
self.language_configuration_ids_by_file_type
.get(&extensions.join("."))
});
if let Some(configuration_ids) = configuration_ids {

View file

@ -89,6 +89,120 @@ fn detect_language_by_first_line_regex() {
);
}
#[test]
fn detect_langauge_by_double_barrel_file_extension() {
let blade_dir = tree_sitter_dir(
r#"{
"grammars": [
{
"name": "blade",
"path": ".",
"scope": "source.blade",
"file-types": [
"blade.php"
]
}
],
"metadata": {
"version": "0.0.1"
}
}
"#,
"blade",
);
let mut loader = Loader::with_parser_lib_path(scratch_dir().to_path_buf());
let config = loader
.find_language_configurations_at_path(blade_dir.path(), false)
.unwrap();
// this is just to validate that we can read the tree-sitter.json correctly
assert_eq!(config[0].scope.as_ref().unwrap(), "source.blade");
let file_name = blade_dir.path().join("foo.blade.php");
fs::write(&file_name, "").unwrap();
assert_eq!(
get_lang_scope(&loader, &file_name),
Some("source.blade".into())
);
}
#[test]
fn detect_language_without_filename() {
let gitignore_dir = tree_sitter_dir(
r#"{
"grammars": [
{
"name": "gitignore",
"path": ".",
"scope": "source.gitignore",
"file-types": [
".gitignore"
]
}
],
"metadata": {
"version": "0.0.1"
}
}
"#,
"gitignore",
);
let mut loader = Loader::with_parser_lib_path(scratch_dir().to_path_buf());
let config = loader
.find_language_configurations_at_path(gitignore_dir.path(), false)
.unwrap();
// this is just to validate that we can read the tree-sitter.json correctly
assert_eq!(config[0].scope.as_ref().unwrap(), "source.gitignore");
let file_name = gitignore_dir.path().join(".gitignore");
fs::write(&file_name, "").unwrap();
assert_eq!(
get_lang_scope(&loader, &file_name),
Some("source.gitignore".into())
);
}
#[test]
fn detect_language_without_file_extension() {
let ssh_config_dir = tree_sitter_dir(
r#"{
"grammars": [
{
"name": "ssh_config",
"path": ".",
"scope": "source.ssh_config",
"file-types": [
"ssh_config"
]
}
],
"metadata": {
"version": "0.0.1"
}
}
"#,
"ssh_config",
);
let mut loader = Loader::with_parser_lib_path(scratch_dir().to_path_buf());
let config = loader
.find_language_configurations_at_path(ssh_config_dir.path(), false)
.unwrap();
// this is just to validate that we can read the tree-sitter.json correctly
assert_eq!(config[0].scope.as_ref().unwrap(), "source.ssh_config");
let file_name = ssh_config_dir.path().join("ssh_config");
fs::write(&file_name, "").unwrap();
assert_eq!(
get_lang_scope(&loader, &file_name),
Some("source.ssh_config".into())
);
}
fn tree_sitter_dir(tree_sitter_json: &str, name: &str) -> tempfile::TempDir {
let temp_dir = tempfile::tempdir().unwrap();
fs::write(temp_dir.path().join("tree-sitter.json"), tree_sitter_json).unwrap();