Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

theme: ✨ add default and update the others optional #591

Merged
merged 6 commits into from
Jan 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added support for the MISSING / mi= dircolors variable for broken symlink targets.
- Add support for theme from [zwpaper](https://github.com/zwpaper) [#452](https://github.com/Peltoche/lsd/pull/452)
- Update theme to support partial themes [zwpaper](https://github.com/zwpaper) [#591](https://github.com/Peltoche/lsd/pull/591)
- Update minimal rust version to 1.42.0 from [zwpaper](https://github.com/zwpaper) [#534](https://github.com/Peltoche/lsd/issues/534)
- [`NO_COLOR`](https://no-color.org/) environment variable support from [AnInternetTroll](https://github.com/aninternettroll)
### Changed
Expand All @@ -17,7 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add `--config-file` flag to read configuration file from a custom location
- Clarify custom date format for `date` field in configuration file in the README.
### Fixed
- Support all `strftime` like formatting [#532](https://github.com/Peltoche/lsd/issues/532)
- Support all `strftime` like formatting [#532](https://github.com/Peltoche/lsd/issues/532)

## [0.20.1] - 2021-03-07
### Fixed
Expand Down
18 changes: 12 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,12 @@ Check [Theme file content](#theme-file-content) for details.
### Theme file content

Theme file use the [crossterm](https://crates.io/crates/crossterm)
configure the colors, check [crossterm](https://docs.rs/crossterm/0.20.0/crossterm/style/enum.Color.html)
for the supported colors.
to configure the colors, check [crossterm](https://docs.rs/crossterm/0.20.0/crossterm/style/enum.Color.html)
for supported colors.

Color table: https://upload.wikimedia.org/wikipedia/commons/1/15/Xterm_256color_chart.svg

Please notice that color value would ignore case, both lowercase and UPPERCASE is supported.
Please notice that color values would ignore the case, both lowercase and UPPERCASE is supported.

This is the default theme scheme shipped with `lsd`.

Expand Down Expand Up @@ -264,6 +264,12 @@ links:
tree-edge: 245
```

When creating a theme for `lsd`, you can specify any part of the default theme,
and then change its colors, the items missed would fallback to use the default colors.

Please also notice that an empty theme is **NOT** supported due to
[a bug in serde lib](https://github.com/dtolnay/serde-yaml/issues/86).

## External Configurations

### Required
Expand Down Expand Up @@ -306,11 +312,11 @@ To check if the font you are using is setup correctly, try running the following
```sh
echo $'\uf115'
```

### Icons missing or not rendering correctly using PuTTY/KiTTY on Windows

First of all, make sure a patched font is installed and PuTTY/KiTTY is configurated to use it, please check [Prerequisites](#prerequisites).

There are problems for PuTTY/KiTTY to show 2 char wide icons, make sure using a 1 char wide font like [Hack Regular Nerd Font Complete Mono Windows Compatible](https://github.com/ryanoasis/nerd-fonts/blob/master/patched-fonts/Hack/Regular/complete/Hack%20Regular%20Nerd%20Font%20Complete%20Mono%20Windows%20Compatible.ttf), check [this issue](https://github.com/Peltoche/lsd/issues/331) for detail.

### Colors
Expand Down
16 changes: 7 additions & 9 deletions src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,12 @@ impl Elem {

Elem::User => theme.user,
Elem::Group => theme.group,

Elem::NonFile => theme.size.none,
Elem::FileLarge => theme.size.large,
Elem::FileMedium => theme.size.medium,
Elem::FileSmall => theme.size.small,

Elem::INode { valid: false } => theme.inode.valid,
Elem::INode { valid: true } => theme.inode.invalid,

Elem::TreeEdge => theme.tree_edge,
Elem::Links { valid: false } => theme.links.invalid,
Elem::Links { valid: true } => theme.links.valid,
Expand Down Expand Up @@ -187,7 +184,7 @@ impl Colors {

fn style_default(&self, elem: &Elem) -> ContentStyle {
if let Some(t) = &self.theme {
let style_fg = ContentStyle::default().with(elem.get_color(&t));
let style_fg = ContentStyle::default().with(elem.get_color(t));
if elem.has_suid() {
style_fg.on(Color::AnsiValue(124)) // Red3
} else {
Expand Down Expand Up @@ -254,10 +251,11 @@ fn to_content_style(ls: &lscolors::Style) -> ContentStyle {
lscolors::style::Color::Cyan => Color::DarkCyan,
lscolors::style::Color::White => Color::White,
};
let mut style = ContentStyle::default();

style.foreground_color = ls.foreground.as_ref().map(to_crossterm_color);
style.background_color = ls.background.as_ref().map(to_crossterm_color);
let mut style = ContentStyle {
foreground_color: ls.foreground.as_ref().map(to_crossterm_color),
background_color: ls.background.as_ref().map(to_crossterm_color),
..ContentStyle::default()
};

if ls.font_style.bold {
style.attributes.set(Attribute::Bold);
Expand Down Expand Up @@ -381,7 +379,7 @@ mod elem {
}

#[test]
fn test_default_file() {
fn test_default_theme_color() {
assert_eq!(
Elem::File {
exec: true,
Expand Down
185 changes: 136 additions & 49 deletions src/color/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::path::Path;
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct Theme {
pub user: Color,
pub group: Color,
Expand All @@ -30,6 +31,7 @@ pub struct Theme {
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct Permission {
pub read: Color,
pub write: Color,
Expand All @@ -41,6 +43,7 @@ pub struct Permission {
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct FileType {
pub file: File,
pub dir: Dir,
Expand All @@ -55,6 +58,7 @@ pub struct FileType {
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct File {
pub exec_uid: Color,
pub uid_no_exec: Color,
Expand All @@ -65,6 +69,7 @@ pub struct File {
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct Dir {
pub uid: Color,
pub no_uid: Color,
Expand All @@ -73,6 +78,7 @@ pub struct Dir {
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct Symlink {
pub default: Color,
pub broken: Color,
Expand All @@ -82,6 +88,7 @@ pub struct Symlink {
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct Date {
pub hour_old: Color,
pub day_old: Color,
Expand All @@ -91,6 +98,7 @@ pub struct Date {
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct Size {
pub none: Color,
pub small: Color,
Expand All @@ -101,6 +109,7 @@ pub struct Size {
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct INode {
pub valid: Color,
pub invalid: Color,
Expand All @@ -109,14 +118,97 @@ pub struct INode {
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct Links {
pub valid: Color,
pub invalid: Color,
}

impl Default for Permission {
fn default() -> Self {
Permission {
read: Color::DarkGreen,
write: Color::DarkYellow,
exec: Color::DarkRed,
exec_sticky: Color::AnsiValue(5),
no_access: Color::AnsiValue(245), // Grey
}
}
}
impl Default for FileType {
fn default() -> Self {
Theme::default_dark().file_type
FileType {
file: File::default(),
dir: Dir::default(),
symlink: Symlink::default(),
pipe: Color::AnsiValue(44), // DarkTurquoise
block_device: Color::AnsiValue(44), // DarkTurquoise
char_device: Color::AnsiValue(172), // Orange3
socket: Color::AnsiValue(44), // DarkTurquoise
special: Color::AnsiValue(44), // DarkTurquoise
}
}
}
impl Default for File {
fn default() -> Self {
File {
exec_uid: Color::AnsiValue(40), // Green3
uid_no_exec: Color::AnsiValue(184), // Yellow3
exec_no_uid: Color::AnsiValue(40), // Green3
no_exec_no_uid: Color::AnsiValue(184), // Yellow3
}
}
}
impl Default for Dir {
fn default() -> Self {
Dir {
uid: Color::AnsiValue(33), // DodgerBlue1
no_uid: Color::AnsiValue(33), // DodgerBlue1
}
}
}
impl Default for Symlink {
fn default() -> Self {
Symlink {
default: Color::AnsiValue(44), // DarkTurquoise
broken: Color::AnsiValue(124), // Red3
missing_target: Color::AnsiValue(124), // Red3
}
}
}
impl Default for Date {
fn default() -> Self {
Date {
hour_old: Color::AnsiValue(40), // Green3
day_old: Color::AnsiValue(42), // SpringGreen2
older: Color::AnsiValue(36), // DarkCyan
}
}
}
impl Default for Size {
fn default() -> Self {
Size {
none: Color::AnsiValue(245), // Grey
small: Color::AnsiValue(229), // Wheat1
medium: Color::AnsiValue(216), // LightSalmon1
large: Color::AnsiValue(172), // Orange3
}
}
}
impl Default for INode {
fn default() -> Self {
INode {
valid: Color::AnsiValue(13), // Pink
invalid: Color::AnsiValue(245), // Grey
}
}
}
impl Default for Links {
fn default() -> Self {
Links {
valid: Color::AnsiValue(13), // Pink
invalid: Color::AnsiValue(245), // Grey
}
}
}

Expand Down Expand Up @@ -181,54 +273,12 @@ impl Theme {
Theme {
user: Color::AnsiValue(230), // Cornsilk1
group: Color::AnsiValue(187), // LightYellow3
permission: Permission {
read: Color::DarkGreen,
write: Color::DarkYellow,
exec: Color::DarkRed,
exec_sticky: Color::AnsiValue(5),
no_access: Color::AnsiValue(245), // Grey
},
file_type: FileType {
file: File {
exec_uid: Color::AnsiValue(40), // Green3
uid_no_exec: Color::AnsiValue(184), // Yellow3
exec_no_uid: Color::AnsiValue(40), // Green3
no_exec_no_uid: Color::AnsiValue(184), // Yellow3
},
dir: Dir {
uid: Color::AnsiValue(33), // DodgerBlue1
no_uid: Color::AnsiValue(33), // DodgerBlue1
},
pipe: Color::AnsiValue(44), // DarkTurquoise
symlink: Symlink {
default: Color::AnsiValue(44), // DarkTurquoise
broken: Color::AnsiValue(124), // Red3
missing_target: Color::AnsiValue(124), // Red3
},
block_device: Color::AnsiValue(44), // DarkTurquoise
char_device: Color::AnsiValue(172), // Orange3
socket: Color::AnsiValue(44), // DarkTurquoise
special: Color::AnsiValue(44), // DarkTurquoise
},
date: Date {
hour_old: Color::AnsiValue(40), // Green3
day_old: Color::AnsiValue(42), // SpringGreen2
older: Color::AnsiValue(36), // DarkCyan
},
size: Size {
none: Color::AnsiValue(245), // Grey
small: Color::AnsiValue(229), // Wheat1
medium: Color::AnsiValue(216), // LightSalmon1
large: Color::AnsiValue(172), // Orange3
},
inode: INode {
valid: Color::AnsiValue(13), // Pink
invalid: Color::AnsiValue(245), // Grey
},
links: Links {
valid: Color::AnsiValue(13), // Pink
invalid: Color::AnsiValue(245), // Grey
},
permission: Permission::default(),
file_type: FileType::default(),
date: Date::default(),
size: Size::default(),
inode: INode::default(),
links: Links::default(),
tree_edge: Color::AnsiValue(245), // Grey
}
}
Expand Down Expand Up @@ -290,4 +340,41 @@ mod tests {
Theme::from_path(theme.to_str().unwrap()).unwrap()
);
}

#[test]
fn test_empty_theme_return_default() {
// Must contain one field at least
// ref https://github.com/dtolnay/serde-yaml/issues/86
let empty_theme = Theme::with_yaml("user: 230".into()).unwrap(); // 230 is the default value
let default_theme = Theme::default_dark();
assert_eq!(empty_theme, default_theme);
}

#[test]
fn test_first_level_theme_return_default_but_changed() {
// Must contain one field at least
// ref https://github.com/dtolnay/serde-yaml/issues/86
let empty_theme = Theme::with_yaml("user: 130".into()).unwrap();
let mut theme = Theme::default_dark();
use crossterm::style::Color;
theme.user = Color::AnsiValue(130);
assert_eq!(empty_theme, theme);
}

#[test]
fn test_second_level_theme_return_default_but_changed() {
// Must contain one field at least
// ref https://github.com/dtolnay/serde-yaml/issues/86
let empty_theme = Theme::with_yaml(
r#"---
permission:
read: 130"#
.into(),
)
.unwrap();
let mut theme = Theme::default_dark();
use crossterm::style::Color;
theme.permission.read = Color::AnsiValue(130);
assert_eq!(empty_theme, theme);
}
}
2 changes: 1 addition & 1 deletion src/meta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ impl Meta {
}
}

fn calculate_total_file_size(path: &PathBuf) -> u64 {
fn calculate_total_file_size(path: &Path) -> u64 {
let metadata = path.symlink_metadata();
let metadata = match metadata {
Ok(meta) => meta,
Expand Down
Loading