From c477e23fe9c8c0d677f8ed2b2b94c81262a48cc6 Mon Sep 17 00:00:00 2001 From: Kienyew Date: Sun, 6 Sep 2020 20:08:13 +0800 Subject: [PATCH] Handle file extension conflicts in --list-languages --- src/assets.rs | 15 +++++++++++++++ src/bin/bat/main.rs | 23 +++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/assets.rs b/src/assets.rs index b30fa3b7..eecb0693 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -170,6 +170,21 @@ impl HighlightingAssets { self.theme_set.themes.keys().map(|s| s.as_ref()) } + pub fn syntax_for_file_name( + &self, + file_name: impl AsRef, + mapping: &SyntaxMapping, + ) -> Option<&SyntaxReference> { + let file_name = file_name.as_ref(); + match mapping.get_syntax_for(file_name) { + Some(MappingTarget::MapToUnknown) => None, + Some(MappingTarget::MapTo(syntax_name)) => { + self.syntax_set.find_syntax_by_name(syntax_name) + } + None => self.get_extension_syntax(file_name.as_os_str()), + } + } + pub(crate) fn get_theme(&self, theme: &str) -> &Theme { match self.theme_set.themes.get(theme) { Some(theme) => theme, diff --git a/src/bin/bat/main.rs b/src/bin/bat/main.rs index 65129fa7..1fd43b85 100644 --- a/src/bin/bat/main.rs +++ b/src/bin/bat/main.rs @@ -86,6 +86,29 @@ pub fn list_languages(config: &Config) -> Result<()> { .filter(|syntax| !syntax.hidden && !syntax.file_extensions.is_empty()) .cloned() .collect::>(); + + // Handling of file-extension conflicts, see issue #1076 + for lang in languages.iter_mut() { + let lang_name = lang.name.clone(); + lang.file_extensions.retain(|extension| { + // The 'extension' variable is not certainly a real extension. + // + // Skip if 'extension' starts with '.', likely a hidden file like '.vimrc' + // Also skip if the 'extension' contains another real extension, likely + // that is a full match file name like 'CMakeLists.txt' and 'Cargo.lock' + if extension.starts_with('.') || Path::new(extension).extension().is_some() { + true + } else { + let test_file = Path::new("test").with_extension(extension); + if let Some(syntax) = assets.syntax_for_file_name(test_file, &config.syntax_mapping) { + syntax.name == lang_name + } else { + false + } + } + }); + } + languages.sort_by_key(|lang| lang.name.to_uppercase()); let configured_languages = get_syntax_mapping_to_paths(config.syntax_mapping.mappings());