Skip to content

Commit ea64953

Browse files
committed
Extract a symlink's target type if possible, so it can have proper colors.
1 parent 74c1206 commit ea64953

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased] - ReleaseDate
88
### Added
9+
- Added support for coloring symlink targets.
910
- Added support for the MISSING / mi= dircolors variable for broken symlink targets.
1011
- Add support for theme from [zwpaper](https://github.com/zwpaper) [#452](https://github.com/Peltoche/lsd/pull/452)
1112
- Update minimal rust version to 1.42.0 from [zwpaper](https://github.com/zwpaper) [#534](https://github.com/Peltoche/lsd/issues/534)

src/meta/symlink.rs

+33-1
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
11
use crate::color::{ColoredString, Colors, Elem};
22
use crate::flags::Flags;
3+
use crate::meta::{FileType, Permissions};
34
use std::fs::read_link;
45
use std::path::Path;
56

67
#[derive(Clone, Debug)]
78
pub struct SymLink {
89
target: Option<String>,
10+
target_type: Option<FileType>,
911
valid: bool,
1012
}
1113

1214
impl<'a> From<&'a Path> for SymLink {
1315
fn from(path: &'a Path) -> Self {
1416
if let Ok(target) = read_link(path) {
17+
// Extract the symlink's target type if possible, so it can have proper colors.
18+
let target_type = match target.metadata() {
19+
Ok(metadata) => Some(FileType::new(
20+
&metadata,
21+
None,
22+
&Permissions::from(&metadata),
23+
)),
24+
Err(_) => None,
25+
};
26+
1527
if target.is_absolute() || path.parent() == None {
1628
return Self {
1729
valid: target.exists(),
@@ -21,6 +33,7 @@ impl<'a> From<&'a Path> for SymLink {
2133
.expect("failed to convert symlink to str")
2234
.to_string(),
2335
),
36+
target_type,
2437
};
2538
}
2639

@@ -31,12 +44,14 @@ impl<'a> From<&'a Path> for SymLink {
3144
.expect("failed to convert symlink to str")
3245
.to_string(),
3346
),
47+
target_type,
3448
valid: path.parent().unwrap().join(target).exists(),
3549
};
3650
}
3751

3852
Self {
3953
target: None,
54+
target_type: None,
4055
valid: false,
4156
}
4257
}
@@ -50,7 +65,20 @@ impl SymLink {
5065
pub fn render(&self, colors: &Colors, flag: &Flags) -> ColoredString {
5166
if let Some(target_string) = self.symlink_string() {
5267
let elem = if self.valid {
53-
&Elem::SymLink
68+
// Proper colors for symlink target file types.
69+
match self.target_type {
70+
Some(FileType::BlockDevice) => &Elem::BlockDevice,
71+
Some(FileType::CharDevice) => &Elem::CharDevice,
72+
Some(FileType::Directory { uid: _ }) => &Elem::Dir { uid: false },
73+
Some(FileType::File { uid: _, exec: _ }) => &Elem::File {
74+
uid: false,
75+
exec: false,
76+
},
77+
Some(FileType::Pipe) => &Elem::Pipe,
78+
Some(FileType::Socket) => &Elem::Socket,
79+
Some(FileType::Special) => &Elem::Special,
80+
_ => &Elem::SymLink,
81+
}
5482
} else {
5583
&Elem::MissingSymLinkTarget
5684
};
@@ -79,11 +107,13 @@ mod tests {
79107
use crate::color::{Colors, ThemeOption};
80108
use crate::config_file::Config;
81109
use crate::flags::Flags;
110+
use crate::meta::FileType;
82111

83112
#[test]
84113
fn test_symlink_render_default_valid_target_nocolor() {
85114
let link = SymLink {
86115
target: Some("/target".to_string()),
116+
target_type: None,
87117
valid: true,
88118
};
89119
let argv = vec!["lsd"];
@@ -102,6 +132,7 @@ mod tests {
102132
fn test_symlink_render_default_invalid_target_nocolor() {
103133
let link = SymLink {
104134
target: Some("/target".to_string()),
135+
target_type: None,
105136
valid: false,
106137
};
107138
let argv = vec!["lsd"];
@@ -120,6 +151,7 @@ mod tests {
120151
fn test_symlink_render_default_invalid_target_withcolor() {
121152
let link = SymLink {
122153
target: Some("/target".to_string()),
154+
target_type: Some(FileType::SymLink { is_dir: false }),
123155
valid: false,
124156
};
125157
let argv = vec!["lsd"];

0 commit comments

Comments
 (0)