1
0
mirror of https://github.com/sharkdp/bat synced 2026-06-09 10:03:18 +00:00

feat(syntax): add support for hidden_file_extensions (#3613)

* feat(syntax): add support for hidden_file_extensions
This commit is contained in:
Matei6942
2026-03-06 23:44:20 +05:30
committed by GitHub
parent a1a10c777f
commit ab80bd9717
2 changed files with 71 additions and 0 deletions
+1
View File
@@ -5,6 +5,7 @@
## Features
- Added support for `hidden_file_extensions` from `.sublime-syntax` files, see #3613 (@Matei02355)
- Add word wrapping mode via `--wrap=word`, see #3597 (@veeceey)
- Implement `--unbuffered` mode for streaming input, allowing partial lines to display immediately (e.g. `tail -f | bat -u`). Closes #3555, see #3583 (@mainnebula)
- Added an initial `flake.nix` for a ready made development environment; see #3578 (@vorburger)
+70
View File
@@ -262,6 +262,24 @@ impl HighlightingAssets {
.map(|syntax| SyntaxReferenceInSet { syntax, syntax_set }))
}
fn find_syntax_by_hidden_file_name(
&self,
file_name: &OsStr,
) -> Result<Option<SyntaxReferenceInSet<'_>>> {
let Some(hidden_file_extension) = file_name
.to_str()
.and_then(|name| name.strip_prefix('.'))
.filter(|name| !name.is_empty())
else {
return Ok(None);
};
// syntect stores `hidden_file_extensions` in the same extension list as
// regular file extensions, but dotfiles must be queried without the
// leading period.
self.find_syntax_by_extension(Some(OsStr::new(hidden_file_extension)))
}
fn find_syntax_by_token(&self, token: &str) -> Result<Option<SyntaxReferenceInSet<'_>>> {
let syntax_set = self.get_syntax_set()?;
Ok(syntax_set
@@ -275,6 +293,9 @@ impl HighlightingAssets {
ignored_suffixes: &IgnoredSuffixes,
) -> Result<Option<SyntaxReferenceInSet<'_>>> {
let mut syntax = self.find_syntax_by_extension(Some(file_name))?;
if syntax.is_none() {
syntax = self.find_syntax_by_hidden_file_name(file_name)?;
}
if syntax.is_none() {
syntax =
ignored_suffixes.try_with_stripped_suffix(file_name, |stripped_file_name| {
@@ -661,6 +682,55 @@ mod tests {
);
}
#[cfg(feature = "build-assets")]
#[test]
fn syntax_detection_hidden_file_extensions() {
let source_dir = TempDir::new().expect("creation of temporary source directory");
let cache_dir = TempDir::new().expect("creation of temporary cache directory");
let syntax_dir = source_dir.path().join("syntaxes");
std::fs::create_dir_all(&syntax_dir).expect("creation of syntax directory succeeds");
std::fs::write(
syntax_dir.join("HiddenFileExtension.sublime-syntax"),
r#"%YAML 1.2
---
name: Hidden File Extension
hidden_file_extensions:
- testrc
scope: source.hiddenfileextension
contexts:
main:
- match: .
scope: source.hiddenfileextension
"#,
)
.expect("custom syntax can be written");
build(
source_dir.path(),
false,
false,
cache_dir.path(),
env!("CARGO_PKG_VERSION"),
)
.expect("custom assets can be built");
let test = SyntaxDetectionTest {
assets: HighlightingAssets::from_cache(cache_dir.path())
.expect("custom syntax cache can be loaded"),
syntax_mapping: SyntaxMapping::new(),
temp_dir: TempDir::new().expect("creation of temporary directory"),
};
assert_eq!(test.syntax_for_file(".testrc"), "Hidden File Extension");
assert_eq!(
test.syntax_for_stdin_with_content(".testrc", b""),
"Hidden File Extension"
);
assert!(test.syntax_is_same_for_inputkinds(".testrc", ""));
}
#[cfg(unix)]
#[test]
fn syntax_detection_for_symlinked_file() {