mirror of
https://github.com/sharkdp/bat
synced 2026-08-10 20:01:45 +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
|
## Bugfixes
|
||||||
- Fix `BAT_CONFIG_DIR` pointing at system config directory causing duplicate flag errors. Closes #3589, see #3620 (@Xavrir)
|
- 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)
|
- 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 `--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)
|
- 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 = input.path();
|
||||||
let path_syntax = if let Some(path) = path {
|
let absolute_path = path.and_then(|p| {
|
||||||
self.get_syntax_for_path(
|
PathAbs::new(p)
|
||||||
PathAbs::new(path).map_or_else(|_| path.to_owned(), |p| p.as_path().to_path_buf()),
|
.ok()
|
||||||
mapping,
|
.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 {
|
} else {
|
||||||
Err(Error::UndetectedSyntax("[unknown]".into()))
|
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 {
|
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)) => {
|
Err(Error::UndetectedSyntax(path)) => {
|
||||||
if let Some(syntax_in_set) = self.get_first_line_syntax(&mut input.reader)? {
|
if let Some(syntax_in_set) = self.get_first_line_syntax(&mut input.reader)? {
|
||||||
Ok(syntax_in_set)
|
Ok(syntax_in_set)
|
||||||
@@ -765,4 +787,31 @@ contexts:
|
|||||||
"SSH Config"
|
"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