summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDLFW <daniel@llin.info>2021-06-28 02:56:28 +0200
committerGitHub <noreply@github.com>2021-06-27 20:56:28 -0400
commit8cefdc24500864993e66d28ba198070906161b67 (patch)
tree6f81e82b1a5777601fa55cebd6c0c9c187fec105
parentfe87911dbbdd0c20acef825a0bb6213e011fca02 (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.toml4
-rw-r--r--src/config/theme/app_theme.rs10
-rw-r--r--src/fs/metadata.rs21
-rw-r--r--src/ui/widgets/tui_dirlist_detailed.rs2
-rw-r--r--src/ui/widgets/tui_footer.rs18
-rw-r--r--src/util/style.rs6
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)