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

Enhancement #857 - Implemented -p flag #1103

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
4 changes: 4 additions & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ pub struct Cli {
#[arg(short = 'F', long = "classify")]
pub indicators: bool,

/// Append "/" at the end of the directories names
#[arg(short = 'p', long = "slash-indicator")]
pub slash_indicator: bool,

/// Display extended file metadata as a table
#[arg(short, long)]
pub long: bool,
Expand Down
8 changes: 8 additions & 0 deletions src/config_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub struct Config {
pub icons: Option<Icons>,
pub ignore_globs: Option<Vec<String>>,
pub indicators: Option<bool>,
pub slash_indicator: Option<bool>,
pub layout: Option<Layout>,
pub recursion: Option<Recursion>,
pub size: Option<SizeFlag>,
Expand Down Expand Up @@ -117,6 +118,7 @@ impl Config {
icons: None,
ignore_globs: None,
indicators: None,
slash_indicator: None,
layout: None,
recursion: None,
size: None,
Expand Down Expand Up @@ -288,6 +290,11 @@ icons:
# Possible values: false, true
indicators: false

# == Slash Indicator ==
# Whether to add indicator "/" to directories.
# Possible values: false, true
slash_indicator: false

# == Layout ==
# Which layout to use. "oneline" might be a bit confusing here and should be
# called "one-per-line". It might be changed in the future.
Expand Down Expand Up @@ -406,6 +413,7 @@ mod tests {
}),
ignore_globs: None,
indicators: Some(false),
slash_indicator: Some(false),
layout: Some(Layout::Grid),
recursion: Some(config_file::Recursion {
enabled: Some(false),
Expand Down
1 change: 1 addition & 0 deletions src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ fn get_output(
flags.literal.0,
),
meta.indicator.render(flags),
meta.slash_indicator.render(flags),
]);
if !(flags.no_symlink.0 || flags.dereference.0 || flags.layout == Layout::Grid) {
block_vec.push(meta.symlink.render(colors, flags))
Expand Down
4 changes: 4 additions & 0 deletions src/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod hyperlink;
pub mod icons;
pub mod ignore_globs;
pub mod indicators;
pub mod slash_indicator;
pub mod layout;
pub mod literal;
pub mod permission;
Expand All @@ -32,6 +33,7 @@ pub use icons::IconTheme;
pub use icons::Icons;
pub use ignore_globs::IgnoreGlobs;
pub use indicators::Indicators;
pub use slash_indicator::SlashIndicator;
pub use layout::Layout;
pub use literal::Literal;
pub use permission::PermissionFlag;
Expand Down Expand Up @@ -63,6 +65,7 @@ pub struct Flags {
pub dereference: Dereference,
pub display: Display,
pub display_indicators: Indicators,
pub slash_indicator: SlashIndicator,
pub icons: Icons,
pub ignore_globs: IgnoreGlobs,
pub layout: Layout,
Expand Down Expand Up @@ -97,6 +100,7 @@ impl Flags {
size: SizeFlag::configure_from(cli, config),
permission: PermissionFlag::configure_from(cli, config),
display_indicators: Indicators::configure_from(cli, config),
slash_indicator: SlashIndicator::configure_from(cli, config),
icons: Icons::configure_from(cli, config),
ignore_globs: IgnoreGlobs::configure_from(cli, config)?,
no_symlink: NoSymlink::configure_from(cli, config),
Expand Down
78 changes: 78 additions & 0 deletions src/flags/slash_indicator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//! This module defines the [SlashIndicator] flag. To set it up from [Cli], a [Config] and its
//! [Default] value, use the [configure_from](Configurable::configure_from) method.

use super::Configurable;

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

/// The flag showing whether to print slash indicator for directories.
#[derive(Clone, Debug, Copy, PartialEq, Eq, Default)]
pub struct SlashIndicator(pub bool);

impl Configurable<Self> for SlashIndicator {
/// Get a potential `SlashIndicator` value from [Cli].
///
/// If the "SlashIndicator" argument is passed, this returns an `SlashIndicator` with value `true` in a
/// [Some]. Otherwise this returns [None].
fn from_cli(cli: &Cli) -> Option<Self> {
if cli.slash_indicator {
Some(Self(true))
} else {
None
}
}

/// Get a potential `SlashIndicator` value from a [Config].
///
/// If the `Config::slash_indicator` has value,
/// this returns its value as the value of the `SlashIndicator`, in a [Some].
/// Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> {
config.slash_indicator.as_ref().map(|ind| Self(*ind))
}
}

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

use super::SlashIndicator;

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

#[test]
fn test_from_cli_none() {
let argv = ["lsd"];
let cli = Cli::try_parse_from(argv).unwrap();
assert_eq!(None, SlashIndicator::from_cli(&cli));
}

#[test]
fn test_from_cli_true() {
let argv = ["lsd", "--slash-indicator"];
let cli = Cli::try_parse_from(argv).unwrap();
assert_eq!(Some(SlashIndicator(true)), SlashIndicator::from_cli(&cli));
}

#[test]
fn test_from_config_none() {
assert_eq!(None, SlashIndicator::from_config(&Config::with_none()));
}

#[test]
fn test_from_config_true() {
let mut c = Config::with_none();
c.slash_indicator = Some(true);
assert_eq!(Some(SlashIndicator(true)), SlashIndicator::from_config(&c));
}

#[test]
fn test_from_config_false() {
let mut c = Config::with_none();
c.slash_indicator = Some(false);
assert_eq!(Some(SlashIndicator(false)), SlashIndicator::from_config(&c));
}
}
4 changes: 4 additions & 0 deletions src/meta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod date;
mod filetype;
pub mod git_file_status;
mod indicator;
mod slash_indicator;
mod inode;
mod links;
mod locale;
Expand All @@ -23,6 +24,7 @@ pub use self::date::Date;
pub use self::filetype::FileType;
pub use self::git_file_status::GitFileStatus;
pub use self::indicator::Indicator;
pub use self::slash_indicator::SlashIndicator;
pub use self::inode::INode;
pub use self::links::Links;
pub use self::name::Name;
Expand Down Expand Up @@ -52,6 +54,7 @@ pub struct Meta {
pub size: Option<Size>,
pub symlink: SymLink,
pub indicator: Indicator,
pub slash_indicator: SlashIndicator,
pub inode: Option<INode>,
pub links: Option<Links>,
pub content: Option<Vec<Meta>>,
Expand Down Expand Up @@ -356,6 +359,7 @@ impl Meta {
size,
date,
indicator: Indicator::from(file_type),
slash_indicator: SlashIndicator::from(file_type),
owner: owner.unwrap_or_default(),
permissions_or_attributes: permissions_or_attributes.unwrap_or_default(),
name,
Expand Down
68 changes: 68 additions & 0 deletions src/meta/slash_indicator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use crate::color::{ColoredString, Colors};
use crate::flags::Flags;
use crate::meta::FileType;

#[derive(Clone, Debug)]
pub struct SlashIndicator(&'static str);

impl From<FileType> for SlashIndicator {
fn from(file_type: FileType) -> Self {
let res = match file_type {
FileType::Directory { .. } => "/",
_ => "",
};

SlashIndicator(res)
}
}

impl SlashIndicator {
pub fn render(&self, flags: &Flags) -> ColoredString {
if flags.slash_indicator.0 && !flags.display_indicators.0{
ColoredString::new(Colors::default_style(), self.0.to_string())
} else {
ColoredString::new(Colors::default_style(), "".into())
}
}
}

#[cfg(test)]
mod test {
use super::SlashIndicator;
use crate::flags::{Flags, SlashIndicator as SlashIndicatorFlag};
use crate::meta::FileType;

#[test]
fn test_directory_slash_indicator() {
let flags = Flags {
slash_indicator: SlashIndicatorFlag(true),
..Default::default()
};

let file_type = SlashIndicator::from(FileType::Directory { uid: false });

assert_eq!("/", file_type.render(&flags).to_string());
}

#[test]
fn test_not_represented_indicators() {
let flags = Flags {
slash_indicator: SlashIndicatorFlag(true),
..Default::default()
};

// Test multiple non-directory file types
let file_types = vec![
FileType::File { exec: false, uid: false },
FileType::Pipe,
FileType::Socket,
FileType::SymLink { is_dir: false },
];

for file_type in file_types {
let indicator = SlashIndicator::from(file_type);
assert_eq!("", indicator.render(&flags).to_string());
}
}

}