diff --git a/crates/typos-cli/src/file_type.rs b/crates/typos-cli/src/file_type.rs index afaff6f..c5787b6 100644 --- a/crates/typos-cli/src/file_type.rs +++ b/crates/typos-cli/src/file_type.rs @@ -107,9 +107,15 @@ impl Types { } pub fn file_matched(&self, path: &std::path::Path) -> Option<&str> { - let file_name = path.file_name()?.to_str()?.trim_end_matches(".in"); + let mut file_name = path.file_name()?.to_str()?; let mut matches = self.matches.get_or_default().borrow_mut(); - self.set.matches_into(file_name, &mut *matches); + loop { + self.set.matches_into(file_name, &mut *matches); + if !matches.is_empty() || !file_name.ends_with(".in") { + break; + } + file_name = file_name.strip_suffix(".in")?; + } matches .last() .copied() @@ -145,16 +151,22 @@ mod tests { ("js", &["*.js"]), ("json", &["*.json"]), ("lock", &["package-lock.json", "*.lock"]), + ("js-in", &["*.js.in"]), ] } + fn in_types() -> &'static [(&'static str, &'static [&'static str])] { + &[("html", &["*.html", "*.htm"]), ("in-canary", &["*.in"])] + } matched!(basic_match, types(), "leftpad.js", "js"); matched!(multi_def_1, types(), "index.html", "html"); matched!(multi_def_2, types(), "index.htm", "html"); matched!(no_match, types(), "leftpad.ada", None); matched!(more_specific, types(), "package-lock.json", "lock"); - matched!(trailing_in, types(), "index.html.in", "html"); - matched!(trailing_in_in, types(), "index.html.in.in", "html"); + matched!(basic_in, types(), "index.html.in", "html"); + matched!(basic_in_in, types(), "index.html.in.in", "html"); + matched!(ext_plus_in, types(), "foo.js.in", "js-in"); + matched!(toplevel_in, in_types(), "index.html.in", "in-canary"); macro_rules! sort { ($name:ident, $actual:expr, $expected:expr) => {