Skip to content
Open
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
1,047 changes: 705 additions & 342 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,12 @@ xdg = "2.5"
git2 = { version = "0.18", optional = true, default-features = false }

[target.'cfg(unix)'.dependencies]
num-format = { version = "0.4.4", features = ["with-system-locale"] }
users = { version = "0.11.3", package = "uzers" }
xattr = "1"

[target.'cfg(windows)'.dependencies]
num-format = "0.4.4"
windows = { version = "0.43.0", features = ["Win32_Foundation", "Win32_Security_Authorization", "Win32_Storage_FileSystem", "Win32_System_Memory"] }

[dependencies.clap]
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,13 @@ recursion:
# Possible values: default, short, bytes
size: default

# == Size Separator ==
# Specifies the number separator kind used for the size column.
# use number format from https://docs.rs/num-format/latest/num_format/
# Possible values: "en", "fr"
#
# size-separator: "en"

# == Permission ==
# Specify the format of the permission column
# Possible value: rwx, octal, attributes (windows only), disable
Expand Down
3 changes: 3 additions & 0 deletions doc/lsd.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ lsd is a ls command with a lot of pretty colours and some other stuff to enrich
`--size <size>...`
: How to display size [default: default] [possible values: default, short, bytes]

`--size-separator <size-separator>...`
: Separator kind to format file size [default: none] [possible values: none, en]

`--sort <WORD>...`
: Sort by WORD instead of name [possible values: size, time, version, extension, git]

Expand Down
4 changes: 4 additions & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ pub struct Cli {
#[arg(long, value_name = "MODE", value_parser = ["default", "short", "bytes"])]
pub size: Option<String>,

/// Size separator kind [default: none]
#[arg(long, value_name = "KIND", value_parser = ["en"])]
pub size_separator: Option<String>,

/// Display the total size of directories
#[arg(long)]
pub total_size: bool,
Expand Down
11 changes: 11 additions & 0 deletions src/config_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::flags::icons::{IconOption, IconTheme};
use crate::flags::layout::Layout;
use crate::flags::permission::PermissionFlag;
use crate::flags::size::SizeFlag;

use crate::flags::sorting::{DirGrouping, SortColumn};
use crate::flags::HyperlinkOption;
use crate::flags::{ColorOption, ThemeOption};
Expand Down Expand Up @@ -35,6 +36,7 @@ pub struct Config {
pub layout: Option<Layout>,
pub recursion: Option<Recursion>,
pub size: Option<SizeFlag>,
pub size_separator: Option<String>,
pub permission: Option<PermissionFlag>,
pub sorting: Option<Sorting>,
pub no_symlink: Option<bool>,
Expand Down Expand Up @@ -120,6 +122,7 @@ impl Config {
layout: None,
recursion: None,
size: None,
size_separator: None,
permission: None,
sorting: None,
no_symlink: None,
Expand Down Expand Up @@ -308,6 +311,13 @@ recursion:
# Possible values: default, short, bytes
size: default

# == Size Separator ==
# Specifies the number separator kind used for the size column.
# use number format from https://docs.rs/num-format/latest/num_format/
# Possible values: "en"
#
# size-separator: "en"

# == Permission ==
# Specify the format of the permission column.
# Possible value: rwx, octal, attributes, disable
Expand Down Expand Up @@ -412,6 +422,7 @@ mod tests {
depth: None,
}),
size: Some(SizeFlag::Default),
size_separator: None,
permission: None,
sorting: Some(config_file::Sorting {
column: Some(SortColumn::Name),
Expand Down
2 changes: 1 addition & 1 deletion src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl Core {
let mut exit_code = ExitCode::OK;
let mut meta_list = Vec::with_capacity(paths.len());
let depth = match self.flags.layout {
Layout::Tree { .. } => self.flags.recursion.depth,
Layout::Tree => self.flags.recursion.depth,
_ if self.flags.recursion.enabled => self.flags.recursion.depth,
_ => 1,
};
Expand Down
2 changes: 1 addition & 1 deletion src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ mod tests {
.lines()
.nth(i)
.unwrap()
.split(|c| c == 'K' || c == 'B')
.split(['K', 'B'])
.next()
.unwrap()
.len()
Expand Down
4 changes: 4 additions & 0 deletions src/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub mod literal;
pub mod permission;
pub mod recursion;
pub mod size;
pub mod size_separator;
pub mod sorting;
pub mod symlink_arrow;
pub mod symlinks;
Expand All @@ -37,6 +38,7 @@ pub use literal::Literal;
pub use permission::PermissionFlag;
pub use recursion::Recursion;
pub use size::SizeFlag;
use size_separator::SizeSeparator;
pub use sorting::DirGrouping;
pub use sorting::SortColumn;
pub use sorting::SortOrder;
Expand Down Expand Up @@ -69,6 +71,7 @@ pub struct Flags {
pub no_symlink: NoSymlink,
pub recursion: Recursion,
pub size: SizeFlag,
pub size_separator: Option<SizeSeparator>,
pub permission: PermissionFlag,
pub sorting: Sorting,
pub total_size: TotalSize,
Expand All @@ -95,6 +98,7 @@ impl Flags {
display: Display::configure_from(cli, config),
layout: Layout::configure_from(cli, config),
size: SizeFlag::configure_from(cli, config),
size_separator: Some(SizeSeparator::configure_from(cli, config)),
permission: PermissionFlag::configure_from(cli, config),
display_indicators: Indicators::configure_from(cli, config),
icons: Icons::configure_from(cli, config),
Expand Down
67 changes: 67 additions & 0 deletions src/flags/size_separator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//! This module defines the [SizeSeparator]. To set it up from [Cli], a [Config] and its
//! [Default] value, use its [configure_from](Configurable::configure_from) method.

use super::Configurable;

use crate::app::Cli;
use crate::config_file::Config;
use crate::print_error;

use num_format::Locale;
use serde::Deserialize;

/// The flag showing which separator to use for file sizes.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Default)]
pub struct SizeSeparator {
locale: Option<String>,
}

impl SizeSeparator {
pub fn new(locale: Option<String>) -> Self {
Self { locale }
}

pub fn get_locale(&self) -> Option<Locale> {
self.locale.as_ref().and_then(|s| {
Locale::from_name(s).ok().or_else(|| {
print_error!("Invalid locale: {s}");
None
})
})
}
}

impl Configurable<Self> for SizeSeparator {
fn from_cli(cli: &Cli) -> Option<Self> {
cli.size_separator
.as_ref()
.map(|s| Self::new(Some(s.clone())))
}

fn from_config(config: &Config) -> Option<Self> {
config
.size_separator
.as_ref()
.map(|s| Self::new(Some(s.clone())))
}
}

#[cfg(test)]
mod test {
use clap::Parser;

use super::SizeSeparator;

use crate::app::Cli;
use crate::flags::Configurable;

#[test]
fn test_from_cli_bytes_with_separator() {
let argv = ["lsd", "--size-separator", "en"];
let cli = Cli::try_parse_from(argv).unwrap();
assert_eq!(
Some(SizeSeparator::new(Some("en".to_string()))),
SizeSeparator::from_cli(&cli)
);
}
}
8 changes: 4 additions & 4 deletions src/meta/access_control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ mod test {

#[test]
fn test_smack_only_indicator() {
let access_control = AccessControl::from_data(false, &[], &[b'a']);
let access_control = AccessControl::from_data(false, &[], b"a");

assert_eq!(
String::from(".").with(Color::Cyan),
Expand All @@ -112,7 +112,7 @@ mod test {

#[test]
fn test_acl_and_selinux_indicator() {
let access_control = AccessControl::from_data(true, &[b'a'], &[]);
let access_control = AccessControl::from_data(true, b"a", &[]);

assert_eq!(
String::from("+").with(Color::DarkCyan),
Expand All @@ -122,7 +122,7 @@ mod test {

#[test]
fn test_selinux_context() {
let access_control = AccessControl::from_data(false, &[b'a'], &[]);
let access_control = AccessControl::from_data(false, b"a", &[]);

assert_eq!(
String::from("a").with(Color::Cyan),
Expand All @@ -132,7 +132,7 @@ mod test {

#[test]
fn test_selinux_and_smack_context() {
let access_control = AccessControl::from_data(false, &[b'a'], &[b'b']);
let access_control = AccessControl::from_data(false, b"a", b"b");

assert_eq!(
String::from("a+b").with(Color::Cyan),
Expand Down
Loading
Loading