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
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ SPDX-License-Identifier: EUPL-1.2
[Available for MacOS, Linux, & Windows](https://www.warp.dev/eza)<br>

</div>

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some changing is unrelated to this PR feat: add --spacing parameter

we'd better submit those commit in a separate PR

# eza

A modern replacement for ls.
Expand Down Expand Up @@ -113,6 +113,7 @@ eza’s options are almost, but not quite, entirely unlike `ls`’s. Quick overv
- **--hyperlink**: display entries as hyperlinks
- **--absolute=(mode)**: display entries with their absolute path (on, follow, off)
- **-w**, **--width=(columns)**: set screen width in columns
- **--spacing=(columns)**: set the number of spaces between columns

</details>

Expand Down Expand Up @@ -203,7 +204,7 @@ precedence for backwards compatibility.
#### **New** Pre-made themes
Check out the themes available in the official [eza-themes](https://github.com/eza-community/eza-themes) repository, or contribute your own.

An example theme file is available in `docs/theme.yml`, and needs to either be placed in a directory specified by the
An example theme file is available in `docs/theme.yml`, and needs to either be placed in a directory specified by the
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

environment variable `EZA_CONFIG_DIR`, or will looked for by default in `$XDG_CONFIG_HOME/eza`.

Full details are available on the [man page](https://github.com/eza-community/eza/tree/main/man/eza_colors-explanation.5.md) and an example theme file is included [here](https://github.com/eza-community/eza/tree/main/docs/theme.yml)
Expand All @@ -213,10 +214,10 @@ Full details are available on the [man page](https://github.com/eza-community/ez

# Hacking on eza

If you wanna contribute to eza, firstly, you're expected to follow our
[code of conduct](https://github.com/eza-community/eza/blob/main/CODE_OF_CONDUCT.md).
If you wanna contribute to eza, firstly, you're expected to follow our
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

[code of conduct](https://github.com/eza-community/eza/blob/main/CODE_OF_CONDUCT.md).
After having understood the code of conduct, you can have a look at our
[CONTRIBUTING.md](https://github.com/eza-community/eza/blob/main/CONTRIBUTING.md)
[CONTRIBUTING.md](https://github.com/eza-community/eza/blob/main/CONTRIBUTING.md)
for more info about actual hacking.

[![Star History Chart](https://api.star-history.com/svg?repos=eza-community/eza&type=Date)](https://star-history.com/#eza-community/eza&Date)
3 changes: 2 additions & 1 deletion completions/fish/eza.fish
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@ complete -c eza -l group-directories-first -d "Sort directories before other fil
complete -c eza -l group-directories-last -d "Sort directories after other files"
complete -c eza -l git-ignore -d "Ignore files mentioned in '.gitignore'"
complete -c eza -s a -l all -d "Show hidden and 'dot' files. Use this twice to also show the '.' and '..' directories"
complete -c eza -s A -l almost-all -d "Equivalent to --all; included for compatibility with `ls -A`"
complete -c eza -s A -l almost-all -d "Equivalent to --all; included for compatibility with $(ls -A)"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand why the $() is nescesarry here?

complete -c eza -s d -l treat-dirs-as-files -d "List directories like regular files"
complete -c eza -s L -l level -d "Limit the depth of recursion" -x -a "1 2 3 4 5 6 7 8 9"
complete -c eza -s w -l width -d "Limits column output of grid, 0 implies auto-width"
complete -c eza -l spacing -d "Set the space between columns"
complete -c eza -s r -l reverse -d "Reverse the sort order"
complete -c eza -s s -l sort -d "Which field to sort by" -x -a "
accessed\t'Sort by file accessed time'
Expand Down
1 change: 1 addition & 0 deletions completions/nush/eza.nu
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export extern "eza" [
--treat-dirs-as-files(-d) # List directories like regular files
--level(-L): string # Limit the depth of recursion
--width(-w) # Limits column output of grid, 0 implies auto-width
--spacing # Space between columns in grid mode
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
--spacing # Space between columns in grid mode
--spacing # Space between columns in grid mode

--reverse(-r) # Reverse the sort order
--sort(-s) # Which field to sort by
--only-dirs(-D) # List only directories
Expand Down
1 change: 1 addition & 0 deletions completions/zsh/_eza
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ __eza() {
{-f,--only-files}"[List only files]" \
{-L,--level}"+[Limit the depth of recursion]" \
{-w,--width}"+[Limits column output of grid, 0 implies auto-width]" \
--spacing"+[Set the space between columns]" \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't remember the zsh syntax but this does seem odd compared to other lines, why not --spacing"[Set ...]" \?

{-r,--reverse}"[Reverse the sort order]" \
{-s,--sort}="[Which field to sort by]:(sort field):(accessed age changed created date extension Extension filename Filename inode modified oldest name Name newest none size time type)" \
{-I,--ignore-glob}"[Ignore files that match these glob patterns]" \
Expand Down
5 changes: 4 additions & 1 deletion man/eza.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ The default value is ‘`automatic`’.
`-w`, `--width=COLS`
: Set screen width in columns.

`--spacing=COLS`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

COLS should be something appropriate for the context, e.g. spacing

: Set the number of spaces between columns.

FILTERING AND SORTING OPTIONS
=============================

Expand Down Expand Up @@ -356,7 +359,7 @@ Specifies the minimum luminance to use when color-scale is active. It's value ca

If set, automates the same behavior as using `--icons` or `--icons=auto`. Useful for if you always want to have icons enabled.

Any explicit use of the `--icons=WHEN` flag overrides this behavior.
Any explicit use of the `--icons=WHEN` flag overrides this behavior.

## `EZA_STDIN_SEPARATOR`

Expand Down
4 changes: 4 additions & 0 deletions src/options/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ pub enum OptionsError {

/// A glob ignore was given that failed to be parsed as a pattern.
FailedGlobPattern(String),

/// A numeric option was given that contained a negative number.
NegativeNumber(&'static Arg, String),
}

/// The source of a string that failed to be parsed as a number.
Expand Down Expand Up @@ -102,6 +105,7 @@ impl fmt::Display for OptionsError {
Self::TreeAllAll => write!(f, "Option --tree is useless given --all --all"),
Self::FailedParse(s, n, e) => write!(f, "Value {s:?} not valid for {n}: {e}"),
Self::FailedGlobPattern(ref e) => write!(f, "Failed to parse glob pattern: {e}"),
Self::NegativeNumber(a, n) => write!(f, "Value {n:?} not valid for {a}: Negative numbers are not allowed"),
};
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/options/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub static TREE: Arg = Arg { short: Some(b'T'), long: "tree",
pub static CLASSIFY: Arg = Arg { short: Some(b'F'), long: "classify", takes_value: TakesValue::Optional(Some(WHEN), "auto") };
pub static DEREF_LINKS: Arg = Arg { short: Some(b'X'), long: "dereference", takes_value: TakesValue::Forbidden };
pub static WIDTH: Arg = Arg { short: Some(b'w'), long: "width", takes_value: TakesValue::Necessary(None) };
pub static SPACING:Arg = Arg { short: None, long: "spacing", takes_value: TakesValue::Necessary(None) };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be formatted like adjacent lines

pub static NO_QUOTES: Arg = Arg { short: None, long: "no-quotes", takes_value: TakesValue::Forbidden };
pub static ABSOLUTE: Arg = Arg { short: None, long: "absolute", takes_value: TakesValue::Optional(Some(ABSOLUTE_MODES), "on") };
pub static FOLLOW_LINKS: Arg = Arg { short: None, long: "follow-symlinks", takes_value: TakesValue::Forbidden };
Expand Down Expand Up @@ -103,7 +104,7 @@ pub static ALL_ARGS: Args = Args(&[

&ONE_LINE, &LONG, &GRID, &ACROSS, &RECURSE, &TREE, &CLASSIFY, &DEREF_LINKS, &FOLLOW_LINKS,
&COLOR, &COLOUR, &COLOR_SCALE, &COLOUR_SCALE, &COLOR_SCALE_MODE, &COLOUR_SCALE_MODE,
&WIDTH, &NO_QUOTES, &ABSOLUTE,
&WIDTH, &NO_QUOTES, &ABSOLUTE, &SPACING,

&ALL, &ALMOST_ALL, &TREAT_DIRS_AS_FILES, &LIST_DIRS, &LEVEL, &REVERSE, &SORT, &DIRS_FIRST, &DIRS_LAST,
&IGNORE_GLOB, &GIT_IGNORE, &ONLY_DIRS, &ONLY_FILES,
Expand Down
3 changes: 2 additions & 1 deletion src/options/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ DISPLAY OPTIONS
--absolute display entries with their absolute path (on, follow, off)
--follow-symlinks drill down into symbolic links that point to directories
-w, --width COLS set screen width in columns
--spacing set the space between columns (0 for no spacing)


FILTERING AND SORTING OPTIONS
Expand Down Expand Up @@ -88,7 +89,7 @@ LONG VIEW OPTIONS
--no-filesize suppress the filesize field
--no-user suppress the user field
--no-time suppress the time field
--stdin read file names from stdin, one per line or other separator
--stdin read file names from stdin, one per line or other separator
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change doesn't seem like it should be introduced in this pr

specified in environment";

static GIT_VIEW_HELP: &str = " \
Expand Down
82 changes: 74 additions & 8 deletions src/options/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::output::table::{
Columns, FlagsFormat, GroupFormat, Options as TableOptions, SizeFormat, TimeTypes, UserFormat,
};
use crate::output::time::TimeFormat;
use crate::output::{details, grid, Mode, TerminalWidth, View};
use crate::output::{details, grid, Mode, SpacingBetweenColumns, SpacingMode, TerminalWidth, View};

impl View {
pub fn deduce<V: Vars>(matches: &MatchedFlags<'_>, vars: &V) -> Result<Self, OptionsError> {
Expand All @@ -27,9 +27,12 @@ impl View {
let follow_links = matches.has(&flags::FOLLOW_LINKS)?;
let total_size = matches.has(&flags::TOTAL_SIZE)?;
let file_style = FileStyle::deduce(matches, vars, is_tty)?;
let space_between_columns = SpacingBetweenColumns::deduce(matches)?;

Ok(Self {
mode,
width,
space_between_columns,
file_style,
deref_links,
follow_links,
Expand Down Expand Up @@ -61,10 +64,13 @@ impl Mode {

let Some(flag) = flag else {
Self::strict_check_long_flags(matches)?;

if is_tty {
let grid = grid::Options::deduce(matches)?;
let spacing = SpacingBetweenColumns::deduce(matches)?;
let grid = grid::Options::deduce(matches, spacing.spaces(SpacingMode::Grid))?;
return Ok(Self::Grid(grid));
}

return Ok(Self::Lines);
};

Expand All @@ -73,7 +79,9 @@ impl Mode {
|| (flag.matches(&flags::GRID) && matches.has(&flags::LONG)?)
{
let _ = matches.has(&flags::LONG)?;
let details = details::Options::deduce_long(matches, vars)?;
let spacing = SpacingBetweenColumns::deduce(matches)?;
let details =
details::Options::deduce_long(matches, vars, spacing.spaces(SpacingMode::Details))?;

let flag =
matches.has_where_any(|f| f.matches(&flags::GRID) || f.matches(&flags::TREE));
Expand All @@ -96,7 +104,9 @@ impl Mode {

if flag.matches(&flags::TREE) {
let _ = matches.has(&flags::TREE)?;
let details = details::Options::deduce_tree(matches, vars)?;
let spacing = SpacingBetweenColumns::deduce(matches)?;
let details =
details::Options::deduce_tree(matches, vars, spacing.spaces(SpacingMode::Details))?;
return Ok(Self::Details(details));
}

Expand All @@ -105,7 +115,8 @@ impl Mode {
return Ok(Self::Lines);
}

let grid = grid::Options::deduce(matches)?;
let spacing = SpacingBetweenColumns::deduce(matches)?;
let grid = grid::Options::deduce(matches, spacing.spaces(SpacingMode::Grid))?;
Ok(Self::Grid(grid))
}

Expand Down Expand Up @@ -149,17 +160,22 @@ impl Mode {
}

impl grid::Options {
fn deduce(matches: &MatchedFlags<'_>) -> Result<Self, OptionsError> {
fn deduce(matches: &MatchedFlags<'_>, spacing: usize) -> Result<Self, OptionsError> {
let grid = grid::Options {
across: matches.has(&flags::ACROSS)?,
spacing,
};

Ok(grid)
}
}

impl details::Options {
fn deduce_tree<V: Vars>(matches: &MatchedFlags<'_>, vars: &V) -> Result<Self, OptionsError> {
fn deduce_tree<V: Vars>(
matches: &MatchedFlags<'_>,
vars: &V,
spacing: usize,
) -> Result<Self, OptionsError> {
let details = details::Options {
table: None,
header: false,
Expand All @@ -168,12 +184,17 @@ impl details::Options {
mounts: matches.has(&flags::MOUNTS)?,
color_scale: ColorScaleOptions::deduce(matches, vars)?,
follow_links: matches.has(&flags::FOLLOW_LINKS)?,
spacing,
};

Ok(details)
}

fn deduce_long<V: Vars>(matches: &MatchedFlags<'_>, vars: &V) -> Result<Self, OptionsError> {
fn deduce_long<V: Vars>(
matches: &MatchedFlags<'_>,
vars: &V,
spacing: usize,
) -> Result<Self, OptionsError> {
if matches.is_strict() {
if matches.has(&flags::ACROSS)? && !matches.has(&flags::GRID)? {
return Err(OptionsError::Useless(&flags::ACROSS, true, &flags::LONG));
Expand All @@ -190,6 +211,7 @@ impl details::Options {
mounts: matches.has(&flags::MOUNTS)?,
color_scale: ColorScaleOptions::deduce(matches, vars)?,
follow_links: matches.has(&flags::FOLLOW_LINKS)?,
spacing,
})
}
}
Expand Down Expand Up @@ -225,6 +247,33 @@ impl TerminalWidth {
}
}

impl SpacingBetweenColumns {
fn deduce(matches: &MatchedFlags<'_>) -> Result<Self, OptionsError> {
if let Some(spacing) = matches.get(&flags::SPACING)? {
let arg_str = spacing.to_string_lossy();
match arg_str.parse::<i32>() {
Ok(n) => {
use std::cmp::Ordering;
match n.cmp(&0) {
Ordering::Less => Err(OptionsError::NegativeNumber(
&flags::SPACING,
arg_str.to_string(),
)),
Ordering::Equal => Ok(Self::Set(0)),
Ordering::Greater => Ok(Self::Set(n as usize)),
}
}
Err(e) => {
let source = NumberSource::Arg(&flags::SPACING);
Err(OptionsError::FailedParse(arg_str.to_string(), source, e))
}
}
} else {
Ok(Self::Default)
}
}
}

impl RowThreshold {
fn deduce<V: Vars>(vars: &V) -> Result<Self, OptionsError> {
if let Some(columns) = vars
Expand Down Expand Up @@ -560,6 +609,7 @@ mod test {
&flags::ONE_LINE,
&flags::TREE,
&flags::NUMERIC,
&flags::SPACING,
];

#[allow(unused_macro_rules)]
Expand Down Expand Up @@ -840,4 +890,20 @@ mod test {
test_mode!(og: <- ["--oneline", "--grid"], None; Both => like Ok(Mode::Grid(_)));
test_mode!(tg: <- ["--tree", "--grid"], None; Both => like Ok(Mode::Grid(_)));
}

mod spacing_between_columns {
use super::*;

test!(default: SpacingBetweenColumns <- []; Both => like Ok(SpacingBetweenColumns::Default));
test!(zero: SpacingBetweenColumns <- ["--spacing", "0"]; Both => like Ok(SpacingBetweenColumns::Set(0)));
test!(one: SpacingBetweenColumns <- ["--spacing", "1"]; Both => like Ok(SpacingBetweenColumns::Set(1)));
test!(three: SpacingBetweenColumns <- ["--spacing", "3"]; Both => like Ok(SpacingBetweenColumns::Set(3)));
test!(five: SpacingBetweenColumns <- ["--spacing", "5"]; Both => like Ok(SpacingBetweenColumns::Set(5)));
test!(large: SpacingBetweenColumns <- ["--spacing", "100"]; Both => like Ok(SpacingBetweenColumns::Set(100)));
test!(negative: SpacingBetweenColumns <- ["--spacing", "-1"]; Both => like Err(OptionsError::NegativeNumber(_, _)));
test!(negative_zero: SpacingBetweenColumns <- ["--spacing", "-0"]; Both => like Ok(SpacingBetweenColumns::Set(0)));
test!(invalid: SpacingBetweenColumns <- ["--spacing", "abc"]; Both => like Err(OptionsError::FailedParse(_, _, _)));
test!(invalid_float: SpacingBetweenColumns <- ["--spacing", "1.5"]; Both => like Err(OptionsError::FailedParse(_, _, _)));
test!(empty: SpacingBetweenColumns <- ["--spacing", ""]; Both => like Err(OptionsError::FailedParse(_, _, _)));
}
}
13 changes: 11 additions & 2 deletions src/output/details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ pub struct Options {
/// Whether to show a header line or not.
pub header: bool,

/// Whether to show each files extended attributes.
/// Whether to show each file's extended attributes.
pub xattr: bool,

/// Whether to show each file's security attribute.
Expand All @@ -124,6 +124,9 @@ pub struct Options {

/// Whether to drill down into symbolic links that point to directories
pub follow_links: bool,

/// The spacing between columns in the table
pub spacing: usize,
}

pub struct Render<'a> {
Expand Down Expand Up @@ -192,7 +195,13 @@ impl<'a> Render<'a> {
(None, _) => { /* Keep Git how it is */ }
}

let mut table = Table::new(table, self.git, self.theme, self.git_repos);
let mut table = Table::new(
table,
self.git,
self.theme,
self.opts.spacing,
self.git_repos,
);

if self.opts.header {
let header = table.header_row();
Expand Down
3 changes: 2 additions & 1 deletion src/output/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::theme::Theme;
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub struct Options {
pub across: bool,
pub spacing: usize,
}

impl Options {
Expand Down Expand Up @@ -57,7 +58,7 @@ impl Render<'_> {
let grid = Grid::new(
cells,
GridOptions {
filling: Filling::Spaces(2),
filling: Filling::Spaces(self.opts.spacing),
direction: self.opts.direction(),
width: self.console_width,
},
Expand Down
8 changes: 7 additions & 1 deletion src/output/grid_details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,13 @@ impl<'a> Render<'a> {
(None, _) => { /* Keep Git how it is */ }
}

let mut table = Table::new(options, self.git, self.theme, self.git_repos);
let mut table = Table::new(
options,
self.git,
self.theme,
self.details.spacing,
self.git_repos,
);

// The header row will be printed separately, but it should be
// considered for the width calculations.
Expand Down
Loading
Loading