feat: add hovered icons for files and folders

This commit is contained in:
stickyburn 2026-03-02 00:39:11 -05:00 committed by sxyazi
parent 0efeaf5f64
commit ec730960ac
No known key found for this signature in database
5 changed files with 70 additions and 19 deletions

View file

@ -9,6 +9,7 @@ pub struct Icon {
v_text: Option<Value>,
v_style: Option<Value>,
v_hovered_text: Option<Value>,
}
impl Deref for Icon {
@ -19,7 +20,7 @@ impl Deref for Icon {
impl From<&'static yazi_config::Icon> for Icon {
fn from(icon: &'static yazi_config::Icon) -> Self {
Self { inner: icon, v_text: None, v_style: None }
Self { inner: icon, v_text: None, v_style: None, v_hovered_text: None }
}
}
@ -27,5 +28,8 @@ impl UserData for Icon {
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
cached_field!(fields, text, |lua, me| lua.create_string(&me.text));
cached_field!(fields, style, |_, me| Ok(Style::from(me.style)));
cached_field!(fields, hovered_text, |lua, me| {
me.hovered_text.as_ref().map(|s| lua.create_string(s)).transpose()
});
}
}

View file

@ -997,7 +997,7 @@ conds = [
{ if = "dummy", text = "", fg = "#f44336" },
# Fallback
{ if = "dir", text = "", fg = "#03a9f4" },
{ if = "dir", text = "", fg = "#03a9f4", hovered_text = "" },
{ if = "exec", text = "", fg = "#8bc34a" },
{ if = "!dir", text = "", fg = "#ffffff" },
]

View file

@ -4,4 +4,5 @@ use crate::Style;
pub struct Icon {
pub text: String,
pub style: Style,
pub hovered_text: Option<String>,
}

View file

@ -135,12 +135,19 @@ impl<'de> Deserialize<'de> for PatIcons {
url: Pattern,
text: String,
fg: Option<Color>,
hovered_text: Option<String>,
}
Ok(Self(
<Vec<Shadow>>::deserialize(deserializer)?
.into_iter()
.map(|s| (s.url, I { text: s.text, style: Style { fg: s.fg, ..Default::default() } }))
.map(|s| {
(s.url, I {
text: s.text,
style: Style { fg: s.fg, ..Default::default() },
hovered_text: s.hovered_text,
})
})
.collect(),
))
}
@ -165,12 +172,19 @@ impl<'de> Deserialize<'de> for StrIcons {
name: String,
text: String,
fg: Option<Color>,
hovered_text: Option<String>,
}
Ok(Self(
<Vec<Shadow>>::deserialize(deserializer)?
.into_iter()
.map(|s| (s.name, I { text: s.text, style: Style { fg: s.fg, ..Default::default() } }))
.map(|s| {
(s.name, I {
text: s.text,
style: Style { fg: s.fg, ..Default::default() },
hovered_text: s.hovered_text,
})
})
.collect(),
))
}
@ -195,13 +209,44 @@ impl<'de> Deserialize<'de> for CondIcons {
r#if: Condition,
text: String,
fg: Option<Color>,
hovered_text: Option<String>,
}
Ok(Self(
<Vec<Shadow>>::deserialize(deserializer)?
.into_iter()
.map(|s| (s.r#if, I { text: s.text, style: Style { fg: s.fg, ..Default::default() } }))
.map(|s| {
(s.r#if, I {
text: s.text,
style: Style { fg: s.fg, ..Default::default() },
hovered_text: s.hovered_text,
})
})
.collect(),
))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_icon_struct_with_hovered_text() {
let icon = I {
text: "normal_icon".to_string(),
style: Style::default(),
hovered_text: Some("hovered_icon".to_string()),
};
assert_eq!(icon.text, "normal_icon");
assert_eq!(icon.hovered_text, Some("hovered_icon".to_string()));
}
#[test]
fn test_icon_struct_without_hovered_text() {
let icon =
I { text: "normal_icon".to_string(), style: Style::default(), hovered_text: None };
assert_eq!(icon.text, "normal_icon");
assert_eq!(icon.hovered_text, None);
}
}

View file

@ -30,7 +30,8 @@ function Entity:icon()
if not icon then
return ""
elseif self._file.is_hovered then
return icon.text .. " "
local text = icon.hovered_text or icon.text
return text .. " "
else
return ui.Line(icon.text .. " "):style(icon.style)
end