Skip to content

Commit

Permalink
Allow customizing size scale colours.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
de-vri-es committed Nov 17, 2019
1 parent 89c861f commit 3ef6195
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 65 deletions.
24 changes: 22 additions & 2 deletions contrib/man/exa.1
Original file line number Diff line number Diff line change
Expand Up @@ -316,9 +316,29 @@ glob, including keys that happen to be two letters long.
.IP \[bu] 2
\f[B]xa\f[], the extended attribute indicator
.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
\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
\f[B]df\f[], a device\[aq]s major ID
.IP \[bu] 2
Expand Down
43 changes: 34 additions & 9 deletions src/options/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,15 +323,15 @@ mod colour_test {
test!(width_7: [], || Some(80); Both => Ok(Colours::colourful(false)));
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_2: ["--color=always", "--color-scale", ], || None; Last => like Ok(Colours { scale: true, .. }));
test!(scale_3: ["--color=always", "--colour-scale"], || None; Last => like Ok(Colours { scale: true, .. }));
test!(scale_4: ["--color=always", ], || None; Last => like Ok(Colours { scale: false, .. }));
test!(scale_1: ["--color=always", "--color-scale", "--colour-scale"], || None; Last => Ok(Colours::colourful(true)));
test!(scale_2: ["--color=always", "--color-scale", ], || None; Last => Ok(Colours::colourful(true)));
test!(scale_3: ["--color=always", "--colour-scale"], || None; Last => Ok(Colours::colourful(true)));
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_6: ["--color=always", "--color-scale", ], || None; Complain => like Ok(Colours { scale: true, .. }));
test!(scale_7: ["--color=always", "--colour-scale"], || None; Complain => like Ok(Colours { scale: true, .. }));
test!(scale_8: ["--color=always", ], || None; Complain => like Ok(Colours { scale: false, .. }));
test!(scale_6: ["--color=always", "--color-scale", ], || None; Complain => Ok(Colours::colourful(true)));
test!(scale_7: ["--color=always", "--colour-scale"], || None; Complain => Ok(Colours::colourful(true)));
test!(scale_8: ["--color=always", ], || None; Complain => Ok(Colours::colourful(false)));
}


Expand Down Expand Up @@ -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_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_sb: ls "", exa "sb=38;5;114" => colours c -> { c.size.unit = Fixed(114).normal(); });
test!(exa_sn: ls "", exa "sn=38;5;113" => colours c -> {
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_ds: ls "", exa "ds=38;5;116" => colours c -> { c.size.minor = Fixed(116).normal(); });

Expand Down
25 changes: 16 additions & 9 deletions src/output/render/size.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use locale::Numeric as NumericLocale;
use fs::fields as f;
use output::cell::{TextCell, DisplayWidth};
use output::table::SizeFormat;
use number_prefix::Prefix;



Expand All @@ -21,13 +22,19 @@ impl f::Size {
SizeFormat::DecimalBytes => NumberPrefix::decimal(size as f64),
SizeFormat::BinaryBytes => NumberPrefix::binary(size as f64),
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);
return TextCell::paint(colours.size(size), string);
return TextCell::paint(colours.size(prefix), string);
},
};

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)
};

Expand All @@ -42,8 +49,8 @@ impl f::Size {
TextCell {
width,
contents: vec![
colours.size(size).paint(number),
colours.unit().paint(symbol),
colours.size(Some(prefix)).paint(number),
colours.unit(Some(prefix)).paint(symbol),
].into(),
}
}
Expand All @@ -66,10 +73,9 @@ impl f::DeviceIDs {
}
}


pub trait Colours {
fn size(&self, size: u64) -> Style;
fn unit(&self) -> Style;
fn size(&self, prefix: Option<Prefix>) -> Style;
fn unit(&self, prefix: Option<Prefix>) -> Style;
fn no_size(&self) -> Style;

fn major(&self) -> Style;
Expand All @@ -88,13 +94,14 @@ pub mod test {
use locale::Numeric as NumericLocale;
use ansi_term::Colour::*;
use ansi_term::Style;
use number_prefix::Prefix;


struct TestColours;

impl Colours for TestColours {
fn size(&self, _size: u64) -> Style { Fixed(66).normal() }
fn unit(&self) -> Style { Fixed(77).bold() }
fn size(&self, _prefix: Option<Prefix>) -> Style { Fixed(66).normal() }
fn unit(&self, _prefix: Option<Prefix>) -> Style { Fixed(77).bold() }
fn no_size(&self) -> Style { Black.italic() }

fn major(&self) -> Style { Blue.on(Red) }
Expand Down
152 changes: 107 additions & 45 deletions src/style/colours.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use style::lsc::Pair;
#[derive(Debug, Default, PartialEq)]
pub struct Colours {
pub colourful: bool,
pub scale: bool,

pub filekinds: FileKinds,
pub perms: Permissions,
Expand Down Expand Up @@ -67,17 +66,20 @@ pub struct Permissions {

#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Size {
pub numbers: Style,
pub unit: Style,

pub major: Style,
pub minor: Style,

pub scale_byte: Style,
pub scale_kilo: Style,
pub scale_mega: Style,
pub scale_giga: Style,
pub scale_huge: Style,
pub number_byte: Style,
pub number_kilo: Style,
pub number_mega: Style,
pub number_giga: 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)]
Expand Down Expand Up @@ -112,7 +114,6 @@ impl Colours {
pub fn colourful(scale: bool) -> Colours {
Colours {
colourful: true,
scale,

filekinds: FileKinds {
normal: Style::default(),
Expand Down Expand Up @@ -146,19 +147,7 @@ impl Colours {
attribute: Style::default(),
},

size: Size {
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(),
},
size: Size::colourful(scale),

users: Users {
user_you: Yellow.bold(),
Expand Down Expand Up @@ -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
/// set as regular styles (foreground and background colours, bold, underline,
Expand Down Expand Up @@ -270,8 +308,18 @@ impl Colours {
"sf" => self.perms.special_other = pair.to_style(),
"xa" => self.perms.attribute = pair.to_style(),

"sn" => self.size.numbers = pair.to_style(),
"sb" => self.size.unit = pair.to_style(),
"sn" => self.set_number_style(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(),
"ds" => self.size.minor = pair.to_style(),

Expand Down Expand Up @@ -302,6 +350,22 @@ impl Colours {
}
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;
}
}


Expand Down Expand Up @@ -360,30 +424,28 @@ impl render::PermissionsColours for Colours {
}

impl render::SizeColours for Colours {
fn size(&self, size: u64) -> Style {
if self.scale {
if size < 1024 {
self.size.scale_byte
}
else if size < 1024 * 1024 {
self.size.scale_kilo
}
else if size < 1024 * 1024 * 1024 {
self.size.scale_mega
}
else if size < 1024 * 1024 * 1024 * 1024 {
self.size.scale_giga
}
else {
self.size.scale_huge
}
fn size(&self, prefix: Option<number_prefix::Prefix>) -> Style {
use number_prefix::Prefix::*;
match prefix {
None => self.size.number_byte,
Some(Kilo) | Some(Kibi) => self.size.number_kilo,
Some(Mega) | Some(Mibi) => self.size.number_mega,
Some(Giga) | Some(Gibi) => self.size.number_giga,
Some(_) => self.size.number_huge,
}
else {
self.size.numbers
}

fn unit(&self, prefix: Option<number_prefix::Prefix>) -> Style {
use number_prefix::Prefix::*;
match prefix {
None => self.size.unit_byte,
Some(Kilo) | Some(Kibi) => self.size.unit_kilo,
Some(Mega) | Some(Mibi) => self.size.unit_mega,
Some(Giga) | Some(Gibi) => self.size.unit_giga,
Some(_) => self.size.unit_huge,
}
}

fn unit(&self) -> Style { self.size.unit }
fn no_size(&self) -> Style { self.punctuation }
fn major(&self) -> Style { self.size.major }
fn comma(&self) -> Style { self.punctuation }
Expand Down
1 change: 1 addition & 0 deletions src/style/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod colours;
pub use self::colours::Colours;
pub use self::colours::Size as SizeColours;

mod lsc;
pub use self::lsc::LSColors;

0 comments on commit 3ef6195

Please sign in to comment.