From 89d73954fd3820ec5a324503a660e29280520174 Mon Sep 17 00:00:00 2001 From: Andy Wang <128531452+Andy-W-Developer@users.noreply.github.com> Date: Sat, 24 Feb 2024 16:55:33 +1300 Subject: [PATCH] feat: add FiletypeIs to icons --- yazi-config/src/theme/icon.rs | 69 +++++++++++++++++++++++++++++++++++ yazi-fm/src/lives/file.rs | 2 +- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/yazi-config/src/theme/icon.rs b/yazi-config/src/theme/icon.rs index c0f78430..3933b5b9 100644 --- a/yazi-config/src/theme/icon.rs +++ b/yazi-config/src/theme/icon.rs @@ -1,14 +1,40 @@ +use std::str::FromStr; + +use anyhow::bail; use serde::{Deserialize, Deserializer}; +use yazi_shared::fs::File; use super::Style; use crate::{preset::Preset, theme::{Color, StyleShadow}, Pattern}; pub struct Icon { + pub is: FiletypeIs, pub name: Pattern, pub text: String, pub style: Style, } +impl Icon { + pub fn matches(&self, file: &File) -> 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 { + 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 +50,8 @@ impl Icon { } #[derive(Deserialize)] struct IconRule { + #[serde(default)] + is: FiletypeIs, name: Pattern, text: String, @@ -45,6 +73,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(), @@ -53,3 +82,43 @@ impl Icon { ) } } + +// --- 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-fm/src/lives/file.rs b/yazi-fm/src/lives/file.rs index 98aebb26..128f944c 100644 --- a/yazi-fm/src/lives/file.rs +++ b/yazi-fm/src/lives/file.rs @@ -61,7 +61,7 @@ impl File { THEME .icons .iter() - .find(|&x| x.name.match_path(&me.url, me.is_dir())) + .find(|&x| x.matches(me)) .map(|x| Icon::cast(lua, x)) .transpose() });