🔨 icon: refactor to use icon by file type

This commit is contained in:
Wei Zhang 2022-07-31 17:06:30 +08:00 committed by Abin Simon
parent 6df27aebad
commit a60ab3d3e4
5 changed files with 74 additions and 42 deletions

View file

@ -1,10 +1,7 @@
use crate::color::Colors;
use crate::display;
use crate::flags::{
ColorOption, Display, Flags, HyperlinkOption, IconOption, IconTheme, Layout, SortOrder,
ThemeOption,
};
use crate::icon::{self, Icons};
use crate::flags::{ColorOption, Display, Flags, HyperlinkOption, Layout, SortOrder, ThemeOption};
use crate::icon::Icons;
use crate::meta::Meta;
use crate::{print_error, print_output, sort, ExitCode};
use std::path::PathBuf;

View file

@ -90,7 +90,7 @@ impl Configurable<Self> for IconOption {
}
/// The flag showing which icon theme to use.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum IconTheme {
Unicode,

View file

@ -36,34 +36,34 @@ impl Icons {
// Check file types
let file_type: FileType = name.file_type();
let icon = match file_type {
FileType::SymLink { is_dir: true } => "\u{f482}", // ""
FileType::SymLink { is_dir: false } => "\u{f481}", // ""
FileType::Socket => "\u{f6a7}", // ""
FileType::Pipe => "\u{f731}", // ""
FileType::CharDevice => "\u{e601}", // ""
FileType::BlockDevice => "\u{fc29}", // "ﰩ"
FileType::Special => "\u{f2dc}", // ""
FileType::SymLink { is_dir: true } => &t.icons_by_filetype.symlink_dir,
FileType::SymLink { is_dir: false } => &t.icons_by_filetype.symlink_file,
FileType::Socket => &t.icons_by_filetype.socket,
FileType::Pipe => &t.icons_by_filetype.pipe,
FileType::CharDevice => &t.icons_by_filetype.device_char,
FileType::BlockDevice => &t.icons_by_filetype.device_block,
FileType::Special => &t.icons_by_filetype.special,
_ => {
// Use the known names
if let Some(icon) = t
.icons_by_name
.get(name.file_name().to_lowercase().as_str())
{
icon
}
// Use the known extensions
else if let Some(icon) = name.extension().and_then(|extension| {
t.icons_by_extension.get(extension.to_lowercase().as_str())
}) {
} else if let Some(icon) = name
.extension()
.and_then(|ext| t.icons_by_extension.get(ext.to_lowercase().as_str()))
{
icon
} else {
match file_type {
FileType::Directory { .. } => &t.default_folder_icon,
FileType::Directory { .. } => &t.icons_by_filetype.dir,
// If a file has no extension and is executable, show an icon.
// Except for Windows, it marks everything as an executable.
#[cfg(not(windows))]
FileType::File { exec: true, .. } => "\u{f489}", // ""
_ => &t.default_file_icon,
FileType::File { exec: true, .. } => {
&t.icons_by_filetype.executable
}
_ => &t.icons_by_filetype.file,
}
}
}

View file

@ -11,7 +11,7 @@ use crate::print_error;
use color::ColorTheme;
use icon::IconTheme;
#[derive(Debug, Deserialize, PartialEq)]
#[derive(Debug, Deserialize, Default, PartialEq)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
@ -20,16 +20,6 @@ pub struct Theme {
pub icon: IconTheme,
}
impl Default for Theme {
fn default() -> Self {
// TODO(zwpaper): check terminal color and return light or dark
Theme {
color: ColorTheme::default(),
icon: IconTheme::default(),
}
}
}
impl Theme {
/// This read theme from file,
/// use the file path if it is absolute

View file

@ -8,31 +8,76 @@ use std::collections::HashMap;
pub struct IconTheme {
pub icons_by_name: HashMap<String, String>,
pub icons_by_extension: HashMap<String, String>,
// pub icons_by_filetype: HashMap<String, String>,
pub default_folder_icon: String,
pub default_file_icon: String,
pub icons_by_filetype: IconByType,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct IconByType {
pub dir: String,
pub file: String,
pub pipe: String,
pub socket: String,
pub executable: String,
pub device_char: String,
pub device_block: String,
pub special: String,
pub symlink_dir: String,
pub symlink_file: String,
}
impl Default for IconTheme {
fn default() -> Self {
// TODO(zwpaper): check terminal color and return light or dark
IconTheme {
icons_by_name: Self::get_default_icons_by_name(),
icons_by_extension: Self::get_default_icons_by_extension(),
default_folder_icon: "\u{f115}".into(),
default_file_icon: "\u{f016}".into(),
icons_by_filetype: IconByType::default(),
}
}
}
impl Default for IconByType {
fn default() -> IconByType {
IconByType {
dir: "\u{f115}".into(), // 
file: "\u{f016}".into(), // 
pipe: "\u{f731}".into(), // 
socket: "\u{f6a7}".into(), // 
executable: "\u{f489}".into(), // 
symlink_dir: "\u{f482}".into(), // 
symlink_file: "\u{f481}".into(), // 
device_char: "\u{e601}".into(), // 
device_block: "\u{fc29}".into(), // ﰩ
special: "\u{f2dc}".into(), // 
}
}
}
impl IconByType {
pub fn unicode() -> Self {
IconByType {
dir: "\u{1f4c2}".into(),
file: "\u{1f4c4}".into(),
pipe: "\u{1f4e9}".into(),
socket: "\u{1f4ec}".into(),
executable: "\u{1f3d7}".into(),
symlink_dir: "\u{1f5c2}".into(),
symlink_file: "\u{1f516}".into(),
device_char: "\u{1f5a8}".into(),
device_block: "\u{1f4bd}".into(),
special: "\u{1f4df}".into(),
}
}
}
impl IconTheme {
pub fn unicode() -> Self {
// TODO(zwpaper): check terminal color and return light or dark
IconTheme {
icons_by_name: HashMap::new(),
icons_by_extension: HashMap::new(),
default_folder_icon: "\u{1f5cb}".into(),
default_file_icon: "\u{1f5c1}".into(),
icons_by_filetype: IconByType::unicode(),
}
}