Pass overrides to guess() and display them in --list-languages

pull/517/head
Wilfred Hughes 2023-05-15 08:20:32 +07:00
parent 0e2c167dda
commit b3a7bec430
3 changed files with 62 additions and 13 deletions

@ -51,7 +51,7 @@ use files::{
};
use log::info;
use mimalloc::MiMalloc;
use parse::guess_language::{guess, language_name, Language};
use parse::guess_language::{guess, language_name, Language, LanguageOverride};
/// The global allocator used by difftastic.
///
@ -98,12 +98,15 @@ fn main() {
reset_sigpipe();
match options::parse_args() {
Mode::DumpTreeSitter { path, language_overrides} => {
Mode::DumpTreeSitter {
path,
language_overrides,
} => {
let path = Path::new(&path);
let bytes = read_or_die(path);
let src = String::from_utf8_lossy(&bytes).to_string();
let language = guess(path, &src);
let language = guess(path, &src, &language_overrides);
match language {
Some(lang) => {
let ts_lang = tsp::from_language(lang);
@ -124,7 +127,7 @@ fn main() {
let bytes = read_or_die(path);
let src = String::from_utf8_lossy(&bytes).to_string();
let language = guess(path, &src);
let language = guess(path, &src, &language_overrides);
match language {
Some(lang) => {
let ts_lang = tsp::from_language(lang);
@ -138,7 +141,23 @@ fn main() {
}
}
}
Mode::ListLanguages { use_color, language_overrides } => {
Mode::ListLanguages {
use_color,
language_overrides,
} => {
for (glob, lang_override) in language_overrides {
let mut name = match lang_override {
LanguageOverride::Language(lang) => language_name(lang),
LanguageOverride::PlainText => "Text",
}
.to_string();
if use_color {
name = name.bold().to_string();
}
println!("{} (from override)", name);
println!(" {}", glob.as_str());
}
for language in Language::iter() {
let mut name = language_name(language).to_string();
if use_color {
@ -199,9 +218,15 @@ fn main() {
}
});
diff_directories(lhs_path, rhs_path, &display_options, &diff_options)
.try_for_each_with(send, |s, diff_result| s.send(diff_result))
.expect("Receiver should be connected");
diff_directories(
lhs_path,
rhs_path,
&display_options,
&diff_options,
&language_overrides,
)
.try_for_each_with(send, |s, diff_result| s.send(diff_result))
.expect("Receiver should be connected");
printing_thread
.join()
@ -216,6 +241,7 @@ fn main() {
&display_options,
&diff_options,
false,
&language_overrides,
);
print_diff_result(&display_options, &diff_result);
@ -259,6 +285,7 @@ fn diff_file(
display_options: &DisplayOptions,
diff_options: &DiffOptions,
missing_as_empty: bool,
overrides: &[(glob::Pattern, LanguageOverride)],
) -> DiffResult {
let (lhs_bytes, rhs_bytes) = read_files_or_die(lhs_path, rhs_path, missing_as_empty);
diff_file_content(
@ -270,6 +297,7 @@ fn diff_file(
&rhs_bytes,
display_options,
diff_options,
overrides,
)
}
@ -305,6 +333,7 @@ fn diff_file_content(
rhs_bytes: &[u8],
display_options: &DisplayOptions,
diff_options: &DiffOptions,
overrides: &[(glob::Pattern, LanguageOverride)],
) -> DiffResult {
let (lhs_src, rhs_src) = match (guess_content(lhs_bytes), guess_content(rhs_bytes)) {
(ProbableFileKind::Binary, _) | (_, ProbableFileKind::Binary) => {
@ -330,7 +359,7 @@ fn diff_file_content(
FileArgument::DevNull => (&lhs_src, Path::new(&display_path)),
};
let language = guess(guess_path, guess_src);
let language = guess(guess_path, guess_src, overrides);
let lang_config = language.map(tsp::from_language);
if lhs_bytes == rhs_bytes {
@ -555,9 +584,11 @@ fn diff_directories<'a>(
rhs_dir: &'a Path,
display_options: &DisplayOptions,
diff_options: &DiffOptions,
overrides: &[(glob::Pattern, LanguageOverride)],
) -> impl ParallelIterator<Item = DiffResult> + 'a {
let diff_options = diff_options.clone();
let display_options = display_options.clone();
let overrides: Vec<_> = overrides.into();
// We greedily list all files in the directory, and then diff them
// in parallel. This is assuming that diffing is slower than
@ -578,6 +609,7 @@ fn diff_directories<'a>(
&display_options,
&diff_options,
true,
&overrides,
)
})
}

@ -5,12 +5,11 @@ use std::{env, ffi::OsStr, path::Path, path::PathBuf};
use clap::{crate_authors, crate_description, crate_version, Arg, Command};
use const_format::formatcp;
use crossterm::tty::IsTty;
use strum::IntoEnumIterator;
use crate::{
display::style::BackgroundColor,
exit_codes::EXIT_BAD_ARGUMENTS,
parse::guess_language::{self, language_name, LanguageOverride, language_override_from_name},
parse::guess_language::{language_override_from_name, LanguageOverride},
};
pub const DEFAULT_BYTE_LIMIT: usize = 1_000_000;

@ -72,7 +72,7 @@ pub enum Language {
Zig,
}
#[derive(Debug)]
#[derive(Debug, Clone, Copy)]
pub enum LanguageOverride {
Language(Language),
PlainText,
@ -356,7 +356,25 @@ fn looks_like_hacklang(path: &Path, src: &str) -> bool {
false
}
pub fn guess(path: &Path, src: &str) -> Option<Language> {
pub fn guess(
path: &Path,
src: &str,
overrides: &[(glob::Pattern, LanguageOverride)],
) -> Option<Language> {
if let Some(file_name) = path.file_name() {
let file_name = file_name.to_string_lossy();
for (pattern, lang_override) in overrides {
if pattern.matches(&file_name) {
match lang_override {
LanguageOverride::Language(lang) => return Some(*lang),
LanguageOverride::PlainText => {
return None;
}
}
}
}
}
if let Some(lang) = from_emacs_mode_header(src) {
return Some(lang);
}