mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: add hovered icons for files and folders
This commit is contained in:
parent
0efeaf5f64
commit
ec730960ac
5 changed files with 70 additions and 19 deletions
|
|
@ -7,8 +7,9 @@ use crate::{Style, cached_field};
|
||||||
pub struct Icon {
|
pub struct Icon {
|
||||||
inner: &'static yazi_config::Icon,
|
inner: &'static yazi_config::Icon,
|
||||||
|
|
||||||
v_text: Option<Value>,
|
v_text: Option<Value>,
|
||||||
v_style: Option<Value>,
|
v_style: Option<Value>,
|
||||||
|
v_hovered_text: Option<Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for Icon {
|
impl Deref for Icon {
|
||||||
|
|
@ -19,7 +20,7 @@ impl Deref for Icon {
|
||||||
|
|
||||||
impl From<&'static yazi_config::Icon> for Icon {
|
impl From<&'static yazi_config::Icon> for Icon {
|
||||||
fn from(icon: &'static yazi_config::Icon) -> Self {
|
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) {
|
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||||
cached_field!(fields, text, |lua, me| lua.create_string(&me.text));
|
cached_field!(fields, text, |lua, me| lua.create_string(&me.text));
|
||||||
cached_field!(fields, style, |_, me| Ok(Style::from(me.style)));
|
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()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -997,7 +997,7 @@ conds = [
|
||||||
{ if = "dummy", text = "", fg = "#f44336" },
|
{ if = "dummy", text = "", fg = "#f44336" },
|
||||||
|
|
||||||
# Fallback
|
# Fallback
|
||||||
{ if = "dir", text = "", fg = "#03a9f4" },
|
{ if = "dir", text = "", fg = "#03a9f4", hovered_text = "" },
|
||||||
{ if = "exec", text = "", fg = "#8bc34a" },
|
{ if = "exec", text = "", fg = "#8bc34a" },
|
||||||
{ if = "!dir", text = "", fg = "#ffffff" },
|
{ if = "!dir", text = "", fg = "#ffffff" },
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ use crate::Style;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Icon {
|
pub struct Icon {
|
||||||
pub text: String,
|
pub text: String,
|
||||||
pub style: Style,
|
pub style: Style,
|
||||||
|
pub hovered_text: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,15 +132,22 @@ impl<'de> Deserialize<'de> for PatIcons {
|
||||||
{
|
{
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Shadow {
|
struct Shadow {
|
||||||
url: Pattern,
|
url: Pattern,
|
||||||
text: String,
|
text: String,
|
||||||
fg: Option<Color>,
|
fg: Option<Color>,
|
||||||
|
hovered_text: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self(
|
Ok(Self(
|
||||||
<Vec<Shadow>>::deserialize(deserializer)?
|
<Vec<Shadow>>::deserialize(deserializer)?
|
||||||
.into_iter()
|
.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(),
|
.collect(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
@ -162,15 +169,22 @@ impl<'de> Deserialize<'de> for StrIcons {
|
||||||
{
|
{
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Shadow {
|
struct Shadow {
|
||||||
name: String,
|
name: String,
|
||||||
text: String,
|
text: String,
|
||||||
fg: Option<Color>,
|
fg: Option<Color>,
|
||||||
|
hovered_text: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self(
|
Ok(Self(
|
||||||
<Vec<Shadow>>::deserialize(deserializer)?
|
<Vec<Shadow>>::deserialize(deserializer)?
|
||||||
.into_iter()
|
.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(),
|
.collect(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
@ -192,16 +206,47 @@ impl<'de> Deserialize<'de> for CondIcons {
|
||||||
{
|
{
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Shadow {
|
struct Shadow {
|
||||||
r#if: Condition,
|
r#if: Condition,
|
||||||
text: String,
|
text: String,
|
||||||
fg: Option<Color>,
|
fg: Option<Color>,
|
||||||
|
hovered_text: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self(
|
Ok(Self(
|
||||||
<Vec<Shadow>>::deserialize(deserializer)?
|
<Vec<Shadow>>::deserialize(deserializer)?
|
||||||
.into_iter()
|
.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(),
|
.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,8 @@ function Entity:icon()
|
||||||
if not icon then
|
if not icon then
|
||||||
return ""
|
return ""
|
||||||
elseif self._file.is_hovered then
|
elseif self._file.is_hovered then
|
||||||
return icon.text .. " "
|
local text = icon.hovered_text or icon.text
|
||||||
|
return text .. " "
|
||||||
else
|
else
|
||||||
return ui.Line(icon.text .. " "):style(icon.style)
|
return ui.Line(icon.text .. " "):style(icon.style)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue