From 4e7e135cb5aeed55afb5c0beece71d503f16d2db Mon Sep 17 00:00:00 2001 From: sxyazi Date: Mon, 26 Feb 2024 10:25:35 +0800 Subject: [PATCH] feat: support `is` rule for `[icon]` (#720) --- yazi-config/src/theme/filetype.rs | 62 ++----------------------------- yazi-config/src/theme/icon.rs | 17 ++++++++- yazi-config/src/theme/is.rs | 61 ++++++++++++++++++++++++++++++ yazi-config/src/theme/mod.rs | 2 + yazi-fm/src/lives/file.rs | 7 +--- 5 files changed, 84 insertions(+), 65 deletions(-) create mode 100644 yazi-config/src/theme/is.rs diff --git a/yazi-config/src/theme/filetype.rs b/yazi-config/src/theme/filetype.rs index 94ffbed0..e61069f5 100644 --- a/yazi-config/src/theme/filetype.rs +++ b/yazi-config/src/theme/filetype.rs @@ -1,14 +1,11 @@ -use std::str::FromStr; - -use anyhow::bail; use serde::{Deserialize, Deserializer}; use yazi_shared::fs::File; -use super::{Color, Style, StyleShadow}; +use super::{Color, Is, Style, StyleShadow}; use crate::Pattern; pub struct Filetype { - pub is: FiletypeIs, + pub is: Is, pub name: Option, pub mime: Option, pub style: Style, @@ -16,18 +13,7 @@ pub struct Filetype { impl Filetype { pub fn matches(&self, file: &File, mime: Option<&str>) -> bool { - let b = match self.is { - FiletypeIs::None => true, - FiletypeIs::Block => file.cha.is_block_device(), - FiletypeIs::Char => file.cha.is_char_device(), - FiletypeIs::Exec => file.cha.is_exec(), - FiletypeIs::Fifo => file.cha.is_fifo(), - FiletypeIs::Link => file.cha.is_link(), - FiletypeIs::Orphan => file.cha.is_orphan(), - FiletypeIs::Sock => file.cha.is_socket(), - FiletypeIs::Sticky => file.cha.is_sticky(), - }; - if !b { + if !self.is.check(&file.cha) { return false; } @@ -48,7 +34,7 @@ impl Filetype { #[derive(Deserialize)] struct FiletypeRule { #[serde(default)] - is: FiletypeIs, + is: Is, name: Option, mime: Option, @@ -101,43 +87,3 @@ impl Filetype { ) } } - -// --- FiletypeIs -#[derive(Default, Deserialize)] -#[serde(try_from = "String")] -pub enum FiletypeIs { - #[default] - None, - Block, - Char, - Exec, - Fifo, - Link, - Orphan, - Sock, - Sticky, -} - -impl FromStr for FiletypeIs { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - Ok(match s { - "block" => Self::Block, - "char" => Self::Char, - "exec" => Self::Exec, - "fifo" => Self::Fifo, - "link" => Self::Link, - "orphan" => Self::Orphan, - "sock" => Self::Sock, - "sticky" => Self::Sticky, - _ => bail!("invalid filetype: {s}"), - }) - } -} - -impl TryFrom for FiletypeIs { - type Error = anyhow::Error; - - fn try_from(s: String) -> Result { Self::from_str(&s) } -} diff --git a/yazi-config/src/theme/icon.rs b/yazi-config/src/theme/icon.rs index c0f78430..c9b0f4db 100644 --- a/yazi-config/src/theme/icon.rs +++ b/yazi-config/src/theme/icon.rs @@ -1,14 +1,26 @@ use serde::{Deserialize, Deserializer}; +use yazi_shared::fs::File; use super::Style; -use crate::{preset::Preset, theme::{Color, StyleShadow}, Pattern}; +use crate::{preset::Preset, theme::{Color, Is, StyleShadow}, Pattern}; pub struct Icon { + pub is: Is, pub name: Pattern, pub text: String, pub style: Style, } +impl Icon { + pub fn matches(&self, file: &File) -> bool { + if !self.is.check(&file.cha) { + return false; + } + + self.name.match_path(&file.url, file.is_dir()) + } +} + impl Icon { pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where @@ -24,6 +36,8 @@ impl Icon { } #[derive(Deserialize)] struct IconRule { + #[serde(default)] + is: Is, name: Pattern, text: String, @@ -45,6 +59,7 @@ impl Icon { .rules .into_iter() .map(|r| Icon { + is: r.is, name: r.name, text: r.text, style: StyleShadow { fg: r.fg, ..Default::default() }.into(), diff --git a/yazi-config/src/theme/is.rs b/yazi-config/src/theme/is.rs new file mode 100644 index 00000000..994d620b --- /dev/null +++ b/yazi-config/src/theme/is.rs @@ -0,0 +1,61 @@ +use std::str::FromStr; + +use anyhow::bail; +use serde::Deserialize; +use yazi_shared::fs::Cha; + +#[derive(Default, Deserialize)] +#[serde(try_from = "String")] +pub enum Is { + #[default] + None, + Block, + Char, + Exec, + Fifo, + Link, + Orphan, + Sock, + Sticky, +} + +impl FromStr for Is { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + Ok(match s { + "block" => Self::Block, + "char" => Self::Char, + "exec" => Self::Exec, + "fifo" => Self::Fifo, + "link" => Self::Link, + "orphan" => Self::Orphan, + "sock" => Self::Sock, + "sticky" => Self::Sticky, + _ => bail!("invalid filetype: {s}"), + }) + } +} + +impl TryFrom for Is { + type Error = anyhow::Error; + + fn try_from(s: String) -> Result { Self::from_str(&s) } +} + +impl Is { + #[inline] + pub fn check(&self, cha: &Cha) -> bool { + match self { + Self::None => true, + Self::Block => cha.is_block_device(), + Self::Char => cha.is_char_device(), + Self::Exec => cha.is_exec(), + Self::Fifo => cha.is_fifo(), + Self::Link => cha.is_link(), + Self::Orphan => cha.is_orphan(), + Self::Sock => cha.is_socket(), + Self::Sticky => cha.is_sticky(), + } + } +} diff --git a/yazi-config/src/theme/mod.rs b/yazi-config/src/theme/mod.rs index ed9aa3df..c3f0b004 100644 --- a/yazi-config/src/theme/mod.rs +++ b/yazi-config/src/theme/mod.rs @@ -1,11 +1,13 @@ mod color; mod filetype; mod icon; +mod is; mod style; mod theme; pub use color::*; pub use filetype::*; pub use icon::*; +pub use is::*; pub use style::*; pub use theme::*; diff --git a/yazi-fm/src/lives/file.rs b/yazi-fm/src/lives/file.rs index 98aebb26..e8c46cc4 100644 --- a/yazi-fm/src/lives/file.rs +++ b/yazi-fm/src/lives/file.rs @@ -58,12 +58,7 @@ impl File { Some(lua.create_string(p.as_path().as_os_str().as_encoded_bytes())).transpose() }); reg.add_method("icon", |lua, me, ()| { - THEME - .icons - .iter() - .find(|&x| x.name.match_path(&me.url, me.is_dir())) - .map(|x| Icon::cast(lua, x)) - .transpose() + THEME.icons.iter().find(|&x| x.matches(me)).map(|x| Icon::cast(lua, x)).transpose() }); reg.add_method("style", |lua, me, ()| { let cx = lua.named_registry_value::("cx")?;