Allow customizing size scale colours.

Also adjust the selection of the colour depending on the scale used.
 * With decimal prefixes colours change on powers of 1000.
 * With binary or no prefixes colours change on powers of 1024.
This commit is contained in:
Maarten de Vries 2019-11-17 15:50:07 +01:00
parent 89c861f24d
commit 3ef6195ffd
5 changed files with 181 additions and 66 deletions

View File

@ -316,9 +316,29 @@ glob, including keys that happen to be two letters long.
.IP \[bu] 2 .IP \[bu] 2
\f[B]xa\f[], the extended attribute indicator \f[B]xa\f[], the extended attribute indicator
.IP \[bu] 2 .IP \[bu] 2
\f[B]sn\f[], the numbers of a file\[aq]s size \f[B]sn\f[], the numbers of a file\[aq]s size (sets nb, nk, nm, ng and nh)
.IP \[bu] 2 .IP \[bu] 2
\f[B]sb\f[], the units of a file\[aq]s size \f[B]nb\f[], the numbers of a file\[aq]s size if it is lower than 1 KB/Kib
.IP \[bu] 2
\f[B]nk\f[], the numbers of a file\[aq]s size if it is between 1 KB/KiB and 1 MB/MiB
.IP \[bu] 2
\f[B]nm\f[], the numbers of a file\[aq]s size if it is between 1 MB/MiB and 1 GB/GiB
.IP \[bu] 2
\f[B]ng\f[], the numbers of a file\[aq]s size if it is between 1 GB/GiB and 1 TB/TiB
.IP \[bu] 2
\f[B]nt\f[], the numbers of a file\[aq]s size if it is 1 TB/TiB or higher
.IP \[bu] 2
\f[B]sb\f[], the units of a file\[aq]s size (sets ub, uk, um, ug and uh)
.IP \[bu] 2
\f[B]ub\f[], the units of a file\[aq]s size if it is lower than 1 KB/Kib
.IP \[bu] 2
\f[B]uk\f[], the units of a file\[aq]s size if it is between 1 KB/KiB and 1 MB/MiB
.IP \[bu] 2
\f[B]um\f[], the units of a file\[aq]s size if it is between 1 MB/MiB and 1 GB/GiB
.IP \[bu] 2
\f[B]ug\f[], the units of a file\[aq]s size if it is between 1 GB/GiB and 1 TB/TiB
.IP \[bu] 2
\f[B]ut\f[], the units of a file\[aq]s size if it is 1 TB/TiB or higher
.IP \[bu] 2 .IP \[bu] 2
\f[B]df\f[], a device\[aq]s major ID \f[B]df\f[], a device\[aq]s major ID
.IP \[bu] 2 .IP \[bu] 2

View File

@ -323,15 +323,15 @@ mod colour_test {
test!(width_7: [], || Some(80); Both => Ok(Colours::colourful(false))); test!(width_7: [], || Some(80); Both => Ok(Colours::colourful(false)));
test!(width_8: [], || None; Both => Ok(Colours::plain())); test!(width_8: [], || None; Both => Ok(Colours::plain()));
test!(scale_1: ["--color=always", "--color-scale", "--colour-scale"], || None; Last => like Ok(Colours { scale: true, .. })); test!(scale_1: ["--color=always", "--color-scale", "--colour-scale"], || None; Last => Ok(Colours::colourful(true)));
test!(scale_2: ["--color=always", "--color-scale", ], || None; Last => like Ok(Colours { scale: true, .. })); test!(scale_2: ["--color=always", "--color-scale", ], || None; Last => Ok(Colours::colourful(true)));
test!(scale_3: ["--color=always", "--colour-scale"], || None; Last => like Ok(Colours { scale: true, .. })); test!(scale_3: ["--color=always", "--colour-scale"], || None; Last => Ok(Colours::colourful(true)));
test!(scale_4: ["--color=always", ], || None; Last => like Ok(Colours { scale: false, .. })); test!(scale_4: ["--color=always", ], || None; Last => Ok(Colours::colourful(false)));
test!(scale_5: ["--color=always", "--color-scale", "--colour-scale"], || None; Complain => err Misfire::Duplicate(Flag::Long("color-scale"), Flag::Long("colour-scale"))); test!(scale_5: ["--color=always", "--color-scale", "--colour-scale"], || None; Complain => err Misfire::Duplicate(Flag::Long("color-scale"), Flag::Long("colour-scale")));
test!(scale_6: ["--color=always", "--color-scale", ], || None; Complain => like Ok(Colours { scale: true, .. })); test!(scale_6: ["--color=always", "--color-scale", ], || None; Complain => Ok(Colours::colourful(true)));
test!(scale_7: ["--color=always", "--colour-scale"], || None; Complain => like Ok(Colours { scale: true, .. })); test!(scale_7: ["--color=always", "--colour-scale"], || None; Complain => Ok(Colours::colourful(true)));
test!(scale_8: ["--color=always", ], || None; Complain => like Ok(Colours { scale: false, .. })); test!(scale_8: ["--color=always", ], || None; Complain => Ok(Colours::colourful(false)));
} }
@ -461,8 +461,33 @@ mod customs_test {
test!(exa_sf: ls "", exa "sf=38;5;111" => colours c -> { c.perms.special_other = Fixed(111).normal(); }); test!(exa_sf: ls "", exa "sf=38;5;111" => colours c -> { c.perms.special_other = Fixed(111).normal(); });
test!(exa_xa: ls "", exa "xa=38;5;112" => colours c -> { c.perms.attribute = Fixed(112).normal(); }); test!(exa_xa: ls "", exa "xa=38;5;112" => colours c -> { c.perms.attribute = Fixed(112).normal(); });
test!(exa_sn: ls "", exa "sn=38;5;113" => colours c -> { c.size.numbers = Fixed(113).normal(); }); test!(exa_sn: ls "", exa "sn=38;5;113" => colours c -> {
test!(exa_sb: ls "", exa "sb=38;5;114" => colours c -> { c.size.unit = Fixed(114).normal(); }); c.size.number_byte = Fixed(113).normal();
c.size.number_kilo = Fixed(113).normal();
c.size.number_mega = Fixed(113).normal();
c.size.number_giga = Fixed(113).normal();
c.size.number_huge = Fixed(113).normal();
});
test!(exa_sb: ls "", exa "sb=38;5;114" => colours c -> {
c.size.unit_byte = Fixed(114).normal();
c.size.unit_kilo = Fixed(114).normal();
c.size.unit_mega = Fixed(114).normal();
c.size.unit_giga = Fixed(114).normal();
c.size.unit_huge = Fixed(114).normal();
});
test!(exa_nb: ls "", exa "nb=38;5;115" => colours c -> { c.size.number_byte = Fixed(115).normal(); });
test!(exa_nk: ls "", exa "nk=38;5;116" => colours c -> { c.size.number_kilo = Fixed(116).normal(); });
test!(exa_nm: ls "", exa "nm=38;5;117" => colours c -> { c.size.number_mega = Fixed(117).normal(); });
test!(exa_ng: ls "", exa "ng=38;5;118" => colours c -> { c.size.number_giga = Fixed(118).normal(); });
test!(exa_nh: ls "", exa "nh=38;5;119" => colours c -> { c.size.number_huge = Fixed(119).normal(); });
test!(exa_ub: ls "", exa "ub=38;5;115" => colours c -> { c.size.unit_byte = Fixed(115).normal(); });
test!(exa_uk: ls "", exa "uk=38;5;116" => colours c -> { c.size.unit_kilo = Fixed(116).normal(); });
test!(exa_um: ls "", exa "um=38;5;117" => colours c -> { c.size.unit_mega = Fixed(117).normal(); });
test!(exa_ug: ls "", exa "ug=38;5;118" => colours c -> { c.size.unit_giga = Fixed(118).normal(); });
test!(exa_uh: ls "", exa "uh=38;5;119" => colours c -> { c.size.unit_huge = Fixed(119).normal(); });
test!(exa_df: ls "", exa "df=38;5;115" => colours c -> { c.size.major = Fixed(115).normal(); }); test!(exa_df: ls "", exa "df=38;5;115" => colours c -> { c.size.major = Fixed(115).normal(); });
test!(exa_ds: ls "", exa "ds=38;5;116" => colours c -> { c.size.minor = Fixed(116).normal(); }); test!(exa_ds: ls "", exa "ds=38;5;116" => colours c -> { c.size.minor = Fixed(116).normal(); });

View File

@ -4,6 +4,7 @@ use locale::Numeric as NumericLocale;
use fs::fields as f; use fs::fields as f;
use output::cell::{TextCell, DisplayWidth}; use output::cell::{TextCell, DisplayWidth};
use output::table::SizeFormat; use output::table::SizeFormat;
use number_prefix::Prefix;
@ -21,13 +22,19 @@ impl f::Size {
SizeFormat::DecimalBytes => NumberPrefix::decimal(size as f64), SizeFormat::DecimalBytes => NumberPrefix::decimal(size as f64),
SizeFormat::BinaryBytes => NumberPrefix::binary(size as f64), SizeFormat::BinaryBytes => NumberPrefix::binary(size as f64),
SizeFormat::JustBytes => { SizeFormat::JustBytes => {
// Use the binary prefix to select a style.
let prefix = match NumberPrefix::binary(size as f64) {
Standalone(_) => None,
Prefixed(p, _) => Some(p),
};
// But format the number directly using the locale.
let string = numerics.format_int(size); let string = numerics.format_int(size);
return TextCell::paint(colours.size(size), string); return TextCell::paint(colours.size(prefix), string);
}, },
}; };
let (prefix, n) = match result { let (prefix, n) = match result {
Standalone(b) => return TextCell::paint(colours.size(b as u64), b.to_string()), Standalone(b) => return TextCell::paint(colours.size(None), b.to_string()),
Prefixed(p, n) => (p, n) Prefixed(p, n) => (p, n)
}; };
@ -42,8 +49,8 @@ impl f::Size {
TextCell { TextCell {
width, width,
contents: vec![ contents: vec![
colours.size(size).paint(number), colours.size(Some(prefix)).paint(number),
colours.unit().paint(symbol), colours.unit(Some(prefix)).paint(symbol),
].into(), ].into(),
} }
} }
@ -66,10 +73,9 @@ impl f::DeviceIDs {
} }
} }
pub trait Colours { pub trait Colours {
fn size(&self, size: u64) -> Style; fn size(&self, prefix: Option<Prefix>) -> Style;
fn unit(&self) -> Style; fn unit(&self, prefix: Option<Prefix>) -> Style;
fn no_size(&self) -> Style; fn no_size(&self) -> Style;
fn major(&self) -> Style; fn major(&self) -> Style;
@ -88,13 +94,14 @@ pub mod test {
use locale::Numeric as NumericLocale; use locale::Numeric as NumericLocale;
use ansi_term::Colour::*; use ansi_term::Colour::*;
use ansi_term::Style; use ansi_term::Style;
use number_prefix::Prefix;
struct TestColours; struct TestColours;
impl Colours for TestColours { impl Colours for TestColours {
fn size(&self, _size: u64) -> Style { Fixed(66).normal() } fn size(&self, _prefix: Option<Prefix>) -> Style { Fixed(66).normal() }
fn unit(&self) -> Style { Fixed(77).bold() } fn unit(&self, _prefix: Option<Prefix>) -> Style { Fixed(77).bold() }
fn no_size(&self) -> Style { Black.italic() } fn no_size(&self) -> Style { Black.italic() }
fn major(&self) -> Style { Blue.on(Red) } fn major(&self) -> Style { Blue.on(Red) }

View File

@ -10,7 +10,6 @@ use style::lsc::Pair;
#[derive(Debug, Default, PartialEq)] #[derive(Debug, Default, PartialEq)]
pub struct Colours { pub struct Colours {
pub colourful: bool, pub colourful: bool,
pub scale: bool,
pub filekinds: FileKinds, pub filekinds: FileKinds,
pub perms: Permissions, pub perms: Permissions,
@ -67,17 +66,20 @@ pub struct Permissions {
#[derive(Clone, Copy, Debug, Default, PartialEq)] #[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Size { pub struct Size {
pub numbers: Style,
pub unit: Style,
pub major: Style, pub major: Style,
pub minor: Style, pub minor: Style,
pub scale_byte: Style, pub number_byte: Style,
pub scale_kilo: Style, pub number_kilo: Style,
pub scale_mega: Style, pub number_mega: Style,
pub scale_giga: Style, pub number_giga: Style,
pub scale_huge: Style, pub number_huge: Style,
pub unit_byte: Style,
pub unit_kilo: Style,
pub unit_mega: Style,
pub unit_giga: Style,
pub unit_huge: Style,
} }
#[derive(Clone, Copy, Debug, Default, PartialEq)] #[derive(Clone, Copy, Debug, Default, PartialEq)]
@ -112,7 +114,6 @@ impl Colours {
pub fn colourful(scale: bool) -> Colours { pub fn colourful(scale: bool) -> Colours {
Colours { Colours {
colourful: true, colourful: true,
scale,
filekinds: FileKinds { filekinds: FileKinds {
normal: Style::default(), normal: Style::default(),
@ -146,19 +147,7 @@ impl Colours {
attribute: Style::default(), attribute: Style::default(),
}, },
size: Size { size: Size::colourful(scale),
numbers: Green.bold(),
unit: Green.normal(),
major: Green.bold(),
minor: Green.normal(),
scale_byte: Fixed(118).normal(),
scale_kilo: Fixed(190).normal(),
scale_mega: Fixed(226).normal(),
scale_giga: Fixed(220).normal(),
scale_huge: Fixed(214).normal(),
},
users: Users { users: Users {
user_you: Yellow.bold(), user_you: Yellow.bold(),
@ -195,6 +184,55 @@ impl Colours {
} }
} }
impl Size {
pub fn colourful(scale: bool) -> Self {
if scale {
Self::colourful_scale()
} else {
Self::colourful_plain()
}
}
fn colourful_plain() -> Self {
Self {
major: Green.bold(),
minor: Green.normal(),
number_byte: Green.bold(),
number_kilo: Green.bold(),
number_mega: Green.bold(),
number_giga: Green.bold(),
number_huge: Green.bold(),
unit_byte: Green.normal(),
unit_kilo: Green.normal(),
unit_mega: Green.normal(),
unit_giga: Green.normal(),
unit_huge: Green.normal(),
}
}
fn colourful_scale() -> Self {
Self {
major: Green.bold(),
minor: Green.normal(),
number_byte: Fixed(118).normal(),
number_kilo: Fixed(190).normal(),
number_mega: Fixed(226).normal(),
number_giga: Fixed(220).normal(),
number_huge: Fixed(214).normal(),
unit_byte: Green.normal(),
unit_kilo: Green.normal(),
unit_mega: Green.normal(),
unit_giga: Green.normal(),
unit_huge: Green.normal(),
}
}
}
/// Some of the styles are **overlays**: although they have the same attribute /// Some of the styles are **overlays**: although they have the same attribute
/// set as regular styles (foreground and background colours, bold, underline, /// set as regular styles (foreground and background colours, bold, underline,
@ -270,8 +308,18 @@ impl Colours {
"sf" => self.perms.special_other = pair.to_style(), "sf" => self.perms.special_other = pair.to_style(),
"xa" => self.perms.attribute = pair.to_style(), "xa" => self.perms.attribute = pair.to_style(),
"sn" => self.size.numbers = pair.to_style(), "sn" => self.set_number_style(pair.to_style()),
"sb" => self.size.unit = pair.to_style(), "sb" => self.set_unit_style(pair.to_style()),
"nb" => self.size.number_byte = pair.to_style(),
"nk" => self.size.number_kilo = pair.to_style(),
"nm" => self.size.number_mega = pair.to_style(),
"ng" => self.size.number_giga = pair.to_style(),
"nh" => self.size.number_huge = pair.to_style(),
"ub" => self.size.unit_byte = pair.to_style(),
"uk" => self.size.unit_kilo = pair.to_style(),
"um" => self.size.unit_mega = pair.to_style(),
"ug" => self.size.unit_giga = pair.to_style(),
"uh" => self.size.unit_huge = pair.to_style(),
"df" => self.size.major = pair.to_style(), "df" => self.size.major = pair.to_style(),
"ds" => self.size.minor = pair.to_style(), "ds" => self.size.minor = pair.to_style(),
@ -302,6 +350,22 @@ impl Colours {
} }
true true
} }
pub fn set_number_style(&mut self, style: Style) {
self.size.number_byte = style;
self.size.number_kilo = style;
self.size.number_mega = style;
self.size.number_giga = style;
self.size.number_huge = style;
}
pub fn set_unit_style(&mut self, style: Style) {
self.size.unit_byte = style;
self.size.unit_kilo = style;
self.size.unit_mega = style;
self.size.unit_giga = style;
self.size.unit_huge = style;
}
} }
@ -360,30 +424,28 @@ impl render::PermissionsColours for Colours {
} }
impl render::SizeColours for Colours { impl render::SizeColours for Colours {
fn size(&self, size: u64) -> Style { fn size(&self, prefix: Option<number_prefix::Prefix>) -> Style {
if self.scale { use number_prefix::Prefix::*;
if size < 1024 { match prefix {
self.size.scale_byte None => self.size.number_byte,
} Some(Kilo) | Some(Kibi) => self.size.number_kilo,
else if size < 1024 * 1024 { Some(Mega) | Some(Mibi) => self.size.number_mega,
self.size.scale_kilo Some(Giga) | Some(Gibi) => self.size.number_giga,
} Some(_) => self.size.number_huge,
else if size < 1024 * 1024 * 1024 { }
self.size.scale_mega }
}
else if size < 1024 * 1024 * 1024 * 1024 { fn unit(&self, prefix: Option<number_prefix::Prefix>) -> Style {
self.size.scale_giga use number_prefix::Prefix::*;
} match prefix {
else { None => self.size.unit_byte,
self.size.scale_huge Some(Kilo) | Some(Kibi) => self.size.unit_kilo,
} Some(Mega) | Some(Mibi) => self.size.unit_mega,
} Some(Giga) | Some(Gibi) => self.size.unit_giga,
else { Some(_) => self.size.unit_huge,
self.size.numbers
} }
} }
fn unit(&self) -> Style { self.size.unit }
fn no_size(&self) -> Style { self.punctuation } fn no_size(&self) -> Style { self.punctuation }
fn major(&self) -> Style { self.size.major } fn major(&self) -> Style { self.size.major }
fn comma(&self) -> Style { self.punctuation } fn comma(&self) -> Style { self.punctuation }

View File

@ -1,5 +1,6 @@
mod colours; mod colours;
pub use self::colours::Colours; pub use self::colours::Colours;
pub use self::colours::Size as SizeColours;
mod lsc; mod lsc;
pub use self::lsc::LSColors; pub use self::lsc::LSColors;