mirror of
https://github.com/sharkdp/bat
synced 2026-07-20 16:33:20 +00:00
Merge pull request #3621 from Xavrir/fix-symlink-syntax-detection
Fix syntax highlighting for symlinked files by resolving target path
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
|
||||
## Bugfixes
|
||||
- Fix `BAT_CONFIG_DIR` pointing at system config directory causing duplicate flag errors. Closes #3589, see #3620 (@Xavrir)
|
||||
- Fix syntax highlighting for symlinked files when the symlink name has no extension but the target does. Closes #1001, see #3621 (@Xavrir)
|
||||
- Report error when pager is missing instead of silently falling back, see #3588 (@IMaloney)
|
||||
- Fix `--wrap=never` and `-S` flags being ignored when piping to pager, see #3592 (@IMaloney)
|
||||
- Fix crash with BusyBox `less` on Windows, see #3527 (@Anchal-T)
|
||||
|
||||
+56
-7
@@ -223,18 +223,40 @@ impl HighlightingAssets {
|
||||
}
|
||||
|
||||
let path = input.path();
|
||||
let path_syntax = if let Some(path) = path {
|
||||
self.get_syntax_for_path(
|
||||
PathAbs::new(path).map_or_else(|_| path.to_owned(), |p| p.as_path().to_path_buf()),
|
||||
mapping,
|
||||
)
|
||||
let absolute_path = path.and_then(|p| {
|
||||
PathAbs::new(p)
|
||||
.ok()
|
||||
.map(|abs| abs.as_path().to_path_buf())
|
||||
.or_else(|| Some(p.to_owned()))
|
||||
});
|
||||
|
||||
let path_syntax = if let Some(ref path) = absolute_path {
|
||||
self.get_syntax_for_path(path, mapping).or_else(|e| {
|
||||
// If syntax detection failed on the given path, retry with the
|
||||
// canonicalized path (which resolves symlinks). This handles
|
||||
// cases like `Aliases/0install -> ../Formula/zero-install.rb`
|
||||
// where the symlink name has no extension but the target does.
|
||||
// See #1001.
|
||||
if matches!(e, Error::UndetectedSyntax(_)) {
|
||||
if let Ok(resolved) = fs::canonicalize(path) {
|
||||
if resolved != *path {
|
||||
return match self.get_syntax_for_path(&resolved, mapping) {
|
||||
Ok(syntax) => Ok(syntax),
|
||||
Err(Error::UndetectedSyntax(_)) => Err(e),
|
||||
Err(err) => Err(err),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e)
|
||||
})
|
||||
} else {
|
||||
Err(Error::UndetectedSyntax("[unknown]".into()))
|
||||
};
|
||||
|
||||
// If a path wasn't provided, or if path based syntax detection
|
||||
// above failed, we fall back to first-line syntax detection.
|
||||
match path_syntax {
|
||||
// If a path wasn't provided, or if path based syntax detection
|
||||
// above failed, we fall back to first-line syntax detection.
|
||||
Err(Error::UndetectedSyntax(path)) => {
|
||||
if let Some(syntax_in_set) = self.get_first_line_syntax(&mut input.reader)? {
|
||||
Ok(syntax_in_set)
|
||||
@@ -765,4 +787,31 @@ contexts:
|
||||
"SSH Config"
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn syntax_detection_for_symlinked_file_by_target_extension() {
|
||||
use std::os::unix::fs::symlink;
|
||||
|
||||
let test = SyntaxDetectionTest::new();
|
||||
|
||||
let formula_dir = test.temp_dir.path().join("Formula");
|
||||
std::fs::create_dir(&formula_dir).unwrap();
|
||||
let target = formula_dir.join("zero-install.rb");
|
||||
File::create(&target).unwrap();
|
||||
|
||||
let aliases_dir = test.temp_dir.path().join("Aliases");
|
||||
std::fs::create_dir(&aliases_dir).unwrap();
|
||||
let link = aliases_dir.join("0install");
|
||||
symlink(&target, &link).unwrap();
|
||||
|
||||
let input = Input::ordinary_file(&link);
|
||||
let dummy_stdin: &[u8] = &[];
|
||||
let mut opened_input = input.open(dummy_stdin, None).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
test.get_syntax_name(None, None, &mut opened_input, &test.syntax_mapping),
|
||||
"Ruby"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user