Allow a language override to include multiple globs

pull/504/merge
Wilfred Hughes 2023-08-24 08:47:59 +07:00
parent 72475493a4
commit 0db99d76c6
3 changed files with 28 additions and 23 deletions

@ -154,7 +154,7 @@ fn main() {
use_color, use_color,
language_overrides, language_overrides,
} => { } => {
for (glob, lang_override) in language_overrides { for (lang_override, globs) in language_overrides {
let mut name = match lang_override { let mut name = match lang_override {
LanguageOverride::Language(lang) => language_name(lang), LanguageOverride::Language(lang) => language_name(lang),
LanguageOverride::PlainText => "Text", LanguageOverride::PlainText => "Text",
@ -164,7 +164,10 @@ fn main() {
name = name.bold().to_string(); name = name.bold().to_string();
} }
println!("{} (from override)", name); println!("{} (from override)", name);
println!(" {}", glob.as_str()); for glob in globs {
print!(" {}", glob.as_str());
}
println!();
} }
for language in Language::iter() { for language in Language::iter() {
@ -328,7 +331,7 @@ fn diff_file(
display_options: &DisplayOptions, display_options: &DisplayOptions,
diff_options: &DiffOptions, diff_options: &DiffOptions,
missing_as_empty: bool, missing_as_empty: bool,
overrides: &[(glob::Pattern, LanguageOverride)], overrides: &[(LanguageOverride, Vec<glob::Pattern>)],
) -> DiffResult { ) -> DiffResult {
let (lhs_bytes, rhs_bytes) = read_files_or_die(lhs_path, rhs_path, missing_as_empty); let (lhs_bytes, rhs_bytes) = read_files_or_die(lhs_path, rhs_path, missing_as_empty);
let (lhs_src, rhs_src) = match (guess_content(&lhs_bytes), guess_content(&rhs_bytes)) { let (lhs_src, rhs_src) = match (guess_content(&lhs_bytes), guess_content(&rhs_bytes)) {
@ -367,7 +370,7 @@ fn diff_conflicts_file(
path: &FileArgument, path: &FileArgument,
display_options: &DisplayOptions, display_options: &DisplayOptions,
diff_options: &DiffOptions, diff_options: &DiffOptions,
overrides: &[(glob::Pattern, LanguageOverride)], overrides: &[(LanguageOverride, Vec<glob::Pattern>)],
) -> DiffResult { ) -> DiffResult {
let bytes = read_file_or_die(path); let bytes = read_file_or_die(path);
let src = match guess_content(&bytes) { let src = match guess_content(&bytes) {
@ -452,7 +455,7 @@ fn diff_file_content(
rhs_src: &str, rhs_src: &str,
display_options: &DisplayOptions, display_options: &DisplayOptions,
diff_options: &DiffOptions, diff_options: &DiffOptions,
overrides: &[(glob::Pattern, LanguageOverride)], overrides: &[(LanguageOverride, Vec<glob::Pattern>)],
) -> DiffResult { ) -> DiffResult {
let (guess_src, guess_path) = match rhs_path { let (guess_src, guess_path) = match rhs_path {
FileArgument::NamedPath(path) => (&rhs_src, Path::new(path)), FileArgument::NamedPath(path) => (&rhs_src, Path::new(path)),
@ -686,7 +689,7 @@ fn diff_directories<'a>(
rhs_dir: &'a Path, rhs_dir: &'a Path,
display_options: &DisplayOptions, display_options: &DisplayOptions,
diff_options: &DiffOptions, diff_options: &DiffOptions,
overrides: &[(glob::Pattern, LanguageOverride)], overrides: &[(LanguageOverride, Vec<glob::Pattern>)],
) -> impl ParallelIterator<Item = DiffResult> + 'a { ) -> impl ParallelIterator<Item = DiffResult> + 'a {
let diff_options = diff_options.clone(); let diff_options = diff_options.clone();
let display_options = display_options.clone(); let display_options = display_options.clone();

@ -353,7 +353,7 @@ pub enum Mode {
diff_options: DiffOptions, diff_options: DiffOptions,
display_options: DisplayOptions, display_options: DisplayOptions,
set_exit_code: bool, set_exit_code: bool,
language_overrides: Vec<(glob::Pattern, LanguageOverride)>, language_overrides: Vec<(LanguageOverride, Vec<glob::Pattern>)>,
/// The path where we can read the LHS file. This is often a /// The path where we can read the LHS file. This is often a
/// temporary file generated by source control. /// temporary file generated by source control.
lhs_path: FileArgument, lhs_path: FileArgument,
@ -369,23 +369,23 @@ pub enum Mode {
diff_options: DiffOptions, diff_options: DiffOptions,
display_options: DisplayOptions, display_options: DisplayOptions,
set_exit_code: bool, set_exit_code: bool,
language_overrides: Vec<(glob::Pattern, LanguageOverride)>, language_overrides: Vec<(LanguageOverride, Vec<glob::Pattern>)>,
path: FileArgument, path: FileArgument,
/// The path that we show to the user. /// The path that we show to the user.
display_path: String, display_path: String,
}, },
ListLanguages { ListLanguages {
use_color: bool, use_color: bool,
language_overrides: Vec<(glob::Pattern, LanguageOverride)>, language_overrides: Vec<(LanguageOverride, Vec<glob::Pattern>)>,
}, },
DumpTreeSitter { DumpTreeSitter {
path: String, path: String,
language_overrides: Vec<(glob::Pattern, LanguageOverride)>, language_overrides: Vec<(LanguageOverride, Vec<glob::Pattern>)>,
}, },
DumpSyntax { DumpSyntax {
path: String, path: String,
ignore_comments: bool, ignore_comments: bool,
language_overrides: Vec<(glob::Pattern, LanguageOverride)>, language_overrides: Vec<(LanguageOverride, Vec<glob::Pattern>)>,
}, },
} }
@ -434,8 +434,8 @@ fn build_display_path(lhs_path: &FileArgument, rhs_path: &FileArgument) -> Strin
} }
} }
fn parse_overrides_or_die(raw_overrides: &[String]) -> Vec<(glob::Pattern, LanguageOverride)> { fn parse_overrides_or_die(raw_overrides: &[String]) -> Vec<(LanguageOverride, Vec<glob::Pattern>)> {
let mut res = vec![]; let mut res: Vec<(LanguageOverride, Vec<glob::Pattern>)> = vec![];
let mut invalid_syntax = false; let mut invalid_syntax = false;
for raw_override in raw_overrides { for raw_override in raw_overrides {
@ -443,7 +443,7 @@ fn parse_overrides_or_die(raw_overrides: &[String]) -> Vec<(glob::Pattern, Langu
match glob::Pattern::new(glob_str) { match glob::Pattern::new(glob_str) {
Ok(pattern) => { Ok(pattern) => {
if let Some(language_override) = language_override_from_name(lang_name) { if let Some(language_override) = language_override_from_name(lang_name) {
res.push((pattern, language_override)); res.push((language_override, vec![pattern]));
} else { } else {
eprintln!("No such language '{}'", lang_name); eprintln!("No such language '{}'", lang_name);
eprintln!("See --list-languages for the names of all languages available. Language overrides are case insensitive."); eprintln!("See --list-languages for the names of all languages available. Language overrides are case insensitive.");

@ -365,16 +365,18 @@ fn looks_like_hacklang(path: &Path, src: &str) -> bool {
pub fn guess( pub fn guess(
path: &Path, path: &Path,
src: &str, src: &str,
overrides: &[(glob::Pattern, LanguageOverride)], overrides: &[(LanguageOverride, Vec<glob::Pattern>)],
) -> Option<Language> { ) -> Option<Language> {
if let Some(file_name) = path.file_name() { if let Some(file_name) = path.file_name() {
let file_name = file_name.to_string_lossy(); let file_name = file_name.to_string_lossy();
for (pattern, lang_override) in overrides { for (lang_override, patterns) in overrides {
if pattern.matches(&file_name) { for pattern in patterns {
match lang_override { if pattern.matches(&file_name) {
LanguageOverride::Language(lang) => return Some(*lang), match lang_override {
LanguageOverride::PlainText => { LanguageOverride::Language(lang) => return Some(*lang),
return None; LanguageOverride::PlainText => {
return None;
}
} }
} }
} }
@ -596,8 +598,8 @@ mod tests {
path, path,
"", "",
&[( &[(
glob::Pattern::new("*.el").unwrap(), LanguageOverride::Language(Css),
LanguageOverride::Language(Css) vec![glob::Pattern::new("*.el").unwrap()],
)] )]
), ),
Some(Css) Some(Css)