diff options
author | DLFW <daniel@llin.info> | 2021-06-28 02:56:28 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-27 20:56:28 -0400 |
commit | 8cefdc24500864993e66d28ba198070906161b67 (patch) | |
tree | 6f81e82b1a5777601fa55cebd6c0c9c187fec105 | |
parent | fe87911dbbdd0c20acef825a0bb6213e011fca02 (diff) |
highlight invalid symlinks (#80)
* own display style for invalid symlinks
* add link_invalid to default theme.toml
* footer shows link target in link style
-rw-r--r-- | config/theme.toml | 4 | ||||
-rw-r--r-- | src/config/theme/app_theme.rs | 10 | ||||
-rw-r--r-- | src/fs/metadata.rs | 21 | ||||
-rw-r--r-- | src/ui/widgets/tui_dirlist_detailed.rs | 2 | ||||
-rw-r--r-- | src/ui/widgets/tui_footer.rs | 18 | ||||
-rw-r--r-- | src/util/style.rs | 6 |
6 files changed, 46 insertions, 15 deletions
diff --git a/config/theme.toml b/config/theme.toml index 62f9d6c..8a0223e 100644 --- a/config/theme.toml +++ b/config/theme.toml @@ -20,6 +20,10 @@ bold = true fg = "light_cyan" bold = true +[link_invalid] +fg = "red" +bold = true + [socket] fg = "light_magenta" bold = true diff --git a/src/config/theme/app_theme.rs b/src/config/theme/app_theme.rs index 5b05fd3..1b7eab5 100644 --- a/src/config/theme/app_theme.rs +++ b/src/config/theme/app_theme.rs @@ -19,6 +19,8 @@ pub struct RawAppTheme { #[serde(default)] pub link: RawAppStyle, #[serde(default)] + pub link_invalid: RawAppStyle, + #[serde(default)] pub socket: RawAppStyle, #[serde(default)] pub ext: HashMap<String, RawAppStyle>, @@ -32,6 +34,7 @@ impl std::default::Default for RawAppTheme { directory: RawAppStyle::default(), executable: RawAppStyle::default(), link: RawAppStyle::default(), + link_invalid: RawAppStyle::default(), socket: RawAppStyle::default(), ext: HashMap::default(), } @@ -45,6 +48,7 @@ impl Flattenable<AppTheme> for RawAppTheme { let regular = self.regular.to_style_theme(); let directory = self.directory.to_style_theme(); let link = self.link.to_style_theme(); + let link_invalid = self.link_invalid.to_style_theme(); let socket = self.socket.to_style_theme(); let ext: HashMap<String, AppStyle> = self .ext @@ -61,6 +65,7 @@ impl Flattenable<AppTheme> for RawAppTheme { regular, directory, link, + link_invalid, socket, ext, } @@ -74,6 +79,7 @@ pub struct AppTheme { pub directory: AppStyle, pub executable: AppStyle, pub link: AppStyle, + pub link_invalid: AppStyle, pub socket: AppStyle, pub ext: HashMap<String, AppStyle>, } @@ -99,6 +105,9 @@ impl std::default::Default for AppTheme { let link = AppStyle::default() .set_fg(Color::LightCyan) .insert(Modifier::BOLD); + let link_invalid = AppStyle::default() + .set_fg(Color::Red) + .insert(Modifier::BOLD); let socket = AppStyle::default() .set_fg(Color::LightMagenta) .insert(Modifier::BOLD); @@ -110,6 +119,7 @@ impl std::default::Default for AppTheme { regular, directory, link, + link_invalid, socket, ext, } diff --git a/src/fs/metadata.rs b/src/fs/metadata.rs index 60e81f8..0035024 100644 --- a/src/fs/metadata.rs +++ b/src/fs/metadata.rs @@ -9,7 +9,7 @@ pub enum FileType { #[derive(Clone, Debug)] pub enum LinkType { Normal, - Symlink(String), + Symlink(String, bool), // link target, link validity } #[derive(Clone, Debug)] @@ -52,18 +52,19 @@ impl JoshutoMetadata { _ => (FileType::File, None), }; - let _link_type = match symlink_metadata.file_type().is_symlink() { - true => { - let mut link = "".to_string(); + let _link_type = if symlink_metadata.file_type().is_symlink() { + let mut link = "".to_string(); - if let Ok(path) = fs::read_link(path) { - if let Some(s) = path.to_str() { - link = s.to_string(); - } + if let Ok(path) = fs::read_link(path) { + if let Some(s) = path.to_str() { + link = s.to_string(); } - LinkType::Symlink(link) } - false => LinkType::Normal, + + let exists = path.exists(); + LinkType::Symlink(link, exists) + } else { + LinkType::Normal }; #[cfg(unix)] diff --git a/src/ui/widgets/tui_dirlist_detailed.rs b/src/ui/widgets/tui_dirlist_detailed.rs index 4a4dc2a..a43d4f6 100644 --- a/src/ui/widgets/tui_dirlist_detailed.rs +++ b/src/ui/widgets/tui_dirlist_detailed.rs @@ -90,7 +90,7 @@ fn print_entry( }; let symlink_string = match entry.metadata.link_type() { LinkType::Normal => "", - LinkType::Symlink(_) => "-> ", + LinkType::Symlink(_, _) => "-> ", }; let left_label_original = entry.label(); let right_label_original = format!(" {}{} ", symlink_string, size_string); diff --git a/src/ui/widgets/tui_footer.rs b/src/ui/widgets/tui_footer.rs index 1bf9c2a..d340983 100644 --- a/src/ui/widgets/tui_footer.rs +++ b/src/ui/widgets/tui_footer.rs @@ -7,6 +7,7 @@ use tui::widgets::{Paragraph, Widget}; use crate::fs::{JoshutoDirList, LinkType}; use crate::util::format; use crate::util::unix; +use crate::THEME_T; pub struct TuiFooter<'a> { dirlist: &'a JoshutoDirList, @@ -41,9 +42,20 @@ impl<'a> Widget for TuiFooter<'a> { Span::raw(size_str), ]; - if let LinkType::Symlink(s) = entry.metadata.link_type() { - text.push(Span::styled(" -> ", mode_style)); - text.push(Span::styled(s, mode_style)); + if let LinkType::Symlink(target, valid) = entry.metadata.link_type() { + let link_style = if *valid { + Style::default() + .fg(THEME_T.link.fg) + .bg(THEME_T.link.bg) + .add_modifier(THEME_T.link.modifier) + } else { + Style::default() + .fg(THEME_T.link_invalid.fg) + .bg(THEME_T.link_invalid.bg) + .add_modifier(THEME_T.link_invalid.modifier) + }; + text.push(Span::styled(" -> ", link_style)); + text.push(Span::styled(target, link_style)); } Paragraph::new(Spans::from(text)).render(area, buf); diff --git a/src/util/style.rs b/src/util/style.rs index 69a3704..5627444 100644 --- a/src/util/style.rs +++ b/src/util/style.rs @@ -17,10 +17,14 @@ pub fn entry_style(entry: &JoshutoDirEntry) -> Style { .add_modifier(THEME_T.selection.modifier) } else { match linktype { - LinkType::Symlink(_) => Style::default() + LinkType::Symlink(_, true) => Style::default() .fg(THEME_T.link.fg) .bg(THEME_T.link.bg) .add_modifier(THEME_T.link.modifier), + LinkType::Symlink(_, false) => Style::default() + .fg(THEME_T.link_invalid.fg) + .bg(THEME_T.link_invalid.bg) + .add_modifier(THEME_T.link_invalid.modifier), LinkType::Normal => match filetype { FileType::Directory => Style::default() .fg(THEME_T.directory.fg) |