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

Fix: 🐛 Contradicting argument configurations #147

Merged
merged 12 commits into from
Apr 27, 2023
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Arguments:
[DIR] Directory to traverse; defaults to current working directory

Options:
-C, --force-color Turn on colorization always
-C, --color Output Coloring [default: auto] [possible values: none, auto, forced]
-d, --disk-usage <DISK_USAGE> Print physical or logical file size [default: physical] [possible values: logical, physical]
-f, --follow Follow symlinks
-F, --flat Print disk usage information in plain format without the ASCII tree
Expand All @@ -87,7 +87,6 @@ Options:
--completions <COMPLETIONS> Print completions for a given shell to stdout [possible values: bash, elvish, fish, powershell, zsh]
--dirs-only Only print directories
--inverted Print tree with the root directory at the topmost position
--no-color Print plainly without ANSI escapes
--no-config Don't read configuration file
--suppress-size Omit disk usage from output
--truncate Truncate output to fit terminal emulator window
Expand Down Expand Up @@ -118,13 +117,13 @@ $ cargo install erdtree
The Windows version relies on some experimental features in order to properly support hard-link detection. If you want to build from `crates.io` you'll first need to install the nightly toolchain before installing `erdtree`:

```
$ rustup toolchain install nightly-2023-03-05
$ rustup toolchain install nightly-2023-03-05
```

Thereafter:

```
$ cargo +nightly-2023-03-05 install erdtree
$ cargo +nightly-2023-03-05 install erdtree
```

### Homebrew-core
Expand Down Expand Up @@ -424,22 +423,21 @@ In these situations the following may be used:
### Redirecting output and colorization

If you wish to force a colorless output the following may be used:

```
--no-color Print plainly without ANSI escapes
-C none Print plainly without ANSI escapes
```

Colorization is also turned off if the output is redirected to something that is not a tty. If you wish to preserve the ANSI escape sequences (e.g.
preserve the colors as in the case of piping) the following may be used:

```
-C, --force-color Turn on colorization always
-C, forced Turn on colorization always
```

<p align="center">
<img src="https://github.com/solidiquis/erdtree/blob/master/assets/no_color.png?raw=true" alt="failed to load picture" />
</p>

<p align="center">
<img src="https://github.com/solidiquis/erdtree/blob/master/assets/force_color.png?raw=true" alt="failed to load picture" />
</p>
Expand Down
61 changes: 36 additions & 25 deletions src/render/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@ pub mod time;
#[cfg(test)]
mod test;

#[derive(Clone, Copy, Debug, clap::ValueEnum, PartialEq, Eq, Default)]
pub enum Coloring {
/// Print plainly without ANSI escapes
None,

/// Check the [`no_color`] function for the Auto behaviour
///
/// [`no_color`]: no_color
#[default]
Auto,

/// Turn on colorization always
Forced,
}
/// Defines the CLI.
#[derive(Parser, Debug)]
#[command(name = "erdtree")]
Expand All @@ -48,9 +62,9 @@ pub struct Context {
/// Directory to traverse; defaults to current working directory
dir: Option<PathBuf>,

/// Turn on colorization always
#[arg(short = 'C', long)]
pub force_color: bool,
/// Coloring of the Output
#[arg(short = 'C', long, value_enum, default_value_t = Coloring::default())]
pub color: Coloring,

/// Print physical or logical file size
#[arg(short, long, value_enum, default_value_t = DiskUsage::default())]
Expand Down Expand Up @@ -151,10 +165,6 @@ pub struct Context {
#[arg(long)]
pub inverted: bool,

/// Print plainly without ANSI escapes
#[arg(long)]
pub no_color: bool,

/// Don't read configuration file
#[arg(long)]
pub no_config: bool,
Expand Down Expand Up @@ -205,7 +215,6 @@ pub struct Context {
#[clap(skip)]
pub window_width: Option<usize>,
}

type Predicate = Result<Box<dyn Fn(&DirEntry) -> bool + Send + Sync + 'static>, Error>;
impl Context {
/// Initializes [Context], optionally reading in the configuration file to override defaults.
Expand Down Expand Up @@ -275,15 +284,15 @@ impl Context {
}

/// Determines whether or not it's appropriate to display color in output based on
/// `--no-color`, `--force-color`, and whether or not stdout is connected to a tty.
/// the Coloring, and whether or not stdout is connected to a tty.
///
/// If `--force-color` is `true` then this will always evaluate to `false`.
/// If Coloring is Forced then this will always evaluate to `false`.
pub const fn no_color(&self) -> bool {
if self.force_color {
return false;
match self.color {
Coloring::Auto if !self.stdout_is_tty => true,
Coloring::None => true,
Coloring::Auto | Coloring::Forced => false,
}

self.no_color || !self.stdout_is_tty
}

/// Returns [Path] of the root directory to be traversed.
Expand All @@ -310,7 +319,7 @@ impl Context {
self.time.unwrap_or_default()
}

/// Which filetype to filter on; defaults to regular file.
/// Which `FileType` to filter on; defaults to regular file.
pub fn file_type(&self) -> file::Type {
self.file_type.unwrap_or_default()
}
Expand Down Expand Up @@ -346,19 +355,17 @@ impl Context {

let file_type = self.file_type();

match file_type {
file::Type::Dir => Ok(Box::new(move |dir_entry: &DirEntry| {
Ok(match file_type {
file::Type::Dir => Box::new(move |dir_entry: &DirEntry| {
let is_dir = dir_entry.file_type().map_or(false, |ft| ft.is_dir());

if is_dir {
// Problem right here.
return Self::ancestor_regex_match(dir_entry.path(), &re, 0);
}

Self::ancestor_regex_match(dir_entry.path(), &re, 1)
})),
}),

_ => Ok(Box::new(move |dir_entry: &DirEntry| {
_ => Box::new(move |dir_entry: &DirEntry| {
let entry_type = dir_entry.file_type();
let is_dir = entry_type.map_or(false, |ft| ft.is_dir());

Expand All @@ -367,16 +374,18 @@ impl Context {
}

match file_type {
file::Type::File if entry_type.map_or(true, |ft| !ft.is_file()) => return false,
file::Type::File if entry_type.map_or(true, |ft| !ft.is_file()) => {
return false
}
file::Type::Link if entry_type.map_or(true, |ft| !ft.is_symlink()) => {
return false
}
_ => (),
}
let file_name = dir_entry.file_name().to_string_lossy();
re.is_match(&file_name)
})),
}
}),
})
}

/// Predicate used for filtering via globs and file-types.
Expand Down Expand Up @@ -437,7 +446,9 @@ impl Context {
}

match file_type {
file::Type::File if entry_type.map_or(true, |ft| !ft.is_file()) => return false,
file::Type::File if entry_type.map_or(true, |ft| !ft.is_file()) => {
return false
}
file::Type::Link if entry_type.map_or(true, |ft| !ft.is_symlink()) => {
return false
}
Expand Down