fix(config): User file types override default file types

This also ensures `typos --type-list` will report the glob in only one
place.

Fixes #754
This commit is contained in:
Ed Page 2023-06-21 14:31:04 -05:00
parent 77f0389a9e
commit fce92e4e5f
2 changed files with 24 additions and 8 deletions

View file

@ -4,7 +4,7 @@ use kstring::KString;
#[derive(Default, Clone, Debug)] #[derive(Default, Clone, Debug)]
pub struct TypesBuilder { pub struct TypesBuilder {
definitions: BTreeMap<KString, Vec<KString>>, definitions: BTreeMap<KString, Vec<(KString, usize)>>,
} }
impl TypesBuilder { impl TypesBuilder {
@ -18,7 +18,7 @@ impl TypesBuilder {
.iter() .iter()
.map(|(name, glob)| { .map(|(name, glob)| {
let name = KString::from(*name); let name = KString::from(*name);
let globs = glob.iter().map(|s| KString::from(*s)).collect(); let globs = glob.iter().map(|s| (KString::from(*s), 0)).collect();
(name, globs) (name, globs)
}), }),
); );
@ -31,7 +31,11 @@ impl TypesBuilder {
pub fn add(&mut self, name: impl Into<KString>, glob: impl Into<KString>) { pub fn add(&mut self, name: impl Into<KString>, glob: impl Into<KString>) {
let name = name.into(); let name = name.into();
let glob = glob.into(); let glob = glob.into();
self.definitions.entry(name).or_default().push(glob); let weight = self.definitions.len();
self.definitions
.entry(name)
.or_default()
.push((glob, weight));
} }
pub fn build(self) -> Result<Types, anyhow::Error> { pub fn build(self) -> Result<Types, anyhow::Error> {
@ -39,17 +43,29 @@ impl TypesBuilder {
.definitions .definitions
.iter() .iter()
.flat_map(|(name, globs)| { .flat_map(|(name, globs)| {
globs.iter().map(move |glob| { globs.iter().map(move |(glob, weight)| {
let sort = sort_key(glob); let sort = sort_key(glob);
(sort, name, glob) (sort, weight, name, glob)
}) })
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
definitions.sort(); definitions.sort();
let rev_definitions = definitions
.iter()
.map(|(_, _, name, glob)| (*glob, *name))
.collect::<BTreeMap<_, _>>();
let mut unique_definitions = BTreeMap::<KString, Vec<KString>>::new();
for (glob, name) in rev_definitions {
unique_definitions
.entry(name.clone())
.or_default()
.push(glob.clone());
}
let mut glob_to_name = Vec::new(); let mut glob_to_name = Vec::new();
let mut build_set = globset::GlobSetBuilder::new(); let mut build_set = globset::GlobSetBuilder::new();
for (_, name, glob) in definitions { for (_, _, name, glob) in definitions {
glob_to_name.push(name.clone()); glob_to_name.push(name.clone());
build_set.add( build_set.add(
globset::GlobBuilder::new(glob) globset::GlobBuilder::new(glob)
@ -60,7 +76,7 @@ impl TypesBuilder {
let set = build_set.build()?; let set = build_set.build()?;
Ok(Types { Ok(Types {
definitions: self.definitions, definitions: unique_definitions,
glob_to_name, glob_to_name,
set, set,
matches: std::sync::Arc::new(thread_local::ThreadLocal::default()), matches: std::sync::Arc::new(thread_local::ThreadLocal::default()),

View file

@ -6,6 +6,6 @@ stdin = '''
Destory Destory
''' '''
stdout = """ stdout = """
./key.asc:asciidoc ./key.asc:asc
""" """
stderr = "" stderr = ""